设置页面自适应,添加查看最新版本日志按钮

This commit is contained in:
2026-05-16 13:34:10 +08:00
parent d718ee5b42
commit 68e3b92a6a

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="p-8 text-content max-w-2xl"> <div class="p-8 text-content">
<button @click="$router.back()" class="mb-4 text-content-2 hover:text-content transition"> <button @click="$router.back()" class="mb-4 text-content-2 hover:text-content transition">
返回 返回
</button> </button>
@ -157,15 +157,25 @@
<p class="text-xs text-content-3 leading-relaxed"> <p class="text-xs text-content-3 leading-relaxed">
Nekosonic 是一款高颜值的跨平台第三方网易云音乐桌面客户端基于 Tauri 2 + Vue 3 构建提供轻量流畅的音乐播放体验 Nekosonic 是一款高颜值的跨平台第三方网易云音乐桌面客户端基于 Tauri 2 + Vue 3 构建提供轻量流畅的音乐播放体验
</p> </p>
<button <div class="flex items-center gap-2">
@click="handleCheckUpdate" <button
:disabled="updater.checking.value" @click="handleCheckUpdate"
class="flex items-center gap-2 px-4 py-2 bg-subtle hover:bg-muted rounded-lg text-sm transition" :disabled="updater.checking.value"
> class="flex items-center gap-2 px-4 py-2 bg-subtle hover:bg-muted rounded-lg text-sm transition"
<svg v-if="!updater.checking.value" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg> >
<svg v-else class="animate-spin" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12a9 9 0 11-6.22-8.56"/></svg> <svg v-if="!updater.checking.value" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>
{{ updater.checking.value ? '检查中...' : '检查更新' }} <svg v-else class="animate-spin" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12a9 9 0 11-6.22-8.56"/></svg>
</button> {{ updater.checking.value ? '检查中...' : '检查更新' }}
</button>
<button
@click="fetchChangelog"
:disabled="fetchingChangelog"
class="flex items-center gap-2 px-4 py-2 bg-subtle hover:bg-muted rounded-lg text-sm transition"
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>
{{ fetchingChangelog ? '获取中...' : '更新日志' }}
</button>
</div>
<p v-if="updater.error.value" class="text-xs text-content-3">{{ updater.error.value }}</p> <p v-if="updater.error.value" class="text-xs text-content-3">{{ updater.error.value }}</p>
</div> </div>
</section> </section>
@ -188,6 +198,36 @@
</div> </div>
</Transition> </Transition>
<Transition name="fade">
<div v-if="showChangelogModal" class="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm" @click.self="showChangelogModal = false">
<div class="bg-surface border border-line rounded-2xl shadow-2xl w-[480px] max-h-[80vh] flex flex-col select-auto">
<div class="p-6 pb-4">
<div class="flex items-center justify-between mb-1">
<h2 class="text-lg font-semibold text-content">更新日志</h2>
<span v-if="changelogRelease" class="text-xs font-medium px-2 py-0.5 rounded-full bg-accent/15 text-accent-text">v{{ changelogRelease.tag_name?.replace('v', '') }}</span>
</div>
<p v-if="changelogRelease?.published_at" class="text-xs text-content-3 mt-1">{{ formatDate(changelogRelease.published_at) }}</p>
</div>
<div v-if="changelogRelease?.body" class="px-6 pb-4 flex-1 overflow-y-auto max-h-60">
<div class="text-sm text-content-2 leading-relaxed whitespace-pre-wrap">{{ changelogRelease.body }}</div>
</div>
<div v-else class="px-6 pb-4">
<p class="text-sm text-content-3">暂无更新日志</p>
</div>
<div class="p-4 border-t border-line flex gap-3">
<button @click="showChangelogModal = false"
class="flex-1 py-2 rounded-lg bg-muted hover:bg-emphasis text-sm text-content-2 transition">
关闭
</button>
<button v-if="changelogRelease?.html_url" @click="openUrl(changelogRelease.html_url)"
class="flex-1 py-2 rounded-lg bg-accent/20 hover:bg-accent/30 text-accent-text text-sm font-medium transition">
GitHub 中查看
</button>
</div>
</div>
</div>
</Transition>
</div> </div>
</template> </template>
@ -249,6 +289,38 @@ async function handleCheckUpdate() {
} }
} }
const fetchingChangelog = ref(false);
const changelogRelease = ref<any>(null);
const showChangelogModal = ref(false);
async function fetchChangelog() {
fetchingChangelog.value = true;
try {
const resp = await fetch('https://api.github.com/repos/atdunbg/Nekosonic-Music/releases?per_page=1');
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
const releases = await resp.json();
if (releases && releases.length > 0) {
changelogRelease.value = releases[0];
showChangelogModal.value = true;
} else {
showToast('暂无发布版本', 'info');
}
} catch (e: any) {
showToast(`获取失败: ${e}`, 'error');
} finally {
fetchingChangelog.value = false;
}
}
function formatDate(dateStr: string) {
try {
const d = new Date(dateStr);
return d.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' });
} catch {
return dateStr;
}
}
const recordingId = ref<string | null>(null); const recordingId = ref<string | null>(null);
function formatShortcut(key: string): string { function formatShortcut(key: string): string {