mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 17:38:10 +00:00
Scene Name naming and renaming (#284)
- renaming from the TopBar is done 100% - name will appear at the inputs of the file operations as well, i.e.: when you rename in the input of the save scene dialog, it changes the name on the TopBar as well, & vice versa - !! Note: this does not help with saving and loading scene, that will be in another branch with a big fix Co-authored-by: wil <wil@storyteller.ai>
This commit is contained in:
1 parent
123724971c
commit
a522db8fef
3 files changed
+78
-25
No files matched your search
@@ -2,7 +2,7 @@ import React from "react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { IconDefinition } from "@fortawesome/pro-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { Label } from "./Typography";
|
||||
import { Label, H6 } from "./Typography";
|
||||
import { kebabCase } from "~/utilities";
|
||||
import {
|
||||
disableHotkeyInput,
|
||||
@@ -11,13 +11,16 @@ import {
|
||||
} from "~/pages/PageEnigma/store";
|
||||
|
||||
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
inputClassName ?: string,
|
||||
label?: string;
|
||||
icon?: IconDefinition;
|
||||
isError?: boolean;
|
||||
errorMessage?: string;
|
||||
}
|
||||
|
||||
export const Input = React.forwardRef(
|
||||
(
|
||||
{ label, icon, className, id, ...rest }: InputProps,
|
||||
export const Input = React.forwardRef(({
|
||||
label, icon, inputClassName, className, id, isError, errorMessage, ...rest
|
||||
} : InputProps,
|
||||
ref: React.ForwardedRef<HTMLInputElement>,
|
||||
) => {
|
||||
return (
|
||||
@@ -33,12 +36,21 @@ export const Input = React.forwardRef(
|
||||
id={id ? id : label ? kebabCase(label) : undefined}
|
||||
className={twMerge(
|
||||
"h-10 w-full rounded-md bg-brand-secondary px-3 py-2.5 text-white outline-none outline-offset-0 transition-all duration-150 ease-in-out focus:outline-brand-primary",
|
||||
icon ? "pl-12" : "",
|
||||
icon && "pl-12",
|
||||
isError && "outline-red focus:outline-red",
|
||||
inputClassName
|
||||
)}
|
||||
onFocus={() => disableHotkeyInput(DomLevels.INPUT)}
|
||||
onBlur={() => enableHotkeyInput(DomLevels.INPUT)}
|
||||
onFocus={(e: React.FocusEvent<HTMLInputElement>) => {
|
||||
if (rest.onFocus) rest.onFocus(e);
|
||||
disableHotkeyInput(DomLevels.INPUT)
|
||||
}}
|
||||
onBlur={(e: React.FocusEvent<HTMLInputElement>) => {
|
||||
if (rest.onBlur) rest.onBlur(e);
|
||||
enableHotkeyInput(DomLevels.INPUT)
|
||||
}}
|
||||
{...rest}
|
||||
/>
|
||||
{errorMessage && <H6 className="absolute text-red z-10">{errorMessage}</H6>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
import { useState } from 'react';
|
||||
import { useLocation } from "@remix-run/react";
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
|
||||
import { faChevronLeft } from "@fortawesome/pro-solid-svg-icons";
|
||||
|
||||
import { ButtonLink } from "~/components";
|
||||
|
||||
import { AuthButtons } from "./AuthButtons";
|
||||
import { sceneTitle } from "~/store";
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import {
|
||||
showErrorDialog,
|
||||
errorDialogMessage,
|
||||
errorDialogTitle,
|
||||
} from "~/pages/PageEnigma/store";
|
||||
|
||||
import { MyMoviesButton } from "~/modules/TopBar/MyMoviesButton";
|
||||
import { Input } from "~/components";
|
||||
|
||||
interface Props {
|
||||
pageName: string;
|
||||
@@ -16,7 +23,25 @@ interface Props {
|
||||
export const TopBar = ({ pageName }: Props) => {
|
||||
useSignals();
|
||||
const currentLocation = useLocation().pathname;
|
||||
|
||||
const [isValid, setIsValid] = useState<boolean>(true);
|
||||
const handleShowErrorDialog = ()=>{
|
||||
errorDialogTitle.value = "Error";
|
||||
errorDialogMessage.value = "Scene name can not be empty.";
|
||||
showErrorDialog.value = true;
|
||||
};
|
||||
const handleChangeSceneTitle = (e: React.ChangeEvent<HTMLInputElement>)=>{
|
||||
sceneTitle.value = e.target.value;
|
||||
if (sceneTitle.value !== "") {
|
||||
setIsValid(true);
|
||||
}
|
||||
}
|
||||
const validateSceneTitle = (e: React.FocusEvent<HTMLInputElement>)=>{
|
||||
if (sceneTitle.value === "") {
|
||||
setIsValid(false);
|
||||
handleShowErrorDialog();
|
||||
e.target.focus();
|
||||
}
|
||||
}
|
||||
return (
|
||||
<header className="fixed left-0 top-0 w-full border-b border-ui-panel-border bg-ui-panel">
|
||||
<nav
|
||||
@@ -38,12 +63,17 @@ export const TopBar = ({ pageName }: Props) => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-center font-medium">
|
||||
<span className="opacity-60">{pageName} /</span>
|
||||
|
||||
{sceneTitle.value}
|
||||
|
||||
<span className="opacity-60">@ CURRENT_STORYTELLER_GIT_VERSION</span>
|
||||
<div className="flex items-center justify-center font-medium gap-2">
|
||||
<span className="opacity-60">{pageName}</span>
|
||||
<span className="opacity-60">/</span>
|
||||
<Input
|
||||
className="-ml-2"
|
||||
inputClassName="bg-ui-panel focus:bg-brand-secondary focus:ml-3"
|
||||
isError={!isValid}
|
||||
value={sceneTitle.value}
|
||||
onChange={handleChangeSceneTitle}
|
||||
onBlur={validateSceneTitle}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2.5">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useContext, useState } from "react";
|
||||
import { sceneTitle } from "~/store";
|
||||
import { ButtonDropdown, Input } from "~/components";
|
||||
import { ButtonDialogue } from "~/modules/ButtonDialogue";
|
||||
import { EngineContext } from "~/contexts/EngineContext";
|
||||
@@ -18,8 +19,10 @@ export const ControlsTopButtons = () => {
|
||||
const { addToast } = useContext(ToasterContext);
|
||||
|
||||
const handleButtonSave = async () => {
|
||||
console.log(`SceneName is ${sceneName}`);
|
||||
const sceneMediaToken = await editorEngine?.saveScene(sceneName);
|
||||
// console.log(`SceneName is ${sceneName}`);
|
||||
// const sceneMediaToken = await editorEngine?.saveScene(sceneName);
|
||||
console.log(`SceneName is ${sceneTitle.value}`);
|
||||
const sceneMediaToken = await editorEngine?.saveScene(sceneTitle.value);
|
||||
if (sceneMediaToken) {
|
||||
addToast(ToastTypes.SUCCESS, sceneMediaToken);
|
||||
}
|
||||
@@ -37,6 +40,11 @@ export const ControlsTopButtons = () => {
|
||||
console.log(`Selected Scene Token is ${token}`);
|
||||
};
|
||||
|
||||
|
||||
const handleChangeSceneTitle = (e: React.ChangeEvent<HTMLInputElement>)=>{
|
||||
sceneTitle.value = e.target.value;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2 pl-3 pt-3">
|
||||
<div className="flex gap-1.5">
|
||||
@@ -52,7 +60,6 @@ export const ControlsTopButtons = () => {
|
||||
content: (
|
||||
<Input
|
||||
label="Please enter a name for your new scene"
|
||||
value={sceneName}
|
||||
onChange={(e) => {
|
||||
setSceneName(e.target.value);
|
||||
}}
|
||||
@@ -117,10 +124,12 @@ export const ControlsTopButtons = () => {
|
||||
title: "Save Scene",
|
||||
content: (
|
||||
<Input
|
||||
value={sceneTitle.value}
|
||||
label="Please enter a name for your scene"
|
||||
onChange={(e) => {
|
||||
setSceneName(e.target.value);
|
||||
}}
|
||||
// onChange={(e) => {
|
||||
// setSceneName(e.target.value);
|
||||
// }}
|
||||
onChange={handleChangeSceneTitle}
|
||||
/>
|
||||
),
|
||||
confirmButtonProps: {
|
||||
@@ -142,10 +151,12 @@ export const ControlsTopButtons = () => {
|
||||
title: "Save Scene as Copy",
|
||||
content: (
|
||||
<Input
|
||||
value={sceneTitle.value}
|
||||
label="Please enter a name for your scene"
|
||||
onChange={(e) => {
|
||||
setSceneName(e.target.value);
|
||||
}}
|
||||
// onChange={(e) => {
|
||||
// setSceneName(e.target.value);
|
||||
// }}
|
||||
onChange={handleChangeSceneTitle}
|
||||
/>
|
||||
),
|
||||
confirmButtonProps: {
|
||||
|
||||
Reference in new issue
Block a user