Skip to content

Commit

Permalink
setTimeout Fixes (#3082)
Browse files Browse the repository at this point in the history
* fix: fixed types and some unmanaged timeouts

* fix: refetch type

Co-authored-by: Chi Vinh Le <vinh@vinh.tech>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
3 people committed Aug 6, 2020
1 parent 6fabeb2 commit b029a01
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 58 deletions.
10 changes: 5 additions & 5 deletions src/core/client/auth/hooks/useResizePopup.ts
Expand Up @@ -6,7 +6,7 @@ import resizePopup from "../dom/resizePopup";

export default function useResizePopup() {
const polling = useRef(true);
const pollTimeout = useRef<any>(null);
const pollTimeout = useRef<number | null>(null);

const pollPopupHeight = useCallback((interval = 200) => {
if (!polling.current) {
Expand All @@ -16,7 +16,7 @@ export default function useResizePopup() {
// Save the reference to the browser timeout we create.
pollTimeout.current =
// Create the timeout to fire after the interval.
setTimeout(() => {
window.setTimeout(() => {
// Using requestAnimationFrame, resize the popup, and reschedule the
// resize timeout again in another interval.
window.requestAnimationFrame(() => {
Expand All @@ -31,13 +31,13 @@ export default function useResizePopup() {
pollPopupHeight();

return () => {
if (pollTimeout) {
clearTimeout(pollTimeout.current);
if (pollTimeout.current) {
window.clearTimeout(pollTimeout.current);
pollTimeout.current = null;
polling.current = false;
}
};
}, []);
}, [pollPopupHeight]);

const ref = useResizeObserver(() => {
resizePopup();
Expand Down
64 changes: 27 additions & 37 deletions src/core/client/framework/components/CopyButton.tsx
Expand Up @@ -3,7 +3,6 @@ import React, {
FunctionComponent,
useCallback,
useEffect,
useMemo,
useState,
} from "react";
import CopyToClipboard from "react-copy-to-clipboard";
Expand All @@ -25,53 +24,44 @@ const CopyButton: FunctionComponent<Props> = ({
innerCopied,
...rest
}) => {
let timeout: any = null;
const [copied, setCopied] = useState(false);

// clear time out when we de-scope
useEffect(() => {
return function cleanup() {
clearTimeout(timeout);
};
}, [timeout]);

const timeoutCallback = useCallback(() => {
setCopied(false);
}, [setCopied]);

const handleCopy = useCallback(() => {
setCopied(true);
clearTimeout(timeout);
timeout = setTimeout(timeoutCallback, 500);
}, [timeout, setCopied]);
}, [setCopied]);

const copyBody = useMemo(() => {
if (inner) {
return inner;
// Handle the animation event associated with toggling the copied state.
useEffect(() => {
if (!copied) {
return;
}

return (
<Localized id="framework-copyButton-copy">
<span>Copy</span>
</Localized>
);
}, [inner]);
const copiedBody = useMemo(() => {
if (innerCopied) {
return innerCopied;
}
const timeout = window.setTimeout(() => {
setCopied(false);
}, 500);

return (
<Localized id="framework-copyButton-copied">
<span>Copied!</span>
</Localized>
);
}, [innerCopied]);
return () => {
window.clearTimeout(timeout);
};
}, [copied]);

return (
<CopyToClipboard text={text} onCopy={handleCopy}>
<Button color={color || "mono"} variant="flat" {...rest}>
{copied ? copiedBody : copyBody}
{copied ? (
innerCopied ? (
innerCopied
) : (
<Localized id="framework-copyButton-copied">
<span>Copied!</span>
</Localized>
)
) : inner ? (
inner
) : (
<Localized id="framework-copyButton-copy">
<span>Copy</span>
</Localized>
)}
</Button>
</CopyToClipboard>
);
Expand Down
46 changes: 33 additions & 13 deletions src/core/client/framework/lib/relay/fetch.tsx
Expand Up @@ -74,29 +74,49 @@ export function useFetch<V, R>(
export function useImmediateFetch<V extends {}, R>(
fetch: Fetch<any, V, Promise<R>>,
variables: V,
refetch?: string
refetch?: any
): [R | null, boolean] {
const fetcher = useFetch(fetch);
const [state, setState] = useState<R | null>(null);
const [loading, setLoading] = useState<boolean>(false);
const [state, setState] = useState<{ data: R | null; loading: boolean }>({
data: null,
loading: false,
});

useEffect(() => {
let aborted = false;

async function doTheFetch() {
setState(null);
setLoading(true);
const value = await fetcher(variables);

// TODO: Maybe we don't need this timeout?
setTimeout(() => {
setState(value);
setLoading(false);
}, 100 + 50 * Math.random());
// Update the state by setting loading to true.
setState((s) => ({ ...s, loading: true }));

try {
// Perform the fetch.
const data = await fetcher(variables);
if (aborted) {
// If we've aborted, we're either unmounting or a variable has changed,
// so don't bother finishing updating the state because another
// request is about to occur.
return;
}

// Update the state with the data.
setState({ data, loading: false });
} catch (err) {
// eslint-disable-next-line no-console
console.error("could not perform fetch", err);

setState({ data: null, loading: false });
}
}

void doTheFetch();

return () => {
aborted = true;
};
}, Object.values(variables).concat(isUndefined(refetch) ? [] : [refetch]));

return [state, loading];
return [state.data, state.loading];
}

/**
Expand Down
@@ -1,5 +1,5 @@
import { CoralRTE } from "@coralproject/rte";
import { clearLongTimeout, setLongTimeout } from "long-settimeout";
import { clearLongTimeout, LongTimeout, setLongTimeout } from "long-settimeout";
import React, { Component } from "react";
import { graphql } from "react-relay";

Expand Down Expand Up @@ -73,7 +73,7 @@ function getMediaFromComment(comment: CommentData) {
}

export class EditCommentFormContainer extends Component<Props, State> {
private expiredTimer: any;
private expiredTimer?: LongTimeout;
private intitialValues = {
body: this.props.comment.body || "",
media: getMediaFromComment(this.props.comment),
Expand All @@ -93,7 +93,9 @@ export class EditCommentFormContainer extends Component<Props, State> {
}

public componentWillUnmount() {
clearLongTimeout(this.expiredTimer);
if (this.expiredTimer) {
clearLongTimeout(this.expiredTimer);
}
}

private updateWhenExpired() {
Expand Down

0 comments on commit b029a01

Please sign in to comment.