mirror of
https://github.com/revoltchat/revite.git
synced 2024-12-24 22:52:09 -05:00
Add animations to loaders.
This commit is contained in:
parent
e98a962071
commit
22b21c030f
16 changed files with 123 additions and 21 deletions
|
@ -49,7 +49,7 @@ export default function TextFile({ attachment }: Props) {
|
|||
content ?
|
||||
<pre><code>{ content }</code></pre>
|
||||
: <RequiresOnline>
|
||||
<Preloader />
|
||||
<Preloader type="ring" />
|
||||
</RequiresOnline>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,103 @@
|
|||
export default function Preloader() {
|
||||
return <span>LOADING</span>;
|
||||
import styled, { keyframes } from "styled-components";
|
||||
|
||||
const skSpinner = keyframes`
|
||||
0%, 80%, 100% {
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0);
|
||||
}
|
||||
40% {
|
||||
-webkit-transform: scale(1.0);
|
||||
transform: scale(1.0);
|
||||
}
|
||||
`;
|
||||
|
||||
const prRing = keyframes`
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
`;
|
||||
|
||||
const PreloaderBase = styled.div`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
display: grid;
|
||||
place-items: center;
|
||||
|
||||
.spinner {
|
||||
width: 58px;
|
||||
display: flex;
|
||||
text-align: center;
|
||||
margin: 100px auto 0;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.spinner > div {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background-color: var(--tertiary-foreground);
|
||||
|
||||
border-radius: 100%;
|
||||
display: inline-block;
|
||||
animation: ${skSpinner} 1.4s infinite ease-in-out both;
|
||||
}
|
||||
|
||||
.spinner div:nth-child(1) {
|
||||
animation-delay: -0.32s;
|
||||
}
|
||||
|
||||
.spinner div:nth-child(2) {
|
||||
animation-delay: -0.16s;
|
||||
}
|
||||
|
||||
.ring {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 48px;
|
||||
height: 52px;
|
||||
}
|
||||
|
||||
.ring div {
|
||||
width: 32px;
|
||||
margin: 8px;
|
||||
height: 32px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
border: 2px solid #fff;
|
||||
animation: ${prRing} 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||
border-color: #fff transparent transparent transparent;
|
||||
}
|
||||
|
||||
.ring div:nth-child(1) {
|
||||
animation-delay: -0.45s;
|
||||
}
|
||||
|
||||
.ring div:nth-child(2) {
|
||||
animation-delay: -0.3s;
|
||||
}
|
||||
|
||||
.ring div:nth-child(3) {
|
||||
animation-delay: -0.15s;
|
||||
}
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
type: 'spinner' | 'ring'
|
||||
}
|
||||
|
||||
export default function Preloader({ type }: Props) {
|
||||
return (
|
||||
<PreloaderBase>
|
||||
<div class={type}>
|
||||
<div />
|
||||
<div />
|
||||
<div />
|
||||
</div>
|
||||
</PreloaderBase>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ export function OnboardingModal({ onClose, callback }: Props) {
|
|||
</div>
|
||||
<div className={styles.form}>
|
||||
{loading ? (
|
||||
<Preloader />
|
||||
<Preloader type="spinner" />
|
||||
) : (
|
||||
<>
|
||||
<p>
|
||||
|
|
|
@ -309,7 +309,7 @@ export function UserProfile({ user_id, onClose, dummy, dummyProfile }: Props) {
|
|||
)}
|
||||
</div>
|
||||
) : (
|
||||
<Preloader />
|
||||
<Preloader type="ring" />
|
||||
))}
|
||||
{tab === "groups" && (
|
||||
<div className={styles.entries}>
|
||||
|
|
|
@ -187,7 +187,7 @@ export function FileUploader(props: Props) {
|
|||
onClick={onClick}>
|
||||
{ uploading ?
|
||||
<div className={styles.uploading}>
|
||||
<Preloader />
|
||||
<Preloader type="ring" />
|
||||
</div> :
|
||||
<div className={styles.edit}>
|
||||
<Edit size={30} />
|
||||
|
|
|
@ -29,7 +29,7 @@ const Base = styled.div`
|
|||
export default function RequiresOnline(props: Props) {
|
||||
const status = useContext(StatusContext);
|
||||
|
||||
if (status === ClientStatus.CONNECTING) return <Preloader />;
|
||||
if (status === ClientStatus.CONNECTING) return <Preloader type="ring" />;
|
||||
if (status !== ClientStatus.ONLINE && status !== ClientStatus.READY)
|
||||
return (
|
||||
<Base>
|
||||
|
|
|
@ -202,7 +202,7 @@ function Context({ auth, sync, children, dispatcher }: Props) {
|
|||
}, []);
|
||||
|
||||
if (status === ClientStatus.LOADING) {
|
||||
return <Preloader />;
|
||||
return <Preloader type="spinner" />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -34,13 +34,15 @@ const Routes = styled.div`
|
|||
export default function App() {
|
||||
const path = useLocation().pathname;
|
||||
const fixedBottomNav = (path === '/' || path === '/settings' || path.startsWith("/friends"));
|
||||
const inSettings = path === '/settings';
|
||||
const inChannel = path.includes('/channel');
|
||||
|
||||
return (
|
||||
<OverlappingPanels
|
||||
width="100vw"
|
||||
height="100vh"
|
||||
leftPanel={{ width: 292, component: <LeftSidebar /> }}
|
||||
rightPanel={{ width: 240, component: <RightSidebar /> }}
|
||||
leftPanel={inSettings ? undefined : { width: 292, component: <LeftSidebar /> }}
|
||||
rightPanel={(!inSettings && inChannel) ? { width: 240, component: <RightSidebar /> } : undefined}
|
||||
bottomNav={{
|
||||
component: <BottomNavigation />,
|
||||
showIf: fixedBottomNav ? ShowIf.Always : ShowIf.Left,
|
||||
|
|
|
@ -12,7 +12,7 @@ export function App() {
|
|||
<Context>
|
||||
{/*
|
||||
// @ts-expect-error */}
|
||||
<Suspense fallback={<Preloader />}>
|
||||
<Suspense fallback={<Preloader type="spinner" />}>
|
||||
<Switch>
|
||||
<Route path="/login">
|
||||
<CheckAuth>
|
||||
|
|
|
@ -215,10 +215,10 @@ export function MessageArea({ id }: Props) {
|
|||
<MessageAreaWidthContext.Provider value={(width ?? 0) - MESSAGE_AREA_PADDING}>
|
||||
<Area ref={ref}>
|
||||
<div>
|
||||
{state.type === "LOADING" && <Preloader />}
|
||||
{state.type === "LOADING" && <Preloader type="ring" />}
|
||||
{state.type === "WAITING_FOR_NETWORK" && (
|
||||
<RequiresOnline>
|
||||
<Preloader />
|
||||
<Preloader type="ring" />
|
||||
</RequiresOnline>
|
||||
)}
|
||||
{state.type === "RENDER" && (
|
||||
|
|
|
@ -60,7 +60,7 @@ function MessageRenderer({ id, state, queue }: Props) {
|
|||
} else {
|
||||
render.push(
|
||||
<RequiresOnline>
|
||||
<Preloader />
|
||||
<Preloader type="ring" />
|
||||
</RequiresOnline>
|
||||
);
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ function MessageRenderer({ id, state, queue }: Props) {
|
|||
} else {
|
||||
render.push(
|
||||
<RequiresOnline>
|
||||
<Preloader />
|
||||
<Preloader type="ring" />
|
||||
</RequiresOnline>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ export default function Invite() {
|
|||
<div className={styles.preloader}>
|
||||
<RequiresOnline>
|
||||
{ error ? <Overline type="error" error={error} />
|
||||
: <Preloader /> }
|
||||
: <Preloader type="spinner" /> }
|
||||
</RequiresOnline>
|
||||
</div>
|
||||
)
|
||||
|
@ -52,7 +52,7 @@ export default function Invite() {
|
|||
</div> }
|
||||
|
||||
<div className={styles.details}>
|
||||
{ processing ? <Preloader /> :
|
||||
{ processing ? <Preloader type="ring" /> :
|
||||
<>
|
||||
<h1>{ invite.server_name }</h1>
|
||||
<h2>#{invite.channel_name}</h2>
|
||||
|
|
|
@ -20,7 +20,7 @@ export function CaptchaBlock(props: CaptchaProps) {
|
|||
}, []);
|
||||
|
||||
if (!client.configuration?.features.captcha.enabled)
|
||||
return <Preloader />;
|
||||
return <Preloader type="spinner" />;
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
|
|
@ -138,7 +138,7 @@ export function Form({ page, callback }: Props) {
|
|||
}
|
||||
|
||||
if (captcha) return <CaptchaBlock {...captcha} />;
|
||||
if (loading) return <Preloader />;
|
||||
if (loading) return <Preloader type="spinner" />;
|
||||
|
||||
return (
|
||||
<div className={styles.form}>
|
||||
|
|
|
@ -55,7 +55,7 @@ export function Sessions() {
|
|||
if (typeof sessions === "undefined") {
|
||||
return (
|
||||
<div className={styles.loader}>
|
||||
<Preloader />
|
||||
<Preloader type="ring" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ export function Invites({ server }: Props) {
|
|||
|
||||
return (
|
||||
<div className={styles.invites}>
|
||||
{ typeof invites === 'undefined' && <Preloader /> }
|
||||
{ typeof invites === 'undefined' && <Preloader type="ring" /> }
|
||||
{
|
||||
invites?.map(
|
||||
invite => {
|
||||
|
|
Loading…
Reference in a new issue