Composer: Fix syncing drafts between tabs
This commit is contained in:
parent
c3fd837a81
commit
c624675e9f
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user