mirror of
https://gitlab.com/ArkHost/HelixNotes.git
synced 2026-09-19 17:37:29 +02:00
Add scroll font size preference and bump v1.3.5
This commit is contained in:
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
"name": "helixnotes",
|
"name": "helixnotes",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"version": "1.3.4",
|
"version": "1.3.5",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev",
|
"dev": "vite dev",
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
"prepare": "svelte-kit sync || echo ''",
|
"prepare": "svelte-kit sync || echo ''",
|
||||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||||
"test": "node --test tests/*.test.mjs",
|
"test": "node --test tests/*.test.mjs src/lib/utils/*.test.mjs",
|
||||||
"test:rust": "cargo test --manifest-path src-tauri/Cargo.toml",
|
"test:rust": "cargo test --manifest-path src-tauri/Cargo.toml",
|
||||||
"lint:rust": "cargo fmt --manifest-path src-tauri/Cargo.toml --check && cargo clippy --manifest-path src-tauri/Cargo.toml --all-targets -- -D warnings",
|
"lint:rust": "cargo fmt --manifest-path src-tauri/Cargo.toml --check && cargo clippy --manifest-path src-tauri/Cargo.toml --all-targets -- -D warnings",
|
||||||
"verify": "pnpm check && pnpm test && pnpm test:rust && pnpm lint:rust && pnpm build",
|
"verify": "pnpm check && pnpm test && pnpm test:rust && pnpm lint:rust && pnpm build",
|
||||||
|
|||||||
Generated
+1
-1
@@ -1776,7 +1776,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "helixnotes"
|
name = "helixnotes"
|
||||||
version = "1.3.4"
|
version = "1.3.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arboard",
|
"arboard",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "helixnotes"
|
name = "helixnotes"
|
||||||
version = "1.3.4"
|
version = "1.3.5"
|
||||||
description = "Local markdown note-taking app"
|
description = "Local markdown note-taking app"
|
||||||
authors = ["HelixNotes"]
|
authors = ["HelixNotes"]
|
||||||
license = "AGPL-3.0-or-later"
|
license = "AGPL-3.0-or-later"
|
||||||
|
|||||||
@@ -470,6 +470,22 @@ pub fn set_font_size(app: AppHandle, state: State<'_, AppState>, size: u32) -> R
|
|||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn set_scroll_to_change_font_size(
|
||||||
|
app: AppHandle,
|
||||||
|
state: State<'_, AppState>,
|
||||||
|
enabled: bool,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
let mut config = state.config.lock().map_err(|e| e.to_string())?;
|
||||||
|
config.scroll_to_change_font_size = enabled;
|
||||||
|
save_app_config(&config)?;
|
||||||
|
drop(config);
|
||||||
|
|
||||||
|
use tauri::Emitter;
|
||||||
|
app.emit("scroll-to-change-font-size-changed", enabled)
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn set_font_family(state: State<'_, AppState>, family: String) -> Result<(), String> {
|
pub fn set_font_family(state: State<'_, AppState>, family: String) -> Result<(), String> {
|
||||||
let mut config = state.config.lock().map_err(|e| e.to_string())?;
|
let mut config = state.config.lock().map_err(|e| e.to_string())?;
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ pub fn run() {
|
|||||||
commands::export_custom_theme,
|
commands::export_custom_theme,
|
||||||
commands::import_custom_themes,
|
commands::import_custom_themes,
|
||||||
commands::set_font_size,
|
commands::set_font_size,
|
||||||
|
commands::set_scroll_to_change_font_size,
|
||||||
commands::set_font_family,
|
commands::set_font_family,
|
||||||
commands::set_line_height,
|
commands::set_line_height,
|
||||||
commands::set_ui_scale,
|
commands::set_ui_scale,
|
||||||
|
|||||||
@@ -124,6 +124,8 @@ pub struct AppConfig {
|
|||||||
pub accent_color: Option<String>,
|
pub accent_color: Option<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub font_size: Option<u32>,
|
pub font_size: Option<u32>,
|
||||||
|
#[serde(default = "default_true")]
|
||||||
|
pub scroll_to_change_font_size: bool,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub font_family: Option<String>,
|
pub font_family: Option<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
@@ -296,6 +298,7 @@ impl Default for AppConfig {
|
|||||||
system_dark_theme: default_system_dark_theme(),
|
system_dark_theme: default_system_dark_theme(),
|
||||||
accent_color: None,
|
accent_color: None,
|
||||||
font_size: None,
|
font_size: None,
|
||||||
|
scroll_to_change_font_size: true,
|
||||||
font_family: None,
|
font_family: None,
|
||||||
line_height: None,
|
line_height: None,
|
||||||
ui_scale: None,
|
ui_scale: None,
|
||||||
@@ -554,4 +557,19 @@ mod startup_view_tests {
|
|||||||
|
|
||||||
assert!(!config.show_note_switcher);
|
assert!(!config.show_note_switcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn scroll_font_sizing_stays_enabled_for_new_and_existing_configs() {
|
||||||
|
let config = AppConfig::default();
|
||||||
|
assert!(config.scroll_to_change_font_size);
|
||||||
|
|
||||||
|
let mut value = serde_json::to_value(config).unwrap();
|
||||||
|
value
|
||||||
|
.as_object_mut()
|
||||||
|
.unwrap()
|
||||||
|
.remove("scroll_to_change_font_size");
|
||||||
|
let config: AppConfig = serde_json::from_value(value).unwrap();
|
||||||
|
|
||||||
|
assert!(config.scroll_to_change_font_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
||||||
"productName": "HelixNotes",
|
"productName": "HelixNotes",
|
||||||
"version": "1.3.4",
|
"version": "1.3.5",
|
||||||
"identifier": "com.helixnotes.app",
|
"identifier": "com.helixnotes.app",
|
||||||
"build": {
|
"build": {
|
||||||
"frontendDist": "../build",
|
"frontendDist": "../build",
|
||||||
|
|||||||
@@ -71,6 +71,10 @@ export async function setFontSize(size: number): Promise<void> {
|
|||||||
return invoke("set_font_size", { size });
|
return invoke("set_font_size", { size });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function setScrollToChangeFontSize(enabled: boolean): Promise<void> {
|
||||||
|
return invoke("set_scroll_to_change_font_size", { enabled });
|
||||||
|
}
|
||||||
|
|
||||||
export async function setFontFamily(family: string): Promise<void> {
|
export async function setFontFamily(family: string): Promise<void> {
|
||||||
return invoke("set_font_family", { family });
|
return invoke("set_font_family", { family });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { showSettings, theme, resolvedTheme, appConfig, platformIsMobile, activeVaultConfig, updateAvailable as globalUpdateAvailable, updateObj as globalUpdateObj, installType, settingsTab, vaultReady, androidApkUrl, checkForUpdateMobile, notebookSortMode, isManagedInstall, customThemes } from '$lib/stores/app';
|
import { showSettings, theme, resolvedTheme, appConfig, platformIsMobile, activeVaultConfig, updateAvailable as globalUpdateAvailable, updateObj as globalUpdateObj, installType, settingsTab, vaultReady, androidApkUrl, checkForUpdateMobile, notebookSortMode, isManagedInstall, customThemes } from '$lib/stores/app';
|
||||||
import { setTheme, setSystemThemes, setAccentColor, setFontSize, setFontFamily, setLineHeight, setUiScale, setContentWidth, setGeneralSettings, importObsidian, createBackup, listBackups, restoreBackup, deleteBackup, setBackupSettings, setAiSettings, testAiConnection, setSyncSettings, testSyncConnection, syncNow, getAppConfig, saveCustomTheme, deleteCustomTheme, exportCustomTheme, importCustomThemes, getVaultStats, findOrphanedAttachments, trashOrphanedAttachments } from '$lib/api';
|
import { setTheme, setSystemThemes, setAccentColor, setFontSize, setScrollToChangeFontSize, setFontFamily, setLineHeight, setUiScale, setContentWidth, setGeneralSettings, importObsidian, createBackup, listBackups, restoreBackup, deleteBackup, setBackupSettings, setAiSettings, testAiConnection, setSyncSettings, testSyncConnection, syncNow, getAppConfig, saveCustomTheme, deleteCustomTheme, exportCustomTheme, importCustomThemes, getVaultStats, findOrphanedAttachments, trashOrphanedAttachments } from '$lib/api';
|
||||||
import { darkThemes, isMobile, isAndroid } from '$lib/platform';
|
import { darkThemes, isMobile, isAndroid } from '$lib/platform';
|
||||||
import { open as openDialog, save as saveDialog } from '@tauri-apps/plugin-dialog';
|
import { open as openDialog, save as saveDialog } from '@tauri-apps/plugin-dialog';
|
||||||
import { listen } from '@tauri-apps/api/event';
|
import { listen } from '@tauri-apps/api/event';
|
||||||
@@ -583,6 +583,7 @@
|
|||||||
let activeAccent = $state($appConfig?.accent_color ?? 'Indigo');
|
let activeAccent = $state($appConfig?.accent_color ?? 'Indigo');
|
||||||
let customAccentColor = $state(($appConfig?.accent_color?.startsWith('#') ? $appConfig.accent_color : null) ?? '#5b6abf');
|
let customAccentColor = $state(($appConfig?.accent_color?.startsWith('#') ? $appConfig.accent_color : null) ?? '#5b6abf');
|
||||||
let activeFontSize = $state($appConfig?.font_size ?? 14);
|
let activeFontSize = $state($appConfig?.font_size ?? 14);
|
||||||
|
let scrollToChangeFontSize = $state($appConfig?.scroll_to_change_font_size ?? true);
|
||||||
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);
|
let activeUiScale = $state($appConfig?.ui_scale ?? 1);
|
||||||
@@ -987,6 +988,13 @@
|
|||||||
setFontSize(size).catch((e) => console.error('Failed to save font size:', e));
|
setFontSize(size).catch((e) => console.error('Failed to save font size:', e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleScrollToChangeFontSize() {
|
||||||
|
scrollToChangeFontSize = !scrollToChangeFontSize;
|
||||||
|
if ($appConfig) $appConfig.scroll_to_change_font_size = scrollToChangeFontSize;
|
||||||
|
setScrollToChangeFontSize(scrollToChangeFontSize)
|
||||||
|
.catch((e) => console.error('Failed to save scroll font size setting:', e));
|
||||||
|
}
|
||||||
|
|
||||||
function applyFontSize(size: number) {
|
function applyFontSize(size: number) {
|
||||||
document.documentElement.style.setProperty('--editor-font-size', `${size}px`);
|
document.documentElement.style.setProperty('--editor-font-size', `${size}px`);
|
||||||
}
|
}
|
||||||
@@ -1080,6 +1088,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
scrollToChangeFontSize = $appConfig?.scroll_to_change_font_size ?? true;
|
||||||
const savedSize = $appConfig?.font_size;
|
const savedSize = $appConfig?.font_size;
|
||||||
if (savedSize) {
|
if (savedSize) {
|
||||||
activeFontSize = savedSize;
|
activeFontSize = savedSize;
|
||||||
@@ -1910,6 +1919,17 @@
|
|||||||
</button>
|
</button>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
{#if !isMobile}
|
||||||
|
<label class="setting-toggle">
|
||||||
|
<span class="setting-label">
|
||||||
|
<span class="setting-name">Scroll to change font size</span>
|
||||||
|
<span class="setting-desc">Allow Cmd/Ctrl + scroll to resize editor text</span>
|
||||||
|
</span>
|
||||||
|
<button class="toggle-switch" class:on={scrollToChangeFontSize} role="switch" aria-checked={scrollToChangeFontSize} aria-label="Scroll to change font size" onclick={toggleScrollToChangeFontSize}>
|
||||||
|
<span class="toggle-knob"></span>
|
||||||
|
</button>
|
||||||
|
</label>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if !isMobile}
|
{#if !isMobile}
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ export interface AppConfig {
|
|||||||
system_dark_theme: string;
|
system_dark_theme: string;
|
||||||
accent_color: string | null;
|
accent_color: string | null;
|
||||||
font_size: number | null;
|
font_size: number | null;
|
||||||
|
scroll_to_change_font_size: boolean;
|
||||||
font_family: string | null;
|
font_family: string | null;
|
||||||
line_height: number | null;
|
line_height: number | null;
|
||||||
ui_scale: number | null;
|
ui_scale: number | null;
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import test from 'node:test';
|
||||||
|
|
||||||
|
const { getWheelFontSizeAction } = await import(
|
||||||
|
new URL('./editor-zoom.ts', import.meta.url)
|
||||||
|
);
|
||||||
|
|
||||||
|
test('blocks modified wheel input when scroll font sizing is disabled', () => {
|
||||||
|
assert.equal(
|
||||||
|
getWheelFontSizeAction({ ctrlKey: false, metaKey: true, deltaY: -1 }, false),
|
||||||
|
'block'
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
getWheelFontSizeAction({ ctrlKey: true, metaKey: false, deltaY: 1 }, false),
|
||||||
|
'block'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('changes font size from modified wheel input when enabled', () => {
|
||||||
|
assert.equal(
|
||||||
|
getWheelFontSizeAction({ ctrlKey: false, metaKey: true, deltaY: -1 }, true),
|
||||||
|
'increase'
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
getWheelFontSizeAction({ ctrlKey: true, metaKey: false, deltaY: 1 }, true),
|
||||||
|
'decrease'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ignores unmodified wheel input', () => {
|
||||||
|
assert.equal(
|
||||||
|
getWheelFontSizeAction({ ctrlKey: false, metaKey: false, deltaY: -1 }, false),
|
||||||
|
'ignore'
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
export type WheelFontSizeAction = 'ignore' | 'block' | 'increase' | 'decrease';
|
||||||
|
|
||||||
|
interface WheelModifierInput {
|
||||||
|
ctrlKey: boolean;
|
||||||
|
metaKey: boolean;
|
||||||
|
deltaY: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getWheelFontSizeAction(
|
||||||
|
event: WheelModifierInput,
|
||||||
|
scrollToChangeFontSize: boolean,
|
||||||
|
): WheelFontSizeAction {
|
||||||
|
if (!event.ctrlKey && !event.metaKey) return 'ignore';
|
||||||
|
if (!scrollToChangeFontSize) return 'block';
|
||||||
|
return event.deltaY < 0 ? 'increase' : 'decrease';
|
||||||
|
}
|
||||||
+13
-2
@@ -3,6 +3,7 @@
|
|||||||
import { appConfig, vaultReady, theme } from '$lib/stores/app';
|
import { appConfig, vaultReady, theme } from '$lib/stores/app';
|
||||||
import { getAppConfig, openVault, restoreExternalVault, setFontSize } from '$lib/api';
|
import { getAppConfig, openVault, restoreExternalVault, setFontSize } from '$lib/api';
|
||||||
import { darkThemes, isIOS, isMobile } from '$lib/platform';
|
import { darkThemes, isIOS, isMobile } from '$lib/platform';
|
||||||
|
import { getWheelFontSizeAction } from '$lib/utils/editor-zoom';
|
||||||
import { getCurrentWebview } from '@tauri-apps/api/webview';
|
import { getCurrentWebview } from '@tauri-apps/api/webview';
|
||||||
import { listen } from '@tauri-apps/api/event';
|
import { listen } from '@tauri-apps/api/event';
|
||||||
import { getCurrentWindow } from '@tauri-apps/api/window';
|
import { getCurrentWindow } from '@tauri-apps/api/window';
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
let fontSizeSaveTimer: ReturnType<typeof setTimeout> | null = null;
|
let fontSizeSaveTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
let removeEditorZoomShortcuts: (() => void) | null = null;
|
let removeEditorZoomShortcuts: (() => void) | null = null;
|
||||||
let removeFontSizeListener: (() => void) | null = null;
|
let removeFontSizeListener: (() => void) | null = null;
|
||||||
|
let removeScrollFontSizeListener: (() => void) | null = null;
|
||||||
let startupRevealTimer: ReturnType<typeof setTimeout> | null = null;
|
let startupRevealTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
let startupWindowRevealed = false;
|
let startupWindowRevealed = false;
|
||||||
|
|
||||||
@@ -121,10 +123,15 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleWheel = (event: WheelEvent) => {
|
const handleWheel = (event: WheelEvent) => {
|
||||||
if (!event.ctrlKey && !event.metaKey) return;
|
const action = getWheelFontSizeAction(
|
||||||
|
event,
|
||||||
|
$appConfig?.scroll_to_change_font_size ?? true
|
||||||
|
);
|
||||||
|
if (action === 'ignore') return;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
zoomEditor(event.deltaY < 0 ? 1 : -1);
|
if (action === 'increase') zoomEditor(1);
|
||||||
|
else if (action === 'decrease') zoomEditor(-1);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('keydown', handleKeydown);
|
window.addEventListener('keydown', handleKeydown);
|
||||||
@@ -153,6 +160,9 @@
|
|||||||
removeFontSizeListener = await listen<number>('editor-font-size-changed', (event) => {
|
removeFontSizeListener = await listen<number>('editor-font-size-changed', (event) => {
|
||||||
if ($appConfig?.font_size !== event.payload) applyEditorFontSize(event.payload);
|
if ($appConfig?.font_size !== event.payload) applyEditorFontSize(event.payload);
|
||||||
});
|
});
|
||||||
|
removeScrollFontSizeListener = await listen<boolean>('scroll-to-change-font-size-changed', (event) => {
|
||||||
|
if ($appConfig) $appConfig.scroll_to_change_font_size = event.payload;
|
||||||
|
});
|
||||||
$theme = config.theme || 'system';
|
$theme = config.theme || 'system';
|
||||||
|
|
||||||
// Apply theme immediately to prevent flash. Runs before the stores settle, so resolve
|
// Apply theme immediately to prevent flash. Runs before the stores settle, so resolve
|
||||||
@@ -287,6 +297,7 @@
|
|||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
removeEditorZoomShortcuts?.();
|
removeEditorZoomShortcuts?.();
|
||||||
removeFontSizeListener?.();
|
removeFontSizeListener?.();
|
||||||
|
removeScrollFontSizeListener?.();
|
||||||
if (fontSizeSaveTimer) clearTimeout(fontSizeSaveTimer);
|
if (fontSizeSaveTimer) clearTimeout(fontSizeSaveTimer);
|
||||||
if (startupRevealTimer) clearTimeout(startupRevealTimer);
|
if (startupRevealTimer) clearTimeout(startupRevealTimer);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user