feat: add about panel

This commit is contained in:
2026-01-20 14:29:10 -08:00
parent 8aa4116063
commit 7aec0c1287
2 changed files with 166 additions and 0 deletions
+146
View File
@@ -0,0 +1,146 @@
<script lang="ts">
import { openUrl } from "@tauri-apps/plugin-opener";
import { getVersion } from "@tauri-apps/api/app";
import { onMount } from "svelte";
interface Props {
onClose: () => void;
}
const { onClose }: Props = $props();
let appVersion = $state("");
onMount(async () => {
appVersion = await getVersion();
});
const links = {
source: "https://git.nhcarrigan.com/nhcarrigan/hikari-desktop",
discord: "https://chat.nhcarrigan.com",
website: "https://nhcarrigan.com",
license: "https://docs.nhcarrigan.com/legal/license/",
};
</script>
<div
class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4"
onclick={onClose}
role="button"
tabindex="0"
onkeydown={(e) => e.key === "Escape" && onClose()}
>
<div
class="bg-[var(--bg-primary)] border border-[var(--border-color)] rounded-lg shadow-xl max-w-md w-full p-6"
onclick={(e) => e.stopPropagation()}
role="dialog"
aria-labelledby="about-title"
>
<div class="flex items-center justify-between mb-4">
<h2 id="about-title" class="text-xl font-semibold text-gray-100">
About Hikari Desktop
</h2>
<button
onclick={onClose}
class="p-1 text-gray-500 hover:text-gray-300 transition-colors"
aria-label="Close"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
<div class="space-y-4 text-sm">
<div>
<h3 class="font-medium text-gray-200 mb-2">What is Hikari Desktop?</h3>
<p class="text-gray-400">
Hikari Desktop is an AI-powered desktop assistant that brings Claude directly to your desktop.
Built with love using Tauri, Svelte, and Rust for a fast, native experience.
</p>
</div>
<div>
<h3 class="font-medium text-gray-200 mb-2">Version</h3>
<p class="text-gray-400">
{appVersion || "Loading..."}
</p>
</div>
<div>
<h3 class="font-medium text-gray-200 mb-2">Source Code</h3>
<button
onclick={() => openUrl(links.source)}
class="text-[var(--accent-primary)] hover:text-[var(--accent-primary-hover)] transition-colors underline"
>
View on Git
</button>
</div>
<div>
<h3 class="font-medium text-gray-200 mb-2">Support & Community</h3>
<p class="text-gray-400 mb-1">
Found a bug or have a suggestion?
</p>
<button
onclick={() => openUrl(links.discord)}
class="text-[var(--accent-primary)] hover:text-[var(--accent-primary-hover)] transition-colors underline"
>
Join our Discord
</button>
</div>
<div>
<h3 class="font-medium text-gray-200 mb-2">Built with 💕 by</h3>
<button
onclick={() => openUrl(links.website)}
class="text-[var(--accent-primary)] hover:text-[var(--accent-primary-hover)] transition-colors underline"
>
Naomi Carrigan
</button>
</div>
<div>
<h3 class="font-medium text-gray-200 mb-2">License</h3>
<p class="text-gray-400 mb-1">
This project is open source and available under our license terms.
</p>
<button
onclick={() => openUrl(links.license)}
class="text-[var(--accent-primary)] hover:text-[var(--accent-primary-hover)] transition-colors underline"
>
View License
</button>
</div>
<div class="pt-4 mt-4 border-t border-[var(--border-color)]">
<p class="text-xs text-gray-500 text-center">
Copyright © {new Date().getFullYear()} Naomi Carrigan. All rights reserved.
</p>
</div>
</div>
</div>
</div>
<style>
/* Ensure the panel appears above other content */
[role="dialog"] {
animation: slideIn 0.2s ease-out;
}
@keyframes slideIn {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
</style>
+20
View File
@@ -15,6 +15,7 @@
import type { ConnectionStatus } from "$lib/types/messages";
import { onMount } from "svelte";
import StatsDisplay from "./StatsDisplay.svelte";
import AboutPanel from "./AboutPanel.svelte";
import { achievementProgress } from "$lib/stores/achievements";
const DISCORD_URL = "https://chat.nhcarrigan.com";
@@ -27,6 +28,7 @@
let grantedToolsList: string[] = $state([]);
let appVersion = $state("");
let showStats = $state(false);
let showAbout = $state(false);
const progress = $derived($achievementProgress);
let currentConfig: HikariConfig = $state({
model: null,
@@ -253,6 +255,20 @@
/>
</svg>
</button>
<button
onclick={() => (showAbout = true)}
class="p-1 text-gray-500 hover:text-[var(--accent-primary)] transition-colors"
title="About Hikari Desktop"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</button>
<button
onclick={() => openUrl(DISCORD_URL)}
class="p-1 text-gray-500 hover:text-[var(--accent-primary)] transition-colors"
@@ -300,3 +316,7 @@
<StatsDisplay />
</div>
{/if}
{#if showAbout}
<AboutPanel onClose={() => (showAbout = false)} />
{/if}