Composer: Respect no_webpage option when editing a message (#2804)

This commit is contained in:
Alexander Zinchuk 2023-03-30 18:25:01 -05:00
parent b41827d291
commit 4cbe9c1112

View File

@ -4,9 +4,10 @@ import { getActions } from '../../../../global';
import type { ApiFormattedText, ApiMessage } from '../../../../api/types';
import type { MessageListType } from '../../../../global/types';
import type { Signal } from '../../../../util/signals';
import { ApiMessageEntityTypes } from '../../../../api/types';
import useEffectWithPrevDeps from '../../../../hooks/useEffectWithPrevDeps';
import { EDITABLE_INPUT_CSS_SELECTOR } from '../../../../config';
import useEffectWithPrevDeps from '../../../../hooks/useEffectWithPrevDeps';
import parseMessageInput from '../../../../util/parseMessageInput';
import focusEditableElement from '../../../../util/focusEditableElement';
import { hasMessageMedia } from '../../../../global/helpers';
@ -14,6 +15,11 @@ import { getTextWithEntitiesAsHtml } from '../../../common/helpers/renderTextWit
import { fastRaf } from '../../../../util/schedulers';
import useBackgroundMode from '../../../../hooks/useBackgroundMode';
import useBeforeUnload from '../../../../hooks/useBeforeUnload';
import { useDebouncedResolver } from '../../../../hooks/useAsyncResolvers';
import useDerivedSignal from '../../../../hooks/useDerivedSignal';
const URL_ENTITIES = new Set<string>([ApiMessageEntityTypes.TextUrl, ApiMessageEntityTypes.Url]);
const DEBOUNCE_MS = 300;
const useEditing = (
getHtml: Signal<string>,
@ -28,7 +34,7 @@ const useEditing = (
editingDraft?: ApiFormattedText,
replyingToId?: number,
): [VoidFunction, VoidFunction, boolean] => {
const { editMessage, setEditingDraft } = getActions();
const { editMessage, setEditingDraft, toggleMessageWebPage } = getActions();
const [shouldForceShowEditing, setShouldForceShowEditing] = useState<boolean>();
useEffectWithPrevDeps(([prevEditedMessage, prevReplyingToId]) => {
@ -61,6 +67,21 @@ const useEditing = (
// eslint-disable-next-line react-hooks-static-deps/exhaustive-deps -- `as const` not yet supported by linter
}, [editedMessage, replyingToId, setHtml] as const);
useEffect(() => {
if (!editedMessage) {
return;
}
const shouldSetNoWebPage = !('webPage' in editedMessage.content)
&& editedMessage.content.text?.entities?.some((entity) => URL_ENTITIES.has(entity.type));
toggleMessageWebPage({
chatId,
threadId,
noWebPage: shouldSetNoWebPage,
});
}, [chatId, threadId, editedMessage]);
useEffect(() => {
if (!editedMessage) return undefined;
return () => {
@ -73,6 +94,32 @@ const useEditing = (
};
}, [chatId, editedMessage, getHtml, setEditingDraft, threadId, type]);
const detectLinkDebounced = useDebouncedResolver(() => {
if (!editedMessage) return false;
const edited = parseMessageInput(getHtml());
return !('webPage' in editedMessage.content)
&& editedMessage.content.text?.entities?.some((entity) => URL_ENTITIES.has(entity.type))
&& !(edited.entities?.some((entity) => URL_ENTITIES.has(entity.type)));
}, [editedMessage, getHtml], DEBOUNCE_MS, true);
const getShouldResetNoWebPageDebounced = useDerivedSignal(detectLinkDebounced, [detectLinkDebounced, getHtml], true);
useEffectWithPrevDeps(([prevEditedMessage]) => {
if (!editedMessage || prevEditedMessage?.id !== editedMessage.id) {
return;
}
if (getShouldResetNoWebPageDebounced()) {
toggleMessageWebPage({
chatId,
threadId,
noWebPage: false,
});
}
// eslint-disable-next-line react-hooks-static-deps/exhaustive-deps -- `as const` not yet supported by linter
}, [editedMessage, chatId, getHtml, threadId] as const);
const restoreNewDraftAfterEditing = useCallback(() => {
if (!draft) return;
// Run 1 frame after editing draft reset