1
1
'use client'
2
2
import { Button , Callout , Code , Dialog , Progress } from '@radix-ui/themes'
3
- import { useToggle } from '@react-hookz/web'
4
3
import { fileOpen } from 'browser-fs-access'
4
+ import confetti from 'canvas-confetti'
5
5
import clsx from 'clsx'
6
6
import { chunk } from 'es-toolkit'
7
7
import ky from 'ky'
@@ -10,10 +10,9 @@ import useSWRMutation from 'swr/mutation'
10
10
import { useRouter_UNSTABLE } from 'waku/router/client'
11
11
import { platformMap } from '@/constants/platform.ts'
12
12
13
- export function UploadDialog ( { platform } : { platform : string } ) {
13
+ export function UploadDialog ( { platform, toggleOpen } : { platform : string ; toggleOpen : any } ) {
14
14
const router = useRouter_UNSTABLE ( )
15
15
16
- const [ done , toggleDone ] = useToggle ( )
17
16
const [ files , setFiles ] = useState < File [ ] > ( [ ] )
18
17
const [ uploadedFiles , setUploadedFiles ] = useState < Record < string , File [ ] > > ( { failure : [ ] , success : [ ] } )
19
18
@@ -26,7 +25,7 @@ export function UploadDialog({ platform }: { platform: string }) {
26
25
await ky . put ( url , { body : formData } )
27
26
}
28
27
29
- const { isMutating , trigger } = useSWRMutation ( '/api/v1/rom/new' , async ( url , { arg : files } : { arg : File [ ] } ) => {
28
+ const { trigger } = useSWRMutation ( '/api/v1/rom/new' , async ( url , { arg : files } : { arg : File [ ] } ) => {
30
29
for ( const filesChunk of chunk ( files , 10 ) ) {
31
30
const newUploadedFiles = { ...uploadedFiles }
32
31
try {
@@ -36,87 +35,64 @@ export function UploadDialog({ platform }: { platform: string }) {
36
35
newUploadedFiles . failure . push ( ...filesChunk )
37
36
}
38
37
setUploadedFiles ( newUploadedFiles )
39
- if ( newUploadedFiles . success . length + newUploadedFiles . failure . length === files . length ) {
40
- toggleDone ( )
41
- }
42
38
}
43
39
} )
44
40
45
- function handleClickOk ( ) {
46
- router . reload ( )
47
- }
48
-
49
41
async function handleClickSelect ( ) {
50
42
const files = await fileOpen ( { extensions : platformMap [ platform ] . fileExtensions , multiple : true } )
51
43
setFiles ( files )
52
44
await trigger ( files )
53
- // router.reload()
45
+ toggleOpen ( )
46
+ confetti ( )
47
+ router . reload ( )
54
48
}
55
49
56
- let status = ''
50
+ function prevendDefaultWhenUploading ( event : Event ) {
51
+ if ( files . length > 0 ) {
52
+ event . preventDefault ( )
53
+ }
54
+ }
55
+
56
+ let status = 'loading'
57
57
if ( files . length === 0 ) {
58
58
status = 'initial'
59
- } else if ( isMutating ) {
60
- status = 'loading'
61
- } else if ( done ) {
62
- status = 'done'
63
59
}
64
60
65
61
return (
66
- < Dialog . Content >
62
+ < Dialog . Content
63
+ aria-describedby = { undefined }
64
+ onEscapeKeyDown = { prevendDefaultWhenUploading }
65
+ onPointerDownOutside = { prevendDefaultWhenUploading }
66
+ >
67
67
< Dialog . Title >
68
68
{
69
69
{
70
- done : 'Done' ,
71
70
initial : 'Select ROMs' ,
72
71
loading : 'Uploading ROMs' ,
73
72
} [ status ]
74
73
}
75
74
</ Dialog . Title >
76
75
77
- < Dialog . Description >
78
- { status === 'initial' ? (
79
- < Callout . Root className = { clsx ( { hidden : status !== 'initial' } ) } size = '1' >
80
- < Callout . Icon >
81
- < span className = 'icon-[mdi--information]' />
82
- </ Callout . Icon >
83
- < Callout . Text >
84
- < div className = 'text-xs' >
85
- < div >
86
- You are going to upload ROMs for < b > { platformMap [ platform ] . displayName } </ b > .
87
- </ div >
88
- < div > We support these file extensions for this platform:</ div >
89
- < div className = 'mt-0.5 flex gap-1' >
90
- { platformMap [ platform ] . fileExtensions . map ( ( extention ) => (
91
- < Code key = { extention } > { extention } </ Code >
92
- ) ) }
93
- </ div >
94
- </ div >
95
- </ Callout . Text >
96
- </ Callout . Root >
97
- ) : null }
98
- </ Dialog . Description >
76
+ { status === 'initial' ? (
77
+ < Callout . Root className = { clsx ( { hidden : status !== 'initial' } ) } size = '1' >
78
+ < Callout . Icon >
79
+ < span className = 'icon-[mdi--information]' />
80
+ </ Callout . Icon >
81
+ < Callout . Text className = 'text-xs' >
82
+ You are uploading ROMs for < b > { platformMap [ platform ] . displayName } </ b > . We support these file extensions for
83
+ this platform:
84
+ < br />
85
+ < span className = 'inline-flex gap-1 py-2' >
86
+ { platformMap [ platform ] . fileExtensions . map ( ( extention ) => (
87
+ < Code key = { extention } > { extention } </ Code >
88
+ ) ) }
89
+ </ span >
90
+ </ Callout . Text >
91
+ </ Callout . Root >
92
+ ) : null }
99
93
100
94
{
101
95
{
102
- done : (
103
- < div >
104
- < div className = 'my-8 flex items-center justify-center gap-2 text-lg text-[var(--theme)]' >
105
- < span > 🎉</ span >
106
- ROMs uploaded. Enjoy!
107
- </ div >
108
-
109
- < div className = 'mt-4 flex justify-end' >
110
- < Dialog . Close onClick = { handleClickOk } >
111
- < Button >
112
- < span className = 'icon-[mdi--check]' />
113
- OK
114
- </ Button >
115
- </ Dialog . Close >
116
- </ div >
117
- </ div >
118
- ) ,
119
-
120
96
initial : (
121
97
< div >
122
98
< div className = 'mt-4 flex justify-center' >
@@ -128,7 +104,7 @@ export function UploadDialog({ platform }: { platform: string }) {
128
104
129
105
< div className = 'mt-4 flex justify-end' >
130
106
< Dialog . Close >
131
- < Button type = 'button' variant = 'soft' >
107
+ < Button variant = 'soft' >
132
108
< span className = 'icon-[mdi--close]' />
133
109
Cancel
134
110
</ Button >
@@ -140,6 +116,7 @@ export function UploadDialog({ platform }: { platform: string }) {
140
116
loading : (
141
117
< div className = 'my-4' >
142
118
< Progress
119
+ duration = '1s'
143
120
size = '3'
144
121
value = { ( ( uploadedFiles . success . length + uploadedFiles . failure . length ) / files . length ) * 100 }
145
122
/>
0 commit comments