Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src-tauri/capabilities/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"windows": ["main"],
"permissions": [
"core:default",
"core:webview:allow-set-webview-zoom",
"core:window:allow-start-dragging",
"core:window:allow-minimize",
"core:window:allow-toggle-maximize",
Expand Down
5 changes: 4 additions & 1 deletion src/lib/components/layout/header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@

<header
data-tauri-drag-region
class={['z-500 flex h-10 w-full flex-row items-center gap-8 border-b border-theme/5 bg-background px-1.5', customTitlebar ? 'pl-3' : 'pl-20']}>
class={[
'z-500 flex w-full flex-row items-center gap-8 border-b border-theme/5 bg-background px-1.5',
customTitlebar ? 'h-10 pl-3' : 'h-[max(2.5rem,calc(40px/var(--ui-zoom,1)))] pl-[calc(80px/var(--ui-zoom,1))]'
]}>
{@render left?.()}

<div class="ml-auto flex flex-row items-center gap-4">
Expand Down
2 changes: 1 addition & 1 deletion src/lib/modules/form/ui/password_input.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<button
type="button"
tabindex={-1}
class="absolute top-1/2 right-1 -translate-y-1/2 text-neutral-500 hover:text-neutral-800"
class="absolute top-1/2 right-1 flex -translate-y-1/2 text-neutral-500 hover:text-neutral-800"
title={visible ? 'Hide password' : 'Show password'}
onclick={() => (visible = !visible)}>
{#if visible}
Expand Down
30 changes: 27 additions & 3 deletions src/lib/modules/settings/stores.svelte.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { browser } from '$app/environment';
import { isEnabled } from '@tauri-apps/plugin-autostart';
import { getCurrentWebview } from '@tauri-apps/api/webview';

const KEY = 'app:settings';

Expand All @@ -13,6 +14,7 @@ interface Stored {
confirmOverwriteChanges: boolean;
keepRunningOnDisconnect: boolean;
pipelineSampleRate: number;
uiScale: number;
}

const DEFAULTS: Stored = {
Expand All @@ -24,11 +26,15 @@ const DEFAULTS: Stored = {
launchOnStartup: false,
confirmOverwriteChanges: true,
keepRunningOnDisconnect: true,
pipelineSampleRate: 48_000
pipelineSampleRate: 48_000,
uiScale: 100
};

export const SNAPSHOT_LIMITS = [10, 20, 50, 100] as const;
export const GRID_SIZES = [10, 20, 40] as const;
export const UI_SCALE_MIN = 50;
export const UI_SCALE_MAX = 200;
export const UI_SCALE_STEP = 10;
export const PIPELINE_SAMPLE_RATE_PRESETS = [44100, 48000, 88200, 96000, 176400, 192000] as const;

function load(): Stored {
Expand All @@ -51,6 +57,7 @@ class AppSettings {
confirmOverwriteChanges = $state(this.#initial.confirmOverwriteChanges);
keepRunningOnDisconnect = $state(this.#initial.keepRunningOnDisconnect);
pipelineSampleRate = $state(this.#initial.pipelineSampleRate ?? 48_000);
uiScale = $state(this.#initial.uiScale ?? 100);

persist(): void {
if (!browser) return;
Expand All @@ -63,7 +70,8 @@ class AppSettings {
launchOnStartup,
confirmOverwriteChanges,
keepRunningOnDisconnect,
pipelineSampleRate
pipelineSampleRate,
uiScale
} = this;
window.localStorage.setItem(
KEY,
Expand All @@ -76,14 +84,30 @@ class AppSettings {
launchOnStartup,
confirmOverwriteChanges,
keepRunningOnDisconnect,
pipelineSampleRate
pipelineSampleRate,
uiScale
})
);
}

reset(): void {
Object.assign(this, DEFAULTS);
this.persist();
this.applyUiScale();
}

setUiScale(percent: number): void {
this.uiScale = Math.min(Math.max(Math.round(percent), UI_SCALE_MIN), UI_SCALE_MAX);
this.persist();
this.applyUiScale();
}

applyUiScale(): void {
if (!browser) return;
document.documentElement.style.setProperty('--ui-zoom', String(this.uiScale / 100));
getCurrentWebview()
.setZoom(this.uiScale / 100)
.catch(() => {});
}

/** Reconciles the mirror from the plugin's real OS registration state,
Expand Down
1 change: 1 addition & 0 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@

onMount(async () => {
logStore.installConsoleCapture();
appSettings.applyUiScale();
window.addEventListener('keydown', onLogsHotkey);
await installErrorHandlers().catch(() => {});
loadAppInfo().catch(() => {});
Expand Down
29 changes: 28 additions & 1 deletion src/routes/settings/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@
import EdgeShapeIcon from '$lib/modules/flow/ui/_edge_shape_icon.svelte';
import Toggle from '$lib/components/toggle.svelte';
import { themeStore, type ThemePref } from '$lib/modules/theme/stores';
import { appSettings, GRID_SIZES, SNAPSHOT_LIMITS, PIPELINE_SAMPLE_RATE_PRESETS } from '$lib/modules/settings/stores.svelte';
import {
appSettings,
UI_SCALE_MIN,
UI_SCALE_MAX,
UI_SCALE_STEP,
GRID_SIZES,
SNAPSHOT_LIMITS,
PIPELINE_SAMPLE_RATE_PRESETS
} from '$lib/modules/settings/stores.svelte';
import NumberStepper from '$lib/components/number_stepper.svelte';
import { formatHz } from '$lib/components/format';
import PresetsSection from './_presets_section.svelte';
Expand Down Expand Up @@ -106,6 +114,25 @@
</button>
{/each}
</div>

<div class="flex items-center gap-2">
<span class="text-xs text-neutral-900">Interface scale</span>
<NumberStepper
value={appSettings.uiScale}
min={UI_SCALE_MIN}
max={UI_SCALE_MAX}
step={UI_SCALE_STEP}
label="Interface scale"
onchange={(v) => appSettings.setUiScale(v)} />
<span class="font-mono text-xs text-neutral-800 tabular-nums">%</span>
<button
type="button"
disabled={appSettings.uiScale === 100}
onclick={() => appSettings.setUiScale(100)}
class="rounded-lg border border-neutral-400 bg-neutral-100 px-3 py-1 text-[11px] font-medium text-neutral-1000 transition-colors hover:bg-neutral-200 disabled:opacity-40">
Reset
</button>
</div>
</section>

<section class="flex flex-col gap-3">
Expand Down
Loading