mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-30 05:22:51 -04:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e44c679a25 |
@@ -17,7 +17,6 @@ import {
|
||||
faVideo,
|
||||
faWandMagicSparkles,
|
||||
faArrowRotateRight,
|
||||
faWaveformLines,
|
||||
} from "@fortawesome/pro-solid-svg-icons";
|
||||
import { MediaFileDelete } from "@storyteller/tauri-api";
|
||||
import { LoadingSpinner } from "@storyteller/ui-loading-spinner";
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
Model,
|
||||
VIDEO_MODELS,
|
||||
IMAGE_MODELS,
|
||||
IMAGE_MODELS_BY_ID,
|
||||
SPLAT_MODELS,
|
||||
OBJECT_3D_MODELS,
|
||||
} from "@storyteller/model-list";
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useEffect, useMemo } from "react";
|
||||
import { PopoverMenu, type PopoverItem } from "@storyteller/ui-popover";
|
||||
import { ModelPage } from "./model-pages";
|
||||
import { Model } from "@storyteller/model-list";
|
||||
import { Provider } from "@storyteller/tauri-api";
|
||||
import { GenerationProvider } from "@storyteller/api-enums";
|
||||
import { getProviderDisplayName, getProviderIcon } from "./provider-icons";
|
||||
import {
|
||||
useClassyModelSelectorStore,
|
||||
@@ -16,17 +16,17 @@ import {
|
||||
interface ProviderSelectorProps {
|
||||
page: ModelPage;
|
||||
model: Model | undefined;
|
||||
providersByModel?: Partial<Record<string, Provider[]>>;
|
||||
providersByModel?: Partial<Record<string, GenerationProvider[]>>;
|
||||
panelTitle?: string;
|
||||
buttonClassName?: string;
|
||||
panelClassName?: string;
|
||||
triggerLabel?: string;
|
||||
}
|
||||
|
||||
const DEFAULT_PROVIDER_OPTIONS: Provider[] = [
|
||||
Provider.ArtCraft,
|
||||
Provider.Fal,
|
||||
Provider.Sora,
|
||||
const DEFAULT_PROVIDER_OPTIONS: GenerationProvider[] = [
|
||||
GenerationProvider.Artcraft,
|
||||
GenerationProvider.Fal,
|
||||
GenerationProvider.Sora,
|
||||
];
|
||||
|
||||
export function ProviderSelector({
|
||||
@@ -38,7 +38,7 @@ export function ProviderSelector({
|
||||
const { setSelectedProvider } = useClassyModelSelectorStore();
|
||||
|
||||
const modelId = model?.id;
|
||||
const allowedProviders: Provider[] = useMemo(() => {
|
||||
const allowedProviders: GenerationProvider[] = useMemo(() => {
|
||||
if (!modelId) return DEFAULT_PROVIDER_OPTIONS;
|
||||
return providersByModel?.[modelId] ?? DEFAULT_PROVIDER_OPTIONS;
|
||||
}, [providersByModel, modelId]);
|
||||
@@ -74,8 +74,8 @@ export function ProviderSelector({
|
||||
|
||||
const handleSelect = (item: PopoverItem) => {
|
||||
if (!modelId) return;
|
||||
const prov: Provider | undefined = (item as any).provider as
|
||||
| Provider
|
||||
const prov: GenerationProvider | undefined = (item as any).provider as
|
||||
| GenerationProvider
|
||||
| undefined;
|
||||
if (!prov) return;
|
||||
setSelectedProvider(page, modelId, prov);
|
||||
|
||||
@@ -173,7 +173,3 @@ export class Node {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function generateId(): string {
|
||||
return `node-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ function DragScrubButton({
|
||||
interface Edit3DScrubControlsProps {
|
||||
nodeId: string;
|
||||
stageRef: { current: Konva.Stage };
|
||||
overlayHandle: React.RefObject<Model3DOverlayHandle>;
|
||||
overlayHandle: React.RefObject<Model3DOverlayHandle | null>;
|
||||
}
|
||||
|
||||
const Edit3DScrubControls = memo(function Edit3DScrubControls({
|
||||
@@ -351,7 +351,6 @@ const PageDraw = ({ adapter }: PageDrawProps) => {
|
||||
historyImageBundles,
|
||||
pendingGenerations,
|
||||
getAspectRatioDimensions,
|
||||
finishRemoveBackground,
|
||||
createImageFromUrl,
|
||||
createImageFromFile,
|
||||
createImageFrom3DModel,
|
||||
@@ -361,7 +360,6 @@ const PageDraw = ({ adapter }: PageDrawProps) => {
|
||||
removeHistoryImage,
|
||||
addHistoryImageBundle,
|
||||
addPendingGeneration,
|
||||
resolvePendingGeneration,
|
||||
removePendingGeneration,
|
||||
clearPendingGenerations,
|
||||
setAspectRatioType,
|
||||
@@ -391,8 +389,6 @@ const PageDraw = ({ adapter }: PageDrawProps) => {
|
||||
(state) => state.setGenerationCount,
|
||||
);
|
||||
const useSystemPrompt = promptStoreProvider((state) => state.useSystemPrompt);
|
||||
const referenceImages = promptStoreProvider((state) => state.referenceImages);
|
||||
const prompt = promptStoreProvider((state) => state.prompt);
|
||||
|
||||
const baseImageKonvaRef = useRef<Konva.Image>({} as Konva.Image);
|
||||
const baseImageUrl = baseImageInfo?.url;
|
||||
@@ -524,13 +520,13 @@ const PageDraw = ({ adapter }: PageDrawProps) => {
|
||||
|
||||
window.addEventListener(
|
||||
"gallery-2d-drop",
|
||||
handleGallery2DDrop as EventListener,
|
||||
handleGallery2DDrop as unknown as EventListener,
|
||||
);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener(
|
||||
"gallery-2d-drop",
|
||||
handleGallery2DDrop as EventListener,
|
||||
handleGallery2DDrop as unknown as EventListener,
|
||||
);
|
||||
};
|
||||
}, [createImageFromUrl, createImageFrom3DModel]);
|
||||
|
||||
@@ -15,12 +15,10 @@ import {
|
||||
Line,
|
||||
Image,
|
||||
Transformer,
|
||||
Group,
|
||||
} from "react-konva";
|
||||
import Konva from "konva";
|
||||
import { LineNode, SceneState, useSceneStore } from "./stores/SceneState";
|
||||
import { Node } from "./Node";
|
||||
import { useStageSnapshot } from "./hooks/useUpdateSnapshot";
|
||||
import "./pagedraw.css";
|
||||
import SplitPane from "./components/ui/SplitPane";
|
||||
import { useRightPanelLayoutManagement } from "./hooks/useRightPanelLayoutManagement";
|
||||
|
||||
@@ -4,10 +4,6 @@ import { ImageStyleSelectorProps } from './types';
|
||||
const ImageStyleSelector: React.FC<ImageStyleSelectorProps> = ({ onImageSelect }) => {
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const handleClick = () => {
|
||||
fileInputRef.current?.click();
|
||||
};
|
||||
|
||||
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const files = e.target.files;
|
||||
if (files && files.length > 0) {
|
||||
|
||||
@@ -2,7 +2,6 @@ import React, { useState, useRef, useEffect } from "react";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import {
|
||||
faMousePointer,
|
||||
faTrash,
|
||||
faEyeDropper,
|
||||
faImage,
|
||||
faUndo,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Vector2d } from "konva/lib/types";
|
||||
import { useEffect } from "react";
|
||||
import { DragState } from "../types";
|
||||
// This piece of code ensures that when you are selecting or dragging and go off the stage,
|
||||
|
||||
+1
-1
@@ -210,7 +210,7 @@ export const ControlPanelSceneObject = () => {
|
||||
// document mouseup/keydown listeners can interact poorly with the
|
||||
// freecam pointer-capture and canvas keydown handlers).
|
||||
useEffect(() => {
|
||||
if (!isShowing) return;
|
||||
if (!isShowing) return undefined;
|
||||
const flush = () => {
|
||||
transformSessionRef.current?.commit();
|
||||
transformSessionRef.current = null;
|
||||
|
||||
@@ -151,14 +151,12 @@ export const Outliner = () => {
|
||||
}
|
||||
}
|
||||
|
||||
if (viewport.width < 2000) {
|
||||
if (camAspect === CameraAspectRatio.VERTICAL_9_16) {
|
||||
return `${editorHeight * 0.7 - 10}px`;
|
||||
} else if (camAspect === CameraAspectRatio.SQUARE_1_1) {
|
||||
return `${editorHeight * 0.7}px`;
|
||||
} else {
|
||||
return `${editorHeight * 0.7}px`;
|
||||
}
|
||||
if (camAspect === CameraAspectRatio.VERTICAL_9_16) {
|
||||
return `${editorHeight * 0.7 - 10}px`;
|
||||
} else if (camAspect === CameraAspectRatio.SQUARE_1_1) {
|
||||
return `${editorHeight * 0.7}px`;
|
||||
} else {
|
||||
return `${editorHeight * 0.7}px`;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ export const EngineProvider = ({
|
||||
// available; callback refs in SceneContainer / EditorCanvas /
|
||||
// CameraViewCanvas drive this by setting their nodes (and clearing
|
||||
// them to null on unmount).
|
||||
if (!sceneContainer || !editorCanvas || !camViewCanvas) return;
|
||||
if (!sceneContainer || !editorCanvas || !camViewCanvas) return undefined;
|
||||
|
||||
const newEditor = new Editor(adapterRef.current);
|
||||
newEditor.initialize({
|
||||
|
||||
@@ -153,29 +153,35 @@ function removeObject3D(object3D) {
|
||||
|
||||
obj.traverse(child => {
|
||||
(child as THREE.Mesh)?.geometry?.dispose()
|
||||
if (Array.isArray((child as THREE.Mesh).texture)) {
|
||||
(child as THREE.Mesh).texture.forEach(mat => mat.dispose());
|
||||
} else if ((child as THREE.Mesh).texture) {
|
||||
(child as THREE.Mesh).texture.dispose();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const childTexture = (child as any).texture;
|
||||
if (Array.isArray(childTexture)) {
|
||||
childTexture.forEach(mat => mat.dispose());
|
||||
} else if (childTexture) {
|
||||
childTexture.dispose();
|
||||
}
|
||||
|
||||
if (Array.isArray((child as THREE.Mesh).material)) {
|
||||
(child as THREE.Mesh).material.forEach(mat => mat.dispose());
|
||||
} else if ((child as THREE.Mesh).material) {
|
||||
(child as THREE.Mesh).material.dispose();
|
||||
const childMaterial = (child as THREE.Mesh).material;
|
||||
if (Array.isArray(childMaterial)) {
|
||||
childMaterial.forEach(mat => mat.dispose());
|
||||
} else if (childMaterial) {
|
||||
childMaterial.dispose();
|
||||
}
|
||||
})
|
||||
|
||||
if (Array.isArray((obj as THREE.Mesh).texture)) {
|
||||
(obj as THREE.Mesh).texture.forEach(mat => mat.dispose());
|
||||
} else if ((obj as THREE.Mesh).texture) {
|
||||
(obj as THREE.Mesh).texture.dispose();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const objTexture = (obj as any).texture;
|
||||
if (Array.isArray(objTexture)) {
|
||||
objTexture.forEach(mat => mat.dispose());
|
||||
} else if (objTexture) {
|
||||
objTexture.dispose();
|
||||
}
|
||||
|
||||
if (Array.isArray((obj as THREE.Mesh).material)) {
|
||||
(obj as THREE.Mesh).material.forEach(mat => mat.dispose());
|
||||
} else if ((obj as THREE.Mesh).material) {
|
||||
(obj as THREE.Mesh).material.dispose();
|
||||
const objMaterial = (obj as THREE.Mesh).material;
|
||||
if (Array.isArray(objMaterial)) {
|
||||
objMaterial.forEach(mat => mat.dispose());
|
||||
} else if (objMaterial) {
|
||||
objMaterial.dispose();
|
||||
}
|
||||
|
||||
if ((obj as THREE.Mesh).geometry) {
|
||||
|
||||
@@ -399,7 +399,8 @@ export class MouseControls {
|
||||
event.preventDefault();
|
||||
this.isProcessing = true;
|
||||
try {
|
||||
await this.sceneManager?.undo();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
await (this.sceneManager as any)?.undo();
|
||||
} finally {
|
||||
this.isProcessing = false;
|
||||
}
|
||||
@@ -408,7 +409,8 @@ export class MouseControls {
|
||||
event.preventDefault();
|
||||
this.isProcessing = true;
|
||||
try {
|
||||
await this.sceneManager?.redo();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
await (this.sceneManager as any)?.redo();
|
||||
} finally {
|
||||
this.isProcessing = false;
|
||||
}
|
||||
@@ -417,7 +419,8 @@ export class MouseControls {
|
||||
event.preventDefault();
|
||||
this.isProcessing = true;
|
||||
try {
|
||||
await this.sceneManager?.redo();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
await (this.sceneManager as any)?.redo();
|
||||
} finally {
|
||||
this.isProcessing = false;
|
||||
}
|
||||
|
||||
@@ -372,7 +372,7 @@ class Scene {
|
||||
);
|
||||
if (obj_keyframe_uuid === keyframe_uuid) {
|
||||
keyframe_point = object;
|
||||
return object;
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -611,7 +611,7 @@ class Scene {
|
||||
async loadObjectFromUrl(
|
||||
url: string,
|
||||
position: THREE.Vector3 = new THREE.Vector3(-0.5, 1.5, 0),
|
||||
): Promise<THREE.Object3D> {
|
||||
): Promise<THREE.Object3D | undefined> {
|
||||
console.log("loadObjectFromUrl!!!!!!!!", url);
|
||||
if (
|
||||
url.includes(".png") ||
|
||||
@@ -628,6 +628,7 @@ class Scene {
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async loadObject(
|
||||
@@ -910,8 +911,8 @@ class Scene {
|
||||
media_url: string,
|
||||
onComplete: () => void,
|
||||
signal?: AbortSignal,
|
||||
) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
): Promise<GLTF> {
|
||||
return new Promise<GLTF>(async (resolve, reject) => {
|
||||
let buffer;
|
||||
try {
|
||||
// Host-supplied CORS-bypassed binary fetch (FetchProxy under
|
||||
|
||||
@@ -92,6 +92,7 @@ export class SceneManager implements SceneManagerAPI {
|
||||
} else {
|
||||
return this.scene.instantiate(name, position);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateSkybox(media_id: string) {
|
||||
|
||||
@@ -89,7 +89,7 @@ export const useFreeCam = (
|
||||
|
||||
// Hand the state to the editor so its render loop can integrate it.
|
||||
useEffect(() => {
|
||||
if (!editor) return;
|
||||
if (!editor) return undefined;
|
||||
editor.cameraController.setFreeCamState(stateRef.current);
|
||||
return () => editor.cameraController.setFreeCamState(null);
|
||||
}, [editor]);
|
||||
@@ -98,7 +98,7 @@ export const useFreeCam = (
|
||||
// inside the viewport); keys on document so the user doesn't need
|
||||
// to click canvas first for WASD to work.
|
||||
useEffect(() => {
|
||||
if (!canvas || !editor) return;
|
||||
if (!canvas || !editor) return undefined;
|
||||
const state = stateRef.current;
|
||||
state.enabled = true;
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ export const useViewportKeyboard = (editor: Editor | null) => {
|
||||
const bindings = useMemo(() => buildKeymap(), []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!editor) return;
|
||||
if (!editor) return undefined;
|
||||
|
||||
const onKeyDown = (event: KeyboardEvent) => {
|
||||
if (isEventFromEditableElement(event)) return;
|
||||
|
||||
@@ -25,7 +25,7 @@ export const useViewportPointer = (
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!canvas || !editor) return;
|
||||
if (!canvas || !editor) return undefined;
|
||||
|
||||
const onPointerMove = (e: PointerEvent) => {
|
||||
if (!editor.mouse) return;
|
||||
|
||||
@@ -18,7 +18,7 @@ export const useViewportSize = (): { width: number; height: number } => {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === "undefined") return;
|
||||
if (typeof window === "undefined") return undefined;
|
||||
const onResize = () => {
|
||||
setSize(
|
||||
adapterGet?.() ?? {
|
||||
|
||||
@@ -22,6 +22,10 @@ export interface ObjectJSON {
|
||||
object_uuid: string;
|
||||
object_user_data_name: string;
|
||||
media_file_token: string;
|
||||
// Legacy top-level field. Not written by toJSON() (the value is
|
||||
// carried inside user_data.media_file_type); kept optional so reads
|
||||
// that reference it directly type-check without changing behavior.
|
||||
media_file_type?: MediaFileType;
|
||||
color: string;
|
||||
metalness: number;
|
||||
shininess: number;
|
||||
|
||||
@@ -96,7 +96,6 @@ export function CostBreakdownModal({ activeTabId }: CostBreakdownModalProps) {
|
||||
const {
|
||||
currency,
|
||||
setCurrency,
|
||||
currencyOption,
|
||||
formatPrice,
|
||||
currencyOptions,
|
||||
} = useCurrency();
|
||||
|
||||
@@ -547,7 +547,7 @@ export const PromptBox3D = ({
|
||||
};
|
||||
|
||||
const getCurrentAspectRatio = (): CommonAspectRatio => {
|
||||
switch (cameraAspectRatio.value) {
|
||||
switch (cameraAspectRatio) {
|
||||
case CameraAspectRatio.HORIZONTAL_3_2:
|
||||
return CommonAspectRatio.Wide;
|
||||
case CameraAspectRatio.VERTICAL_2_3:
|
||||
|
||||
@@ -5,8 +5,6 @@ import {
|
||||
} from "@fortawesome/pro-regular-svg-icons";
|
||||
import {
|
||||
faEdit,
|
||||
faMessageCheck,
|
||||
faMessageXmark,
|
||||
faMousePointer,
|
||||
faFrame,
|
||||
faPen,
|
||||
@@ -19,7 +17,7 @@ import {
|
||||
faChevronUp,
|
||||
} from "@fortawesome/pro-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { Button, ToggleButton, GenerateButton } from "@storyteller/ui-button";
|
||||
import { Button, GenerateButton } from "@storyteller/ui-button";
|
||||
import { ButtonIconSelect } from "@storyteller/ui-button-icon-select";
|
||||
import { PopoverMenu, PopoverItem } from "@storyteller/ui-popover";
|
||||
import { Tooltip } from "@storyteller/ui-tooltip";
|
||||
@@ -83,7 +81,6 @@ export const PromptBoxEdit = ({
|
||||
credits,
|
||||
}: PromptBoxEditProps) => {
|
||||
const [prompt, setPrompt] = useState("");
|
||||
const [useSystemPrompt, setUseSystemPrompt] = useState(true);
|
||||
const [isFocused, setIsFocused] = useState(false);
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
|
||||
|
||||
@@ -11,17 +11,17 @@ interface State {
|
||||
}
|
||||
|
||||
export class PromptBoxErrorBoundary extends Component<Props, State> {
|
||||
state: State = { hasError: false, resetKey: 0 };
|
||||
override state: State = { hasError: false, resetKey: 0 };
|
||||
|
||||
static getDerivedStateFromError(): Partial<State> {
|
||||
return { hasError: true };
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, info: ErrorInfo) {
|
||||
override componentDidCatch(error: Error, info: ErrorInfo) {
|
||||
console.error("PromptBox crashed:", error, info.componentStack);
|
||||
}
|
||||
|
||||
render() {
|
||||
override render() {
|
||||
if (this.state.hasError) {
|
||||
return (
|
||||
<div className="flex items-center justify-center rounded-xl border border-red-500/30 bg-red-500/10 px-6 py-4 text-sm text-red-300">
|
||||
|
||||
@@ -4,18 +4,16 @@ import { JobContextType, UploaderState } from "@storyteller/common";
|
||||
import { toast } from "@storyteller/ui-toaster";
|
||||
import { PopoverMenu, PopoverItem } from "@storyteller/ui-popover";
|
||||
import { Tooltip } from "@storyteller/ui-tooltip";
|
||||
import { Button, ToggleButton, GenerateButton } from "@storyteller/ui-button";
|
||||
import { Button, GenerateButton } from "@storyteller/ui-button";
|
||||
import { Modal } from "@storyteller/ui-modal";
|
||||
import { GenerateImage, GenerateImageRequest } from "@storyteller/tauri-api";
|
||||
import {
|
||||
faMessageXmark,
|
||||
faMessageCheck,
|
||||
faExpand,
|
||||
faChevronDown,
|
||||
faChevronUp,
|
||||
} from "@fortawesome/pro-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { CommonAspectRatio, ImageModel } from "@storyteller/model-list";
|
||||
import { ImageModel } from "@storyteller/model-list";
|
||||
import {
|
||||
usePromptImageStore,
|
||||
RefImage,
|
||||
@@ -30,7 +28,6 @@ import { AspectRatioIcon } from "./common/AspectRatioIcon";
|
||||
import { GenerationCountPicker } from "./common/GenerationCountPicker";
|
||||
import { ResolutionPicker } from "./common/ResolutionPicker";
|
||||
import { QualityPicker } from "./common/QualityPicker";
|
||||
import { CommonResolution } from "@storyteller/model-list";
|
||||
|
||||
interface PromptBoxImageProps {
|
||||
useJobContext: () => JobContextType;
|
||||
@@ -96,8 +93,6 @@ export const PromptBoxImage = ({
|
||||
|
||||
const prompt = usePromptImageStore((s) => s.prompt);
|
||||
const setPrompt = usePromptImageStore((s) => s.setPrompt);
|
||||
const useSystemPrompt = usePromptImageStore((s) => s.useSystemPrompt);
|
||||
const setUseSystemPrompt = usePromptImageStore((s) => s.setUseSystemPrompt);
|
||||
const aspectRatio = usePromptImageStore((s) => s.aspectRatio);
|
||||
const setAspectRatio = usePromptImageStore((s) => s.setAspectRatio);
|
||||
const resolution = usePromptImageStore((s) => s.resolution);
|
||||
|
||||
@@ -274,7 +274,7 @@ export const PromptBoxVideo = ({
|
||||
aspectRatioOptions = buildAspectRatioOptions(DEFAULT_RESOLUTIONS);
|
||||
}
|
||||
|
||||
const [aspectRatioList, setAspectRatioList] =
|
||||
const [, setAspectRatioList] =
|
||||
useState<PopoverItem[]>(aspectRatioOptions);
|
||||
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
|
||||
@@ -349,8 +349,8 @@ export const UploadFiles3D = ({
|
||||
{selectionError && <h6 className="z-10 text-red">{selectionError}</h6>}
|
||||
|
||||
{isMulti ? (
|
||||
<PanelGroup orientation="horizontal">
|
||||
<Panel defaultSize="33%" minSize="20%">
|
||||
<PanelGroup direction="horizontal">
|
||||
<Panel defaultSize={33} minSize={20}>
|
||||
<ul className="flex h-full flex-col gap-1 overflow-y-auto rounded-lg bg-brand-secondary p-2">
|
||||
{fileEntries.map((entry, i) => (
|
||||
<li
|
||||
@@ -412,11 +412,14 @@ export const UploadFiles3D = ({
|
||||
</ul>
|
||||
</Panel>
|
||||
|
||||
<PanelResizeHandle className="flex w-4 items-center justify-center" onPointerDown={(e) => e.stopPropagation()}>
|
||||
<div className="h-8 w-1 rounded-full bg-white/20 transition-colors hover:bg-white/40" />
|
||||
<PanelResizeHandle className="flex w-4 items-center justify-center">
|
||||
<div
|
||||
className="h-8 w-1 rounded-full bg-white/20 transition-colors hover:bg-white/40"
|
||||
onPointerDown={(e) => e.stopPropagation()}
|
||||
/>
|
||||
</PanelResizeHandle>
|
||||
|
||||
<Panel defaultSize="67%" minSize="25%">
|
||||
<Panel defaultSize={67} minSize={25}>
|
||||
<div className="flex h-full flex-col gap-2">
|
||||
<div className="relative w-full min-h-48 overflow-hidden rounded-lg bg-brand-secondary">
|
||||
<canvas
|
||||
|
||||
@@ -211,8 +211,8 @@ export const UploadFilesImage = ({
|
||||
|
||||
{fileEntries.length > 0 && (
|
||||
isMulti ? (
|
||||
<PanelGroup orientation="horizontal">
|
||||
<Panel defaultSize="33%" minSize="20%">
|
||||
<PanelGroup direction="horizontal">
|
||||
<Panel defaultSize={33} minSize={20}>
|
||||
<ul className="flex h-full flex-col gap-1 overflow-y-auto rounded-lg bg-brand-secondary p-2">
|
||||
{fileEntries.map((entry, i) => (
|
||||
<li
|
||||
@@ -274,11 +274,14 @@ export const UploadFilesImage = ({
|
||||
</ul>
|
||||
</Panel>
|
||||
|
||||
<PanelResizeHandle className="flex w-4 items-center justify-center" onPointerDown={(e) => e.stopPropagation()}>
|
||||
<div className="h-8 w-1 rounded-full bg-white/20 transition-colors hover:bg-white/40" />
|
||||
<PanelResizeHandle className="flex w-4 items-center justify-center">
|
||||
<div
|
||||
className="h-8 w-1 rounded-full bg-white/20 transition-colors hover:bg-white/40"
|
||||
onPointerDown={(e) => e.stopPropagation()}
|
||||
/>
|
||||
</PanelResizeHandle>
|
||||
|
||||
<Panel defaultSize="67%" minSize="25%">
|
||||
<Panel defaultSize={67} minSize={25}>
|
||||
<div className="flex h-full flex-col gap-2">
|
||||
<div className="relative aspect-square w-full overflow-hidden rounded-lg bg-brand-secondary flex items-center justify-center">
|
||||
{previewUrl && (
|
||||
|
||||
@@ -339,8 +339,8 @@ export const UploadFilesSplat = ({
|
||||
)}
|
||||
|
||||
{isMulti ? (
|
||||
<PanelGroup orientation="horizontal">
|
||||
<Panel defaultSize="33%" minSize="20%">
|
||||
<PanelGroup direction="horizontal">
|
||||
<Panel defaultSize={33} minSize={20}>
|
||||
<ul className="flex h-full flex-col gap-1 overflow-y-auto rounded-lg bg-brand-secondary p-2">
|
||||
{fileEntries.map((entry, i) => (
|
||||
<li
|
||||
@@ -399,11 +399,14 @@ export const UploadFilesSplat = ({
|
||||
</ul>
|
||||
</Panel>
|
||||
|
||||
<PanelResizeHandle className="flex w-4 items-center justify-center" onPointerDown={(e) => e.stopPropagation()}>
|
||||
<div className="h-8 w-1 rounded-full bg-white/20 transition-colors hover:bg-white/40" />
|
||||
<PanelResizeHandle className="flex w-4 items-center justify-center">
|
||||
<div
|
||||
className="h-8 w-1 rounded-full bg-white/20 transition-colors hover:bg-white/40"
|
||||
onPointerDown={(e) => e.stopPropagation()}
|
||||
/>
|
||||
</PanelResizeHandle>
|
||||
|
||||
<Panel defaultSize="67%" minSize="25%">
|
||||
<Panel defaultSize={67} minSize={25}>
|
||||
<div className="flex h-full flex-col gap-2">
|
||||
<div className="relative w-full min-h-48 overflow-hidden rounded-lg bg-brand-secondary">
|
||||
<canvas
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export * from './lib/subscription-plan-details';
|
||||
export * from './lib/subscription-plans';
|
||||
export * from './lib/subscription-state';
|
||||
export * from './lib/subscription-plan-details.js';
|
||||
export * from './lib/subscription-plans.js';
|
||||
export * from './lib/subscription-state.js';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user