mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-01 20:22:19 +08:00
62 lines
1.5 KiB
TypeScript
62 lines
1.5 KiB
TypeScript
import { Box, Button, Typography } from '@mui/material'
|
|
import { useLockFn } from 'ahooks'
|
|
import { useRef, useState } from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
|
|
interface Props {
|
|
onChange: (file: File, value: string) => void
|
|
}
|
|
|
|
export const FileInput = (props: Props) => {
|
|
const { onChange } = props
|
|
|
|
const { t } = useTranslation()
|
|
// file input
|
|
const inputRef = useRef<any>(undefined)
|
|
const [loading, setLoading] = useState(false)
|
|
const [fileName, setFileName] = useState('')
|
|
|
|
const onFileInput = useLockFn(async (e: any) => {
|
|
const file = e.target.files?.[0] as File
|
|
|
|
if (!file) return
|
|
|
|
setFileName(file.name)
|
|
setLoading(true)
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const reader = new FileReader()
|
|
reader.onload = (event) => {
|
|
resolve(null)
|
|
onChange(file, event.target?.result as string)
|
|
}
|
|
reader.onerror = reject
|
|
reader.readAsText(file)
|
|
}).finally(() => setLoading(false))
|
|
})
|
|
|
|
return (
|
|
<Box sx={{ mt: 2, mb: 1, display: 'flex', alignItems: 'center' }}>
|
|
<Button
|
|
variant="outlined"
|
|
sx={{ flex: 'none' }}
|
|
onClick={() => inputRef.current?.click()}
|
|
>
|
|
{t('profiles.components.fileInput.chooseFile')}
|
|
</Button>
|
|
|
|
<input
|
|
type="file"
|
|
accept=".yaml,.yml"
|
|
ref={inputRef}
|
|
style={{ display: 'none' }}
|
|
onChange={onFileInput}
|
|
/>
|
|
|
|
<Typography noWrap sx={{ ml: 1 }}>
|
|
{loading ? t('shared.statuses.loading') : fileName}
|
|
</Typography>
|
|
</Box>
|
|
)
|
|
}
|