mirror of
https://github.com/atdunbg/Nekosonic-Music.git
synced 2026-06-22 00:58:51 +08:00
新功能: - 亮色主题:新增浅色外观模式,7种主题色各有对应亮色变体 - 封面主色背景:漫游抽屉自动提取封面主色,PlayerBar跟随继承 - 发现页重做:多类型搜索(歌曲/歌手/专辑)+搜索建议+搜索历史 - 漫游页重做:进入即播放,布局改为封面+歌名+播放/下一首/减少推荐 - 减少推荐:FM模式下可标记不推荐歌曲或歌手 - 列表风格统一:播放指示器跳动动画+hover播放图标+图标统一使用Lucide 修复: - 专辑页艺术家过多时窗口缩小竖排,改为自动换行 - FM播放时退出登录后首页仍可点击下一首 - 本地音乐播放时缓冲进度条未重置 - 亮色主题下多处文字不可见 - 退出FM模式时状态未正确清理 - 暗色模式下关闭抽屉时PlayerBar闪烁亮色(改用opacity过渡) - player.ts tickInterval双变量状态不同步,统一为clearTick/setTick 变更: - 移除播放列表按钮数字角标 - 主页卡片标题固定白色不随主题变化 - 全项目空catch块格式统一 - 清理冗余注释和代码
143 lines
3.3 KiB
TypeScript
143 lines
3.3 KiB
TypeScript
import { ref } from 'vue'
|
|
import { check } from '@tauri-apps/plugin-updater'
|
|
import { relaunch } from '@tauri-apps/plugin-process'
|
|
import { getVersion } from '@tauri-apps/api/app'
|
|
|
|
export interface UpdateInfo {
|
|
version: string
|
|
date: string | null
|
|
body: string | null
|
|
}
|
|
|
|
const IGNORED_VERSION_KEY = 'updater_ignored_version'
|
|
|
|
export function useUpdater() {
|
|
const checking = ref(false)
|
|
const downloading = ref(false)
|
|
const downloadProgress = ref(0)
|
|
const updateAvailable = ref(false)
|
|
const updateInfo = ref<UpdateInfo | null>(null)
|
|
const currentVersion = ref('')
|
|
const error = ref('')
|
|
|
|
async function getCurrentVersion() {
|
|
try {
|
|
currentVersion.value = await getVersion()
|
|
} catch {
|
|
currentVersion.value = ''
|
|
}
|
|
}
|
|
|
|
function getIgnoredVersion(): string {
|
|
try {
|
|
return localStorage.getItem(IGNORED_VERSION_KEY) || ''
|
|
} catch {
|
|
return ''
|
|
}
|
|
}
|
|
|
|
function setIgnoredVersion(version: string) {
|
|
try {
|
|
localStorage.setItem(IGNORED_VERSION_KEY, version)
|
|
} catch { /* 忽略 */ }
|
|
}
|
|
|
|
async function checkForUpdate(silent = false): Promise<UpdateInfo | null> {
|
|
if (checking.value) return null
|
|
checking.value = true
|
|
error.value = ''
|
|
updateAvailable.value = false
|
|
updateInfo.value = null
|
|
|
|
try {
|
|
await getCurrentVersion()
|
|
const result = await check()
|
|
|
|
if (!result) {
|
|
if (!silent) error.value = '当前已是最新版本'
|
|
return null
|
|
}
|
|
|
|
const info: UpdateInfo = {
|
|
version: result.version,
|
|
date: result.date ?? null,
|
|
body: result.body ?? null,
|
|
}
|
|
|
|
const ignored = getIgnoredVersion()
|
|
if (info.version === ignored && silent) {
|
|
return null
|
|
}
|
|
|
|
updateAvailable.value = true
|
|
updateInfo.value = info
|
|
return info
|
|
} catch (e: any) {
|
|
if (!silent) error.value = `检查更新失败: ${e}`
|
|
return null
|
|
} finally {
|
|
checking.value = false
|
|
}
|
|
}
|
|
|
|
async function downloadAndInstall() {
|
|
if (downloading.value) return
|
|
downloading.value = true
|
|
downloadProgress.value = 0
|
|
error.value = ''
|
|
|
|
try {
|
|
const result = await check()
|
|
if (!result) {
|
|
error.value = '未找到可用更新'
|
|
return
|
|
}
|
|
|
|
let downloaded = 0
|
|
let contentLength = 0
|
|
await result.downloadAndInstall((event) => {
|
|
switch (event.event) {
|
|
case 'Started':
|
|
contentLength = event.data.contentLength ?? 0
|
|
break
|
|
case 'Progress':
|
|
downloaded += event.data.chunkLength
|
|
if (contentLength > 0) {
|
|
downloadProgress.value = Math.round((downloaded / contentLength) * 100)
|
|
}
|
|
break
|
|
case 'Finished':
|
|
downloadProgress.value = 100
|
|
break
|
|
}
|
|
})
|
|
|
|
await relaunch()
|
|
} catch (e: any) {
|
|
error.value = `更新失败: ${e}`
|
|
} finally {
|
|
downloading.value = false
|
|
}
|
|
}
|
|
|
|
function ignoreVersion(version: string) {
|
|
setIgnoredVersion(version)
|
|
updateAvailable.value = false
|
|
updateInfo.value = null
|
|
}
|
|
|
|
return {
|
|
checking,
|
|
downloading,
|
|
downloadProgress,
|
|
updateAvailable,
|
|
updateInfo,
|
|
currentVersion,
|
|
error,
|
|
checkForUpdate,
|
|
downloadAndInstall,
|
|
ignoreVersion,
|
|
getCurrentVersion,
|
|
}
|
|
}
|