generated from nhcarrigan/template
feat: naomi did too much at once (#53)
- feat: add slash commands - feat: toggle window always on top - fix: save settings button closes settings panel - feat: input history (both text and commands) - feat: add keyboard shortcuts - feat: add confirmation modal when closing connected tabs - fix: better text colours in light mode - fix: handle multiple tabs requesting permission Closes #6 Closes #13 Closes #21 Closes #28 Reviewed-on: #53 Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com> Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>
This commit was merged in pull request #53.
This commit is contained in:
+76
-1
@@ -1,9 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy } from "svelte";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { get } from "svelte/store";
|
||||
import { initializeTauriListeners, cleanupTauriListeners } from "$lib/tauri";
|
||||
import { configStore, applyTheme } from "$lib/stores/config";
|
||||
import { initNotificationSync, cleanupNotificationSync } from "$lib/stores/notifications";
|
||||
import { conversationsStore } from "$lib/stores/conversations";
|
||||
import { claudeStore, isClaudeProcessing } from "$lib/stores/claude";
|
||||
import { getCurrentWindow } from "@tauri-apps/api/window";
|
||||
import "$lib/notifications/testNotifications";
|
||||
import Terminal from "$lib/components/Terminal.svelte";
|
||||
import InputBar from "$lib/components/InputBar.svelte";
|
||||
@@ -17,6 +21,67 @@
|
||||
let initialized = false;
|
||||
let achievementPanelOpen = $state(false);
|
||||
|
||||
// Global keyboard shortcuts
|
||||
function handleGlobalKeydown(event: KeyboardEvent) {
|
||||
// Don't trigger shortcuts when typing in inputs (except for specific ones)
|
||||
const target = event.target as HTMLElement;
|
||||
const isInputFocused = target.tagName === "INPUT" || target.tagName === "TEXTAREA";
|
||||
|
||||
// Escape closes panels (always works)
|
||||
if (event.key === "Escape") {
|
||||
// Check if any panels are open and close them
|
||||
if (achievementPanelOpen) {
|
||||
achievementPanelOpen = false;
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
// ConfigSidebar handles its own escape via store
|
||||
if (get(configStore.isSidebarOpen)) {
|
||||
configStore.closeSidebar();
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip other shortcuts if user is typing in an input
|
||||
if (isInputFocused) return;
|
||||
|
||||
// Ctrl+L - Clear terminal
|
||||
if (event.ctrlKey && event.key === "l") {
|
||||
event.preventDefault();
|
||||
claudeStore.clearTerminal();
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+, - Open settings
|
||||
if (event.ctrlKey && event.key === ",") {
|
||||
event.preventDefault();
|
||||
configStore.openSidebar();
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+C - Interrupt (only when processing)
|
||||
if (event.ctrlKey && event.key === "c") {
|
||||
if (get(isClaudeProcessing)) {
|
||||
event.preventDefault();
|
||||
handleInterrupt();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function handleInterrupt() {
|
||||
try {
|
||||
const conversationId = get(claudeStore.activeConversationId);
|
||||
if (!conversationId) return;
|
||||
|
||||
await invoke("interrupt_claude", { conversationId });
|
||||
claudeStore.addLine("system", "Process interrupted");
|
||||
} catch (error) {
|
||||
console.error("Failed to interrupt:", error);
|
||||
}
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
@@ -27,12 +92,21 @@
|
||||
await initializeTauriListeners();
|
||||
await configStore.loadConfig();
|
||||
|
||||
// Apply saved theme on startup
|
||||
// Apply saved settings on startup
|
||||
const config = configStore.getConfig();
|
||||
applyTheme(config.theme);
|
||||
|
||||
// Apply always-on-top setting
|
||||
if (config.always_on_top) {
|
||||
const window = getCurrentWindow();
|
||||
await window.setAlwaysOnTop(true);
|
||||
}
|
||||
|
||||
// Initialize notification settings sync
|
||||
initNotificationSync();
|
||||
|
||||
// Add global keyboard shortcut listener
|
||||
window.addEventListener("keydown", handleGlobalKeydown);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -40,6 +114,7 @@
|
||||
if (initialized) {
|
||||
cleanupTauriListeners();
|
||||
cleanupNotificationSync();
|
||||
window.removeEventListener("keydown", handleGlobalKeydown);
|
||||
initialized = false;
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user