From 00f37b1d30ff859e9f91666785a76cd1eef53c02 Mon Sep 17 00:00:00 2001 From: olivicmic Date: Fri, 28 Jul 2023 18:03:30 -0700 Subject: [PATCH 1/8] revised PageHeader component --- .../layout/PageHeader/PageHeader.tsx | 41 +++++++++++++++++++ .../src/components/layout/PageHeader/index.js | 1 + .../src/components/layout/index.js | 5 +++ .../fakeyou.com/src/v2/view/PageContainer.tsx | 5 +++ .../lipsync/LipsyncEditor/LipsyncEditor.tsx | 14 +++++++ .../pages/lipsync/LipsyncEditor/index.tsx | 1 + .../src/v2/view/pages/lipsync/index.tsx | 3 ++ 7 files changed, 70 insertions(+) create mode 100644 packages/fakeyou.com/src/components/layout/PageHeader/PageHeader.tsx create mode 100644 packages/fakeyou.com/src/components/layout/PageHeader/index.js create mode 100644 packages/fakeyou.com/src/components/layout/index.js create mode 100644 packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx create mode 100644 packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/index.tsx create mode 100644 packages/fakeyou.com/src/v2/view/pages/lipsync/index.tsx diff --git a/packages/fakeyou.com/src/components/layout/PageHeader/PageHeader.tsx b/packages/fakeyou.com/src/components/layout/PageHeader/PageHeader.tsx new file mode 100644 index 0000000000..d6f4b85956 --- /dev/null +++ b/packages/fakeyou.com/src/components/layout/PageHeader/PageHeader.tsx @@ -0,0 +1,41 @@ +import React from "react"; + +interface Props { + titleIcon?: JSX.Element; + extra?: React.ComponentType; + title?: string; + subText: string; + showButtons: boolean; + actionButtons?: JSX.Element; +} + + +//export default function PageHeader({ actionButtons, showButtons, subText, Extra, title, titleIcon }: Props) + +const PageHeader: React.FunctionComponent = ({ actionButtons, showButtons, subText, extra, title, titleIcon }) => { + console.log('aaa',extra); + const Extra = extra || null; + // return
Hiii
; + return ; + // return
+ //
+ //
+ // + // {/* { + // Title ? () : <h1 className="fw-bold text-center text-md-start"> + // { titleIcon } + // { title } + // </h1> + // }*/} + // <p className="text-center text-md-start pt-1">{ subText }</p> + // { showButtons && ( + // <div className="d-flex flex-column flex-md-row gap-3 justify-content-center justify-content-md-start mt-4"> + // { actionButtons } + // </div> + // )} + // </div> + // </div> + // </div>; +}; + +export default PageHeader; diff --git a/packages/fakeyou.com/src/components/layout/PageHeader/index.js b/packages/fakeyou.com/src/components/layout/PageHeader/index.js new file mode 100644 index 0000000000..58edd62eef --- /dev/null +++ b/packages/fakeyou.com/src/components/layout/PageHeader/index.js @@ -0,0 +1 @@ +export { default } from './PageHeader'; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/layout/index.js b/packages/fakeyou.com/src/components/layout/index.js new file mode 100644 index 0000000000..110b9fc1d6 --- /dev/null +++ b/packages/fakeyou.com/src/components/layout/index.js @@ -0,0 +1,5 @@ +import PageHeader from './PageHeader'; + +export { + PageHeader, +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/PageContainer.tsx b/packages/fakeyou.com/src/v2/view/PageContainer.tsx index 5210ac206b..10dc7ec360 100644 --- a/packages/fakeyou.com/src/v2/view/PageContainer.tsx +++ b/packages/fakeyou.com/src/v2/view/PageContainer.tsx @@ -6,6 +6,7 @@ import { LoginPage } from "./pages/login/LoginPage"; import { ModerationFc } from "./pages/moderation/moderation_main/ModerationFc"; import { ModerationIpBanListFc } from "./pages/moderation/moderation_ip_ban_list/ModerationIpBanListFc"; import { ModerationViewIpBanFc } from "./pages/moderation/moderation_view_ip_ban/ModerationViewIpBanFc"; +import { LipsyncEditor } from "./pages/lipsync"; import { FooterNav } from "./nav/FooterNav"; import { TopNav } from "./nav/TopNav"; import { ProfileEditFc } from "./pages/profile/profile_edit/ProfileEditFc"; @@ -429,6 +430,10 @@ class PageContainer extends React.Component<Props, State> { <CreateCategoryPage sessionWrapper={this.props.sessionWrapper} /> </Route> + <Route path="/dev-lipsync"> + <LipsyncEditor /> + </Route> + <Route path="/moderation/user/list"> <ModerationUserListFc sessionWrapper={this.props.sessionWrapper} diff --git a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx new file mode 100644 index 0000000000..98cdddf69b --- /dev/null +++ b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx @@ -0,0 +1,14 @@ +import React from "react"; +import { PageHeader } from "components/layout" + +const Title: React.ComponentType = () => <div> + <h1 className="fw-bold text-center text-md-start"> + Hello + </h1> +</div>; + +export default function LipsyncEditor({ ...rest }) { + return <div> + <PageHeader {...{ extra: Title, subText: "some text", showButtons: false,}}/> + </div>; +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/index.tsx b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/index.tsx new file mode 100644 index 0000000000..02f8db5b47 --- /dev/null +++ b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/index.tsx @@ -0,0 +1 @@ +export { default } from './LipsyncEditor'; \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/lipsync/index.tsx b/packages/fakeyou.com/src/v2/view/pages/lipsync/index.tsx new file mode 100644 index 0000000000..e9598cfc23 --- /dev/null +++ b/packages/fakeyou.com/src/v2/view/pages/lipsync/index.tsx @@ -0,0 +1,3 @@ +import LipsyncEditor from './LipsyncEditor'; + +export { LipsyncEditor }; \ No newline at end of file From 7541f76f72ebd1d0f9fa62701aecd3102d2790ed Mon Sep 17 00:00:00 2001 From: olivicmic <vic@vics.pics> Date: Sun, 30 Jul 2023 19:27:55 -0700 Subject: [PATCH 2/8] UploaderComponent revised as Uploader at new shared component directory. Uploader uses the new hook useUploader which allows for state to exist external to the component --- .../common/Uploader/LoadingIcon.tsx | 12 ++ .../components/common/Uploader/Uploader.tsx | 113 ++++++++++++++++++ .../src/components/common/Uploader/index.tsx | 1 + .../src/components/common/index.tsx | 5 + .../layout/PageHeader/PageHeader.tsx | 48 ++++---- .../components/layout/{index.js => index.tsx} | 0 packages/fakeyou.com/src/hooks/index.tsx | 3 + .../src/hooks/useUploader/index.tsx | 1 + .../src/hooks/useUploader/useUploader.tsx | 62 ++++++++++ .../lipsync/LipsyncEditor/LipsyncEditor.scss | 41 +++++++ .../lipsync/LipsyncEditor/LipsyncEditor.tsx | 73 +++++++++-- 11 files changed, 324 insertions(+), 35 deletions(-) create mode 100644 packages/fakeyou.com/src/components/common/Uploader/LoadingIcon.tsx create mode 100644 packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx create mode 100644 packages/fakeyou.com/src/components/common/Uploader/index.tsx create mode 100644 packages/fakeyou.com/src/components/common/index.tsx rename packages/fakeyou.com/src/components/layout/{index.js => index.tsx} (100%) create mode 100644 packages/fakeyou.com/src/hooks/index.tsx create mode 100644 packages/fakeyou.com/src/hooks/useUploader/index.tsx create mode 100644 packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx create mode 100644 packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss diff --git a/packages/fakeyou.com/src/components/common/Uploader/LoadingIcon.tsx b/packages/fakeyou.com/src/components/common/Uploader/LoadingIcon.tsx new file mode 100644 index 0000000000..dce6894198 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/Uploader/LoadingIcon.tsx @@ -0,0 +1,12 @@ +import React from "react"; + +export default function LoadingIcon() { + return <> + <span + className="spinner-border spinner-border-sm ms-3" + role="status" + aria-hidden="true" + ></span> + <span className="visually-hidden">Loading...</span> + </>; +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx b/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx new file mode 100644 index 0000000000..a4d2bb8a4b --- /dev/null +++ b/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx @@ -0,0 +1,113 @@ +import React from "react"; +import { FileUploader } from "react-drag-drop-files"; +import { faCheck, faFileArrowUp, faFileAudio, faTrash } from "@fortawesome/pro-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { InputVcAudioPlayer } from "v2/view/_common/InputVcAudioPlayer"; +import LoadingIcon from "./LoadingIcon"; + +const FILE_TYPES = ["MP3", "WAV", "FLAC", "OGG"]; + +interface Idempotency { token: any; set: (file?: any) => void; } + +interface Props { + audioLink?: string; + file?: any; + fileSet?: (file?: any) => void; + canConvertSet?: (canConvert: boolean) => void; + handleUploadFile?: () => void; + idempotency?: Idempotency; + onChange?: (file?: any) => void; + onClear?: (file?: any) => void; + uploading?: boolean; + uploadDisabled?: boolean; +} + +const n = () => {}; + +export default function Uploader({ audioLink = "", file, fileSet = n, canConvertSet = n, handleUploadFile = n, idempotency = { token: '', set: n }, onChange = n, onClear = n, uploading = false, uploadDisabled = false }: Props) { + + const handleChange = (file: any) => { + onChange({ target: { name: 'uploader', value: file }}); + }; + + const handleClear = () => { onClear(); }; + + const onDragEvent = (onOff: number) => (e: React.DragEvent<HTMLDivElement>): void => { + e.preventDefault(); + e.stopPropagation(); + e.currentTarget.classList[onOff ? "add" : "remove" ]("upload-zone-drag"); + }; + + const fileSize = + file && file.size >= 1024 * 1024 + ? (file.size / 1024 / 1024).toFixed(2) + " MB" + : file + ? `${Math.floor(file.size / 1024)} KB` + : null; + + const uploadBtnClass = uploadDisabled + ? "btn btn-uploaded w-100 disabled" + : "btn btn-primary w-100"; + + return ( + <div className="d-flex flex-column gap-3"> + {/* Usage refer to https://github.com/KarimMokhtar/react-drag-drop-files */} + <FileUploader {...{ handleChange, maxSize: 50, name: "file", types: FILE_TYPES }} + children={ + <div {...{ className: "panel panel-inner upload-zone d-flex align-items-center p-3", + onDragLeave: onDragEvent(1), onDragOver: onDragEvent(0) }}> + <div className="me-4"> + <FontAwesomeIcon {...{ className: "upload-icon", icon: file ? faFileAudio : faFileArrowUp }}/> + </div> + <div> + <div className="pb-0"> + {file ? ( + <span className="filename" title={file.name}> + {file.name.slice(0, file.name.lastIndexOf("."))} + </span> + ) : ( + <> + <u className="fw-medium">Upload a file</u> or drop it + here... + </> + )} + </div> + <div className="d-flex gap-1"> + <div> + {file ? ( + <p> + <span className="opacity-50"> + {file && `${file.name.split(".").pop().toUpperCase()}`}{" "} + file size: {fileSize} + </span>{" "} + <u className="fw-medium opacity-100 ms-1">Change file</u> + </p> + ) : ( + <p className="opacity-50"> + {FILE_TYPES.join(", ").toString()} supported + </p> + )} + </div> + </div> + </div> + </div> + } + /> + { file && <> + <div className="panel panel-inner rounded p-3"> + <InputVcAudioPlayer {...{ filename: audioLink as string }}/> + </div> + <div className="d-flex gap-3"> + <button {...{ className: uploadBtnClass, disabled: uploading || uploadDisabled, onClick: () => handleUploadFile(), type: "submit", }}> + <FontAwesomeIcon {...{ className: "me-2", icon: uploadDisabled ? faCheck : faFileArrowUp, }}/> + { uploading && <LoadingIcon /> } + </button> + <button className="btn btn-destructive w-100" onClick={handleClear}> + <FontAwesomeIcon icon={faTrash} className="me-2" /> + Clear + </button> + </div> + </> } + </div> + ); +}; diff --git a/packages/fakeyou.com/src/components/common/Uploader/index.tsx b/packages/fakeyou.com/src/components/common/Uploader/index.tsx new file mode 100644 index 0000000000..2d16ee2adb --- /dev/null +++ b/packages/fakeyou.com/src/components/common/Uploader/index.tsx @@ -0,0 +1 @@ +export { default } from './Uploader'; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/index.tsx b/packages/fakeyou.com/src/components/common/index.tsx new file mode 100644 index 0000000000..bee7e49142 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/index.tsx @@ -0,0 +1,5 @@ +import Uploader from './Uploader'; + +export { + Uploader, +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/layout/PageHeader/PageHeader.tsx b/packages/fakeyou.com/src/components/layout/PageHeader/PageHeader.tsx index d6f4b85956..e0c8b6e0e4 100644 --- a/packages/fakeyou.com/src/components/layout/PageHeader/PageHeader.tsx +++ b/packages/fakeyou.com/src/components/layout/PageHeader/PageHeader.tsx @@ -1,8 +1,9 @@ import React from "react"; interface Props { + childProps?: any; titleIcon?: JSX.Element; - extra?: React.ComponentType; + titleComponent?: React.ComponentType; title?: string; subText: string; showButtons: boolean; @@ -10,32 +11,23 @@ interface Props { } -//export default function PageHeader({ actionButtons, showButtons, subText, Extra, title, titleIcon }: Props) - -const PageHeader: React.FunctionComponent<Props> = ({ actionButtons, showButtons, subText, extra, title, titleIcon }) => { - console.log('aaa',extra); - const Extra = extra || null; - // return <div>Hiii</div>; - return <Extra/>; - // return <div className="container-panel hero-section py-4"> - // <div className="panel"> - // <div className="p-3 py-4 p-md-4"> - // <Extra hello="true"/> - // {/* { - // Title ? (<Title />) : <h1 className="fw-bold text-center text-md-start"> - // { titleIcon } - // { title } - // </h1> - // }*/} - // <p className="text-center text-md-start pt-1">{ subText }</p> - // { showButtons && ( - // <div className="d-flex flex-column flex-md-row gap-3 justify-content-center justify-content-md-start mt-4"> - // { actionButtons } - // </div> - // )} - // </div> - // </div> - // </div>; +export default function PageHeader({ actionButtons, childProps, showButtons, subText, titleComponent: Title, title, titleIcon }: Props) { + return <div className="container-panel hero-section py-4"> + <div className="panel"> + <div className="p-3 py-4 p-md-4"> + { Title ? <Title {...childProps }/> : <h1 className="fw-bold text-center text-md-start"> + { titleIcon } + { title } + </h1> } + <p className="text-center text-md-start pt-1">{ subText }</p> + { showButtons && ( + <div className="d-flex flex-column flex-md-row gap-3 justify-content-center justify-content-md-start mt-4"> + { actionButtons } + </div> + )} + </div> + </div> + </div>; }; -export default PageHeader; +// export default PageHeader; diff --git a/packages/fakeyou.com/src/components/layout/index.js b/packages/fakeyou.com/src/components/layout/index.tsx similarity index 100% rename from packages/fakeyou.com/src/components/layout/index.js rename to packages/fakeyou.com/src/components/layout/index.tsx diff --git a/packages/fakeyou.com/src/hooks/index.tsx b/packages/fakeyou.com/src/hooks/index.tsx new file mode 100644 index 0000000000..8ff5d6100e --- /dev/null +++ b/packages/fakeyou.com/src/hooks/index.tsx @@ -0,0 +1,3 @@ +import useUploader from './useUploader'; + +export { useUploader }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/hooks/useUploader/index.tsx b/packages/fakeyou.com/src/hooks/useUploader/index.tsx new file mode 100644 index 0000000000..bd6d3c6c8e --- /dev/null +++ b/packages/fakeyou.com/src/hooks/useUploader/index.tsx @@ -0,0 +1 @@ +export { default } from "./useUploader"; \ No newline at end of file diff --git a/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx b/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx new file mode 100644 index 0000000000..632ea77018 --- /dev/null +++ b/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx @@ -0,0 +1,62 @@ +import { useState } from 'react'; +import { v4 as uuidv4 } from "uuid"; +import { UploadAudio, UploadAudioIsOk, UploadAudioRequest } from "@storyteller/components/src/api/upload/UploadAudio"; + +const n = (o: any) => o; + +interface Props { + formClearedSet?: (cleared: boolean) => void; +} + +export default function useUploader({ formClearedSet = n }: Props) { + const [file, fileSet] = useState<any>(undefined); + const [audioLink, audioLinkSet] = useState<string>(); + const [uploading, uploadingSet] = useState(false); + const [uploadDisabled, uploadDisabledSet] = useState<boolean>(false); + const [mediaUploadToken, mediaUploadTokenSet] = useState<string | undefined>(undefined); + const [convertIdempotencyToken, convertIdempotencyTokenSet] = useState(uuidv4()); + const [canConvert, canConvertSet] = useState(false); + const [iToken, iTokenSet] = useState(uuidv4()); // Auto generated + const resetIToken = () => iTokenSet(uuidv4()); + + const handleUploadFile = async () => { + if (file === undefined) { return false; } + + uploadingSet(true); + + const request: UploadAudioRequest = { + uuid_idempotency_token: iToken, + file: file, + source: "file", + }; + + let result = await UploadAudio(request); + + if (UploadAudioIsOk(result)) { + uploadDisabledSet(true); + mediaUploadTokenSet(result.upload_token); + formClearedSet(false); + canConvertSet(true); + } + + uploadingSet(false); + }; + const inputChange = (file?: any) => { + convertIdempotencyTokenSet(uuidv4()); + fileSet(file || null); + audioLinkSet(file ? URL.createObjectURL(file) : ""); + canConvertSet(false); + resetIToken(); + uploadDisabledSet(false); + formClearedSet(!file); + }; + const onChange = ({ target = {} }: { target: any }) => { + inputChange(target.value); + }; + const onClear = () => { + inputChange(); + mediaUploadTokenSet(undefined); + }; + + return { audioLink, canConvert, convertIdempotencyToken, file, fileSet, handleUploadFile, idempotency: { token: iToken, set: iTokenSet}, mediaUploadToken, mediaUploadTokenSet, onChange, onClear, resetIToken, uploading, uploadDisabled, uploadingSet }; +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss new file mode 100644 index 0000000000..3e8d0401f6 --- /dev/null +++ b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss @@ -0,0 +1,41 @@ +.progress-header { + display: flex; + align-items: center; + margin-bottom: 1rem; + + .progress-heading { + display: inline-block; + margin: auto 1rem auto 0; + } + + .async-progress-tracker { + display: inline-flex; + justify-content: space-around; + flex-grow: 1; + margin-right: 1rem; + padding-left: 0; + + li { + display: flex; + align-items: center; + font-size: 1.25rem; + font-weight: 500; + } + + svg { + border: 2px solid #fff; + border-radius: 50%; + margin-right: .5rem; + height: 2rem; + width: 2rem; + stroke: white; + } + } + + button { + margin: 0 0 0 auto; + background-color: #ccccff; + // flex-grow: 1; + width: fit-content; + } +} \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx index 98cdddf69b..667c78c6b7 100644 --- a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx @@ -1,14 +1,73 @@ import React from "react"; -import { PageHeader } from "components/layout" +import { useUploader } from "hooks"; +import { Uploader } from "components/common"; +import { PageHeader } from "components/layout"; +import './LipsyncEditor.scss'; -const Title: React.ComponentType = () => <div> - <h1 className="fw-bold text-center text-md-start"> - Hello - </h1> -</div>; +// interface Props { +// titleIcon?: JSX.Element; +// extra?: React.ComponentType; +// title?: string; +// subText: string; +// showButtons: boolean; +// actionButtons?: JSX.Element; +// } + +const ProgressCheck = ({ disabled = false }: {disabled?: boolean}) => <svg> + { !disabled && <polyline {...{ + fill: 'none', + points: '7 16 12 20 20 10', + strokeLinecap: 'round', + strokeLinejoin: 'round', + strokeWidth: '4', + }}/> } +</svg>; + +const Title = ({ ...rest }) => { + console.log('🥚',rest) + return <div {...{ className: 'progress-header' }}> + <h1 {...{ className: "fw-bold text-center text-md-start progress-heading" }}> + Generate a lipsync + </h1> + <ul {...{ className: 'async-progress-tracker' }}> + <li> + <ProgressCheck {...{}}/> + Image + </li> + <li> + <ProgressCheck {...{ disabled: false }}/> + Audio + </li> + </ul> + <button className="btn btn-primary"> + Generate + </button> + </div> +}; export default function LipsyncEditor({ ...rest }) { + const { file: audioFile, ...uploader } = useUploader({}); + + const subText = "Select an image with a clear face, or one of our existing templates, then choose either text to speech or uploaded audio(eg. music). Then you can generate a beautifully lipsynced video."; + const headerProps = { + childProps: { audioFile }, + titleComponent: Title, + subText, + showButtons: false + }; + return <div> - <PageHeader {...{ extra: Title, subText: "some text", showButtons: false,}}/> + <PageHeader { ...headerProps }/> + <div className="container"> + <div className="panel d-flex p-md-4"> + <div {...{ className: "col-12 col-lg-6" }}> + <h5>Image</h5> + </div> + <div {...{ className: "col-12 col-lg-6" }}> + <h5>Audio</h5> + <Uploader {...{ file: audioFile, ...uploader }}/> + </div> + </div> + </div> </div>; }; \ No newline at end of file From 16aeb6afd32e93862a68aefac34f5a4d013d36c3 Mon Sep 17 00:00:00 2001 From: olivicmic <vic@vics.pics> Date: Mon, 31 Jul 2023 09:04:00 -0700 Subject: [PATCH 3/8] removed react-drag-drop-files dependency --- .../components/common/Uploader/Uploader.scss | 16 +++++++ .../components/common/Uploader/Uploader.tsx | 47 +++++++++---------- 2 files changed, 38 insertions(+), 25 deletions(-) create mode 100644 packages/fakeyou.com/src/components/common/Uploader/Uploader.scss diff --git a/packages/fakeyou.com/src/components/common/Uploader/Uploader.scss b/packages/fakeyou.com/src/components/common/Uploader/Uploader.scss new file mode 100644 index 0000000000..a22dc5a993 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/Uploader/Uploader.scss @@ -0,0 +1,16 @@ +.fy-uploader { + [type="file"] { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + overflow: hidden; + padding: 0; + position: absolute !important; + white-space: nowrap; + width: 1px; + + + label { + cursor: pointer; + } + } +} \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx b/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx index a4d2bb8a4b..fb26f26022 100644 --- a/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx +++ b/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx @@ -1,21 +1,16 @@ import React from "react"; -import { FileUploader } from "react-drag-drop-files"; import { faCheck, faFileArrowUp, faFileAudio, faTrash } from "@fortawesome/pro-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome"; import { InputVcAudioPlayer } from "v2/view/_common/InputVcAudioPlayer"; import LoadingIcon from "./LoadingIcon"; +import './Uploader.scss' const FILE_TYPES = ["MP3", "WAV", "FLAC", "OGG"]; -interface Idempotency { token: any; set: (file?: any) => void; } - interface Props { audioLink?: string; file?: any; - fileSet?: (file?: any) => void; - canConvertSet?: (canConvert: boolean) => void; handleUploadFile?: () => void; - idempotency?: Idempotency; onChange?: (file?: any) => void; onClear?: (file?: any) => void; uploading?: boolean; @@ -24,20 +19,27 @@ interface Props { const n = () => {}; -export default function Uploader({ audioLink = "", file, fileSet = n, canConvertSet = n, handleUploadFile = n, idempotency = { token: '', set: n }, onChange = n, onClear = n, uploading = false, uploadDisabled = false }: Props) { +export default function Uploader({ audioLink = "", file, handleUploadFile = n, onChange = n, onClear = n, uploading = false, uploadDisabled = false }: Props) { - const handleChange = (file: any) => { - onChange({ target: { name: 'uploader', value: file }}); + const fileChange = ({ target }: { target: any }) => { + onChange({ target: { name: 'uploader', value: target.files[0] }}); }; const handleClear = () => { onClear(); }; + const onDragDrop = (e: any) => { e.preventDefault(); e.stopPropagation(); }; const onDragEvent = (onOff: number) => (e: React.DragEvent<HTMLDivElement>): void => { - e.preventDefault(); - e.stopPropagation(); + onDragDrop(e); e.currentTarget.classList[onOff ? "add" : "remove" ]("upload-zone-drag"); }; + const onDrop = (e: React.DragEvent<HTMLDivElement>): void => { + onDragDrop(e); + if (e.dataTransfer.files && e.dataTransfer.files[0]) { + onChange({ target: { name: 'uploader', value: e.dataTransfer.files[0] }}); + } + }; + const fileSize = file && file.size >= 1024 * 1024 ? (file.size / 1024 / 1024).toFixed(2) + " MB" @@ -50,14 +52,11 @@ export default function Uploader({ audioLink = "", file, fileSet = n, canConvert : "btn btn-primary w-100"; return ( - <div className="d-flex flex-column gap-3"> - {/* Usage refer to https://github.com/KarimMokhtar/react-drag-drop-files */} - <FileUploader {...{ handleChange, maxSize: 50, name: "file", types: FILE_TYPES }} - children={ - <div {...{ className: "panel panel-inner upload-zone d-flex align-items-center p-3", - onDragLeave: onDragEvent(1), onDragOver: onDragEvent(0) }}> - <div className="me-4"> - <FontAwesomeIcon {...{ className: "upload-icon", icon: file ? faFileAudio : faFileArrowUp }}/> + <div {...{ className: "fy-uploader d-flex flex-column gap-3", onDragLeave: onDragEvent(1), onDragOver: onDragEvent(0), onDrop }}> + <input { ...{ name: 'file', onChange: fileChange, type: 'file', id: 'file' }} /> + <label {...{ className: "panel panel-inner upload-zone d-flex align-items-center p-3", htmlFor: "file"}} > + <div className="me-4"> + <Icon {...{ className: "upload-icon", icon: file ? faFileAudio : faFileArrowUp }}/> </div> <div> <div className="pb-0"> @@ -90,20 +89,18 @@ export default function Uploader({ audioLink = "", file, fileSet = n, canConvert </div> </div> </div> - </div> - } - /> + </label> { file && <> <div className="panel panel-inner rounded p-3"> <InputVcAudioPlayer {...{ filename: audioLink as string }}/> </div> <div className="d-flex gap-3"> <button {...{ className: uploadBtnClass, disabled: uploading || uploadDisabled, onClick: () => handleUploadFile(), type: "submit", }}> - <FontAwesomeIcon {...{ className: "me-2", icon: uploadDisabled ? faCheck : faFileArrowUp, }}/> + <Icon {...{ className: "me-2", icon: uploadDisabled ? faCheck : faFileArrowUp, }}/> { uploading && <LoadingIcon /> } </button> <button className="btn btn-destructive w-100" onClick={handleClear}> - <FontAwesomeIcon icon={faTrash} className="me-2" /> + <Icon icon={faTrash} className="me-2" /> Clear </button> </div> From c488fbca1a9c59f751c6de5e6d6c1882558e604b Mon Sep 17 00:00:00 2001 From: olivicmic <vic@vics.pics> Date: Tue, 1 Aug 2023 17:48:53 -0700 Subject: [PATCH 4/8] split uploader into AudioUploader and ImageUploader. Uploader is now a component they share which handles file inputs --- .../common/AudioUploader/AudioUploader.scss | 16 +++ .../common/AudioUploader/AudioUploader.tsx | 75 ++++++++++++++ .../common/AudioUploader/LoadingIcon.tsx | 12 +++ .../components/common/AudioUploader/index.tsx | 1 + .../common/ImageUploader/ImageUploader.scss | 22 +++++ .../common/ImageUploader/ImageUploader.tsx | 24 +++++ .../components/common/ImageUploader/index.tsx | 1 + .../common/UploadLabel/UploadLabel.tsx | 27 +++++ .../components/common/UploadLabel/index.tsx | 1 + .../components/common/Uploader/Uploader.tsx | 99 +++---------------- .../src/components/common/index.tsx | 6 ++ packages/fakeyou.com/src/hooks/index.tsx | 3 +- .../fakeyou.com/src/hooks/useId/index.tsx | 1 + .../fakeyou.com/src/hooks/useId/useId.tsx | 15 +++ .../src/hooks/useUploader/useUploader.tsx | 34 ++++--- .../lipsync/LipsyncEditor/LipsyncEditor.scss | 26 +++++ .../lipsync/LipsyncEditor/LipsyncEditor.tsx | 23 +++-- 17 files changed, 276 insertions(+), 110 deletions(-) create mode 100644 packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.scss create mode 100644 packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx create mode 100644 packages/fakeyou.com/src/components/common/AudioUploader/LoadingIcon.tsx create mode 100644 packages/fakeyou.com/src/components/common/AudioUploader/index.tsx create mode 100644 packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.scss create mode 100644 packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx create mode 100644 packages/fakeyou.com/src/components/common/ImageUploader/index.tsx create mode 100644 packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx create mode 100644 packages/fakeyou.com/src/components/common/UploadLabel/index.tsx create mode 100644 packages/fakeyou.com/src/hooks/useId/index.tsx create mode 100644 packages/fakeyou.com/src/hooks/useId/useId.tsx diff --git a/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.scss b/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.scss new file mode 100644 index 0000000000..a22dc5a993 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.scss @@ -0,0 +1,16 @@ +.fy-uploader { + [type="file"] { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + overflow: hidden; + padding: 0; + position: absolute !important; + white-space: nowrap; + width: 1px; + + + label { + cursor: pointer; + } + } +} \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx b/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx new file mode 100644 index 0000000000..2472078002 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx @@ -0,0 +1,75 @@ +import React from "react"; +import { faCheck, faFileArrowUp, faTrash } from "@fortawesome/pro-solid-svg-icons"; +import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome"; +import { InputVcAudioPlayer } from "v2/view/_common/InputVcAudioPlayer"; +import { Uploader, UploadLabel } from 'components/common'; +import LoadingIcon from "./LoadingIcon"; +import './AudioUploader.scss' + +const FILE_TYPES = ["MP3", "WAV", "FLAC", "OGG"]; + +interface Props { + blob?: string; + file?: any; + handleUploadFile?: () => void; + onChange?: (file?: any) => void; + onClear?: (file?: any) => void; + uploading?: boolean; + uploadDisabled?: boolean; +} + +const n = () => {}; + +export default function AudioUploader({ blob = "", file, handleUploadFile = n, onChange = n, onClear = n, uploading = false, uploadDisabled = false }: Props) { + console.log("🥶",file); + const handleClear = () => { onClear(); }; + const fileSize = + file && file.size >= 1024 * 1024 + ? (file.size / 1024 / 1024).toFixed(2) + " MB" + : file + ? `${Math.floor(file.size / 1024)} KB` + : null; + + const uploadBtnClass = uploadDisabled + ? "btn btn-uploaded w-100 disabled" + : "btn btn-primary w-100"; + + return <> + <Uploader {...{ onChange, panelClass: 'p-3' }}> + <UploadLabel {...{ file }}> + <div className="d-flex gap-1"> + <div> + {file ? ( + <p> + <span className="opacity-50"> + {file && `${file.name.split(".").pop().toUpperCase()}`}{" "} + file size: {fileSize} + </span>{" "} + <u className="fw-medium opacity-100 ms-1">Change file</u> + </p> + ) : ( + <p className="opacity-50"> + {FILE_TYPES.join(", ").toString()} supported + </p> + )} + </div> + </div> + </UploadLabel> + </Uploader> + { file && <> + <div className="panel panel-inner rounded p-3"> + <InputVcAudioPlayer {...{ filename: blob as string }}/> + </div> + <div className="d-flex gap-3"> + <button {...{ className: uploadBtnClass, disabled: uploading || uploadDisabled, onClick: () => handleUploadFile(), type: "submit", }}> + <Icon {...{ className: "me-2", icon: uploadDisabled ? faCheck : faFileArrowUp, }}/> + { uploading && <LoadingIcon /> } + </button> + <button className="btn btn-destructive w-100" onClick={handleClear}> + <Icon icon={faTrash} className="me-2" /> + Clear + </button> + </div> + </> } + </>; +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/AudioUploader/LoadingIcon.tsx b/packages/fakeyou.com/src/components/common/AudioUploader/LoadingIcon.tsx new file mode 100644 index 0000000000..dce6894198 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/AudioUploader/LoadingIcon.tsx @@ -0,0 +1,12 @@ +import React from "react"; + +export default function LoadingIcon() { + return <> + <span + className="spinner-border spinner-border-sm ms-3" + role="status" + aria-hidden="true" + ></span> + <span className="visually-hidden">Loading...</span> + </>; +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/AudioUploader/index.tsx b/packages/fakeyou.com/src/components/common/AudioUploader/index.tsx new file mode 100644 index 0000000000..d7d3905d81 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/AudioUploader/index.tsx @@ -0,0 +1 @@ +export { default } from './AudioUploader'; diff --git a/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.scss b/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.scss new file mode 100644 index 0000000000..d422534dec --- /dev/null +++ b/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.scss @@ -0,0 +1,22 @@ +@import "scss/colours.scss"; + +.fy-image-uploader { + overflow: hidden; + height: 100%; + width: 100%; + + .file-preview { + height: 100%; + width: 100%; + border-radius: .5rem; + object-fit: cover; + } + + .file-details { + background-color: rgba($panel, .85); + top: 1rem; + left: 1rem; + width: calc(100% - 2rem); + position: absolute; + } +} \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx b/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx new file mode 100644 index 0000000000..c22694bd86 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import { Uploader } from "components/common"; +import "./ImageUploader.scss"; + +interface Props { + blob?: string; + file?: any; + handleUploadFile?: () => void; + onChange?: (file?: any) => void; + onClear?: (file?: any) => void; + uploading?: boolean; + uploadDisabled?: boolean; +} + +const n = () => {}; + +export default function ImageUploader({ blob = "", file, handleUploadFile = n, onChange = n, onClear = n, uploading = false, uploadDisabled = false }: Props) { + return <Uploader {...{ onChange }}> + <div {...{ className: "fy-image-uploader" }}> + <img {...{ alt: "file preview", className: "file-preview", src: blob }} /> + <div {...{ className: "file-details panel rounded p-3" }}>Hi</div> + </div> + </Uploader>; +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/ImageUploader/index.tsx b/packages/fakeyou.com/src/components/common/ImageUploader/index.tsx new file mode 100644 index 0000000000..3695b16bd2 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/ImageUploader/index.tsx @@ -0,0 +1 @@ +export { default } from './ImageUploader'; diff --git a/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx b/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx new file mode 100644 index 0000000000..dfcc27d308 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome"; +import { faFileArrowUp, faFileAudio } from "@fortawesome/pro-solid-svg-icons"; + +interface Props { + children?: JSX.Element|JSX.Element[]; + file?: any; +} + +export default function UploadLabel({ children, file }: Props) { + return <> + <div className="me-4"> + <Icon {...{ className: "upload-icon", icon: file ? faFileAudio : faFileArrowUp }}/> + </div> + <div> + <div className="pb-0"> + { file ? <span className="filename" title={file.name}> + { file.name.slice(0, file.name.lastIndexOf(".")) } + </span> : <> + <u className="fw-medium">Upload a file</u> or drop it + here... + </> } + </div> + { children } + </div> + </>; +}; diff --git a/packages/fakeyou.com/src/components/common/UploadLabel/index.tsx b/packages/fakeyou.com/src/components/common/UploadLabel/index.tsx new file mode 100644 index 0000000000..3b934839e2 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/UploadLabel/index.tsx @@ -0,0 +1 @@ +export { default } from './UploadLabel'; diff --git a/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx b/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx index fb26f26022..377ff250d6 100644 --- a/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx +++ b/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx @@ -1,31 +1,21 @@ import React from "react"; -import { faCheck, faFileArrowUp, faFileAudio, faTrash } from "@fortawesome/pro-solid-svg-icons"; -import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome"; -import { InputVcAudioPlayer } from "v2/view/_common/InputVcAudioPlayer"; -import LoadingIcon from "./LoadingIcon"; +import { useId } from 'hooks'; // replace with react v18 import './Uploader.scss' -const FILE_TYPES = ["MP3", "WAV", "FLAC", "OGG"]; - interface Props { - audioLink?: string; - file?: any; - handleUploadFile?: () => void; - onChange?: (file?: any) => void; - onClear?: (file?: any) => void; - uploading?: boolean; - uploadDisabled?: boolean; -} + children?: JSX.Element|JSX.Element[]; + containerClass?: string; + onChange: (file?: any) => void; + panelClass?: string; +}; -const n = () => {}; - -export default function Uploader({ audioLink = "", file, handleUploadFile = n, onChange = n, onClear = n, uploading = false, uploadDisabled = false }: Props) { +export default function Uploader({ children, containerClass, onChange, panelClass }: Props) { + const id = 'uploader-' + useId(); const fileChange = ({ target }: { target: any }) => { onChange({ target: { name: 'uploader', value: target.files[0] }}); }; - const handleClear = () => { onClear(); }; const onDragDrop = (e: any) => { e.preventDefault(); e.stopPropagation(); }; const onDragEvent = (onOff: number) => (e: React.DragEvent<HTMLDivElement>): void => { @@ -40,71 +30,10 @@ export default function Uploader({ audioLink = "", file, handleUploadFile = n, o } }; - const fileSize = - file && file.size >= 1024 * 1024 - ? (file.size / 1024 / 1024).toFixed(2) + " MB" - : file - ? `${Math.floor(file.size / 1024)} KB` - : null; - - const uploadBtnClass = uploadDisabled - ? "btn btn-uploaded w-100 disabled" - : "btn btn-primary w-100"; - - return ( - <div {...{ className: "fy-uploader d-flex flex-column gap-3", onDragLeave: onDragEvent(1), onDragOver: onDragEvent(0), onDrop }}> - <input { ...{ name: 'file', onChange: fileChange, type: 'file', id: 'file' }} /> - <label {...{ className: "panel panel-inner upload-zone d-flex align-items-center p-3", htmlFor: "file"}} > - <div className="me-4"> - <Icon {...{ className: "upload-icon", icon: file ? faFileAudio : faFileArrowUp }}/> - </div> - <div> - <div className="pb-0"> - {file ? ( - <span className="filename" title={file.name}> - {file.name.slice(0, file.name.lastIndexOf("."))} - </span> - ) : ( - <> - <u className="fw-medium">Upload a file</u> or drop it - here... - </> - )} - </div> - <div className="d-flex gap-1"> - <div> - {file ? ( - <p> - <span className="opacity-50"> - {file && `${file.name.split(".").pop().toUpperCase()}`}{" "} - file size: {fileSize} - </span>{" "} - <u className="fw-medium opacity-100 ms-1">Change file</u> - </p> - ) : ( - <p className="opacity-50"> - {FILE_TYPES.join(", ").toString()} supported - </p> - )} - </div> - </div> - </div> - </label> - { file && <> - <div className="panel panel-inner rounded p-3"> - <InputVcAudioPlayer {...{ filename: audioLink as string }}/> - </div> - <div className="d-flex gap-3"> - <button {...{ className: uploadBtnClass, disabled: uploading || uploadDisabled, onClick: () => handleUploadFile(), type: "submit", }}> - <Icon {...{ className: "me-2", icon: uploadDisabled ? faCheck : faFileArrowUp, }}/> - { uploading && <LoadingIcon /> } - </button> - <button className="btn btn-destructive w-100" onClick={handleClear}> - <Icon icon={faTrash} className="me-2" /> - Clear - </button> - </div> - </> } - </div> - ); + return <div {...{ className: `fy-uploader${ containerClass ? " " + containerClass : "" }`, onDragLeave: onDragEvent(1), onDragOver: onDragEvent(0), onDrop }}> + <input { ...{ name: "file", onChange: fileChange, type: "file", id }} /> + <label {...{ className: `panel panel-inner upload-zone d-flex align-items-center${ panelClass ? " " + panelClass : "" }`, htmlFor: id }} > + { children } + </label> + </div>; }; diff --git a/packages/fakeyou.com/src/components/common/index.tsx b/packages/fakeyou.com/src/components/common/index.tsx index bee7e49142..eed171c125 100644 --- a/packages/fakeyou.com/src/components/common/index.tsx +++ b/packages/fakeyou.com/src/components/common/index.tsx @@ -1,5 +1,11 @@ +import AudioUploader from './AudioUploader'; +import ImageUploader from './ImageUploader'; import Uploader from './Uploader'; +import UploadLabel from './UploadLabel'; export { + AudioUploader, + ImageUploader, Uploader, + UploadLabel }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/hooks/index.tsx b/packages/fakeyou.com/src/hooks/index.tsx index 8ff5d6100e..3748987f4d 100644 --- a/packages/fakeyou.com/src/hooks/index.tsx +++ b/packages/fakeyou.com/src/hooks/index.tsx @@ -1,3 +1,4 @@ +import useId from './useId'; import useUploader from './useUploader'; -export { useUploader }; \ No newline at end of file +export { useId, useUploader }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/hooks/useId/index.tsx b/packages/fakeyou.com/src/hooks/useId/index.tsx new file mode 100644 index 0000000000..bf8a1630ed --- /dev/null +++ b/packages/fakeyou.com/src/hooks/useId/index.tsx @@ -0,0 +1 @@ +export { default } from './useId'; diff --git a/packages/fakeyou.com/src/hooks/useId/useId.tsx b/packages/fakeyou.com/src/hooks/useId/useId.tsx new file mode 100644 index 0000000000..57852ce56f --- /dev/null +++ b/packages/fakeyou.com/src/hooks/useId/useId.tsx @@ -0,0 +1,15 @@ +import { useEffect, useState } from 'react'; + +const S4 = () => (((1+Math.random())*0x10000)|0).toString(16).substring(1); + +export default function useId() { + const [id,idSet] = useState<string>(); + + useEffect(() => { + if (!id) idSet(S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4()); + },[id]); + + return id; +}; + +// based on https://stackoverflow.com/questions/6860853/generate-random-string-for-div-id/6860916#6860916 \ No newline at end of file diff --git a/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx b/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx index 632ea77018..9aec56d9dd 100644 --- a/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx +++ b/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx @@ -5,19 +5,20 @@ import { UploadAudio, UploadAudioIsOk, UploadAudioRequest } from "@storyteller/c const n = (o: any) => o; interface Props { - formClearedSet?: (cleared: boolean) => void; + debug?: boolean; + formClearedSet?: (cleared: boolean) => void; } -export default function useUploader({ formClearedSet = n }: Props) { - const [file, fileSet] = useState<any>(undefined); - const [audioLink, audioLinkSet] = useState<string>(); - const [uploading, uploadingSet] = useState(false); - const [uploadDisabled, uploadDisabledSet] = useState<boolean>(false); - const [mediaUploadToken, mediaUploadTokenSet] = useState<string | undefined>(undefined); - const [convertIdempotencyToken, convertIdempotencyTokenSet] = useState(uuidv4()); - const [canConvert, canConvertSet] = useState(false); - const [iToken, iTokenSet] = useState(uuidv4()); // Auto generated - const resetIToken = () => iTokenSet(uuidv4()); +export default function useUploader({ debug, formClearedSet = n }: Props) { + const [file, fileSet] = useState<any>(undefined); + const [blob, blobSet] = useState<string>(); + const [uploading, uploadingSet] = useState(false); + const [uploadDisabled, uploadDisabledSet] = useState<boolean>(false); + const [mediaUploadToken, mediaUploadTokenSet] = useState<string | undefined>(undefined); + const [convertIdempotencyToken, convertIdempotencyTokenSet] = useState(uuidv4()); + const [canConvert, canConvertSet] = useState(false); + const [iToken, iTokenSet] = useState(uuidv4()); // Auto generated + const resetIToken = () => iTokenSet(uuidv4()); const handleUploadFile = async () => { if (file === undefined) { return false; } @@ -41,14 +42,15 @@ export default function useUploader({ formClearedSet = n }: Props) { uploadingSet(false); }; - const inputChange = (file?: any) => { + const inputChange = (inputFile?: any) => { + console.log("🍡",inputFile); convertIdempotencyTokenSet(uuidv4()); - fileSet(file || null); - audioLinkSet(file ? URL.createObjectURL(file) : ""); + fileSet(inputFile || null); + blobSet(inputFile ? URL.createObjectURL(inputFile) : ""); canConvertSet(false); resetIToken(); uploadDisabledSet(false); - formClearedSet(!file); + formClearedSet(!inputFile); }; const onChange = ({ target = {} }: { target: any }) => { inputChange(target.value); @@ -58,5 +60,5 @@ export default function useUploader({ formClearedSet = n }: Props) { mediaUploadTokenSet(undefined); }; - return { audioLink, canConvert, convertIdempotencyToken, file, fileSet, handleUploadFile, idempotency: { token: iToken, set: iTokenSet}, mediaUploadToken, mediaUploadTokenSet, onChange, onClear, resetIToken, uploading, uploadDisabled, uploadingSet }; + return { blob, canConvert, convertIdempotencyToken, file, fileSet, handleUploadFile, idempotency: { token: iToken, set: iTokenSet}, mediaUploadToken, mediaUploadTokenSet, onChange, onClear, resetIToken, uploading, uploadDisabled, uploadingSet }; }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss index 3e8d0401f6..d58163d15a 100644 --- a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss +++ b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss @@ -1,3 +1,29 @@ +.lipsync-editor { + display: grid; + grid-template-columns: repeat(2, 1fr); + grid-gap: 1rem; + + .grid-square { + aspect-ratio: 1; + padding-bottom: 1rem; + &:nth-child(odd) { + padding-left: 1rem; + } + &:nth-child(even) { + padding-right: 1rem; + } + } + + + + + // div.grid-square { aspect-ratio: 1 } + .fy-uploader { height: 100%; } + .lipsync-audio { + label { height: 100% } + } +} + .progress-header { display: flex; align-items: center; diff --git a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx index 667c78c6b7..613a38cc76 100644 --- a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx @@ -1,6 +1,6 @@ import React from "react"; import { useUploader } from "hooks"; -import { Uploader } from "components/common"; +import { AudioUploader, ImageUploader } from "components/common"; import { PageHeader } from "components/layout"; import './LipsyncEditor.scss'; @@ -46,26 +46,33 @@ const Title = ({ ...rest }) => { }; export default function LipsyncEditor({ ...rest }) { - const { file: audioFile, ...uploader } = useUploader({}); + const audioProps = useUploader({ debug: true }); + const imageProps = useUploader({}); const subText = "Select an image with a clear face, or one of our existing templates, then choose either text to speech or uploaded audio(eg. music). Then you can generate a beautifully lipsynced video."; const headerProps = { - childProps: { audioFile }, + childProps: { audioProps, imageProps }, titleComponent: Title, subText, showButtons: false }; + console.log("👁",imageProps); return <div> <PageHeader { ...headerProps }/> - <div className="container"> - <div className="panel d-flex p-md-4"> - <div {...{ className: "col-12 col-lg-6" }}> + <div {...{ className: "container" }}> + <div {...{ className: "lipsync-editor panel" }}> + <div {...{ className: "grid-title" }}> <h5>Image</h5> </div> - <div {...{ className: "col-12 col-lg-6" }}> + <div {...{ className: "grid-title" }}> <h5>Audio</h5> - <Uploader {...{ file: audioFile, ...uploader }}/> + </div> + <div {...{ className: "grid-square lipsync-audio" }}> + <ImageUploader {...imageProps}/> + </div> + <div {...{ className: "grid-square" }}> + <AudioUploader {...audioProps}/> </div> </div> </div> From 3715c634afd62fa94684534243188a4de38e902d Mon Sep 17 00:00:00 2001 From: olivicmic <vic@vics.pics> Date: Thu, 3 Aug 2023 13:44:31 -0700 Subject: [PATCH 5/8] further broker uploaders into components --- .../common/AudioUploader/AudioUploader.tsx | 56 +++---------------- .../common/ImageUploader/ImageUploader.scss | 23 +++++++- .../common/ImageUploader/ImageUploader.tsx | 17 +++++- .../LoadingIcon.tsx | 0 .../common/UploadActions/UploadActions.tsx | 28 ++++++++++ .../components/common/UploadActions/index.tsx | 1 + .../common/UploadDetails/UploadDetails.tsx | 26 +++++++++ .../components/common/UploadDetails/index.tsx | 1 + .../common/UploadLabel/UploadLabel.scss | 3 + .../common/UploadLabel/UploadLabel.tsx | 11 +++- .../src/components/common/index.tsx | 4 ++ .../lipsync/LipsyncEditor/LipsyncEditor.scss | 29 ++++++++-- .../lipsync/LipsyncEditor/LipsyncEditor.tsx | 23 ++++---- 13 files changed, 149 insertions(+), 73 deletions(-) rename packages/fakeyou.com/src/components/common/{AudioUploader => UploadActions}/LoadingIcon.tsx (100%) create mode 100644 packages/fakeyou.com/src/components/common/UploadActions/UploadActions.tsx create mode 100644 packages/fakeyou.com/src/components/common/UploadActions/index.tsx create mode 100644 packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.tsx create mode 100644 packages/fakeyou.com/src/components/common/UploadDetails/index.tsx create mode 100644 packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.scss diff --git a/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx b/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx index 2472078002..cca0116fe8 100644 --- a/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx +++ b/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx @@ -1,75 +1,37 @@ import React from "react"; -import { faCheck, faFileArrowUp, faTrash } from "@fortawesome/pro-solid-svg-icons"; -import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome"; import { InputVcAudioPlayer } from "v2/view/_common/InputVcAudioPlayer"; -import { Uploader, UploadLabel } from 'components/common'; -import LoadingIcon from "./LoadingIcon"; +import { UploadActions, UploadDetails, Uploader, UploadLabel } from 'components/common'; import './AudioUploader.scss' -const FILE_TYPES = ["MP3", "WAV", "FLAC", "OGG"]; +const fileTypes = ["MP3", "WAV", "FLAC", "OGG"]; interface Props { blob?: string; + disabled?: boolean; file?: any; - handleUploadFile?: () => void; + handleUpload?: () => void; onChange?: (file?: any) => void; onClear?: (file?: any) => void; uploading?: boolean; - uploadDisabled?: boolean; } const n = () => {}; -export default function AudioUploader({ blob = "", file, handleUploadFile = n, onChange = n, onClear = n, uploading = false, uploadDisabled = false }: Props) { - console.log("🥶",file); - const handleClear = () => { onClear(); }; - const fileSize = - file && file.size >= 1024 * 1024 - ? (file.size / 1024 / 1024).toFixed(2) + " MB" - : file - ? `${Math.floor(file.size / 1024)} KB` - : null; +export default function AudioUploader({ blob = "", disabled = false, file, handleUpload = n, onChange = n, onClear = n, uploading = false }: Props) { - const uploadBtnClass = uploadDisabled - ? "btn btn-uploaded w-100 disabled" - : "btn btn-primary w-100"; + const handleClear = () => { onClear(); }; return <> <Uploader {...{ onChange, panelClass: 'p-3' }}> - <UploadLabel {...{ file }}> - <div className="d-flex gap-1"> - <div> - {file ? ( - <p> - <span className="opacity-50"> - {file && `${file.name.split(".").pop().toUpperCase()}`}{" "} - file size: {fileSize} - </span>{" "} - <u className="fw-medium opacity-100 ms-1">Change file</u> - </p> - ) : ( - <p className="opacity-50"> - {FILE_TYPES.join(", ").toString()} supported - </p> - )} - </div> - </div> + <UploadLabel {...{ file, fileTypes }}> + <UploadDetails {...{ file }}/> </UploadLabel> </Uploader> { file && <> <div className="panel panel-inner rounded p-3"> <InputVcAudioPlayer {...{ filename: blob as string }}/> </div> - <div className="d-flex gap-3"> - <button {...{ className: uploadBtnClass, disabled: uploading || uploadDisabled, onClick: () => handleUploadFile(), type: "submit", }}> - <Icon {...{ className: "me-2", icon: uploadDisabled ? faCheck : faFileArrowUp, }}/> - { uploading && <LoadingIcon /> } - </button> - <button className="btn btn-destructive w-100" onClick={handleClear}> - <Icon icon={faTrash} className="me-2" /> - Clear - </button> - </div> + <UploadActions {...{ disabled, handleClear, handleUpload, uploading }}/> </> } </>; }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.scss b/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.scss index d422534dec..1ed9219673 100644 --- a/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.scss +++ b/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.scss @@ -1,6 +1,9 @@ @import "scss/colours.scss"; .fy-image-uploader { + display: flex; + justify-content: center; + align-items: center; overflow: hidden; height: 100%; width: 100%; @@ -11,12 +14,26 @@ border-radius: .5rem; object-fit: cover; } - - .file-details { + .image-upload-label, .upload-details { background-color: rgba($panel, .85); + position: absolute; + } + .image-upload-label { + border-radius: .5rem .5rem 0 0; + display: flex; + width: 100%; + top: 0; + padding: 1rem; + } + + .upload-details { top: 1rem; left: 1rem; width: calc(100% - 2rem); - position: absolute; + } + + .image-placeholder { + // background-color: red; + fill: $secondary; } } \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx b/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx index c22694bd86..93cd2af2e7 100644 --- a/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx +++ b/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx @@ -1,7 +1,9 @@ import React from "react"; -import { Uploader } from "components/common"; +import { UploadDetails, Uploader, UploadLabel } from "components/common"; import "./ImageUploader.scss"; +const fileTypes = ["JPG", "GIF", "PNG"]; + interface Props { blob?: string; file?: any; @@ -17,8 +19,17 @@ const n = () => {}; export default function ImageUploader({ blob = "", file, handleUploadFile = n, onChange = n, onClear = n, uploading = false, uploadDisabled = false }: Props) { return <Uploader {...{ onChange }}> <div {...{ className: "fy-image-uploader" }}> - <img {...{ alt: "file preview", className: "file-preview", src: blob }} /> - <div {...{ className: "file-details panel rounded p-3" }}>Hi</div> + { file ? <> + <img {...{ alt: "file preview", className: "file-preview", src: blob }} /> + <UploadDetails {...{ file }}/> + </> : <> + <svg {...{ className: "image-placeholder", height: 400, viewBox: "0 0 300 300", width: 400 }}> + <path d="m152.42 226c41.8 0 69.49-43.57 73.21-90.87 3.78-47.97-26.06-87.13-75.69-87.13-49.64 0-79.28 39.15-75.69 87.13 3.72 49.79 36.37 90.87 78.17 90.87zm-29.19-50.93c1.62-1.51 4.15-1.42 5.65.2 4.1 4.41 15.31 6.97 21.88 6.97s17.77-2.56 21.88-6.97c1.5-1.62 4.04-1.71 5.65-.2 1.62 1.5 1.92 3.95.2 5.65-6.31 6.27-18.31 9.52-27.74 9.52s-22.16-3.54-27.74-9.52c-1.49-1.61-1.4-4.14.22-5.65zm115.25 112.93h-176.62c-37.67 0-38.24-17.41-27.56-26.36 21.49-18.01 57.18-23.64 114.81-23.64 60.01 0 96.24 4.84 117.41 24.06 10.09 9.16 7.67 25.94-28.04 25.94z"/> + </svg> + <div {...{ className: "image-upload-label" }}> + <UploadLabel {...{ file, fileTypes }} /> + </div> + </> } </div> </Uploader>; }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/AudioUploader/LoadingIcon.tsx b/packages/fakeyou.com/src/components/common/UploadActions/LoadingIcon.tsx similarity index 100% rename from packages/fakeyou.com/src/components/common/AudioUploader/LoadingIcon.tsx rename to packages/fakeyou.com/src/components/common/UploadActions/LoadingIcon.tsx diff --git a/packages/fakeyou.com/src/components/common/UploadActions/UploadActions.tsx b/packages/fakeyou.com/src/components/common/UploadActions/UploadActions.tsx new file mode 100644 index 0000000000..68847e4267 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/UploadActions/UploadActions.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome"; +import { faCheck, faFileArrowUp, faTrash } from "@fortawesome/pro-solid-svg-icons"; +import LoadingIcon from "./LoadingIcon"; + +interface Props { + disabled?: boolean; + handleClear?: (x?: any) => void; + handleUpload?: (x?: any) => void; + uploading?: boolean; +} + +const n = () => {}; + +export default function UploadActions({ disabled, handleClear = n, handleUpload = n, uploading }: Props) { + const uploadBtnClass = disabled ? "btn btn-uploaded w-100 disabled" : "btn btn-primary w-100"; + + return <div className="d-flex gap-3"> + <button {...{ className: uploadBtnClass, disabled: uploading || disabled, onClick: () => handleUpload(), type: "submit", }}> + <Icon {...{ className: "me-2", icon: disabled ? faCheck : faFileArrowUp, }}/> + { uploading && <LoadingIcon /> } + </button> + <button {...{ className: "btn btn-destructive w-100", onClick: handleClear }}> + <Icon icon={faTrash} className="me-2" /> + Clear + </button> + </div>; +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/UploadActions/index.tsx b/packages/fakeyou.com/src/components/common/UploadActions/index.tsx new file mode 100644 index 0000000000..9f1d7197a9 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/UploadActions/index.tsx @@ -0,0 +1 @@ +export { default } from './UploadActions'; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.tsx b/packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.tsx new file mode 100644 index 0000000000..64b79227d9 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.tsx @@ -0,0 +1,26 @@ +import React from 'react'; + +interface Props { + file?: any; +} + +export default function UploadDetails({ file }: Props) { + const fileSize = + file && file.size >= 1024 * 1024 + ? (file.size / 1024 / 1024).toFixed(2) + " MB" + : file + ? `${Math.floor(file.size / 1024)} KB` + : null; + + return <div {...{ className: "upload-details d-flex gap-1" }}> + <div> + { file && <p> + <span className="opacity-50"> + {file && `${file.name.split(".").pop().toUpperCase()} `} + file size: { fileSize } + </span>{" "} + <u className="fw-medium opacity-100 ms-1">Change file</u> + </p> } + </div> + </div>; +}; diff --git a/packages/fakeyou.com/src/components/common/UploadDetails/index.tsx b/packages/fakeyou.com/src/components/common/UploadDetails/index.tsx new file mode 100644 index 0000000000..6f9a2ce2b6 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/UploadDetails/index.tsx @@ -0,0 +1 @@ +export { default } from './UploadDetails'; diff --git a/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.scss b/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.scss new file mode 100644 index 0000000000..80692d20ea --- /dev/null +++ b/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.scss @@ -0,0 +1,3 @@ +.fy-upload-label-icon { + font-size: 2.625rem; +} \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx b/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx index dfcc27d308..2c0621f35d 100644 --- a/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx +++ b/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx @@ -1,16 +1,18 @@ import React from 'react'; import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome"; import { faFileArrowUp, faFileAudio } from "@fortawesome/pro-solid-svg-icons"; +import "./UploadLabel.scss" interface Props { children?: JSX.Element|JSX.Element[]; file?: any; + fileTypes?: string[]; } -export default function UploadLabel({ children, file }: Props) { +export default function UploadLabel({ children, file, fileTypes = [] }: Props) { return <> - <div className="me-4"> - <Icon {...{ className: "upload-icon", icon: file ? faFileAudio : faFileArrowUp }}/> + <div {...{ className: "me-4 "}}> + <Icon {...{ className: "fy-upload-label-icon", icon: file ? faFileAudio : faFileArrowUp }}/> </div> <div> <div className="pb-0"> @@ -19,6 +21,9 @@ export default function UploadLabel({ children, file }: Props) { </span> : <> <u className="fw-medium">Upload a file</u> or drop it here... + { fileTypes.length ? <p className="opacity-50"> + { fileTypes.join(", ").toString() } supported + </p> : null } </> } </div> { children } diff --git a/packages/fakeyou.com/src/components/common/index.tsx b/packages/fakeyou.com/src/components/common/index.tsx index eed171c125..f8f26bed0d 100644 --- a/packages/fakeyou.com/src/components/common/index.tsx +++ b/packages/fakeyou.com/src/components/common/index.tsx @@ -1,11 +1,15 @@ import AudioUploader from './AudioUploader'; import ImageUploader from './ImageUploader'; +import UploadActions from './UploadActions'; +import UploadDetails from './UploadDetails'; import Uploader from './Uploader'; import UploadLabel from './UploadLabel'; export { AudioUploader, ImageUploader, + UploadActions, + UploadDetails, Uploader, UploadLabel }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss index d58163d15a..aa58f5194b 100644 --- a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss +++ b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss @@ -1,11 +1,9 @@ .lipsync-editor { display: grid; - grid-template-columns: repeat(2, 1fr); + grid-template-columns: repeat(2, minmax(0, 1fr)); grid-gap: 1rem; - .grid-square { - aspect-ratio: 1; - padding-bottom: 1rem; + .grid-heading, .grid-square { &:nth-child(odd) { padding-left: 1rem; } @@ -14,6 +12,29 @@ } } + .grid-heading { + display: flex; + align-items: center; + // background-color: blue; + // padding-left: 1rem; + h5 { + margin: 1rem 0 0; + // background: red; + line-height: 1em; + } + } + + .grid-square { + aspect-ratio: 1; + padding-bottom: 1rem; + // &:nth-child(odd) { + // padding-left: 1rem; + // } + // &:nth-child(even) { + // padding-right: 1rem; + // } + } + diff --git a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx index 613a38cc76..edf395de84 100644 --- a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx @@ -4,14 +4,10 @@ import { AudioUploader, ImageUploader } from "components/common"; import { PageHeader } from "components/layout"; import './LipsyncEditor.scss'; -// interface Props { -// titleIcon?: JSX.Element; -// extra?: React.ComponentType; -// title?: string; -// subText: string; -// showButtons: boolean; -// actionButtons?: JSX.Element; -// } +interface Props { + audioFile?: any; + imageFile?: any; +} const ProgressCheck = ({ disabled = false }: {disabled?: boolean}) => <svg> { !disabled && <polyline {...{ @@ -24,6 +20,7 @@ const ProgressCheck = ({ disabled = false }: {disabled?: boolean}) => <svg> </svg>; const Title = ({ ...rest }) => { + const { audioFile, imageFile } = rest; console.log('🥚',rest) return <div {...{ className: 'progress-header' }}> <h1 {...{ className: "fw-bold text-center text-md-start progress-heading" }}> @@ -31,11 +28,11 @@ const Title = ({ ...rest }) => { </h1> <ul {...{ className: 'async-progress-tracker' }}> <li> - <ProgressCheck {...{}}/> + <ProgressCheck {...{ disabled: imageFile }}/> Image </li> <li> - <ProgressCheck {...{ disabled: false }}/> + <ProgressCheck {...{ disabled: audioFile }}/> Audio </li> </ul> @@ -51,7 +48,7 @@ export default function LipsyncEditor({ ...rest }) { const subText = "Select an image with a clear face, or one of our existing templates, then choose either text to speech or uploaded audio(eg. music). Then you can generate a beautifully lipsynced video."; const headerProps = { - childProps: { audioProps, imageProps }, + childProps: { audioFile: !audioProps.file, imageFile: !imageProps.file }, titleComponent: Title, subText, showButtons: false @@ -62,10 +59,10 @@ export default function LipsyncEditor({ ...rest }) { <PageHeader { ...headerProps }/> <div {...{ className: "container" }}> <div {...{ className: "lipsync-editor panel" }}> - <div {...{ className: "grid-title" }}> + <div {...{ className: "grid-heading" }}> <h5>Image</h5> </div> - <div {...{ className: "grid-title" }}> + <div {...{ className: "grid-heading" }}> <h5>Audio</h5> </div> <div {...{ className: "grid-square lipsync-audio" }}> From 3083109e9dd834398c0a7ef0ea9e81f71c09057e Mon Sep 17 00:00:00 2001 From: olivicmic <vic@vics.pics> Date: Tue, 8 Aug 2023 23:47:44 -0700 Subject: [PATCH 6/8] further modularized useUploader --- .../common/AudioUploader/AudioUploader.scss | 17 +--- .../common/AudioUploader/AudioUploader.tsx | 27 +++---- .../common/ImageUploader/ImageUploader.tsx | 9 +-- .../src/components/common/UpLab/UpLab.scss | 0 .../src/components/common/UpLab/UpLab.tsx | 20 +++++ .../src/components/common/UpLab/index.tsx | 1 + .../common/UploadActions/UploadActions.tsx | 20 ++--- .../common/UploadDetails/UploadDetails.scss | 10 +++ .../common/UploadDetails/UploadDetails.tsx | 27 ++++--- .../common/UploadLabel/UploadLabel.scss | 3 - .../common/UploadLabel/UploadLabel.tsx | 34 +++----- .../components/common/Uploader/Uploader.scss | 19 ++++- .../components/common/Uploader/Uploader.tsx | 13 +-- .../src/components/common/index.tsx | 2 + .../src/hooks/useConvertIdempotency/index.tsx | 1 + .../useConvertIdempotency.tsx | 6 ++ .../src/hooks/useIdempotency/index.tsx | 1 + .../hooks/useIdempotency/useIdempotency.tsx | 7 ++ .../src/hooks/useUploader/useUploader.tsx | 81 +++++++++---------- .../lipsync/LipsyncEditor/LipsyncEditor.scss | 2 +- .../lipsync/LipsyncEditor/LipsyncEditor.tsx | 13 ++- 21 files changed, 173 insertions(+), 140 deletions(-) create mode 100644 packages/fakeyou.com/src/components/common/UpLab/UpLab.scss create mode 100644 packages/fakeyou.com/src/components/common/UpLab/UpLab.tsx create mode 100644 packages/fakeyou.com/src/components/common/UpLab/index.tsx create mode 100644 packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.scss create mode 100644 packages/fakeyou.com/src/hooks/useConvertIdempotency/index.tsx create mode 100644 packages/fakeyou.com/src/hooks/useConvertIdempotency/useConvertIdempotency.tsx create mode 100644 packages/fakeyou.com/src/hooks/useIdempotency/index.tsx create mode 100644 packages/fakeyou.com/src/hooks/useIdempotency/useIdempotency.tsx diff --git a/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.scss b/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.scss index a22dc5a993..73d95b4aad 100644 --- a/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.scss +++ b/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.scss @@ -1,16 +1 @@ -.fy-uploader { - [type="file"] { - border: 0; - clip: rect(0, 0, 0, 0); - height: 1px; - overflow: hidden; - padding: 0; - position: absolute !important; - white-space: nowrap; - width: 1px; - - + label { - cursor: pointer; - } - } -} \ No newline at end of file +.fy-audio-uploader > div { margin-bottom: 1rem } \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx b/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx index cca0116fe8..6822a21515 100644 --- a/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx +++ b/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx @@ -1,37 +1,34 @@ import React from "react"; import { InputVcAudioPlayer } from "v2/view/_common/InputVcAudioPlayer"; import { UploadActions, UploadDetails, Uploader, UploadLabel } from 'components/common'; +import { faFileAudio } from "@fortawesome/pro-solid-svg-icons"; import './AudioUploader.scss' const fileTypes = ["MP3", "WAV", "FLAC", "OGG"]; interface Props { blob?: string; - disabled?: boolean; + clear?: (file?: any) => void; file?: any; - handleUpload?: () => void; - onChange?: (file?: any) => void; - onClear?: (file?: any) => void; + inputProps?: any; + success?: boolean; + upload?: () => void; uploading?: boolean; } const n = () => {}; -export default function AudioUploader({ blob = "", disabled = false, file, handleUpload = n, onChange = n, onClear = n, uploading = false }: Props) { +export default function AudioUploader({ blob = "", clear = n, file, inputProps, success = false, upload = n, uploading = false }: Props) { - const handleClear = () => { onClear(); }; - - return <> - <Uploader {...{ onChange, panelClass: 'p-3' }}> - <UploadLabel {...{ file, fileTypes }}> - <UploadDetails {...{ file }}/> - </UploadLabel> + return <div {...{ className: "fy-audio-uploader" }}> + <Uploader {...{ ...inputProps, panelClass: 'p-3' }}> + { file ? <UploadDetails {...{ clear, icon: faFileAudio, file }}/> : <UploadLabel {...{ fileTypes }}/> } </Uploader> { file && <> - <div className="panel panel-inner rounded p-3"> + <div {...{ className: "panel panel-inner rounded p-3" }}> <InputVcAudioPlayer {...{ filename: blob as string }}/> </div> - <UploadActions {...{ disabled, handleClear, handleUpload, uploading }}/> + <UploadActions {...{ clear, success, upload, uploading }}/> </> } - </>; + </div>; }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx b/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx index 93cd2af2e7..1ad1ec1e49 100644 --- a/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx +++ b/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx @@ -8,16 +8,15 @@ interface Props { blob?: string; file?: any; handleUploadFile?: () => void; - onChange?: (file?: any) => void; onClear?: (file?: any) => void; + uploader?: any; uploading?: boolean; - uploadDisabled?: boolean; } const n = () => {}; -export default function ImageUploader({ blob = "", file, handleUploadFile = n, onChange = n, onClear = n, uploading = false, uploadDisabled = false }: Props) { - return <Uploader {...{ onChange }}> +export default function ImageUploader({ blob = "", file, handleUploadFile = n, onClear = n, uploader, uploading = false }: Props) { + return <Uploader {...{ ...uploader }}> <div {...{ className: "fy-image-uploader" }}> { file ? <> <img {...{ alt: "file preview", className: "file-preview", src: blob }} /> @@ -27,7 +26,7 @@ export default function ImageUploader({ blob = "", file, handleUploadFile = n, o <path d="m152.42 226c41.8 0 69.49-43.57 73.21-90.87 3.78-47.97-26.06-87.13-75.69-87.13-49.64 0-79.28 39.15-75.69 87.13 3.72 49.79 36.37 90.87 78.17 90.87zm-29.19-50.93c1.62-1.51 4.15-1.42 5.65.2 4.1 4.41 15.31 6.97 21.88 6.97s17.77-2.56 21.88-6.97c1.5-1.62 4.04-1.71 5.65-.2 1.62 1.5 1.92 3.95.2 5.65-6.31 6.27-18.31 9.52-27.74 9.52s-22.16-3.54-27.74-9.52c-1.49-1.61-1.4-4.14.22-5.65zm115.25 112.93h-176.62c-37.67 0-38.24-17.41-27.56-26.36 21.49-18.01 57.18-23.64 114.81-23.64 60.01 0 96.24 4.84 117.41 24.06 10.09 9.16 7.67 25.94-28.04 25.94z"/> </svg> <div {...{ className: "image-upload-label" }}> - <UploadLabel {...{ file, fileTypes }} /> + { !file && <UploadLabel {...{ fileTypes }} /> } </div> </> } </div> diff --git a/packages/fakeyou.com/src/components/common/UpLab/UpLab.scss b/packages/fakeyou.com/src/components/common/UpLab/UpLab.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/fakeyou.com/src/components/common/UpLab/UpLab.tsx b/packages/fakeyou.com/src/components/common/UpLab/UpLab.tsx new file mode 100644 index 0000000000..0cab4e7594 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/UpLab/UpLab.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome"; +import { faFileArrowUp } from "@fortawesome/pro-solid-svg-icons"; +import "./UpLab.scss"; + +interface Props { + fileTypes?: string[]; +} + +export default function UpLab({ fileTypes = [] }: Props) { + return <div {...{ className: "fy-uploader-layout fy-upload-label" }}> + <Icon {...{ className: "fy-uploader-layout-icon", icon: faFileArrowUp }}/> + <div className="pb-0"> + <u className="fw-medium">Upload a file</u> or drop it here... + <p className="opacity-50"> + { fileTypes.join(", ").toString() } supported + </p> + </div> + </div>; +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/UpLab/index.tsx b/packages/fakeyou.com/src/components/common/UpLab/index.tsx new file mode 100644 index 0000000000..896562dc7a --- /dev/null +++ b/packages/fakeyou.com/src/components/common/UpLab/index.tsx @@ -0,0 +1 @@ +export { default } from './UpLab'; diff --git a/packages/fakeyou.com/src/components/common/UploadActions/UploadActions.tsx b/packages/fakeyou.com/src/components/common/UploadActions/UploadActions.tsx index 68847e4267..ae500b52d3 100644 --- a/packages/fakeyou.com/src/components/common/UploadActions/UploadActions.tsx +++ b/packages/fakeyou.com/src/components/common/UploadActions/UploadActions.tsx @@ -4,23 +4,23 @@ import { faCheck, faFileArrowUp, faTrash } from "@fortawesome/pro-solid-svg-icon import LoadingIcon from "./LoadingIcon"; interface Props { - disabled?: boolean; - handleClear?: (x?: any) => void; - handleUpload?: (x?: any) => void; - uploading?: boolean; + clear?: (x?: any) => void; + upload?: (x?: any) => void; + successful?: boolean; + working?: boolean; } const n = () => {}; -export default function UploadActions({ disabled, handleClear = n, handleUpload = n, uploading }: Props) { - const uploadBtnClass = disabled ? "btn btn-uploaded w-100 disabled" : "btn btn-primary w-100"; +export default function UploadActions({ clear = n, upload = n, successful, working }: Props) { + const uploadBtnClass = successful ? "btn btn-uploaded w-100 disabled" : "btn btn-primary w-100"; return <div className="d-flex gap-3"> - <button {...{ className: uploadBtnClass, disabled: uploading || disabled, onClick: () => handleUpload(), type: "submit", }}> - <Icon {...{ className: "me-2", icon: disabled ? faCheck : faFileArrowUp, }}/> - { uploading && <LoadingIcon /> } + <button {...{ className: uploadBtnClass, disabled: working || successful, onClick: () => upload(), type: "submit", }}> + <Icon {...{ className: "me-2", icon: successful ? faCheck : faFileArrowUp, }}/> + { working && <LoadingIcon /> } </button> - <button {...{ className: "btn btn-destructive w-100", onClick: handleClear }}> + <button {...{ className: "btn btn-destructive w-100", onClick: clear }}> <Icon icon={faTrash} className="me-2" /> Clear </button> diff --git a/packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.scss b/packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.scss new file mode 100644 index 0000000000..1f5d412f66 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.scss @@ -0,0 +1,10 @@ +.upload-details { + width: 100%; + + .upload-details-clear { + height: 36px; + width: 36px; + margin: auto 0 auto auto; + padding: 10px; + } +} \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.tsx b/packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.tsx index 64b79227d9..29d7eea902 100644 --- a/packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.tsx +++ b/packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.tsx @@ -1,10 +1,15 @@ import React from 'react'; +import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome"; +import { faTrash } from "@fortawesome/pro-solid-svg-icons"; +import "./UploadDetails.scss"; interface Props { file?: any; + handleClear?: (x?: any) => void; + icon?: any; } -export default function UploadDetails({ file }: Props) { +export default function UploadDetails({ file, handleClear = () => {}, icon }: Props) { const fileSize = file && file.size >= 1024 * 1024 ? (file.size / 1024 / 1024).toFixed(2) + " MB" @@ -12,15 +17,19 @@ export default function UploadDetails({ file }: Props) { ? `${Math.floor(file.size / 1024)} KB` : null; - return <div {...{ className: "upload-details d-flex gap-1" }}> + return <div {...{ className: "fy-uploader-layout upload-details" }}> + <Icon {...{ className: "fy-uploader-layout-icon", icon }}/> <div> - { file && <p> - <span className="opacity-50"> - {file && `${file.name.split(".").pop().toUpperCase()} `} - file size: { fileSize } - </span>{" "} - <u className="fw-medium opacity-100 ms-1">Change file</u> - </p> } + <div {...{ className: "filename" }}> + { file.name.slice(0, file.name.lastIndexOf(".")) } + </div> + <span className="opacity-50"> + {`${ file.name.split(".").pop().toUpperCase() } file size: ${ fileSize }`} + </span> + <u className="fw-medium opacity-100 ms-1">Change file</u> </div> + <button {...{ className: "upload-details-clear btn btn-destructive align-items-center justify-content-center", onClick: e => { e.preventDefault(); handleClear() } }}> + <Icon {...{ icon: faTrash }}/> + </button> </div>; }; diff --git a/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.scss b/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.scss index 80692d20ea..e69de29bb2 100644 --- a/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.scss +++ b/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.scss @@ -1,3 +0,0 @@ -.fy-upload-label-icon { - font-size: 2.625rem; -} \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx b/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx index 2c0621f35d..1b566e4df8 100644 --- a/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx +++ b/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx @@ -1,32 +1,20 @@ import React from 'react'; import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome"; -import { faFileArrowUp, faFileAudio } from "@fortawesome/pro-solid-svg-icons"; -import "./UploadLabel.scss" +import { faFileArrowUp } from "@fortawesome/pro-solid-svg-icons"; +import "./UploadLabel.scss"; interface Props { - children?: JSX.Element|JSX.Element[]; - file?: any; fileTypes?: string[]; } -export default function UploadLabel({ children, file, fileTypes = [] }: Props) { - return <> - <div {...{ className: "me-4 "}}> - <Icon {...{ className: "fy-upload-label-icon", icon: file ? faFileAudio : faFileArrowUp }}/> - </div> - <div> - <div className="pb-0"> - { file ? <span className="filename" title={file.name}> - { file.name.slice(0, file.name.lastIndexOf(".")) } - </span> : <> - <u className="fw-medium">Upload a file</u> or drop it - here... - { fileTypes.length ? <p className="opacity-50"> +export default function UploadLabel({ fileTypes = [] }: Props) { + return <div {...{ className: "fy-uploader-layout fy-upload-label" }}> + <Icon {...{ className: "fy-uploader-layout-icon", icon: faFileArrowUp }}/> + <div className="pb-0"> + <u className="fw-medium">Upload a file</u> or drop it here... + <p className="opacity-50"> { fileTypes.join(", ").toString() } supported - </p> : null } - </> } - </div> - { children } + </p> </div> - </>; -}; + </div>; +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/Uploader/Uploader.scss b/packages/fakeyou.com/src/components/common/Uploader/Uploader.scss index a22dc5a993..8d9e467507 100644 --- a/packages/fakeyou.com/src/components/common/Uploader/Uploader.scss +++ b/packages/fakeyou.com/src/components/common/Uploader/Uploader.scss @@ -1,3 +1,5 @@ +@import "scss/colours.scss"; + .fy-uploader { [type="file"] { border: 0; @@ -11,6 +13,21 @@ + label { cursor: pointer; + border: dashed 2px rgba(255, 255, 255, 0.12) !important; + border-radius: 0.5rem; + transition: 0.1s all; + &:hover { + background-color: lighten($panel, 6%); + } } } -} \ No newline at end of file + .fy-uploader-layout { + display: flex; + align-items: center; + + .fy-uploader-layout-icon { + font-size: 2.625rem; + margin-right: 1rem; + } + } +} diff --git a/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx b/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx index 377ff250d6..913361d10d 100644 --- a/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx +++ b/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx @@ -5,15 +5,18 @@ import './Uploader.scss' interface Props { children?: JSX.Element|JSX.Element[]; containerClass?: string; + inputRef: any; onChange: (file?: any) => void; panelClass?: string; }; -export default function Uploader({ children, containerClass, onChange, panelClass }: Props) { +export default function Uploader({ children, containerClass, inputRef, onChange, panelClass, }: Props) { const id = 'uploader-' + useId(); - const fileChange = ({ target }: { target: any }) => { - onChange({ target: { name: 'uploader', value: target.files[0] }}); + const fileChange = (e: any) => { + console.log("🧑🏻‍🎤",e.target.files); + e.preventDefault(); + onChange({ target: { name: 'uploader', value: e.target.files[0] }}); }; const onDragDrop = (e: any) => { e.preventDefault(); e.stopPropagation(); }; @@ -31,8 +34,8 @@ export default function Uploader({ children, containerClass, onChange, panelClas }; return <div {...{ className: `fy-uploader${ containerClass ? " " + containerClass : "" }`, onDragLeave: onDragEvent(1), onDragOver: onDragEvent(0), onDrop }}> - <input { ...{ name: "file", onChange: fileChange, type: "file", id }} /> - <label {...{ className: `panel panel-inner upload-zone d-flex align-items-center${ panelClass ? " " + panelClass : "" }`, htmlFor: id }} > + <input { ...{ name: "file", onChange: fileChange, type: "file", id, onClick: e => console.log('👨🏿‍🚒',e.target), ref: inputRef }} /> + <label {...{ className: `panel panel-inner d-flex align-items-center${ panelClass ? " " + panelClass : "" }`, htmlFor: id }} > { children } </label> </div>; diff --git a/packages/fakeyou.com/src/components/common/index.tsx b/packages/fakeyou.com/src/components/common/index.tsx index f8f26bed0d..99b090cf24 100644 --- a/packages/fakeyou.com/src/components/common/index.tsx +++ b/packages/fakeyou.com/src/components/common/index.tsx @@ -1,5 +1,6 @@ import AudioUploader from './AudioUploader'; import ImageUploader from './ImageUploader'; +import UpLab from './UpLab'; import UploadActions from './UploadActions'; import UploadDetails from './UploadDetails'; import Uploader from './Uploader'; @@ -8,6 +9,7 @@ import UploadLabel from './UploadLabel'; export { AudioUploader, ImageUploader, + UpLab, UploadActions, UploadDetails, Uploader, diff --git a/packages/fakeyou.com/src/hooks/useConvertIdempotency/index.tsx b/packages/fakeyou.com/src/hooks/useConvertIdempotency/index.tsx new file mode 100644 index 0000000000..6efc7549f7 --- /dev/null +++ b/packages/fakeyou.com/src/hooks/useConvertIdempotency/index.tsx @@ -0,0 +1 @@ +export { default } from './useConvertIdempotency'; diff --git a/packages/fakeyou.com/src/hooks/useConvertIdempotency/useConvertIdempotency.tsx b/packages/fakeyou.com/src/hooks/useConvertIdempotency/useConvertIdempotency.tsx new file mode 100644 index 0000000000..5295a7b7fe --- /dev/null +++ b/packages/fakeyou.com/src/hooks/useConvertIdempotency/useConvertIdempotency.tsx @@ -0,0 +1,6 @@ +import { useState } from 'react'; +import { v4 as uuidv4 } from "uuid"; + +export default function useConvertIdempotencyToken() { + return useState(uuidv4()); +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/hooks/useIdempotency/index.tsx b/packages/fakeyou.com/src/hooks/useIdempotency/index.tsx new file mode 100644 index 0000000000..fe06c4c25a --- /dev/null +++ b/packages/fakeyou.com/src/hooks/useIdempotency/index.tsx @@ -0,0 +1 @@ +export { default } from './useIdempotency'; diff --git a/packages/fakeyou.com/src/hooks/useIdempotency/useIdempotency.tsx b/packages/fakeyou.com/src/hooks/useIdempotency/useIdempotency.tsx new file mode 100644 index 0000000000..0f264b57a0 --- /dev/null +++ b/packages/fakeyou.com/src/hooks/useIdempotency/useIdempotency.tsx @@ -0,0 +1,7 @@ +import { useState } from 'react'; +import { v4 as uuidv4 } from "uuid"; + +export default function useIdempotency() { + const [token, set] = useState(uuidv4()); + return { reset: () => set(uuidv4()), set, token }; +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx b/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx index 9aec56d9dd..a43d9a1fdf 100644 --- a/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx +++ b/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx @@ -1,64 +1,55 @@ -import { useState } from 'react'; -import { v4 as uuidv4 } from "uuid"; -import { UploadAudio, UploadAudioIsOk, UploadAudioRequest } from "@storyteller/components/src/api/upload/UploadAudio"; +import { useRef, useState } from 'react'; const n = (o: any) => o; interface Props { - debug?: boolean; + debug?: any; formClearedSet?: (cleared: boolean) => void; + onChange?: (file: any) => void; + onClear?: (x?: any) => void; + onUpload?: (file: any) => boolean; } -export default function useUploader({ debug, formClearedSet = n }: Props) { +export default function useUploader({ debug, onChange = n, onClear = n, onUpload = n }: Props) { const [file, fileSet] = useState<any>(undefined); const [blob, blobSet] = useState<string>(); - const [uploading, uploadingSet] = useState(false); - const [uploadDisabled, uploadDisabledSet] = useState<boolean>(false); - const [mediaUploadToken, mediaUploadTokenSet] = useState<string | undefined>(undefined); - const [convertIdempotencyToken, convertIdempotencyTokenSet] = useState(uuidv4()); - const [canConvert, canConvertSet] = useState(false); - const [iToken, iTokenSet] = useState(uuidv4()); // Auto generated - const resetIToken = () => iTokenSet(uuidv4()); + const [working, workingSet] = useState(false); + const [successful, successfulSet] = useState<boolean>(false); + const inputRef = useRef<HTMLInputElement>(null); - const handleUploadFile = async () => { + const submit = async () => { if (file === undefined) { return false; } - - uploadingSet(true); - - const request: UploadAudioRequest = { - uuid_idempotency_token: iToken, - file: file, - source: "file", - }; - - let result = await UploadAudio(request); - - if (UploadAudioIsOk(result)) { - uploadDisabledSet(true); - mediaUploadTokenSet(result.upload_token); - formClearedSet(false); - canConvertSet(true); - } - - uploadingSet(false); + const onUploadResult = await onUpload(file); + workingSet(true); + if (onUploadResult) { successfulSet(true); } + successfulSet(false); }; - const inputChange = (inputFile?: any) => { - console.log("🍡",inputFile); - convertIdempotencyTokenSet(uuidv4()); + const fileChange = (inputFile?: any) => { + onChange(file); fileSet(inputFile || null); blobSet(inputFile ? URL.createObjectURL(inputFile) : ""); - canConvertSet(false); - resetIToken(); - uploadDisabledSet(false); - formClearedSet(!inputFile); + successfulSet(false); }; - const onChange = ({ target = {} }: { target: any }) => { - inputChange(target.value); + const inputChange = ({ target = {} }: { target: any }) => { + fileChange(target.value); }; - const onClear = () => { - inputChange(); - mediaUploadTokenSet(undefined); + const clear = () => { + if (inputRef?.current?.value) inputRef.current.value = ''; + fileChange(); + onClear(); }; - return { blob, canConvert, convertIdempotencyToken, file, fileSet, handleUploadFile, idempotency: { token: iToken, set: iTokenSet}, mediaUploadToken, mediaUploadTokenSet, onChange, onClear, resetIToken, uploading, uploadDisabled, uploadingSet }; + return { + blob, + clear, + file, + fileSet, + inputProps: { + onChange: inputChange, + inputRef + }, + submit, + successful, + working, + }; }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss index aa58f5194b..dc0825c225 100644 --- a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss +++ b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.scss @@ -39,7 +39,7 @@ // div.grid-square { aspect-ratio: 1 } - .fy-uploader { height: 100%; } + .fy-image-uploader { height: 100%; } .lipsync-audio { label { height: 100% } } diff --git a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx index edf395de84..4874485640 100644 --- a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx @@ -4,10 +4,10 @@ import { AudioUploader, ImageUploader } from "components/common"; import { PageHeader } from "components/layout"; import './LipsyncEditor.scss'; -interface Props { - audioFile?: any; - imageFile?: any; -} +// interface Props { +// audioFile?: any; +// imageFile?: any; +// } const ProgressCheck = ({ disabled = false }: {disabled?: boolean}) => <svg> { !disabled && <polyline {...{ @@ -21,7 +21,7 @@ const ProgressCheck = ({ disabled = false }: {disabled?: boolean}) => <svg> const Title = ({ ...rest }) => { const { audioFile, imageFile } = rest; - console.log('🥚',rest) + return <div {...{ className: 'progress-header' }}> <h1 {...{ className: "fw-bold text-center text-md-start progress-heading" }}> Generate a lipsync @@ -43,7 +43,7 @@ const Title = ({ ...rest }) => { }; export default function LipsyncEditor({ ...rest }) { - const audioProps = useUploader({ debug: true }); + const audioProps = useUploader({ debug: 'audio useUploader' }); const imageProps = useUploader({}); const subText = "Select an image with a clear face, or one of our existing templates, then choose either text to speech or uploaded audio(eg. music). Then you can generate a beautifully lipsynced video."; @@ -53,7 +53,6 @@ export default function LipsyncEditor({ ...rest }) { subText, showButtons: false }; - console.log("👁",imageProps); return <div> <PageHeader { ...headerProps }/> From 8f9ce71afb9265b0b5fd5e3a9bb59224402d5e1d Mon Sep 17 00:00:00 2001 From: olivicmic <vic@vics.pics> Date: Wed, 9 Aug 2023 15:26:36 -0700 Subject: [PATCH 7/8] renamed components from "uploader" to "file" naming schemes since uploading occurs outside of inputs --- .../AudioInput.scss} | 0 .../common/AudioInput/AudioInput.tsx | 37 +++++++++++++++++++ .../components/common/AudioInput/index.tsx | 1 + .../common/AudioUploader/AudioUploader.tsx | 34 ----------------- .../components/common/AudioUploader/index.tsx | 1 - .../FileActions.tsx} | 2 +- .../LoadingIcon.tsx | 0 .../components/common/FileActions/index.tsx | 1 + .../FileDetails.scss} | 0 .../FileDetails.tsx} | 13 ++++--- .../components/common/FileDetails/index.tsx | 1 + .../UpLab.scss => FileLabel/FileLabel.scss} | 0 .../FileLabel.tsx} | 6 +-- .../src/components/common/FileLabel/index.tsx | 1 + .../FileWrapper.scss} | 0 .../FileWrapper.tsx} | 23 ++++++------ .../{Uploader => FileWrapper}/LoadingIcon.tsx | 0 .../components/common/FileWrapper/index.tsx | 1 + .../ImageInput.scss} | 0 .../ImageInput.tsx} | 26 +++++++------ .../components/common/ImageInput/index.tsx | 1 + .../components/common/ImageUploader/index.tsx | 1 - .../src/components/common/UpLab/UpLab.tsx | 20 ---------- .../src/components/common/UpLab/index.tsx | 1 - .../components/common/UploadActions/index.tsx | 1 - .../components/common/UploadDetails/index.tsx | 1 - .../common/UploadLabel/UploadLabel.scss | 0 .../components/common/UploadLabel/index.tsx | 1 - .../src/components/common/Uploader/index.tsx | 1 - .../src/components/common/index.tsx | 26 ++++++------- packages/fakeyou.com/src/hooks/index.tsx | 3 +- .../src/hooks/useConvertIdempotency/index.tsx | 1 - .../useConvertIdempotency.tsx | 6 --- .../src/hooks/useUploader/useUploader.tsx | 18 ++++----- .../lipsync/LipsyncEditor/LipsyncEditor.tsx | 6 +-- 35 files changed, 105 insertions(+), 129 deletions(-) rename packages/fakeyou.com/src/components/common/{AudioUploader/AudioUploader.scss => AudioInput/AudioInput.scss} (100%) create mode 100644 packages/fakeyou.com/src/components/common/AudioInput/AudioInput.tsx create mode 100644 packages/fakeyou.com/src/components/common/AudioInput/index.tsx delete mode 100644 packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx delete mode 100644 packages/fakeyou.com/src/components/common/AudioUploader/index.tsx rename packages/fakeyou.com/src/components/common/{UploadActions/UploadActions.tsx => FileActions/FileActions.tsx} (90%) rename packages/fakeyou.com/src/components/common/{UploadActions => FileActions}/LoadingIcon.tsx (100%) create mode 100644 packages/fakeyou.com/src/components/common/FileActions/index.tsx rename packages/fakeyou.com/src/components/common/{UploadDetails/UploadDetails.scss => FileDetails/FileDetails.scss} (100%) rename packages/fakeyou.com/src/components/common/{UploadDetails/UploadDetails.tsx => FileDetails/FileDetails.tsx} (66%) create mode 100644 packages/fakeyou.com/src/components/common/FileDetails/index.tsx rename packages/fakeyou.com/src/components/common/{UpLab/UpLab.scss => FileLabel/FileLabel.scss} (100%) rename packages/fakeyou.com/src/components/common/{UploadLabel/UploadLabel.tsx => FileLabel/FileLabel.tsx} (82%) create mode 100644 packages/fakeyou.com/src/components/common/FileLabel/index.tsx rename packages/fakeyou.com/src/components/common/{Uploader/Uploader.scss => FileWrapper/FileWrapper.scss} (100%) rename packages/fakeyou.com/src/components/common/{Uploader/Uploader.tsx => FileWrapper/FileWrapper.tsx} (59%) rename packages/fakeyou.com/src/components/common/{Uploader => FileWrapper}/LoadingIcon.tsx (100%) create mode 100644 packages/fakeyou.com/src/components/common/FileWrapper/index.tsx rename packages/fakeyou.com/src/components/common/{ImageUploader/ImageUploader.scss => ImageInput/ImageInput.scss} (100%) rename packages/fakeyou.com/src/components/common/{ImageUploader/ImageUploader.tsx => ImageInput/ImageInput.tsx} (62%) create mode 100644 packages/fakeyou.com/src/components/common/ImageInput/index.tsx delete mode 100644 packages/fakeyou.com/src/components/common/ImageUploader/index.tsx delete mode 100644 packages/fakeyou.com/src/components/common/UpLab/UpLab.tsx delete mode 100644 packages/fakeyou.com/src/components/common/UpLab/index.tsx delete mode 100644 packages/fakeyou.com/src/components/common/UploadActions/index.tsx delete mode 100644 packages/fakeyou.com/src/components/common/UploadDetails/index.tsx delete mode 100644 packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.scss delete mode 100644 packages/fakeyou.com/src/components/common/UploadLabel/index.tsx delete mode 100644 packages/fakeyou.com/src/components/common/Uploader/index.tsx delete mode 100644 packages/fakeyou.com/src/hooks/useConvertIdempotency/index.tsx delete mode 100644 packages/fakeyou.com/src/hooks/useConvertIdempotency/useConvertIdempotency.tsx diff --git a/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.scss b/packages/fakeyou.com/src/components/common/AudioInput/AudioInput.scss similarity index 100% rename from packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.scss rename to packages/fakeyou.com/src/components/common/AudioInput/AudioInput.scss diff --git a/packages/fakeyou.com/src/components/common/AudioInput/AudioInput.tsx b/packages/fakeyou.com/src/components/common/AudioInput/AudioInput.tsx new file mode 100644 index 0000000000..7e90e4312b --- /dev/null +++ b/packages/fakeyou.com/src/components/common/AudioInput/AudioInput.tsx @@ -0,0 +1,37 @@ +import React from "react"; +import { InputVcAudioPlayer } from "v2/view/_common/InputVcAudioPlayer"; +import { FileActions, FileDetails, FileLabel, FileWrapper } from 'components/common'; +import { faFileAudio } from "@fortawesome/pro-solid-svg-icons"; +import './AudioInput.scss' + +const fileTypes = ["MP3", "WAV", "FLAC", "OGG"]; + +interface Props { + blob?: string; + clear?: (file?: any) => void; + file?: any; + hideActions?: boolean; + hideClearDetails?: boolean; + inputProps?: any; + success?: boolean; + submit?: () => void; + working?: boolean; + [x:string]: any; +} + +const n = () => {}; + +export default function AudioInput({ blob = "", clear = n, file, hideActions, hideClearDetails, inputProps, success = false, submit = n, working = false, ...rest }: Props) { + + return <div {...{ className: "fy-audio-uploader" }}> + <FileWrapper {...{ fileTypes, ...inputProps, panelClass: "p-3", ...rest }}> + { file ? <FileDetails {...{ clear, hideClearDetails, icon: faFileAudio, file }}/> : <FileLabel {...{ fileTypes }}/> } + </FileWrapper> + { file && <> + <div {...{ className: "panel panel-inner rounded p-3" }}> + <InputVcAudioPlayer {...{ filename: blob as string }}/> + </div> + { !hideActions && <FileActions {...{ clear, success, submit, working }}/> } + </> } + </div>; +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/AudioInput/index.tsx b/packages/fakeyou.com/src/components/common/AudioInput/index.tsx new file mode 100644 index 0000000000..919bf06fd5 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/AudioInput/index.tsx @@ -0,0 +1 @@ +export { default } from './AudioInput'; diff --git a/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx b/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx deleted file mode 100644 index 6822a21515..0000000000 --- a/packages/fakeyou.com/src/components/common/AudioUploader/AudioUploader.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from "react"; -import { InputVcAudioPlayer } from "v2/view/_common/InputVcAudioPlayer"; -import { UploadActions, UploadDetails, Uploader, UploadLabel } from 'components/common'; -import { faFileAudio } from "@fortawesome/pro-solid-svg-icons"; -import './AudioUploader.scss' - -const fileTypes = ["MP3", "WAV", "FLAC", "OGG"]; - -interface Props { - blob?: string; - clear?: (file?: any) => void; - file?: any; - inputProps?: any; - success?: boolean; - upload?: () => void; - uploading?: boolean; -} - -const n = () => {}; - -export default function AudioUploader({ blob = "", clear = n, file, inputProps, success = false, upload = n, uploading = false }: Props) { - - return <div {...{ className: "fy-audio-uploader" }}> - <Uploader {...{ ...inputProps, panelClass: 'p-3' }}> - { file ? <UploadDetails {...{ clear, icon: faFileAudio, file }}/> : <UploadLabel {...{ fileTypes }}/> } - </Uploader> - { file && <> - <div {...{ className: "panel panel-inner rounded p-3" }}> - <InputVcAudioPlayer {...{ filename: blob as string }}/> - </div> - <UploadActions {...{ clear, success, upload, uploading }}/> - </> } - </div>; -}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/AudioUploader/index.tsx b/packages/fakeyou.com/src/components/common/AudioUploader/index.tsx deleted file mode 100644 index d7d3905d81..0000000000 --- a/packages/fakeyou.com/src/components/common/AudioUploader/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './AudioUploader'; diff --git a/packages/fakeyou.com/src/components/common/UploadActions/UploadActions.tsx b/packages/fakeyou.com/src/components/common/FileActions/FileActions.tsx similarity index 90% rename from packages/fakeyou.com/src/components/common/UploadActions/UploadActions.tsx rename to packages/fakeyou.com/src/components/common/FileActions/FileActions.tsx index ae500b52d3..d7062684b8 100644 --- a/packages/fakeyou.com/src/components/common/UploadActions/UploadActions.tsx +++ b/packages/fakeyou.com/src/components/common/FileActions/FileActions.tsx @@ -12,7 +12,7 @@ interface Props { const n = () => {}; -export default function UploadActions({ clear = n, upload = n, successful, working }: Props) { +export default function FileActions({ clear = n, upload = n, successful, working }: Props) { const uploadBtnClass = successful ? "btn btn-uploaded w-100 disabled" : "btn btn-primary w-100"; return <div className="d-flex gap-3"> diff --git a/packages/fakeyou.com/src/components/common/UploadActions/LoadingIcon.tsx b/packages/fakeyou.com/src/components/common/FileActions/LoadingIcon.tsx similarity index 100% rename from packages/fakeyou.com/src/components/common/UploadActions/LoadingIcon.tsx rename to packages/fakeyou.com/src/components/common/FileActions/LoadingIcon.tsx diff --git a/packages/fakeyou.com/src/components/common/FileActions/index.tsx b/packages/fakeyou.com/src/components/common/FileActions/index.tsx new file mode 100644 index 0000000000..02ee6bf0e4 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/FileActions/index.tsx @@ -0,0 +1 @@ +export { default } from './FileActions'; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.scss b/packages/fakeyou.com/src/components/common/FileDetails/FileDetails.scss similarity index 100% rename from packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.scss rename to packages/fakeyou.com/src/components/common/FileDetails/FileDetails.scss diff --git a/packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.tsx b/packages/fakeyou.com/src/components/common/FileDetails/FileDetails.tsx similarity index 66% rename from packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.tsx rename to packages/fakeyou.com/src/components/common/FileDetails/FileDetails.tsx index 29d7eea902..0c4250af52 100644 --- a/packages/fakeyou.com/src/components/common/UploadDetails/UploadDetails.tsx +++ b/packages/fakeyou.com/src/components/common/FileDetails/FileDetails.tsx @@ -1,15 +1,16 @@ import React from 'react'; import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome"; import { faTrash } from "@fortawesome/pro-solid-svg-icons"; -import "./UploadDetails.scss"; +import "./FileDetails.scss"; interface Props { + clear?: (file?: any) => void; file?: any; - handleClear?: (x?: any) => void; + hideClearDetails?: boolean; icon?: any; } -export default function UploadDetails({ file, handleClear = () => {}, icon }: Props) { +export default function FileDetails({ clear = () => {}, file, hideClearDetails, icon }: Props) { const fileSize = file && file.size >= 1024 * 1024 ? (file.size / 1024 / 1024).toFixed(2) + " MB" @@ -28,8 +29,8 @@ export default function UploadDetails({ file, handleClear = () => {}, icon }: Pr </span> <u className="fw-medium opacity-100 ms-1">Change file</u> </div> - <button {...{ className: "upload-details-clear btn btn-destructive align-items-center justify-content-center", onClick: e => { e.preventDefault(); handleClear() } }}> - <Icon {...{ icon: faTrash }}/> - </button> + { !hideClearDetails && <button {...{ className: "upload-details-clear btn btn-destructive align-items-center justify-content-center", onClick: e => { e.preventDefault(); clear() } }}> + <Icon {...{ icon: faTrash }}/> + </button> } </div>; }; diff --git a/packages/fakeyou.com/src/components/common/FileDetails/index.tsx b/packages/fakeyou.com/src/components/common/FileDetails/index.tsx new file mode 100644 index 0000000000..d24335d24b --- /dev/null +++ b/packages/fakeyou.com/src/components/common/FileDetails/index.tsx @@ -0,0 +1 @@ +export { default } from './FileDetails'; diff --git a/packages/fakeyou.com/src/components/common/UpLab/UpLab.scss b/packages/fakeyou.com/src/components/common/FileLabel/FileLabel.scss similarity index 100% rename from packages/fakeyou.com/src/components/common/UpLab/UpLab.scss rename to packages/fakeyou.com/src/components/common/FileLabel/FileLabel.scss diff --git a/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx b/packages/fakeyou.com/src/components/common/FileLabel/FileLabel.tsx similarity index 82% rename from packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx rename to packages/fakeyou.com/src/components/common/FileLabel/FileLabel.tsx index 1b566e4df8..6f422e8746 100644 --- a/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.tsx +++ b/packages/fakeyou.com/src/components/common/FileLabel/FileLabel.tsx @@ -1,13 +1,13 @@ -import React from 'react'; +import React from "react"; import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome"; import { faFileArrowUp } from "@fortawesome/pro-solid-svg-icons"; -import "./UploadLabel.scss"; +import "./FileLabel.scss"; interface Props { fileTypes?: string[]; } -export default function UploadLabel({ fileTypes = [] }: Props) { +export default function FileLabel({ fileTypes = [] }: Props) { return <div {...{ className: "fy-uploader-layout fy-upload-label" }}> <Icon {...{ className: "fy-uploader-layout-icon", icon: faFileArrowUp }}/> <div className="pb-0"> diff --git a/packages/fakeyou.com/src/components/common/FileLabel/index.tsx b/packages/fakeyou.com/src/components/common/FileLabel/index.tsx new file mode 100644 index 0000000000..28efdc8e72 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/FileLabel/index.tsx @@ -0,0 +1 @@ +export { default } from './FileLabel'; diff --git a/packages/fakeyou.com/src/components/common/Uploader/Uploader.scss b/packages/fakeyou.com/src/components/common/FileWrapper/FileWrapper.scss similarity index 100% rename from packages/fakeyou.com/src/components/common/Uploader/Uploader.scss rename to packages/fakeyou.com/src/components/common/FileWrapper/FileWrapper.scss diff --git a/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx b/packages/fakeyou.com/src/components/common/FileWrapper/FileWrapper.tsx similarity index 59% rename from packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx rename to packages/fakeyou.com/src/components/common/FileWrapper/FileWrapper.tsx index 913361d10d..649c6f2c81 100644 --- a/packages/fakeyou.com/src/components/common/Uploader/Uploader.tsx +++ b/packages/fakeyou.com/src/components/common/FileWrapper/FileWrapper.tsx @@ -1,40 +1,39 @@ import React from "react"; import { useId } from 'hooks'; // replace with react v18 -import './Uploader.scss' +import './FileWrapper.scss' interface Props { children?: JSX.Element|JSX.Element[]; containerClass?: string; + fileTypes?: string[]; inputRef: any; onChange: (file?: any) => void; panelClass?: string; + [x:string]: any; }; -export default function Uploader({ children, containerClass, inputRef, onChange, panelClass, }: Props) { - const id = 'uploader-' + useId(); +export default function FileWrapper({ children, containerClass, fileTypes = [], inputRef, onChange, panelClass, ...rest }: Props) { + const id = 'file-input-' + useId(); + const accept = fileTypes.map((type,i) => `.${ type.toLowerCase() }`).join(","); const fileChange = (e: any) => { - console.log("🧑🏻‍🎤",e.target.files); - e.preventDefault(); - onChange({ target: { name: 'uploader', value: e.target.files[0] }}); + e.preventDefault(); + onChange({ target: { name: e.target?.name || "file-input", value: e.target.files[0] }}); }; - const onDragDrop = (e: any) => { e.preventDefault(); e.stopPropagation(); }; - const onDragEvent = (onOff: number) => (e: React.DragEvent<HTMLDivElement>): void => { onDragDrop(e); e.currentTarget.classList[onOff ? "add" : "remove" ]("upload-zone-drag"); }; - - const onDrop = (e: React.DragEvent<HTMLDivElement>): void => { + const onDrop = (e: any): void => { onDragDrop(e); if (e.dataTransfer.files && e.dataTransfer.files[0]) { - onChange({ target: { name: 'uploader', value: e.dataTransfer.files[0] }}); + onChange({ target: { name: e.target?.name || "file-input", value: e.dataTransfer.files[0] }}); } }; return <div {...{ className: `fy-uploader${ containerClass ? " " + containerClass : "" }`, onDragLeave: onDragEvent(1), onDragOver: onDragEvent(0), onDrop }}> - <input { ...{ name: "file", onChange: fileChange, type: "file", id, onClick: e => console.log('👨🏿‍🚒',e.target), ref: inputRef }} /> + <input { ...{ accept, onChange: fileChange, type: "file", id, ref: inputRef, ...rest }} /> <label {...{ className: `panel panel-inner d-flex align-items-center${ panelClass ? " " + panelClass : "" }`, htmlFor: id }} > { children } </label> diff --git a/packages/fakeyou.com/src/components/common/Uploader/LoadingIcon.tsx b/packages/fakeyou.com/src/components/common/FileWrapper/LoadingIcon.tsx similarity index 100% rename from packages/fakeyou.com/src/components/common/Uploader/LoadingIcon.tsx rename to packages/fakeyou.com/src/components/common/FileWrapper/LoadingIcon.tsx diff --git a/packages/fakeyou.com/src/components/common/FileWrapper/index.tsx b/packages/fakeyou.com/src/components/common/FileWrapper/index.tsx new file mode 100644 index 0000000000..56d7376ab7 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/FileWrapper/index.tsx @@ -0,0 +1 @@ +export { default } from './FileWrapper'; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.scss b/packages/fakeyou.com/src/components/common/ImageInput/ImageInput.scss similarity index 100% rename from packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.scss rename to packages/fakeyou.com/src/components/common/ImageInput/ImageInput.scss diff --git a/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx b/packages/fakeyou.com/src/components/common/ImageInput/ImageInput.tsx similarity index 62% rename from packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx rename to packages/fakeyou.com/src/components/common/ImageInput/ImageInput.tsx index 1ad1ec1e49..da03a47a36 100644 --- a/packages/fakeyou.com/src/components/common/ImageUploader/ImageUploader.tsx +++ b/packages/fakeyou.com/src/components/common/ImageInput/ImageInput.tsx @@ -1,34 +1,38 @@ import React from "react"; -import { UploadDetails, Uploader, UploadLabel } from "components/common"; -import "./ImageUploader.scss"; +import { FileDetails, FileWrapper, FileLabel } from "components/common"; +import "./ImageInput.scss"; const fileTypes = ["JPG", "GIF", "PNG"]; interface Props { blob?: string; + clear?: (file?: any) => void; file?: any; - handleUploadFile?: () => void; - onClear?: (file?: any) => void; - uploader?: any; - uploading?: boolean; + hideActions?: boolean; + hideClearDetails?: boolean; + inputProps?: any; + success?: boolean; + submit?: () => void; + working?: boolean; + [x:string]: any; } const n = () => {}; -export default function ImageUploader({ blob = "", file, handleUploadFile = n, onClear = n, uploader, uploading = false }: Props) { - return <Uploader {...{ ...uploader }}> +export default function ImageInput({ blob = "", clear = n, file, hideActions, hideClearDetails, inputProps, success = false, submit = n, working = false, ...rest }: Props) { + return <FileWrapper {...{ fileTypes, ...inputProps, ...rest }}> <div {...{ className: "fy-image-uploader" }}> { file ? <> <img {...{ alt: "file preview", className: "file-preview", src: blob }} /> - <UploadDetails {...{ file }}/> + <FileDetails {...{ file, hideClearDetails }}/> </> : <> <svg {...{ className: "image-placeholder", height: 400, viewBox: "0 0 300 300", width: 400 }}> <path d="m152.42 226c41.8 0 69.49-43.57 73.21-90.87 3.78-47.97-26.06-87.13-75.69-87.13-49.64 0-79.28 39.15-75.69 87.13 3.72 49.79 36.37 90.87 78.17 90.87zm-29.19-50.93c1.62-1.51 4.15-1.42 5.65.2 4.1 4.41 15.31 6.97 21.88 6.97s17.77-2.56 21.88-6.97c1.5-1.62 4.04-1.71 5.65-.2 1.62 1.5 1.92 3.95.2 5.65-6.31 6.27-18.31 9.52-27.74 9.52s-22.16-3.54-27.74-9.52c-1.49-1.61-1.4-4.14.22-5.65zm115.25 112.93h-176.62c-37.67 0-38.24-17.41-27.56-26.36 21.49-18.01 57.18-23.64 114.81-23.64 60.01 0 96.24 4.84 117.41 24.06 10.09 9.16 7.67 25.94-28.04 25.94z"/> </svg> <div {...{ className: "image-upload-label" }}> - { !file && <UploadLabel {...{ fileTypes }} /> } + { !file && <FileLabel {...{ fileTypes }} /> } </div> </> } </div> - </Uploader>; + </FileWrapper>; }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/ImageInput/index.tsx b/packages/fakeyou.com/src/components/common/ImageInput/index.tsx new file mode 100644 index 0000000000..4bcb609d53 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/ImageInput/index.tsx @@ -0,0 +1 @@ +export { default } from './ImageInput'; diff --git a/packages/fakeyou.com/src/components/common/ImageUploader/index.tsx b/packages/fakeyou.com/src/components/common/ImageUploader/index.tsx deleted file mode 100644 index 3695b16bd2..0000000000 --- a/packages/fakeyou.com/src/components/common/ImageUploader/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './ImageUploader'; diff --git a/packages/fakeyou.com/src/components/common/UpLab/UpLab.tsx b/packages/fakeyou.com/src/components/common/UpLab/UpLab.tsx deleted file mode 100644 index 0cab4e7594..0000000000 --- a/packages/fakeyou.com/src/components/common/UpLab/UpLab.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; -import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome"; -import { faFileArrowUp } from "@fortawesome/pro-solid-svg-icons"; -import "./UpLab.scss"; - -interface Props { - fileTypes?: string[]; -} - -export default function UpLab({ fileTypes = [] }: Props) { - return <div {...{ className: "fy-uploader-layout fy-upload-label" }}> - <Icon {...{ className: "fy-uploader-layout-icon", icon: faFileArrowUp }}/> - <div className="pb-0"> - <u className="fw-medium">Upload a file</u> or drop it here... - <p className="opacity-50"> - { fileTypes.join(", ").toString() } supported - </p> - </div> - </div>; -}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/UpLab/index.tsx b/packages/fakeyou.com/src/components/common/UpLab/index.tsx deleted file mode 100644 index 896562dc7a..0000000000 --- a/packages/fakeyou.com/src/components/common/UpLab/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './UpLab'; diff --git a/packages/fakeyou.com/src/components/common/UploadActions/index.tsx b/packages/fakeyou.com/src/components/common/UploadActions/index.tsx deleted file mode 100644 index 9f1d7197a9..0000000000 --- a/packages/fakeyou.com/src/components/common/UploadActions/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './UploadActions'; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/UploadDetails/index.tsx b/packages/fakeyou.com/src/components/common/UploadDetails/index.tsx deleted file mode 100644 index 6f9a2ce2b6..0000000000 --- a/packages/fakeyou.com/src/components/common/UploadDetails/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './UploadDetails'; diff --git a/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.scss b/packages/fakeyou.com/src/components/common/UploadLabel/UploadLabel.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/fakeyou.com/src/components/common/UploadLabel/index.tsx b/packages/fakeyou.com/src/components/common/UploadLabel/index.tsx deleted file mode 100644 index 3b934839e2..0000000000 --- a/packages/fakeyou.com/src/components/common/UploadLabel/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './UploadLabel'; diff --git a/packages/fakeyou.com/src/components/common/Uploader/index.tsx b/packages/fakeyou.com/src/components/common/Uploader/index.tsx deleted file mode 100644 index 2d16ee2adb..0000000000 --- a/packages/fakeyou.com/src/components/common/Uploader/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './Uploader'; \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/index.tsx b/packages/fakeyou.com/src/components/common/index.tsx index 99b090cf24..5e570e82e2 100644 --- a/packages/fakeyou.com/src/components/common/index.tsx +++ b/packages/fakeyou.com/src/components/common/index.tsx @@ -1,17 +1,15 @@ -import AudioUploader from './AudioUploader'; -import ImageUploader from './ImageUploader'; -import UpLab from './UpLab'; -import UploadActions from './UploadActions'; -import UploadDetails from './UploadDetails'; -import Uploader from './Uploader'; -import UploadLabel from './UploadLabel'; +import AudioInput from './AudioInput'; +import ImageInput from './ImageInput'; +import FileActions from './FileActions'; +import FileDetails from './FileDetails'; +import FileWrapper from './FileWrapper'; +import FileLabel from './FileLabel'; export { - AudioUploader, - ImageUploader, - UpLab, - UploadActions, - UploadDetails, - Uploader, - UploadLabel + AudioInput, + ImageInput, + FileActions, + FileDetails, + FileWrapper, + FileLabel }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/hooks/index.tsx b/packages/fakeyou.com/src/hooks/index.tsx index 3748987f4d..4cf47d636c 100644 --- a/packages/fakeyou.com/src/hooks/index.tsx +++ b/packages/fakeyou.com/src/hooks/index.tsx @@ -1,4 +1,5 @@ import useId from './useId'; +import useIdempotency from './useIdempotency'; import useUploader from './useUploader'; -export { useId, useUploader }; \ No newline at end of file +export { useId, useIdempotency, useUploader }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/hooks/useConvertIdempotency/index.tsx b/packages/fakeyou.com/src/hooks/useConvertIdempotency/index.tsx deleted file mode 100644 index 6efc7549f7..0000000000 --- a/packages/fakeyou.com/src/hooks/useConvertIdempotency/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from './useConvertIdempotency'; diff --git a/packages/fakeyou.com/src/hooks/useConvertIdempotency/useConvertIdempotency.tsx b/packages/fakeyou.com/src/hooks/useConvertIdempotency/useConvertIdempotency.tsx deleted file mode 100644 index 5295a7b7fe..0000000000 --- a/packages/fakeyou.com/src/hooks/useConvertIdempotency/useConvertIdempotency.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import { useState } from 'react'; -import { v4 as uuidv4 } from "uuid"; - -export default function useConvertIdempotencyToken() { - return useState(uuidv4()); -}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx b/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx index a43d9a1fdf..22683dcf23 100644 --- a/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx +++ b/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx @@ -4,31 +4,30 @@ const n = (o: any) => o; interface Props { debug?: any; - formClearedSet?: (cleared: boolean) => void; onChange?: (file: any) => void; onClear?: (x?: any) => void; - onUpload?: (file: any) => boolean; + onSubmit?: (file: any) => boolean; } -export default function useUploader({ debug, onChange = n, onClear = n, onUpload = n }: Props) { +export default function useUploader({ debug, onChange = n, onClear = n, onSubmit = n }: Props) { const [file, fileSet] = useState<any>(undefined); const [blob, blobSet] = useState<string>(); const [working, workingSet] = useState(false); - const [successful, successfulSet] = useState<boolean>(false); + const [success, successSet] = useState<boolean>(false); const inputRef = useRef<HTMLInputElement>(null); const submit = async () => { if (file === undefined) { return false; } - const onUploadResult = await onUpload(file); + const onUploadResult = await onSubmit(file); workingSet(true); - if (onUploadResult) { successfulSet(true); } - successfulSet(false); + if (onUploadResult) { successSet(true); } + successSet(false); }; const fileChange = (inputFile?: any) => { onChange(file); fileSet(inputFile || null); blobSet(inputFile ? URL.createObjectURL(inputFile) : ""); - successfulSet(false); + successSet(false); }; const inputChange = ({ target = {} }: { target: any }) => { fileChange(target.value); @@ -43,13 +42,12 @@ export default function useUploader({ debug, onChange = n, onClear = n, onUpload blob, clear, file, - fileSet, inputProps: { onChange: inputChange, inputRef }, submit, - successful, + success, working, }; }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx index 4874485640..1153b7a688 100644 --- a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx @@ -1,6 +1,6 @@ import React from "react"; import { useUploader } from "hooks"; -import { AudioUploader, ImageUploader } from "components/common"; +import { AudioInput, ImageInput } from "components/common"; import { PageHeader } from "components/layout"; import './LipsyncEditor.scss'; @@ -65,10 +65,10 @@ export default function LipsyncEditor({ ...rest }) { <h5>Audio</h5> </div> <div {...{ className: "grid-square lipsync-audio" }}> - <ImageUploader {...imageProps}/> + <ImageInput {...imageProps}/> </div> <div {...{ className: "grid-square" }}> - <AudioUploader {...audioProps}/> + <AudioInput {...{ ...audioProps, hideActions: true } }/> </div> </div> </div> From 30f3756e027f1756154df2b0245d3dc517f3f449 Mon Sep 17 00:00:00 2001 From: olivicmic <vic@vics.pics> Date: Wed, 9 Aug 2023 15:47:40 -0700 Subject: [PATCH 8/8] renamed useUploader to useFile --- packages/fakeyou.com/src/hooks/index.tsx | 4 ++-- packages/fakeyou.com/src/hooks/useFile/index.tsx | 1 + .../{useUploader/useUploader.tsx => useFile/useFile.tsx} | 2 +- packages/fakeyou.com/src/hooks/useUploader/index.tsx | 1 - .../v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 packages/fakeyou.com/src/hooks/useFile/index.tsx rename packages/fakeyou.com/src/hooks/{useUploader/useUploader.tsx => useFile/useFile.tsx} (92%) delete mode 100644 packages/fakeyou.com/src/hooks/useUploader/index.tsx diff --git a/packages/fakeyou.com/src/hooks/index.tsx b/packages/fakeyou.com/src/hooks/index.tsx index 4cf47d636c..bf9bef4f63 100644 --- a/packages/fakeyou.com/src/hooks/index.tsx +++ b/packages/fakeyou.com/src/hooks/index.tsx @@ -1,5 +1,5 @@ +import useFile from './useFile'; import useId from './useId'; import useIdempotency from './useIdempotency'; -import useUploader from './useUploader'; -export { useId, useIdempotency, useUploader }; \ No newline at end of file +export { useFile, useId, useIdempotency }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/hooks/useFile/index.tsx b/packages/fakeyou.com/src/hooks/useFile/index.tsx new file mode 100644 index 0000000000..e10364a878 --- /dev/null +++ b/packages/fakeyou.com/src/hooks/useFile/index.tsx @@ -0,0 +1 @@ +export { default } from "./useFile"; \ No newline at end of file diff --git a/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx b/packages/fakeyou.com/src/hooks/useFile/useFile.tsx similarity index 92% rename from packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx rename to packages/fakeyou.com/src/hooks/useFile/useFile.tsx index 22683dcf23..f75d512939 100644 --- a/packages/fakeyou.com/src/hooks/useUploader/useUploader.tsx +++ b/packages/fakeyou.com/src/hooks/useFile/useFile.tsx @@ -9,7 +9,7 @@ interface Props { onSubmit?: (file: any) => boolean; } -export default function useUploader({ debug, onChange = n, onClear = n, onSubmit = n }: Props) { +export default function useFile({ debug, onChange = n, onClear = n, onSubmit = n }: Props) { const [file, fileSet] = useState<any>(undefined); const [blob, blobSet] = useState<string>(); const [working, workingSet] = useState(false); diff --git a/packages/fakeyou.com/src/hooks/useUploader/index.tsx b/packages/fakeyou.com/src/hooks/useUploader/index.tsx deleted file mode 100644 index bd6d3c6c8e..0000000000 --- a/packages/fakeyou.com/src/hooks/useUploader/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./useUploader"; \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx index 1153b7a688..17e71c5862 100644 --- a/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/lipsync/LipsyncEditor/LipsyncEditor.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { useUploader } from "hooks"; +import { useFile } from "hooks"; import { AudioInput, ImageInput } from "components/common"; import { PageHeader } from "components/layout"; import './LipsyncEditor.scss'; @@ -43,8 +43,8 @@ const Title = ({ ...rest }) => { }; export default function LipsyncEditor({ ...rest }) { - const audioProps = useUploader({ debug: 'audio useUploader' }); - const imageProps = useUploader({}); + const audioProps = useFile({ debug: 'audio useFile' }); + const imageProps = useFile({}); const subText = "Select an image with a clear face, or one of our existing templates, then choose either text to speech or uploaded audio(eg. music). Then you can generate a beautifully lipsynced video."; const headerProps = {