mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2026-03-15 03:53:16 +08:00
✨完善非回正模式下的窗口位置&大小处理 (#226)
* ⚡️大幅提升UIGF导入速度 (#225) * Initial plan * perf: optimize gacha import with batch transactions and reduced UI delays - Wrap DB inserts in transactions (batches of 500) for mergeUIGF/mergeUIGF4 - Pre-transform all data before batch insert loop - Pass timeout: 0 to showLoading.update in progress callbacks - Remove 1500ms snackbar delay in cleanGachaRecords - Reduce per-item loading update delay in refreshGachaPool Co-authored-by: Mikachu2333 <63829496+Mikachu2333@users.noreply.github.com> * fix: increment progress counter per item instead of per batch for accurate progress display Co-authored-by: Mikachu2333 <63829496+Mikachu2333@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Mikachu2333 <63829496+Mikachu2333@users.noreply.github.com> * Initial plan * feat: calculate window size based on resolution/scaling with baseline check and centering - resizeWindow: add baseline check (1920x1080@150%), clamp to screen bounds - setWindowPos: ensure window fits on screen and always center - App.vue: use setWindowPos instead of manual positioning, center on deep link show - tray.rs: center window when showing from system tray Co-authored-by: Mikachu2333 <63829496+Mikachu2333@users.noreply.github.com> * fix: address code review - add zero guard and use setWindowPos consistently Co-authored-by: Mikachu2333 <63829496+Mikachu2333@users.noreply.github.com> * refactor: address review feedback - move baseline to setWindowPos, revert tray.rs - tray.rs: reverted, center() removed as redundant - TGWindow.ts: baseline check moved to setWindowPos, resizeWindow restored as fallback - App.vue: needResize=false → setWindowPos, else → center; deep link reverted; handleResizeListen true path unchanged, setWindowPos moved inside else Co-authored-by: Mikachu2333 <63829496+Mikachu2333@users.noreply.github.com> * refactor: use needResize judgment condition (targetZoom/scaleFactor/textScale) in setWindowPos Replace the simple curSize > screen.size overflow check with the same condition used by resizeWindow(): targetZoom < 1, which considers scaleFactor and textScale. Falls back to resizeWindow() when below baseline or when targetZoom < 1. Co-authored-by: Mikachu2333 <63829496+Mikachu2333@users.noreply.github.com> * 🚸 调整尺寸判断 * 🚸 处理溢出 * 🚸 优化处理 * 🚸 移除冗余scale处理 * 🎨 CodeStyle --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Mikachu2333 <63829496+Mikachu2333@users.noreply.github.com> Co-authored-by: BTMuli <bt-muli@outlook.com>
This commit is contained in:
21
src/App.vue
21
src/App.vue
@@ -28,12 +28,12 @@ import useAppStore from "@store/app.js";
|
||||
import useUserStore from "@store/user.js";
|
||||
import { app, core, event, webviewWindow } from "@tauri-apps/api";
|
||||
import type { Event, UnlistenFn } from "@tauri-apps/api/event";
|
||||
import { getCurrentWindow, LogicalPosition, LogicalSize } from "@tauri-apps/api/window";
|
||||
import { getCurrentWindow } from "@tauri-apps/api/window";
|
||||
import { type CliMatches, getMatches } from "@tauri-apps/plugin-cli";
|
||||
import { mkdir } from "@tauri-apps/plugin-fs";
|
||||
import { openUrl } from "@tauri-apps/plugin-opener";
|
||||
import TGLogger from "@utils/TGLogger.js";
|
||||
import { getWindowSize, resizeWindow } from "@utils/TGWindow.js";
|
||||
import { resizeWindow, setWindowPos } from "@utils/TGWindow.js";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { computed, nextTick, onMounted, onUnmounted, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
@@ -74,11 +74,10 @@ onMounted(async () => {
|
||||
textScaleListener = await event.listen<void>("text_scale_change", resizeWindow);
|
||||
const isShow = await win.isVisible();
|
||||
if (!isShow) {
|
||||
if (needResize.value !== "false") await win.center();
|
||||
else {
|
||||
// TODO: 结合窗口尺寸&放缩以及设计尺寸放置合适位置
|
||||
const position = new LogicalPosition(20, 20);
|
||||
await win.setPosition(position);
|
||||
if (needResize.value === "false") {
|
||||
await setWindowPos();
|
||||
} else {
|
||||
await win.center();
|
||||
}
|
||||
await win.show();
|
||||
}
|
||||
@@ -275,15 +274,11 @@ function handleThemeListen(event: Event<string>): void {
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function handleResizeListen(event: Event<string>): Promise<void> {
|
||||
const win = getCurrentWindow();
|
||||
const webview = webviewWindow.getCurrentWebviewWindow();
|
||||
if (event.payload !== "false") {
|
||||
await resizeWindow();
|
||||
await win.center();
|
||||
await getCurrentWindow().center();
|
||||
} else {
|
||||
const size = getWindowSize(webview.label);
|
||||
await win.setSize(new LogicalSize(size.width, size.height));
|
||||
await webview.setZoom(1);
|
||||
await setWindowPos();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
* 窗口创建相关工具函数
|
||||
* @since Beta v0.9.6
|
||||
* @since Beta v0.9.8
|
||||
*/
|
||||
|
||||
import type { RenderCard } from "@comp/app/t-postcard.vue";
|
||||
import showSnackbar from "@comp/func/snackbar.js";
|
||||
import { core, webviewWindow, window as TauriWindow } from "@tauri-apps/api";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { PhysicalSize } from "@tauri-apps/api/dpi";
|
||||
import { PhysicalPosition, PhysicalSize } from "@tauri-apps/api/dpi";
|
||||
import { currentMonitor, WindowOptions } from "@tauri-apps/api/window";
|
||||
import { openUrl } from "@tauri-apps/plugin-opener";
|
||||
|
||||
@@ -100,24 +100,42 @@ export function getWindowSize(label: string): PhysicalSize {
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断窗口位置
|
||||
* 判断窗口位置,确保窗口不超出屏幕并居中
|
||||
* @since Beta v0.9.8
|
||||
* @remarks 当窗口超出屏幕时回滚到 resizeWindow,此时回正配置默认生效
|
||||
* @returns 无返回值
|
||||
*/
|
||||
export async function setWindowPos(): Promise<void> {
|
||||
const screen = await currentMonitor();
|
||||
const NAV_BAR_HEIGHT = 28;
|
||||
if (screen === null) {
|
||||
showSnackbar.error("获取屏幕信息失败!", 3000);
|
||||
return;
|
||||
}
|
||||
const windowCur = webviewWindow.getCurrentWebviewWindow();
|
||||
const textScale = await invoke<number>("read_text_scale");
|
||||
if (await windowCur.isMaximized()) return;
|
||||
const designSize = getWindowSize(windowCur.label);
|
||||
console.log(textScale, designSize);
|
||||
// TODO: 判断设计大小是否会超出窗口大小
|
||||
// 如果超出,设计合适窗口位置使得顶部能够展示或者将窗口最大化
|
||||
// 否则直接居中
|
||||
const screenScale = screen.scaleFactor;
|
||||
const targetWidth = Math.round(designSize.width * screenScale);
|
||||
const targetHeight = Math.round(designSize.height * screenScale);
|
||||
const cpWidth = screen.size.width - NAV_BAR_HEIGHT * screenScale;
|
||||
const cpHeight = screen.size.height - NAV_BAR_HEIGHT * screenScale;
|
||||
if (targetWidth > cpWidth && targetHeight > cpHeight) {
|
||||
await resizeWindow();
|
||||
await windowCur.center();
|
||||
} else if (targetHeight > cpHeight) {
|
||||
const left = (screen.size.width - targetWidth) / 2;
|
||||
await windowCur.setSize(new PhysicalSize(targetWidth, targetHeight));
|
||||
await windowCur.setPosition(new PhysicalPosition(left, 24));
|
||||
} else if (targetWidth > screen.size.width) {
|
||||
const top = (screen.size.height - targetHeight) / 2;
|
||||
await windowCur.setSize(new PhysicalSize(targetWidth, targetHeight));
|
||||
await windowCur.setPosition(new PhysicalPosition(24, top));
|
||||
} else {
|
||||
await windowCur.setSize(new PhysicalSize(targetWidth, targetHeight));
|
||||
await windowCur.center();
|
||||
}
|
||||
await windowCur.setZoom(1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user