mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 17:38:10 +00:00
Merge branch 'test' into feature/fps-fix
This commit is contained in:
34 files changed
+517
-434
No files matched your search
+7
-1
@@ -1,3 +1,9 @@
|
||||
{
|
||||
"plugins": ["prettier-plugin-tailwindcss"]
|
||||
"plugins": ["prettier-plugin-tailwindcss"],
|
||||
"semi": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "all",
|
||||
"bracketSpacing": true,
|
||||
"bracketSameLine": true,
|
||||
"arrowParens": "always"
|
||||
}
|
||||
@@ -1,3 +1,25 @@
|
||||
```
|
||||
Short Style Guide TS React and Engine:
|
||||
|
||||
No use of lets
|
||||
|
||||
No basic for loop operators.
|
||||
Use the collection operators and array operators.
|
||||
|
||||
React Side / No modules over 200 lines. ( loose rule )
|
||||
|
||||
Don't do:
|
||||
if (condition) return;
|
||||
|
||||
Do:
|
||||
if (condition) {
|
||||
return;
|
||||
}
|
||||
|
||||
No use of any type.
|
||||
If you can use chat gpt to create the interface.
|
||||
```
|
||||
|
||||
# IF YOU ARE WORKING ON THIS PROJECT PLEASE ASK THE TEAM MEMBERS HOW TO SET UP THIS IS OUTDATED INFORMATION
|
||||
# GottaGoFast-SS
|
||||
Fast Prototyping with Better Netlify Pipeline:
|
||||
|
||||
@@ -6,32 +6,23 @@ import { kebabCase } from "~/utilities";
|
||||
|
||||
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
label?: string;
|
||||
icon?: IconDefinition
|
||||
icon?: IconDefinition;
|
||||
}
|
||||
|
||||
export function Input({
|
||||
label, icon, className, id, ...rest
|
||||
}: InputProps) {
|
||||
export function Input({ label, icon, className, id, ...rest }: InputProps) {
|
||||
return (
|
||||
<div className={twMerge("flex flex-col gap-2", className)}>
|
||||
{label &&
|
||||
<Label htmlFor={id ? id : kebabCase(label)}>
|
||||
{label}
|
||||
</Label>
|
||||
}
|
||||
{label && <Label htmlFor={id ? id : kebabCase(label)}>{label}</Label>}
|
||||
|
||||
<div className="relative w-full">
|
||||
{icon && (
|
||||
<FontAwesomeIcon
|
||||
icon={icon}
|
||||
className="absolute pt-2.5 pl-3 h-5"
|
||||
/>
|
||||
<FontAwesomeIcon icon={icon} className="absolute h-5 pl-3 pt-2.5" />
|
||||
)}
|
||||
<input
|
||||
id={id ? id : (label ? kebabCase(label) : undefined)}
|
||||
id={id ? id : label ? kebabCase(label) : undefined}
|
||||
className={twMerge(
|
||||
"w-full h-10 rounded-md bg-brand-secondary p-3 text-white transition-all duration-150 ease-in-out outline-none outline-offset-0 focus:outline-brand-primary",
|
||||
icon? "pl-12" : "",
|
||||
"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" : "",
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
|
||||
@@ -30,7 +30,7 @@ export const ItemPicker = ({
|
||||
>
|
||||
<img className="aspect-square" {...imgProps} alt="style" />
|
||||
<div className="absolute left-0 top-0 h-full w-full bg-gradient-to-t from-gray-700" />
|
||||
<H4 className="absolute bottom-[1px] left-[6px] text-sm drop-shadow-md">
|
||||
<H4 className="absolute bottom-[1px] left-[6px] text-start text-sm drop-shadow-md">
|
||||
{label}
|
||||
</H4>
|
||||
</button>
|
||||
|
||||
@@ -30,7 +30,7 @@ export const Textarea = ({
|
||||
<textarea
|
||||
id={id ? id : label ? kebabCase(label) : undefined}
|
||||
className={twMerge(
|
||||
"rounded-lg border border-ui-panel-border bg-ui-controls p-3",
|
||||
"rounded-lg border border-ui-panel-border bg-ui-controls px-3 py-2",
|
||||
className,
|
||||
)}
|
||||
style={{
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
import {
|
||||
createContext,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useState,
|
||||
ReactNode,
|
||||
Dispatch,
|
||||
SetStateAction
|
||||
} from "react";
|
||||
import { useCookies } from 'react-cookie';
|
||||
|
||||
import {
|
||||
SessionResponse,
|
||||
AuthState,
|
||||
STORAGE_KEYS
|
||||
} from "./types";
|
||||
|
||||
import { CreateSession, DestroySession, GetSession } from "./utilities";
|
||||
|
||||
export const AuthenticationContext = createContext<{
|
||||
authState: AuthState,
|
||||
setAuthState?: Dispatch<SetStateAction<AuthState>>,
|
||||
loginAndGetUserInfo?: (
|
||||
usernameOrEmail: string,
|
||||
password:string,
|
||||
failureCallback?:()=>void
|
||||
)=>void;
|
||||
logout?: ()=>void;
|
||||
}>({
|
||||
authState:{}
|
||||
});
|
||||
|
||||
export const AuthenticationProvider = ({children}:{children:ReactNode})=>{
|
||||
// console.log('auth provider rerender');
|
||||
const [, setAuthCookie, removeAuthCookie] = useCookies([STORAGE_KEYS.USER_INFO]);
|
||||
const [authState, setAuthState] = useState<AuthState>({});
|
||||
|
||||
const loginAndGetUserInfo = useCallback((
|
||||
usernameOrEmail: string,
|
||||
password:string,
|
||||
failureCallback?:()=>void
|
||||
)=>{
|
||||
CreateSession({usernameOrEmail, password})
|
||||
.then((respond)=>{
|
||||
GetSession().then((
|
||||
res: SessionResponse
|
||||
)=>{
|
||||
if(res.success && res.user && setAuthState){
|
||||
setAuthState({
|
||||
isLoggedIn: true,
|
||||
sessionData: JSON.stringify(res.user),
|
||||
userInfo: res.user
|
||||
});
|
||||
}else{
|
||||
if(failureCallback) failureCallback();
|
||||
}
|
||||
});
|
||||
});
|
||||
},[]);
|
||||
|
||||
const setLogoutState = useCallback(()=>{
|
||||
setAuthState({
|
||||
isLoggedIn: false,
|
||||
sessionData: null,
|
||||
userInfo: undefined
|
||||
});
|
||||
},[]);
|
||||
|
||||
const logout = useCallback(()=>{
|
||||
DestroySession().then((res)=>{
|
||||
if (res) setLogoutState();
|
||||
});
|
||||
},[]);
|
||||
|
||||
//Set Session upon Auth State Changes
|
||||
useEffect(()=>{
|
||||
//On First Load
|
||||
if(authState.isLoggedIn === undefined){
|
||||
//Persist Login if Session Data exist
|
||||
const sessionData = localStorage.getItem(STORAGE_KEYS.USER_INFO);
|
||||
// console.log(`Session Data: ${sessionData?.substring(0, 30)}${sessionData ? '...':''}`);
|
||||
if (sessionData !== null){
|
||||
// console.log('Getting session to persist login');
|
||||
GetSession().then((
|
||||
res: SessionResponse
|
||||
)=>{
|
||||
// console.log('Session Returned');
|
||||
// console.log(res);
|
||||
if(res.success && res.user){
|
||||
// console.log('Setting Auth State');
|
||||
setAuthState({
|
||||
isLoggedIn: true,
|
||||
sessionData: JSON.stringify(res.user),
|
||||
userInfo: res.user
|
||||
});
|
||||
}else{
|
||||
// console.log('Session expired, setting State');
|
||||
setLogoutState();
|
||||
}
|
||||
});
|
||||
}else{
|
||||
setLogoutState();
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate session data to localstorage
|
||||
if(authState.sessionData !== null && authState.sessionData !== undefined){
|
||||
localStorage.setItem(STORAGE_KEYS.USER_INFO, authState.sessionData);
|
||||
setAuthCookie(STORAGE_KEYS.USER_INFO, authState.userInfo);
|
||||
}
|
||||
// Propagate Logout
|
||||
else if (authState.sessionData === null){
|
||||
localStorage.removeItem(STORAGE_KEYS.USER_INFO);
|
||||
removeAuthCookie(STORAGE_KEYS.USER_INFO);
|
||||
}
|
||||
},[authState]);
|
||||
|
||||
return(
|
||||
<AuthenticationContext.Provider value={{
|
||||
authState,
|
||||
setAuthState,
|
||||
loginAndGetUserInfo,
|
||||
logout,
|
||||
}}>
|
||||
{children}
|
||||
</AuthenticationContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { createContext, Dispatch, SetStateAction } from "react";
|
||||
import { AuthState, AUTH_STATUS } from "./types";
|
||||
|
||||
export const AuthenticationContext = createContext<{
|
||||
authState: AuthState,
|
||||
setAuthState?: Dispatch<SetStateAction<AuthState>>,
|
||||
login?: (
|
||||
usernameOrEmail: string,
|
||||
password:string,
|
||||
failureCallback?:()=>void
|
||||
)=>void;
|
||||
logout?: ()=>void;
|
||||
}>({
|
||||
authState:{
|
||||
authStatus: AUTH_STATUS.INIT
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
import { useCallback, useEffect, useState, ReactNode} from "react";
|
||||
import { SessionResponse, AuthState, STORAGE_KEYS, AUTH_STATUS, UserInfo} from "./types";
|
||||
import { CreateSession, DestroySession, GetSession } from "./utilities";
|
||||
import { AuthenticationContext } from "./AuthenticationContext";
|
||||
|
||||
export const AuthenticationProvider = ({children}:{children:ReactNode})=>{
|
||||
console.log('auth provider rerender');
|
||||
|
||||
const [authState, setAuthState] = useState<AuthState>({
|
||||
authStatus: AUTH_STATUS.INIT
|
||||
});
|
||||
|
||||
const startLoggingState = useCallback(()=>{
|
||||
setAuthState({
|
||||
authStatus: AUTH_STATUS.LOGGING,
|
||||
sessionToken: undefined,
|
||||
userInfo: undefined
|
||||
});
|
||||
}, []);
|
||||
|
||||
const updateLoggingState = useCallback((sessionToken: string)=>{
|
||||
setAuthState({
|
||||
authStatus: AUTH_STATUS.LOGGING,
|
||||
sessionToken: sessionToken,
|
||||
userInfo: undefined
|
||||
});
|
||||
}, []);
|
||||
|
||||
const setLoginState = useCallback((userInfo: UserInfo)=>{
|
||||
setAuthState((curr)=>({
|
||||
...curr,
|
||||
authStatus: AUTH_STATUS.LOGGED_IN,
|
||||
userInfo: userInfo,
|
||||
}));
|
||||
}, [])
|
||||
|
||||
const setLogoutState = useCallback(()=>{
|
||||
setAuthState({
|
||||
authStatus: AUTH_STATUS.LOGGED_OUT,
|
||||
sessionToken: undefined,
|
||||
userInfo: undefined
|
||||
});
|
||||
},[]);
|
||||
|
||||
const login = useCallback((
|
||||
usernameOrEmail: string,
|
||||
password:string,
|
||||
failureCallback?:()=>void
|
||||
)=>{
|
||||
console.log('CreateSession');
|
||||
startLoggingState();
|
||||
CreateSession({usernameOrEmail, password})
|
||||
.then((loginResponse)=>{
|
||||
updateLoggingState(loginResponse.signed_session);
|
||||
GetSession(loginResponse.signed_session).then((
|
||||
sessionResponse: SessionResponse
|
||||
)=>{
|
||||
if(sessionResponse.success && sessionResponse.user && sessionResponse.user !== null){
|
||||
setLoginState(sessionResponse.user);
|
||||
}else{
|
||||
if(failureCallback) failureCallback();
|
||||
setLogoutState();
|
||||
}
|
||||
});
|
||||
});
|
||||
},[]);
|
||||
|
||||
const logout = useCallback(()=>{
|
||||
const sessionToken = localStorage.getItem(STORAGE_KEYS.SESSION_TOKEN);
|
||||
if (sessionToken !== null){
|
||||
DestroySession(sessionToken).then((res)=>{
|
||||
//TODO: error handling maybe necessary
|
||||
});}
|
||||
setLogoutState();
|
||||
},[]);
|
||||
|
||||
//Set Session upon Auth State Changes
|
||||
useEffect(()=>{
|
||||
//On First Load
|
||||
if(authState.authStatus === AUTH_STATUS.INIT){
|
||||
//Persist Login if Session Data exist
|
||||
const sessionToken = localStorage.getItem(STORAGE_KEYS.SESSION_TOKEN);
|
||||
console.log(`Session Data: ${sessionToken?.substring(0, 30)}${sessionToken ? '...':''}`);
|
||||
if (sessionToken !== null){
|
||||
console.log('Getting session to persist login');
|
||||
updateLoggingState(sessionToken);
|
||||
GetSession(sessionToken).then((
|
||||
sessionResponse: SessionResponse
|
||||
)=>{
|
||||
console.log('Session Returned');
|
||||
console.log(sessionResponse);
|
||||
if(sessionResponse.success && sessionResponse.user && sessionResponse.user !== null){
|
||||
console.log('Setting Auth State');
|
||||
setLoginState(sessionResponse.user)
|
||||
}else{
|
||||
console.log('Session expired, setting State');
|
||||
setLogoutState();
|
||||
}
|
||||
});
|
||||
}else{
|
||||
setLogoutState();
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate session data to localstorage
|
||||
if(authState.sessionToken !== null && authState.sessionToken !== undefined){
|
||||
localStorage.setItem(STORAGE_KEYS.SESSION_TOKEN, authState.sessionToken);
|
||||
}
|
||||
// Propagate Logout
|
||||
else if (authState.sessionToken === null){
|
||||
localStorage.removeItem(STORAGE_KEYS.SESSION_TOKEN);
|
||||
}
|
||||
},[authState]);
|
||||
|
||||
return(
|
||||
<AuthenticationContext.Provider value={{
|
||||
authState,
|
||||
setAuthState,
|
||||
login,
|
||||
logout,
|
||||
}}>
|
||||
{children}
|
||||
</AuthenticationContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { AuthenticationContext, AuthenticationProvider } from "./Authentication";
|
||||
import { AuthenticationContext, } from "./AuthenticationContext";
|
||||
import { AuthenticationProvider } from "./AuthenticationProvider";
|
||||
import { UserInfo, AUTH_STATUS } from "./types";
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
export enum STORAGE_KEYS{
|
||||
USER_INFO = "user_info",
|
||||
SESSION_TOKEN = "session_token",
|
||||
}
|
||||
|
||||
export enum AUTH_STATUS {
|
||||
INIT = "INIT",
|
||||
LOGGED_IN = "logged_in",
|
||||
LOGGING = "logging",
|
||||
LOGGED_OUT = "logged_out",
|
||||
}
|
||||
|
||||
export type AuthState = {
|
||||
isLoggedIn?: boolean;
|
||||
sessionData?: string | null;
|
||||
authStatus: AUTH_STATUS;
|
||||
sessionToken?: string | null;
|
||||
userInfo?: UserInfo;
|
||||
}
|
||||
export interface UserInfo {
|
||||
|
||||
@@ -21,7 +21,7 @@ export const CreateSession = async ({
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
credentials: 'include',
|
||||
// credentials: 'include',
|
||||
body: JSON.stringify(request)
|
||||
})
|
||||
.then(res => res.json())
|
||||
@@ -33,13 +33,14 @@ export const CreateSession = async ({
|
||||
};
|
||||
});
|
||||
}
|
||||
export const GetSession = async () => {
|
||||
export const GetSession = async (sessionToken:string) => {
|
||||
return await fetch(getSession, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'session': sessionToken,
|
||||
},
|
||||
credentials: 'include',
|
||||
// credentials: 'include',
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
@@ -53,13 +54,14 @@ export const GetSession = async () => {
|
||||
};
|
||||
});
|
||||
}
|
||||
export async function DestroySession() : Promise<boolean> {
|
||||
export async function DestroySession(sessionToken:string) : Promise<boolean> {
|
||||
return await fetch(logout, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'session': sessionToken,
|
||||
},
|
||||
credentials: 'include',
|
||||
// credentials: 'include',
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
|
||||
@@ -59,7 +59,7 @@ export async function GetInferenceJobStatus(jobToken:string) : Promise<GetJobSta
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
credentials: 'include',
|
||||
// credentials: 'include',
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { useContext, } from "react";
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
|
||||
import { AuthenticationContext } from "~/contexts/Authentication";
|
||||
import { AUTH_STATUS, AuthenticationContext } from "~/contexts/Authentication";
|
||||
import { Button, ButtonLink } from "~/components";
|
||||
import { DialogueInference } from "../DialogueInference";
|
||||
import { inferenceJobs } from "~/pages/PageEnigma/store/inferenceJobs";
|
||||
|
||||
export const AuthButtons = ()=>{
|
||||
useSignals();
|
||||
@@ -13,7 +12,7 @@ export const AuthButtons = ()=>{
|
||||
const handleLogout = ()=>{
|
||||
if(logout)logout();
|
||||
}
|
||||
if ( authState && authState.isLoggedIn ) {
|
||||
if ( authState && authState.authStatus === AUTH_STATUS.LOGGED_IN ) {
|
||||
return(
|
||||
<>
|
||||
<DialogueInference />
|
||||
|
||||
@@ -40,8 +40,9 @@ export const TopBar = ({ pageName }: Props) => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center">
|
||||
<span className="opacity-60">{pageName} /</span>
|
||||
<div className="flex items-center justify-center font-medium">
|
||||
<span className="opacity-60">{pageName} /</span>
|
||||
|
||||
{sceneTitle.value}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,25 +1,33 @@
|
||||
import { useContext, useEffect, ComponentType } from "react";
|
||||
import { useNavigate, useLocation } from "@remix-run/react";
|
||||
import { AuthenticationContext } from "~/contexts/Authentication";
|
||||
import { AUTH_STATUS, AuthenticationContext } from "~/contexts/Authentication";
|
||||
import { LoadingDots } from "~/components";
|
||||
|
||||
export const withProtectionRoute = <P extends {}>(Component: ComponentType<P>) => (rest:P) => {
|
||||
const { authState } = useContext(AuthenticationContext);
|
||||
if (authState.isLoggedIn === undefined ) {
|
||||
return <>waiting</>;
|
||||
}
|
||||
if (authState.isLoggedIn === false) {
|
||||
if (authState.authStatus === AUTH_STATUS.LOGGED_OUT) {
|
||||
return <RedirectToLogin />
|
||||
}
|
||||
return (
|
||||
<Component {...rest}/>
|
||||
);
|
||||
else if (authState.authStatus === AUTH_STATUS.LOGGED_IN ) {
|
||||
return (<Component {...rest}/>);
|
||||
}else {
|
||||
return(
|
||||
<div className="fixed w-full h-full flex flex-col justify-center items-center">
|
||||
<LoadingDots type="bricks" message="Checking for Authentication..."/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const RedirectToLogin = ()=>{
|
||||
const navigate = useNavigate();
|
||||
const {pathname} = useLocation();
|
||||
useEffect(()=>{
|
||||
navigate(`/login?redirect=${pathname}`);
|
||||
setTimeout(()=>navigate(`/login?redirect=${pathname}`), 2000);
|
||||
},[]);
|
||||
return <>redirecting</>
|
||||
return (
|
||||
<div className="fixed w-full h-full flex flex-col justify-center items-center">
|
||||
<LoadingDots type="bricks" message="Failed, redirecting..."/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { useContext } from "react";
|
||||
import { useParams } from "@remix-run/react";
|
||||
|
||||
import { LoadingBar, LoadingDots } from "~/components";
|
||||
import { SidePanel } from "~/modules/SidePanel";
|
||||
|
||||
@@ -5,6 +5,8 @@ import { AppUiContext } from "~/contexts/AppUiContext";
|
||||
import { EngineContext } from "~/contexts/EngineContext";
|
||||
import { PageEditor } from "~/pages/PageEnigma/PageEditor";
|
||||
import { PageStyling } from "~/pages/PageEnigma/PageStyling";
|
||||
import { useParams } from "@remix-run/react";
|
||||
|
||||
|
||||
export const PageEnigmaComponent = () => {
|
||||
useSignals();
|
||||
@@ -12,13 +14,17 @@ export const PageEnigmaComponent = () => {
|
||||
const [, dispatchAppUiState] = useContext(AppUiContext);
|
||||
const editor = useContext(EngineContext);
|
||||
const [page, setPage] = useState("edit");
|
||||
|
||||
const params = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
if (editor && editor.can_initialize && dispatchAppUiState !== null) {
|
||||
console.log("initializing Editor");
|
||||
|
||||
const sceneToken = params["sceneToken"]
|
||||
|
||||
editor.initialize({
|
||||
dispatchAppUiState,
|
||||
});
|
||||
dispatchAppUiState
|
||||
},sceneToken);
|
||||
}
|
||||
}, [editor, dispatchAppUiState]);
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faAngleLeft } from "@fortawesome/pro-solid-svg-icons";
|
||||
import { Button, Link } from "~/components";
|
||||
import {
|
||||
faAngleLeft,
|
||||
faArrowsRotate,
|
||||
faFilm,
|
||||
} from "@fortawesome/pro-solid-svg-icons";
|
||||
import { Button,LoadingBar } from "~/components";
|
||||
import { StyleSelection } from "~/pages/PageEnigma/comps/StyleSelection";
|
||||
import { LowerPanel } from "~/modules/LowerPanel";
|
||||
import { TimerGrid } from "~/pages/PageEnigma/comps/TimerGrid/TimerGrid";
|
||||
@@ -14,10 +18,11 @@ import { EngineContext } from "~/contexts/EngineContext";
|
||||
interface Props {
|
||||
setPage: (page: string) => void;
|
||||
}
|
||||
|
||||
import { AppUiContext } from "~/contexts/AppUiContext";
|
||||
export const PageStyling = ({ setPage }: Props) => {
|
||||
useSignals();
|
||||
const editorEngine = useContext(EngineContext);
|
||||
const [appUiState] = useContext(AppUiContext);
|
||||
|
||||
const generateFrame = async () => {
|
||||
await editorEngine?.generateFrame();
|
||||
@@ -30,32 +35,38 @@ export const PageStyling = ({ setPage }: Props) => {
|
||||
const switchEdit = () => {
|
||||
editorEngine?.switchEdit();
|
||||
setPage("edit");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-screen">
|
||||
<TopBar pageName="Stylization" />
|
||||
<div className="flex w-full justify-center">
|
||||
<div className="bg-ui-controls p-2">
|
||||
<div className="rounded-b-lg bg-ui-controls p-2">
|
||||
<Button variant="action" onClick={() => switchEdit()}>
|
||||
<FontAwesomeIcon icon={faAngleLeft} />
|
||||
Back to Scene
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 flex flex-col items-center gap-4">
|
||||
<div className="mt-5 flex flex-col items-center gap-6">
|
||||
<PreviewImages />
|
||||
<StyleSelection />
|
||||
</div>
|
||||
<div className="fixed bottom-0 left-0 w-full">
|
||||
<div className="flex h-[62px] w-full items-center justify-center gap-5 bg-ui-panel">
|
||||
<div>
|
||||
<Button variant="action" onClick={generateFrame}>Update Preview</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button variant="primary" onClick={generateMovie}>Generate Movie</Button>
|
||||
<div className="flex flex-col items-center">
|
||||
<StyleSelection />
|
||||
<div className="flex w-full justify-center gap-4 rounded-b-lg bg-ui-panel pb-5">
|
||||
<Button
|
||||
icon={faArrowsRotate}
|
||||
variant="action"
|
||||
onClick={generateFrame}
|
||||
>
|
||||
Update Preview
|
||||
</Button>
|
||||
<Button icon={faFilm} variant="primary" onClick={generateMovie}>
|
||||
Generate Movie
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="fixed bottom-0 left-0 w-full">
|
||||
<div className="relative flex h-[80px] w-full gap-5 border-t border-t-action-600 bg-ui-panel">
|
||||
<LowerPanel onStyle>
|
||||
<TimerGrid />
|
||||
@@ -63,6 +74,15 @@ export const PageStyling = ({ setPage }: Props) => {
|
||||
</LowerPanel>
|
||||
</div>
|
||||
</div>
|
||||
<LoadingBar
|
||||
id="editor-loading-bar"
|
||||
wrapperClassName="absolute top-0 left-0"
|
||||
innerWrapperClassName="max-w-screen-sm"
|
||||
isShowing={appUiState.showEditorLoadingBar.isShowing}
|
||||
message={appUiState.showEditorLoadingBar.message}
|
||||
label={appUiState.showEditorLoadingBar.label}
|
||||
progress={appUiState.showEditorLoadingBar.progress}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -59,9 +59,9 @@ export const Controls3D = ({ setPage }: Props) => {
|
||||
};
|
||||
|
||||
const changeStylize = () => {
|
||||
editorEngine?.switchPreview();
|
||||
editorEngine?.switchPreview();
|
||||
setPage("style");
|
||||
}
|
||||
};
|
||||
|
||||
const modes = [
|
||||
{ value: "move", icon: faArrowsUpDownLeftRight },
|
||||
@@ -73,13 +73,13 @@ export const Controls3D = ({ setPage }: Props) => {
|
||||
<div>
|
||||
<div className="flex justify-center">
|
||||
<div className="rounded-b-lg border-x border-b border-ui-panel-border bg-ui-controls p-2 text-white">
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<div className="flex items-center justify-center gap-3">
|
||||
<ButtonIconSelect
|
||||
options={modes}
|
||||
onOptionChange={handleModeChange}
|
||||
/>
|
||||
|
||||
<span className="h-4 w-0 border-l border-white/[0.15]" />
|
||||
<span className="h-6 w-0 border-l border-white/[0.2]" />
|
||||
|
||||
<Button variant="primary" onClick={() => changeStylize()}>
|
||||
Stylize <FontAwesomeIcon icon={faAngleRight} />
|
||||
|
||||
@@ -24,7 +24,7 @@ export async function GenerateTtsAudio(request: GenerateTtsAudioRequest) : Promi
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'include',
|
||||
// credentials: 'include',
|
||||
body: JSON.stringify(request),
|
||||
})
|
||||
.then(res => res.json())
|
||||
@@ -47,39 +47,4 @@ export async function GenerateTtsAudio(request: GenerateTtsAudioRequest) : Promi
|
||||
return { error: GenerateTtsAudioErrorType.UnknownError };
|
||||
});
|
||||
|
||||
// return await fetch(inferTts, {
|
||||
// method: 'POST',
|
||||
// headers: {
|
||||
// 'Accept': 'application/json',
|
||||
// 'Content-Type': 'application/json',
|
||||
// },
|
||||
// credentials: 'include',
|
||||
// body: JSON.stringify(request),
|
||||
// })
|
||||
// .then(res => res.json().then(data => ({ status: <number>res.status, body: <EndpointResponse>data })))
|
||||
// .then((fullResponse) => {
|
||||
// let maybeError = maybeMapError(fullResponse);
|
||||
// if (maybeError !== undefined) {
|
||||
// return { error: maybeError };
|
||||
// }
|
||||
// if (!fullResponse.body || !fullResponse.body.success) {
|
||||
// return { error: GenerateTtsAudioErrorType.UnknownError };
|
||||
// }
|
||||
|
||||
// if (!('inference_job_token' in fullResponse.body)) {
|
||||
// return { error: GenerateTtsAudioErrorType.UnknownError };
|
||||
// } else {
|
||||
// return <GenerateTtsAudioSuccess> {
|
||||
// inference_job_token: fullResponse.body.inference_job_token,
|
||||
// inference_job_token_type: fullResponse.body.inference_job_token_type,
|
||||
// };
|
||||
// }
|
||||
// })
|
||||
// .catch(e => {
|
||||
// let maybeError = maybeMapError(e);
|
||||
// if (maybeError !== undefined) {
|
||||
// return { error: maybeError };
|
||||
// }
|
||||
// return { error: GenerateTtsAudioErrorType.UnknownError };
|
||||
// });
|
||||
};
|
||||
@@ -8,7 +8,7 @@ export const PreviewImages = () => {
|
||||
|
||||
const imageWidth1 = pageWidth.value > 1340 ? 630 : (pageWidth.value - 80) / 2;
|
||||
const imageHeight1 = imageWidth1 * 0.56;
|
||||
const imageHeight2 = pageHeight.value > 1138 ? 354 : pageHeight.value - 620;
|
||||
const imageHeight2 = pageHeight.value > 1138 ? 354 : pageHeight.value - 650;
|
||||
const imageWidth2 = imageHeight2 / 0.56;
|
||||
|
||||
const imageWidth = imageHeight1 < imageHeight2 ? imageWidth1 : imageWidth2;
|
||||
@@ -21,18 +21,14 @@ export const PreviewImages = () => {
|
||||
].join(" ");
|
||||
|
||||
return (
|
||||
<div className="flex justify-center gap-2">
|
||||
<div className="flex justify-center gap-1">
|
||||
<div className="flex flex-col" style={{ width: imageWidth }}>
|
||||
<div className={textClasses}>Raw Preview</div>
|
||||
<div
|
||||
className="block w-full rounded-b-lg"
|
||||
className="block w-full overflow-hidden rounded-b-lg"
|
||||
style={{ height: imageHeight }}
|
||||
>
|
||||
<canvas
|
||||
id="raw-preview"
|
||||
width={imageWidth}
|
||||
height={imageHeight}
|
||||
/>
|
||||
<canvas id="raw-preview" width={imageWidth} height={imageHeight} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-[40px] flex-col justify-center">
|
||||
@@ -41,7 +37,7 @@ export const PreviewImages = () => {
|
||||
<div className="flex flex-col" style={{ width: imageWidth }}>
|
||||
<div className={textClasses}>Styled Preview</div>
|
||||
<div
|
||||
className="block w-full rounded-b-lg"
|
||||
className="block w-full overflow-hidden rounded-b-lg"
|
||||
style={{ height: imageHeight }}
|
||||
>
|
||||
<img id="styled-preview" width={imageWidth} height={imageHeight} />
|
||||
|
||||
@@ -45,7 +45,7 @@ export const AudioTabComponent = () => {
|
||||
object_uuid: item.token,
|
||||
name: item.maybe_title || item.origin.maybe_model.title,
|
||||
length: 25,
|
||||
thumbnail: "resources/placeholders/audio_placeholder.png",
|
||||
thumbnail: "/resources/placeholders/audio_placeholder.png",
|
||||
isMine: true,
|
||||
// isBookmarked?: boolean;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ export const ListAudioByUser = async(username:string) => {
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
},
|
||||
credentials: 'include'
|
||||
// credentials: 'include'
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
|
||||
@@ -7,37 +7,37 @@ import { TabStylization } from "~/pages/PageEnigma/comps/SidePanelTabs/TabStyliz
|
||||
import { CameraTab } from "./itemTabs/CameraTab";
|
||||
export const tabList = [
|
||||
{
|
||||
icon: "resources/icons/characters.png",
|
||||
icon: "/resources/icons/characters.png",
|
||||
title: "Characters",
|
||||
value: AssetType.CHARACTER,
|
||||
component: <ObjectsTab type={AssetType.CHARACTER} />,
|
||||
},
|
||||
{
|
||||
icon: "resources/icons/animations.png",
|
||||
icon: "/resources/icons/animations.png",
|
||||
title: "Animation",
|
||||
value: AssetType.ANIMATION,
|
||||
component: <AnimationTab />,
|
||||
},
|
||||
{
|
||||
icon: "resources/icons/objects.png",
|
||||
icon: "/resources/icons/objects.png",
|
||||
title: "Objects",
|
||||
value: AssetType.OBJECT,
|
||||
component: <ObjectsTab type={AssetType.OBJECT} />,
|
||||
},
|
||||
{
|
||||
icon: "resources/icons/shapes.png",
|
||||
icon: "/resources/icons/shapes.png",
|
||||
title: "Shapes",
|
||||
value: AssetType.SHAPE,
|
||||
component: <ShapeTab />,
|
||||
},
|
||||
{
|
||||
icon: "resources/icons/camera.png",
|
||||
icon: "/resources/icons/camera.png",
|
||||
title: "Camera",
|
||||
value: AssetType.CAMERA,
|
||||
component: <CameraTab />,
|
||||
},
|
||||
{
|
||||
icon: "resources/icons/audios.png",
|
||||
icon: "/resources/icons/audios.png",
|
||||
title: "Audio",
|
||||
value: AssetType.AUDIO,
|
||||
component: <AudioTab />,
|
||||
|
||||
@@ -46,55 +46,62 @@ export const StyleSelection = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex h-[280px] w-[800px] flex-col gap-3 rounded-lg bg-ui-panel p-4">
|
||||
<div className="flex flex-col gap-4 rounded-t-lg bg-ui-panel p-5">
|
||||
<div className="flex w-full flex-col">
|
||||
<Label>Select Base Style</Label>
|
||||
<div
|
||||
className="relative overflow-x-hidden"
|
||||
style={{ width: 768, height: 80 }}
|
||||
>
|
||||
<div className="relative">
|
||||
<div
|
||||
className="absolute flex gap-2"
|
||||
style={{
|
||||
width: styleList.length * 84 + 26,
|
||||
left: scrollPosition * -86,
|
||||
top: 0,
|
||||
}}
|
||||
className="relative overflow-x-hidden"
|
||||
style={{ width: 768, height: 80 }}
|
||||
>
|
||||
{styleList.map((style) => (
|
||||
<ItemPicker
|
||||
key={style.type}
|
||||
label={style.label}
|
||||
type={style.type}
|
||||
selected={selection === style.type}
|
||||
onSelected={handlePickingStylizer}
|
||||
src={style.image}
|
||||
width={80}
|
||||
height={80}
|
||||
/>
|
||||
))}
|
||||
<div
|
||||
className="absolute flex gap-2 transition-all duration-300 ease-in-out"
|
||||
style={{
|
||||
width: styleList.length * 84 + 26,
|
||||
left: scrollPosition * -86,
|
||||
top: 0,
|
||||
}}
|
||||
>
|
||||
{styleList.map((style) => (
|
||||
<ItemPicker
|
||||
key={style.type}
|
||||
label={style.label}
|
||||
type={style.type}
|
||||
selected={selection === style.type}
|
||||
onSelected={handlePickingStylizer}
|
||||
src={style.image}
|
||||
width={80}
|
||||
height={80}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
{scrollPosition > 0 && (
|
||||
<div className="absolute left-3 top-5">
|
||||
<ButtonIcon
|
||||
icon={faAngleLeft}
|
||||
onClick={() =>
|
||||
setScrollPosition(Math.max(scrollPosition - 6, 0))
|
||||
}
|
||||
/>
|
||||
<div className="pointer-events-none absolute left-[-10px] top-0 h-full w-12 bg-gradient-to-r from-ui-panel to-transparent">
|
||||
<div className="flex h-full w-full items-center justify-start">
|
||||
<ButtonIcon
|
||||
icon={faAngleLeft}
|
||||
onClick={() =>
|
||||
setScrollPosition(Math.max(scrollPosition - 6, 0))
|
||||
}
|
||||
className="pointer-events-auto h-6 w-6 rounded-full bg-white/80 text-gray-800/75 hover:bg-white/100 hover:text-gray-800"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{scrollPosition < styleList.length - 9 && (
|
||||
<div className="absolute right-3 top-5">
|
||||
<ButtonIcon
|
||||
icon={faAngleRight}
|
||||
onClick={() =>
|
||||
setScrollPosition(
|
||||
Math.min(scrollPosition + 6, styleList.length - 9),
|
||||
)
|
||||
}
|
||||
fill
|
||||
/>
|
||||
<div className="pointer-events-none absolute right-[-10px] top-0 h-full w-12 bg-gradient-to-l from-ui-panel to-transparent">
|
||||
<div className="flex h-full w-full items-center justify-end">
|
||||
<ButtonIcon
|
||||
icon={faAngleRight}
|
||||
onClick={() =>
|
||||
setScrollPosition(
|
||||
Math.min(scrollPosition + 6, styleList.length - 9),
|
||||
)
|
||||
}
|
||||
className="pointer-events-auto h-6 w-6 rounded-full bg-white/80 text-gray-800/75 hover:bg-white/100 hover:text-gray-800"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -40,10 +40,10 @@ export const TrackKeyFrame = ({ keyframe, updateKeyframe }: Props) => {
|
||||
: "bg-keyframe-unselected",
|
||||
].join(" ")}
|
||||
style={{
|
||||
width: 18,
|
||||
height: 18,
|
||||
width: 14,
|
||||
height: 14,
|
||||
left: displayOffset * 4 * scale.value - 6,
|
||||
top: 8,
|
||||
top: 11,
|
||||
}}
|
||||
onPointerDown={(event) => onPointerDown(event, "drag")}
|
||||
onClick={() => (selectedItem.value = keyframe)}
|
||||
|
||||
@@ -238,7 +238,7 @@ export class APIManager {
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
// credentials: "include",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
},
|
||||
@@ -291,7 +291,7 @@ export class APIManager {
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
// credentials: "include",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
},
|
||||
@@ -325,7 +325,7 @@ export class APIManager {
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
// credentials: "include",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
},
|
||||
@@ -362,7 +362,7 @@ export class APIManager {
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
// credentials: "include",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
},
|
||||
@@ -421,7 +421,7 @@ export class APIManager {
|
||||
|
||||
const response = await fetch(`${this.baseUrl}/v1/video/enqueue_vst`, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
// credentials: "include",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
|
||||
@@ -31,6 +31,7 @@ import Queue from "~/pages/PageEnigma/Queue/Queue";
|
||||
import { QueueNames } from "~/pages/PageEnigma/Queue/QueueNames";
|
||||
import { fromEngineActions } from "~/pages/PageEnigma/Queue/fromEngineActions";
|
||||
import { AssetType, MediaItem } from "~/pages/PageEnigma/models";
|
||||
import { LoadingBar } from "~/components";
|
||||
|
||||
// Main editor class that will call everything else all you need to call is " initialize() ".
|
||||
class Editor {
|
||||
@@ -217,7 +218,12 @@ class Editor {
|
||||
);
|
||||
}
|
||||
|
||||
initialize(config: any) {
|
||||
isEmpty(value:string) {
|
||||
return (value == null || (typeof value === "string" && value.trim().length === 0));
|
||||
}
|
||||
|
||||
initialize(config: any,sceneToken) {
|
||||
|
||||
//setup reactland Callbacks
|
||||
this.dispatchAppUiState = config.dispatchAppUiState;
|
||||
|
||||
@@ -351,6 +357,10 @@ class Editor {
|
||||
|
||||
this.updateLoop();
|
||||
|
||||
if (this.isEmpty(sceneToken) == false) {
|
||||
this.loadScene(sceneToken)
|
||||
}
|
||||
|
||||
this.dispatchAppUiState({
|
||||
type: APPUI_ACTION_TYPES.UPDATE_EDITOR_LOADINGBAR,
|
||||
payload: {
|
||||
@@ -552,6 +562,30 @@ class Editor {
|
||||
this.activeScene.load_glb(media_file_token);
|
||||
}
|
||||
|
||||
async showLoading() {
|
||||
this.dispatchAppUiState({
|
||||
type: APPUI_ACTION_TYPES.SHOW_EDITOR_LOADINGBAR,
|
||||
});
|
||||
}
|
||||
|
||||
async updateLoad(progress:number,message:string) {
|
||||
this.dispatchAppUiState({
|
||||
type: APPUI_ACTION_TYPES.UPDATE_EDITOR_LOADINGBAR,
|
||||
payload: {
|
||||
showEditorLoadingBar: {
|
||||
progress: progress,
|
||||
message: message
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async endLoading() {
|
||||
this.dispatchAppUiState({
|
||||
type: APPUI_ACTION_TYPES.HIDE_EDITOR_LOADINGBAR,
|
||||
});
|
||||
}
|
||||
|
||||
async _test_demo() {
|
||||
// note the database from the server is the source of truth for all the data.
|
||||
// Test code here
|
||||
@@ -856,23 +890,28 @@ class Editor {
|
||||
);
|
||||
}
|
||||
|
||||
async _debugDownloadVideo(videoURL:string) {
|
||||
// DEBUG ONLY to download the video
|
||||
|
||||
let a = document.createElement('a');
|
||||
a.href = videoURL;
|
||||
a.download = 'video.mp4'; // Name of the downloaded file
|
||||
document.body.appendChild(a);
|
||||
a.click(); // Trigger the download
|
||||
}
|
||||
|
||||
async stopPlayback(compile_audio: boolean = true) {
|
||||
//let video_fps = Math.floor(this.frames * (this.cap_fps / this.timeline.timeline_limit));
|
||||
//console.log("Video FPS:", video_fps)
|
||||
this.rendering = false;
|
||||
|
||||
const videoBlob = new Blob(this.frame_buffer, { type: 'video/webm' });
|
||||
const videoURL = URL.createObjectURL(videoBlob);
|
||||
//const arrayBuffer = await videoBlob.arrayBuffer();
|
||||
//const uint8Array = new Uint8Array(arrayBuffer);
|
||||
|
||||
// Create an anchor element
|
||||
let a = document.createElement('a');
|
||||
a.href = videoURL;
|
||||
a.download = 'video.mp4'; // Name of the downloaded file
|
||||
document.body.appendChild(a);
|
||||
a.click(); // Trigger the download
|
||||
|
||||
// DEBUG ONLY to download the video
|
||||
//this._debugDownloadVideo(videoURL)
|
||||
|
||||
this.generating_preview = true;
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
@@ -887,6 +926,7 @@ class Editor {
|
||||
// );
|
||||
//}
|
||||
|
||||
this.updateLoad(50,"Processing ...")
|
||||
|
||||
// Write the Uint8Array to the FFmpeg file system
|
||||
ffmpeg.FS('writeFile', 'input.webm', await fetchFile(videoURL));
|
||||
@@ -952,6 +992,8 @@ class Editor {
|
||||
});
|
||||
|
||||
// {"success":true,"inference_job_token":"jinf_j3nbqbd15wqxb0xcks13qh3f3bz"}
|
||||
this.updateLoad(100,"Done Check Your Media Tab On Profile.")
|
||||
this.endLoading()
|
||||
|
||||
console.log(result);
|
||||
this.recorder = undefined;
|
||||
@@ -1015,7 +1057,7 @@ class Editor {
|
||||
this.switchCameraView();
|
||||
}
|
||||
this.activeScene.renderMode(true);
|
||||
|
||||
|
||||
const ffmpeg = createFFmpeg({ log: false });
|
||||
await ffmpeg.load();
|
||||
await ffmpeg.FS("writeFile", `render.png`, await fetchFile(imgData));
|
||||
@@ -1051,10 +1093,14 @@ class Editor {
|
||||
|
||||
// This initializes the generation of a video render scene is where the core work happens
|
||||
generateVideo() {
|
||||
|
||||
console.log("Generating video...", this.frame_buffer);
|
||||
if (this.rendering) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.showLoading()
|
||||
|
||||
this.rendering = true; // has to go first to debounce
|
||||
this.startPlayback();
|
||||
this.frame_buffer = [];
|
||||
@@ -1068,6 +1114,9 @@ class Editor {
|
||||
}
|
||||
|
||||
startPlayback() {
|
||||
|
||||
this.updateLoad(25,"Starting Processing")
|
||||
|
||||
this.timeline.is_playing = true;
|
||||
this.timeline.scrubber_frame_position = 0;
|
||||
if (!this.camera_person_mode) {
|
||||
|
||||
@@ -9,7 +9,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Sit",
|
||||
thumbnail: "resources/characters/img04.png",
|
||||
thumbnail: "/resources/characters/img04.png",
|
||||
isMine: true,
|
||||
},
|
||||
{
|
||||
@@ -18,7 +18,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Idle",
|
||||
thumbnail: "resources/characters/img07.png",
|
||||
thumbnail: "/resources/characters/img07.png",
|
||||
isBookmarked: true,
|
||||
},
|
||||
{
|
||||
@@ -27,7 +27,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Walk",
|
||||
thumbnail: "resources/characters/img07.png",
|
||||
thumbnail: "/resources/characters/img07.png",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -35,7 +35,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Punch",
|
||||
thumbnail: "resources/characters/img08.png",
|
||||
thumbnail: "/resources/characters/img08.png",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -43,7 +43,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Jump",
|
||||
thumbnail: "resources/characters/img06.png",
|
||||
thumbnail: "/resources/characters/img06.png",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -51,7 +51,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Dance",
|
||||
thumbnail: "resources/characters/img11.png",
|
||||
thumbnail: "/resources/characters/img11.png",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -59,7 +59,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Jump Forward",
|
||||
thumbnail: "resources/characters_gif/Jump Forward.gif",
|
||||
thumbnail: "/resources/characters_gif/Jump Forward.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -67,7 +67,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Tonic Seizure",
|
||||
thumbnail: "resources/characters_gif/Tonic Seizure.gif",
|
||||
thumbnail: "/resources/characters_gif/Tonic Seizure.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -75,7 +75,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Ginga Variation 3",
|
||||
thumbnail: "resources/characters_gif/Ginga Variation 3.gif",
|
||||
thumbnail: "/resources/characters_gif/Ginga Variation 3.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -83,7 +83,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Crouch Running",
|
||||
thumbnail: "resources/characters_gif/Crouch Running.gif",
|
||||
thumbnail: "/resources/characters_gif/Crouch Running.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -91,7 +91,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Strafing Jump",
|
||||
thumbnail: "resources/characters_gif/Strafing Jump.gif",
|
||||
thumbnail: "/resources/characters_gif/Strafing Jump.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -99,7 +99,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Texting",
|
||||
thumbnail: "resources/characters_gif/Texting.gif",
|
||||
thumbnail: "/resources/characters_gif/Texting.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -107,7 +107,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Pushing",
|
||||
thumbnail: "resources/characters_gif/Pushing.gif",
|
||||
thumbnail: "/resources/characters_gif/Pushing.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -115,7 +115,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Standing Idle To Crouch",
|
||||
thumbnail: "resources/characters_gif/Standing Idle To Crouch.gif",
|
||||
thumbnail: "/resources/characters_gif/Standing Idle To Crouch.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -123,7 +123,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Fight Idle To Standing Idle",
|
||||
thumbnail: "resources/characters_gif/Fight Idle To Standing Idle.gif",
|
||||
thumbnail: "/resources/characters_gif/Fight Idle To Standing Idle.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -131,7 +131,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Texting While Standing",
|
||||
thumbnail: "resources/characters_gif/Texting While Standing.gif",
|
||||
thumbnail: "/resources/characters_gif/Texting While Standing.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -139,7 +139,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Getting Bit",
|
||||
thumbnail: "resources/characters_gif/Getting Bit.gif",
|
||||
thumbnail: "/resources/characters_gif/Getting Bit.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -147,7 +147,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Female Laying Pose",
|
||||
thumbnail: "resources/characters_gif/Female Laying Pose.gif",
|
||||
thumbnail: "/resources/characters_gif/Female Laying Pose.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -155,7 +155,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Twist Dance",
|
||||
thumbnail: "resources/characters_gif/Twist Dance.gif",
|
||||
thumbnail: "/resources/characters_gif/Twist Dance.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -163,7 +163,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Femme Peek Around Corner",
|
||||
thumbnail: "resources/characters_gif/Femme Peek Around Corner.gif",
|
||||
thumbnail: "/resources/characters_gif/Femme Peek Around Corner.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -171,7 +171,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Sword And Shield Casting",
|
||||
thumbnail: "resources/characters_gif/Sword And Shield Casting.gif",
|
||||
thumbnail: "/resources/characters_gif/Sword And Shield Casting.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -179,7 +179,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Breakdance Ready",
|
||||
thumbnail: "resources/characters_gif/Breakdance Ready.gif",
|
||||
thumbnail: "/resources/characters_gif/Breakdance Ready.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -187,7 +187,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Sitting Yell",
|
||||
thumbnail: "resources/characters_gif/Sitting Yell.gif",
|
||||
thumbnail: "/resources/characters_gif/Sitting Yell.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -195,7 +195,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Uppercut",
|
||||
thumbnail: "resources/characters_gif/Uppercut.gif",
|
||||
thumbnail: "/resources/characters_gif/Uppercut.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -203,7 +203,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Female Standing Pose",
|
||||
thumbnail: "resources/characters_gif/Female Standing Pose.gif",
|
||||
thumbnail: "/resources/characters_gif/Female Standing Pose.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -211,7 +211,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Breakdance Uprock Var 1",
|
||||
thumbnail: "resources/characters_gif/Breakdance Uprock Var 1.gif",
|
||||
thumbnail: "/resources/characters_gif/Breakdance Uprock Var 1.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -219,7 +219,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Standard Walk",
|
||||
thumbnail: "resources/characters_gif/Standard Walk.gif",
|
||||
thumbnail: "/resources/characters_gif/Standard Walk.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -227,7 +227,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Rifle Pull Out",
|
||||
thumbnail: "resources/characters_gif/Rifle Pull Out.gif",
|
||||
thumbnail: "/resources/characters_gif/Rifle Pull Out.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -235,7 +235,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Sword And Shield Jump",
|
||||
thumbnail: "resources/characters_gif/Sword And Shield Jump.gif",
|
||||
thumbnail: "/resources/characters_gif/Sword And Shield Jump.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -243,7 +243,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Baseball Bunt",
|
||||
thumbnail: "resources/characters_gif/Baseball Bunt.gif",
|
||||
thumbnail: "/resources/characters_gif/Baseball Bunt.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -251,7 +251,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Strafing",
|
||||
thumbnail: "resources/characters_gif/Strafing.gif",
|
||||
thumbnail: "/resources/characters_gif/Strafing.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -259,7 +259,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Sneaking Forward",
|
||||
thumbnail: "resources/characters_gif/Sneaking Forward.gif",
|
||||
thumbnail: "/resources/characters_gif/Sneaking Forward.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -267,7 +267,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Skinning Test",
|
||||
thumbnail: "resources/characters_gif/Skinning Test.gif",
|
||||
thumbnail: "/resources/characters_gif/Skinning Test.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -275,7 +275,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Female Dance Pose",
|
||||
thumbnail: "resources/characters_gif/Female Dance Pose.gif",
|
||||
thumbnail: "/resources/characters_gif/Female Dance Pose.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -283,7 +283,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Right Strafe Walking",
|
||||
thumbnail: "resources/characters_gif/Right Strafe Walking.gif",
|
||||
thumbnail: "/resources/characters_gif/Right Strafe Walking.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -291,7 +291,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Laying Breathless",
|
||||
thumbnail: "resources/characters_gif/Laying Breathless.gif",
|
||||
thumbnail: "/resources/characters_gif/Laying Breathless.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -299,7 +299,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Box Jump",
|
||||
thumbnail: "resources/characters_gif/Box Jump.gif",
|
||||
thumbnail: "/resources/characters_gif/Box Jump.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -307,7 +307,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Orc Walk",
|
||||
thumbnail: "resources/characters_gif/Orc Walk.gif",
|
||||
thumbnail: "/resources/characters_gif/Orc Walk.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -315,7 +315,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Run Look Back",
|
||||
thumbnail: "resources/characters_gif/Run Look Back.gif",
|
||||
thumbnail: "/resources/characters_gif/Run Look Back.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -323,7 +323,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Standing Torch Jump",
|
||||
thumbnail: "resources/characters_gif/Standing Torch Jump.gif",
|
||||
thumbnail: "/resources/characters_gif/Standing Torch Jump.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -331,7 +331,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Lengthy Head Nod",
|
||||
thumbnail: "resources/characters_gif/Lengthy Head Nod.gif",
|
||||
thumbnail: "/resources/characters_gif/Lengthy Head Nod.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -339,7 +339,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Pistol Run Backward Arc",
|
||||
thumbnail: "resources/characters_gif/Pistol Run Backward Arc.gif",
|
||||
thumbnail: "/resources/characters_gif/Pistol Run Backward Arc.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -347,7 +347,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Right Hook",
|
||||
thumbnail: "resources/characters_gif/Right Hook.gif",
|
||||
thumbnail: "/resources/characters_gif/Right Hook.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -355,7 +355,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Great Sword Impact",
|
||||
thumbnail: "resources/characters_gif/Great Sword Impact.gif",
|
||||
thumbnail: "/resources/characters_gif/Great Sword Impact.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -363,7 +363,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Zombie Biting",
|
||||
thumbnail: "resources/characters_gif/Zombie Biting.gif",
|
||||
thumbnail: "/resources/characters_gif/Zombie Biting.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -371,7 +371,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Leaning",
|
||||
thumbnail: "resources/characters_gif/Leaning.gif",
|
||||
thumbnail: "/resources/characters_gif/Leaning.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -379,7 +379,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Standing Torch To Crouch Torch",
|
||||
thumbnail: "resources/characters_gif/Standing Torch To Crouch Torch.gif",
|
||||
thumbnail: "/resources/characters_gif/Standing Torch To Crouch Torch.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -387,7 +387,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Action Idle To Fight Idle",
|
||||
thumbnail: "resources/characters_gif/Action Idle To Fight Idle.gif",
|
||||
thumbnail: "/resources/characters_gif/Action Idle To Fight Idle.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -395,7 +395,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Corkscrew Evade",
|
||||
thumbnail: "resources/characters_gif/Corkscrew Evade.gif",
|
||||
thumbnail: "/resources/characters_gif/Corkscrew Evade.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -403,7 +403,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Catwalk Walk Forward Crossed",
|
||||
thumbnail: "resources/characters_gif/Catwalk Walk Forward Crossed.gif",
|
||||
thumbnail: "/resources/characters_gif/Catwalk Walk Forward Crossed.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -411,7 +411,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Look Around",
|
||||
thumbnail: "resources/characters_gif/Look Around.gif",
|
||||
thumbnail: "/resources/characters_gif/Look Around.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -419,7 +419,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Zombie Stand Up",
|
||||
thumbnail: "resources/characters_gif/Zombie Stand Up.gif",
|
||||
thumbnail: "/resources/characters_gif/Zombie Stand Up.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -427,7 +427,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Convulsing",
|
||||
thumbnail: "resources/characters_gif/Convulsing.gif",
|
||||
thumbnail: "/resources/characters_gif/Convulsing.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -435,7 +435,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Pistol Whip",
|
||||
thumbnail: "resources/characters_gif/Pistol Whip.gif",
|
||||
thumbnail: "/resources/characters_gif/Pistol Whip.gif",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -443,7 +443,7 @@ export const animationItems = signal<MediaItem[]>([
|
||||
type: AssetType.ANIMATION,
|
||||
length: 100,
|
||||
name: "Mutant Idle",
|
||||
thumbnail: "resources/characters_gif/Mutant Idle.gif",
|
||||
thumbnail: "/resources/characters_gif/Mutant Idle.gif",
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -454,7 +454,7 @@ export const audioItems = signal<MediaItem[]>([
|
||||
type: AssetType.AUDIO,
|
||||
length: 25,
|
||||
name: "Talk (Demo Sounds)",
|
||||
thumbnail: "resources/placeholders/audio_placeholder.png",
|
||||
thumbnail: "/resources/placeholders/audio_placeholder.png",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
@@ -462,7 +462,7 @@ export const audioItems = signal<MediaItem[]>([
|
||||
type: AssetType.AUDIO,
|
||||
length: 25,
|
||||
name: "NCS Song",
|
||||
thumbnail: "resources/placeholders/audio_placeholder.png",
|
||||
thumbnail: "/resources/placeholders/audio_placeholder.png",
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -472,14 +472,14 @@ export const cameraItems = signal<MediaItem[]>([
|
||||
media_id: uuid.v4(),
|
||||
type: AssetType.CAMERA,
|
||||
name: "Portrait Zoom Out",
|
||||
thumbnail: "resources/placeholders/placeholder.png",
|
||||
thumbnail: "/resources/placeholders/placeholder.png",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
media_id: uuid.v4(),
|
||||
type: AssetType.CAMERA,
|
||||
name: "Pan Left and Right",
|
||||
thumbnail: "resources/placeholders/placeholder.png",
|
||||
thumbnail: "/resources/placeholders/placeholder.png",
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -489,35 +489,35 @@ export const characterItems = signal<MediaItem[]>([
|
||||
media_id: "m_fmxy8wjnep1hdaz7qdg4n7y15d2bsp",
|
||||
type: AssetType.CHARACTER,
|
||||
name: "Shrek",
|
||||
thumbnail: "resources/placeholders/placeholder.png",
|
||||
thumbnail: "/resources/placeholders/placeholder.png",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
media_id: "m_9f3d3z94kk6m25zywyz6an3p43fjtw",
|
||||
type: AssetType.CHARACTER,
|
||||
name: "Stick Man",
|
||||
thumbnail: "resources/placeholders/placeholder.png",
|
||||
thumbnail: "/resources/placeholders/placeholder.png",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
media_id: "m_r7w1tmkx2jg8nznr3hyzj4k6zhfh7d ",
|
||||
type: AssetType.CHARACTER,
|
||||
name: "Female Doll",
|
||||
thumbnail: "resources/characters/img03.png",
|
||||
thumbnail: "/resources/characters/img03.png",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
media_id: "m_9sqg0evpr23587jnr8z3zsvav1x077 ",
|
||||
type: AssetType.CHARACTER,
|
||||
name: "Male Doll",
|
||||
thumbnail: "resources/characters/img03.png",
|
||||
thumbnail: "/resources/characters/img03.png",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
media_id: "m_pwtk45wsfr5z2bavmwxh2efnwvh4rr ",
|
||||
type: AssetType.CHARACTER,
|
||||
name: "Story Girl",
|
||||
thumbnail: "resources/characters/img13.png",
|
||||
thumbnail: "/resources/characters/img13.png",
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -527,7 +527,7 @@ export const objectItems = signal<MediaItem[]>([
|
||||
media_id: "m_0xfrmekc56satjxn66wt6c9dkw7dxe",
|
||||
type: AssetType.OBJECT,
|
||||
name: "Pikachu Statue",
|
||||
thumbnail: "resources/placeholders/placeholder.png",
|
||||
thumbnail: "/resources/placeholders/placeholder.png",
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -538,27 +538,27 @@ export const shapeItems = signal<MediaItem[]>([
|
||||
media_id: "Box",
|
||||
type: AssetType.SHAPE,
|
||||
name: "Cube",
|
||||
thumbnail: "resources/shapes/cube.png",
|
||||
thumbnail: "/resources/shapes/cube.png",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
media_id: "Cylinder",
|
||||
type: AssetType.SHAPE,
|
||||
name: "Cylinder",
|
||||
thumbnail: "resources/shapes/cylinder.png",
|
||||
thumbnail: "/resources/shapes/cylinder.png",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
media_id: "Donut",
|
||||
type: AssetType.SHAPE,
|
||||
name: "Donut",
|
||||
thumbnail: "resources/shapes/donut.png",
|
||||
thumbnail: "/resources/shapes/donut.png",
|
||||
},
|
||||
{
|
||||
version: 1,
|
||||
media_id: "Sphere",
|
||||
type: AssetType.SHAPE,
|
||||
name: "Sphere",
|
||||
thumbnail: "resources/shapes/sphere.png",
|
||||
thumbnail: "/resources/shapes/sphere.png",
|
||||
},
|
||||
]);
|
||||
+8
-11
@@ -1,5 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { CookiesProvider } from "react-cookie";
|
||||
import { Transition } from "@headlessui/react";
|
||||
import { LinksFunction } from "@remix-run/deno";
|
||||
import {
|
||||
@@ -96,16 +95,14 @@ export default function App() {
|
||||
</head>
|
||||
<body className="overflow-hidden bg-ui-background">
|
||||
<CompleteTakeoverLoadingScreen isShowing={showLoader} />
|
||||
<CookiesProvider defaultSetOptions={{ path: "/" }}>
|
||||
<AuthenticationProvider>
|
||||
<ToasterProvider>
|
||||
<AppUIProvider>
|
||||
<div className="topbar-spacer" />
|
||||
<Outlet />
|
||||
</AppUIProvider>
|
||||
</ToasterProvider>
|
||||
</AuthenticationProvider>
|
||||
</CookiesProvider>
|
||||
<AuthenticationProvider>
|
||||
<ToasterProvider>
|
||||
<AppUIProvider>
|
||||
<div className="topbar-spacer" />
|
||||
<Outlet />
|
||||
</AppUIProvider>
|
||||
</ToasterProvider>
|
||||
</AuthenticationProvider>
|
||||
<ScrollRestoration />
|
||||
<Scripts />
|
||||
</body>
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { HeadersFunction } from "@remix-run/deno";
|
||||
import { withProtectionRoute } from "~/modules/withProtectedRoute";
|
||||
import { PageEnigma } from "~/pages/PageEnigma";
|
||||
|
||||
// NB(bt): Netlify's custom directives cannot set headers for pages served by Remix,
|
||||
// so we must specify them here instead. Netlify header rules (in either _headers or
|
||||
// netlify.toml) will apply to statically served files (images, css, js), however.
|
||||
// Setting these headers in `vite.config.ts` will also fail to apply them in
|
||||
// production.
|
||||
export const headers: HeadersFunction = ({
|
||||
actionHeaders,
|
||||
errorHeaders,
|
||||
loaderHeaders,
|
||||
parentHeaders,
|
||||
}) => ({
|
||||
// NB(bt): The following two headers are required for enabling SharedArrayBuffer (required by
|
||||
// ffmpeg.wasm) in the post-SPECTRE world. Without these headers being sent by the page, the
|
||||
// page cannot use SharedArrayBuffer. Downstream services must also set relevant CORS headers.
|
||||
//
|
||||
// See the following documentation on how this complex system works:
|
||||
//
|
||||
// - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements
|
||||
// - https://stackoverflow.com/questions/73275184/enable-shared-array-buffer-in-cross-domain
|
||||
// - https://blog.logrocket.com/understanding-sharedarraybuffer-and-cross-origin-isolation/
|
||||
// - https://github.com/ffmpegwasm/react-app/issues/3
|
||||
//
|
||||
"Cross-Origin-Embedder-Policy": "require-corp",
|
||||
"Cross-Origin-Opener-Policy": "same-origin",
|
||||
});
|
||||
|
||||
const IdealEnigma = withProtectionRoute(()=><PageEnigma />);
|
||||
export default IdealEnigma;
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useContext, useEffect, useState, useRef } from "react";
|
||||
import { useNavigate, useSearchParams } from "@remix-run/react";
|
||||
import { faKey, faUser } from "@fortawesome/pro-solid-svg-icons";
|
||||
import { AuthenticationContext } from "~/contexts/Authentication";
|
||||
import { AUTH_STATUS, AuthenticationContext } from "~/contexts/Authentication";
|
||||
|
||||
import { Button,H1,Input,Link,P } from '~/components';
|
||||
import { LoadingDots } from "~/components";
|
||||
@@ -12,7 +12,7 @@ export default function LoginScreen() {
|
||||
|
||||
const [showLoader, setShowLoader] = useState<string|undefined>(undefined);
|
||||
const formRef = useRef<HTMLFormElement | null>(null);
|
||||
const {authState, loginAndGetUserInfo} = useContext(AuthenticationContext);
|
||||
const {authState, login} = useContext(AuthenticationContext);
|
||||
|
||||
const handleOnSumbit = (ev: React.FormEvent<HTMLFormElement>)=>{
|
||||
ev.preventDefault();
|
||||
@@ -20,9 +20,9 @@ export default function LoginScreen() {
|
||||
const form = new FormData(formRef.current);
|
||||
const usernameOrEmail = form.get("usernameOrEmail")?.toString();
|
||||
const password = form.get("password")?.toString();
|
||||
if( usernameOrEmail && password && loginAndGetUserInfo){
|
||||
if( usernameOrEmail && password && login){
|
||||
setShowLoader("Authenticating");
|
||||
loginAndGetUserInfo(
|
||||
login(
|
||||
usernameOrEmail,
|
||||
password,
|
||||
()=>{
|
||||
@@ -34,7 +34,7 @@ export default function LoginScreen() {
|
||||
|
||||
useEffect(()=>{
|
||||
const redirectPath = searchParams.get('redirect');
|
||||
if(authState && authState.isLoggedIn)
|
||||
if(authState && authState.authStatus === AUTH_STATUS.LOGGED_IN)
|
||||
navigate(redirectPath ? redirectPath:'/');
|
||||
},[authState]);
|
||||
|
||||
|
||||
Generated
+7
-43
@@ -27,7 +27,6 @@
|
||||
"ccapture.js": "github:aceslowman/ccapture.js#npm-fix",
|
||||
"isbot": "^4.1.0",
|
||||
"react": "^18.2.0",
|
||||
"react-cookie": "^7.1.4",
|
||||
"react-dom": "^18.2.0",
|
||||
"tailwind-merge": "^2.2.2",
|
||||
"terser": "^5.30.3",
|
||||
@@ -2346,15 +2345,6 @@
|
||||
"@types/unist": "^2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/hoist-non-react-statics": {
|
||||
"version": "3.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz",
|
||||
"integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==",
|
||||
"dependencies": {
|
||||
"@types/react": "*",
|
||||
"hoist-non-react-statics": "^3.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
||||
@@ -2412,12 +2402,14 @@
|
||||
"node_modules/@types/prop-types": {
|
||||
"version": "15.7.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
|
||||
"integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
|
||||
"integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "18.2.57",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.57.tgz",
|
||||
"integrity": "sha512-ZvQsktJgSYrQiMirAN60y4O/LRevIV8hUzSOSNB6gfR3/o3wCBFQx3sPwIYtuDMeiVgsSS3UzCV26tEzgnfvQw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
"@types/scheduler": "*",
|
||||
@@ -2436,7 +2428,8 @@
|
||||
"node_modules/@types/scheduler": {
|
||||
"version": "0.16.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
|
||||
"integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A=="
|
||||
"integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/semver": {
|
||||
"version": "7.5.7",
|
||||
@@ -3969,7 +3962,8 @@
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/damerau-levenshtein": {
|
||||
"version": "1.0.8",
|
||||
@@ -6122,14 +6116,6 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/hoist-non-react-statics": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||
"dependencies": {
|
||||
"react-is": "^16.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hosted-git-info": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz",
|
||||
@@ -10395,19 +10381,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-cookie": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-7.1.4.tgz",
|
||||
"integrity": "sha512-wDxxa/HYaSXSMlyWJvJ5uZTzIVtQTPf1gMksFgwAz/2/W3lCtY8r4OChCXMPE7wax0PAdMY97UkNJedGv7KnDw==",
|
||||
"dependencies": {
|
||||
"@types/hoist-non-react-statics": "^3.3.5",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"universal-cookie": "^7.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">= 16.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
||||
@@ -12510,15 +12483,6 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/universal-cookie": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-7.1.4.tgz",
|
||||
"integrity": "sha512-Q+DVJsdykStWRMtXr2Pdj3EF98qZHUH/fXv/gwFz/unyToy1Ek1w5GsWt53Pf38tT8Gbcy5QNsj61Xe9TggP4g==",
|
||||
"dependencies": {
|
||||
"@types/cookie": "^0.6.0",
|
||||
"cookie": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
"ccapture.js": "github:aceslowman/ccapture.js#npm-fix",
|
||||
"isbot": "^4.1.0",
|
||||
"react": "^18.2.0",
|
||||
"react-cookie": "^7.1.4",
|
||||
"react-dom": "^18.2.0",
|
||||
"tailwind-merge": "^2.2.2",
|
||||
"terser": "^5.30.3",
|
||||
|
||||
Reference in new issue
Block a user