-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fb7fd05
commit d0196a8
Showing
16 changed files
with
352 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
### [7.0.0] - 2023-10-30 | ||
|
||
- Add file converter | ||
|
||
### [6.5.0] - 2023-10-30 | ||
|
||
- Update github issue | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
.ic { | ||
display: flex; | ||
flex-direction: column; | ||
gap: 20px; | ||
|
||
&__item { | ||
transition: opacity 0.3s, height 0.3s; | ||
min-height: 66px; | ||
padding: 8px; | ||
border: 1px solid #d9d9d9; | ||
border-radius: 8px; | ||
display: grid; | ||
align-items: center; | ||
gap: 20px; | ||
grid-template-columns: auto auto; | ||
|
||
h5 { | ||
overflow: hidden; | ||
} | ||
|
||
&_right { | ||
display: flex; | ||
align-items: center; | ||
justify-content: end; | ||
gap: 20px; | ||
> div { | ||
margin-bottom: 0px !important; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
import { useState } from "react"; | ||
import { fetchFile } from "@ffmpeg/util"; | ||
import { Button, message, Upload } from "antd"; | ||
import Icon from "components/General/Icon"; | ||
import type { UploadFile, UploadProps } from "antd"; | ||
import { | ||
ResponsiveButton, | ||
ResponsiveSelectWithLabel, | ||
} from "components/General/FormComponents"; | ||
import styles from "./FileConverter.module.scss"; | ||
import { useFfmpeg } from "./useFfmpeg"; | ||
import { | ||
getFileExtension, | ||
removeExtension, | ||
} from "utils/helper-functions/files"; | ||
|
||
const { Dragger } = Upload; | ||
|
||
const IMAGE_TYPES = [ | ||
{ label: "PNG", value: ".png" }, | ||
{ label: "JPEG", value: ".jpeg" }, | ||
{ label: "SVG", value: ".svg" }, | ||
{ label: "WEBP", value: ".webp" }, | ||
]; | ||
|
||
interface FileConverter { | ||
file: UploadFile; | ||
from: string; | ||
to: string; | ||
} | ||
|
||
function FileConverter() { | ||
const [uploadFiles, setUploadedFiles] = useState<FileConverter[]>([]); | ||
const [selectedFormat, setSelectedFormat] = useState(IMAGE_TYPES[0].value); | ||
const { loaded, ffmpegRef } = useFfmpeg(); | ||
|
||
const transcode = async (fileConverter: FileConverter) => { | ||
const ffmpeg = ffmpegRef.current; | ||
const outputFileName = `${removeExtension(fileConverter.file.name)}${ | ||
fileConverter.to | ||
}`; | ||
|
||
await ffmpeg.writeFile( | ||
fileConverter.file.name, | ||
await fetchFile(fileConverter.file.originFileObj) | ||
); | ||
await ffmpeg.exec(["-i", fileConverter.file.name, outputFileName]); | ||
const fileData = await ffmpeg.readFile(outputFileName); | ||
const data = new Uint8Array(fileData as ArrayBuffer); | ||
|
||
const blob = new Blob([data.buffer], { | ||
type: `${fileConverter.file.type}/${fileConverter.to}`, | ||
}); | ||
const url = URL.createObjectURL(blob); | ||
return [url, outputFileName]; | ||
}; | ||
|
||
const convertFiles = async () => { | ||
const convertedFilesPromises = uploadFiles.map(transcode); | ||
const convertedFiles = await Promise.all(convertedFilesPromises); | ||
convertedFiles.forEach(([url, fileName]) => | ||
downloadFiles(url, fileName) | ||
); | ||
}; | ||
|
||
const downloadFiles = async (url: string, fileName: string) => { | ||
const a = document.createElement("a"); | ||
a.download = fileName; | ||
a.href = url; | ||
document.body.appendChild(a); | ||
a.click(); | ||
document.body.removeChild(a); | ||
}; | ||
|
||
const props: UploadProps = { | ||
name: "file", | ||
multiple: true, | ||
customRequest: (options) => { | ||
if (options.onSuccess) { | ||
options.onSuccess({}, new XMLHttpRequest()); | ||
} | ||
}, | ||
onChange(info) { | ||
const { status } = info.file; | ||
if (status !== "uploading") { | ||
// console.log(info.file, info.fileList); | ||
} | ||
if (status === "done") { | ||
message.success( | ||
`${info.file.name} file uploaded successfully.` | ||
); | ||
|
||
let fileExtension = ""; | ||
try { | ||
fileExtension = getFileExtension(info.file.name); | ||
} catch (e) { | ||
console.log("e", e); | ||
} | ||
|
||
if (fileExtension === "") return; | ||
setUploadedFiles((prevFiles) => [ | ||
...prevFiles, | ||
{ | ||
file: info.file, | ||
from: fileExtension, | ||
to: selectedFormat, | ||
}, | ||
]); | ||
} else if (status === "error") { | ||
message.error(`${info.file.name} file upload failed.`); | ||
} | ||
}, | ||
accept: "image/*,video/*,audio/*", | ||
itemRender: ( | ||
_, | ||
file: UploadFile, | ||
__, | ||
actions: { | ||
download: (file: UploadFile) => void; | ||
preview: (file: UploadFile) => void; | ||
remove: (file: UploadFile) => void; | ||
} | ||
) => { | ||
return ( | ||
<div className={styles.ic__item}> | ||
<h5>{file.name}</h5> | ||
<div className={styles.ic__item_right}> | ||
<ResponsiveSelectWithLabel | ||
label="Convert file to:" | ||
value={selectedFormat} | ||
options={IMAGE_TYPES} | ||
onSelect={(_, info) => { | ||
setSelectedFormat(info.value); | ||
}} | ||
/> | ||
<Button | ||
icon={<Icon name="Trash" />} | ||
onClick={() => actions.remove(file)} | ||
/> | ||
</div> | ||
</div> | ||
); | ||
}, | ||
}; | ||
|
||
return ( | ||
<div className={styles.ic}> | ||
<Dragger {...props}> | ||
<p className="ant-upload-drag-icon"> | ||
<Icon name="Inbox" size={100} strokeWidth="0.2" /> | ||
</p> | ||
<p className="ant-upload-text"> | ||
Click or drag file to this area to upload | ||
</p> | ||
<p className="ant-upload-hint"> | ||
Support for a single or bulk upload. | ||
</p> | ||
</Dragger> | ||
<ResponsiveButton | ||
type="primary" | ||
onClick={convertFiles} | ||
disabled={!loaded} | ||
> | ||
{uploadFiles.length > 1 ? "Convert All" : "Convert"} | ||
</ResponsiveButton> | ||
</div> | ||
); | ||
} | ||
|
||
export default FileConverter; |
Oops, something went wrong.