Chore: README Update

This commit is contained in:
Youwes09
2026-03-23 19:18:27 -05:00
parent 6d85be751a
commit b23292cff5
15 changed files with 218 additions and 55 deletions
+22 -3
View File
@@ -104,10 +104,29 @@
getVersion(),
invoke<Array<{ tag_name: string; html_url: string }>>("list_releases"),
]);
if (!releases.length) return;
const latestTag = releases[0].tag_name.replace(/^v/, "");
if (latestTag !== currentVersion) {
// Filter out drafts / incomplete releases that have no tag_name
const valid = releases.filter(r => typeof r.tag_name === "string" && r.tag_name.trim());
if (!valid.length) return;
const parse = (tag: string): number[] =>
tag.replace(/^v/, "").split(".").map(Number);
const compare = (a: number[], b: number[]): number => {
for (let i = 0; i < 3; i++) {
if ((a[i] ?? 0) !== (b[i] ?? 0)) return (b[i] ?? 0) - (a[i] ?? 0);
}
return 0;
};
const latestTag = valid
.map(r => r.tag_name)
.sort((a, b) => compare(parse(a), parse(b)))[0]
.replace(/^v/, "");
// Only toast if latest is strictly newer than installed
const isNewer = compare(parse(latestTag), parse(currentVersion)) < 0;
if (isNewer) {
addToast({
kind: "info",
title: `Update available — v${latestTag}`,
+38 -3
View File
@@ -336,16 +336,26 @@
let dlTotal = $state<number | null>(null);
let targetTag = $state<string | null>(null); // tag being installed
let releasesLoaded = false; // plain var — not $state, so effect doesn't re-run on change
$effect(() => {
if (tab !== "about") return;
getVersion().then(v => appVersion = v).catch(() => appVersion = "unknown");
if (releases.length === 0 && !releasesLoading) loadReleases();
if (!releasesLoaded) { releasesLoaded = true; loadReleases(); }
});
async function loadReleases() {
releasesLoading = true; releasesError = null;
try {
releases = await invoke<ReleaseInfo[]>("list_releases");
const timeout = new Promise<never>((_, reject) =>
setTimeout(() => reject(new Error("Request timed out after 10s")), 10_000)
);
const all = await Promise.race([
invoke<ReleaseInfo[]>("list_releases"),
timeout,
]);
// Filter out drafts / incomplete entries with no tag_name
releases = all.filter(r => typeof r.tag_name === "string" && r.tag_name.trim());
} catch (e: any) {
releasesError = e instanceof Error ? e.message : String(e);
} finally {
@@ -358,6 +368,25 @@
function isCurrentVersion(tag: string) { return stripV(tag) === appVersion; }
function parseSemver(v: string): number[] {
return stripV(v).split(".").map(Number);
}
function compareSemver(a: string, b: string): number {
const pa = parseSemver(a), pb = parseSemver(b);
for (let i = 0; i < 3; i++) {
if ((pa[i] ?? 0) !== (pb[i] ?? 0)) return (pb[i] ?? 0) - (pa[i] ?? 0);
}
return 0;
}
// True when releases are loaded and installed version is >= highest published tag
let onLatestVersion = $derived((() => {
if (releasesLoading || releases.length === 0 || !appVersion || appVersion === "…") return false;
const sorted = releases.slice().sort((a, b) => compareSemver(a.tag_name, b.tag_name));
return compareSemver(appVersion, sorted[0].tag_name) >= 0;
})());
function fmtDate(iso: string): string {
if (!iso) return "";
const d = new Date(iso);
@@ -1044,10 +1073,15 @@
<span class="toggle-desc">v{appVersion}</span>
</div>
<button class="step-btn" style="width:auto;padding:0 var(--sp-3);font-size:var(--text-xs);letter-spacing:var(--tracking-wide)"
onclick={loadReleases} disabled={releasesLoading}>
onclick={() => { releasesError = null; loadReleases(); }} disabled={releasesLoading}>
{releasesLoading ? "Loading…" : "Refresh"}
</button>
</div>
{#if onLatestVersion}
<div class="step-row">
<span class="toggle-desc" style="padding:0 var(--sp-3);color:var(--accent-fg)">✓ You're on the latest version.</span>
</div>
{/if}
<!-- active download progress -->
{#if updatePhase === "downloading" && IS_WINDOWS}
@@ -1157,6 +1191,7 @@
<p class="section-title">Links</p>
<div class="about-block">
<a href="https://github.com/Youwes09/Moku" target="_blank" class="about-line" style="color:var(--accent-fg);text-decoration:none">GitHub →</a>
<a href="https://discord.gg/cfncTbJ2" target="_blank" class="about-line" style="color:var(--accent-fg);text-decoration:none;margin-top:var(--sp-1)">Discord →</a>
</div>
</div>