import { Injectable } from '@angular/core'; import { invoke } from '@tauri-apps/api'; import { Observable, ReplaySubject, Subject, from, map, switchMap, tap } from 'rxjs'; import { Plan, PlanInterface, PlanMetadata } from '../_models/plan'; import { MatDialog } from '@angular/material/dialog'; import { UrlDialog } from '../plan-display/url-dialog.component'; import { fetch } from '@tauri-apps/api/http'; @Injectable({ providedIn: 'root' }) export class PlanService { private _currentPlanSubject: Subject = new ReplaySubject(1); private _basePlanSubject: Subject = new ReplaySubject(1); constructor(private dialog: MatDialog) { this.loadBasePlan(); } public getBasePlan(): Observable { return this._basePlanSubject.asObservable(); } public getCurrentPlan(): Observable { return this._currentPlanSubject.asObservable(); } public setCurrentPlan(plan: Plan) { this._currentPlanSubject.next(plan); } public enumerateStoredPlans(): Observable { return from(invoke('enumerate_stored_plans')); } public loadPlanFromPath(path: string, save_local: boolean = true): Observable { return from(invoke('load_plan_at_path', { path, saveLocal: save_local })).pipe(map(plan => { return new Plan(plan) })); } public loadFromUrl(url?: string, name?: string): Observable { if (!url || !name) { const dialogRef = this.dialog.open(UrlDialog, { data: { url: url, name: name } }); return dialogRef.afterClosed().pipe(switchMap(data => { if (data.url) { return this._loadFromUrl(data.url, data.name); } return new Observable((s) => s.complete()); })); } else { return this._loadFromUrl(url, name); } } public savePlanAtPath(path: string, plan: Plan) { plan.plan.forEach(elem => { if (!elem.notes) { elem.notes = "" } }); return from(invoke('save_plan_at_path', { path, plan: plan.toInterface() })); } public savePlanAtStore(name: string, plan: Plan) { return from(invoke('save_plan_at_store', { name, plan: plan.toInterface() })); } private _loadFromUrl(url: string, name: string): Observable { //Tauri fetch return from(fetch( url, { method: 'GET', timeout: 10 })).pipe(map(response => { return new Plan(response.data as PlanInterface); })).pipe(tap(plan => { plan.update_url = url; plan.name = name; })); } private loadBasePlan() { from(invoke('base_plan')).subscribe(plan => { plan.plan.forEach(elem => { elem.edited = false; }); this._basePlanSubject?.next(new Plan(plan)); }); } }