mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-05 17:58:55 +00:00
Merge pull request #668 from storytold/camera-capture-testing
initial camera capture input progress for testing
This commit is contained in:
15 files changed
+415
-80
No files matched your search
@@ -34,10 +34,12 @@
|
||||
"@babel/runtime": "^7.25.0",
|
||||
"@react-spring/types": "^9.7.3",
|
||||
"@typeform/embed": "^4.8.1",
|
||||
"@types/dom-mediacapture-record": "^1.0.19",
|
||||
"framer-motion": "6.5.1",
|
||||
"local-storage": "^2.0.0",
|
||||
"moment": "^2.29.4",
|
||||
"react-easy-crop": "^5.0.7",
|
||||
"react-webcam": "^7.2.0",
|
||||
"universal-cookie": "^6.1.1",
|
||||
"yarn": "^1.22.19"
|
||||
},
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
@import "scss/colours.scss";
|
||||
@import "scss/site-refresh.scss";
|
||||
|
||||
@mixin video-tint {
|
||||
background-color: rgba($secondary-very-dark, 0.5);
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
.fy-slide-frame {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
|
||||
@@ -41,6 +41,7 @@ interface EntityInputProps {
|
||||
name?: string;
|
||||
onChange?: any;
|
||||
onPromptUpdate?: (prompt: Prompt | null) => void;
|
||||
showWebcam?: boolean;
|
||||
type: EntityModeProp;
|
||||
value?: string;
|
||||
}
|
||||
@@ -177,6 +178,7 @@ export default function EntityInput({
|
||||
name = "",
|
||||
onChange,
|
||||
onPromptUpdate,
|
||||
showWebcam = false,
|
||||
type,
|
||||
value,
|
||||
...rest
|
||||
@@ -305,6 +307,7 @@ export default function EntityInput({
|
||||
onSelect,
|
||||
queryUser,
|
||||
render: EntityInputEmpty,
|
||||
showWebcam,
|
||||
type,
|
||||
...sharedProps,
|
||||
...rest,
|
||||
|
||||
+27
-2
@@ -5,9 +5,11 @@ import {
|
||||
useModal,
|
||||
useSession,
|
||||
} from "hooks";
|
||||
import MediaBrowser, {
|
||||
import {
|
||||
CameraCapture,
|
||||
MediaBrowser,
|
||||
MediaBrowserProps,
|
||||
} from "components/modals/MediaBrowser";
|
||||
} from "components/modals";
|
||||
import { FileWrapper } from "components/common";
|
||||
import {
|
||||
AcceptTypes,
|
||||
@@ -20,6 +22,7 @@ import {
|
||||
} from "components/entities/EntityTypes";
|
||||
import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome";
|
||||
import {
|
||||
faCamera,
|
||||
faDiagramSankey,
|
||||
faFile,
|
||||
faFileArrowUp,
|
||||
@@ -33,6 +36,7 @@ interface EmptySlideProps extends SlideProps {
|
||||
accept: AcceptTypes | AcceptTypes[];
|
||||
inputProps?: any;
|
||||
queryUser?: string;
|
||||
showWebcam: boolean;
|
||||
type: EntityModeProp;
|
||||
}
|
||||
|
||||
@@ -40,6 +44,7 @@ export default function EntityInputEmpty({
|
||||
accept,
|
||||
inputProps,
|
||||
queryUser,
|
||||
showWebcam,
|
||||
type,
|
||||
...rest
|
||||
}: EmptySlideProps) {
|
||||
@@ -71,6 +76,13 @@ export default function EntityInputEmpty({
|
||||
props,
|
||||
});
|
||||
|
||||
const cameraClick = () =>
|
||||
open({
|
||||
component: CameraCapture,
|
||||
padding: false,
|
||||
width: "square",
|
||||
});
|
||||
|
||||
const mediaIcons = () => {
|
||||
if (isSelectedType(MediaFilters.audio, accepted[0])) return faWaveform;
|
||||
if (isSelectedType(MediaFilters.engine_asset, accepted[0]))
|
||||
@@ -130,6 +142,19 @@ export default function EntityInputEmpty({
|
||||
/>
|
||||
Choose from your {["bookmarks", "media", "weights"][inputMode]}
|
||||
</div>
|
||||
{showWebcam && (
|
||||
<div
|
||||
{...{
|
||||
className: "fy-entity-input-row fy-entity-input-button",
|
||||
onClick: cameraClick,
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
{...{ className: "fy-entity-input-label-icon", icon: faCamera }}
|
||||
/>
|
||||
Record with your camera
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
@import "scss/colours.scss";
|
||||
@import "scss/site-refresh.scss";
|
||||
|
||||
.fy-camera-capture-modal {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
position: relative;
|
||||
|
||||
.fy-camera-capture-display {
|
||||
height: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.fy-camera-capture-controls {
|
||||
@include video-tint;
|
||||
position: absolute;
|
||||
bottom: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.5rem 0.5rem 0.25rem;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
width: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.fy-camera-capture-record-toggle {
|
||||
appearance: none;
|
||||
border: none;
|
||||
background: none;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
font-size: 0.75rem;
|
||||
|
||||
// background: green;
|
||||
|
||||
svg {
|
||||
display: block;
|
||||
// background: rgba(#00f, 0.25);
|
||||
height: 2rem;
|
||||
width: 2rem;
|
||||
margin-bottom: 0.25rem;
|
||||
|
||||
circle {
|
||||
fill: none;
|
||||
stroke: $primary;
|
||||
stroke-width: 2px;
|
||||
}
|
||||
rect {
|
||||
fill: $primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
import React, { useCallback, useRef, useState } from "react";
|
||||
import Webcam from "react-webcam";
|
||||
import { a, useSpring } from "@react-spring/web";
|
||||
// import { MediaRecorder, IMediaRecorder } from "extendable-media-recorder";
|
||||
import "./CameraCapture.scss";
|
||||
|
||||
import { ModalUtilities } from "components/common";
|
||||
|
||||
// interface Props {
|
||||
// value?: any;
|
||||
// }
|
||||
|
||||
export default function CameraCapture({ handleClose }: ModalUtilities) {
|
||||
const webcamRef = useRef<Webcam>(null);
|
||||
const mediaRecorderRef = useRef<MediaRecorder | null>(null);
|
||||
const [capturing, capturingSet] = useState(false);
|
||||
const [recordedChunks, setRecordedChunks] = useState([]);
|
||||
|
||||
const handleDataAvailable = useCallback(
|
||||
({ data }) => {
|
||||
if (data.size > 0) {
|
||||
setRecordedChunks(prev => prev.concat(data));
|
||||
}
|
||||
},
|
||||
[setRecordedChunks]
|
||||
);
|
||||
|
||||
const handleDownload = React.useCallback(() => {
|
||||
if (recordedChunks.length) {
|
||||
const blob = new Blob(recordedChunks, {
|
||||
type: "video/webm",
|
||||
});
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
document.body.appendChild(a);
|
||||
// a.style = "display: none";
|
||||
a.href = url;
|
||||
a.download = "react-webcam-stream-capture.webm";
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
setRecordedChunks([]);
|
||||
}
|
||||
}, [recordedChunks]);
|
||||
|
||||
const mainToggleClick = () => {
|
||||
if (!capturing) {
|
||||
capturingSet(true);
|
||||
|
||||
if (webcamRef.current && webcamRef.current.stream) {
|
||||
console.log("🧢", webcamRef.current.stream);
|
||||
mediaRecorderRef.current = new MediaRecorder(webcamRef.current.stream, {
|
||||
mimeType: "video/webm",
|
||||
});
|
||||
|
||||
mediaRecorderRef.current.addEventListener(
|
||||
"dataavailable",
|
||||
handleDataAvailable
|
||||
);
|
||||
mediaRecorderRef.current.start();
|
||||
}
|
||||
} else {
|
||||
capturingSet(false);
|
||||
|
||||
if (mediaRecorderRef.current !== null) {
|
||||
mediaRecorderRef.current.stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const mainToggleStyle = useSpring({
|
||||
rx: capturing ? 1 : 8,
|
||||
size: capturing ? 14 : 16,
|
||||
xy: capturing ? 9 : 8,
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
{...{
|
||||
className: "fy-camera-capture-modal",
|
||||
}}
|
||||
>
|
||||
<Webcam
|
||||
audio
|
||||
{...{
|
||||
audioConstraints: {
|
||||
sampleSize: 16,
|
||||
channelCount: 2,
|
||||
},
|
||||
className: "fy-camera-capture-display",
|
||||
ref: webcamRef,
|
||||
videoConstraints: {
|
||||
width: 512,
|
||||
height: 512,
|
||||
facingMode: "user",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<div {...{ className: "fy-camera-capture-controls" }}>
|
||||
<button
|
||||
{...{
|
||||
className: "fy-camera-capture-record-toggle",
|
||||
onClick: mainToggleClick,
|
||||
}}
|
||||
>
|
||||
<svg>
|
||||
<circle
|
||||
{...{
|
||||
cx: 16,
|
||||
cy: 16,
|
||||
r: 15,
|
||||
}}
|
||||
/>
|
||||
<a.rect
|
||||
{...{
|
||||
x: mainToggleStyle.xy,
|
||||
y: mainToggleStyle.xy,
|
||||
height: mainToggleStyle.size,
|
||||
width: mainToggleStyle.size,
|
||||
rx: mainToggleStyle.rx,
|
||||
}}
|
||||
/>
|
||||
</svg>
|
||||
Record
|
||||
</button>
|
||||
{recordedChunks.length > 0 && (
|
||||
<button onClick={handleDownload}>Download</button>
|
||||
)}
|
||||
</div>
|
||||
{/* {capturing ? (
|
||||
<button onClick={handleStopCaptureClick}>Stop Capture</button>
|
||||
) : (
|
||||
<button onClick={handleStartCaptureClick}>Start Capture</button>
|
||||
)}
|
||||
{recordedChunks.length > 0 && (
|
||||
<button onClick={handleDownload}>Download</button>
|
||||
)}*/}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from "./CameraCapture";
|
||||
@@ -1,4 +1,7 @@
|
||||
import CameraCapture from "./CameraCapture";
|
||||
import InferenceJobsModal from "./InferenceJobsModal";
|
||||
import MediaBrowser from "./MediaBrowser";
|
||||
import MediaBrowser, { MediaBrowserProps } from "./MediaBrowser";
|
||||
|
||||
export { InferenceJobsModal, MediaBrowser };
|
||||
export { CameraCapture, InferenceJobsModal, MediaBrowser };
|
||||
|
||||
export type { MediaBrowserProps };
|
||||
+15
@@ -37,6 +37,17 @@
|
||||
.fy-modal-body-small {
|
||||
width: 100%;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
.fy-modal-body-square {
|
||||
width: 75vh;
|
||||
height: 75vh;
|
||||
}
|
||||
|
||||
.fy-modal-body-wide,
|
||||
.fy-modal-body-narrow,
|
||||
.fy-modal-body-small,
|
||||
.fy-modal-body-square {
|
||||
overflow: hidden;
|
||||
background-color: $panel;
|
||||
border-color: lighten($panel, 8%) !important;
|
||||
@@ -54,4 +65,8 @@
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.fy-modal-no-padding {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
+9
-1
@@ -12,6 +12,7 @@ interface Props {
|
||||
lockTint?: boolean;
|
||||
modalOpen: boolean;
|
||||
onModalCloseEnd: (x: any) => void;
|
||||
padding?: boolean;
|
||||
width?: ModalWidth;
|
||||
}
|
||||
|
||||
@@ -23,6 +24,7 @@ export default function ModalLayer({
|
||||
lockTint,
|
||||
modalOpen,
|
||||
onModalCloseEnd,
|
||||
padding = true,
|
||||
width = "wide",
|
||||
}: Props) {
|
||||
const mainClassName = "fy-modal-layer";
|
||||
@@ -57,7 +59,13 @@ export default function ModalLayer({
|
||||
},
|
||||
}}
|
||||
>
|
||||
<div {...{ className: `fy-modal-body-${width}` }}>
|
||||
<div
|
||||
{...{
|
||||
className: `fy-modal-body-${width}${
|
||||
padding ? "" : " fy-modal-no-padding"
|
||||
}`,
|
||||
}}
|
||||
>
|
||||
{Content && (
|
||||
<Content {...{ ...contentProps, handleClose: close }} />
|
||||
)}
|
||||
|
||||
+1
@@ -50,6 +50,7 @@ export default function ModalProvider({ children }: ModalProviderProps) {
|
||||
lockTint: modalState?.lockTint,
|
||||
modalOpen,
|
||||
onModalCloseEnd,
|
||||
padding: modalState?.padding,
|
||||
width: modalState?.width,
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { isMobile } from "react-device-detect";
|
||||
|
||||
export type ModalWidth = "wide" | "narrow" | "small";
|
||||
export type ModalWidth = "wide" | "narrow" | "small" | "square";
|
||||
|
||||
export interface ModalConfig {
|
||||
component: React.ElementType;
|
||||
lockTint?: boolean;
|
||||
padding?: boolean;
|
||||
props?: any;
|
||||
width?: ModalWidth;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,11 @@ styles with important tags:
|
||||
}
|
||||
}
|
||||
|
||||
@mixin video-tint {
|
||||
background-color: rgba($secondary-very-dark, 0.5);
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
.fakeyou-refresh {
|
||||
//- BS5 classnames -//
|
||||
.object-fit-cover {
|
||||
|
||||
@@ -1,11 +1,25 @@
|
||||
import React, { useState } from "react";
|
||||
import { EntityInput } from "components/entities";
|
||||
import { EntityFilterOptions, EntityInputMode, EntityModeProp, ListEntityFilters } from "components/entities/EntityTypes";
|
||||
import { useModal, useNotifications,
|
||||
// useSession
|
||||
import {
|
||||
EntityFilterOptions,
|
||||
EntityInputMode,
|
||||
EntityModeProp,
|
||||
ListEntityFilters,
|
||||
} from "components/entities/EntityTypes";
|
||||
import {
|
||||
useModal,
|
||||
useNotifications,
|
||||
// useSession
|
||||
} from "hooks";
|
||||
import { InferenceJobsModal } from "components/modals";
|
||||
import { Button, Checkbox, NumberSlider, SegmentButtons, TempInput, TempSelect } from "components/common";
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
NumberSlider,
|
||||
SegmentButtons,
|
||||
TempInput,
|
||||
TempSelect,
|
||||
} from "components/common";
|
||||
import { onChanger } from "resources";
|
||||
import "./DevEntityInput.scss";
|
||||
|
||||
@@ -14,35 +28,37 @@ interface Props {
|
||||
}
|
||||
|
||||
interface Yank {
|
||||
[key: string]: any[]
|
||||
[key: string]: any[];
|
||||
}
|
||||
|
||||
export default function DevMediaInput({ value }: Props) {
|
||||
// const { studioAccessCheck } = useSession();
|
||||
const { create } = useNotifications();
|
||||
const [mediaToken,mediaTokenSet] = useState();
|
||||
const [notTitle,notTitleSet] = useState("Notification Title");
|
||||
const [notContent,notContentSet] = useState("Notification Content");
|
||||
const [autoRemove,autoRemoveSet] = useState(true);
|
||||
const [btnCount,btnCountSet] = useState(0);
|
||||
const [mediaToken, mediaTokenSet] = useState();
|
||||
const [notTitle, notTitleSet] = useState("Notification Title");
|
||||
const [notContent, notContentSet] = useState("Notification Content");
|
||||
const [autoRemove, autoRemoveSet] = useState(true);
|
||||
const [btnCount, btnCountSet] = useState(0);
|
||||
const [mode, modeSet] = useState<EntityModeProp>("media");
|
||||
const yadda = Object.keys(EntityInputMode).filter(val => isNaN(Number(val))).reduce((obj,modeType,i) => {
|
||||
return {
|
||||
[modeType]: ListEntityFilters(i),
|
||||
...obj
|
||||
};
|
||||
},{});
|
||||
const yadda = Object.keys(EntityInputMode)
|
||||
.filter(val => isNaN(Number(val)))
|
||||
.reduce((obj, modeType, i) => {
|
||||
return {
|
||||
[modeType]: ListEntityFilters(i),
|
||||
...obj,
|
||||
};
|
||||
}, {});
|
||||
|
||||
const onChange = onChanger({
|
||||
autoRemoveSet,
|
||||
btnCountSet,
|
||||
mediaTokenSet,
|
||||
notContentSet,
|
||||
notTitleSet
|
||||
notTitleSet,
|
||||
});
|
||||
|
||||
const [filters,filtersSet] = useState<Yank>(yadda);
|
||||
const [owner,ownerSet] = useState("");
|
||||
const [filters, filtersSet] = useState<Yank>(yadda);
|
||||
const [owner, ownerSet] = useState("");
|
||||
// const onChange = ({ target }: any) => mediaTokenSet(target.value);
|
||||
const { open } = useModal();
|
||||
|
||||
@@ -53,61 +69,104 @@ export default function DevMediaInput({ value }: Props) {
|
||||
|
||||
console.log("❌", mode, inputMode, filterOptions, filters[mode]);
|
||||
|
||||
const changeFilter = ({ target }: { target: any }) => filtersSet({ ...filters, [mode]: target.value });
|
||||
const changeFilter = ({ target }: { target: any }) =>
|
||||
filtersSet({ ...filters, [mode]: target.value });
|
||||
const openModal = () => open({ component: InferenceJobsModal });
|
||||
|
||||
const testBtn = { label: "abc" };
|
||||
|
||||
const actions = Array.from({length: btnCount},() => testBtn);
|
||||
const actions = Array.from({ length: btnCount }, () => testBtn);
|
||||
|
||||
const createNotification = () => create({
|
||||
actions,
|
||||
autoRemove,
|
||||
title: notTitle,
|
||||
content: notContent,
|
||||
onClick: () => console.log("🍉")
|
||||
});
|
||||
const createNotification = () =>
|
||||
create({
|
||||
actions,
|
||||
autoRemove,
|
||||
title: notTitle,
|
||||
content: notContent,
|
||||
onClick: () => console.log("🍉"),
|
||||
});
|
||||
|
||||
return (<div {...{ className: "fy-engine-compositor p-3"}}>
|
||||
<h2>{ [526,187].map((num = 0) => String.fromCodePoint(128000 + num)) }</h2>
|
||||
<div {...{ className: "panel p-3 mb-3 fy-basic-grid" }}>
|
||||
<header>
|
||||
<h5>Make-a-notification</h5>
|
||||
</header>
|
||||
<TempInput {...{ value: notTitle, name: "notTitle", onChange }}/>
|
||||
<TempInput {...{ value: notContent, name: "notContent", onChange }}/>
|
||||
<NumberSlider {...{ value: btnCount, name: "btnCount", onChange, label: "Button amount", min: 0, max: 3 }}/>
|
||||
<div {...{ className: "lower-controls" }}>
|
||||
<Checkbox {...{ checked: autoRemove, name: "autoRemove", onChange, label: "Auto remove" }}/>
|
||||
<Button {...{ label: "Create Notification", onClick: createNotification, variant: "primary" }}/>
|
||||
return (
|
||||
<div {...{ className: "fy-engine-compositor p-3" }}>
|
||||
<h2>{[526, 187].map((num = 0) => String.fromCodePoint(128000 + num))}</h2>
|
||||
<div {...{ className: "panel p-3 mb-3 fy-basic-grid" }}>
|
||||
<header>
|
||||
<h5>Make-a-notification</h5>
|
||||
</header>
|
||||
<TempInput {...{ value: notTitle, name: "notTitle", onChange }} />
|
||||
<TempInput {...{ value: notContent, name: "notContent", onChange }} />
|
||||
<NumberSlider
|
||||
{...{
|
||||
value: btnCount,
|
||||
name: "btnCount",
|
||||
onChange,
|
||||
label: "Button amount",
|
||||
min: 0,
|
||||
max: 3,
|
||||
}}
|
||||
/>
|
||||
<div {...{ className: "lower-controls" }}>
|
||||
<Checkbox
|
||||
{...{
|
||||
checked: autoRemove,
|
||||
name: "autoRemove",
|
||||
onChange,
|
||||
label: "Auto remove",
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
{...{
|
||||
label: "Create Notification",
|
||||
onClick: createNotification,
|
||||
variant: "primary",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div {...{ className: "panel p-3 fy-basic-grid" }}>
|
||||
<h5>Select Entities</h5>
|
||||
<header>
|
||||
<SegmentButtons
|
||||
{...{
|
||||
onChange: ({ target }: { target: any }) => modeSet(target.value),
|
||||
options,
|
||||
value: mode,
|
||||
}}
|
||||
/>
|
||||
<TempInput
|
||||
{...{
|
||||
value: owner,
|
||||
onChange: ({ target }: { target: any }) => ownerSet(target.value),
|
||||
placeholder: "User",
|
||||
}}
|
||||
/>
|
||||
</header>
|
||||
<TempSelect
|
||||
{...{
|
||||
options: filterOptions,
|
||||
value: filters[mode],
|
||||
onChange: changeFilter,
|
||||
}}
|
||||
/>
|
||||
<EntityInput
|
||||
{...{
|
||||
accept: filters[mode],
|
||||
aspectRatio: "landscape",
|
||||
label: "Choose entity",
|
||||
name: "mediaToken",
|
||||
// label: `Choose ${ ["","media file","weight"][entityType] }`,
|
||||
onChange,
|
||||
owner,
|
||||
// search: "Dream"
|
||||
showWebcam: true,
|
||||
type: mode,
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
{...{ label: "Open modal", onClick: openModal, variant: "primary" }}
|
||||
/>
|
||||
<div>{mediaToken}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div {...{ className: "panel p-3 fy-basic-grid" }}>
|
||||
<h5>Select Entities</h5>
|
||||
<header>
|
||||
<SegmentButtons {...{ onChange: ({ target }: { target: any }) => modeSet(target.value), options, value: mode }}/>
|
||||
<TempInput {...{ value: owner, onChange: ({ target }: { target: any }) => ownerSet(target.value), placeholder: "User" }}/>
|
||||
</header>
|
||||
<TempSelect {...{
|
||||
options: filterOptions,
|
||||
value: filters[mode],
|
||||
onChange: changeFilter
|
||||
}}/>
|
||||
<EntityInput {...{
|
||||
accept: filters[mode],
|
||||
aspectRatio: "landscape",
|
||||
label: "Choose entity",
|
||||
name: "mediaToken",
|
||||
// label: `Choose ${ ["","media file","weight"][entityType] }`,
|
||||
onChange,
|
||||
owner,
|
||||
// search: "Dream",
|
||||
type: mode
|
||||
}}/>
|
||||
<Button {...{ label: "Open modal", onClick: openModal, variant: "primary" }}/>
|
||||
<div>
|
||||
{ mediaToken }
|
||||
</div>
|
||||
</div>
|
||||
</div>);
|
||||
};
|
||||
);
|
||||
}
|
||||
@@ -4487,6 +4487,7 @@ __metadata:
|
||||
"@babel/runtime": ^7.25.0
|
||||
"@react-spring/types": ^9.7.3
|
||||
"@typeform/embed": ^4.8.1
|
||||
"@types/dom-mediacapture-record": ^1.0.19
|
||||
craco: ^0.0.3
|
||||
cross-env: ^7.0.3
|
||||
framer-motion: 6.5.1
|
||||
@@ -4497,6 +4498,7 @@ __metadata:
|
||||
prettier: ^3.1.0
|
||||
pretty-quick: ^3.1.3
|
||||
react-easy-crop: ^5.0.7
|
||||
react-webcam: ^7.2.0
|
||||
universal-cookie: ^6.1.1
|
||||
yarn: ^1.22.19
|
||||
languageName: unknown
|
||||
@@ -5100,6 +5102,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/dom-mediacapture-record@npm:^1.0.19":
|
||||
version: 1.0.19
|
||||
resolution: "@types/dom-mediacapture-record@npm:1.0.19"
|
||||
checksum: 4fb7b0bb7bcc6378fa9f0cfce2e144fcc41b5df3c7842bab07f6b812084bd41c18110ed27043ab28b24e2c251233fe4ae5ab0597e6b8509fef9647b29eed2d40
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/eslint-scope@npm:^3.7.0":
|
||||
version: 3.7.3
|
||||
resolution: "@types/eslint-scope@npm:3.7.3"
|
||||
@@ -18207,6 +18216,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-webcam@npm:^7.2.0":
|
||||
version: 7.2.0
|
||||
resolution: "react-webcam@npm:7.2.0"
|
||||
peerDependencies:
|
||||
react: ">=16.2.0"
|
||||
react-dom: ">=16.2.0"
|
||||
checksum: 55aecc9e33ea711525f9b68a7c14c9cf4089777b9edd6d9c93813568d701a101f3da09ffd7df04b64eca8c9783a37830522376049589699c6015555ec8d7ccd8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react@npm:^16.13.1":
|
||||
version: 16.14.0
|
||||
resolution: "react@npm:16.14.0"
|
||||
|
||||
Reference in new issue
Block a user