下载/主界面优化

This commit is contained in:
2026-07-22 22:26:40 +08:00
parent f7d3c13f35
commit 95a69b0017
16 changed files with 295 additions and 106 deletions
+44 -10
View File
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { ref, computed, onUnmounted } from 'vue'
import { Search, Minus, Square, X, Settings, ChevronRight } from '@lucide/vue'
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { Search, Minus, X, Settings, ChevronRight } from '@lucide/vue'
import { Input } from '@/components/ui/input'
import { getCurrentWindow } from '@tauri-apps/api/window'
import { useSearchStore, type SearchItem } from '@/stores/searchStore'
@@ -64,6 +64,10 @@ const minimize = async () => {
await tauriWindow?.minimize()
}
// 窗口最大化状态:切换最大化/还原图标
const isMaximized = ref(false)
let unlistenMaximize: (() => void) | null = null
const maximize = async () => {
await tauriWindow?.toggleMaximize()
}
@@ -119,9 +123,9 @@ if (tauriWindow) {
if (document.activeElement instanceof HTMLElement) {
document.activeElement.blur()
}
// 200ms 后恢复 hover,足够让浏览器重置伪类状态
restoreHover(200)
// 同时注册鼠标移动监听作为后备(定时器可能不够,鼠标移动更可靠)
// 不使用定时器恢复 hover:窗口从隐藏恢复显示时,浏览器 :hover 可能被冻结
// mouseleave 在窗口隐藏时不触发),定时器恢复会让冻结的 hover 提前暴露
// 仅依赖鼠标移动恢复——移动时浏览器才会重新评估 :hover 状态
armMouseMoveRestore()
} else {
hoverSuppressed.value = true
@@ -132,9 +136,23 @@ if (tauriWindow) {
// 初始时窗口已显示,恢复 hover
restoreHover(300)
onMounted(async () => {
if (tauriWindow) {
try {
isMaximized.value = await tauriWindow.isMaximized()
unlistenMaximize = await tauriWindow.onResized(async () => {
isMaximized.value = await tauriWindow!.isMaximized()
})
} catch {
// 非 Tauri 环境忽略
}
}
})
onUnmounted(() => {
window.removeEventListener('mousemove', handleFirstMouseMove)
if (restoreHoverTimer) clearTimeout(restoreHoverTimer)
if (unlistenMaximize) unlistenMaximize()
})
const handleBlur = () => {
@@ -241,21 +259,30 @@ const handleBlur = () => {
<div class="flex items-center pointer-events-auto" :class="{ 'hover-suppressed': hoverSuppressed }">
<button
class="h-10 w-10 flex items-center justify-center hover:bg-secondary/50 transition-colors rounded-sm"
class="h-10 w-10 flex items-center justify-center hover:bg-foreground/5 transition-colors rounded-sm"
@click="minimize"
@mousedown.stop
>
<Minus class="h-4 w-4" />
</button>
<button
class="h-10 w-10 flex items-center justify-center hover:bg-secondary/50 transition-colors rounded-sm"
id="titlebar-maximize"
class="h-10 w-10 flex items-center justify-center transition-colors rounded-sm titlebar-maximize-btn"
@click="maximize"
@mousedown.stop
>
<Square class="h-3.5 w-3.5" />
<!-- 最大化单圆角矩形 -->
<svg v-if="!isMaximized" class="h-3 w-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="4" y="4" width="16" height="16" rx="2" />
</svg>
<!-- 还原单圆角矩形 + 右上角圆角 L形顶边+右边圆角连接 -->
<svg v-else class="h-3 w-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="4" y="4" width="16" height="16" rx="2" />
<path d="M14 4H20V10" />
</svg>
</button>
<button
class="h-10 w-10 flex items-center justify-center hover:bg-destructive/20 transition-colors rounded-sm text-destructive"
class="h-10 w-10 flex items-center justify-center hover:bg-red-500 hover:text-white text-foreground transition-colors rounded-sm"
@click="close"
@mousedown.stop
>
@@ -267,10 +294,17 @@ const handleBlur = () => {
<style scoped>
/* 窗口隐藏/重新显示瞬间,抑制按钮 hover 样式,避免冻结的 :hover 残留 */
.hover-suppressed button:hover {
.hover-suppressed button:hover,
.hover-suppressed button.is-hovered {
background-color: transparent !important;
}
/* 最大化按钮:snap-layout 插件的原生子窗口遮挡了指针事件,
:hover 无法触发,改用插件注入的 .is-hovered 类(鼠标进入原生子窗口时添加) */
.titlebar-maximize-btn.is-hovered {
background-color: color-mix(in srgb, var(--foreground) 5%, transparent);
}
/* 浮动标签切换器进出动画:淡入 + 从左侧滑入 */
.floating-tabs-enter-active,
.floating-tabs-leave-active {