Sync progress circle
This commit is contained in:
parent
604329b02a
commit
a2bba5a7ab
@ -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<FeatherProps>;
|
||||
@ -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<void>;
|
||||
completer: (context: CompletionContext) => Promise<CompletionResult | null>;
|
||||
actionButtons: ActionButton[];
|
||||
@ -119,20 +122,34 @@ export function TopBar({
|
||||
</div>
|
||||
)}
|
||||
<div className="sb-actions">
|
||||
{actionButtons.map((actionButton) => {
|
||||
const button =
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
actionButton.callback();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
title={actionButton.description}
|
||||
{progressPerc !== undefined &&
|
||||
(
|
||||
<div className="progress-wrapper" title={`${progressPerc}%`}>
|
||||
<div
|
||||
className="progress-bar"
|
||||
style={`background: radial-gradient(closest-side, white 79%, transparent 80% 100%), conic-gradient(#282828 ${progressPerc}%, #adadad 0);`}
|
||||
>
|
||||
<actionButton.icon size={18} />
|
||||
</button>
|
||||
{progressPerc}%
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{actionButtons.map((actionButton) => {
|
||||
const button = (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
actionButton.callback();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
title={actionButton.description}
|
||||
>
|
||||
<actionButton.icon size={18} />
|
||||
</button>
|
||||
);
|
||||
|
||||
return actionButton.href !== undefined ? (<a href={actionButton.href}>{button}</a>) : button;
|
||||
return actionButton.href !== undefined
|
||||
? <a href={actionButton.href}>{button}</a>
|
||||
: button;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -202,7 +202,7 @@ export class Editor {
|
||||
const runtimeConfig = window.silverBulletConfig;
|
||||
|
||||
// Instantiate a PlugOS system
|
||||
const system = new System<SilverBulletHooks>();
|
||||
const system = new System<SilverBulletHooks>("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) {
|
||||
|
@ -176,6 +176,11 @@ export default function reducer(
|
||||
[action.key]: action.value,
|
||||
},
|
||||
};
|
||||
case "set-progress":
|
||||
return {
|
||||
...state,
|
||||
progressPerc: action.progressPerc,
|
||||
};
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -104,8 +104,8 @@ export class SyncService {
|
||||
}
|
||||
|
||||
async registerSyncProgress(status?: SyncStatus): Promise<void> {
|
||||
// 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);
|
||||
|
@ -52,6 +52,7 @@ export type AppViewState = {
|
||||
showCommandPaletteContext?: string;
|
||||
unsavedChanges: boolean;
|
||||
synced: boolean;
|
||||
progressPerc?: number;
|
||||
panels: { [key: string]: PanelConfig };
|
||||
allPages: PageMeta[];
|
||||
commands: Map<string, AppCommand>;
|
||||
@ -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 };
|
||||
|
Loading…
Reference in New Issue
Block a user