-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathupload.tsx
More file actions
126 lines (113 loc) · 3.48 KB
/
upload.tsx
File metadata and controls
126 lines (113 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { ChangeEvent, ReactElement, useMemo, useState } from "react"
import { MdUploadFile } from "react-icons/md/index"
import { VisuallyHidden } from "reakit"
import * as Dailp from "src/graphql/dailp"
import { AudioPlayer } from "../audio-player"
import { CleanButton, IconTextButton } from "../button"
import { contributeAudioOptions } from "../contribute-audio-section.css"
import { subtleButton } from "../subtle-button.css"
import { ContributeAudioPanel } from "./contribute-audio-panel"
export function UploadAudioPanel(p: {
uploadTo: Dailp.FormFieldsFragment | Dailp.DocumentFieldsFragment
}) {
return (
<ContributeAudioPanel
panelTitle="Upload Audio"
Icon={MdUploadFile}
Component={UploadAudioContent}
parent={p.uploadTo}
/>
)
}
const ALLOWED_EXTENSIONS = ["mp3"]
export function UploadAudioContent({
uploadAudio,
}: {
uploadAudio: (data: Blob) => Promise<boolean>
}): ReactElement {
const [selectedFile, setSelectedFile] = useState<File>()
function onFileChanged(event: ChangeEvent<HTMLInputElement>) {
if (!event.currentTarget.files) return
const [file] = event.currentTarget.files
if (!file) return
const fileExtension = file.name.split(".").pop()
if (!fileExtension) return
if (!ALLOWED_EXTENSIONS.includes(fileExtension)) {
window.alert(
`The file you've selected does not have a supported extension (${fileExtension}). The following formats are supported:\n\t${ALLOWED_EXTENSIONS.join(
"\n\t"
)}`
)
return
}
setSelectedFile(file)
}
async function uploadAudioAndReset(data: Blob) {
const success = await uploadAudio(data)
if (success) {
setSelectedFile(undefined)
}
}
const selectedFileDataUrl = useMemo(
() => selectedFile && window.URL.createObjectURL(selectedFile),
[selectedFile]
)
if (!selectedFileDataUrl || !selectedFile)
return (
<>
<VisuallyHidden>
<input
type="file"
id="file-upload"
onChange={onFileChanged}
accept={ALLOWED_EXTENSIONS.map((s) => "." + s).join(",")}
/>
</VisuallyHidden>
<IconTextButton
icon={<MdUploadFile />}
className={subtleButton}
// @ts-ignore -- I couldn't find a way to fix how this is typed
// this is part of React's ugly insides
as="label"
htmlFor="file-upload"
>
Upload file
</IconTextButton>
<em>
No file selected! Hit upload file above to select a file from your
computer.
</em>
</>
)
return (
<>
<VisuallyHidden>
<input type="file" id="file-upload" onChange={onFileChanged} />
</VisuallyHidden>
<em>
Below is the audio you selected. If you would like to select a different
file click "Upload audio" again.
</em>
<AudioPlayer showProgress audioUrl={selectedFileDataUrl} />
<div className={contributeAudioOptions}>
<CleanButton
className={subtleButton}
onClick={() => {
uploadAudioAndReset(selectedFile)
}}
>
Save audio
</CleanButton>
<CleanButton
className={subtleButton}
// @ts-ignore -- I couldn't find a way to fix how this is typed
// this is part of React's ugly insides
as="label"
htmlFor="file-upload"
>
Choose a different file
</CleanButton>
</div>
</>
)
}