Merge pull request #13 from storytold/feature/loading-screen

Feature/loading screen
This commit is contained in:
wil authored and GitHub committed 2024-03-26 13:23:17 -04:00
commit 12246aa088
5 files changed
+234 -4

No files matched your search

+67
View File
@@ -0,0 +1,67 @@
import { useState, useEffect } from 'react';
interface LoadingDotsProps {
show?: boolean;
transition?: boolean;
transitionDuration?: number;
};
interface LoadingDotsInnerProps {
show?: boolean;
transition?: boolean;
transitionDuration?: number;
children: React.ReactNode;
};
export const LoadingDotsTyping = (props: LoadingDotsProps)=>{
return (
<LoadingDots {...props}>
<div className="dot-typing"></div>
</LoadingDots>
)
}
export const LoadingDotsBricks = (props: LoadingDotsProps)=>{
return (
<LoadingDots {...props}>
<div className="dot-bricks"></div>
</LoadingDots>
)
}
function LoadingDots({
show=true,
transition = false,
transitionDuration = 1000,
children,
}: LoadingDotsInnerProps){
const [state, setState] = useState<'loading'|'loaded'|'completed'>('loading');
const transitionClasses =
(transition ? `transition-opacity duration-${transitionDuration} `: "")
+ (state === 'loading' ? 'opacity-100' : 'opacity-0');
const classNames = "w-full h-full flex justify-center items-center bg-ui-background " + transitionClasses;
useEffect(()=>{
if(!show){
if(transition){
setState((curr)=>{
if (curr === 'loading') return 'loaded'
else return curr;
});
setTimeout(()=>setState('completed'), 2000);
} else {
setState('completed');
}
}
}, [show, transition]);
if(state!== 'completed'){
return(
<div className={classNames}>
{children}
</div>
);
}else{
return null;
}
};
+3
View File
@@ -6,6 +6,7 @@ import { Input } from "./Input";
import { H4 } from "./H4";
import { ItemPicker } from "./ItemPicker";
import { Textarea } from "./Textarea";
import { LoadingDotsBricks, LoadingDotsTyping } from "./LoadingDots";
export {
Button,
@@ -16,4 +17,6 @@ export {
ItemPicker,
Textarea,
Input,
LoadingDotsBricks,
LoadingDotsTyping,
};
@@ -1,10 +1,15 @@
import { useContext } from "react"
import { useContext, useEffect, useState } from "react"
import { EngineContext } from "~/contexts/EngineContext"
import { LoadingDotsTyping } from "~/components";
export const PreviewWindow = ()=>{
const editorEngine = useContext(EngineContext);
//take data from egine context
const [showLoader, setShowLoader] = useState<boolean>(true);
useEffect(()=>{
setTimeout(()=>setShowLoader(false), 5000);
},[]);
return (
<div
id="preview-window"
@@ -17,12 +22,16 @@ export const PreviewWindow = ()=>{
>
<p>Camera View</p>
</div>
<div className="rounded-lg border border-white box overflow-hidden">
<div className="relative rounded-lg border border-white box overflow-hidden">
<img
//shoot that datat from engine context to this image
className="aspect-video max-h-40"
src="/resources/uiAssets/video_player_placeholder.gif"
/>
<div className="absolute w-full h-full top-0 left-0">
<LoadingDotsTyping show={showLoader} transition/>
</div>
</div>
</div>
</div>
+41 -2
View File
@@ -1,4 +1,4 @@
import { useState } from "react";
import { useState, useEffect } from "react";
import { LinksFunction } from "@remix-run/deno";
import {
Links,
@@ -12,6 +12,7 @@ import normalizeCss from "./styles/normalize.css?url";
import tailwindCss from "./styles/tailwind.css?url";
import baseCss from "./styles/base.css?url";
import { LoadingDotsBricks } from "~/components";
import { TopBar } from "./modules/TopBar";
import { TopBarInnerContext } from "~/contexts/TopBarInner";
@@ -45,7 +46,13 @@ export const links: LinksFunction = () => [
export default function App() {
const [topBarInnerComponent, setTopBarInnerComponent] =
useState<JSX.Element | null>(null);
useState<JSX.Element | null>(null);
const [isLoaded, setIsLoaded] = useState<'loading'|'loaded'|'completed'>('loading');
useEffect(()=>{
setIsLoaded('loaded');
setTimeout(()=>setIsLoaded('completed'), 2000);
},[]);
return (
<html lang="en">
@@ -56,6 +63,15 @@ export default function App() {
<Links />
</head>
<body className="overflow-hidden bg-ui-background">
{isLoaded !== 'completed' &&
<CompleteTakeoverLoadingScreen
className={
isLoaded === 'loading'
? "transition-opacity duration-1000 opacity-100"
: "transition-opacity duration-1000 opacity-0"
}
/>
}
<TopBarInnerContext.Provider
value={{
TopBarInner: topBarInnerComponent,
@@ -72,3 +88,26 @@ export default function App() {
</html>
);
}
function CompleteTakeoverLoadingScreen({className}:{className:string}){
return(
<div
id='complete-takeover-loading-screen'
className={className}
style={{
backgroundColor: '#1a1a27',
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100vh',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
zIndex: 9999,
}}
>
<LoadingDotsBricks />
</div>
);
};
+112
View File
@@ -35,3 +35,115 @@ body {
user-select: none; /* Standard syntax */
pointer-events: none;
}
/*!
* three-dots - v0.3.2
* CSS loading animations made with single element
* https://nzbin.github.io/three-dots/
*
* Copyright (c) 2018 nzbin
* Released under MIT License
*/
/**
* ==============================================
* Dot Typing
* ==============================================
*/
.dot-typing {
position: relative;
left: -9999px;
width: 10px;
height: 10px;
border-radius: 5px;
background-color: #393948;
color: #393948;
box-shadow: 9984px 0 0 0 #393948, 9999px 0 0 0 #393948, 10014px 0 0 0 #393948;
animation: dot-typing 1.5s infinite linear;
}
@keyframes dot-typing {
0% {
box-shadow: 9984px 0 0 0 #393948, 9999px 0 0 0 #393948, 10014px 0 0 0 #393948;
}
16.667% {
box-shadow: 9984px -10px 0 0 #393948, 9999px 0 0 0 #393948, 10014px 0 0 0 #393948;
}
33.333% {
box-shadow: 9984px 0 0 0 #393948, 9999px 0 0 0 #393948, 10014px 0 0 0 #393948;
}
50% {
box-shadow: 9984px 0 0 0 #393948, 9999px -10px 0 0 #393948, 10014px 0 0 0 #393948;
}
66.667% {
box-shadow: 9984px 0 0 0 #393948, 9999px 0 0 0 #393948, 10014px 0 0 0 #393948;
}
83.333% {
box-shadow: 9984px 0 0 0 #393948, 9999px 0 0 0 #393948, 10014px -10px 0 0 #393948;
}
100% {
box-shadow: 9984px 0 0 0 #393948, 9999px 0 0 0 #393948, 10014px 0 0 0 #393948;
}
}
/**
* ==============================================
* Dot Bricks
* ==============================================
*/
.dot-bricks {
position: relative;
top: 8px;
left: -9999px;
width: 10px;
height: 10px;
border-radius: 5px;
background-color: #393948;
color: #393948;
box-shadow: 9991px -16px 0 0 #393948, 9991px 0 0 0 #393948, 10007px 0 0 0 #393948;
animation: dot-bricks 2s infinite ease;
}
@keyframes dot-bricks {
0% {
box-shadow: 9991px -16px 0 0 #393948, 9991px 0 0 0 #393948, 10007px 0 0 0 #393948;
}
8.333% {
box-shadow: 10007px -16px 0 0 #393948, 9991px 0 0 0 #393948, 10007px 0 0 0 #393948;
}
16.667% {
box-shadow: 10007px -16px 0 0 #393948, 9991px -16px 0 0 #393948, 10007px 0 0 0 #393948;
}
25% {
box-shadow: 10007px -16px 0 0 #393948, 9991px -16px 0 0 #393948, 9991px 0 0 0 #393948;
}
33.333% {
box-shadow: 10007px 0 0 0 #393948, 9991px -16px 0 0 #393948, 9991px 0 0 0 #393948;
}
41.667% {
box-shadow: 10007px 0 0 0 #393948, 10007px -16px 0 0 #393948, 9991px 0 0 0 #393948;
}
50% {
box-shadow: 10007px 0 0 0 #393948, 10007px -16px 0 0 #393948, 9991px -16px 0 0 #393948;
}
58.333% {
box-shadow: 9991px 0 0 0 #393948, 10007px -16px 0 0 #393948, 9991px -16px 0 0 #393948;
}
66.666% {
box-shadow: 9991px 0 0 0 #393948, 10007px 0 0 0 #393948, 9991px -16px 0 0 #393948;
}
75% {
box-shadow: 9991px 0 0 0 #393948, 10007px 0 0 0 #393948, 10007px -16px 0 0 #393948;
}
83.333% {
box-shadow: 9991px -16px 0 0 #393948, 10007px 0 0 0 #393948, 10007px -16px 0 0 #393948;
}
91.667% {
box-shadow: 9991px -16px 0 0 #393948, 9991px 0 0 0 #393948, 10007px -16px 0 0 #393948;
}
100% {
box-shadow: 9991px -16px 0 0 #393948, 9991px 0 0 0 #393948, 10007px 0 0 0 #393948;
}
}