diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 20715ee..cd9ffba 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -72,9 +72,12 @@ fn enumerate_stored_plans() -> Vec { Storage::enumerate_plans() } - #[tauri::command] -fn load_plan_at_path(path: PathBuf, state: tauri::State>) -> Option { +fn load_plan_at_path( + path: PathBuf, + save_local: Option, + state: tauri::State>, +) -> Option { if !path.exists() { return None; } @@ -84,8 +87,10 @@ fn load_plan_at_path(path: PathBuf, state: tauri::State>) -> Opti Err(_) => return None, }; + let save_local = save_local.unwrap_or(true); + storage.last_plan = Some(path.clone()); - Storage::load_plan_at_path(path) + Storage::load_plan_at_path(path, save_local) } #[tauri::command] diff --git a/src-tauri/src/plan.rs b/src-tauri/src/plan.rs index 9b088b4..0a781c6 100644 --- a/src-tauri/src/plan.rs +++ b/src-tauri/src/plan.rs @@ -12,39 +12,45 @@ pub struct Plan { #[derive(Deserialize, Debug, Clone)] pub struct PlanMetadata { - #[serde(skip)] stored_path: Option, update_url: Option, } -impl From for Option { - fn from(metadata: PlanMetadata) -> Self { - Some(serde_json::from_slice(&std::fs::read(metadata.stored_path?).ok()?).ok()?) +impl PlanMetadata { + pub fn set_stored_path(&mut self, file: Option) { + self.stored_path = file; } } impl Serialize for PlanMetadata { fn serialize(&self, serializer: S) -> Result where - S: serde::Serializer, + S: serde::Serializer, { - let mut state = serializer.serialize_struct("PlanMetadata", 2)?; - + let mut state = serializer.serialize_struct("PlanMetadata", 3)?; + state.serialize_field("update_url", &self.update_url)?; - + state.serialize_field("stored_path", &self.stored_path)?; + if let Some(path) = &self.stored_path { if let Some(name) = path.file_name() { - state.serialize_field("name", name)?; + state.serialize_field("name", &name.to_str())?; } } - + state.end() } } +impl From for Option { + fn from(metadata: PlanMetadata) -> Self { + Some(serde_json::from_slice(&std::fs::read(metadata.stored_path?).ok()?).ok()?) + } +} + impl Plan { - pub fn set_stored_path(&mut self, file: PathBuf) { - self.metadata.stored_path = Some(file); + pub fn set_stored_path(&mut self, file: Option) { + self.metadata.stored_path = file; } } diff --git a/src-tauri/src/storage.rs b/src-tauri/src/storage.rs index 6629595..f2f7e49 100644 --- a/src-tauri/src/storage.rs +++ b/src-tauri/src/storage.rs @@ -82,24 +82,26 @@ impl Storage { Ok(()) } - pub fn load_plan_at_path(path: PathBuf) -> Option { + pub fn load_plan_at_path(path: PathBuf, save_local: bool) -> Option { log::trace!("Loading plan: {path:?}"); let plan: Plan = match serde_json::from_str(&std::fs::read_to_string(&path).ok()?).ok() { Some(plan) => plan, None => convert_old(path.clone())?, }; - match Self::save_plan_at_store_path(path.file_name()?.to_str()?, plan.clone()) { - Ok(_) => (), - Err(_e) => { - log::error!("Could not save plan at store path during load"); - }, + if save_local { + match Self::save_plan_at_store_path(path.file_name()?.to_str()?, plan.clone()) { + Ok(_) => (), + Err(_e) => { + log::error!("Could not save plan at store path during load"); + } + } } - + Some(plan) } - pub fn save_plan_at_store_path(file_name: &str, mut plan: Plan) -> Result<(), Box> { + pub fn save_plan_at_store_path(file_name: &str, plan: Plan) -> Result<(), Box> { let plan_dir = match Self::plan_dir() { Some(dir) => dir, None => return Err("No plan dir".into()), @@ -112,7 +114,8 @@ impl Storage { return Err("File already exists".into()); } - plan.set_stored_path(file_path.clone()); + //TODO: Determine necessity + // plan.set_stored_path(file_path.clone()); std::fs::write(file_path, serde_json::to_string(&plan)?)?; @@ -162,6 +165,9 @@ impl Storage { } fn load_metadata_at_path(path: PathBuf) -> Option { - serde_json::from_str(&std::fs::read_to_string(&path).ok()?).ok() + let mut plan: PlanMetadata = + serde_json::from_str(&std::fs::read_to_string(&path).ok()?).ok()?; + plan.set_stored_path(Some(path)); + Some(plan) } } diff --git a/src/app/_models/plan.ts b/src/app/_models/plan.ts index ecd6a0a..96df7a9 100644 --- a/src/app/_models/plan.ts +++ b/src/app/_models/plan.ts @@ -10,7 +10,9 @@ export interface PlanInterface { } export interface PlanMetadata { - + stored_path?: string; + update_url?: string; + name: string; } export class Plan { @@ -56,7 +58,6 @@ export class Plan { } private directSelfSave() { - console.log("Underlying save"); invoke('save_plan', { plan: { plan: this.plan, diff --git a/src/app/_services/config.service.ts b/src/app/_services/config.service.ts index c341df4..55e64ff 100644 --- a/src/app/_services/config.service.ts +++ b/src/app/_services/config.service.ts @@ -65,7 +65,7 @@ export class ConfigService { } private underlyingSync() { - invoke('set_config', { config: this.config }); + invoke('update_config', { config: this.config }); } } diff --git a/src/app/_services/plan.service.ts b/src/app/_services/plan.service.ts index 6e88371..460d016 100644 --- a/src/app/_services/plan.service.ts +++ b/src/app/_services/plan.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { invoke } from '@tauri-apps/api'; import { Observable, ReplaySubject, Subject, from, map, switchMap, tap } from 'rxjs'; -import { Plan, PlanInterface } from '../_models/plan'; +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'; @@ -30,16 +30,12 @@ export class PlanService { this._currentPlanSubject.next(plan); } - public enumerateStoredPlans(): Observable { - return from(invoke('enumerate_stored_plans')); + public enumerateStoredPlans(): Observable { + return from(invoke('enumerate_stored_plans')); } - public getPathFromKnownName(name: string): Observable { - return from(invoke('path_from_name', { name })); - } - - public loadPlanFromPath(path: string): Observable { - return from(invoke('load_plan_at_path', { path })); + public loadPlanFromPath(path: string, save_local: boolean = true): Observable { + return from(invoke('load_plan_at_path', { path, save_local })).pipe(map(plan => {return new Plan(plan)})); } public loadFromUrl(url?: string, name?: string): Observable { @@ -65,7 +61,7 @@ export class PlanService { } public savePlanAtPath(path: string, plan: Plan) { - invoke('save_plan_at_path', { path, plan: plan }); + return from(invoke('save_plan_at_path', { path, plan: plan })); } private _loadFromUrl(url: string, name: string): Observable { diff --git a/src/app/editor/editor.component.html b/src/app/editor/editor.component.html index 29b5f9e..6e6d48d 100644 --- a/src/app/editor/editor.component.html +++ b/src/app/editor/editor.component.html @@ -86,7 +86,7 @@
+
-
Place at end of list diff --git a/src/app/editor/editor.component.ts b/src/app/editor/editor.component.ts index 2756e69..d8da817 100644 --- a/src/app/editor/editor.component.ts +++ b/src/app/editor/editor.component.ts @@ -124,7 +124,7 @@ export class EditorComponent implements OnInit { const bounds = this.planElemFilterBounds(); let index = event.currentIndex; - if(bounds) { + if (bounds) { index += bounds[0]; } this.planInEditing.plan.splice(index, 0, this.planItemFromArea(event.previousContainer.data[event.previousIndex])); @@ -195,15 +195,13 @@ export class EditorComponent implements OnInit { } planElemFilterBounds() { - if(this.planFilterAct.value !== 0) { + if (this.planFilterAct.value !== 0) { let bounds = this.planInEditing.plan.filter(item => item.anchor_act === this.planFilterAct.value || this.planFilterAct.value + 1 === item.anchor_act).map((value) => this.planIndexOf(value)); - console.log("bounds, ", bounds); if (bounds.length == 2) { return bounds; } - if(bounds.length == 1 && this.planFilterAct.value == 10) { - console.log("Setting bound to last index"); + if (bounds.length == 1 && this.planFilterAct.value == 10) { bounds[1] = this.planInEditing.plan.length; return bounds; } @@ -268,7 +266,7 @@ export class EditorComponent implements OnInit { }] })).subscribe(file => { if (file) { - this.planService.savePlan(file as string, this.planInEditing); + this.planService.savePlanAtPath(file, this.planInEditing).subscribe(); } }); } @@ -284,7 +282,8 @@ export class EditorComponent implements OnInit { ] })).subscribe(file => { if (file) { - this.planService.loadPlanNoSave(file as string).subscribe(plan => { + // We disallow multiple but interface still says it can be multiple, thus the cast. + this.planService.loadPlanFromPath(file as string, false).subscribe(plan => { this.planInEditing.plan.length = 0; plan.plan.forEach(p => this.planInEditing.plan.push(p)); }); @@ -293,7 +292,7 @@ export class EditorComponent implements OnInit { } loadBasePlan() { - this.planService.loadBasePlan().subscribe(plan => { + this.planService.getBasePlan().subscribe(plan => { this.planInEditing.plan.length = 0; plan.plan.forEach(p => this.planInEditing.plan.push(p)); }) diff --git a/src/app/models/generated/Config.ts b/src/app/models/generated/Config.ts deleted file mode 100644 index ed73fc2..0000000 --- a/src/app/models/generated/Config.ts +++ /dev/null @@ -1,4 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -import type { Rect } from "./Rect"; - -export interface Config { initialPlanWindowPosition: Rect, hideOnUnfocus: boolean, toggleOverlay: string, prev: string, next: string, planBg: string, backdropBg: string, noteDefaultFg: string, poeClientLogPath: string | null, } \ No newline at end of file diff --git a/src/app/models/generated/Rect.ts b/src/app/models/generated/Rect.ts deleted file mode 100644 index 0bfe163..0000000 --- a/src/app/models/generated/Rect.ts +++ /dev/null @@ -1,3 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. - -export interface Rect { x: number, y: number, width: number, height: number, } \ No newline at end of file diff --git a/src/app/plan-display/plan-display.component.html b/src/app/plan-display/plan-display.component.html index b263aa3..fa5d828 100644 --- a/src/app/plan-display/plan-display.component.html +++ b/src/app/plan-display/plan-display.component.html @@ -1,18 +1,18 @@
- +
- - +
+ [style.border]="index == currentPlan.current ? '1px white solid' : 'none'"> {{worldAreaMap!.get(slide.area_key)!.name}} @@ -23,7 +23,7 @@
- @@ -57,7 +57,7 @@
@@ -82,9 +82,9 @@
- @@ -94,7 +94,7 @@
-
diff --git a/src/app/plan-display/plan-display.component.ts b/src/app/plan-display/plan-display.component.ts index 7778ec8..65eb321 100644 --- a/src/app/plan-display/plan-display.component.ts +++ b/src/app/plan-display/plan-display.component.ts @@ -6,15 +6,14 @@ import { Rect } from '../_models/generated/Rect'; import { ShortcutService } from '../_services/shortcut.service'; import { CarouselComponent } from '../carousel/carousel.component'; import { PlanService } from '../_services/plan.service'; -import { Plan, PlanElement } from '../_models/plan'; +import { Plan, PlanElement, PlanMetadata } from '../_models/plan'; import { WorldAreaService } from '../_services/world-area.service'; import { WorldArea } from '../_models/world-area'; -import { Observable, Subscription, from } from 'rxjs'; +import { Subscription, from } from 'rxjs'; import { open } from '@tauri-apps/api/dialog'; import { OverlayService, StateEvent } from '../_services/overlay.service'; import { appWindow } from '@tauri-apps/api/window'; import { EventsService } from '../_services/events.service'; -import { UnlistenFn } from '@tauri-apps/api/event'; import { Event } from '@tauri-apps/api/event'; @Component({ @@ -43,6 +42,9 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit { nextBind?: Subscription; prevBind?: Subscription; + currentPlan?: Plan; + previousPlans: PlanMetadata[] = []; + constructor(private events: EventsService, public configService: ConfigService, private cdr: ChangeDetectorRef, private shortcut: ShortcutService, public planService: PlanService, public worldAreaService: WorldAreaService, public overlayService: OverlayService, private zone: NgZone) { window.addEventListener("resize", () => { this.zone.run(() => { @@ -50,21 +52,32 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit { }) }); + + this.planService.enumerateStoredPlans().subscribe(plans => { + this.previousPlans = plans; + }) + + this.planService.getCurrentPlan().subscribe(plan => { + this.currentPlan = plan; + setTimeout(() => this.setIndex(plan.current), 0); + }) + } + + registerOnZoneEnter() { appWindow.listen("entered", (entered) => { - if (this.planService.currentPlan) { - const current = this.planService.currentPlan.current; - const length = this.planService.currentPlan.plan.length; + if (this.currentPlan) { + const current = this.currentPlan.current; + const length = this.currentPlan.plan.length; if (current + 1 < length) { - if (entered.payload === this.planService.currentPlan.plan[current + 1].area_key) { + if (entered.payload === this.currentPlan.plan[current + 1].area_key) { this.zone.run(() => this.next()); } } } }); - - this.planService.getPreviousPlans(); } + windowInitHandler() { if (window.innerWidth > 0) { this.ngAfterViewInit(); @@ -110,7 +123,7 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit { hasWaypoint(key?: string): boolean { if (!key) { - key = this.planService.currentPlan!.plan[this.planService.currentPlan!.current].area_key; + key = this.currentPlan!.plan[this.currentPlan!.current].area_key; } const world_area = this.worldAreaMap?.get(key); return world_area!.has_waypoint; @@ -118,7 +131,7 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit { hasTrial(key?: string): boolean { if (!key) { - key = this.planService.currentPlan!.plan[this.planService.currentPlan!.current].area_key; + key = this.currentPlan!.plan[this.currentPlan!.current].area_key; } return this.worldAreaService.hasTrial(key); @@ -192,7 +205,7 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit { next() { if (this.overlayService.visible) { - this.planService.currentPlan!.next(); + this.currentPlan!.next(); this.currentSlides?.next(); this.zoneSlides?.next(); } @@ -200,7 +213,7 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit { prev() { if (this.overlayService.visible) { - this.planService.currentPlan!.prev(); + this.currentPlan!.prev(); this.currentSlides?.prev(); this.zoneSlides?.prev(); } @@ -216,9 +229,9 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit { } } - setPrevious(plan: string) { - this.planService.loadPrevious(plan).subscribe(plan => { - setTimeout(() => this.setIndex(plan.current), 0); + loadPrevious(path: string) { + this.planService.loadPlanFromPath(path, false).subscribe(plan => { + this.planService.setCurrentPlan(plan); }); } @@ -238,7 +251,7 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit { ] })).subscribe(file => { if (file) { - this.planService.loadPlan(file as string).subscribe(plan => { + this.planService.loadPlanFromPath(file as string).subscribe(plan => { if (plan) { this.settingsOpen = false; } @@ -248,8 +261,8 @@ export class PlanDisplayComponent implements AfterViewInit, OnInit { } loadBasePlan() { - this.planService.loadBasePlan().subscribe(plan => { - this.planService.currentPlan = new Plan(plan); + this.planService.getBasePlan().subscribe(plan => { + this.currentPlan = new Plan(plan); if (this.zoneSlides) { this.zoneSlides.setIndex(0); }