feat: add help panel

This commit is contained in:
2026-01-20 16:29:57 -08:00
parent 7aec0c1287
commit c37c530f89
2 changed files with 175 additions and 0 deletions
+155
View File
@@ -0,0 +1,155 @@
<script lang="ts">
interface Props {
onClose: () => void;
}
const { onClose }: Props = $props();
const sections = [
{
title: "Getting Started",
items: [
"Enter your Claude API key in Settings (gear icon)",
"Set your working directory and click Connect",
"Start chatting with Hikari - your AI assistant!"
]
},
{
title: "Key Features",
items: [
"๐Ÿ—‚๏ธ File Management: Hikari can read, write, and edit files in your project",
"๐Ÿ’ป Terminal Access: Execute commands and run scripts",
"๐Ÿ” Code Search: Find files and search through code",
"๐ŸŒ Web Access: Fetch information from the web",
"๐Ÿ“Š MCP Servers: Connect to external tools via Model Context Protocol",
"๐Ÿ“ Multi-tab Support: Work on multiple conversations simultaneously"
]
},
{
title: "Available Commands",
items: [
"Type naturally - Hikari understands context!",
"Ask to read, create, or modify files",
"Request code explanations or debugging help",
"Have Hikari run tests or build commands",
"Search for specific functions or patterns"
]
},
{
title: "Tips & Tricks",
items: [
"๐Ÿ’ก Use the stats panel to track your usage",
"๐ŸŽฏ Be specific about file paths and requirements",
"๐Ÿ”’ Grant tool permissions as needed for security",
"๐Ÿ“Œ Pin important conversations for quick access",
"๐ŸŽจ Customize your theme and preferences in Settings"
]
},
{
title: "Keyboard Shortcuts",
items: [
"Ctrl/Cmd + Enter: Send message",
"Ctrl/Cmd + K: Clear chat (when supported)",
"Escape: Close modals and panels"
]
}
];
</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-2xl w-full max-h-[80vh] overflow-hidden flex flex-col"
onclick={(e) => e.stopPropagation()}
role="dialog"
aria-labelledby="help-title"
>
<div class="flex items-center justify-between p-6 pb-4 border-b border-[var(--border-color)]">
<h2 id="help-title" class="text-xl font-semibold text-gray-100">
How to Use 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="overflow-y-auto flex-1 p-6 space-y-6">
{#each sections as section}
<div>
<h3 class="font-medium text-gray-200 mb-3">{section.title}</h3>
<ul class="space-y-2 text-sm text-gray-400">
{#each section.items as item}
<li class="flex items-start">
<span class="text-[var(--accent-primary)] mr-2 mt-0.5">โ€ข</span>
<span>{item}</span>
</li>
{/each}
</ul>
</div>
{/each}
<div class="pt-4 border-t border-[var(--border-color)]">
<p class="text-sm text-gray-500">
<strong>Need more help?</strong> Join our Discord community for support and updates!
</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) translateY(10px);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
}
/* Custom scrollbar styling */
.overflow-y-auto {
scrollbar-width: thin;
scrollbar-color: var(--border-color) transparent;
}
.overflow-y-auto::-webkit-scrollbar {
width: 8px;
}
.overflow-y-auto::-webkit-scrollbar-track {
background: transparent;
}
.overflow-y-auto::-webkit-scrollbar-thumb {
background-color: var(--border-color);
border-radius: 4px;
}
.overflow-y-auto::-webkit-scrollbar-thumb:hover {
background-color: var(--accent-primary);
}
</style>
+20
View File
@@ -16,6 +16,7 @@
import { onMount } from "svelte"; import { onMount } from "svelte";
import StatsDisplay from "./StatsDisplay.svelte"; import StatsDisplay from "./StatsDisplay.svelte";
import AboutPanel from "./AboutPanel.svelte"; import AboutPanel from "./AboutPanel.svelte";
import HelpPanel from "./HelpPanel.svelte";
import { achievementProgress } from "$lib/stores/achievements"; import { achievementProgress } from "$lib/stores/achievements";
const DISCORD_URL = "https://chat.nhcarrigan.com"; const DISCORD_URL = "https://chat.nhcarrigan.com";
@@ -29,6 +30,7 @@
let appVersion = $state(""); let appVersion = $state("");
let showStats = $state(false); let showStats = $state(false);
let showAbout = $state(false); let showAbout = $state(false);
let showHelp = $state(false);
const progress = $derived($achievementProgress); const progress = $derived($achievementProgress);
let currentConfig: HikariConfig = $state({ let currentConfig: HikariConfig = $state({
model: null, model: null,
@@ -269,6 +271,20 @@
/> />
</svg> </svg>
</button> </button>
<button
onclick={() => (showHelp = true)}
class="p-1 text-gray-500 hover:text-[var(--accent-primary)] transition-colors"
title="Help"
>
<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="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</button>
<button <button
onclick={() => openUrl(DISCORD_URL)} onclick={() => openUrl(DISCORD_URL)}
class="p-1 text-gray-500 hover:text-[var(--accent-primary)] transition-colors" class="p-1 text-gray-500 hover:text-[var(--accent-primary)] transition-colors"
@@ -320,3 +336,7 @@
{#if showAbout} {#if showAbout}
<AboutPanel onClose={() => (showAbout = false)} /> <AboutPanel onClose={() => (showAbout = false)} />
{/if} {/if}
{#if showHelp}
<HelpPanel onClose={() => (showHelp = false)} />
{/if}