ConversationView: Move deleteMessage to redux

This commit is contained in:
Scott Nonnenberg 2022-12-14 14:45:39 -08:00 committed by GitHub
parent 50d9b6e5e1
commit 7c86f02c7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 38 deletions

View file

@ -1677,10 +1677,22 @@ export async function startApp(): Promise<void> {
const { selectedMessage } = state.conversations;
if (selectedMessage) {
conversation.trigger('delete-message', selectedMessage);
event.preventDefault();
event.stopPropagation();
window.showConfirmationDialog({
dialogName: 'deleteMessage',
confirmStyle: 'negative',
message: window.i18n('deleteWarning'),
okText: window.i18n('delete'),
resolve: () => {
window.reduxActions.conversations.deleteMessage({
conversationId: conversation.id,
messageId: selectedMessage,
});
},
});
return;
}
}

View file

@ -39,7 +39,10 @@ export type PropsData = {
} & Omit<MessagePropsData, 'renderingContext' | 'menu'>;
export type PropsActions = {
deleteMessage: (id: string) => void;
deleteMessage: (options: {
conversationId: string;
messageId: string;
}) => void;
deleteMessageForEveryone: (id: string) => void;
toggleForwardMessageModal: (id: string) => void;
reactToMessage: (
@ -233,6 +236,7 @@ export function TimelineMessage(props: Props): JSX.Element {
const handleReact = canReact ? () => toggleReactionPicker() : undefined;
const [hasDOEConfirmation, setHasDOEConfirmation] = useState(false);
const [hasDeleteConfirmation, setHasDeleteConfirmation] = useState(false);
const toggleReactionPickerKeyboard = useToggleReactionPicker(
handleReact || noop
@ -266,6 +270,26 @@ export function TimelineMessage(props: Props): JSX.Element {
{i18n('deleteForEveryoneWarning')}
</ConfirmationDialog>
)}
{hasDeleteConfirmation && (
<ConfirmationDialog
actions={[
{
action: () =>
deleteMessage({
conversationId,
messageId: id,
}),
style: 'negative',
text: i18n('delete'),
},
]}
dialogName="TimelineMessage/deleteMessage"
i18n={i18n}
onClose={() => setHasDeleteConfirmation(false)}
>
{i18n('deleteWarning')}
</ConfirmationDialog>
)}
<Message
{...props}
renderingContext="conversation/TimelineItem"
@ -330,7 +354,7 @@ export function TimelineMessage(props: Props): JSX.Element {
: undefined
}
onForward={canForward ? () => toggleForwardMessageModal(id) : undefined}
onDeleteForMe={() => deleteMessage(id)}
onDeleteForMe={() => setHasDeleteConfirmation(true)}
onDeleteForEveryone={
canDeleteForEveryone ? () => setHasDOEConfirmation(true) : undefined
}

View file

@ -101,7 +101,7 @@ import { missingCaseError } from '../../util/missingCaseError';
import { viewedReceiptsJobQueue } from '../../jobs/viewedReceiptsJobQueue';
import { viewSyncJobQueue } from '../../jobs/viewSyncJobQueue';
import { ReadStatus } from '../../messages/MessageReadStatus';
import { isIncoming } from '../selectors/message';
import { isIncoming, isOutgoing } from '../selectors/message';
import { sendDeleteForEveryoneMessage } from '../../util/sendDeleteForEveryoneMessage';
import type { ShowToastActionType } from './toast';
import { SHOW_TOAST, ToastType } from './toast';
@ -882,6 +882,7 @@ export const actions = {
deleteAvatarFromDisk,
deleteConversation,
deleteMessageForEveryone,
deleteMessage,
destroyMessages,
discardMessages,
doubleCheckMissingQuoteReference,
@ -1211,6 +1212,46 @@ function setPinned(
};
}
function deleteMessage({
conversationId,
messageId,
}: {
conversationId: string;
messageId: string;
}): ThunkAction<void, RootStateType, unknown, NoopActionType> {
return async (dispatch, getState) => {
const message = await getMessageById(messageId);
if (!message) {
throw new Error(`deleteMessage: Message ${messageId} missing!`);
}
const conversation = window.ConversationController.get(conversationId);
if (!conversation) {
throw new Error('deleteMessage: No conversation found');
}
const messageConversationId = message.get('conversationId');
if (conversationId !== messageConversationId) {
throw new Error(
`deleteMessage: message conversation ${messageConversationId} doesn't match provided conversation ${conversationId}`
);
}
window.Signal.Data.removeMessage(messageId);
if (isOutgoing(message.attributes)) {
conversation.decrementSentMessageCount();
} else {
conversation.decrementMessageCount();
}
popPanelForConversation(conversationId)(dispatch, getState, undefined);
dispatch({
type: 'NOOP',
payload: null,
});
};
}
function destroyMessages(
conversationId: string
): ThunkAction<void, RootStateType, unknown, NoopActionType> {

View file

@ -65,7 +65,6 @@ export type TimelinePropsType = ExternalProps &
| 'acknowledgeGroupMemberNameCollisions'
| 'contactSupport'
| 'blockGroupLinkRequests'
| 'deleteMessage'
| 'downloadNewVersion'
| 'kickOffAttachmentDownload'
| 'learnMoreAboutDeliveryIssue'

View file

@ -20,7 +20,7 @@ import { enqueueReactionForSend } from '../reactions/enqueueReactionForSend';
import type { GroupNameCollisionsWithIdsByTitle } from '../util/groupMemberNameCollisions';
import { isGroup } from '../util/whatTypeOfConversation';
import { getPreferredBadgeSelector } from '../state/selectors/badges';
import { isIncoming, isOutgoing } from '../state/selectors/message';
import { isIncoming } from '../state/selectors/message';
import { getActiveCallState } from '../state/selectors/calling';
import { getTheme } from '../state/selectors/user';
import { ReactWrapperView } from './ReactWrapperView';
@ -73,7 +73,6 @@ const { getAbsoluteAttachmentPath, upgradeMessageSchema } =
const { getMessagesBySentAt } = window.Signal.Data;
type MessageActionsType = {
deleteMessage: (messageId: string) => unknown;
downloadNewVersion: () => unknown;
kickOffAttachmentDownload: (
options: Readonly<{ messageId: string }>
@ -147,7 +146,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
window.reduxActions.conversations.popPanelForConversation(this.model.id);
});
this.listenTo(this.model, 'show-message-details', this.showMessageDetail);
this.listenTo(this.model, 'delete-message', this.deleteMessage);
this.listenTo(this.model, 'pushPanel', this.pushPanel);
this.listenTo(this.model, 'popPanel', this.popPanel);
@ -410,9 +408,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
}
};
const retrySend = retryMessageSend;
const deleteMessage = (messageId: string) => {
this.deleteMessage(messageId);
};
const showMessageDetail = (messageId: string) => {
this.showMessageDetail(messageId);
};
@ -471,7 +466,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
};
return {
deleteMessage,
downloadNewVersion,
kickOffAttachmentDownload,
markAttachmentAsCorrupted,
@ -862,31 +856,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
return view;
}
deleteMessage(messageId: string): void {
const message = window.MessageController.getById(messageId);
if (!message) {
throw new Error(`deleteMessage: Message ${messageId} missing!`);
}
window.showConfirmationDialog({
dialogName: 'deleteMessage',
confirmStyle: 'negative',
message: window.i18n('deleteWarning'),
okText: window.i18n('delete'),
resolve: () => {
window.Signal.Data.removeMessage(message.id);
if (isOutgoing(message.attributes)) {
this.model.decrementSentMessageCount();
} else {
this.model.decrementMessageCount();
}
window.reduxActions.conversations.popPanelForConversation(
this.model.id
);
},
});
}
showGroupLinkManagement(): void {
window.reduxActions.conversations.pushPanelForConversation(this.model.id, {
type: PanelType.GroupLinkManagement,