ConversationView: Move deleteMessage to redux
This commit is contained in:
parent
50d9b6e5e1
commit
7c86f02c7e
5 changed files with 83 additions and 38 deletions
|
@ -1677,10 +1677,22 @@ export async function startApp(): Promise<void> {
|
||||||
const { selectedMessage } = state.conversations;
|
const { selectedMessage } = state.conversations;
|
||||||
|
|
||||||
if (selectedMessage) {
|
if (selectedMessage) {
|
||||||
conversation.trigger('delete-message', selectedMessage);
|
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,10 @@ export type PropsData = {
|
||||||
} & Omit<MessagePropsData, 'renderingContext' | 'menu'>;
|
} & Omit<MessagePropsData, 'renderingContext' | 'menu'>;
|
||||||
|
|
||||||
export type PropsActions = {
|
export type PropsActions = {
|
||||||
deleteMessage: (id: string) => void;
|
deleteMessage: (options: {
|
||||||
|
conversationId: string;
|
||||||
|
messageId: string;
|
||||||
|
}) => void;
|
||||||
deleteMessageForEveryone: (id: string) => void;
|
deleteMessageForEveryone: (id: string) => void;
|
||||||
toggleForwardMessageModal: (id: string) => void;
|
toggleForwardMessageModal: (id: string) => void;
|
||||||
reactToMessage: (
|
reactToMessage: (
|
||||||
|
@ -233,6 +236,7 @@ export function TimelineMessage(props: Props): JSX.Element {
|
||||||
const handleReact = canReact ? () => toggleReactionPicker() : undefined;
|
const handleReact = canReact ? () => toggleReactionPicker() : undefined;
|
||||||
|
|
||||||
const [hasDOEConfirmation, setHasDOEConfirmation] = useState(false);
|
const [hasDOEConfirmation, setHasDOEConfirmation] = useState(false);
|
||||||
|
const [hasDeleteConfirmation, setHasDeleteConfirmation] = useState(false);
|
||||||
|
|
||||||
const toggleReactionPickerKeyboard = useToggleReactionPicker(
|
const toggleReactionPickerKeyboard = useToggleReactionPicker(
|
||||||
handleReact || noop
|
handleReact || noop
|
||||||
|
@ -266,6 +270,26 @@ export function TimelineMessage(props: Props): JSX.Element {
|
||||||
{i18n('deleteForEveryoneWarning')}
|
{i18n('deleteForEveryoneWarning')}
|
||||||
</ConfirmationDialog>
|
</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
|
<Message
|
||||||
{...props}
|
{...props}
|
||||||
renderingContext="conversation/TimelineItem"
|
renderingContext="conversation/TimelineItem"
|
||||||
|
@ -330,7 +354,7 @@ export function TimelineMessage(props: Props): JSX.Element {
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
onForward={canForward ? () => toggleForwardMessageModal(id) : undefined}
|
onForward={canForward ? () => toggleForwardMessageModal(id) : undefined}
|
||||||
onDeleteForMe={() => deleteMessage(id)}
|
onDeleteForMe={() => setHasDeleteConfirmation(true)}
|
||||||
onDeleteForEveryone={
|
onDeleteForEveryone={
|
||||||
canDeleteForEveryone ? () => setHasDOEConfirmation(true) : undefined
|
canDeleteForEveryone ? () => setHasDOEConfirmation(true) : undefined
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ import { missingCaseError } from '../../util/missingCaseError';
|
||||||
import { viewedReceiptsJobQueue } from '../../jobs/viewedReceiptsJobQueue';
|
import { viewedReceiptsJobQueue } from '../../jobs/viewedReceiptsJobQueue';
|
||||||
import { viewSyncJobQueue } from '../../jobs/viewSyncJobQueue';
|
import { viewSyncJobQueue } from '../../jobs/viewSyncJobQueue';
|
||||||
import { ReadStatus } from '../../messages/MessageReadStatus';
|
import { ReadStatus } from '../../messages/MessageReadStatus';
|
||||||
import { isIncoming } from '../selectors/message';
|
import { isIncoming, isOutgoing } from '../selectors/message';
|
||||||
import { sendDeleteForEveryoneMessage } from '../../util/sendDeleteForEveryoneMessage';
|
import { sendDeleteForEveryoneMessage } from '../../util/sendDeleteForEveryoneMessage';
|
||||||
import type { ShowToastActionType } from './toast';
|
import type { ShowToastActionType } from './toast';
|
||||||
import { SHOW_TOAST, ToastType } from './toast';
|
import { SHOW_TOAST, ToastType } from './toast';
|
||||||
|
@ -882,6 +882,7 @@ export const actions = {
|
||||||
deleteAvatarFromDisk,
|
deleteAvatarFromDisk,
|
||||||
deleteConversation,
|
deleteConversation,
|
||||||
deleteMessageForEveryone,
|
deleteMessageForEveryone,
|
||||||
|
deleteMessage,
|
||||||
destroyMessages,
|
destroyMessages,
|
||||||
discardMessages,
|
discardMessages,
|
||||||
doubleCheckMissingQuoteReference,
|
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(
|
function destroyMessages(
|
||||||
conversationId: string
|
conversationId: string
|
||||||
): ThunkAction<void, RootStateType, unknown, NoopActionType> {
|
): ThunkAction<void, RootStateType, unknown, NoopActionType> {
|
||||||
|
|
|
@ -65,7 +65,6 @@ export type TimelinePropsType = ExternalProps &
|
||||||
| 'acknowledgeGroupMemberNameCollisions'
|
| 'acknowledgeGroupMemberNameCollisions'
|
||||||
| 'contactSupport'
|
| 'contactSupport'
|
||||||
| 'blockGroupLinkRequests'
|
| 'blockGroupLinkRequests'
|
||||||
| 'deleteMessage'
|
|
||||||
| 'downloadNewVersion'
|
| 'downloadNewVersion'
|
||||||
| 'kickOffAttachmentDownload'
|
| 'kickOffAttachmentDownload'
|
||||||
| 'learnMoreAboutDeliveryIssue'
|
| 'learnMoreAboutDeliveryIssue'
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { enqueueReactionForSend } from '../reactions/enqueueReactionForSend';
|
||||||
import type { GroupNameCollisionsWithIdsByTitle } from '../util/groupMemberNameCollisions';
|
import type { GroupNameCollisionsWithIdsByTitle } from '../util/groupMemberNameCollisions';
|
||||||
import { isGroup } from '../util/whatTypeOfConversation';
|
import { isGroup } from '../util/whatTypeOfConversation';
|
||||||
import { getPreferredBadgeSelector } from '../state/selectors/badges';
|
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 { getActiveCallState } from '../state/selectors/calling';
|
||||||
import { getTheme } from '../state/selectors/user';
|
import { getTheme } from '../state/selectors/user';
|
||||||
import { ReactWrapperView } from './ReactWrapperView';
|
import { ReactWrapperView } from './ReactWrapperView';
|
||||||
|
@ -73,7 +73,6 @@ const { getAbsoluteAttachmentPath, upgradeMessageSchema } =
|
||||||
const { getMessagesBySentAt } = window.Signal.Data;
|
const { getMessagesBySentAt } = window.Signal.Data;
|
||||||
|
|
||||||
type MessageActionsType = {
|
type MessageActionsType = {
|
||||||
deleteMessage: (messageId: string) => unknown;
|
|
||||||
downloadNewVersion: () => unknown;
|
downloadNewVersion: () => unknown;
|
||||||
kickOffAttachmentDownload: (
|
kickOffAttachmentDownload: (
|
||||||
options: Readonly<{ messageId: string }>
|
options: Readonly<{ messageId: string }>
|
||||||
|
@ -147,7 +146,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
||||||
window.reduxActions.conversations.popPanelForConversation(this.model.id);
|
window.reduxActions.conversations.popPanelForConversation(this.model.id);
|
||||||
});
|
});
|
||||||
this.listenTo(this.model, 'show-message-details', this.showMessageDetail);
|
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, 'pushPanel', this.pushPanel);
|
||||||
this.listenTo(this.model, 'popPanel', this.popPanel);
|
this.listenTo(this.model, 'popPanel', this.popPanel);
|
||||||
|
@ -410,9 +408,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const retrySend = retryMessageSend;
|
const retrySend = retryMessageSend;
|
||||||
const deleteMessage = (messageId: string) => {
|
|
||||||
this.deleteMessage(messageId);
|
|
||||||
};
|
|
||||||
const showMessageDetail = (messageId: string) => {
|
const showMessageDetail = (messageId: string) => {
|
||||||
this.showMessageDetail(messageId);
|
this.showMessageDetail(messageId);
|
||||||
};
|
};
|
||||||
|
@ -471,7 +466,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
deleteMessage,
|
|
||||||
downloadNewVersion,
|
downloadNewVersion,
|
||||||
kickOffAttachmentDownload,
|
kickOffAttachmentDownload,
|
||||||
markAttachmentAsCorrupted,
|
markAttachmentAsCorrupted,
|
||||||
|
@ -862,31 +856,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
||||||
return view;
|
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 {
|
showGroupLinkManagement(): void {
|
||||||
window.reduxActions.conversations.pushPanelForConversation(this.model.id, {
|
window.reduxActions.conversations.pushPanelForConversation(this.model.id, {
|
||||||
type: PanelType.GroupLinkManagement,
|
type: PanelType.GroupLinkManagement,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue