Release Healer Man 0.1.14

This commit is contained in:
phenom committed 2026-09-05 11:40:50 -04:00
1 parent 67d7a8ebe7
commit 7b41b102fa
147 files changed
+169892 -1342

No files matched your search

+19 -15
View File
@@ -3,7 +3,8 @@ import { useMemo } from "react";
import {
checkForContentUpdates,
contentPackHasUpdate,
contentPackIsUsable,
contentPackIsBundled,
contentPackIsInstalled,
installContentPack,
removeContentPack,
} from "../content/contentManager";
@@ -40,10 +41,10 @@ export function ContentManagerScreen({ onClose }: { readonly onClose: () => void
<p className="front-kicker">Local-first installation</p>
<h1>Choose what stays on this device</h1>
<p>
Installed adventures work without a server connection. Updates download to a temporary file,
Installed content packs work without a server connection. Updates download to a temporary staging area,
verify their SHA-256, and only then replace the active version.
</p>
{!native && <p className="front-notice">The browser build already includes its complete content catalog.</p>}
{!native && <p className="front-notice">Basic content is included. Optional packs can be downloaded for offline play and removed when you want the storage back.</p>}
<div className="content-manager-summary__actions">
<button type="button" className="front-button" disabled={state.checking} onClick={() => void checkForContentUpdates()}>
{state.checking ? "Checking..." : "Check for updates"}
@@ -61,8 +62,9 @@ export function ContentManagerScreen({ onClose }: { readonly onClose: () => void
<section className="content-manager-packs" aria-label="Content packs">
{packs.length === 0 && <p className="content-manager-empty">Connect once to discover optional downloads. Bundled starter content remains playable offline.</p>}
{packs.map((pack) => {
const installed = contentPackIsUsable(pack.id);
const installed = contentPackIsInstalled(pack.id);
const update = contentPackHasUpdate(pack.id);
const bundled = contentPackIsBundled(pack.id);
const busy = state.installingPackId !== null;
return (
<article key={pack.id} className="content-pack-row">
@@ -71,18 +73,20 @@ export function ContentManagerScreen({ onClose }: { readonly onClose: () => void
<small>{formatBytes(pack.bytes)} / {pack.fileCount} files</small>
</div>
<span className={installed ? "is-installed" : ""}>
{update ? "Update available" : installed ? "Installed — offline ready" : "Not installed"}
{update ? "Update available" : bundled ? "Included — always available" : installed ? "Installed — offline ready" : "Not installed"}
</span>
{native && (!installed || update) && (
<button type="button" className="front-button front-button--primary" disabled={busy} onClick={() => void installContentPack(pack.id).catch(() => undefined)}>
{state.installingPackId === pack.id ? "Downloading..." : update ? "Update" : "Download"}
</button>
)}
{native && installed && !pack.bundledOnAndroid && !update && (
<button type="button" className="front-button" disabled={busy} onClick={() => void removeContentPack(pack.id).catch(() => undefined)}>
Remove
</button>
)}
<div className="content-pack-row__actions">
{(!installed || update) && (
<button type="button" className="front-button front-button--primary" disabled={busy} onClick={() => void installContentPack(pack.id).catch(() => undefined)}>
{state.installingPackId === pack.id ? "Downloading..." : update ? "Update" : "Download"}
</button>
)}
{installed && !bundled && (
<button type="button" className="front-button" disabled={busy} onClick={() => void removeContentPack(pack.id).catch(() => undefined)}>
Remove
</button>
)}
</div>
</article>
);
})}