generated from nhcarrigan/template
feat: toggle window always on top
This commit is contained in:
@@ -55,6 +55,9 @@ pub struct HikariConfig {
|
|||||||
|
|
||||||
#[serde(default = "default_notification_volume")]
|
#[serde(default = "default_notification_volume")]
|
||||||
pub notification_volume: f32,
|
pub notification_volume: f32,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub always_on_top: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for HikariConfig {
|
impl Default for HikariConfig {
|
||||||
@@ -70,6 +73,7 @@ impl Default for HikariConfig {
|
|||||||
greeting_custom_prompt: None,
|
greeting_custom_prompt: None,
|
||||||
notifications_enabled: true,
|
notifications_enabled: true,
|
||||||
notification_volume: 0.7,
|
notification_volume: 0.7,
|
||||||
|
always_on_top: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,6 +113,7 @@ mod tests {
|
|||||||
assert_eq!(config.theme, Theme::Dark);
|
assert_eq!(config.theme, Theme::Dark);
|
||||||
assert!(config.greeting_enabled);
|
assert!(config.greeting_enabled);
|
||||||
assert!(config.greeting_custom_prompt.is_none());
|
assert!(config.greeting_custom_prompt.is_none());
|
||||||
|
assert!(!config.always_on_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -124,6 +129,7 @@ mod tests {
|
|||||||
greeting_custom_prompt: Some("Hello!".to_string()),
|
greeting_custom_prompt: Some("Hello!".to_string()),
|
||||||
notifications_enabled: true,
|
notifications_enabled: true,
|
||||||
notification_volume: 0.7,
|
notification_volume: 0.7,
|
||||||
|
always_on_top: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let json = serde_json::to_string(&config).unwrap();
|
let json = serde_json::to_string(&config).unwrap();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { configStore, type HikariConfig, type Theme } from "$lib/stores/config";
|
import { configStore, type HikariConfig, type Theme } from "$lib/stores/config";
|
||||||
import { claudeStore } from "$lib/stores/claude";
|
import { claudeStore } from "$lib/stores/claude";
|
||||||
|
import { getCurrentWindow } from "@tauri-apps/api/window";
|
||||||
|
|
||||||
let config: HikariConfig = $state({
|
let config: HikariConfig = $state({
|
||||||
model: null,
|
model: null,
|
||||||
@@ -13,6 +14,7 @@
|
|||||||
greeting_custom_prompt: null,
|
greeting_custom_prompt: null,
|
||||||
notifications_enabled: true,
|
notifications_enabled: true,
|
||||||
notification_volume: 0.7,
|
notification_volume: 0.7,
|
||||||
|
always_on_top: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
let isOpen = $state(false);
|
let isOpen = $state(false);
|
||||||
@@ -95,6 +97,13 @@
|
|||||||
function importFromSession() {
|
function importFromSession() {
|
||||||
config.auto_granted_tools = [...new Set([...config.auto_granted_tools, ...grantedTools])];
|
config.auto_granted_tools = [...new Set([...config.auto_granted_tools, ...grantedTools])];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleAlwaysOnTopChange(enabled: boolean) {
|
||||||
|
config.always_on_top = enabled;
|
||||||
|
const window = getCurrentWindow();
|
||||||
|
await window.setAlwaysOnTop(enabled);
|
||||||
|
await configStore.updateConfig({ always_on_top: enabled });
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Backdrop -->
|
<!-- Backdrop -->
|
||||||
@@ -396,6 +405,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- Window Section -->
|
||||||
|
<section class="mb-6">
|
||||||
|
<h3 class="text-sm font-medium text-[var(--accent-primary)] uppercase tracking-wider mb-3">
|
||||||
|
Window
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<!-- Always on Top Toggle -->
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="flex items-center gap-3 cursor-pointer">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={config.always_on_top}
|
||||||
|
onchange={(e) => handleAlwaysOnTopChange(e.currentTarget.checked)}
|
||||||
|
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-gray-300">Always on top</span>
|
||||||
|
</label>
|
||||||
|
<p class="text-xs text-gray-500 mt-1 ml-7">Keep the window above other windows</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- Notifications Section -->
|
<!-- Notifications Section -->
|
||||||
<section class="mb-6">
|
<section class="mb-6">
|
||||||
<h3 class="text-sm font-medium text-[var(--accent-primary)] uppercase tracking-wider mb-3">
|
<h3 class="text-sm font-medium text-[var(--accent-primary)] uppercase tracking-wider mb-3">
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
greeting_custom_prompt: null,
|
greeting_custom_prompt: null,
|
||||||
notifications_enabled: true,
|
notifications_enabled: true,
|
||||||
notification_volume: 0.5,
|
notification_volume: 0.5,
|
||||||
|
always_on_top: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export interface HikariConfig {
|
|||||||
greeting_custom_prompt: string | null;
|
greeting_custom_prompt: string | null;
|
||||||
notifications_enabled: boolean;
|
notifications_enabled: boolean;
|
||||||
notification_volume: number;
|
notification_volume: number;
|
||||||
|
always_on_top: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultConfig: HikariConfig = {
|
const defaultConfig: HikariConfig = {
|
||||||
@@ -27,6 +28,7 @@ const defaultConfig: HikariConfig = {
|
|||||||
greeting_custom_prompt: null,
|
greeting_custom_prompt: null,
|
||||||
notifications_enabled: true,
|
notifications_enabled: true,
|
||||||
notification_volume: 0.7,
|
notification_volume: 0.7,
|
||||||
|
always_on_top: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
function createConfigStore() {
|
function createConfigStore() {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
import { configStore, applyTheme } from "$lib/stores/config";
|
import { configStore, applyTheme } from "$lib/stores/config";
|
||||||
import { initNotificationSync, cleanupNotificationSync } from "$lib/stores/notifications";
|
import { initNotificationSync, cleanupNotificationSync } from "$lib/stores/notifications";
|
||||||
import { conversationsStore } from "$lib/stores/conversations";
|
import { conversationsStore } from "$lib/stores/conversations";
|
||||||
|
import { getCurrentWindow } from "@tauri-apps/api/window";
|
||||||
import "$lib/notifications/testNotifications";
|
import "$lib/notifications/testNotifications";
|
||||||
import Terminal from "$lib/components/Terminal.svelte";
|
import Terminal from "$lib/components/Terminal.svelte";
|
||||||
import InputBar from "$lib/components/InputBar.svelte";
|
import InputBar from "$lib/components/InputBar.svelte";
|
||||||
@@ -27,10 +28,16 @@
|
|||||||
await initializeTauriListeners();
|
await initializeTauriListeners();
|
||||||
await configStore.loadConfig();
|
await configStore.loadConfig();
|
||||||
|
|
||||||
// Apply saved theme on startup
|
// Apply saved settings on startup
|
||||||
const config = configStore.getConfig();
|
const config = configStore.getConfig();
|
||||||
applyTheme(config.theme);
|
applyTheme(config.theme);
|
||||||
|
|
||||||
|
// Apply always-on-top setting
|
||||||
|
if (config.always_on_top) {
|
||||||
|
const window = getCurrentWindow();
|
||||||
|
await window.setAlwaysOnTop(true);
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize notification settings sync
|
// Initialize notification settings sync
|
||||||
initNotificationSync();
|
initNotificationSync();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user