feat: 添加应用图标并实现更新提示徽标
- 新增应用图标资源 - 调整玻璃面板背景色优化视觉效果 - 重构标题栏布局,替换品牌Logo为应用图标 - 为检查更新按钮添加徽标,有更新时显示提示点 - 修改更新逻辑,保留已检测更新状态避免重复检查 - 简化模板代码格式,提升可读性 - 版本号从1.0.0更新为0.9.0
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "frpilot",
|
"name": "frpilot",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.0",
|
"version": "0.9.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
+3
-3
@@ -112,7 +112,7 @@ body {
|
|||||||
.glass-panel {
|
.glass-panel {
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
border: 1px solid rgba(255, 255, 255, 0.55);
|
border: 1px solid rgba(255, 255, 255, 0.55);
|
||||||
background: rgba(255, 255, 255, 0.35);
|
background: rgba(255, 255, 255, 0.45);
|
||||||
backdrop-filter: blur(18px) saturate(160%);
|
backdrop-filter: blur(18px) saturate(160%);
|
||||||
-webkit-backdrop-filter: blur(18px) saturate(160%);
|
-webkit-backdrop-filter: blur(18px) saturate(160%);
|
||||||
box-shadow: 0 8px 32px rgba(15, 23, 42, 0.12);
|
box-shadow: 0 8px 32px rgba(15, 23, 42, 0.12);
|
||||||
@@ -120,7 +120,7 @@ body {
|
|||||||
|
|
||||||
.dark .glass-panel {
|
.dark .glass-panel {
|
||||||
border-color: rgba(255, 255, 255, 0.08);
|
border-color: rgba(255, 255, 255, 0.08);
|
||||||
background: rgba(15, 23, 42, 0.55);
|
background: rgba(15, 23, 42, 0.45);
|
||||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ body {
|
|||||||
*/
|
*/
|
||||||
.glass-card.ant-card {
|
.glass-card.ant-card {
|
||||||
border: 1px solid rgba(255, 255, 255, 0.5) !important;
|
border: 1px solid rgba(255, 255, 255, 0.5) !important;
|
||||||
background: rgba(255, 255, 255, 0.5) !important;
|
background: rgba(255, 255, 255, 0.45) !important;
|
||||||
backdrop-filter: blur(16px) saturate(160%);
|
backdrop-filter: blur(16px) saturate(160%);
|
||||||
-webkit-backdrop-filter: blur(16px) saturate(160%);
|
-webkit-backdrop-filter: blur(16px) saturate(160%);
|
||||||
box-shadow: 0 6px 22px rgba(15, 23, 42, 0.08) !important;
|
box-shadow: 0 6px 22px rgba(15, 23, 42, 0.08) !important;
|
||||||
|
|||||||
@@ -2,22 +2,14 @@
|
|||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
<!-- 语言切换 -->
|
<!-- 语言切换 -->
|
||||||
<a-dropdown placement="bottomRight" trigger="click">
|
<a-dropdown placement="bottomRight" trigger="click">
|
||||||
<a-button
|
<a-button type="text" class="tb-btn" :title="t('titlebar.language')">
|
||||||
type="text"
|
<template #icon>
|
||||||
class="tb-btn"
|
<TranslationOutlined />
|
||||||
:title="t('titlebar.language')"
|
</template>
|
||||||
>
|
|
||||||
<template #icon><TranslationOutlined /></template>
|
|
||||||
</a-button>
|
</a-button>
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<a-menu
|
<a-menu :selected-keys="[appStore.language]" @click="onLanguageClick">
|
||||||
:selected-keys="[appStore.language]"
|
<a-menu-item v-for="item in languageOptions" :key="item.key">
|
||||||
@click="onLanguageClick"
|
|
||||||
>
|
|
||||||
<a-menu-item
|
|
||||||
v-for="item in languageOptions"
|
|
||||||
:key="item.key"
|
|
||||||
>
|
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
</a-menu>
|
</a-menu>
|
||||||
@@ -25,69 +17,50 @@
|
|||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
|
|
||||||
<!-- 明暗切换 -->
|
<!-- 明暗切换 -->
|
||||||
<a-button
|
<a-button type="text" class="tb-btn" :title="appStore.isDark ? t('titlebar.lightMode') : t('titlebar.darkMode')"
|
||||||
type="text"
|
@click="appStore.toggleDark()">
|
||||||
class="tb-btn"
|
|
||||||
:title="appStore.isDark ? t('titlebar.lightMode') : t('titlebar.darkMode')"
|
|
||||||
@click="appStore.toggleDark()"
|
|
||||||
>
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<BulbFilled v-if="appStore.isDark" />
|
<BulbFilled v-if="appStore.isDark" />
|
||||||
<BulbOutlined v-else />
|
<BulbOutlined v-else />
|
||||||
</template>
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
||||||
<!-- 检查更新 -->
|
<!-- 检查更新(有新版本时显示圆点徽标) -->
|
||||||
<a-button
|
<a-badge :dot="updateStore.hasUpdate">
|
||||||
type="text"
|
<a-button type="text" class="tb-btn" :title="t('titlebar.checkUpdate')" :loading="updateStore.checking"
|
||||||
class="tb-btn"
|
@click="onCheckUpdate">
|
||||||
:title="t('titlebar.checkUpdate')"
|
<template #icon>
|
||||||
:loading="updateStore.checking"
|
<CloudSyncOutlined />
|
||||||
@click="onCheckUpdate"
|
</template>
|
||||||
>
|
</a-button>
|
||||||
<template #icon><CloudSyncOutlined /></template>
|
</a-badge>
|
||||||
</a-button>
|
|
||||||
|
|
||||||
<!-- GitHub -->
|
<!-- GitHub -->
|
||||||
<a-button
|
<a-button type="text" class="tb-btn" :title="t('titlebar.github')" @click="onOpenGithub">
|
||||||
type="text"
|
<template #icon>
|
||||||
class="tb-btn"
|
<GithubOutlined />
|
||||||
:title="t('titlebar.github')"
|
</template>
|
||||||
@click="onOpenGithub"
|
|
||||||
>
|
|
||||||
<template #icon><GithubOutlined /></template>
|
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
||||||
<!-- 设置 -->
|
<!-- 设置 -->
|
||||||
<a-button
|
<a-button type="text" class="tb-btn" :title="t('titlebar.settings')" @click="emit('settings')">
|
||||||
type="text"
|
<template #icon>
|
||||||
class="tb-btn"
|
<SettingOutlined />
|
||||||
:title="t('titlebar.settings')"
|
</template>
|
||||||
@click="emit('settings')"
|
|
||||||
>
|
|
||||||
<template #icon><SettingOutlined /></template>
|
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
||||||
<!-- 最小化(macOS 由左侧红绿灯负责,此处隐藏) -->
|
<!-- 最小化(macOS 由左侧红绿灯负责,此处隐藏) -->
|
||||||
<a-button
|
<a-button v-if="!isMac" type="text" class="tb-btn" :title="t('titlebar.minimize')" @click="minimizeWindow()">
|
||||||
v-if="!isMac"
|
<template #icon>
|
||||||
type="text"
|
<MinusOutlined />
|
||||||
class="tb-btn"
|
</template>
|
||||||
:title="t('titlebar.minimize')"
|
|
||||||
@click="minimizeWindow()"
|
|
||||||
>
|
|
||||||
<template #icon><MinusOutlined /></template>
|
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
||||||
<!-- 关闭(macOS 由左侧红绿灯负责,此处隐藏) -->
|
<!-- 关闭(macOS 由左侧红绿灯负责,此处隐藏) -->
|
||||||
<a-button
|
<a-button v-if="!isMac" type="text" class="tb-btn tb-btn-close" :title="t('titlebar.close')" @click="closeWindow()">
|
||||||
v-if="!isMac"
|
<template #icon>
|
||||||
type="text"
|
<CloseOutlined />
|
||||||
class="tb-btn tb-btn-close"
|
</template>
|
||||||
:title="t('titlebar.close')"
|
|
||||||
@click="closeWindow()"
|
|
||||||
>
|
|
||||||
<template #icon><CloseOutlined /></template>
|
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,15 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-modal
|
<a-modal :open="store.modalOpen" :title="modalTitle" :closable="!store.installing" :mask-closable="false"
|
||||||
:open="store.modalOpen"
|
:keyboard="!store.installing" :width="520" centered wrap-class-name="update-modal-wrap" @cancel="onCancel">
|
||||||
:title="modalTitle"
|
|
||||||
:closable="!store.installing"
|
|
||||||
:mask-closable="false"
|
|
||||||
:keyboard="!store.installing"
|
|
||||||
:width="520"
|
|
||||||
centered
|
|
||||||
wrap-class-name="update-modal-wrap"
|
|
||||||
@cancel="onCancel"
|
|
||||||
>
|
|
||||||
<!-- 俏皮的问候 + 版本变化 -->
|
<!-- 俏皮的问候 + 版本变化 -->
|
||||||
<div class="update-hero">
|
<div class="update-hero">
|
||||||
<span class="update-hero-emoji">🎉</span>
|
<span class="update-hero-emoji">🎉</span>
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- Windows 自定义标题栏 -->
|
<!-- Windows 自定义标题栏 -->
|
||||||
<div
|
<div class="titlebar flex h-12 shrink-0 items-center justify-between pl-4 pr-2 select-none" data-tauri-drag-region>
|
||||||
class="titlebar flex h-12 shrink-0 items-center justify-between pl-4 pr-2 select-none"
|
<!-- 左侧:图标 + 标题 -->
|
||||||
data-tauri-drag-region
|
|
||||||
>
|
|
||||||
<!-- 左侧:标题 -->
|
|
||||||
<div class="flex items-center gap-2" data-tauri-drag-region>
|
<div class="flex items-center gap-2" data-tauri-drag-region>
|
||||||
<span class="brand-logo">F</span>
|
<img
|
||||||
|
class="h-[22px] w-[22px] shrink-0 object-contain"
|
||||||
|
:src="appIcon"
|
||||||
|
alt=""
|
||||||
|
draggable="false"
|
||||||
|
/>
|
||||||
<span class="text-sm font-semibold tracking-wide">Frpilot</span>
|
<span class="text-sm font-semibold tracking-wide">Frpilot</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -17,21 +19,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import TitleBarActions from "./TitleBarActions.vue"
|
import TitleBarActions from "./TitleBarActions.vue"
|
||||||
|
import appIcon from "@/assets/images/app-icon.webp"
|
||||||
|
|
||||||
const emit = defineEmits<{ settings: [] }>()
|
const emit = defineEmits<{ settings: [] }>()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.brand-logo {
|
|
||||||
display: inline-flex;
|
|
||||||
height: 22px;
|
|
||||||
width: 22px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border-radius: 6px;
|
|
||||||
background: linear-gradient(135deg, #6366f1, #22d3ee);
|
|
||||||
color: #fff;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
+13
-2
@@ -60,11 +60,19 @@ export const useUpdateStore = defineStore("update", () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 已检测到可用更新(例如用户点过「取消」关掉了弹窗):直接重新打开,
|
||||||
|
// 避免重复联网检查、重复创建后端资源;徽标也因此能持续提示。
|
||||||
|
if (pending) {
|
||||||
|
modalOpen.value = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
checking.value = true
|
checking.value = true
|
||||||
try {
|
try {
|
||||||
const update = await checkForAppUpdate()
|
const update = await checkForAppUpdate()
|
||||||
|
|
||||||
if (!update) {
|
if (!update) {
|
||||||
|
info.value = null
|
||||||
if (!silent) message.success(translate("update.upToDate"))
|
if (!silent) message.success(translate("update.upToDate"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -107,9 +115,12 @@ export const useUpdateStore = defineStore("update", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 取消(本次不更新,下次启动仍会提示) */
|
/**
|
||||||
|
* 取消:仅关闭弹窗,保留已检测到的可用更新。
|
||||||
|
* 顶部栏 / 关于页的圆点徽标会继续提示,再次点击「检查更新」可重新打开弹窗。
|
||||||
|
*/
|
||||||
function cancel() {
|
function cancel() {
|
||||||
void discard()
|
modalOpen.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 忽略该版本(持久化,静默检查不再提示) */
|
/** 忽略该版本(持久化,静默检查不再提示) */
|
||||||
|
|||||||
Vendored
+1
@@ -11,6 +11,7 @@ export {}
|
|||||||
/* prettier-ignore */
|
/* prettier-ignore */
|
||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
|
ABadge: typeof import('ant-design-vue/es')['Badge']
|
||||||
AButton: typeof import('ant-design-vue/es')['Button']
|
AButton: typeof import('ant-design-vue/es')['Button']
|
||||||
ACard: typeof import('ant-design-vue/es')['Card']
|
ACard: typeof import('ant-design-vue/es')['Card']
|
||||||
ACol: typeof import('ant-design-vue/es')['Col']
|
ACol: typeof import('ant-design-vue/es')['Col']
|
||||||
|
|||||||
@@ -48,9 +48,11 @@
|
|||||||
<div class="flex flex-wrap items-center gap-3">
|
<div class="flex flex-wrap items-center gap-3">
|
||||||
<span class="text-xs opacity-60">{{ t("about.currentVersion") }}</span>
|
<span class="text-xs opacity-60">{{ t("about.currentVersion") }}</span>
|
||||||
<a-tag color="purple" class="!me-0">v{{ version }}</a-tag>
|
<a-tag color="purple" class="!me-0">v{{ version }}</a-tag>
|
||||||
<a-button size="small" :loading="updateStore.checking" @click="onCheckUpdate">
|
<a-badge :dot="updateStore.hasUpdate">
|
||||||
{{ t("about.checkUpdate") }}
|
<a-button size="small" :loading="updateStore.checking" @click="onCheckUpdate">
|
||||||
</a-button>
|
{{ t("about.checkUpdate") }}
|
||||||
|
</a-button>
|
||||||
|
</a-badge>
|
||||||
<span v-if="updateStore.hasUpdate" class="text-xs text-[#6366f1]">
|
<span v-if="updateStore.hasUpdate" class="text-xs text-[#6366f1]">
|
||||||
{{ t("about.newVersion", { version: updateStore.info?.version }) }}
|
{{ t("about.newVersion", { version: updateStore.info?.version }) }}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user