Add fixed-source client update detection
Client checks / checks (push) Canceled after 0s
Client dependency and security checks / audit (push) Canceled after 0s

This commit is contained in:
2026-10-25 06:34:37 +01:00
parent 8a3ac54204
commit 9cf297613d
2 changed files with 42 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
# Client updates
The Settings view checks the fixed stable release source for
`ReaperOfVeriod/trixy-linux-client` on Gitea. It compares the release tag with
the running client version and shows the release page when a newer version is
available.
Applying an update remains manual: review the release, download the x86-64
AppImage, replace the existing file, and restart it. The client never accepts
an arbitrary update URL, silently replaces itself, or stores credentials in the
update flow.
+31
View File
@@ -78,6 +78,9 @@
let connectionState = 'OFFLINE';
let serverVersion = '—';
let serverCompatibility = '';
let clientUpdateStatus = '';
let clientUpdateUrl = '';
let clientUpdateBusy = false;
let diagnostics: { status: string; database: string; twitch_identity_count: number; unseen_notification_count: number; realtime: string } | undefined;
let backups: Array<{ filename: string; size_bytes: number; modified_at: string | null }> = [];
let backupError = '';
@@ -227,6 +230,13 @@
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : undefined;
}
function isVersionNewer(candidate: string, current: string) {
const candidateParts = versionParts(candidate);
const currentParts = versionParts(current);
if (!candidateParts || !currentParts) return false;
return candidateParts.some((part, index) => part > currentParts[index] && candidateParts.slice(0, index).every((previous, previousIndex) => previous === currentParts[previousIndex]));
}
function isClientCompatible(minimum: string, maximum: string) {
const client = versionParts(CLIENT_VERSION);
const minimumParts = versionParts(minimum);
@@ -289,6 +299,24 @@
}
}
async function checkClientUpdate() {
clientUpdateBusy = true;
clientUpdateStatus = 'Checking fixed stable release source…';
try {
const response = await fetch('https://git.reaperofveriod.nl/api/v1/repos/ReaperOfVeriod/trixy-linux-client/releases/latest');
if (!response.ok) throw new Error('Release source unavailable.');
const release: { tag_name?: string; html_url?: string } = await response.json();
const latest = release.tag_name?.replace(/^v/, '') || '';
const current = CLIENT_VERSION.replace(/^v/, '');
clientUpdateUrl = release.html_url || 'https://git.reaperofveriod.nl/ReaperOfVeriod/trixy-linux-client/releases/latest';
clientUpdateStatus = latest && isVersionNewer(latest, current) ? `Update available: ${latest}` : `Up to date (${current})`;
} catch (error) {
clientUpdateStatus = error instanceof Error ? error.message : 'Release source unavailable.';
} finally {
clientUpdateBusy = false;
}
}
async function login() {
if (connectionState === 'INCOMPATIBLE') {
authError = 'This client version is not compatible with the server.';
@@ -1689,6 +1717,9 @@
</div>
</section>
{/if}
{#if authenticated && activeView === 'Settings'}
<section class="panel client-update-panel"><div class="panel-header"><span>CLIENT UPDATE</span><span class="micro">v{CLIENT_VERSION}</span></div><div class="settings-body"><p class="settings-note">Updates are manual. Check the fixed stable Gitea release source, review the release, then download and replace the AppImage yourself.</p><button class="secondary" onclick={checkClientUpdate} disabled={clientUpdateBusy}>{clientUpdateBusy ? 'CHECKING…' : 'CHECK FOR UPDATE'}</button>{#if clientUpdateStatus}<span class="settings-note">{clientUpdateStatus}</span>{/if}{#if clientUpdateUrl}<button class="secondary" onclick={() => window.open(clientUpdateUrl, '_blank', 'noopener,noreferrer')}>OPEN RELEASE PAGE</button>{/if}</div></section>
{/if}
</main>
{#if authenticated && sharedChatSession}
<section class="shared-chat-status-control" aria-label="Shared Chat details">