mirror of
https://github.com/excalidraw/excalidraw.git
synced 2024-11-10 11:35:52 +01:00
55 lines
1.3 KiB
TypeScript
55 lines
1.3 KiB
TypeScript
|
import { Tooltip } from "../../packages/excalidraw/components/Tooltip";
|
||
|
import { warning } from "../../packages/excalidraw/components/icons";
|
||
|
import clsx from "clsx";
|
||
|
import { useEffect, useRef, useState } from "react";
|
||
|
|
||
|
import "./CollabError.scss";
|
||
|
import { atom } from "jotai";
|
||
|
|
||
|
type ErrorIndicator = {
|
||
|
message: string | null;
|
||
|
/** used to rerun the useEffect responsible for animation */
|
||
|
nonce: number;
|
||
|
};
|
||
|
|
||
|
export const collabErrorIndicatorAtom = atom<ErrorIndicator>({
|
||
|
message: null,
|
||
|
nonce: 0,
|
||
|
});
|
||
|
|
||
|
const CollabError = ({ collabError }: { collabError: ErrorIndicator }) => {
|
||
|
const [isAnimating, setIsAnimating] = useState(false);
|
||
|
const clearAnimationRef = useRef<string | number | NodeJS.Timeout>();
|
||
|
|
||
|
useEffect(() => {
|
||
|
setIsAnimating(true);
|
||
|
clearAnimationRef.current = setTimeout(() => {
|
||
|
setIsAnimating(false);
|
||
|
}, 1000);
|
||
|
|
||
|
return () => {
|
||
|
clearTimeout(clearAnimationRef.current);
|
||
|
};
|
||
|
}, [collabError.message, collabError.nonce]);
|
||
|
|
||
|
if (!collabError.message) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
<Tooltip label={collabError.message} long={true}>
|
||
|
<div
|
||
|
className={clsx("collab-errors-button", {
|
||
|
"collab-errors-button-shake": isAnimating,
|
||
|
})}
|
||
|
>
|
||
|
{warning}
|
||
|
</div>
|
||
|
</Tooltip>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
CollabError.displayName = "CollabError";
|
||
|
|
||
|
export default CollabError;
|