From a2bba5a7abd248eaa9edce8cabfd046becd6b2d8 Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Wed, 14 Jun 2023 20:58:08 +0200 Subject: [PATCH] Sync progress circle --- web/components/top_bar.tsx | 41 +++++++++++++++++++++++++++----------- web/editor.tsx | 34 +++++++++++++++++++++++-------- web/reducer.ts | 5 +++++ web/styles/main.scss | 23 +++++++++++++++++++++ web/sync_service.ts | 4 ++-- web/types.ts | 4 +++- 6 files changed, 88 insertions(+), 23 deletions(-) diff --git a/web/components/top_bar.tsx b/web/components/top_bar.tsx index f38a9e3..a7c8c34 100644 --- a/web/components/top_bar.tsx +++ b/web/components/top_bar.tsx @@ -8,6 +8,7 @@ import type { ComponentChildren, FunctionalComponent } from "../deps.ts"; import { Notification } from "../types.ts"; import { FeatherProps } from "https://esm.sh/v99/preact-feather@4.2.1/dist/types"; import { MiniEditor } from "./mini_editor.tsx"; +import process from "https://deno.land/std@0.177.1/node/process.ts"; export type ActionButton = { icon: FunctionalComponent; @@ -26,6 +27,7 @@ export function TopBar({ actionButtons, darkMode, vimMode, + progressPerc, completer, lhs, rhs, @@ -37,6 +39,7 @@ export function TopBar({ notifications: Notification[]; darkMode: boolean; vimMode: boolean; + progressPerc?: number; onRename: (newName?: string) => Promise; completer: (context: CompletionContext) => Promise; actionButtons: ActionButton[]; @@ -119,20 +122,34 @@ export function TopBar({ )}
- {actionButtons.map((actionButton) => { - const button = - + {progressPerc}% +
+ + )} + {actionButtons.map((actionButton) => { + const button = ( + + ); - return actionButton.href !== undefined ? ({button}) : button; + return actionButton.href !== undefined + ? {button} + : button; })} diff --git a/web/editor.tsx b/web/editor.tsx index 3eddcba..db9083f 100644 --- a/web/editor.tsx +++ b/web/editor.tsx @@ -202,7 +202,7 @@ export class Editor { const runtimeConfig = window.silverBulletConfig; // Instantiate a PlugOS system - const system = new System(); + const system = new System("client"); this.system = system; // Generate a semi-unique prefix for the database so not to reuse databases for different space paths @@ -499,7 +499,8 @@ export class Editor { this.dispatchAppEvent("editor:pageLoaded", this.currentPage); if (operations) { // Likely initial sync so let's show visually that we're synced now - this.flashNotification(`Synced ${operations} files`, "info"); + // this.flashNotification(`Synced ${operations} files`, "info"); + this.showProgress(100); } } // Reset for next sync cycle @@ -517,12 +518,8 @@ export class Editor { ); }); this.eventHook.addLocalListener("sync:progress", (status: SyncStatus) => { - this.flashNotification( - `Sync: ${ - Math.round(status.filesProcessed / status.totalFiles * 10000) / - 100 - }% — processed ${status.filesProcessed} out of ${status.totalFiles}`, - "info", + this.showProgress( + Math.round(status.filesProcessed / status.totalFiles * 100), ); }); @@ -616,6 +613,26 @@ export class Editor { ); } + progressTimeout?: number; + + showProgress(progressPerc: number) { + this.viewDispatch({ + type: "set-progress", + progressPerc, + }); + if (this.progressTimeout) { + clearTimeout(this.progressTimeout); + } + this.progressTimeout = setTimeout( + () => { + this.viewDispatch({ + type: "set-progress", + }); + }, + 10000, + ); + } + filterBox( label: string, options: FilterOption[], @@ -1417,6 +1434,7 @@ export class Editor { isLoading={viewState.isLoading} vimMode={viewState.uiOptions.vimMode} darkMode={viewState.uiOptions.darkMode} + progressPerc={viewState.progressPerc} completer={editor.miniEditorComplete.bind(editor)} onRename={async (newName) => { if (!newName) { diff --git a/web/reducer.ts b/web/reducer.ts index 9901a79..0794f7c 100644 --- a/web/reducer.ts +++ b/web/reducer.ts @@ -176,6 +176,11 @@ export default function reducer( [action.key]: action.value, }, }; + case "set-progress": + return { + ...state, + progressPerc: action.progressPerc, + }; } return state; } diff --git a/web/styles/main.scss b/web/styles/main.scss index 2928e68..c4c4952 100644 --- a/web/styles/main.scss +++ b/web/styles/main.scss @@ -115,6 +115,29 @@ body { right: 15px; top: 0; } + + .progress-wrapper { + display: inline-block; + position: relative; + top: -6px; + padding-right: 6px; + } + + .progress-bar { + display: flex; + justify-content: center; + align-items: center; + + width: 20px; + height: 20px; + border-radius: 50%; + font-size: 6px; + + } + + // .progress-bar::before { + // content: "66%"; + // } } .sb-panel { diff --git a/web/sync_service.ts b/web/sync_service.ts index 6ae7a48..d555bf3 100644 --- a/web/sync_service.ts +++ b/web/sync_service.ts @@ -104,8 +104,8 @@ export class SyncService { } async registerSyncProgress(status?: SyncStatus): Promise { - // Emit a sync event at most every 10s - if (status && this.lastReportedSyncStatus < Date.now() - 10000) { + // Emit a sync event at most every 2s + if (status && this.lastReportedSyncStatus < Date.now() - 2000) { this.eventHook.dispatchEvent("sync:progress", status); this.lastReportedSyncStatus = Date.now(); await this.saveSnapshot(status.snapshot); diff --git a/web/types.ts b/web/types.ts index 762c572..e4592de 100644 --- a/web/types.ts +++ b/web/types.ts @@ -52,6 +52,7 @@ export type AppViewState = { showCommandPaletteContext?: string; unsavedChanges: boolean; synced: boolean; + progressPerc?: number; panels: { [key: string]: PanelConfig }; allPages: PageMeta[]; commands: Map; @@ -162,4 +163,5 @@ export type Action = callback: (value: boolean) => void; } | { type: "hide-confirm" } - | { type: "set-ui-option"; key: string; value: any }; + | { type: "set-ui-option"; key: string; value: any } + | { type: "set-progress"; progressPerc?: number };