fix tauri module resolution in browser builds - dynamic imports for window controls

This commit is contained in:
2026-04-03 06:10:07 +03:00
parent a8349c3f18
commit a77b2d491c
2 changed files with 41 additions and 29 deletions
+21 -16
View File
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { NavLink, useLocation, useNavigate } from 'react-router-dom' import { NavLink, useLocation, useNavigate } from 'react-router-dom'
import { getCurrentWindow } from '@tauri-apps/api/window'
import { motion, AnimatePresence } from 'framer-motion' import { motion, AnimatePresence } from 'framer-motion'
import { import {
Search, Search,
@@ -110,17 +110,20 @@ export default function AppHeader({ pinned, onTogglePin }: Props) {
if (!isTauri) return if (!isTauri) return
let cancelled = false let cancelled = false
let unlisten: (() => void) | undefined let unlisten: (() => void) | undefined
const win = getCurrentWindow() import('@tauri-apps/api/window').then(({ getCurrentWindow }) => {
win.isMaximized().then(v => { if (cancelled) return
if (!cancelled) setMaximized(v) const win = getCurrentWindow()
}).catch(() => {}) win.isMaximized().then(v => {
win.onResized(async () => { if (!cancelled) setMaximized(v)
const v = await win.isMaximized() }).catch(() => {})
if (!cancelled) setMaximized(v) win.onResized(async () => {
}).then(u => { const v = await win.isMaximized()
if (cancelled) u() if (!cancelled) setMaximized(v)
else unlisten = u }).then(u => {
}).catch(() => {}) if (cancelled) u()
else unlisten = u
}).catch(() => {})
})
return () => { return () => {
cancelled = true cancelled = true
unlisten?.() unlisten?.()
@@ -129,10 +132,12 @@ export default function AppHeader({ pinned, onTogglePin }: Props) {
function callWin(action: 'minimize' | 'toggleMaximize' | 'close') { function callWin(action: 'minimize' | 'toggleMaximize' | 'close') {
if (!isTauri) return if (!isTauri) return
const win = getCurrentWindow() import('@tauri-apps/api/window').then(({ getCurrentWindow }) => {
if (action === 'minimize') win.minimize() const win = getCurrentWindow()
else if (action === 'toggleMaximize') win.toggleMaximize() if (action === 'minimize') win.minimize()
else win.close() else if (action === 'toggleMaximize') win.toggleMaximize()
else win.close()
})
} }
const showBack = !TOP_LEVEL_PATHS.has(location.pathname) const showBack = !TOP_LEVEL_PATHS.has(location.pathname)
+20 -13
View File
@@ -1,5 +1,4 @@
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { getCurrentWindow } from '@tauri-apps/api/window'
import { Minus, Square, RestoreDown, X } from '../../lib/icons' import { Minus, Square, RestoreDown, X } from '../../lib/icons'
/** /**
@@ -13,22 +12,30 @@ import { Minus, Square, RestoreDown, X } from '../../lib/icons'
*/ */
export default function Titlebar() { export default function Titlebar() {
const [maximized, setMaximized] = useState(false) const [maximized, setMaximized] = useState(false)
const win = getCurrentWindow() const [win, setWin] = useState<any>(null)
useEffect(() => { useEffect(() => {
let cancelled = false let cancelled = false
win.isMaximized().then(v => { let unlisten: (() => void) | undefined
if (!cancelled) setMaximized(v) import('@tauri-apps/api/window').then(({ getCurrentWindow }) => {
}) if (cancelled) return
const unlistenP = win.onResized(async () => { const w = getCurrentWindow()
const v = await win.isMaximized() setWin(w)
if (!cancelled) setMaximized(v) w.isMaximized().then((v: boolean) => {
if (!cancelled) setMaximized(v)
})
w.onResized(async () => {
const v = await w.isMaximized()
if (!cancelled) setMaximized(v)
}).then((u: () => void) => {
unlisten = u
})
}) })
return () => { return () => {
cancelled = true cancelled = true
unlistenP.then(u => u()) unlisten?.()
} }
}, [win]) }, [])
return ( return (
<div <div
@@ -52,13 +59,13 @@ export default function Titlebar() {
</div> </div>
<div className="flex items-stretch h-full"> <div className="flex items-stretch h-full">
<TitlebarButton onClick={() => win.minimize()} aria-label="Minimize"> <TitlebarButton onClick={() => win?.minimize()} aria-label="Minimize">
<Minus size={14} stroke={2} /> <Minus size={14} stroke={2} />
</TitlebarButton> </TitlebarButton>
<TitlebarButton onClick={() => win.toggleMaximize()} aria-label={maximized ? 'Restore' : 'Maximize'}> <TitlebarButton onClick={() => win?.toggleMaximize()} aria-label={maximized ? 'Restore' : 'Maximize'}>
{maximized ? <RestoreDown size={12} stroke={2} /> : <Square size={12} stroke={2} />} {maximized ? <RestoreDown size={12} stroke={2} /> : <Square size={12} stroke={2} />}
</TitlebarButton> </TitlebarButton>
<TitlebarButton onClick={() => win.close()} aria-label="Close" variant="close"> <TitlebarButton onClick={() => win?.close()} aria-label="Close" variant="close">
<X size={14} stroke={2.25} /> <X size={14} stroke={2.25} />
</TitlebarButton> </TitlebarButton>
</div> </div>