diff --git a/frontend/src/views/Downloads.vue b/frontend/src/views/Downloads.vue index dfeb02e..de508d0 100644 --- a/frontend/src/views/Downloads.vue +++ b/frontend/src/views/Downloads.vue @@ -301,7 +301,29 @@ Files Downloaded - {{ selectedDownload.file_count }} + {{ runStats?.downloaded_count ?? selectedDownload.file_count }} + + + Skipped + {{ runStats.skipped_count }} (already in archive) + + + Per-item Failures + {{ runStats.per_item_failures }} (single items gallery-dl skipped over) + + + Warnings + {{ runStats.warning_count }} + + + Duration + {{ formatDuration(selectedDownload) }} + + + Exit Code + + {{ runStats.exit_code }} + Created @@ -326,17 +348,69 @@ - + + + + Errors & Warnings + + mdi-content-copy + Copy + + + +
{{ selectedDownload.metadata.stderr_errors_warnings }}
+
+
- Output Log + + Output Log (stdout) + + mdi-content-copy + Copy + +
{{ selectedDownload.metadata.stdout }}
- Verbose Log (stderr) + + Verbose Log (stderr) + + mdi-content-copy + Copy + + -
{{ selectedDownload.metadata.stderr }}
+ +
{{ filteredVerboseLog || '(no matching lines)' }}
@@ -379,6 +453,8 @@ const filterExcludeSuperseded = ref(true) const detailsDialog = ref(false) const selectedDownload = ref(null) const retryingIds = ref([]) +const verboseLogFilter = ref('') +const openLogPanels = ref([]) let refreshInterval = null const statusOptions = [ @@ -595,9 +671,34 @@ function getSourceLabel(item) { return `Source #${sourceId}` } +const runStats = computed(() => selectedDownload.value?.metadata?.run_stats || null) + +const filteredVerboseLog = computed(() => { + const stderr = selectedDownload.value?.metadata?.stderr || '' + const query = verboseLogFilter.value.trim().toLowerCase() + if (!query) return stderr + return stderr + .split('\n') + .filter(line => line.toLowerCase().includes(query)) + .join('\n') +}) + function showDetails(download) { selectedDownload.value = download detailsDialog.value = true + verboseLogFilter.value = '' + // Open the errors/warnings panel by default when there's anything worth seeing. + openLogPanels.value = download?.metadata?.stderr_errors_warnings ? [0] : [] +} + +async function copyToClipboard(text, label = 'content') { + if (!text) return + try { + await navigator.clipboard.writeText(text) + notifications.success(`Copied ${label} to clipboard`) + } catch (err) { + notifications.error(`Copy failed: ${err.message}`) + } } async function retryDownload(download) {