mirror of
https://github.com/OpenListTeam/OpenList-Desktop.git
synced 2025-11-25 19:27:33 +08:00
feat: enhance version update notifications
This commit is contained in:
@@ -9,7 +9,11 @@
|
|||||||
<span class="current-version">{{ currentVersions.openlist }}</span>
|
<span class="current-version">{{ currentVersions.openlist }}</span>
|
||||||
</div>
|
</div>
|
||||||
<button @click="refreshVersions" :disabled="refreshing" class="refresh-icon-btn">
|
<button @click="refreshVersions" :disabled="refreshing" class="refresh-icon-btn">
|
||||||
<component :is="refreshing ? LoaderIcon : RefreshCw" :size="16" />
|
<component
|
||||||
|
:is="refreshing ? Loader : RefreshCw"
|
||||||
|
:size="16"
|
||||||
|
:class="{ 'rotate-animation': refreshing && !loading.openlist }"
|
||||||
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="version-controls">
|
<div class="version-controls">
|
||||||
@@ -26,8 +30,10 @@
|
|||||||
"
|
"
|
||||||
class="update-btn"
|
class="update-btn"
|
||||||
>
|
>
|
||||||
<component :is="loading.openlist ? LoaderIcon : Download" :size="14" />
|
<component :is="loading.openlist ? Loader : Download" :size="14" />
|
||||||
<span>{{ loading.openlist ? t('common.loading') : t('dashboard.versionManager.update') }}</span>
|
<span>{{
|
||||||
|
loading.openlist ? t('dashboard.versionManager.updating') : t('dashboard.versionManager.update')
|
||||||
|
}}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -38,7 +44,11 @@
|
|||||||
<span class="current-version">{{ currentVersions.rclone }}</span>
|
<span class="current-version">{{ currentVersions.rclone }}</span>
|
||||||
</div>
|
</div>
|
||||||
<button @click="refreshVersions" :disabled="refreshing" class="refresh-icon-btn">
|
<button @click="refreshVersions" :disabled="refreshing" class="refresh-icon-btn">
|
||||||
<component :is="refreshing ? LoaderIcon : RefreshCw" :size="16" />
|
<component
|
||||||
|
:is="refreshing ? Loader : RefreshCw"
|
||||||
|
:size="16"
|
||||||
|
:class="{ 'rotate-animation': refreshing && !loading.rclone }"
|
||||||
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="version-controls">
|
<div class="version-controls">
|
||||||
@@ -55,8 +65,10 @@
|
|||||||
"
|
"
|
||||||
class="update-btn"
|
class="update-btn"
|
||||||
>
|
>
|
||||||
<component :is="loading.rclone ? LoaderIcon : Download" :size="14" />
|
<component :is="loading.rclone ? Loader : Download" :size="14" />
|
||||||
<span>{{ loading.rclone ? t('common.loading') : t('dashboard.versionManager.update') }}</span>
|
<span>{{
|
||||||
|
loading.rclone ? t('dashboard.versionManager.updating') : t('dashboard.versionManager.update')
|
||||||
|
}}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -68,7 +80,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { useTranslation } from '../../composables/useI18n'
|
import { useTranslation } from '../../composables/useI18n'
|
||||||
import { Download, RefreshCw, Loader2 as LoaderIcon } from 'lucide-vue-next'
|
import { Download, RefreshCw, Loader } from 'lucide-vue-next'
|
||||||
import Card from '../ui/Card.vue'
|
import Card from '../ui/Card.vue'
|
||||||
import { TauriAPI } from '../../api/tauri'
|
import { TauriAPI } from '../../api/tauri'
|
||||||
|
|
||||||
@@ -144,20 +156,95 @@ const refreshVersions = async () => {
|
|||||||
|
|
||||||
const updateVersion = async (type: 'openlist' | 'rclone') => {
|
const updateVersion = async (type: 'openlist' | 'rclone') => {
|
||||||
loading.value[type] = true
|
loading.value[type] = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await TauriAPI.bin.updateVersion(type, selectedVersions.value[type])
|
const result = await TauriAPI.bin.updateVersion(type, selectedVersions.value[type])
|
||||||
|
|
||||||
currentVersions.value[type] = selectedVersions.value[type]
|
currentVersions.value[type] = selectedVersions.value[type]
|
||||||
selectedVersions.value[type] = ''
|
selectedVersions.value[type] = ''
|
||||||
|
|
||||||
|
showNotification(
|
||||||
|
'success',
|
||||||
|
t('dashboard.versionManager.updateSuccess', { type: type.charAt(0).toUpperCase() + type.slice(1) })
|
||||||
|
)
|
||||||
|
|
||||||
console.log(`Updated ${type}:`, result)
|
console.log(`Updated ${type}:`, result)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to update ${type}:`, error)
|
console.error(`Failed to update ${type}:`, error)
|
||||||
|
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||||
|
showNotification(
|
||||||
|
'error',
|
||||||
|
t('dashboard.versionManager.updateError', {
|
||||||
|
type: type.charAt(0).toUpperCase() + type.slice(1),
|
||||||
|
error: errorMessage
|
||||||
|
})
|
||||||
|
)
|
||||||
} finally {
|
} finally {
|
||||||
loading.value[type] = false
|
loading.value[type] = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const showNotification = (type: 'success' | 'error', message: string) => {
|
||||||
|
const notification = document.createElement('div')
|
||||||
|
const bgColor =
|
||||||
|
type === 'success'
|
||||||
|
? 'linear-gradient(135deg, rgb(16, 185, 129), rgb(5, 150, 105))'
|
||||||
|
: 'linear-gradient(135deg, rgb(239, 68, 68), rgb(220, 38, 38))'
|
||||||
|
const icon = type === 'success' ? '✓' : '⚠'
|
||||||
|
|
||||||
|
notification.innerHTML = `
|
||||||
|
<div style="
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
background: ${bgColor};
|
||||||
|
color: white;
|
||||||
|
padding: 12px 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
z-index: 10000;
|
||||||
|
font-weight: 500;
|
||||||
|
max-width: 350px;
|
||||||
|
word-break: break-word;
|
||||||
|
animation: slideInRight 0.3s ease-out;
|
||||||
|
">
|
||||||
|
<div style="display: flex; align-items: center; gap: 8px;">
|
||||||
|
<div style="font-size: 18px;">${icon}</div>
|
||||||
|
<div style="font-size: 14px;">${message}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
|
||||||
|
if (!document.querySelector('#notification-styles')) {
|
||||||
|
const style = document.createElement('style')
|
||||||
|
style.id = 'notification-styles'
|
||||||
|
style.innerHTML = `
|
||||||
|
@keyframes slideInRight {
|
||||||
|
from {
|
||||||
|
transform: translateX(100%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateX(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
document.head.appendChild(style)
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.appendChild(notification)
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (notification.parentNode) {
|
||||||
|
notification.style.animation = 'slideInRight 0.3s ease-in reverse'
|
||||||
|
setTimeout(() => {
|
||||||
|
notification.parentNode?.removeChild(notification)
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
}, 4000)
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
refreshVersions()
|
refreshVersions()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -57,7 +57,10 @@
|
|||||||
"openlist": "OpenList",
|
"openlist": "OpenList",
|
||||||
"rclone": "Rclone",
|
"rclone": "Rclone",
|
||||||
"selectVersion": "Select Version",
|
"selectVersion": "Select Version",
|
||||||
"update": "Update"
|
"update": "Update",
|
||||||
|
"updating": "Updating...",
|
||||||
|
"updateSuccess": "{type} updated successfully!",
|
||||||
|
"updateError": "Failed to update {type}: {error}"
|
||||||
},
|
},
|
||||||
"documentation": {
|
"documentation": {
|
||||||
"title": "Documentation",
|
"title": "Documentation",
|
||||||
|
|||||||
@@ -57,7 +57,10 @@
|
|||||||
"openlist": "OpenList",
|
"openlist": "OpenList",
|
||||||
"rclone": "Rclone",
|
"rclone": "Rclone",
|
||||||
"selectVersion": "选择版本",
|
"selectVersion": "选择版本",
|
||||||
"update": "更新"
|
"update": "更新",
|
||||||
|
"updating": "更新中...",
|
||||||
|
"updateSuccess": "{type} 更新成功!",
|
||||||
|
"updateError": "更新 {type} 失败:{error}"
|
||||||
},
|
},
|
||||||
"documentation": {
|
"documentation": {
|
||||||
"title": "文档",
|
"title": "文档",
|
||||||
|
|||||||
Reference in New Issue
Block a user