mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-05 17:58:55 +00:00
some EntityInput refactor
This commit is contained in:
1 parent
60f4eb7d93
commit
b0c3f23f2e
7 files changed
+88
-40
No files matched your search
@@ -5,12 +5,14 @@ import { useSpring, a } from "@react-spring/web";
|
||||
import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
|
||||
import "./Modal.scss";
|
||||
|
||||
type HandleClose = () => void;
|
||||
|
||||
interface ModalProps {
|
||||
className?: string;
|
||||
content?: React.ElementType | null;
|
||||
contentProps?: any;
|
||||
show: boolean;
|
||||
handleClose: () => void;
|
||||
handleClose: HandleClose;
|
||||
noHeader?: boolean;
|
||||
omitBody?: boolean;
|
||||
onCancel?: (e: React.MouseEvent<HTMLElement>) => any;
|
||||
@@ -25,6 +27,10 @@ interface ModalProps {
|
||||
mobileFullscreen?: boolean;
|
||||
}
|
||||
|
||||
export interface ModalUtilities {
|
||||
handleClose: HandleClose;
|
||||
}
|
||||
|
||||
const ModalBody = ({ children, omitBody, padding }: { children: any, omitBody?: boolean, padding?: boolean }) => omitBody ? children : <div {...{ className: `modal-body ${padding ? "p-3" : ""}` }}>
|
||||
{ children }
|
||||
</div>;
|
||||
@@ -85,6 +91,8 @@ const Modal: React.FC<ModalProps> = ({
|
||||
handleClose();
|
||||
};
|
||||
|
||||
const modalUtilities: ModalUtilities = { handleClose };
|
||||
|
||||
if (!show) {
|
||||
return null;
|
||||
}
|
||||
@@ -115,7 +123,7 @@ const Modal: React.FC<ModalProps> = ({
|
||||
</header>
|
||||
)}
|
||||
<ModalBody {...{ omitBody, padding }}>
|
||||
{Content && <Content {...{ ...contentProps, handleClose }} />}
|
||||
{Content && <Content {...{ ...contentProps, ...modalUtilities }} />}
|
||||
</ModalBody>
|
||||
{showButtons && (
|
||||
<div className="modal-footer">
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export { default } from "./Modal";
|
||||
export type { ModalUtilities } from "./Modal";
|
||||
@@ -22,7 +22,7 @@ import Label from "./Label";
|
||||
import LikeButton from "./LikeButton";
|
||||
import MocapInput from "./MocapInput";
|
||||
import MasonryGrid from "./MasonryGrid/MasonryGrid";
|
||||
import Modal from "./Modal";
|
||||
import Modal, { ModalUtilities } from "./Modal";
|
||||
import Notification from "./Notification";
|
||||
import NumberSlider from "./NumberSlider";
|
||||
import NumberSliderV2 from "./NumberSliderV2";
|
||||
@@ -53,7 +53,6 @@ import VideoBasic from "./VideoBasic";
|
||||
import VideoFakeyou from "./VideoFakeyou";
|
||||
import VideoInput from "./VideoInput";
|
||||
import WeightCoverImage from "./WeightCoverImage";
|
||||
export type { SelectModalData };
|
||||
|
||||
export {
|
||||
Accordion,
|
||||
@@ -117,3 +116,8 @@ export {
|
||||
VideoInput,
|
||||
WeightCoverImage,
|
||||
};
|
||||
|
||||
export type {
|
||||
ModalUtilities,
|
||||
SelectModalData
|
||||
};
|
||||
@@ -4,8 +4,8 @@ import { a, useTransition } from "@react-spring/web";
|
||||
import { MediaFile } from "@storyteller/components/src/api/media_files/GetMedia";
|
||||
import Iframe from "react-iframe";
|
||||
import { Button, Label, Spinner } from "components/common";
|
||||
import { AcceptTypes, EntityInputMode, EntityModeProp, getMediaTypesByCategory, mediaCategoryfromString, MediaFilters, UploaderResponse } from "components/entities/EntityTypes";
|
||||
import { useMedia, useMediaUploader, useModal, useSession } from "hooks";
|
||||
import { AcceptTypes, EntityModeProp, mediaCategoryfromString, MediaFilters, UploaderResponse } from "components/entities/EntityTypes";
|
||||
import { useMedia, useMediaUploader } from "hooks";
|
||||
import { BucketConfig } from "@storyteller/components/src/api/BucketConfig";
|
||||
import EntityInputEmpty from "./EntityInputEmpty";
|
||||
import "./EntityInput.scss";
|
||||
@@ -37,11 +37,10 @@ const MediaBusy = () => {
|
||||
return <Spinner/>;
|
||||
};
|
||||
|
||||
const MocapInputFull = ({ media, clear, ...rest }: SlideProps) => {
|
||||
const EntityInputFull = ({ media, clear }: SlideProps) => {
|
||||
const bucketConfig = new BucketConfig();
|
||||
const mediaUrl = media?.public_bucket_path ? bucketConfig.getGcsUrl(media.public_bucket_path) : "";
|
||||
const mediaType = mediaCategoryfromString(media?.media_type || "");
|
||||
// const yada = ListEntityFilters(EntityInputMode.media).indexOf(media.media_type);
|
||||
|
||||
switch (mediaType) {
|
||||
case MediaFilters.video: return <>
|
||||
@@ -66,26 +65,20 @@ const MocapInputFull = ({ media, clear, ...rest }: SlideProps) => {
|
||||
}
|
||||
};
|
||||
|
||||
const AniMod = ({ animating, className, isLeaving, render: Render, style, ...rest }: AniProps) => <a.div {...{
|
||||
const AnimatedSlide = ({ animating, className, isLeaving, render: Render, style, ...rest }: AniProps) => <a.div {...{
|
||||
className: `fy-slide-frame${ className ? " " + className : "" }`,
|
||||
style
|
||||
}}>
|
||||
<Render {...{ ...rest, animating }} />
|
||||
</a.div>;
|
||||
|
||||
export default function EntityInput({ accept: inAccept, aspectRatio = "square", label, name = "", onChange, type, value, ...rest }: Props) {
|
||||
const accept = Array.isArray(inAccept) ? inAccept : [inAccept];
|
||||
const inputMode = EntityInputMode[type];
|
||||
const isMedia = inputMode === EntityInputMode.media;
|
||||
const fileTypes = isMedia ? accept.map((mediaCategory,i) => {
|
||||
return mediaCategory ? getMediaTypesByCategory(mediaCategoryfromString(mediaCategory)) : [];
|
||||
}).flat() : [];
|
||||
export default function EntityInput({ accept, aspectRatio = "square", label, name = "", onChange, type, value, ...rest }: Props) {
|
||||
const { search } = useLocation();
|
||||
const presetToken = search ? new URLSearchParams(search).get("preset_token") : "";
|
||||
const urlSearch = new URLSearchParams(search);
|
||||
const presetToken = search ? urlSearch.get("preset_token") : "";
|
||||
const queryUser = search ? urlSearch.get("query_user") : "";
|
||||
const [mediaToken,mediaTokenSet] = useState(presetToken || value || "");
|
||||
const { media, mediaSet } = useMedia({ mediaToken });
|
||||
const { user } = useSession();
|
||||
const { open } = useModal();
|
||||
const clear = () => {
|
||||
mediaSet(undefined);
|
||||
mediaTokenSet("");
|
||||
@@ -130,12 +123,32 @@ export default function EntityInput({ accept: inAccept, aspectRatio = "square",
|
||||
{
|
||||
transitions((style: any, i: number, state: any) => {
|
||||
let isLeaving = state.phase === "leave";
|
||||
let sharedProps = { animating, isLeaving, media, style };
|
||||
let sharedProps = { animating, isLeaving, style };
|
||||
|
||||
return [
|
||||
<AniMod {...{ render: MediaBusy, className: "fy-entity-input-busy", ...sharedProps }}/>,
|
||||
<AniMod {...{ render: MocapInputFull, className: "fy-entity-input-full", accept, clear, ...sharedProps }}/>,
|
||||
<AniMod {...{ render: EntityInputEmpty, className: "fy-entity-input-empty", accept, fileTypes, inputMode, inputProps, onSelect, open, user, ...sharedProps, ...rest }}/>
|
||||
<AnimatedSlide {...{
|
||||
className: "fy-entity-input-busy",
|
||||
render: MediaBusy,
|
||||
...sharedProps
|
||||
}}/>,
|
||||
<AnimatedSlide {...{
|
||||
className: "fy-entity-input-full",
|
||||
clear,
|
||||
media,
|
||||
render: EntityInputFull,
|
||||
...sharedProps
|
||||
}}/>,
|
||||
<AnimatedSlide {...{
|
||||
accept,
|
||||
className: "fy-entity-input-empty",
|
||||
inputProps,
|
||||
onSelect,
|
||||
queryUser,
|
||||
render: EntityInputEmpty,
|
||||
type,
|
||||
...sharedProps,
|
||||
...rest
|
||||
}}/>
|
||||
][i];
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
import React from "react";
|
||||
import { AcceptTypes, EntityInputMode, getMediaTypesByCategory, isSelectedType, mediaCategoryfromString, MediaFilters } from "components/entities/EntityTypes";
|
||||
import { SlideProps } from "./EntityInput";
|
||||
import { MediaBrowser } from "components/modals";
|
||||
import {
|
||||
// useMediaUploader,
|
||||
useModal,
|
||||
useSession
|
||||
} from "hooks";
|
||||
import MediaBrowser, { MediaBrowserProps } from "components/modals/MediaBrowser";
|
||||
import { FileWrapper } from "components/common";
|
||||
import {
|
||||
AcceptTypes,
|
||||
EntityInputMode,
|
||||
EntityModeProp,
|
||||
getMediaTypesByCategory,
|
||||
isSelectedType,
|
||||
mediaCategoryfromString,
|
||||
MediaFilters
|
||||
} from "components/entities/EntityTypes";
|
||||
import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome";
|
||||
import {
|
||||
faDiagramSankey,
|
||||
@@ -16,23 +29,32 @@ import {
|
||||
|
||||
|
||||
interface EmptySlideProps extends SlideProps {
|
||||
accept?: AcceptTypes[],
|
||||
inputMode: EntityInputMode,
|
||||
accept: AcceptTypes | AcceptTypes[],
|
||||
inputProps?: any,
|
||||
open: any,
|
||||
user: any
|
||||
queryUser?: string,
|
||||
type: EntityModeProp,
|
||||
};
|
||||
|
||||
export default function EntityInputEmpty({ accept, open, inputMode, inputProps, user, ...rest }: EmptySlideProps) {
|
||||
const accepted = accept ? accept : [];
|
||||
export default function EntityInputEmpty({ accept, inputProps, queryUser, type, ...rest }: EmptySlideProps) {
|
||||
const { open } = useModal();
|
||||
const { user } = useSession();
|
||||
const accepted = Array.isArray(accept) ? accept : [accept];
|
||||
const inputMode = EntityInputMode[type];
|
||||
const isMedia = inputMode === EntityInputMode.media;
|
||||
const fileTypes = isMedia ? accepted.map((mediaCategory,i) => {
|
||||
return mediaCategory ? getMediaTypesByCategory(mediaCategoryfromString(mediaCategory)) : [];
|
||||
}).flat() : [];
|
||||
|
||||
const props: MediaBrowserProps = {
|
||||
accept: accepted,
|
||||
inputMode,
|
||||
username: queryUser || user?.username || "",
|
||||
...rest
|
||||
};
|
||||
|
||||
const browserClick = () => open({
|
||||
component: MediaBrowser,
|
||||
props: { accept, inputMode, username: user?.username || "", ...rest }
|
||||
props
|
||||
});
|
||||
|
||||
const mediaIcons = () => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useState } from "react";
|
||||
import { MediaList } from "components/entities";
|
||||
import { AcceptTypes, EntityInputMode, EntityFilterOptions } from "components/entities/EntityTypes";
|
||||
import { Pagination, TempSelect } from "components/common";
|
||||
import { AcceptTypes, EntityInputMode, EntityFilterOptions, } from "components/entities/EntityTypes";
|
||||
import { ModalUtilities, Pagination, TempSelect } from "components/common";
|
||||
import AudioPlayerProvider from "components/common/AudioPlayer/AudioPlayerContext";
|
||||
import SkeletonCard from "components/common/Card/SkeletonCard";
|
||||
import { GetBookmarksByUser } from "@storyteller/components/src/api/bookmarks/GetBookmarksByUser";
|
||||
@@ -20,11 +20,9 @@ import "./MediaBrowser.scss";
|
||||
|
||||
const n = () => {};
|
||||
|
||||
interface Props {
|
||||
export interface MediaBrowserProps {
|
||||
accept?: AcceptTypes[],
|
||||
handleClose: any;
|
||||
inputMode: EntityInputMode;
|
||||
mediaToken: string;
|
||||
onSearchChange?: (e: any) => void;
|
||||
onSelect?: any;
|
||||
owner?: string;
|
||||
@@ -32,9 +30,10 @@ interface Props {
|
||||
username: string;
|
||||
}
|
||||
|
||||
interface MediaBrowserInternal extends ModalUtilities, MediaBrowserProps {}
|
||||
|
||||
export default function MediaBrowser({
|
||||
accept,
|
||||
mediaToken,
|
||||
handleClose = n,
|
||||
inputMode,
|
||||
onSearchChange = n,
|
||||
@@ -42,7 +41,7 @@ export default function MediaBrowser({
|
||||
owner,
|
||||
search,
|
||||
username
|
||||
}: Props) {
|
||||
}: MediaBrowserInternal) {
|
||||
|
||||
console.log(
|
||||
"🐢",
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export { default } from "./MediaBrowser";
|
||||
export { default } from "./MediaBrowser";
|
||||
export type { MediaBrowserProps } from "./MediaBrowser";
|
||||
Reference in new issue
Block a user