From 0902aa339b5e05a63fb1a02b7c60756b321fffdc Mon Sep 17 00:00:00 2001 From: Christopher Serr Date: Wed, 5 Jun 2024 00:37:19 +0200 Subject: [PATCH] Add indicators for unsaved changes (#912) This adds indicators to various parts of the UI to indicate that there are unsaved changes. The indicators are mainly shown as white dots in the sidebar highlighting what is unsaved. The title is also updated to reflect this. The Badging API is also used to show a badge on the "app icon" if it's installed as a PWA. In addition to the splits, the layouts are also now properly tracked when it comes to unsaved changes. Changelog: There are now indicators in the user interface that remind you about unsaved changes to your splits and layouts. --- src/css/Sidebar.scss | 6 ++++ src/ui/LSOEventSink.ts | 5 +++ src/ui/LayoutView.tsx | 8 +++++ src/ui/LiveSplit.tsx | 67 +++++++++++++++++++++++++++++--------- src/ui/SplitsSelection.tsx | 5 +++ src/ui/TimerView.tsx | 10 ++++++ 6 files changed, 85 insertions(+), 16 deletions(-) diff --git a/src/css/Sidebar.scss b/src/css/Sidebar.scss index 79b788d..cd8fcf2 100644 --- a/src/css/Sidebar.scss +++ b/src/css/Sidebar.scss @@ -67,6 +67,12 @@ $h2-font-size: 22px; } } } + + .modified-icon { + position: absolute; + font-size: 10px; + padding-left: 5px; + } } .choose-comparison { diff --git a/src/ui/LSOEventSink.ts b/src/ui/LSOEventSink.ts index b565755..adb11aa 100644 --- a/src/ui/LSOEventSink.ts +++ b/src/ui/LSOEventSink.ts @@ -11,6 +11,7 @@ export class LSOEventSink { private currentPhaseChanged: () => void, private currentSplitChanged: () => void, private comparisonListChanged: () => void, + private splitsModifiedChanged: () => void, private onReset: () => void, ) { this.eventSink = new EventSink(new WebEventSink(this).intoGeneric()); @@ -30,6 +31,7 @@ export class LSOEventSink { this.currentPhaseChanged(); this.currentSplitChanged(); + this.splitsModifiedChanged(); } public split(): void { @@ -44,6 +46,7 @@ export class LSOEventSink { this.currentPhaseChanged(); this.currentSplitChanged(); + this.splitsModifiedChanged(); } public reset(): void { @@ -167,6 +170,7 @@ export class LSOEventSink { this.currentPhaseChanged(); this.currentSplitChanged(); this.comparisonListChanged(); + this.splitsModifiedChanged(); return result; } @@ -177,6 +181,7 @@ export class LSOEventSink { public markAsUnmodified(): void { this.timer.markAsUnmodified(); + this.splitsModifiedChanged(); } public getRun(): RunRef { diff --git a/src/ui/LayoutView.tsx b/src/ui/LayoutView.tsx index e1689e4..72813f7 100644 --- a/src/ui/LayoutView.tsx +++ b/src/ui/LayoutView.tsx @@ -27,6 +27,8 @@ export interface Props { currentPhase: TimerPhase, currentSplitIndex: number, allComparisons: string[], + splitsModified: boolean, + layoutModified: boolean, } interface Callbacks { @@ -69,6 +71,8 @@ export class LayoutView extends React.Component { currentPhase={this.props.currentPhase} currentSplitIndex={this.props.currentSplitIndex} allComparisons={this.props.allComparisons} + splitsModified={this.props.splitsModified} + layoutModified={this.props.layoutModified} />; const sidebarContent = this.renderSidebarContent(); return this.props.callbacks.renderViewWithSidebar(renderedView, sidebarContent); @@ -84,6 +88,10 @@ export class LayoutView extends React.Component {