tips
This commit is contained in:
@@ -36,7 +36,6 @@ const displayModules = computed(() => {
|
||||
'bg-primary text-primary-foreground shadow-md': activeModule === module.id,
|
||||
'hover:bg-secondary/50': activeModule !== module.id
|
||||
}"
|
||||
:title="module.name"
|
||||
@click="emit('change', module.id)"
|
||||
>
|
||||
<component :is="getModuleIcon(module.icon)" class="h-5 w-5" />
|
||||
@@ -61,7 +60,6 @@ const displayModules = computed(() => {
|
||||
'bg-primary text-primary-foreground shadow-md': activeModule === 'settings',
|
||||
'hover:bg-secondary/50': activeModule !== 'settings'
|
||||
}"
|
||||
title="常规设置"
|
||||
@click="emit('change', 'settings')"
|
||||
>
|
||||
<Settings class="h-5 w-5" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
import { Search, Minus, X, Settings, ChevronRight } from '@lucide/vue'
|
||||
import { Search, 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'
|
||||
@@ -263,7 +263,10 @@ const handleBlur = () => {
|
||||
@click="minimize"
|
||||
@mousedown.stop
|
||||
>
|
||||
<Minus class="h-4 w-4" />
|
||||
<!-- 最小化:水平线,1:1 渲染 + 0.5 像素偏移确保锐利 -->
|
||||
<svg class="w-[10px] h-[10px]" viewBox="0 0 10 10" fill="none" stroke="currentColor" stroke-width="1" shape-rendering="geometricPrecision">
|
||||
<path d="M0 5.5 H10" />
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
id="titlebar-maximize"
|
||||
@@ -271,14 +274,16 @@ const handleBlur = () => {
|
||||
@click="maximize"
|
||||
@mousedown.stop
|
||||
>
|
||||
<!-- 最大化:单圆角矩形 -->
|
||||
<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" />
|
||||
<!-- 最大化:单正方形(Windows 11 原生样式) -->
|
||||
<svg v-if="!isMaximized" class="w-[10px] h-[10px]" viewBox="0 0 10 10" fill="none" stroke="currentColor" stroke-width="1" shape-rendering="geometricPrecision">
|
||||
<rect x="0.5" y="0.5" width="9" height="9" />
|
||||
</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" />
|
||||
<!-- 还原:两个重叠正方形,前正方形在左下、后正方形在右上(Windows 11 原生样式) -->
|
||||
<svg v-else class="w-[10px] h-[10px]" viewBox="0 0 10 10" fill="none" stroke="currentColor" stroke-width="1" shape-rendering="geometricPrecision">
|
||||
<!-- 后正方形(右上):只勾勒未被前正方形遮挡的可见轮廓,在 (2.5,2.5) 与 (7.5,7.5) 交汇点停止 -->
|
||||
<path d="M2.5 0.5 H9.5 V7.5 H7.5 V2.5 H2.5 Z" />
|
||||
<!-- 前正方形(左下):完整绘制 -->
|
||||
<path d="M0.5 2.5 H7.5 V9.5 H0.5 Z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
@@ -286,7 +291,10 @@ const handleBlur = () => {
|
||||
@click="close"
|
||||
@mousedown.stop
|
||||
>
|
||||
<X class="h-4 w-4" />
|
||||
<!-- 关闭:X 对角线 -->
|
||||
<svg class="w-[10px] h-[10px]" viewBox="0 0 10 10" fill="none" stroke="currentColor" stroke-width="1.05" shape-rendering="geometricPrecision">
|
||||
<path d="M0.5 0.5 L9.5 9.5 M9.5 0.5 L0.5 9.5" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -21,6 +21,7 @@ import { Switch } from '@/components/ui/switch'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'
|
||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
@@ -506,16 +507,20 @@ const toggleSortOrder = () => {
|
||||
<!-- 工具栏:筛选 / 排序 / 搜索 -->
|
||||
<div class="shrink-0 flex items-center gap-2 flex-wrap">
|
||||
<!-- 新建下载按钮 -->
|
||||
<Button
|
||||
size="sm"
|
||||
class="h-8 gap-1.5"
|
||||
:disabled="addingTask"
|
||||
title="添加下载链接"
|
||||
@click="addDialogOpen = true"
|
||||
>
|
||||
<Plus class="h-4 w-4" />
|
||||
新建下载
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="sm"
|
||||
class="h-8 gap-1.5"
|
||||
:disabled="addingTask"
|
||||
@click="addDialogOpen = true"
|
||||
>
|
||||
<Plus class="h-4 w-4" />
|
||||
新建下载
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>添加下载链接</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<!-- 状态筛选 -->
|
||||
<Select v-model="statusFilter">
|
||||
@@ -550,16 +555,20 @@ const toggleSortOrder = () => {
|
||||
</Select>
|
||||
|
||||
<!-- 升降序切换 -->
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
class="h-8 w-8 p-0 bg-transparent"
|
||||
:title="sortOrder === 'asc' ? '升序(点击切换降序)' : '降序(点击切换升序)'"
|
||||
@click="toggleSortOrder"
|
||||
>
|
||||
<ArrowUp v-if="sortOrder === 'asc'" class="h-4 w-4" />
|
||||
<ArrowDown v-else class="h-4 w-4" />
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
class="h-8 w-8 p-0 bg-transparent"
|
||||
@click="toggleSortOrder"
|
||||
>
|
||||
<ArrowUp v-if="sortOrder === 'asc'" class="h-4 w-4" />
|
||||
<ArrowDown v-else class="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{{ sortOrder === 'asc' ? '升序(点击切换降序)' : '降序(点击切换升序)' }}</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<!-- 搜索框 -->
|
||||
<div class="relative flex-1 min-w-[180px] max-w-xs">
|
||||
@@ -571,16 +580,20 @@ const toggleSortOrder = () => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
class="h-8 gap-1.5 bg-transparent"
|
||||
title="下载设置"
|
||||
@click="downloadSettingsOpen = true"
|
||||
>
|
||||
<SettingsIcon class="h-4 w-4" />
|
||||
下载设置
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
class="h-8 gap-1.5 bg-transparent"
|
||||
@click="downloadSettingsOpen = true"
|
||||
>
|
||||
<SettingsIcon class="h-4 w-4" />
|
||||
下载设置
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>下载设置</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<span class="text-xs text-muted-foreground ml-auto">
|
||||
共 {{ sortedTasks.length }} 个任务
|
||||
@@ -603,9 +616,14 @@ const toggleSortOrder = () => {
|
||||
<div class="flex items-start justify-between gap-3 mb-3">
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<span class="font-medium truncate" :title="getFileName(task)">
|
||||
{{ getFileName(task) }}
|
||||
</span>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<span class="font-medium truncate cursor-default">
|
||||
{{ getFileName(task) }}
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{{ getFileName(task) }}</TooltipContent>
|
||||
</Tooltip>
|
||||
<Badge
|
||||
:variant="getTaskStatusBadge(task).variant"
|
||||
class="shrink-0"
|
||||
@@ -626,67 +644,85 @@ const toggleSortOrder = () => {
|
||||
<Zap class="h-2.5 w-2.5" />
|
||||
{{ task.segments.length }} 连接
|
||||
</Badge>
|
||||
<span
|
||||
v-if="task.dir"
|
||||
class="truncate max-w-md cursor-help"
|
||||
:title="task.dir"
|
||||
>
|
||||
{{ truncatePath(task.dir) }}
|
||||
</span>
|
||||
<Tooltip v-if="task.dir">
|
||||
<TooltipTrigger as-child>
|
||||
<span class="truncate max-w-md cursor-default">
|
||||
{{ truncatePath(task.dir) }}
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent class="max-w-[400px] break-all">{{ task.dir }}</TooltipContent>
|
||||
</Tooltip>
|
||||
<span v-if="task.error" class="text-destructive">
|
||||
{{ task.error }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 shrink-0">
|
||||
<Button
|
||||
v-if="task.status === 'active' || task.status === 'queued'"
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8"
|
||||
:title="task.status === 'queued' ? '取消排队' : '暂停'"
|
||||
@click="handlePause(task.id)"
|
||||
>
|
||||
<Pause class="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
v-if="task.status === 'paused' || task.status === 'error'"
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8"
|
||||
title="继续"
|
||||
@click="handleResume(task.id)"
|
||||
>
|
||||
<Play class="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8"
|
||||
title="详细信息"
|
||||
@click="handleShowDetail(task)"
|
||||
>
|
||||
<Info class="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
v-if="task.dir"
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8"
|
||||
title="打开目录"
|
||||
@click="handleOpenDir(task)"
|
||||
>
|
||||
<FolderOpen class="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8 text-destructive hover:text-destructive"
|
||||
title="删除"
|
||||
@click="handleRemove(task)"
|
||||
>
|
||||
<Trash2 class="h-4 w-4" />
|
||||
</Button>
|
||||
<Tooltip v-if="task.status === 'active' || task.status === 'queued'">
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8"
|
||||
@click="handlePause(task.id)"
|
||||
>
|
||||
<Pause class="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{{ task.status === 'queued' ? '取消排队' : '暂停' }}</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip v-if="task.status === 'paused' || task.status === 'error'">
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8"
|
||||
@click="handleResume(task.id)"
|
||||
>
|
||||
<Play class="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>继续</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8"
|
||||
@click="handleShowDetail(task)"
|
||||
>
|
||||
<Info class="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>详细信息</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip v-if="task.dir">
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8"
|
||||
@click="handleOpenDir(task)"
|
||||
>
|
||||
<FolderOpen class="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>打开目录</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8 text-destructive hover:text-destructive"
|
||||
@click="handleRemove(task)"
|
||||
>
|
||||
<Trash2 class="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>删除</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<Progress :model-value="getProgress(task)" class="h-1.5" />
|
||||
@@ -702,51 +738,67 @@ const toggleSortOrder = () => {
|
||||
|
||||
<!-- 分页控件 -->
|
||||
<div v-if="totalPages > 1" class="flex items-center justify-center gap-2 pt-2 pb-4">
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
class="h-8 w-8 p-0"
|
||||
:disabled="currentPage <= 1"
|
||||
title="第一页"
|
||||
@click="currentPage = 1"
|
||||
>
|
||||
<ChevronLeft class="h-4 w-4" />
|
||||
<ChevronLeft class="h-4 w-4 -ml-2" />
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
class="h-8 w-8 p-0"
|
||||
:disabled="currentPage <= 1"
|
||||
title="上一页"
|
||||
@click="currentPage--"
|
||||
>
|
||||
<ChevronLeft class="h-4 w-4" />
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
class="h-8 w-8 p-0"
|
||||
:disabled="currentPage <= 1"
|
||||
@click="currentPage = 1"
|
||||
>
|
||||
<ChevronLeft class="h-4 w-4" />
|
||||
<ChevronLeft class="h-4 w-4 -ml-2" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>第一页</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
class="h-8 w-8 p-0"
|
||||
:disabled="currentPage <= 1"
|
||||
@click="currentPage--"
|
||||
>
|
||||
<ChevronLeft class="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>上一页</TooltipContent>
|
||||
</Tooltip>
|
||||
<span class="text-xs text-muted-foreground px-2">
|
||||
{{ currentPage }} / {{ totalPages }}
|
||||
</span>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
class="h-8 w-8 p-0"
|
||||
:disabled="currentPage >= totalPages"
|
||||
title="下一页"
|
||||
@click="currentPage++"
|
||||
>
|
||||
<ChevronRight class="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
class="h-8 w-8 p-0"
|
||||
:disabled="currentPage >= totalPages"
|
||||
title="最后一页"
|
||||
@click="currentPage = totalPages"
|
||||
>
|
||||
<ChevronRight class="h-4 w-4" />
|
||||
<ChevronRight class="h-4 w-4 -ml-2" />
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
class="h-8 w-8 p-0"
|
||||
:disabled="currentPage >= totalPages"
|
||||
@click="currentPage++"
|
||||
>
|
||||
<ChevronRight class="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>下一页</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
class="h-8 w-8 p-0"
|
||||
:disabled="currentPage >= totalPages"
|
||||
@click="currentPage = totalPages"
|
||||
>
|
||||
<ChevronRight class="h-4 w-4" />
|
||||
<ChevronRight class="h-4 w-4 -ml-2" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>最后一页</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</div>
|
||||
@@ -781,9 +833,14 @@ const toggleSortOrder = () => {
|
||||
class="font-mono text-sm"
|
||||
@update:model-value="(v: string | number) => store.settings && (store.settings.downloadDir = String(v))"
|
||||
/>
|
||||
<Button variant="outline" size="icon" title="选择目录" @click="handleSelectSettingsDir">
|
||||
<FolderOpen class="h-4 w-4" />
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button variant="outline" size="icon" @click="handleSelectSettingsDir">
|
||||
<FolderOpen class="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>选择目录</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
@@ -900,19 +957,28 @@ const toggleSortOrder = () => {
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div class="flex flex-col gap-0.5 min-w-0">
|
||||
<Label class="text-xs text-muted-foreground">API 地址</Label>
|
||||
<span class="font-mono text-sm truncate" :title="store.extensionInfo.url">
|
||||
{{ store.extensionInfo.url }}
|
||||
</span>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<span class="font-mono text-sm truncate cursor-default">
|
||||
{{ store.extensionInfo.url }}
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent class="max-w-[400px] break-all">{{ store.extensionInfo.url }}</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8 shrink-0"
|
||||
title="复制 API 地址"
|
||||
@click="handleCopy(store.extensionInfo.url, 'API 地址')"
|
||||
>
|
||||
<Copy class="h-4 w-4" />
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8 shrink-0"
|
||||
@click="handleCopy(store.extensionInfo.url, 'API 地址')"
|
||||
>
|
||||
<Copy class="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>复制 API 地址</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
@@ -923,27 +989,33 @@ const toggleSortOrder = () => {
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex gap-1 shrink-0">
|
||||
<Button
|
||||
v-if="store.extensionInfo.secret"
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8"
|
||||
:title="showSecret ? '隐藏' : '显示'"
|
||||
@click="showSecret = !showSecret"
|
||||
>
|
||||
<Eye v-if="!showSecret" class="h-4 w-4" />
|
||||
<EyeOff v-else class="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
v-if="store.extensionInfo.secret"
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8"
|
||||
title="复制密钥"
|
||||
@click="handleCopy(store.extensionInfo.secret, '密钥')"
|
||||
>
|
||||
<Copy class="h-4 w-4" />
|
||||
</Button>
|
||||
<Tooltip v-if="store.extensionInfo.secret">
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8"
|
||||
@click="showSecret = !showSecret"
|
||||
>
|
||||
<Eye v-if="!showSecret" class="h-4 w-4" />
|
||||
<EyeOff v-else class="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{{ showSecret ? '隐藏' : '显示' }}</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip v-if="store.extensionInfo.secret">
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-8 w-8"
|
||||
@click="handleCopy(store.extensionInfo.secret, '密钥')"
|
||||
>
|
||||
<Copy class="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>复制密钥</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1002,9 +1074,14 @@ const toggleSortOrder = () => {
|
||||
class="font-mono text-sm"
|
||||
@update:model-value="(v: string | number) => store.settings && (store.settings.downloadDir = String(v))"
|
||||
/>
|
||||
<Button variant="outline" size="icon" title="选择目录" @click="handleSelectSettingsDir">
|
||||
<FolderOpen class="h-4 w-4" />
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button variant="outline" size="icon" @click="handleSelectSettingsDir">
|
||||
<FolderOpen class="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>选择目录</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1112,9 +1189,14 @@ const toggleSortOrder = () => {
|
||||
placeholder="留空使用默认目录"
|
||||
class="font-mono text-sm"
|
||||
/>
|
||||
<Button variant="outline" size="icon" title="选择目录" @click="handleSelectDir">
|
||||
<FolderOpen class="h-4 w-4" />
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button variant="outline" size="icon" @click="handleSelectDir">
|
||||
<FolderOpen class="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>选择目录</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<p v-if="store.settings?.downloadDir" class="text-xs text-muted-foreground">
|
||||
当前默认:
|
||||
@@ -1191,9 +1273,14 @@ const toggleSortOrder = () => {
|
||||
<span class="text-xs text-muted-foreground">文件名</span>
|
||||
<span class="font-medium break-all">{{ detailDialogState.task.filename }}</span>
|
||||
</div>
|
||||
<Button size="icon" variant="ghost" class="h-7 w-7 shrink-0" title="复制文件名" @click="handleCopyText(detailDialogState.task.filename, '文件名')">
|
||||
<Copy class="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button size="icon" variant="ghost" class="h-7 w-7 shrink-0" @click="handleCopyText(detailDialogState.task.filename, '文件名')">
|
||||
<Copy class="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>复制文件名</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
@@ -1213,9 +1300,14 @@ const toggleSortOrder = () => {
|
||||
<span class="text-xs text-muted-foreground">下载链接</span>
|
||||
<span class="font-mono text-xs break-all">{{ detailDialogState.task.url }}</span>
|
||||
</div>
|
||||
<Button size="icon" variant="ghost" class="h-7 w-7 shrink-0" title="复制链接" @click="handleCopyText(detailDialogState.task.url, '下载链接')">
|
||||
<Copy class="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button size="icon" variant="ghost" class="h-7 w-7 shrink-0" @click="handleCopyText(detailDialogState.task.url, '下载链接')">
|
||||
<Copy class="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>复制链接</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
@@ -1224,12 +1316,22 @@ const toggleSortOrder = () => {
|
||||
<div class="flex items-start justify-between gap-2">
|
||||
<div class="flex flex-col gap-0.5 min-w-0 flex-1">
|
||||
<span class="text-xs text-muted-foreground">保存位置</span>
|
||||
<span class="font-mono text-xs break-all" :title="detailDialogState.task.dir">{{ detailDialogState.task.dir }}</span>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<span class="font-mono text-xs break-all cursor-default">{{ detailDialogState.task.dir }}</span>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent class="max-w-[400px] break-all">{{ detailDialogState.task.dir }}</TooltipContent>
|
||||
</Tooltip>
|
||||
<span class="font-mono text-xs text-muted-foreground break-all">{{ detailDialogState.task.filename }}</span>
|
||||
</div>
|
||||
<Button size="icon" variant="ghost" class="h-7 w-7 shrink-0" title="复制完整路径" @click="handleCopyText(detailDialogState.task.dir + '\\' + detailDialogState.task.filename, '完整路径')">
|
||||
<Copy class="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button size="icon" variant="ghost" class="h-7 w-7 shrink-0" @click="handleCopyText(detailDialogState.task.dir + '\\' + detailDialogState.task.filename, '完整路径')">
|
||||
<Copy class="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>复制完整路径</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Switch } from '@/components/ui/switch'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import { useAppStore, type Theme, type EffectType, type ModuleInfo } from '@/stores/appStore'
|
||||
import { useSearchStore } from '@/stores/searchStore'
|
||||
import { useProcessStore } from '@/stores/processStore'
|
||||
@@ -265,12 +266,16 @@ const onDragEnd = () => {
|
||||
:class="{ 'opacity-60': isModuleToggling(module.id) }"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<div
|
||||
class="drag-handle cursor-grab active:cursor-grabbing text-muted-foreground/40 hover:text-muted-foreground transition-colors"
|
||||
title="拖拽排序"
|
||||
>
|
||||
<GripVertical class="h-4 w-4 no-native-drag" />
|
||||
</div>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<div
|
||||
class="drag-handle cursor-grab active:cursor-grabbing text-muted-foreground/40 hover:text-muted-foreground transition-colors"
|
||||
>
|
||||
<GripVertical class="h-4 w-4 no-native-drag" />
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>拖拽排序</TooltipContent>
|
||||
</Tooltip>
|
||||
<div
|
||||
class="w-9 h-9 rounded-lg flex items-center justify-center"
|
||||
:class="module.enabled ? 'bg-primary/10 text-primary' : 'bg-muted text-muted-foreground'"
|
||||
|
||||
@@ -22,6 +22,7 @@ import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'
|
||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@/components/ui/accordion'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import { Progress } from '@/components/ui/progress'
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
|
||||
import {
|
||||
@@ -924,9 +925,14 @@ const saveSettingsForm = async () => {
|
||||
</div>
|
||||
<div v-if="store.kernel?.exists" class="flex items-center justify-between">
|
||||
<span class="text-muted-foreground">当前版本</span>
|
||||
<Badge variant="secondary" class="font-mono text-xs" :title="store.kernel?.version ?? ''">
|
||||
{{ versionShort }}
|
||||
</Badge>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Badge variant="secondary" class="font-mono text-xs cursor-default">
|
||||
{{ versionShort }}
|
||||
</Badge>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{{ store.kernel?.version ?? '' }}</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div v-if="kernelUpdateInfo" class="flex items-center justify-between">
|
||||
<span class="text-muted-foreground">最新版本</span>
|
||||
@@ -947,19 +953,33 @@ const saveSettingsForm = async () => {
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<span class="text-muted-foreground shrink-0">路径</span>
|
||||
<div class="flex items-center gap-1.5 min-w-0">
|
||||
<span
|
||||
v-if="store.kernel?.exists"
|
||||
class="font-mono text-xs text-right truncate"
|
||||
:title="store.kernel?.path ?? ''"
|
||||
>{{ pathDisplay || pathShort }}</span>
|
||||
<span v-else class="font-mono text-xs text-right" :title="store.kernel?.path ?? ''">{{ pathShort }}</span>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<span
|
||||
v-if="store.kernel?.exists"
|
||||
class="font-mono text-xs text-right truncate cursor-default"
|
||||
>{{ pathDisplay || pathShort }}</span>
|
||||
<span v-else class="font-mono text-xs text-right cursor-default">{{ pathShort }}</span>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent class="max-w-[400px] break-all">{{ store.kernel?.path ?? '' }}</TooltipContent>
|
||||
</Tooltip>
|
||||
<template v-if="store.kernel?.exists">
|
||||
<Button size="icon-xs" variant="ghost" title="复制路径" @click="copyPath">
|
||||
<Copy class="size-3" />
|
||||
</Button>
|
||||
<Button size="icon-xs" variant="ghost" title="在文件夹中显示" @click="openFolder">
|
||||
<FolderOpen class="size-3" />
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button size="icon-xs" variant="ghost" @click="copyPath">
|
||||
<Copy class="size-3" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>复制路径</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button size="icon-xs" variant="ghost" @click="openFolder">
|
||||
<FolderOpen class="size-3" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>在文件夹中显示</TooltipContent>
|
||||
</Tooltip>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1448,18 +1468,32 @@ const saveSettingsForm = async () => {
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-1 shrink-0">
|
||||
<Button size="icon-sm" variant="ghost" title="更新" @click="doUpdate(p.id)">
|
||||
<RefreshCw class="size-3.5" />
|
||||
</Button>
|
||||
<Button
|
||||
v-if="store.settings.currentProfile !== p.id"
|
||||
size="icon-sm" variant="ghost" title="切换" @click="doActivate(p.id)"
|
||||
>
|
||||
<Check class="size-3.5" />
|
||||
</Button>
|
||||
<Button size="icon-sm" variant="ghost" title="删除" @click="doDelete(p.id, p.name)">
|
||||
<Trash2 class="size-3.5 text-destructive" />
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button size="icon-sm" variant="ghost" @click="doUpdate(p.id)">
|
||||
<RefreshCw class="size-3.5" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>更新</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip v-if="store.settings.currentProfile !== p.id">
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="icon-sm" variant="ghost" @click="doActivate(p.id)"
|
||||
>
|
||||
<Check class="size-3.5" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>切换</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button size="icon-sm" variant="ghost" @click="doDelete(p.id, p.name)">
|
||||
<Trash2 class="size-3.5 text-destructive" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>删除</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user