more UI polish and schedule safe guards and optimization

This commit is contained in:
Bryan Van Deusen
2026-01-30 00:01:45 -05:00
parent c1fe8148b8
commit 097ab16c50
6 changed files with 133 additions and 25 deletions
+36 -2
View File
@@ -95,6 +95,23 @@
Reset Stuck ({{ stuckRunningCount }})
</v-btn>
<v-spacer />
<!-- Credential Status -->
<div class="d-flex align-center ga-2">
<v-icon size="small" class="mr-1">mdi-key</v-icon>
<span class="text-body-2 text-grey mr-2">Auth:</span>
<v-chip
v-for="platform in supportedPlatforms"
:key="platform"
:color="credentialsStore.hasPlatformCredentials(platform) ? 'success' : 'grey'"
:variant="credentialsStore.hasPlatformCredentials(platform) ? 'tonal' : 'outlined'"
size="x-small"
:to="credentialsStore.hasPlatformCredentials(platform) ? undefined : '/credentials'"
>
<v-icon start size="x-small">{{ getPlatformIcon(platform) }}</v-icon>
{{ platform }}
</v-chip>
</div>
<v-divider vertical class="mx-2" />
<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...' }}
@@ -267,9 +284,10 @@
<v-btn
size="small"
variant="text"
:to="`/sources/${source.id}/edit`"
to="/subscriptions"
>
Edit
View
<v-tooltip activator="parent">View in Subscriptions</v-tooltip>
</v-btn>
</td>
</tr>
@@ -290,13 +308,18 @@
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useSourcesStore } from '../stores/sources'
import { useDownloadsStore } from '../stores/downloads'
import { useCredentialsStore } from '../stores/credentials'
import { useNotificationStore } from '../stores/notifications'
import { settingsApi, downloadsApi } from '../services/api'
const sourcesStore = useSourcesStore()
const downloadsStore = useDownloadsStore()
const credentialsStore = useCredentialsStore()
const notifications = useNotificationStore()
// Supported platforms for credential status
const supportedPlatforms = ['patreon', 'subscribestar', 'hentaifoundry', 'discord']
// State
const checkingAll = ref(false)
const retryingAll = ref(false)
@@ -337,6 +360,7 @@ 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))
credentialsStore.fetchCredentials().catch(e => console.error('Failed to fetch credentials:', e))
downloadsStore.fetchStats()
.catch(e => console.error('Failed to fetch stats:', e))
@@ -490,6 +514,16 @@ function getStatusIcon(status) {
return icons[status] || 'mdi-help-circle'
}
function getPlatformIcon(platform) {
const icons = {
patreon: 'mdi-patreon',
subscribestar: 'mdi-star',
hentaifoundry: 'mdi-palette',
discord: 'mdi-discord',
}
return icons[platform] || 'mdi-web'
}
function getStatusColor(status) {
const colors = {
completed: 'success',
+13 -4
View File
@@ -197,7 +197,7 @@
</td>
<td>
<div>{{ formatDate(source.last_check) }}</div>
<div v-if="source.enabled && source.last_check" class="text-caption text-grey">
<div v-if="source.enabled" class="text-caption text-grey">
Next: {{ formatNextCheck(source) }}
</div>
</td>
@@ -323,15 +323,22 @@
</template>
<script setup>
import { ref, watch, onMounted } from 'vue'
import { ref, watch, onMounted, computed } from 'vue'
import { useSubscriptionsStore } from '../stores/subscriptions'
import { useCredentialsStore } from '../stores/credentials'
import { useSettingsStore } from '../stores/settings'
import { useNotificationStore } from '../stores/notifications'
const subscriptionsStore = useSubscriptionsStore()
const credentialsStore = useCredentialsStore()
const settingsStore = useSettingsStore()
const notifications = useNotificationStore()
// Get global schedule interval from settings (default 8 hours)
const scheduleInterval = computed(() =>
settingsStore.settings['download.schedule_interval'] || 28800
)
const searchQuery = ref('')
const filterEnabled = ref(null)
const expandedIds = ref([])
@@ -387,6 +394,7 @@ const headers = [
onMounted(() => {
loadSubscriptions()
credentialsStore.fetchCredentials()
settingsStore.fetchSettings() // For schedule_interval
})
watch([searchQuery, filterEnabled], () => {
@@ -435,9 +443,10 @@ function formatDate(dateStr) {
}
function formatNextCheck(source) {
if (!source.last_check || !source.check_interval) return 'Unknown'
if (!source.last_check) return 'Due now'
const lastCheck = new Date(source.last_check)
const nextCheck = new Date(lastCheck.getTime() + source.check_interval * 1000)
// Use global schedule_interval from settings
const nextCheck = new Date(lastCheck.getTime() + scheduleInterval.value * 1000)
const now = new Date()
if (nextCheck <= now) return 'Due now'