M4
This commit is contained in:
@@ -4,6 +4,7 @@ import { backend } from "./backend";
|
||||
import { errorText, hostOf } from "./format";
|
||||
import { SIGN_IN_CANCELLED } from "./types";
|
||||
import type {
|
||||
ConflictChoice,
|
||||
InstallProgress,
|
||||
LogEvent,
|
||||
LogLevel,
|
||||
@@ -12,6 +13,7 @@ import type {
|
||||
StackComponent,
|
||||
StackEvent,
|
||||
Status,
|
||||
SyncConflict,
|
||||
Unlisten,
|
||||
} from "./types";
|
||||
|
||||
@@ -24,6 +26,7 @@ export type ActionKind =
|
||||
| "signed_out_offline"
|
||||
| "installing"
|
||||
| "restoring"
|
||||
| "syncing"
|
||||
| "update"
|
||||
| "launch"
|
||||
| "stack"
|
||||
@@ -45,6 +48,8 @@ export function deriveAction(s: Status | null): ActionKind {
|
||||
return "installing";
|
||||
case "restoring":
|
||||
return "restoring";
|
||||
case "syncing":
|
||||
return "syncing";
|
||||
case "launching":
|
||||
case "running":
|
||||
return "stack";
|
||||
@@ -75,6 +80,7 @@ const LOCKED_PHASES: ReadonlySet<Phase> = new Set([
|
||||
"signing_in",
|
||||
"installing",
|
||||
"restoring",
|
||||
"syncing",
|
||||
"launching",
|
||||
"running",
|
||||
]);
|
||||
@@ -104,6 +110,10 @@ class Launcher {
|
||||
busy = $state<string | null>(null);
|
||||
refreshing = $state(false);
|
||||
stopping = $state(false);
|
||||
/** The sync review panel. */
|
||||
syncOpen = $state(false);
|
||||
/** Decisions waiting in this PC's database; null until the panel loads them. */
|
||||
conflicts = $state<SyncConflict[] | null>(null);
|
||||
notes = $state<NotesState>({
|
||||
key: null,
|
||||
loading: false,
|
||||
@@ -117,6 +127,8 @@ class Launcher {
|
||||
/** Settings can't change while something is installing or running. */
|
||||
locked = $derived(this.status ? LOCKED_PHASES.has(this.status.phase) : false);
|
||||
siteName = $derived(this.status ? (this.status.site.name ?? hostOf(this.status.site.url)) : "");
|
||||
/** Conflicts plus refused edits from the last sync: what needs the operator. */
|
||||
syncAttention = $derived(this.status?.sync ? this.status.sync.conflicts + this.status.sync.rejected : 0);
|
||||
notesVersion = $derived(
|
||||
this.status ? (this.status.online ? (this.status.available ?? this.status.installed) : this.status.installed) : null,
|
||||
);
|
||||
@@ -339,6 +351,32 @@ class Launcher {
|
||||
});
|
||||
}
|
||||
|
||||
syncNow() {
|
||||
return this.run("sync", async () => {
|
||||
await backend.syncNow();
|
||||
// The panel lists what the sync just found (or settled).
|
||||
if (this.syncOpen) this.conflicts = await backend.getSyncConflicts();
|
||||
});
|
||||
}
|
||||
|
||||
/** Opens the review panel and loads what waits for a decision. */
|
||||
async openSync() {
|
||||
this.syncOpen = true;
|
||||
await this.run("conflicts", async () => {
|
||||
this.conflicts = await backend.getSyncConflicts();
|
||||
});
|
||||
}
|
||||
|
||||
closeSync() {
|
||||
this.syncOpen = false;
|
||||
}
|
||||
|
||||
resolveConflict(conflict: SyncConflict, choice: ConflictChoice, value?: unknown) {
|
||||
return this.run("resolve", async () => {
|
||||
this.conflicts = await backend.resolveSyncConflict(conflict.tbl, conflict.key, choice, value);
|
||||
});
|
||||
}
|
||||
|
||||
async pickFolder(): Promise<string | null> {
|
||||
try {
|
||||
return await backend.pickFolder();
|
||||
|
||||
Reference in New Issue
Block a user