feat: 界面缩放改用后端持久化 + 原生 webview zoom
Axolotl desktop CI / guardrails (push) Has been cancelled
Axolotl desktop CI / desktop (macos-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (ubuntu-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (windows-latest) (push) Has been cancelled
Axolotl desktop CI / website (push) Has been cancelled
Repository checks / typos (push) Has been cancelled
Repository checks / tombi (push) Has been cancelled
Rust checks / shear (push) Has been cancelled
Sync source to CNB / Sync Git ref (push) Has been cancelled
Axolotl desktop CI / guardrails (push) Has been cancelled
Axolotl desktop CI / desktop (macos-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (ubuntu-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (windows-latest) (push) Has been cancelled
Axolotl desktop CI / website (push) Has been cancelled
Repository checks / typos (push) Has been cancelled
Repository checks / tombi (push) Has been cancelled
Rust checks / shear (push) Has been cancelled
Sync source to CNB / Sync Git ref (push) Has been cancelled
This commit is contained in:
1 parent
81b7219085
commit
34cf186c33
7 files changed
+63
-35
No files matched your search
@@ -142,7 +142,7 @@ import {
|
|||||||
isNetworkMetered,
|
isNetworkMetered,
|
||||||
setRestartAfterPendingUpdate,
|
setRestartAfterPendingUpdate,
|
||||||
} from '@/helpers/utils.js'
|
} from '@/helpers/utils.js'
|
||||||
import { installUiScale } from '@/helpers/ui-scale'
|
import { installUiScale, setUiScale } from '@/helpers/ui-scale'
|
||||||
import { start_join_server, start_join_singleplayer_world } from '@/helpers/worlds.ts'
|
import { start_join_server, start_join_singleplayer_world } from '@/helpers/worlds.ts'
|
||||||
import i18n, { resolveInitialLocale } from '@/i18n.config'
|
import i18n, { resolveInitialLocale } from '@/i18n.config'
|
||||||
import {
|
import {
|
||||||
@@ -1091,6 +1091,7 @@ async function setupApp() {
|
|||||||
close_behavior,
|
close_behavior,
|
||||||
developer_mode,
|
developer_mode,
|
||||||
feature_flags,
|
feature_flags,
|
||||||
|
ui_scale,
|
||||||
} = initialSettings
|
} = initialSettings
|
||||||
|
|
||||||
// Initialize locale from saved settings
|
// Initialize locale from saved settings
|
||||||
@@ -1121,6 +1122,7 @@ async function setupApp() {
|
|||||||
nativeDecorations.value = native_decorations
|
nativeDecorations.value = native_decorations
|
||||||
if (os.value !== 'MacOS') await getCurrentWindow().setDecorations(native_decorations)
|
if (os.value !== 'MacOS') await getCurrentWindow().setDecorations(native_decorations)
|
||||||
|
|
||||||
|
setUiScale(ui_scale)
|
||||||
themeStore.setThemeState(theme)
|
themeStore.setThemeState(theme)
|
||||||
await initializeSystemAccentColor()
|
await initializeSystemAccentColor()
|
||||||
themeStore.setAccentColor(accent_color)
|
themeStore.setAccentColor(accent_color)
|
||||||
|
|||||||
@@ -373,6 +373,12 @@ const customBackgroundPreview = computed(() =>
|
|||||||
: null,
|
: null,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
function updateUiScale(value: number) {
|
||||||
|
const clamped = Math.min(200, Math.max(50, Math.round(value)))
|
||||||
|
setUiScale(clamped)
|
||||||
|
settings.value.ui_scale = clamped
|
||||||
|
}
|
||||||
|
|
||||||
const accentColorOptions: Array<{
|
const accentColorOptions: Array<{
|
||||||
value: AccentColor
|
value: AccentColor
|
||||||
color: string
|
color: string
|
||||||
@@ -1050,7 +1056,7 @@ watch(
|
|||||||
? 'border-brand bg-brand-highlight text-brand'
|
? 'border-brand bg-brand-highlight text-brand'
|
||||||
: 'border-surface-4 bg-surface-3 text-secondary hover:border-surface-5 hover:text-contrast'
|
: 'border-surface-4 bg-surface-3 text-secondary hover:border-surface-5 hover:text-contrast'
|
||||||
"
|
"
|
||||||
@click="setUiScale(preset)"
|
@click="updateUiScale(preset)"
|
||||||
>
|
>
|
||||||
{{ preset }}%
|
{{ preset }}%
|
||||||
</button>
|
</button>
|
||||||
@@ -1062,7 +1068,7 @@ watch(
|
|||||||
:max="200"
|
:max="200"
|
||||||
:step="5"
|
:step="5"
|
||||||
unit="%"
|
unit="%"
|
||||||
@update:model-value="(value) => setUiScale(Number(value))"
|
@update:model-value="(value) => updateUiScale(Number(value))"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ export type AppSettings = {
|
|||||||
home_layout: HomeLayout
|
home_layout: HomeLayout
|
||||||
minimal_home_instance_id: string | null
|
minimal_home_instance_id: string | null
|
||||||
close_behavior: 'ask' | 'close' | 'lightweight'
|
close_behavior: 'ask' | 'close' | 'lightweight'
|
||||||
|
ui_scale: number
|
||||||
home_widgets: HomeDashboardConfig | null
|
home_widgets: HomeDashboardConfig | null
|
||||||
terracotta_public_nodes: string[]
|
terracotta_public_nodes: string[]
|
||||||
|
|
||||||
@@ -213,6 +214,7 @@ type LegacyMirrorSettings = {
|
|||||||
|
|
||||||
function normalizeDownloadSettings(settings: AppSettings & LegacyMirrorSettings): AppSettings {
|
function normalizeDownloadSettings(settings: AppSettings & LegacyMirrorSettings): AppSettings {
|
||||||
settings.close_behavior ??= 'ask'
|
settings.close_behavior ??= 'ask'
|
||||||
|
settings.ui_scale ??= 100
|
||||||
const hasLegacySettings =
|
const hasLegacySettings =
|
||||||
typeof settings.use_minecraft_mirror === 'boolean' &&
|
typeof settings.use_minecraft_mirror === 'boolean' &&
|
||||||
typeof settings.use_modrinth_mirror === 'boolean' &&
|
typeof settings.use_modrinth_mirror === 'boolean' &&
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
import { ref, watch } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动器界面缩放(百分比)。
|
* 启动器界面缩放(百分比)。
|
||||||
* 这是纯本地的显示偏好,用 localStorage 保存即可,无需写入后端设置数据库。
|
* 通过 Tauri 原生 webview zoom(Rust 侧 set_zoom)应用,
|
||||||
|
* 缩放值持久化到后端设置数据库(settings.ui_scale)。
|
||||||
*/
|
*/
|
||||||
const UI_SCALE_STORAGE_KEY = 'starlight-ui-scale'
|
|
||||||
const MIN_UI_SCALE = 50
|
const MIN_UI_SCALE = 50
|
||||||
const MAX_UI_SCALE = 200
|
const MAX_UI_SCALE = 200
|
||||||
const DEFAULT_UI_SCALE = 100
|
const DEFAULT_UI_SCALE = 100
|
||||||
@@ -15,18 +16,7 @@ function clampUiScale(value: number): number {
|
|||||||
return Math.min(MAX_UI_SCALE, Math.max(MIN_UI_SCALE, Math.round(value)))
|
return Math.min(MAX_UI_SCALE, Math.max(MIN_UI_SCALE, Math.round(value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 从 localStorage 读取已保存的缩放值。 */
|
export const uiScale = ref(DEFAULT_UI_SCALE)
|
||||||
function readStoredUiScale(): number {
|
|
||||||
try {
|
|
||||||
const raw = localStorage.getItem(UI_SCALE_STORAGE_KEY)
|
|
||||||
if (raw === null) return DEFAULT_UI_SCALE
|
|
||||||
return clampUiScale(Number(raw))
|
|
||||||
} catch {
|
|
||||||
return DEFAULT_UI_SCALE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const uiScale = ref(readStoredUiScale())
|
|
||||||
|
|
||||||
export function setUiScale(value: number): void {
|
export function setUiScale(value: number): void {
|
||||||
uiScale.value = clampUiScale(value)
|
uiScale.value = clampUiScale(value)
|
||||||
@@ -38,23 +28,27 @@ export function resetUiScale(): void {
|
|||||||
|
|
||||||
export { DEFAULT_UI_SCALE, MAX_UI_SCALE, MIN_UI_SCALE }
|
export { DEFAULT_UI_SCALE, MAX_UI_SCALE, MIN_UI_SCALE }
|
||||||
|
|
||||||
/** 把缩放应用到文档根节点,并在变化时持久化。 */
|
/**
|
||||||
export function installUiScale(): void {
|
* 把缩放值应用到原生 webview。
|
||||||
const apply = (value: number) => {
|
* 同时保留 --ui-scale CSS 变量,供依赖它的样式/锚点使用。
|
||||||
const factor = String(value / 100)
|
*/
|
||||||
const root = document.documentElement
|
async function applyUiScale(value: number): Promise<void> {
|
||||||
root.style.setProperty('--ui-scale', factor)
|
const factor = value / 100
|
||||||
// 用 CSS zoom 整体缩放界面(含内嵌网页),在 WebView2/WebKit 上最可靠。
|
document.documentElement.style.setProperty('--ui-scale', String(factor))
|
||||||
root.style.setProperty('zoom', factor)
|
|
||||||
}
|
|
||||||
|
|
||||||
apply(uiScale.value)
|
|
||||||
watch(uiScale, (value) => {
|
|
||||||
apply(value)
|
|
||||||
try {
|
try {
|
||||||
localStorage.setItem(UI_SCALE_STORAGE_KEY, String(value))
|
await invoke('plugin:settings|set_ui_scale', { factor })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('保存界面缩放失败', error)
|
console.warn('应用界面缩放失败', error)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化缩放:应用当前值,并在变化时同步到原生 webview。
|
||||||
|
* 初值由调用方(App 初始化流程)在读取后端设置后通过 setUiScale 覆盖。
|
||||||
|
*/
|
||||||
|
export function installUiScale(): void {
|
||||||
|
void applyUiScale(uiScale.value)
|
||||||
|
watch(uiScale, (value) => {
|
||||||
|
void applyUiScale(value)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::api::Result;
|
use crate::api::Result;
|
||||||
use tauri::{Emitter, Runtime};
|
use tauri::{Emitter, Manager, Runtime};
|
||||||
use theseus::prelude::*;
|
use theseus::prelude::*;
|
||||||
use theseus::{ProxyConfig, ProxyTestResult};
|
use theseus::{ProxyConfig, ProxyTestResult};
|
||||||
|
|
||||||
@@ -12,7 +12,8 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
|
|||||||
cancel_directory_change,
|
cancel_directory_change,
|
||||||
proxy_get,
|
proxy_get,
|
||||||
proxy_set,
|
proxy_set,
|
||||||
proxy_test
|
proxy_test,
|
||||||
|
set_ui_scale
|
||||||
])
|
])
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
@@ -37,6 +38,17 @@ pub async fn settings_set(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn set_ui_scale(
|
||||||
|
app: tauri::AppHandle<impl Runtime>,
|
||||||
|
factor: f64,
|
||||||
|
) -> Result<()> {
|
||||||
|
if let Some(window) = app.get_webview_window("main") {
|
||||||
|
let _ = window.set_zoom(factor);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn download_engine_set(
|
pub async fn download_engine_set(
|
||||||
engine: settings::DownloadEngine,
|
engine: settings::DownloadEngine,
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE settings ADD COLUMN ui_scale REAL NOT NULL DEFAULT 100.0;
|
||||||
@@ -141,6 +141,8 @@ pub struct Settings {
|
|||||||
pub transparent_background_opacity: u32,
|
pub transparent_background_opacity: u32,
|
||||||
pub transparent_background_blur: bool,
|
pub transparent_background_blur: bool,
|
||||||
pub sidebar_instance_count: u32,
|
pub sidebar_instance_count: u32,
|
||||||
|
#[serde(default = "default_ui_scale")]
|
||||||
|
pub ui_scale: f64,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub close_behavior: String,
|
pub close_behavior: String,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
@@ -192,6 +194,10 @@ fn default_true() -> bool {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_ui_scale() -> f64 {
|
||||||
|
100.0
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, Hash, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, Hash, PartialEq)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum FeatureFlag {
|
pub enum FeatureFlag {
|
||||||
@@ -242,6 +248,7 @@ impl Settings {
|
|||||||
sidebar_instance_count, home_layout, minimal_home_instance_id,
|
sidebar_instance_count, home_layout, minimal_home_instance_id,
|
||||||
json(home_widgets) as \"home_widgets?: String\", auto_hide_downloads_button,
|
json(home_widgets) as \"home_widgets?: String\", auto_hide_downloads_button,
|
||||||
json(terracotta_public_nodes) terracotta_public_nodes,
|
json(terracotta_public_nodes) terracotta_public_nodes,
|
||||||
|
ui_scale,
|
||||||
version
|
version
|
||||||
FROM settings
|
FROM settings
|
||||||
"
|
"
|
||||||
@@ -308,6 +315,7 @@ impl Settings {
|
|||||||
as u32,
|
as u32,
|
||||||
transparent_background_blur: res.transparent_background_blur == 1,
|
transparent_background_blur: res.transparent_background_blur == 1,
|
||||||
sidebar_instance_count: res.sidebar_instance_count as u32,
|
sidebar_instance_count: res.sidebar_instance_count as u32,
|
||||||
|
ui_scale: res.ui_scale,
|
||||||
close_behavior,
|
close_behavior,
|
||||||
auto_hide_downloads_button: res.auto_hide_downloads_button == 1,
|
auto_hide_downloads_button: res.auto_hide_downloads_button == 1,
|
||||||
home_layout: HomeLayout::from_string(&res.home_layout),
|
home_layout: HomeLayout::from_string(&res.home_layout),
|
||||||
@@ -603,7 +611,10 @@ impl Settings {
|
|||||||
.bind(self.force_unicode_font)
|
.bind(self.force_unicode_font)
|
||||||
.execute(exec)
|
.execute(exec)
|
||||||
.await?;
|
.await?;
|
||||||
|
sqlx::query("UPDATE settings SET ui_scale = ? WHERE id = 0")
|
||||||
|
.bind(self.ui_scale)
|
||||||
|
.execute(exec)
|
||||||
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user