improve ux, moved functionality for better ui experience on app and extension.

This commit is contained in:
Bryan Van Deusen
2026-01-26 11:38:51 -05:00
parent 74b1ecf2cf
commit 2a0e37a73d
12 changed files with 369 additions and 78 deletions
+1
View File
@@ -56,6 +56,7 @@ export const settingsApi = {
getApiKey: () => api.get('/settings/api-key'),
regenerateApiKey: () => api.post('/settings/api-key/regenerate'),
getLogs: (params = {}) => api.get('/settings/logs', { params }),
refreshStorageStats: () => api.post('/settings/storage-stats/refresh'),
}
// Platforms API
+3 -2
View File
@@ -208,8 +208,9 @@ const deleteDialog = ref(false)
const deletePlatform = ref('')
const verifyingPlatform = ref('')
onMounted(async () => {
await loadData()
onMounted(() => {
// Don't block UI - load data in background
loadData()
})
async function loadData() {
+60 -11
View File
@@ -82,12 +82,29 @@
Retry All Failed ({{ failedCount }})
</v-btn>
<v-spacer />
<div class="text-body-2 text-grey">
<div class="text-body-2 text-grey d-flex align-center">
<v-icon size="small" class="mr-1">mdi-harddisk</v-icon>
Storage: {{ storageStats?.total_size_formatted || 'Calculating...' }}
<span v-if="storageStats?.file_count" class="ml-2">
({{ storageStats.file_count.toLocaleString() }} files)
</span>
<v-tooltip v-if="storageStats?.calculated_at" location="bottom">
<template v-slot:activator="{ props }">
<v-icon v-bind="props" size="x-small" class="ml-2">mdi-information-outline</v-icon>
</template>
<span>Updated: {{ formatDate(storageStats.calculated_at) }}</span>
</v-tooltip>
<v-btn
icon
size="x-small"
variant="text"
class="ml-1"
:loading="refreshingStorage"
@click="refreshStorageStats"
title="Refresh storage stats"
>
<v-icon size="small">mdi-refresh</v-icon>
</v-btn>
</div>
</v-card-text>
</v-card>
@@ -270,6 +287,10 @@ const checkingAll = ref(false)
const retryingAll = ref(false)
const storageStats = ref(null)
const runningDownloads = ref([])
const loadingStats = ref(true)
const loadingActivity = ref(true)
const loadingStorage = ref(true)
const refreshingStorage = ref(false)
let refreshInterval = null
// Computed
@@ -280,8 +301,9 @@ const sourcesWithErrors = computed(() =>
)
const failedCount = computed(() => stats.value?.failed || 0)
onMounted(async () => {
await loadDashboardData()
onMounted(() => {
// Load data in background - DON'T await, let UI render immediately
loadDashboardData()
// Start auto-refresh for running downloads
startAutoRefresh()
})
@@ -290,14 +312,23 @@ onUnmounted(() => {
stopAutoRefresh()
})
async function loadDashboardData() {
await Promise.all([
sourcesStore.fetchSources(),
downloadsStore.fetchStats(),
downloadsStore.fetchRecentActivity({ limit: 10 }),
fetchRunningDownloads(),
fetchStorageStats(),
])
function loadDashboardData() {
// Fire off all requests in parallel, don't block UI
// Each section handles its own loading state
sourcesStore.fetchSources().catch(e => console.error('Failed to fetch sources:', e))
downloadsStore.fetchStats()
.catch(e => console.error('Failed to fetch stats:', e))
.finally(() => loadingStats.value = false)
downloadsStore.fetchRecentActivity({ limit: 10 })
.catch(e => console.error('Failed to fetch recent activity:', e))
.finally(() => loadingActivity.value = false)
fetchRunningDownloads()
// Storage stats can be slow - load independently
fetchStorageStats()
}
async function fetchRunningDownloads() {
@@ -310,11 +341,29 @@ async function fetchRunningDownloads() {
}
async function fetchStorageStats() {
loadingStorage.value = true
try {
const response = await settingsApi.get()
storageStats.value = response.data.storage_stats
} catch (e) {
console.error('Failed to fetch storage stats:', e)
} finally {
loadingStorage.value = false
}
}
async function refreshStorageStats() {
refreshingStorage.value = true
try {
await settingsApi.refreshStorageStats()
notifications.success('Storage stats refresh queued')
// Wait a moment then fetch updated stats
setTimeout(() => fetchStorageStats(), 3000)
} catch (e) {
console.error('Failed to refresh storage stats:', e)
notifications.error('Failed to refresh storage stats')
} finally {
refreshingStorage.value = false
}
}
+4 -5
View File
@@ -241,11 +241,10 @@ const headers = [
{ title: 'Actions', key: 'actions', width: 100, sortable: false },
]
onMounted(async () => {
await Promise.all([
loadDownloads(),
sourcesStore.fetchSources(),
])
onMounted(() => {
// Load data in background - don't block UI rendering
loadDownloads()
sourcesStore.fetchSources()
})
watch([filterStatus, filterSourceId, filterFromDate, filterToDate], () => {
+3 -2
View File
@@ -330,8 +330,9 @@ const apiHealthy = ref(true)
const showApiKey = ref(false)
const regenerateDialog = ref(false)
onMounted(async () => {
await loadAll()
onMounted(() => {
// Don't block UI - load data in background
loadAll()
})
async function loadAll() {