mirror of
https://gitlab.com/ArkHost/HelixNotes.git
synced 2026-07-23 23:35:57 +02:00
Add Interface Scale setting to zoom the whole app (80-200%)
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
"windows": ["main"],
|
"windows": ["main"],
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"updater:default",
|
"updater:default",
|
||||||
"window-state:default"
|
"window-state:default",
|
||||||
|
"core:webview:allow-set-webview-zoom"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,6 +103,14 @@ pub fn set_line_height(state: State<'_, AppState>, height: f64) -> Result<(), St
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn set_ui_scale(state: State<'_, AppState>, scale: f64) -> Result<(), String> {
|
||||||
|
let mut config = state.config.lock().map_err(|e| e.to_string())?;
|
||||||
|
config.ui_scale = Some(scale);
|
||||||
|
save_app_config(&config)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// ── Notebooks ──
|
// ── Notebooks ──
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ pub fn run() {
|
|||||||
commands::set_font_size,
|
commands::set_font_size,
|
||||||
commands::set_font_family,
|
commands::set_font_family,
|
||||||
commands::set_line_height,
|
commands::set_line_height,
|
||||||
|
commands::set_ui_scale,
|
||||||
commands::get_notebooks,
|
commands::get_notebooks,
|
||||||
commands::count_root_notes,
|
commands::count_root_notes,
|
||||||
commands::create_notebook,
|
commands::create_notebook,
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ pub struct AppConfig {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub line_height: Option<f64>,
|
pub line_height: Option<f64>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
pub ui_scale: Option<f64>,
|
||||||
|
#[serde(default)]
|
||||||
pub compact_notes: bool,
|
pub compact_notes: bool,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub time_format: String,
|
pub time_format: String,
|
||||||
@@ -167,6 +169,7 @@ impl Default for AppConfig {
|
|||||||
font_size: None,
|
font_size: None,
|
||||||
font_family: None,
|
font_family: None,
|
||||||
line_height: None,
|
line_height: None,
|
||||||
|
ui_scale: None,
|
||||||
compact_notes: false,
|
compact_notes: false,
|
||||||
time_format: "relative".to_string(),
|
time_format: "relative".to_string(),
|
||||||
gpu_acceleration: true,
|
gpu_acceleration: true,
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ export async function setLineHeight(height: number): Promise<void> {
|
|||||||
return invoke("set_line_height", { height });
|
return invoke("set_line_height", { height });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function setUiScale(scale: number): Promise<void> {
|
||||||
|
return invoke("set_ui_scale", { scale });
|
||||||
|
}
|
||||||
|
|
||||||
export async function getNotebooks(): Promise<NotebookEntry[]> {
|
export async function getNotebooks(): Promise<NotebookEntry[]> {
|
||||||
return invoke("get_notebooks");
|
return invoke("get_notebooks");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { showSettings, theme, appConfig, updateAvailable as globalUpdateAvailable, updateObj as globalUpdateObj, installType, settingsTab, vaultReady, androidApkUrl, checkForUpdateMobile, notebookSortMode } from '$lib/stores/app';
|
import { showSettings, theme, appConfig, updateAvailable as globalUpdateAvailable, updateObj as globalUpdateObj, installType, settingsTab, vaultReady, androidApkUrl, checkForUpdateMobile, notebookSortMode } from '$lib/stores/app';
|
||||||
import { setTheme, setAccentColor, setFontSize, setFontFamily, setLineHeight, setGeneralSettings, importObsidian, createBackup, listBackups, restoreBackup, deleteBackup, setBackupSettings, setAiSettings, testAiConnection } from '$lib/api';
|
import { setTheme, setAccentColor, setFontSize, setFontFamily, setLineHeight, setUiScale, setGeneralSettings, importObsidian, createBackup, listBackups, restoreBackup, deleteBackup, setBackupSettings, setAiSettings, testAiConnection } from '$lib/api';
|
||||||
import { open as openDialog } from '@tauri-apps/plugin-dialog';
|
import { open as openDialog } from '@tauri-apps/plugin-dialog';
|
||||||
import { listen } from '@tauri-apps/api/event';
|
import { listen } from '@tauri-apps/api/event';
|
||||||
import { getVersion } from '@tauri-apps/api/app';
|
import { getVersion } from '@tauri-apps/api/app';
|
||||||
|
import { getCurrentWebview } from '@tauri-apps/api/webview';
|
||||||
import { openUrl } from '$lib/api';
|
import { openUrl } from '$lib/api';
|
||||||
import type { ImportResult, BackupEntry } from '$lib/types';
|
import type { ImportResult, BackupEntry } from '$lib/types';
|
||||||
|
|
||||||
@@ -336,10 +337,21 @@
|
|||||||
{ label: 'Loose', value: 2.0 },
|
{ label: 'Loose', value: 2.0 },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const uiScalePresets = [
|
||||||
|
{ label: '80%', value: 0.8 },
|
||||||
|
{ label: '90%', value: 0.9 },
|
||||||
|
{ label: '100%', value: 1 },
|
||||||
|
{ label: '125%', value: 1.25 },
|
||||||
|
{ label: '150%', value: 1.5 },
|
||||||
|
{ label: '175%', value: 1.75 },
|
||||||
|
{ label: '200%', value: 2 },
|
||||||
|
];
|
||||||
|
|
||||||
let activeAccent = $state($appConfig?.accent_color ?? 'Indigo');
|
let activeAccent = $state($appConfig?.accent_color ?? 'Indigo');
|
||||||
let activeFontSize = $state($appConfig?.font_size ?? 14);
|
let activeFontSize = $state($appConfig?.font_size ?? 14);
|
||||||
let activeFontFamily = $state($appConfig?.font_family ?? 'system');
|
let activeFontFamily = $state($appConfig?.font_family ?? 'system');
|
||||||
let activeLineHeight = $state($appConfig?.line_height ?? 1.6);
|
let activeLineHeight = $state($appConfig?.line_height ?? 1.6);
|
||||||
|
let activeUiScale = $state($appConfig?.ui_scale ?? 1);
|
||||||
|
|
||||||
// General settings
|
// General settings
|
||||||
let compactNotes = $state($appConfig?.compact_notes ?? false);
|
let compactNotes = $state($appConfig?.compact_notes ?? false);
|
||||||
@@ -477,6 +489,21 @@
|
|||||||
document.documentElement.style.setProperty('--editor-line-height', String(value));
|
document.documentElement.style.setProperty('--editor-line-height', String(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectUiScale(value: number) {
|
||||||
|
activeUiScale = value;
|
||||||
|
applyUiScale(value);
|
||||||
|
if ($appConfig) $appConfig.ui_scale = value;
|
||||||
|
setUiScale(value).catch((e) => console.error('Failed to save interface scale:', e));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function applyUiScale(value: number) {
|
||||||
|
try {
|
||||||
|
await getCurrentWebview().setZoom(value);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to apply interface scale:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
// Ensure AI settings are saved when closing (in case input wasn't blurred)
|
// Ensure AI settings are saved when closing (in case input wasn't blurred)
|
||||||
// Only save if the key differs from what's already stored
|
// Only save if the key differs from what's already stored
|
||||||
@@ -846,6 +873,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{#if !isMobile}
|
||||||
|
<div class="settings-section">
|
||||||
|
<h3>Interface Scale</h3>
|
||||||
|
<div class="font-size-options">
|
||||||
|
{#each uiScalePresets as preset}
|
||||||
|
<button
|
||||||
|
class="font-size-btn"
|
||||||
|
class:active={activeUiScale === preset.value}
|
||||||
|
onclick={() => selectUiScale(preset.value)}
|
||||||
|
>
|
||||||
|
<span class="font-size-label">{preset.label}</span>
|
||||||
|
</button>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
<p class="setting-hint">Zooms the whole app: every panel, menu, and the editor. Use Default (100%) to reset.</p>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<div class="settings-section">
|
<div class="settings-section">
|
||||||
<h3>Line Height</h3>
|
<h3>Line Height</h3>
|
||||||
<div class="font-size-options">
|
<div class="font-size-options">
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ export interface AppConfig {
|
|||||||
font_size: number | null;
|
font_size: number | null;
|
||||||
font_family: string | null;
|
font_family: string | null;
|
||||||
line_height: number | null;
|
line_height: number | null;
|
||||||
|
ui_scale: number | null;
|
||||||
compact_notes: boolean;
|
compact_notes: boolean;
|
||||||
time_format: string;
|
time_format: string;
|
||||||
gpu_acceleration: boolean;
|
gpu_acceleration: boolean;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { appConfig, vaultReady, theme } from '$lib/stores/app';
|
import { appConfig, vaultReady, theme } from '$lib/stores/app';
|
||||||
import { getAppConfig, openVault } from '$lib/api';
|
import { getAppConfig, openVault } from '$lib/api';
|
||||||
|
import { getCurrentWebview } from '@tauri-apps/api/webview';
|
||||||
import VaultPicker from '$lib/components/VaultPicker.svelte';
|
import VaultPicker from '$lib/components/VaultPicker.svelte';
|
||||||
import AppLayout from '$lib/components/AppLayout.svelte';
|
import AppLayout from '$lib/components/AppLayout.svelte';
|
||||||
import NoteWindow from '$lib/components/NoteWindow.svelte';
|
import NoteWindow from '$lib/components/NoteWindow.svelte';
|
||||||
@@ -78,6 +79,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply saved interface scale (desktop main window only; no-ops gracefully elsewhere)
|
||||||
|
if (!noteWindowPath && config.ui_scale && config.ui_scale !== 1) {
|
||||||
|
try {
|
||||||
|
await getCurrentWebview().setZoom(config.ui_scale);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to apply interface scale:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Auto-open last vault if available
|
// Auto-open last vault if available
|
||||||
if (config.active_vault) {
|
if (config.active_vault) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user