generated from nhcarrigan/template
feat: add auto-update checker
Implements issue #17 - the app now checks for updates on startup and shows a notification when a newer version is available. Users can disable this in settings. Uses Gitea releases API with semver comparison. Closes #17
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
notifications_enabled: true,
|
||||
notification_volume: 0.7,
|
||||
always_on_top: false,
|
||||
update_checks_enabled: true,
|
||||
});
|
||||
|
||||
let isOpen = $state(false);
|
||||
@@ -427,6 +428,21 @@
|
||||
Keep the window above other windows
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Update Checks Toggle -->
|
||||
<div class="mb-4">
|
||||
<label class="flex items-center gap-3 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={config.update_checks_enabled}
|
||||
class="w-4 h-4 text-[var(--accent-primary)] bg-[var(--bg-primary)] border-[var(--border-color)] rounded focus:ring-[var(--accent-primary)] focus:ring-2"
|
||||
/>
|
||||
<span class="text-sm text-[var(--text-primary)]">Check for updates on startup</span>
|
||||
</label>
|
||||
<p class="text-xs text-[var(--text-tertiary)] mt-1 ml-7">
|
||||
Notify when a new version is available
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Notifications Section -->
|
||||
|
||||
@@ -365,11 +365,7 @@ User: ${formattedMessage}`;
|
||||
onSelect={selectCommand}
|
||||
/>
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<div
|
||||
class="resize-handle"
|
||||
onmousedown={handleResizeStart}
|
||||
title="Drag to resize"
|
||||
></div>
|
||||
<div class="resize-handle" onmousedown={handleResizeStart} title="Drag to resize"></div>
|
||||
<textarea
|
||||
bind:value={inputValue}
|
||||
onkeydown={handleKeyDown}
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
notifications_enabled: true,
|
||||
notification_volume: 0.5,
|
||||
always_on_top: false,
|
||||
update_checks_enabled: true,
|
||||
});
|
||||
|
||||
onMount(async () => {
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
<script lang="ts">
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { openUrl } from "@tauri-apps/plugin-opener";
|
||||
import type { UpdateInfo } from "$lib/types/messages";
|
||||
import { configStore } from "$lib/stores/config";
|
||||
|
||||
let updateInfo = $state<UpdateInfo | null>(null);
|
||||
let dismissed = $state(false);
|
||||
|
||||
export async function checkForUpdates() {
|
||||
// Check if update checks are enabled
|
||||
const config = configStore.getConfig();
|
||||
if (!config.update_checks_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const info = await invoke<UpdateInfo>("check_for_updates");
|
||||
if (info.has_update) {
|
||||
updateInfo = info;
|
||||
dismissed = false;
|
||||
}
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : String(err);
|
||||
console.error("Failed to check for updates:", errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function dismiss() {
|
||||
dismissed = true;
|
||||
}
|
||||
|
||||
async function openRelease() {
|
||||
if (updateInfo?.release_url) {
|
||||
await openUrl(updateInfo.release_url);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if updateInfo && !dismissed}
|
||||
<div
|
||||
class="fixed bottom-4 right-4 max-w-sm bg-[var(--bg-tertiary)] border border-[var(--accent-primary)] rounded-lg shadow-lg p-4 z-50"
|
||||
>
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="text-2xl">🎉</div>
|
||||
<div class="flex-1">
|
||||
<h3 class="text-[var(--text-primary)] font-semibold mb-1">Update Available!</h3>
|
||||
<p class="text-[var(--text-secondary)] text-sm mb-2">
|
||||
A new version of Hikari Desktop is available:
|
||||
<span class="text-[var(--accent-primary)] font-mono">{updateInfo.latest_version}</span>
|
||||
</p>
|
||||
<p class="text-[var(--text-muted)] text-xs mb-3">
|
||||
Current version: {updateInfo.current_version}
|
||||
</p>
|
||||
<div class="flex gap-2">
|
||||
<button
|
||||
onclick={openRelease}
|
||||
class="px-3 py-1.5 bg-[var(--accent-primary)] text-white rounded text-sm hover:brightness-110 transition-all"
|
||||
>
|
||||
View Release
|
||||
</button>
|
||||
<button
|
||||
onclick={dismiss}
|
||||
class="px-3 py-1.5 bg-[var(--bg-secondary)] text-[var(--text-secondary)] rounded text-sm hover:bg-[var(--bg-primary)] transition-all"
|
||||
>
|
||||
Later
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onclick={dismiss}
|
||||
class="text-[var(--text-muted)] hover:text-[var(--text-primary)] transition-colors"
|
||||
aria-label="Dismiss"
|
||||
>
|
||||
<svg
|
||||
class="w-4 h-4"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M6 18L18 6M6 6l12 12"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
Reference in New Issue
Block a user