Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 39 additions & 6 deletions src/views/SettingsView.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, onMounted, computed } from 'vue';
import { ref, onMounted, computed, markRaw } from 'vue';
import { useUserStore, ThemeType } from '../stores/userStore';
import { useI18n } from 'vue-i18n';
import { availableLanguages, Language, getLanguageByCode } from '../i18n';
Expand Down Expand Up @@ -115,6 +115,38 @@ const downloadedBytes = ref(0);
const totalBytes = ref(0);
const downloadStatus = ref<'idle' | 'downloading' | 'installing' | 'completed' | 'error'>('idle');
const updateInstance = ref<Update | null>(null);
const UPDATE_STATE_KEY = 'sftool.updateState';

const hydrateUpdateState = () => {
try {
const raw = sessionStorage.getItem(UPDATE_STATE_KEY);
if (!raw) return;
const data = JSON.parse(raw) as { status?: string; version?: string; releaseNotes?: string };
if (data?.status === 'completed') {
downloadStatus.value = 'completed';
if (data.version) availableVersion.value = data.version;
if (data.releaseNotes) releaseNotes.value = data.releaseNotes;
updateAvailable.value = true;
}
} catch {
sessionStorage.removeItem(UPDATE_STATE_KEY);
}
};

const persistUpdateState = () => {
if (downloadStatus.value === 'completed') {
sessionStorage.setItem(
UPDATE_STATE_KEY,
JSON.stringify({
status: 'completed',
version: availableVersion.value,
releaseNotes: releaseNotes.value,
})
);
} else {
sessionStorage.removeItem(UPDATE_STATE_KEY);
}
};

// 格式化文件大小
const formatBytes = (bytes: number): string => {
Expand All @@ -139,7 +171,7 @@ const checkForUpdates = async () => {
updateAvailable.value = true;
availableVersion.value = update.version || '';
releaseNotes.value = update.body || '';
updateInstance.value = update;
updateInstance.value = markRaw(update);
} else {
updateAvailable.value = false;
availableVersion.value = '';
Expand All @@ -157,7 +189,6 @@ const checkForUpdates = async () => {
// 下载并安装更新
const downloadAndInstallUpdate = async () => {
if (!updateInstance.value || isDownloading.value) return;

isDownloading.value = true;
downloadStatus.value = 'downloading';
downloadProgress.value = 0;
Expand All @@ -166,6 +197,7 @@ const downloadAndInstallUpdate = async () => {

try {
await updateInstance.value.downloadAndInstall(event => {
console.log('Update event:', event);
switch (event.event) {
case 'Started':
totalBytes.value = event.data.contentLength || 0;
Expand All @@ -187,6 +219,7 @@ const downloadAndInstallUpdate = async () => {

// 下载安装完成
downloadStatus.value = 'completed';
persistUpdateState();
} catch (error: any) {
downloadStatus.value = 'error';
updateError.value = error?.message || String(error);
Expand All @@ -199,6 +232,7 @@ const downloadAndInstallUpdate = async () => {
// 重启应用
const restartApp = async () => {
try {
sessionStorage.removeItem(UPDATE_STATE_KEY);
await relaunch();
} catch (error) {
console.error('Failed to relaunch:', error);
Expand All @@ -212,11 +246,13 @@ const resetUpdateState = () => {
downloadedBytes.value = 0;
totalBytes.value = 0;
updateError.value = '';
sessionStorage.removeItem(UPDATE_STATE_KEY);
};

// 监听点击事件,用于关闭下拉菜单 + 启动时检查更新
onMounted(() => {
document.addEventListener('click', closeLanguageDropdown);
hydrateUpdateState();
checkForUpdates();
});
</script>
Expand Down Expand Up @@ -326,9 +362,6 @@ onMounted(() => {
<span class="material-icons">restart_alt</span>
{{ $t('setting.restart_now') }}
</button>
<button class="btn btn-ghost btn-sm" @click="resetUpdateState">
{{ $t('setting.restart_later') }}
</button>
</div>
</div>
</div>
Expand Down