Skip to content

Commit 7299c1a

Browse files
Dialog performance - delay skeleton animation (codesandbox#3822)
* wait for dialog to come in before skeleton animates * smoothen it up with at least delayed data fetching Co-authored-by: Christian Alfoni <christianalfoni@gmail.com>
1 parent 33af27f commit 7299c1a

File tree

6 files changed

+59
-17
lines changed

6 files changed

+59
-17
lines changed

packages/app/src/app/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const DIALOG_TRANSITION_DURATION = 0.25;
2+
export const DIALOG_WIDTH = 420;
3+
export const REPLY_TRANSITION_DELAY = 0.5;

packages/app/src/app/overmind/effects/browser.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,27 @@ export default {
8989
localStorage.setItem(key, JSON.stringify(value));
9090
},
9191
},
92+
/**
93+
* Wait at least MS before resolving the value
94+
*/
95+
waitAtLeast<T>(ms: number, cb: () => Promise<T>): Promise<T> {
96+
return new Promise((resolve, reject) => {
97+
let resolveValue: T;
98+
setTimeout(() => {
99+
if (!resolveValue) {
100+
return;
101+
}
102+
resolve(resolveValue);
103+
}, ms);
104+
const startTime = Date.now();
105+
cb()
106+
.then(value => {
107+
resolveValue = value;
108+
if (Date.now() - startTime > ms) {
109+
resolve(resolveValue);
110+
}
111+
})
112+
.catch(reject);
113+
});
114+
},
92115
};

packages/app/src/app/overmind/namespaces/comments/actions.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
import { CommentsFilterOption } from '@codesandbox/common/lib/types';
2+
import {
3+
DIALOG_TRANSITION_DURATION,
4+
REPLY_TRANSITION_DELAY,
5+
} from 'app/constants';
26
import {
37
CodeReference,
48
CommentAddedSubscription,
@@ -65,10 +69,14 @@ export const getComments: AsyncAction<string> = async (
6569
// No idea why TS complains about this
6670
// @ts-ignore
6771
sandbox: { comment },
68-
} = await effects.gql.queries.comment({
69-
sandboxId: sandbox.id,
70-
commentId,
71-
});
72+
} = await effects.browser.waitAtLeast(
73+
DIALOG_TRANSITION_DURATION + REPLY_TRANSITION_DELAY,
74+
() =>
75+
effects.gql.queries.comment({
76+
sandboxId: sandbox.id,
77+
commentId,
78+
})
79+
);
7280

7381
comment.comments.forEach(childComment => {
7482
state.comments.comments[sandbox.id][childComment.id] = childComment;

packages/app/src/app/overmind/namespaces/comments/constants.ts

Whitespace-only changes.

packages/app/src/app/pages/Sandbox/Editor/Workspace/screens/Comments/Dialog/Reply.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
import { Element, Menu, Stack, SkeletonText } from '@codesandbox/components';
1+
import { Element, Menu, SkeletonText, Stack } from '@codesandbox/components';
22
import css from '@styled-system/css';
3+
import { DIALOG_TRANSITION_DURATION } from 'app/constants';
34
import { CommentFragment } from 'app/graphql/types';
45
import { useOvermind } from 'app/overmind';
56
import React, { useState } from 'react';
67

7-
import { Markdown } from './Markdown';
88
import { AvatarBlock } from '../components/AvatarBlock';
99
import { EditComment } from '../components/EditComment';
10+
import { Markdown } from './Markdown';
1011

1112
type ReplyProps = {
1213
reply: CommentFragment;
1314
};
1415

16+
const animationDelay = DIALOG_TRANSITION_DURATION + 's';
17+
1518
export const Reply = ({ reply }: ReplyProps) => {
1619
const { user, id, content } = reply;
1720
const { state, actions } = useOvermind();
@@ -84,18 +87,22 @@ export const Reply = ({ reply }: ReplyProps) => {
8487
export const SkeletonReply = props => (
8588
<Element marginX={4} paddingTop={6} {...props}>
8689
<Stack align="center" gap={2} marginBottom={4}>
87-
<SkeletonText style={{ width: '32px', height: '32px' }} />
90+
<SkeletonText style={{ width: '32px', height: '32px', animationDelay }} />
8891

8992
<Stack direction="vertical" gap={1}>
90-
<SkeletonText style={{ width: '120px', height: '14px' }} />
91-
<SkeletonText style={{ width: '120px', height: '14px' }} />
93+
<SkeletonText
94+
style={{ width: '120px', height: '14px', animationDelay }}
95+
/>
96+
<SkeletonText
97+
style={{ width: '120px', height: '14px', animationDelay }}
98+
/>
9299
</Stack>
93100
</Stack>
94101

95102
<Stack direction="vertical" gap={1} marginBottom={6}>
96-
<SkeletonText style={{ width: '100%', height: '14px' }} />
97-
<SkeletonText style={{ width: '100%', height: '14px' }} />
98-
<SkeletonText style={{ width: '100%', height: '14px' }} />
103+
<SkeletonText style={{ width: '100%', height: '14px', animationDelay }} />
104+
<SkeletonText style={{ width: '100%', height: '14px', animationDelay }} />
105+
<SkeletonText style={{ width: '100%', height: '14px', animationDelay }} />
99106
</Stack>
100107
</Element>
101108
);

packages/app/src/app/pages/Sandbox/Editor/Workspace/screens/Comments/Dialog/index.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,19 @@ import {
88
Text,
99
Textarea,
1010
} from '@codesandbox/components';
11-
import { createGlobalStyle } from 'styled-components';
1211
import css from '@styled-system/css';
12+
import {
13+
DIALOG_TRANSITION_DURATION,
14+
DIALOG_WIDTH,
15+
REPLY_TRANSITION_DELAY,
16+
} from 'app/constants';
1317
import { CommentFragment } from 'app/graphql/types';
1418
import { useOvermind } from 'app/overmind';
1519
import { OPTIMISTIC_COMMENT_ID } from 'app/overmind/namespaces/comments/state';
1620
import { motion, useAnimation } from 'framer-motion';
1721
import React, { useState } from 'react';
1822
import ReactDOM from 'react-dom';
23+
import { createGlobalStyle } from 'styled-components';
1924

2025
import { AvatarBlock } from '../components/AvatarBlock';
2126
import { EditComment } from '../components/EditComment';
@@ -26,10 +31,6 @@ import { useScrollTop } from './use-scroll-top';
2631
export const CommentDialog = props =>
2732
ReactDOM.createPortal(<Dialog {...props} />, document.body);
2833

29-
const DIALOG_WIDTH = 420;
30-
const DIALOG_TRANSITION_DURATION = 0.25;
31-
const REPLY_TRANSITION_DELAY = 0.5;
32-
3334
export const Dialog: React.FC = () => {
3435
const { state } = useOvermind();
3536
const controller = useAnimation();

0 commit comments

Comments
 (0)