Files
hikari-desktop/src/lib/components/InputBar.svelte
T
naomi fa04d066e5
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 52s
CI / Lint & Test (pull_request) Failing after 7m33s
CI / Build Linux (pull_request) Has been skipped
CI / Build Windows (cross-compile) (pull_request) Has been skipped
feat: add notification sounds
2026-01-19 15:24:20 -08:00

79 lines
2.5 KiB
Svelte

<script lang="ts">
import { invoke } from "@tauri-apps/api/core";
import { claudeStore } from "$lib/stores/claude";
import { characterState } from "$lib/stores/character";
import { handleNewUserMessage } from "$lib/notifications/rules";
let inputValue = $state("");
let isSubmitting = $state(false);
let isConnected = $state(false);
claudeStore.connectionStatus.subscribe((status) => {
isConnected = status === "connected";
});
async function handleSubmit(event: Event) {
event.preventDefault();
const message = inputValue.trim();
if (!message || isSubmitting || !isConnected) return;
isSubmitting = true;
inputValue = "";
// Reset notification state for new user message
handleNewUserMessage();
claudeStore.addLine("user", message);
characterState.setState("thinking");
try {
await invoke("send_prompt", { message });
} catch (error) {
console.error("Failed to send prompt:", error);
claudeStore.addLine("error", `Failed to send: ${error}`);
characterState.setTemporaryState("error", 3000);
} finally {
isSubmitting = false;
}
}
function handleKeyDown(event: KeyboardEvent) {
if (event.key === "Enter" && !event.shiftKey) {
handleSubmit(event);
}
}
</script>
<form onsubmit={handleSubmit} class="input-bar flex gap-3 items-end">
<div class="flex-1 relative">
<textarea
bind:value={inputValue}
onkeydown={handleKeyDown}
placeholder={isConnected ? "Ask Hikari anything..." : "Connect to Claude first..."}
disabled={!isConnected || isSubmitting}
rows={1}
class="w-full px-4 py-3 bg-[var(--bg-secondary)] border border-[var(--border-color)]
rounded-lg text-white placeholder-gray-500 resize-none
focus:outline-none focus:border-[var(--accent-primary)] focus:ring-1 focus:ring-[var(--accent-primary)]
disabled:opacity-50 disabled:cursor-not-allowed
transition-all duration-200"
></textarea>
</div>
<button
type="submit"
disabled={!isConnected || isSubmitting || !inputValue.trim()}
class="px-6 py-3 bg-[var(--accent-primary)] hover:bg-[var(--accent-secondary)]
text-white font-medium rounded-lg
disabled:opacity-50 disabled:cursor-not-allowed
transition-all duration-200 transform hover:scale-105 active:scale-95"
>
{#if isSubmitting}
<span class="inline-block animate-spin"></span>
{:else}
Send
{/if}
</button>
</form>