diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 71bc554cb..56cd35866 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -41,7 +41,7 @@
"unreadMessages": "Unread Messages",
"debugLogExplanation": "This log will be saved to your desktop.",
"reportIssue": "Report a Bug",
- "markAllAsRead": "Mark All as Read",
+ "markAllAsRead": "Mark Read",
"incomingError": "Error handling incoming message",
"media": "Media",
"mediaEmptyState": "No media",
@@ -79,7 +79,7 @@
"typingAlt": "Typing animation for this conversation",
"contactAvatarAlt": "Avatar for contact $name$",
"downloadAttachment": "Download Attachment",
- "replyToMessage": "Reply to message",
+ "replyToMessage": "Reply",
"replyingToMessage": "Replying to:",
"originalMessageNotFound": "Original message not found",
"you": "You",
@@ -107,13 +107,10 @@
"deleteMessagesConfirmation": "Permanently delete the messages in this conversation?",
"hideConversation": "Hide Conversation",
"hideNoteToSelfConfirmation": "Are you sure you want to hide your Note to Self conversation?",
- "hideConversationFailed": "Failed to hide the Conversation!",
- "hideConversationFailedPleaseTryAgain": "Unable to hide the conversation, please try again",
"deleteConversation": "Delete Conversation",
"deleteConversationConfirmation": "Are you sure you want to delete your conversation with $name$?",
"deleteConversationFailed": "Failed to delete the Conversation!",
"deleteConversationFailedPleaseTryAgain": "Unable to delete the conversation, please try again",
- "hiding": "Hiding...",
"leaving": "Leaving...",
"deleted": "$count$ deleted",
"messageDeletedPlaceholder": "This message has been deleted",
@@ -126,6 +123,7 @@
"groupMembers": "Members",
"moreInformation": "More information",
"failed": "Failed",
+ "failedToSendMessage": "Failed to send message",
"read": "Read",
"resend": "Resend",
"clear": "Clear",
diff --git a/stylesheets/_modules.scss b/stylesheets/_modules.scss
index c7df9722e..349b85b70 100644
--- a/stylesheets/_modules.scss
+++ b/stylesheets/_modules.scss
@@ -554,7 +554,8 @@
justify-content: center;
align-items: center;
flex-grow: 1;
- font-size: 28px;
+ margin-top: var(--margins-sm);
+ font-size: 16px;
}
// Module: Conversation List Item
diff --git a/ts/components/conversation/message/message-content/ClickToTrustSender.tsx b/ts/components/conversation/message/message-content/ClickToTrustSender.tsx
index 25afee8a7..d54733a1a 100644
--- a/ts/components/conversation/message/message-content/ClickToTrustSender.tsx
+++ b/ts/components/conversation/message/message-content/ClickToTrustSender.tsx
@@ -106,6 +106,9 @@ export const ClickToTrustSender = (props: { messageId: string }) => {
})
);
},
+ onClickClose: () => {
+ window.inboxStore?.dispatch(updateConfirmModal(null));
+ },
})
);
};
diff --git a/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx b/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx
index 0a4d9ddc3..c9941095e 100644
--- a/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx
+++ b/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx
@@ -132,7 +132,7 @@ export const MessageContentWithStatuses = (props: Props) => {
onDoubleClickCapture={onDoubleClickReplyToMessage}
dataTestId={dataTestId}
>
-
+
{!isDetailView && }
diff --git a/ts/components/conversation/message/message-content/MessageStatus.tsx b/ts/components/conversation/message/message-content/MessageStatus.tsx
index ea7ce2ebd..41b9386fb 100644
--- a/ts/components/conversation/message/message-content/MessageStatus.tsx
+++ b/ts/components/conversation/message/message-content/MessageStatus.tsx
@@ -30,12 +30,11 @@ type Props = {
* - if the message is incoming: do not show anything (3)
* - if the message is outgoing: show the text for the last message, or a message sending, or in the error state. (4)
*/
-export const MessageStatus = (props: Props) => {
- const { messageId, isDetailView, dataTestId } = props;
- const status = useMessageStatus(props.messageId);
- const selected = useMessageExpirationPropsById(props.messageId);
+export const MessageStatus = ({ isDetailView, messageId, dataTestId }: Props) => {
+ const status = useMessageStatus(messageId);
+ const selected = useMessageExpirationPropsById(messageId);
- if (!props.messageId || !selected || isDetailView) {
+ if (!messageId || !selected || isDetailView) {
return null;
}
const isIncoming = selected.direction === 'incoming';
@@ -79,15 +78,15 @@ const MessageStatusContainer = styled.div<{ isIncoming: boolean; isGroup: boolea
props.isGroup || !props.isIncoming ? 'var(--width-avatar-group-msg-list)' : 0};
`;
-const StyledStatusText = styled.div`
- color: var(--text-secondary-color);
+const StyledStatusText = styled.div<{ textColor: string }>`
font-size: small;
+ color: ${props => props.textColor};
`;
-const TextDetails = ({ text }: { text: string }) => {
+const TextDetails = ({ text, textColor }: { text: string; textColor: string }) => {
return (
<>
- {text}
+ {text}
>
);
@@ -154,7 +153,7 @@ const MessageStatusSending = ({ dataTestId }: Omit) => {
isIncoming={false}
isGroup={false}
>
-
+
);
@@ -193,7 +192,7 @@ const MessageStatusSent = ({ dataTestId, messageId }: Omit
-
+
);
@@ -221,7 +220,7 @@ const MessageStatusRead = ({
isIncoming={isIncoming}
isGroup={isGroup}
>
-
+
);
@@ -243,7 +242,7 @@ const MessageStatusError = ({ dataTestId }: Omit) => {
isIncoming={false}
isGroup={isGroup}
>
-
+
);
diff --git a/ts/components/conversation/message/message-item/InteractionNotification.tsx b/ts/components/conversation/message/message-item/InteractionNotification.tsx
index e4a5d0553..be06bee1d 100644
--- a/ts/components/conversation/message/message-item/InteractionNotification.tsx
+++ b/ts/components/conversation/message/message-item/InteractionNotification.tsx
@@ -38,7 +38,7 @@ export const InteractionNotification = (props: PropsForInteractionNotification)
switch (interactionType) {
case ConversationInteractionType.Hide:
- text = window.i18n('hideConversationFailedPleaseTryAgain');
+ // this can't happen
break;
case ConversationInteractionType.Leave:
text = isCommunity
diff --git a/ts/components/conversation/right-panel/RightPanel.tsx b/ts/components/conversation/right-panel/RightPanel.tsx
index e164c0fb2..8ca45ab0c 100644
--- a/ts/components/conversation/right-panel/RightPanel.tsx
+++ b/ts/components/conversation/right-panel/RightPanel.tsx
@@ -2,6 +2,7 @@ import React from 'react';
import styled from 'styled-components';
import { useRightOverlayMode } from '../../../hooks/useUI';
+import { isRtlBody } from '../../../util/i18n';
import { Flex } from '../../basic/Flex';
import { OverlayRightPanelSettings } from './overlay/OverlayRightPanelSettings';
import { OverlayDisappearingMessages } from './overlay/disappearing-messages/OverlayDisappearingMessages';
@@ -113,6 +114,8 @@ const ClosableOverlay = () => {
};
export const RightPanel = () => {
+ const isRtlMode = isRtlBody();
+
return (
{
width={'var(--right-panel-width)'}
height={'var(--right-panel-height)'}
className="right-panel"
+ style={{ direction: isRtlMode ? 'rtl' : 'initial' }}
>
diff --git a/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx b/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx
index d83a019dd..c08aa5498 100644
--- a/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx
+++ b/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx
@@ -42,7 +42,6 @@ import { AttachmentTypeWithPath } from '../../../../types/Attachment';
import { getAbsoluteAttachmentPath } from '../../../../types/MessageAttachment';
import { Avatar, AvatarSize } from '../../../avatar/Avatar';
import { Flex } from '../../../basic/Flex';
-import { SessionButton, SessionButtonColor, SessionButtonType } from '../../../basic/SessionButton';
import { SpacerMD } from '../../../basic/Text';
import { PanelButtonGroup, PanelIconButton } from '../../../buttons';
import { MediaItemType } from '../../../lightbox/LightboxGallery';
@@ -183,25 +182,6 @@ const HeaderItem = () => {
);
};
-const StyledLeaveButton = styled.div`
- width: 100%;
- .session-button {
- margin-top: auto;
- width: 100%;
- min-height: calc(var(--composition-container-height) + 1px); // include border in height
- flex-shrink: 0;
- align-items: center;
- border-top: 1px solid var(--border-color);
- border-radius: 0px;
-
- &:not(.disabled) {
- &:hover {
- background-color: var(--button-solid-background-hover-color);
- }
- }
- }
-`;
-
const StyledName = styled.h4`
padding-inline: var(--margins-md);
font-size: var(--font-size-md);
@@ -359,15 +339,14 @@ export const OverlayRightPanelSettings = () => {
{isGroup && (
-
-
-
+ void deleteConvoAction()}
+ color={'var(--danger-color)'}
+ iconType={'delete'}
+ />
)}
>
diff --git a/ts/components/conversation/right-panel/overlay/message-info/components/AttachmentInfo.tsx b/ts/components/conversation/right-panel/overlay/message-info/components/AttachmentInfo.tsx
index 555416c89..44344b5a6 100644
--- a/ts/components/conversation/right-panel/overlay/message-info/components/AttachmentInfo.tsx
+++ b/ts/components/conversation/right-panel/overlay/message-info/components/AttachmentInfo.tsx
@@ -10,7 +10,8 @@ type Props = {
const StyledLabelContainer = styled(Flex)`
div {
- flex-grow: 1;
+ // we want 2 items per row and that's the easiest to make it happen
+ min-width: 50%;
}
`;
@@ -23,7 +24,7 @@ export const AttachmentInfo = (props: Props) => {
label={`${window.i18n('fileId')}:`}
info={attachment?.id ? String(attachment.id) : window.i18n('notApplicable')}
/>
-
+
{
label={`${window.i18n('fileSize')}:`}
info={attachment?.fileSize ? String(attachment.fileSize) : window.i18n('notApplicable')}
/>
-
-
{
+ window.inboxStore?.dispatch(updateConfirmModal(null));
+ },
})
);
return;
@@ -122,6 +125,9 @@ async function deleteEverythingAndNetworkData() {
await deleteDbLocally();
window.restart();
},
+ onClickClose: () => {
+ window.inboxStore?.dispatch(updateConfirmModal(null));
+ },
})
);
return;
diff --git a/ts/components/dialog/SessionConfirm.tsx b/ts/components/dialog/SessionConfirm.tsx
index a964a3612..932a8a66c 100644
--- a/ts/components/dialog/SessionConfirm.tsx
+++ b/ts/components/dialog/SessionConfirm.tsx
@@ -1,5 +1,6 @@
import { shell } from 'electron';
import React, { Dispatch, useEffect, useState } from 'react';
+import { useDispatch } from 'react-redux';
import styled from 'styled-components';
import { useLastMessage } from '../../hooks/useParamSelector';
import { MessageInteraction } from '../../interactions';
@@ -69,6 +70,7 @@ export interface SessionConfirmDialogProps {
}
export const SessionConfirm = (props: SessionConfirmDialogProps) => {
+ const dispatch = useDispatch();
const {
title = '',
message = '',
@@ -113,7 +115,7 @@ export const SessionConfirm = (props: SessionConfirmDialogProps) => {
}
if (closeAfterInput) {
- window.inboxStore?.dispatch(updateConfirmModal(null));
+ dispatch(updateConfirmModal(null));
}
};
@@ -137,13 +139,9 @@ export const SessionConfirm = (props: SessionConfirmDialogProps) => {
* Performs specified on close action then removes the modal.
*/
const onClickCancelHandler = () => {
- if (onClickCancel) {
- onClickCancel();
- }
+ onClickCancel?.();
- if (onClickClose) {
- onClickClose();
- }
+ onClickClose?.();
};
return (
diff --git a/ts/components/leftpane/conversation-list-item/InteractionItem.tsx b/ts/components/leftpane/conversation-list-item/InteractionItem.tsx
index 6a2ef801f..0e7b0031f 100644
--- a/ts/components/leftpane/conversation-list-item/InteractionItem.tsx
+++ b/ts/components/leftpane/conversation-list-item/InteractionItem.tsx
@@ -58,14 +58,7 @@ export const InteractionItem = (props: InteractionItemProps) => {
switch (interactionType) {
case ConversationInteractionType.Hide:
- errorText = window.i18n('hideConversationFailed');
- text =
- interactionStatus === ConversationInteractionStatus.Error
- ? errorText
- : interactionStatus === ConversationInteractionStatus.Start ||
- interactionStatus === ConversationInteractionStatus.Loading
- ? window.i18n('hiding')
- : text;
+ // if it's hidden or pending hiding, we don't show any text
break;
case ConversationInteractionType.Leave:
errorText = isCommunity
diff --git a/ts/components/settings/section/CategoryPrivacy.tsx b/ts/components/settings/section/CategoryPrivacy.tsx
index 4e0f5be3b..59e836d52 100644
--- a/ts/components/settings/section/CategoryPrivacy.tsx
+++ b/ts/components/settings/section/CategoryPrivacy.tsx
@@ -32,6 +32,9 @@ async function toggleLinkPreviews(isToggleOn: boolean, forceUpdate: () => void)
await window.setSettingValue(SettingsKey.settingsLinkPreview, newValue);
forceUpdate();
},
+ onClickClose: () => {
+ window.inboxStore?.dispatch(updateConfirmModal(null));
+ },
})
);
} else {
diff --git a/ts/interactions/conversationInteractions.ts b/ts/interactions/conversationInteractions.ts
index de0509504..98d18929d 100644
--- a/ts/interactions/conversationInteractions.ts
+++ b/ts/interactions/conversationInteractions.ts
@@ -294,12 +294,6 @@ async function leaveGroupOrCommunityByConvoId(
onClickClose?: () => void
) {
try {
- await updateConversationInteractionState({
- conversationId,
- type: ConversationInteractionType.Leave,
- status: ConversationInteractionStatus.Start,
- });
-
if (onClickClose) {
onClickClose();
}
@@ -308,13 +302,20 @@ async function leaveGroupOrCommunityByConvoId(
await getConversationController().deleteCommunity(conversationId, {
fromSyncMessage: false,
});
- } else {
- await getConversationController().deleteClosedGroup(conversationId, {
- fromSyncMessage: false,
- sendLeaveMessage: true,
- forceDeleteLocal,
- });
+ return;
}
+ // for groups, we have a "leaving..." state that we don't need for communities.
+ // that's because communities can be left always, whereas for groups we need to send a leave message (and so have some encryption keypairs)
+ await updateConversationInteractionState({
+ conversationId,
+ type: ConversationInteractionType.Leave,
+ status: ConversationInteractionStatus.Start,
+ });
+ await getConversationController().deleteClosedGroup(conversationId, {
+ fromSyncMessage: false,
+ sendLeaveMessage: true,
+ forceDeleteLocal,
+ });
await clearConversationInteractionState({ conversationId });
} catch (err) {
window.log.warn(`showLeaveGroupByConvoId error: ${err}`);
diff --git a/ts/interactions/conversations/unsendingInteractions.ts b/ts/interactions/conversations/unsendingInteractions.ts
index 50f055248..c73c77117 100644
--- a/ts/interactions/conversations/unsendingInteractions.ts
+++ b/ts/interactions/conversations/unsendingInteractions.ts
@@ -347,6 +347,8 @@ export async function deleteMessagesByIdForEveryone(
const messageCount = selectedMessages.length;
const moreThanOne = messageCount > 1;
+ const closeDialog = () => window.inboxStore?.dispatch(updateConfirmModal(null));
+
window.inboxStore?.dispatch(
updateConfirmModal({
title: window.i18n('deleteForEveryone'),
@@ -359,8 +361,9 @@ export async function deleteMessagesByIdForEveryone(
await doDeleteSelectedMessages({ selectedMessages, conversation, deleteForEveryone: true });
// explicitly close modal for this case.
- window.inboxStore?.dispatch(updateConfirmModal(null));
+ closeDialog();
},
+ onClickCancel: closeDialog,
closeAfterInput: false,
})
);
@@ -374,6 +377,7 @@ export async function deleteMessagesById(messageIds: Array, conversation
const messageCount = selectedMessages.length;
const moreThanOne = selectedMessages.length > 1;
+ const closeDialog = () => window.inboxStore?.dispatch(updateConfirmModal(null));
window.inboxStore?.dispatch(
updateConfirmModal({
@@ -398,6 +402,7 @@ export async function deleteMessagesById(messageIds: Array, conversation
window.inboxStore?.dispatch(resetRightOverlayMode());
},
closeAfterInput: false,
+ onClickClose: closeDialog,
})
);
}
diff --git a/ts/models/message.ts b/ts/models/message.ts
index 7b7bfe827..92fb02abd 100644
--- a/ts/models/message.ts
+++ b/ts/models/message.ts
@@ -1435,7 +1435,8 @@ export class MessageModel extends Backbone.Model {
switch (interactionType) {
case ConversationInteractionType.Hide:
- return window.i18n('hideConversationFailed');
+ // there is no text for hiding changes
+ return '';
case ConversationInteractionType.Leave:
return isCommunity
? window.i18n('leaveCommunityFailed')
diff --git a/ts/session/conversations/ConversationController.ts b/ts/session/conversations/ConversationController.ts
index a9cb4daa3..761586f78 100644
--- a/ts/session/conversations/ConversationController.ts
+++ b/ts/session/conversations/ConversationController.ts
@@ -519,7 +519,6 @@ async function leaveClosedGroup(groupId: string, fromSyncMessage: boolean) {
});
window?.log?.info(`We are leaving the group ${groupId}. Sending our leaving message.`);
-
// if we do not have a keypair for that group, we can't send our leave message, so just skip the message sending part
const wasSent = await getMessageQueue().sendToPubKeyNonDurably({
message: ourLeavingMessage,
diff --git a/ts/session/conversations/createClosedGroup.ts b/ts/session/conversations/createClosedGroup.ts
index f1a6ad23f..e30afa86a 100644
--- a/ts/session/conversations/createClosedGroup.ts
+++ b/ts/session/conversations/createClosedGroup.ts
@@ -116,7 +116,6 @@ async function sendToGroupMembers(
const allInvitesSent = _.every(inviteResults, inviteResult => inviteResult !== false);
if (allInvitesSent) {
- // if (true) {
if (isRetry) {
const invitesTitle =
inviteResults.length > 1
@@ -128,6 +127,9 @@ async function sendToGroupMembers(
title: invitesTitle,
message: window.i18n('closedGroupInviteSuccessMessage'),
hideCancel: true,
+ onClickClose: () => {
+ window.inboxStore?.dispatch(updateConfirmModal(null));
+ },
})
);
}
@@ -167,6 +169,9 @@ async function sendToGroupMembers(
);
}
},
+ onClickClose: () => {
+ window.inboxStore?.dispatch(updateConfirmModal(null));
+ },
})
);
diff --git a/ts/types/LocalizerKeys.ts b/ts/types/LocalizerKeys.ts
index fa889bc46..87a80c1ac 100644
--- a/ts/types/LocalizerKeys.ts
+++ b/ts/types/LocalizerKeys.ts
@@ -202,6 +202,7 @@ export type LocalizerKeys =
| 'failedResolveOns'
| 'failedToAddAsModerator'
| 'failedToRemoveFromModerator'
+ | 'failedToSendMessage'
| 'faq'
| 'fileId'
| 'fileSize'
@@ -221,14 +222,11 @@ export type LocalizerKeys =
| 'hide'
| 'hideBanner'
| 'hideConversation'
- | 'hideConversationFailed'
- | 'hideConversationFailedPleaseTryAgain'
| 'hideMenuBarDescription'
| 'hideMenuBarTitle'
| 'hideNoteToSelfConfirmation'
| 'hideRequestBanner'
| 'hideRequestBannerDescription'
- | 'hiding'
| 'iAmSure'
| 'image'
| 'imageAttachmentAlt'