Skip to content

Commit

Permalink
feat(subscriptions): add loading GIF dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholaschiang committed May 17, 2021
1 parent c2c5f44 commit f0e2d98
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 81 deletions.
73 changes: 73 additions & 0 deletions components/dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { ReactNode } from 'react';

export interface DialogProps {
children: ReactNode;
}

export default function Dialog({ children }: DialogProps): JSX.Element {
return (
<div className='wrapper'>
<div className='dialog'>{children}</div>
<div className='scrim' />
<style jsx>{`
.wrapper {
position: fixed;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
z-index: 1;
}
.dialog {
max-width: 540px;
max-height: calc(100% - 32px);
background: var(--background);
border-radius: 10px;
box-shadow: var(--shadow-large);
overflow: auto;
padding: 0 48px;
}
.scrim {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
background: rgba(0, 0, 0, 0.32);
opacity: 1;
}
@media (max-width: 540px) {
.wrapper {
background: var(--background);
}
.dialog {
box-shadow: none;
max-height: 100%;
}
.scrim {
display: none;
}
}
@media (max-width: 450px) {
.dialog {
padding: 0 24px;
}
h1 {
margin-top: 24px;
}
}
`}</style>
</div>
);
}
140 changes: 138 additions & 2 deletions components/subscriptions.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { mutate, useSWRInfinite } from 'swr';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import Head from 'next/head';
import Image from 'next/image';
import NProgress from 'nprogress';
import Router from 'next/router';
import cn from 'classnames';
Expand All @@ -10,6 +11,7 @@ import { SubscriptionsRes } from 'pages/api/subscriptions';

import Avatar from 'components/avatar';
import Button from 'components/button';
import Dialog from 'components/dialog';
import Empty from 'components/empty';

import { Subscription } from 'lib/model/subscription';
Expand All @@ -18,6 +20,141 @@ import { fetcher } from 'lib/fetch';
import { period } from 'lib/utils';
import { useUser } from 'lib/context/user';

const LOADING_MESSAGES = [
'Getting your subscriptions...',
'This might take a moment...',
'One more second...',
'Almost there...',
];

function LoadingDialog(): JSX.Element {
const [message, setMessage] = useState<string>(LOADING_MESSAGES[0]);
useEffect(() => {
const intervalId = setInterval(() => {
setMessage((prev) => {
const idx = LOADING_MESSAGES.indexOf(prev);
if (idx === LOADING_MESSAGES.length - 1) {
clearInterval(intervalId);
return prev;
}
return LOADING_MESSAGES[idx + 1];
});
}, 5000);
return () => clearInterval(intervalId);
}, []);

return (
<Dialog>
<h2>{message}</h2>
<div className='gif'>
<div className='placeholder' />
<Image
src='/rockets.gif'
objectPosition='center'
objectFit='cover'
layout='fill'
/>
</div>
<style jsx>{`
h2 {
color: var(--accents-5);
font-size: 20px;
font-weight: 400;
line-height: 24px;
margin: 48px 0 24px;
text-align: center;
}
.gif {
border: 2px solid var(--accents-2);
border-radius: 10px;
margin: 24px 0 48px;
position: relative;
overflow: hidden;
height: 200px;
width: 400px;
max-width: 100%;
}
.gif .placeholder {
width: 100%;
height: 100%;
filter: blur(2rem);
transform: scale(1.2);
background-size: 100% 20%;
background-repeat: no-repeat;
background-position: 0 0, 0 25%, 0 50%, 0 75%, 0 100%;
background-image: linear-gradient(
90deg,
rgba(178, 195, 214, 255) 10%,
rgba(143, 166, 191, 255) 10% 20%,
rgba(116, 142, 173, 255) 20% 30%,
rgba(93, 122, 161, 255) 30% 40%,
rgba(78, 109, 150, 255) 40% 50%,
rgba(69, 100, 143, 255) 50% 60%,
rgba(57, 90, 137, 255) 60% 70%,
rgba(57, 86, 127, 255) 70% 80%,
rgba(73, 81, 88, 255) 80% 90%,
rgba(69, 76, 80, 255) 90% 100%
),
linear-gradient(
90deg,
rgba(190, 206, 220, 255) 10%,
rgba(160, 181, 205, 255) 10% 20%,
rgba(133, 158, 188, 255) 20% 30%,
rgba(110, 139, 174, 255) 30% 40%,
rgba(89, 120, 160, 255) 40% 50%,
rgba(91, 119, 155, 255) 50% 60%,
rgba(92, 120, 157, 255) 60% 70%,
rgba(80, 109, 146, 255) 70% 80%,
rgba(77, 96, 119, 255) 80% 90%,
rgba(78, 96, 119, 255) 90% 100%
),
linear-gradient(
90deg,
rgba(221, 230, 233, 255) 10%,
rgba(180, 198, 215, 255) 10% 20%,
rgba(146, 171, 201, 255) 20% 30%,
rgba(126, 155, 191, 255) 30% 40%,
rgba(121, 147, 177, 255) 40% 50%,
rgba(125, 147, 171, 255) 50% 60%,
rgba(120, 146, 175, 255) 60% 70%,
rgba(110, 138, 172, 255) 70% 80%,
rgba(104, 134, 171, 255) 80% 90%,
rgba(110, 138, 173, 255) 90% 100%
),
linear-gradient(
90deg,
rgba(245, 252, 246, 255) 10%,
rgba(230, 239, 237, 255) 10% 20%,
rgba(202, 215, 222, 255) 20% 30%,
rgba(178, 196, 212, 255) 30% 40%,
rgba(176, 190, 201, 255) 40% 50%,
rgba(162, 178, 193, 255) 50% 60%,
rgba(141, 162, 185, 255) 60% 70%,
rgba(133, 156, 182, 255) 70% 80%,
rgba(128, 150, 175, 255) 80% 90%,
rgba(125, 147, 172, 255) 90% 100%
),
linear-gradient(
90deg,
rgba(98, 101, 95, 255) 10%,
rgba(113, 115, 106, 255) 10% 20%,
rgba(115, 116, 109, 255) 20% 30%,
rgba(138, 138, 128, 255) 30% 40%,
rgba(127, 127, 118, 255) 40% 50%,
rgba(127, 127, 117, 255) 50% 60%,
rgba(131, 131, 120, 255) 60% 70%,
rgba(127, 127, 117, 255) 70% 80%,
rgba(117, 117, 104, 255) 80% 90%,
rgba(101, 100, 85, 255) 90% 100%
);
}
`}</style>
</Dialog>
);
}

