Page MenuHomePhabricator

D8294.diff
No OneTemporary

D8294.diff

diff --git a/lib/hooks/useResettingState.js b/lib/hooks/useResettingState.js
new file mode 100644
--- /dev/null
+++ b/lib/hooks/useResettingState.js
@@ -0,0 +1,26 @@
+// @flow
+
+import _debounce from 'lodash/debounce.js';
+import * as React from 'react';
+
+import type { SetState } from '../types/hook-types.js';
+
+function useResettingState<T>(
+ initialState: (() => T) | T,
+ duration: number,
+): [T, SetState<T>] {
+ const [value, setValue] = React.useState(initialState);
+ const resetStatusAfterTimeout = React.useRef(
+ _debounce(() => setValue(initialState), duration),
+ );
+ React.useEffect(() => resetStatusAfterTimeout.current.cancel, []);
+
+ const setNewValue = React.useCallback((newValue: (T => T) | T) => {
+ setValue(newValue);
+ resetStatusAfterTimeout.current();
+ }, []);
+
+ return React.useMemo(() => [value, setNewValue], [setNewValue, value]);
+}
+
+export { useResettingState };
diff --git a/web/invite-links/view-invite-link-modal.react.js b/web/invite-links/view-invite-link-modal.react.js
--- a/web/invite-links/view-invite-link-modal.react.js
+++ b/web/invite-links/view-invite-link-modal.react.js
@@ -5,6 +5,7 @@
import { useModalContext } from 'lib/components/modal-provider.react.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
import { inviteLinkUrl } from 'lib/facts/links.js';
+import { useResettingState } from 'lib/hooks/useResettingState.js';
import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
import type { InviteLink } from 'lib/types/link-types.js';
import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
@@ -18,6 +19,7 @@
+inviteLink: InviteLink,
};
+const copiedMessageDurationMs = 2000;
function ViewInviteLinkModal(props: Props): React.Node {
const { inviteLink } = props;
const threadInfo = useSelector(
@@ -27,9 +29,16 @@
const { popModal } = useModalContext();
const url = inviteLinkUrl(inviteLink.name);
- const copyLink = React.useCallback(() => {
- navigator.clipboard.writeText(url);
- }, [url]);
+ const [copied, setCopied] = useResettingState(false, copiedMessageDurationMs);
+ const copyLink = React.useCallback(async () => {
+ try {
+ await navigator.clipboard.writeText(url);
+ setCopied(true);
+ } catch (e) {
+ setCopied(false);
+ }
+ }, [setCopied, url]);
+ const buttonText = copied ? 'Copied!' : 'Copy';
return (
<Modal
@@ -46,7 +55,7 @@
<div className={css.linkUrl}>{url}</div>
<Button className={css.linkCopyButton} onClick={copyLink}>
<SWMansionIcon icon="link" size={24} />
- Copy
+ {buttonText}
</Button>
</div>
</div>
diff --git a/web/utils/tooltip-action-utils.js b/web/utils/tooltip-action-utils.js
--- a/web/utils/tooltip-action-utils.js
+++ b/web/utils/tooltip-action-utils.js
@@ -1,10 +1,10 @@
// @flow
import invariant from 'invariant';
-import _debounce from 'lodash/debounce.js';
import * as React from 'react';
import { useModalContext } from 'lib/components/modal-provider.react.js';
+import { useResettingState } from 'lib/hooks/useResettingState.js';
import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js';
import { useCanEditMessage } from 'lib/shared/edit-messages-utils.js';
import { createMessageReply } from 'lib/shared/message-utils.js';
@@ -120,18 +120,11 @@
): ?MessageTooltipAction {
const { messageInfo } = item;
- const [successful, setSuccessful] = React.useState(false);
- const resetStatusAfterTimeout = React.useRef(
- _debounce(() => setSuccessful(false), copiedMessageDurationMs),
+ const [successful, setSuccessful] = useResettingState(
+ false,
+ copiedMessageDurationMs,
);
- const onSuccess = React.useCallback(() => {
- setSuccessful(true);
- resetStatusAfterTimeout.current();
- }, []);
-
- React.useEffect(() => resetStatusAfterTimeout.current.cancel, []);
-
return React.useMemo(() => {
if (messageInfo.type !== messageTypes.TEXT) {
return null;
@@ -140,7 +133,7 @@
const onClick = async () => {
try {
await navigator.clipboard.writeText(messageInfo.text);
- onSuccess();
+ setSuccessful(true);
} catch (e) {
setSuccessful(false);
}
@@ -150,7 +143,7 @@
onClick,
label: successful ? 'Copied!' : 'Copy',
};
- }, [messageInfo.text, messageInfo.type, onSuccess, successful]);
+ }, [messageInfo.text, messageInfo.type, setSuccessful, successful]);
}
function useMessageReactAction(

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 27, 4:19 AM (21 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2587863
Default Alt Text
D8294.diff (4 KB)

Event Timeline