mirror of
https://github.com/wassname/talk.git
synced 2026-06-27 22:24:06 +08:00
setTimeout Fixes (#3082)
* 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>
This commit is contained in:
@@ -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) {
|
||||
@@ -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(() => {
|
||||
@@ -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();
|
||||
|
||||
@@ -3,7 +3,6 @@ import React, {
|
||||
FunctionComponent,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react";
|
||||
import CopyToClipboard from "react-copy-to-clipboard";
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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(() => {
|
||||
async function doTheFetch() {
|
||||
setState(null);
|
||||
setLoading(true);
|
||||
const value = await fetcher(variables);
|
||||
let aborted = false;
|
||||
|
||||
// TODO: Maybe we don't need this timeout?
|
||||
setTimeout(() => {
|
||||
setState(value);
|
||||
setLoading(false);
|
||||
}, 100 + 50 * Math.random());
|
||||
async function doTheFetch() {
|
||||
// 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];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+5
-3
@@ -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";
|
||||
|
||||
@@ -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),
|
||||
@@ -93,7 +93,9 @@ export class EditCommentFormContainer extends Component<Props, State> {
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
clearLongTimeout(this.expiredTimer);
|
||||
if (this.expiredTimer) {
|
||||
clearLongTimeout(this.expiredTimer);
|
||||
}
|
||||
}
|
||||
|
||||
private updateWhenExpired() {
|
||||
|
||||
Reference in New Issue
Block a user