interface SubscriptionRowProps {
subscription?: Subscription;
selected?: boolean;
Expand Down Expand Up @@ -234,6 +371,7 @@ export default function Subscriptions() {

return (
<div className='wrapper'>
{!data && <LoadingDialog />}
<Head>
<link rel='preload' href='/api/subscriptions' as='fetch' />
</Head>
Expand Down Expand Up @@ -317,7 +455,6 @@ export default function Subscriptions() {
font-size: 30px;
font-weight: 500;
line-height: 36px;
height: 36px;
margin: 0;
}
Expand All @@ -326,7 +463,6 @@ export default function Subscriptions() {
font-size: 20px;
font-weight: 400;
line-height: 24px;
height: 24px;
margin: 60px 0 36px;
}
Expand Down
101 changes: 22 additions & 79 deletions pages/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import NProgress from 'nprogress';
import Router from 'next/router';

import Button from 'components/button';
import Dialog from 'components/dialog';
import LockIcon from 'components/icons/lock';
import Page from 'components/page';
import SyncIcon from 'components/icons/sync';
Expand Down Expand Up @@ -100,33 +101,27 @@ export default function LoginPage(): JSX.Element {

return (
<Page title='Login - Hammock'>
<div className='wrapper'>
<div className='dialog'>
<h1>A few things to know, before we get started</h1>
<div className='line' />
<Section icon={<SyncIcon />} header='Syncs with your Gmail'>
You won’t need to get a new email address or subscribe to all your
newsletters again.
</Section>
<Section
icon={<LockIcon />}
header='We don’t read your email, promise'
>
We’ll request a few Gmail permissions to help us organize your
newsletters. Nothing else.
</Section>
<Section icon={<UndoIcon />} header='Your newsletters are yours'>
You can always go back to reading them in your inbox; we won’t be
offended.
</Section>
<div className='actions'>
<Button disabled={loading} onClick={onClick} google>
Continue signing in
</Button>
{error && <p className='error'>{error}</p>}
</div>
<Dialog>
<h1>A few things to know, before we get started</h1>
<div className='line' />
<Section icon={<SyncIcon />} header='Syncs with your Gmail'>
You won’t need to get a new email address or subscribe to all your
newsletters again.
</Section>
<Section icon={<LockIcon />} header='We don’t read your email, promise'>
We’ll request a few Gmail permissions to help us organize your
newsletters. Nothing else.
</Section>
<Section icon={<UndoIcon />} header='Your newsletters are yours'>
You can always go back to reading them in your inbox; we won’t be
offended.
</Section>
<div className='actions'>
<Button disabled={loading} onClick={onClick} google>
Continue signing in
</Button>
{error && <p className='error'>{error}</p>}
</div>
<div className='scrim' />
<style jsx>{`
h1 {
color: var(--accents-5);
Expand Down Expand Up @@ -157,65 +152,13 @@ export default function LoginPage(): JSX.Element {
margin-top: 12px;
}
.wrapper {
position: fixed;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
z-index: 1;
}
.dialog {
max-width: 540px;
max-height: calc(100% - 32px);
background: var(--background);
border-radius: 10px;
box-shadow: var(--shadow-large);
overflow: auto;
padding: 0 48px;
}
.scrim {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
background: rgba(0, 0, 0, 0.32);
opacity: 1;
}
@media (max-width: 540px) {
.dialog {
box-shadow: none;
max-height: 100%;
}
.scrim {
display: none;
}
}
@media (max-width: 450px) {
.dialog {
padding: 0 24px;
}
h1 {
margin-top: 24px;
}
.actions {
margin-bottom: 24px;
}
}
`}</style>
</div>
</Dialog>
</Page>
);
}
Binary file added public/rockets.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

1 comment on commit f0e2d98

@vercel
Copy link

@vercel vercel bot commented on f0e2d98 May 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.