1- import React , { useState } from "react" ;
1+ import { useState } from "react" ;
22
3+ import AppFileSelect from "@/components/libresplit/AppFileSelect" ;
4+ import { AppSplitPreview } from "@/components/libresplit/AppSplitPreview" ;
35import init , { convert } from "@libresplit/libresplit-converter" ;
46import wasmUrl from "@libresplit/libresplit-converter/libresplit_converter_bg.wasm?url" ;
57
68export function Converter ( ) {
79 const [ selectedFile , setSelectedFile ] = useState < File | null > ( null ) ;
10+ const [ fileText , setFileText ] = useState < string | null > ( null ) ;
811 const [ result , setResult ] = useState < string | null > ( null ) ;
912
10- const handleFileChange = ( event : React . ChangeEvent < HTMLInputElement > ) => {
11- const file = event . target . files ?. [ 0 ] || null ;
13+ const handleSelectChange = async ( files : File | File [ ] | null ) => {
14+ const file = Array . isArray ( files ) ? ( files [ 0 ] ?? null ) : files ;
1215 setSelectedFile ( file ) ;
16+ setResult ( null ) ;
17+ setFileText ( null ) ;
18+
19+ if ( file ) {
20+ const text = await file . text ( ) ;
21+ setFileText ( text ) ;
22+ }
1323 } ;
1424
1525 const handleSubmit = async ( ) => {
@@ -20,11 +30,8 @@ export function Converter() {
2030
2131 try {
2232 const text = await selectedFile . text ( ) ;
23-
2433 await init ( wasmUrl ) ;
25-
2634 const converted = convert ( text ) ;
27-
2835 setResult ( converted ) ;
2936 } catch ( error ) {
3037 console . error ( "Error processing file: " , error ) ;
@@ -36,55 +43,61 @@ export function Converter() {
3643 if ( ! result || ! selectedFile ) return ;
3744
3845 const fileName = selectedFile . name . replace ( / \. [ ^ / . ] + $ / , ".json" ) ;
39-
4046 const blob = new Blob ( [ result ] , { type : "application/json" } ) ;
4147 const url = URL . createObjectURL ( blob ) ;
4248
4349 const link = document . createElement ( "a" ) ;
4450 link . href = url ;
4551 link . download = fileName ;
4652 link . click ( ) ;
47-
4853 URL . revokeObjectURL ( url ) ;
4954 } ;
5055
5156 return (
52- < div className = "flex min-h-screen items-center justify-center bg-linear-to-tr from-gray-700 to-sky-900 p-6" >
53- < div className = "w-full max-w-lg space-y-6 rounded-lg bg-gray-800 p-6 shadow-lg" >
54- < h1 className = "text-center text-2xl font-bold text-white" >
55- LibreSplit Converter
56- </ h1 >
57- < div className = "space-y-4" >
58- < input
59- type = "file"
60- accept = ".lss"
61- onChange = { handleFileChange }
62- className = "block w-full rounded-md border border-white px-3 py-2 text-white focus:ring focus:ring-indigo-500 focus:outline-none"
63- />
64- < button
65- onClick = { handleSubmit }
66- disabled = { ! selectedFile }
67- className = {
68- '${selectedFile ? "bg-indigo-600 hover:bg-indigo-700" : "bg-gray-400 cursor-not-allowed"} w-full rounded-md px-4 py-2 font-semibold text-white'
69- }
70- >
71- Convert
72- </ button >
57+ < div className = "flex h-[calc(100vh-64px-24px)] flex-col space-y-4 overflow-hidden" >
58+ < div className = "shrink-0 px-[100px]" >
59+ < AppFileSelect
60+ label = "Select LiveSplit file:"
61+ value = { selectedFile }
62+ onChange = { handleSelectChange }
63+ multiple = { false }
64+ filters = { [ { name : "LiveSplit (.lss)" , extensions : [ "lss" , "xml" ] } ] }
65+ />
66+ </ div >
67+
68+ < div className = "flex shrink-0 items-center justify-center gap-2" >
69+ < button
70+ onClick = { handleSubmit }
71+ className = "rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
72+ >
73+ Convert
74+ </ button >
75+ < button
76+ onClick = { handleDownload }
77+ disabled = { ! result }
78+ className = "rounded bg-gray-200 px-4 py-2 text-black disabled:opacity-50"
79+ >
80+ Download Splits
81+ </ button >
82+ </ div >
83+
84+ < div className = "min-h-0 flex-1" >
85+ < div className = "flex h-full min-h-0 w-full items-stretch justify-center gap-4" >
86+ { fileText && (
87+ < div className = "flex min-h-0 flex-1 flex-col" >
88+ < span className = "mb-2 text-center font-semibold" > LiveSplit:</ span >
89+ < AppSplitPreview text = { fileText } className = "h-full flex-1" />
90+ </ div >
91+ ) }
92+ { result && (
93+ < div className = "flex min-h-0 flex-1 flex-col" >
94+ < span className = "mb-2 text-center font-semibold" >
95+ LibreSplit:
96+ </ span >
97+ < AppSplitPreview text = { result } className = "h-full flex-1" />
98+ </ div >
99+ ) }
73100 </ div >
74- { result && (
75- < div className = "space-y-4" >
76- < p className = "text-center font-medium text-green-600" >
77- Conversion successful! Click the button below to download your
78- LibreSplit file.
79- </ p >
80- < button
81- onClick = { handleDownload }
82- className = "w-full rounded-md bg-green-600 px-4 py-2 font-semibold text-white hover:bg-green-700"
83- >
84- Download
85- </ button >
86- </ div >
87- ) }
88101 </ div >
89102 </ div >
90103 ) ;
0 commit comments