Composer: Fix syncing drafts between tabs

This commit is contained in:
Alexander Zinchuk 2023-02-22 23:48:48 +01:00
parent c3fd837a81
commit c624675e9f
4 changed files with 40 additions and 15 deletions

View File

@ -4,7 +4,9 @@ import React, {
} from '../../../lib/teact/teact';
import { getActions, withGlobal } from '../../../global';
import type { TabState, MessageListType, GlobalState } from '../../../global/types';
import type {
TabState, MessageListType, GlobalState, ApiDraft,
} from '../../../global/types';
import type {
ApiAttachment,
ApiBotInlineResult,
@ -147,7 +149,7 @@ type StateProps =
{
editingMessage?: ApiMessage;
chat?: ApiChat;
draft?: ApiFormattedText;
draft?: ApiDraft;
isChatWithBot?: boolean;
isChatWithSelf?: boolean;
isChannel?: boolean;

View File

@ -1,7 +1,8 @@
import { useCallback, useEffect } from '../../../../lib/teact/teact';
import { getActions } from '../../../../global';
import type { ApiFormattedText, ApiMessage } from '../../../../api/types';
import type { ApiDraft } from '../../../../global/types';
import type { ApiMessage } from '../../../../api/types';
import type { Signal } from '../../../../util/signals';
import { ApiMessageEntityTypes } from '../../../../api/types';
@ -26,7 +27,7 @@ function freeze() {
}
const useDraft = (
draft: ApiFormattedText | undefined,
draft: ApiDraft | undefined,
chatId: string,
threadId: number,
getHtml: Signal<string>,
@ -38,7 +39,7 @@ const useDraft = (
const isEditing = Boolean(editedMessage);
const updateDraft = useCallback((prevState: { chatId?: string; threadId?: number } = {}) => {
const updateDraft = useCallback((prevState: { chatId?: string; threadId?: number } = {}, shouldForce = false) => {
if (isEditing || !lastSyncTime) return;
const html = getHtml();
@ -48,15 +49,21 @@ const useDraft = (
chatId: prevState.chatId ?? chatId,
threadId: prevState.threadId ?? threadId,
draft: parseMessageInput(html),
shouldForce,
});
} else {
clearDraft({
chatId: prevState.chatId ?? chatId,
threadId: prevState.threadId ?? threadId,
shouldForce,
});
}
}, [chatId, threadId, isEditing, lastSyncTime, getHtml, saveDraft, clearDraft]);
const forceUpdateDraft = useCallback(() => {
updateDraft(undefined, true);
}, [updateDraft]);
const updateDraftRef = useStateRef(updateDraft);
const runDebouncedForSaveDraft = useRunDebounced(DRAFT_DEBOUNCE, true, undefined, [chatId, threadId]);
@ -67,7 +74,9 @@ const useDraft = (
setHtml('');
}
return;
if (!draft?.shouldForce) {
return;
}
}
if (editedMessage || !draft) {
@ -130,8 +139,8 @@ const useDraft = (
});
}, [chatIdRef, getHtml, runDebouncedForSaveDraft, threadIdRef, updateDraftRef]);
useBackgroundMode(updateDraft);
useBeforeUnload(updateDraft);
useBackgroundMode(forceUpdateDraft);
useBeforeUnload(forceUpdateDraft);
};
export default useDraft;

View File

@ -2,7 +2,7 @@ import type { RequiredGlobalActions } from '../../index';
import { addActionHandler, getGlobal, setGlobal } from '../../index';
import type {
ActionReturnType, GlobalState, TabArgs,
ActionReturnType, ApiDraft, GlobalState, TabArgs,
} from '../../types';
import type {
ApiAttachment,
@ -356,7 +356,9 @@ addActionHandler('cancelSendingMessage', (global, actions, payload): ActionRetur
});
addActionHandler('saveDraft', async (global, actions, payload): Promise<void> => {
const { chatId, threadId, draft } = payload!;
const {
chatId, threadId, draft, shouldForce,
} = payload;
if (!draft) {
return;
}
@ -366,6 +368,13 @@ addActionHandler('saveDraft', async (global, actions, payload): Promise<void> =>
const user = selectUser(global, chatId)!;
if (user && isDeletedUser(user)) return;
draft.isLocal = true;
draft.shouldForce = shouldForce;
global = replaceThreadParam(global, chatId, threadId, 'draft', draft);
global = updateChat(global, chatId, { draftDate: Math.round(Date.now() / 1000) });
setGlobal(global);
const result = await callApi('saveDraft', {
chat,
text,
@ -374,8 +383,8 @@ addActionHandler('saveDraft', async (global, actions, payload): Promise<void> =>
threadId: selectThreadTopMessageId(global, chatId, threadId),
});
if (!result) {
draft.isLocal = true;
if (result) {
draft.isLocal = false;
}
global = getGlobal();
@ -386,7 +395,9 @@ addActionHandler('saveDraft', async (global, actions, payload): Promise<void> =>
});
addActionHandler('clearDraft', (global, actions, payload): ActionReturnType => {
const { chatId, threadId = MAIN_THREAD_ID, localOnly } = payload!;
const {
chatId, threadId = MAIN_THREAD_ID, localOnly, shouldForce,
} = payload;
if (!selectDraft(global, chatId, threadId)) {
return undefined;
}
@ -397,7 +408,8 @@ addActionHandler('clearDraft', (global, actions, payload): ActionReturnType => {
void callApi('clearDraft', chat, selectThreadTopMessageId(global, chatId, threadId));
}
global = replaceThreadParam(global, chatId, threadId, 'draft', undefined);
const newDraft: ApiDraft | undefined = shouldForce ? { shouldForce, text: '' } : undefined;
global = replaceThreadParam(global, chatId, threadId, 'draft', newDraft);
global = updateChat(global, chatId, { draftDate: undefined });
return global;

View File

@ -799,7 +799,7 @@ export type CallbackAction = Values<{
}
}>;
export type ApiDraft = ApiFormattedText & { isLocal?: boolean };
export type ApiDraft = ApiFormattedText & { isLocal?: boolean; shouldForce?: boolean };
type WithTabId = { tabId?: number };
@ -1237,11 +1237,13 @@ export interface ActionPayloads {
chatId: string;
threadId: number;
draft: ApiDraft;
shouldForce?: boolean;
};
clearDraft: {
chatId: string;
threadId?: number;
localOnly?: boolean;
shouldForce?: boolean;
};
loadPinnedMessages: {
chatId: string;