11import React from "react" ;
22import type { ModalProps } from "@mantine/core" ;
3- import { Modal , Group , Button , TextInput , Stack , Paper , Text } from "@mantine/core" ;
3+ import { Modal , Group , Button , TextInput , Stack , Paper , Text , Select } from "@mantine/core" ;
44import { Dropzone } from "@mantine/dropzone" ;
55import { event as gaEvent } from "nextjs-google-analytics" ;
66import toast from "react-hot-toast" ;
@@ -11,6 +11,14 @@ import useFile from "../../../store/useFile";
1111export const ImportModal = ( { opened, onClose } : ModalProps ) => {
1212 const [ url , setURL ] = React . useState ( "" ) ;
1313 const [ file , setFile ] = React . useState < File | null > ( null ) ;
14+ const [ encoding , setEncoding ] = React . useState ( "utf-8" ) ;
15+
16+ const encodingOptions = [
17+ { value : "utf-8" , label : "UTF-8 (default)" } ,
18+ { value : "utf-16le" , label : "UTF-16 LE" } ,
19+ { value : "utf-16be" , label : "UTF-16 BE" } ,
20+ { value : "iso-8859-1" , label : "ISO-8859-1 (Latin-1)" } ,
21+ ] ;
1422
1523 const setContents = useFile ( state => state . setContents ) ;
1624 const setFormat = useFile ( state => state . setFormat ) ;
@@ -35,12 +43,19 @@ export const ImportModal = ({ opened, onClose }: ModalProps) => {
3543 const format = file . name . substring ( lastIndex + 1 ) ;
3644 setFormat ( format as FileFormat ) ;
3745
38- file . text ( ) . then ( text => {
39- setContents ( { contents : text } ) ;
40- setFile ( null ) ;
41- setURL ( "" ) ;
42- onClose ( ) ;
43- } ) ;
46+ file
47+ . arrayBuffer ( )
48+ . then ( buffer => {
49+ const decoder = new TextDecoder ( encoding ) ;
50+ const text = decoder . decode ( buffer ) ;
51+ setContents ( { contents : text } ) ;
52+ setFile ( null ) ;
53+ setURL ( "" ) ;
54+ onClose ( ) ;
55+ } )
56+ . catch ( ( ) => {
57+ toast . error ( `Failed to decode file using ${ encoding } ` ) ;
58+ } ) ;
4459
4560 gaEvent ( "import_file" , { label : format } ) ;
4661 }
@@ -88,6 +103,12 @@ export const ImportModal = ({ opened, onClose }: ModalProps) => {
88103 </ Stack >
89104 </ Dropzone >
90105 </ Paper >
106+ < Select
107+ label = "File Encoding"
108+ data = { encodingOptions }
109+ value = { encoding }
110+ onChange = { value => value && setEncoding ( value ) }
111+ />
91112 </ Stack >
92113 < Group justify = "right" >
93114 < Button onClick = { handleImportFile } disabled = { ! ( file || url ) } >
0 commit comments