feat: work on windows resizing

This commit is contained in:
2026-04-23 09:11:01 +02:00
parent 9d181f3676
commit 3fb8e23c07
15 changed files with 1286 additions and 114 deletions

View File

@ -1,29 +1,64 @@
import { useEffect, useState } from "react";
import { invoke } from "@tauri-apps/api/core";
import { getCurrentWindow, LogicalSize } from "@tauri-apps/api/window";
import { useStore } from "./store";
import TitleBar from "./components/TitleBar";
import Sidebar from "./components/Sidebar";
import HomeView from "./components/HomeView";
import GuideView from "./components/GuideView";
import ProfileModal from "./components/ProfileModal";
import SettingsPanel from "./components/SettingsPanel";
import SyncOverlay from "./components/SyncOverlay";
export default function App() {
const { loadProfiles, loadGuides, view, syncing, syncGuides } = useStore();
const [showProfileModal, setShowProfileModal] = useState(false);
const { loadProfiles, loadGuides, openGuide, setResourcesPanelCollapsed, view, syncing, syncGuides } = useStore();
const [showSettings, setShowSettings] = useState(false);
const [needsSync, setNeedsSync] = useState(false);
useEffect(() => {
async function init() {
// Restore window size
const [savedW, savedH] = await Promise.all([
invoke<string | null>("get_setting", { key: "window_width" }),
invoke<string | null>("get_setting", { key: "window_height" }),
]);
if (savedW && savedH) {
await getCurrentWindow().setSize(new LogicalSize(parseInt(savedW), parseInt(savedH)));
}
await loadProfiles();
const has = await invoke<boolean>("has_guides");
if (!has) {
setNeedsSync(true);
} else {
await loadGuides();
// Restore last viewed guide
const lastGuide = await invoke<string | null>("get_setting", { key: "active_guide" });
if (lastGuide) {
try {
await openGuide(lastGuide);
setResourcesPanelCollapsed(true);
} catch { /* guide may no longer exist */ }
}
}
}
init();
// Persist window size on resize (debounced)
const win = getCurrentWindow();
let debounce: ReturnType<typeof setTimeout> | null = null;
const unlisten = win.onResized(async () => {
if (debounce !== null) clearTimeout(debounce);
debounce = setTimeout(async () => {
const size = await win.innerSize();
const factor = await win.scaleFactor();
const w = Math.round(size.width / factor);
const h = Math.round(size.height / factor);
await invoke("set_setting", { key: "window_width", value: w.toString() });
await invoke("set_setting", { key: "window_height", value: h.toString() });
}, 500);
});
return () => { unlisten.then(f => f()); };
}, []);
async function handleInitialSync() {
@ -33,16 +68,15 @@ export default function App() {
return (
<div className="app-shell">
<TitleBar onOpenProfiles={() => setShowProfileModal(true)} />
<TitleBar onOpenSettings={() => setShowSettings(s => !s)} />
<div className="app-body">
<Sidebar />
<main className="app-main">
{view === "home" ? <HomeView /> : <GuideView />}
</main>
</div>
{showProfileModal && <ProfileModal onClose={() => setShowProfileModal(false)} />}
{syncing && <SyncOverlay />}
{showSettings && <SettingsPanel onClose={() => setShowSettings(false)} />}
{syncing && !showSettings && <SyncOverlay />}
{needsSync && (
<div style={{
position: "fixed", inset: 0, background: "rgba(0,0,0,0.85)",