From 5c2d03272fb45e20bbeaac1e91452e9b2fe7fd31 Mon Sep 17 00:00:00 2001 From: isark Date: Wed, 20 Mar 2024 22:01:19 +0100 Subject: [PATCH] Ability to detach notes. Generic "window" component since I'm now at 3 windows and it is getting cumbersome duplicating all that code all over the place. --- src-tauri/src/config.rs | 13 + src/app/_services/time-tracker.service.ts | 3 +- .../draggable-window.component.html | 15 + .../draggable-window.component.scss | 9 + .../draggable-window.component.spec.ts | 21 ++ .../draggable-window.component.ts | 88 ++++++ .../plan-display/plan-display.component.html | 267 +++++++++--------- .../plan-display/plan-display.component.scss | 10 +- .../plan-display/plan-display.component.ts | 143 +--------- src/app/plan-display/plan-display.module.ts | 6 +- src/app/settings/settings.component.html | 6 + 11 files changed, 309 insertions(+), 272 deletions(-) create mode 100644 src/app/draggable-window/draggable-window.component.html create mode 100644 src/app/draggable-window/draggable-window.component.scss create mode 100644 src/app/draggable-window/draggable-window.component.spec.ts create mode 100644 src/app/draggable-window/draggable-window.component.ts diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs index 7b6a233..facffa8 100644 --- a/src-tauri/src/config.rs +++ b/src-tauri/src/config.rs @@ -28,6 +28,8 @@ pub struct Config { pub initial_plan_window_position: Rect, #[serde(default = "Config::default_initial_agg_window_position")] pub initial_agg_window_position: Rect, + #[serde(default = "Config::default_initial_notes_window_position")] + pub initial_notes_window_position: Rect, #[serde(default = "Config::default_hide_on_unfocus")] pub hide_on_unfocus: bool, #[serde(default = "Config::default_toggle_overlay")] @@ -55,6 +57,8 @@ pub struct Config { #[serde(default = "Config::default_run_compare_history")] pub run_compare_history: Option, + #[serde(default = "Config::default_detach_notes")] + detach_notes: bool, #[serde(default = "Config::default_show_livesplit")] show_livesplit: bool, @@ -69,6 +73,7 @@ impl Default for Config { Self { initial_plan_window_position: Self::default_initial_plan_window_position(), initial_agg_window_position: Self::default_initial_agg_window_position(), + initial_notes_window_position: Self::default_initial_agg_window_position(), hide_on_unfocus: Self::default_hide_on_unfocus(), toggle_overlay: Self::default_toggle_overlay(), prev: Self::default_prev(), @@ -83,6 +88,7 @@ impl Default for Config { num_visible: Self::default_plan_num_visible(), offset: Self::default_plan_offset(), run_compare_history: Self::default_run_compare_history(), + detach_notes: Self::default_detach_notes(), enable_stopwatch: Self::default_enable_stopwatch(), show_livesplit: Self::default_show_livesplit(), show_live_aggregate: Self::default_show_live_aggregate(), @@ -100,6 +106,10 @@ impl Config { Default::default() } + fn default_initial_notes_window_position() -> Rect { + Default::default() + } + fn default_hide_on_unfocus() -> bool { true } @@ -159,4 +169,7 @@ impl Config { fn default_shorten_zone_names() -> bool { false } + fn default_detach_notes() -> bool { + false + } } diff --git a/src/app/_services/time-tracker.service.ts b/src/app/_services/time-tracker.service.ts index 527627e..f50d618 100644 --- a/src/app/_services/time-tracker.service.ts +++ b/src/app/_services/time-tracker.service.ts @@ -112,8 +112,9 @@ export class TimeTrackerService { this.currentRunHistory = history; this.newCurrentRunHistorySubject.next(history); } - + get elapsedTimeMillis() { + this.latest = new Date(); return this.latest!.valueOf() - this.start!.valueOf(); } diff --git a/src/app/draggable-window/draggable-window.component.html b/src/app/draggable-window/draggable-window.component.html new file mode 100644 index 0000000..0842cd5 --- /dev/null +++ b/src/app/draggable-window/draggable-window.component.html @@ -0,0 +1,15 @@ + + +
+ +
+ + + +
+
\ No newline at end of file diff --git a/src/app/draggable-window/draggable-window.component.scss b/src/app/draggable-window/draggable-window.component.scss new file mode 100644 index 0000000..aac874d --- /dev/null +++ b/src/app/draggable-window/draggable-window.component.scss @@ -0,0 +1,9 @@ +:host { + overflow: visible; +} + +.target { + position: absolute; + min-width: 50px; + min-height: 50px; +} \ No newline at end of file diff --git a/src/app/draggable-window/draggable-window.component.spec.ts b/src/app/draggable-window/draggable-window.component.spec.ts new file mode 100644 index 0000000..c27285f --- /dev/null +++ b/src/app/draggable-window/draggable-window.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DraggableWindowComponent } from './draggable-window.component'; + +describe('DraggableWindowComponent', () => { + let component: DraggableWindowComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [DraggableWindowComponent] + }); + fixture = TestBed.createComponent(DraggableWindowComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/draggable-window/draggable-window.component.ts b/src/app/draggable-window/draggable-window.component.ts new file mode 100644 index 0000000..fec3a39 --- /dev/null +++ b/src/app/draggable-window/draggable-window.component.ts @@ -0,0 +1,88 @@ +import { AfterViewInit, ChangeDetectorRef, Component, EventEmitter, Input, NgZone, OnInit, Output, ViewChild } from '@angular/core'; +import { Rect } from '../_models/generated/Rect'; +import { NgxMoveableComponent, NgxMoveableModule, OnDrag, OnDragEnd, OnResize, OnResizeEnd } from 'ngx-moveable'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-draggable-window', + templateUrl: './draggable-window.component.html', + styleUrls: ['./draggable-window.component.scss'], + standalone: true, + imports: [CommonModule, NgxMoveableModule] + +}) +export class DraggableWindowComponent implements AfterViewInit { + rect?: Rect; + bounds: any = { "left": 0, "top": 0, "right": 0, "bottom": 0, "position": "css" }; + @Input() public backgroundColor: string = "rgba(0, 0, 0, 0.1)"; + @Input() public configurable: boolean = true; + @Input() public initialRect?: Rect; + @Output() savedRect: EventEmitter = new EventEmitter(); + @ViewChild("moveable") moveable?: NgxMoveableComponent; + init = false; + + + constructor(private cdr: ChangeDetectorRef, private zone: NgZone) { + window.addEventListener("resize", () => { + this.zone.run(() => { + this.windowInitHandler() + }) + }); + } + + windowInitHandler() { + if (window.innerWidth > 0) { + const cfgRect = this.initialRect || { x: 0, y: 0, width: 0.1, height: 0.1 }; + + this.rect = { + x: cfgRect.x * window.innerWidth, + y: cfgRect.y * window.innerHeight, + width: cfgRect.width * window.innerWidth, + height: cfgRect.height * window.innerHeight, + } + + this.moveable?.updateRect(); + + setTimeout(() => this.cdr.detectChanges(), 0); + this.init = true; + } + } + + ngAfterViewInit(): void { + this.windowInitHandler(); + } + + transform() { + return `translate(${this.rect!.x}px, ${this.rect!.y}px)`; + } + + onDrag(e: OnDrag) { + this.rect!.x = e.translate[0]; + this.rect!.y = e.translate[1]; + } + + onDragEnd(_e: OnDragEnd) { + this.saveRect(); + } + + onResize(e: OnResize) { + this.rect!.width = e.width; + this.rect!.height = e.height; + this.onDrag(e.drag); + } + + onResizeEnd(_e: OnResizeEnd) { + this.saveRect(); + } + + saveRect() { + if (this.rect) { + this.savedRect.emit({ + x: this.rect.x / window.innerWidth, + y: this.rect.y / window.innerHeight, + width: this.rect.width / window.innerWidth, + height: this.rect.height / window.innerHeight, + }); + } + } +} diff --git a/src/app/plan-display/plan-display.component.html b/src/app/plan-display/plan-display.component.html index 6ac459b..71a2c10 100644 --- a/src/app/plan-display/plan-display.component.html +++ b/src/app/plan-display/plan-display.component.html @@ -1,154 +1,157 @@ - -
-
- -
-
- - - -
-
-
{{yourDiff(slide)}}
+
+
+ + +
+ + + +
+
+
{{yourDiff(slide)}}
+
-
{{displayZoneName(worldAreaMap!.get(slide.area_key)!.name)}} -
+
+ {{displayZoneName(worldAreaMap!.get(slide.area_key)!.name)}} +
-
-
- {{cpMillis(slide)}}
-
(W)
-
(T)
-
+
+
+ {{cpMillis(slide)}}
+
(W)
+
(T)
- - - - - - - - - +
+
+
+ + + + + + + -
- - -
- (W) = Waypoint - (T) = Trial - The plan window's will have a glow in the corresponding color(s) above to help indicate if - the - current zone has any of those. - You can scroll in the plan window (while it is in 'interactable' mode) to quickly switch - many - zones -
-
- {{timeTrackerService.hmsTimestamp(timeTrackerService.elapsedTimeMillis)}} -
+
+ + +
+ (W) = Waypoint + (T) = Trial + The plan window's will have a glow in the corresponding color(s) above to help + indicate if + the + current zone has any of those. + You can scroll in the plan window (while it is in 'interactable' mode) to quickly + switch + many + zones +
+
+ {{timeTrackerService.hmsTimestamp(timeTrackerService.elapsedTimeMillis)}} + +
+ + + + isark + - + +
+ + + + + + +
- -
- -
- -
- - - -
-
+
- - -
-
-
-
-
- -
-
- -
-
- -
+ + + +
+
+
+
+
+
-
- - - - - - - - - +
+ +
+
+ +
+
+
+ + + + + + + + + -
- -
- + +
- - + +
+
+
+
+ Detach zones + +
+
Enable stopwatch