mirror of
https://github.com/xpltdco/media-rip.git
synced 2026-04-03 02:53:58 -06:00
Mobile queue badge + fix paste-then-download race condition
Mobile: - Queue tab shows badge with active job count (queued/downloading) - Badge hidden when user is already on Queue tab - Styled as accent-colored pill with count (caps at 9+) Paste race fix: - Set isAnalyzing=true immediately on paste event, not after 50ms timeout - Prevents Download button from being briefly clickable between paste and analysis start - Handles edge case where URL is cleared before timeout fires
This commit is contained in:
parent
1b5f24f796
commit
f72b649acf
2 changed files with 44 additions and 2 deletions
|
|
@ -1,13 +1,26 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
import { useDownloadsStore } from '@/stores/downloads'
|
||||
import WireframeBackground from './WireframeBackground.vue'
|
||||
|
||||
const themeStore = useThemeStore()
|
||||
const downloadsStore = useDownloadsStore()
|
||||
const showWireframe = computed(() => themeStore.currentTheme === 'cyberpunk')
|
||||
|
||||
type MobileTab = 'submit' | 'queue'
|
||||
const activeTab = ref<MobileTab>('submit')
|
||||
|
||||
/** Number of active (non-terminal) jobs — shown as badge on Queue tab */
|
||||
const queueBadge = computed(() => {
|
||||
let count = 0
|
||||
for (const job of downloadsStore.jobs.values()) {
|
||||
if (job.status === 'queued' || job.status === 'downloading' || job.status === 'extracting') {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -41,7 +54,10 @@ const activeTab = ref<MobileTab>('submit')
|
|||
:class="{ active: activeTab === 'queue' }"
|
||||
@click="activeTab = 'queue'"
|
||||
>
|
||||
<span class="nav-icon-wrap">
|
||||
<span class="nav-icon">☰</span>
|
||||
<span v-if="queueBadge > 0 && activeTab !== 'queue'" class="nav-badge">{{ queueBadge > 9 ? '9+' : queueBadge }}</span>
|
||||
</span>
|
||||
<span class="nav-label">Queue</span>
|
||||
</button>
|
||||
</nav>
|
||||
|
|
@ -136,5 +152,26 @@ const activeTab = ref<MobileTab>('submit')
|
|||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.nav-icon-wrap {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.nav-badge {
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
right: -10px;
|
||||
background: var(--color-accent);
|
||||
color: var(--color-bg);
|
||||
font-size: 0.6rem;
|
||||
font-weight: 700;
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
border-radius: var(--radius-full);
|
||||
padding: 0 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -184,10 +184,12 @@ function onFormatSelect(formatId: string | null): void {
|
|||
}
|
||||
|
||||
function handlePaste(): void {
|
||||
// Immediately signal that analysis is starting — prevents the Download
|
||||
// button from being briefly clickable between paste and analysis.
|
||||
isAnalyzing.value = true
|
||||
// Auto-extract on paste — unified loading state
|
||||
setTimeout(async () => {
|
||||
if (url.value.trim()) {
|
||||
isAnalyzing.value = true
|
||||
analyzeError.value = null
|
||||
startAnalyzePhase()
|
||||
try {
|
||||
|
|
@ -204,6 +206,9 @@ function handlePaste(): void {
|
|||
isAnalyzing.value = false
|
||||
stopAnalyzePhase()
|
||||
}
|
||||
} else {
|
||||
// URL was cleared before timeout — cancel analysis state
|
||||
isAnalyzing.value = false
|
||||
}
|
||||
}, 50)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue