2025-10-12 00:43:31 +00:00
|
|
|
import { atom } from "jotai"
|
|
|
|
|
import { atomFamily } from "jotai/utils"
|
|
|
|
|
|
2025-10-12 23:48:21 +00:00
|
|
|
export enum FileUploadStatusKind {
|
|
|
|
|
InProgress = "InProgress",
|
|
|
|
|
Error = "Error",
|
|
|
|
|
Success = "Success",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type FileUploadInProgress = {
|
|
|
|
|
kind: FileUploadStatusKind.InProgress
|
2025-10-12 00:43:31 +00:00
|
|
|
progress: number
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-12 23:48:21 +00:00
|
|
|
export type FileUploadError = {
|
|
|
|
|
kind: FileUploadStatusKind.Error
|
|
|
|
|
error: unknown
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type FileUploadSuccess = {
|
|
|
|
|
kind: FileUploadStatusKind.Success
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type FileUploadStatus =
|
|
|
|
|
| FileUploadInProgress
|
|
|
|
|
| FileUploadError
|
|
|
|
|
| FileUploadSuccess
|
|
|
|
|
|
2025-10-13 22:55:25 +00:00
|
|
|
export const fileUploadStatusesAtom = atom<Record<string, FileUploadStatus>>({})
|
2025-10-12 00:43:31 +00:00
|
|
|
|
2025-10-12 23:48:21 +00:00
|
|
|
export const fileUploadStatusAtomFamily = atomFamily((id: string) =>
|
2025-10-12 00:43:31 +00:00
|
|
|
atom(
|
2025-10-13 22:55:25 +00:00
|
|
|
(get) => get(fileUploadStatusesAtom)[id],
|
2025-10-12 23:48:21 +00:00
|
|
|
(get, set, status: FileUploadStatus) => {
|
2025-10-13 22:55:25 +00:00
|
|
|
const fileUploads = { ...get(fileUploadStatusesAtom) }
|
2025-10-12 23:48:21 +00:00
|
|
|
fileUploads[id] = status
|
2025-10-13 22:55:25 +00:00
|
|
|
set(fileUploadStatusesAtom, fileUploads)
|
2025-10-12 00:43:31 +00:00
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
|
2025-10-12 23:48:21 +00:00
|
|
|
export const clearFileUploadStatusesAtom = atom(
|
|
|
|
|
null,
|
|
|
|
|
(get, set, ids: string[]) => {
|
2025-10-13 22:55:25 +00:00
|
|
|
const fileUploads = { ...get(fileUploadStatusesAtom) }
|
2025-10-12 23:48:21 +00:00
|
|
|
for (const id of ids) {
|
|
|
|
|
if (fileUploads[id]) {
|
|
|
|
|
delete fileUploads[id]
|
|
|
|
|
}
|
|
|
|
|
fileUploadStatusAtomFamily.remove(id)
|
|
|
|
|
}
|
2025-10-13 22:55:25 +00:00
|
|
|
set(fileUploadStatusesAtom, fileUploads)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
2025-11-08 18:41:30 +00:00
|
|
|
export const clearAllFileUploadStatusesAtom = atom(null, (_, set) => {
|
2025-11-08 18:03:21 +00:00
|
|
|
set(fileUploadStatusesAtom, {})
|
|
|
|
|
})
|
2025-10-12 23:48:21 +00:00
|
|
|
|
2025-10-12 17:09:42 +00:00
|
|
|
export const fileUploadCountAtom = atom(
|
2025-10-13 22:55:25 +00:00
|
|
|
(get) => Object.keys(get(fileUploadStatusesAtom)).length,
|
2025-10-12 00:43:31 +00:00
|
|
|
)
|
2025-10-12 17:09:42 +00:00
|
|
|
|
2025-10-12 23:48:21 +00:00
|
|
|
export const inProgressFileUploadCountAtom = atom((get) => {
|
2025-10-13 22:55:25 +00:00
|
|
|
const statuses = get(fileUploadStatusesAtom)
|
2025-10-12 23:48:21 +00:00
|
|
|
let count = 0
|
|
|
|
|
for (const status in statuses) {
|
|
|
|
|
if (statuses[status]?.kind === FileUploadStatusKind.InProgress) {
|
|
|
|
|
count += 1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return count
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
export const successfulFileUploadCountAtom = atom((get) => {
|
2025-10-13 22:55:25 +00:00
|
|
|
const statuses = get(fileUploadStatusesAtom)
|
2025-10-12 23:48:21 +00:00
|
|
|
let count = 0
|
|
|
|
|
for (const status in statuses) {
|
|
|
|
|
if (statuses[status]?.kind === FileUploadStatusKind.Success) {
|
|
|
|
|
count += 1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return count
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
export const hasFileUploadsErrorAtom = atom((get) => {
|
2025-10-13 22:55:25 +00:00
|
|
|
const statuses = get(fileUploadStatusesAtom)
|
2025-10-12 23:48:21 +00:00
|
|
|
for (const status in statuses) {
|
|
|
|
|
if (statuses[status]?.kind === FileUploadStatusKind.Error) {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
})
|