This commit is contained in:
Kelorastus
2026-09-28 11:19:02 +02:00
parent 21d6e6bffb
commit 73a8f2c30c
35 changed files with 1615 additions and 86 deletions
+70
View File
@@ -62,6 +62,10 @@
return { label: "Restoring database", tone: "accent", pulse: true, meta: stage };
case "syncing":
return { label: "Syncing with the DHP", tone: "accent", pulse: true, meta: version(s?.installed) };
case "pulling_tiles":
return { label: "Taking map tiles", tone: "accent", pulse: true, meta: tileMeta };
case "removing":
return { label: "Removing", tone: "accent", pulse: true, meta: rp ? `${rp.index}/${rp.count}` : null };
case "update":
return { label: "Update required", tone: "warn", pulse: false, meta: `${s?.installed} → ${s?.available}` };
case "launch":
@@ -76,6 +80,29 @@
}
});
// What the DHP has baked, for the sets this PC holds, since it last looked. Zero means
// level with the site - which is worth saying nothing at all about.
// Chosen, and not all here. ODIAN runs without it, so this is said beside Launch rather
// than in place of it - but it IS said: the marketplace was the only place that knew.
const unfinished = $derived(s?.unfinished ?? null);
const unfinishedNames = $derived.by(() => {
const titles = unfinished?.titles ?? [];
if (titles.length === 0) return "";
const shown = titles.slice(0, 2).join(", ");
return (unfinished?.items ?? 0) > titles.length || titles.length > 2 ? `${shown}…` : shown;
});
const tiles = $derived(s?.tiles_waiting ?? null);
const tilesOffered = $derived(tiles !== null && tiles.tiles > 0);
const tilesCount = $derived(tiles === null ? "" : `${formatCount(tiles.tiles)}${tiles.more ? "+" : ""}`);
const rp = $derived(launcher.removeProgress);
const removeFraction = $derived(rp === null || rp.total === 0 ? null : Math.min(rp.done / rp.total, 1));
const tp = $derived(launcher.tileProgress);
const tileMeta = $derived(tp === null ? null : `${formatCount(tp.tiles)} tiles`);
const tileFraction = $derived(tp === null || tp.page_tiles === 0 ? null : tp.page_done / tp.page_tiles);
const showNotice = $derived(launcher.notice !== null && !(action === "error" && launcher.notice === s?.error));
</script>
@@ -182,6 +209,29 @@
<button class="btn-link" disabled={blocked} onclick={() => launcher.openSync()}>Sync</button>
</p>
{/if}
{#if unfinished}
<p class="secondary attention">
<Icon name="alert" size={14} />
<span>
<strong>{unfinished.items}</strong>
{unfinished.items === 1 ? "chosen map is" : "chosen maps are"} only partly downloaded
{#if unfinishedNames}<span class="dim">({unfinishedNames})</span>{/if}.
<button class="btn-link" disabled={blocked} onclick={() => launcher.finishMarket()}>Finish</button>
</span>
</p>
{/if}
{#if tilesOffered}
<!-- Ground another operator looked at while this PC was away. Online it is already
on screen, drawn from {site}; nothing keeps it, so unplugging loses a week of
other people's map. -->
<p class="secondary attention">
<Icon name="download" size={14} />
<span>
<strong>{tilesCount}</strong> new map tiles on {site} ({formatBytes(tiles?.bytes ?? 0)}).
<button class="btn-link" disabled={blocked} onclick={() => launcher.syncTiles()}>Take them</button>
</span>
</p>
{/if}
{:else if action === "installing"}
<div class="progress">
<div class="stage-line">
@@ -236,6 +286,26 @@
<ProgressBar value={null} label="Syncing with the DHP" />
</div>
<p class="secondary">Sending this PC's changes to {site} and taking in the other operators' work.</p>
{:else if action === "removing"}
<div class="progress">
<div class="stage-line">
<span class="stage-name">Removing {rp?.title ?? "what you unticked"}</span>
{#if removeFraction !== null}<span class="pct mono tabular">{Math.floor(removeFraction * 100)}%</span>{/if}
</div>
<ProgressBar value={removeFraction} label="Removing" />
{#if rp}<p class="message mono">{formatCount(rp.done)} / {formatCount(rp.total)} files</p>{/if}
</div>
<p class="secondary">Deleting a map is hundreds of thousands of files. Nothing is downloaded meanwhile.</p>
{:else if action === "pulling_tiles"}
<div class="progress">
<div class="stage-line">
<span class="stage-name">Taking map tiles from {site}</span>
{#if tp}<span class="pct mono tabular">{formatBytes(tp.bytes)}</span>{/if}
</div>
<ProgressBar value={tileFraction} label="Taking map tiles" />
</div>
<p class="secondary">Tiles the other operators baked while this PC was away. It can be stopped and resumed.</p>
<button class="btn wide" onclick={() => launcher.cancelInstall()}>Stop</button>
{:else if action === "stack"}
<StackList stack={launcher.stack} phase={s?.phase ?? "launching"} />
{#if s?.map_from_site === false}