@@ -16,22 +16,16 @@ import {
1616 maxExpirationReadable ,
1717 BaseUrl ,
1818 APIUrl ,
19+ ErrorWithTitle ,
20+ makeErrorMsg ,
1921} from "../utils/utils.js"
2022
2123import "../style.css"
2224import { UploadedPanel } from "./UploadedPanel.js"
2325import { PasteEditor , PasteEditState } from "./PasteEditor.js"
24- import { genKey , encodeKey , encrypt , EncryptionScheme } from "../utils/encryption.js"
25-
26- async function genAndEncrypt ( scheme : EncryptionScheme , content : string | Uint8Array ) {
27- const key = await genKey ( scheme )
28- const plaintext = typeof content === "string" ? new TextEncoder ( ) . encode ( content ) : content
29- const ciphertext = await encrypt ( scheme , key , plaintext )
30- return { key : await encodeKey ( key ) , ciphertext }
31- }
26+ import { uploadPaste } from "../utils/uploader.js"
3227
3328export function PasteBin ( ) {
34- const encryptionScheme : EncryptionScheme = "AES-GCM"
3529 const [ editorState , setEditorState ] = useState < PasteEditState > ( {
3630 editKind : "edit" ,
3731 editContent : "" ,
@@ -57,7 +51,7 @@ export function PasteBin() {
5751
5852 const [ darkModeSelect , setDarkModeSelect ] = useState < DarkMode > ( defaultDarkMode ( ) )
5953
60- function showModal ( content : string , title : string ) {
54+ function showModal ( title : string , content : string ) {
6155 setErrorState ( { title, content, isOpen : true } )
6256 }
6357
@@ -121,84 +115,31 @@ export function PasteBin() {
121115 }
122116 } , [ ] )
123117
124- async function uploadPaste ( ) : Promise < void > {
125- const fd = new FormData ( )
126- if ( editorState . editKind === "file" ) {
127- if ( editorState . file === null ) {
128- showModal ( "No file selected" , "Error on preparing upload" )
129- return
130- }
131- if ( pasteSetting . doEncrypt ) {
132- const { key, ciphertext } = await genAndEncrypt ( encryptionScheme , await editorState . file . bytes ( ) )
133- const file = new File ( [ ciphertext ] , editorState . file . name )
134- setUploadedEncryptionKey ( key )
135- fd . append ( "c" , file )
136- fd . append ( "encryption-scheme" , encryptionScheme )
137- } else {
138- fd . append ( "c" , editorState . file )
139- }
140- } else {
141- if ( editorState . editContent . length === 0 ) {
142- showModal ( "Empty paste" , "Error on preparing upload" )
143- return
144- }
145- if ( pasteSetting . doEncrypt ) {
146- const { key, ciphertext } = await genAndEncrypt ( encryptionScheme , editorState . editContent )
147- setUploadedEncryptionKey ( key )
148- fd . append ( "c" , new File ( [ ciphertext ] , "" ) )
149- fd . append ( "encryption-scheme" , encryptionScheme )
150- } else {
151- fd . append ( "c" , editorState . editContent )
152- }
153- }
154-
155- fd . append ( "e" , pasteSetting . expiration )
156- if ( pasteSetting . password . length > 0 ) fd . append ( "s" , pasteSetting . password )
157-
158- if ( pasteSetting . uploadKind === "long" ) fd . append ( "p" , "true" )
159- else if ( pasteSetting . uploadKind === "custom" ) fd . append ( "n" , pasteSetting . name )
160-
118+ async function onUploadPaste ( ) : Promise < void > {
161119 try {
162- setIsLoading ( true )
163- setPasteResponse ( null )
164- const isUpdate = pasteSetting . uploadKind !== "manage"
165- // TODO: add progress indicator
166- const resp = isUpdate
167- ? await fetch ( APIUrl , {
168- method : "POST" ,
169- body : fd ,
170- } )
171- : await fetch ( pasteSetting . manageUrl , {
172- method : "PUT" ,
173- body : fd ,
174- } )
175- if ( resp . ok ) {
176- const respParsed = JSON . parse ( await resp . text ( ) ) as PasteResponse
177- setPasteResponse ( respParsed )
178- setIsLoading ( false )
120+ const uploaded = await uploadPaste ( pasteSetting , editorState , setUploadedEncryptionKey , setIsLoading )
121+ setPasteResponse ( uploaded )
122+ } catch ( error ) {
123+ console . log ( error )
124+ if ( error instanceof ErrorWithTitle ) {
125+ showModal ( error . title , ( error as Error ) . message )
179126 } else {
180- await reportResponseError ( resp , `Error ${ resp . status } ` )
181- // will setIsLoading(false) on closing modal
127+ showModal ( "Error on Uploading Paste" , ( error as Error ) . message )
182128 }
183- } catch ( e ) {
184- showModal ( ( e as Error ) . toString ( ) , "Error on uploading paste" )
185- console . error ( e )
186129 }
187130 }
188131
189132 async function deletePaste ( ) {
190133 try {
191- const resp = await fetch ( pasteSetting . manageUrl , {
192- method : "DELETE" ,
193- } )
134+ const resp = await fetch ( pasteSetting . manageUrl , { method : "DELETE" } )
194135 if ( resp . ok ) {
195- showModal ( "It may takes 60 seconds for the deletion to propagate to the world" , "Deletion succeeded ")
136+ showModal ( "Deleted Successfully" , " It may takes 60 seconds for the deletion to propagate to the world")
196137 setPasteResponse ( null )
197138 } else {
198- await reportResponseError ( resp , `Error ${ resp . status } ` )
139+ showModal ( "Error From Server" , await makeErrorMsg ( resp ) )
199140 }
200141 } catch ( e ) {
201- showModal ( ( e as Error ) . message , "Error on deleting paste" )
142+ showModal ( "Error on Deleting Paste" , ( e as Error ) . message )
202143 console . error ( e )
203144 }
204145 }
@@ -250,7 +191,7 @@ export function PasteBin() {
250191 const submitter = (
251192 < div className = "my-4 mx-2 lg:mx-0" >
252193 { /* eslint-disable-next-line @typescript-eslint/no-misused-promises */ }
253- < Button color = "primary" onPress = { uploadPaste } className = "mr-4" isDisabled = { ! canUpload ( ) || isLoading } >
194+ < Button color = "primary" onPress = { onUploadPaste } className = "mr-4" isDisabled = { ! canUpload ( ) || isLoading } >
254195 { pasteSetting . uploadKind === "manage" ? "Update" : "Upload" }
255196 </ Button >
256197 { pasteSetting . uploadKind === "manage" ? (
@@ -299,6 +240,7 @@ export function PasteBin() {
299240 />
300241 { ( pasteResponse || isLoading ) && (
301242 < UploadedPanel
243+ isLoading = { isLoading }
302244 pasteResponse = { pasteResponse }
303245 encryptionKey = { uploadedEncryptionKey }
304246 className = "w-full lg:w-1/2"
0 commit comments