Enhance media upload functionality: add skipped file tracking in upload store, update UploadSnackbar to display skipped duplicates, and improve UI responsiveness for upload status indicators.
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
import { create } from 'zustand'
|
||||
import { queryClient } from '@/shared/api/query-client'
|
||||
import i18n from '@/shared/lib/i18n'
|
||||
import { toast } from '@/shared/ui/toast-store'
|
||||
import { listMedia, uploadMedia } from './api'
|
||||
|
||||
export type UploadItem = {
|
||||
@@ -15,6 +13,7 @@ type UploadStore = {
|
||||
items: UploadItem[]
|
||||
active: boolean
|
||||
minimized: boolean
|
||||
skipped: number
|
||||
enqueue: (files: File[]) => Promise<void>
|
||||
toggleMinimize: () => void
|
||||
dismiss: () => void
|
||||
@@ -35,14 +34,12 @@ async function pump() {
|
||||
running = true
|
||||
useUploadStore.setState({ active: true, minimized: false })
|
||||
|
||||
let uploaded = 0
|
||||
while (queue.length > 0) {
|
||||
const job = queue.shift()!
|
||||
patch(job.id, { status: 'uploading', percent: 0 })
|
||||
try {
|
||||
await uploadMedia(job.file, (percent) => patch(job.id, { percent }))
|
||||
patch(job.id, { status: 'done', percent: 100 })
|
||||
uploaded++
|
||||
void queryClient.invalidateQueries({ queryKey: ['admin', 'media'] })
|
||||
} catch {
|
||||
patch(job.id, { status: 'error' })
|
||||
@@ -51,13 +48,13 @@ async function pump() {
|
||||
|
||||
running = false
|
||||
useUploadStore.setState({ active: false })
|
||||
if (uploaded > 0) toast.success(i18n.t('admin.media.uploadedCount', { count: uploaded }))
|
||||
}
|
||||
|
||||
export const useUploadStore = create<UploadStore>((set) => ({
|
||||
items: [],
|
||||
active: false,
|
||||
minimized: false,
|
||||
skipped: 0,
|
||||
|
||||
enqueue: async (files) => {
|
||||
// Пропускаем дубликаты: уже в библиотеке (не проваленные) и уже в текущей очереди.
|
||||
@@ -82,18 +79,20 @@ export const useUploadStore = create<UploadStore>((set) => ({
|
||||
const toAdd = files.filter((f) => !existing.has(f.name) && !inFlight.has(f.name))
|
||||
const skipped = files.length - toAdd.length
|
||||
|
||||
if (toAdd.length > 0) {
|
||||
const newItems: UploadItem[] = toAdd.map((file) => {
|
||||
const id = `u${++counter}`
|
||||
queue.push({ id, file })
|
||||
return { id, name: file.name, percent: 0, status: 'queued' }
|
||||
})
|
||||
set((s) => ({ items: [...s.items, ...newItems], minimized: false }))
|
||||
void pump()
|
||||
}
|
||||
if (skipped > 0) toast.message(i18n.t('admin.media.skippedDuplicates', { count: skipped }))
|
||||
const newItems: UploadItem[] = toAdd.map((file) => {
|
||||
const id = `u${++counter}`
|
||||
queue.push({ id, file })
|
||||
return { id, name: file.name, percent: 0, status: 'queued' }
|
||||
})
|
||||
|
||||
set((s) => ({
|
||||
items: newItems.length ? [...s.items, ...newItems] : s.items,
|
||||
skipped: s.skipped + skipped,
|
||||
minimized: newItems.length ? false : s.minimized,
|
||||
}))
|
||||
if (newItems.length) void pump()
|
||||
},
|
||||
|
||||
toggleMinimize: () => set((s) => ({ minimized: !s.minimized })),
|
||||
dismiss: () => set({ items: [] }),
|
||||
dismiss: () => set({ items: [], skipped: 0 }),
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user