diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 4c71dee3f..cb565b89d 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -300,8 +300,8 @@
"disappearingMessagesOnlyAdmins": "Only group admins can change this setting.",
"disappearingMessagesSent": "Sent",
"disappearingMessagesSet": "{name} has set messages to disappear {time} after they have been {disappearing_messages_type}.",
- "disappearingMessagesSetYou": "You set messages to disappear {time} after they have been {disappearing_messages_type}.",
"disappearingMessagesTimer": "Timer",
+ "disappearingMessagesSetYou": "You set messages to disappear {time} after they have been {disappearing_messages_type}.",
"disappearingMessagesTurnedOff": "{name} has turned disappearing messages off. Messages they send will no longer disappear.",
"disappearingMessagesTurnedOffYou": "You turned off disappearing messages. Messages you send will no longer disappear.",
"disappearingMessagesTypeRead": "read",
diff --git a/ts/components/conversation/SubtleNotification.tsx b/ts/components/conversation/SubtleNotification.tsx
index fcad96072..a44242f60 100644
--- a/ts/components/conversation/SubtleNotification.tsx
+++ b/ts/components/conversation/SubtleNotification.tsx
@@ -96,7 +96,6 @@ export const NoMessageInConversation = () => {
const isMe = useSelectedIsNoteToSelf();
const canWrite = useSelector(getSelectedCanWrite);
const privateBlindedAndBlockingMsgReqs = useSelectedHasDisabledBlindedMsgRequests();
- // TODOLATER use this selector across the whole application (left pane excluded)
const name = useSelectedNicknameOrProfileNameOrShortenedPubkey();
const messageText = useMemo(() => {
diff --git a/ts/components/conversation/composition/CompositionBox.tsx b/ts/components/conversation/composition/CompositionBox.tsx
index 4ffc7e3c5..f0c3f957e 100644
--- a/ts/components/conversation/composition/CompositionBox.tsx
+++ b/ts/components/conversation/composition/CompositionBox.tsx
@@ -390,6 +390,13 @@ class CompositionBoxInner extends Component {
private renderCompositionView() {
const { showEmojiPanel } = this.state;
const { typingEnabled } = this.props;
+
+ // we can only send a message if the conversation allows writing in it
+ // - we've got a message body
+ // - or we've got a staged attachments
+ const showSendButton =
+ typingEnabled && (!isEmpty(this.state.draft) || !isEmpty(this.props.stagedAttachments));
+
/* eslint-disable @typescript-eslint/no-misused-promises */
return (
@@ -432,7 +439,7 @@ class CompositionBoxInner extends Component {
{typingEnabled && (
)}
- {typingEnabled && }
+ {showSendButton && }
{typingEnabled && showEmojiPanel && (
{
return;
}
- if (!selectedConversation.isPrivate && selectedConversation.left) {
- ToastUtils.pushYouLeftTheGroup();
- return;
- }
- if (!selectedConversation.isPrivate && selectedConversation.isKickedFromGroup) {
+ if (
+ !selectedConversation.isPrivate &&
+ (selectedConversation.left || selectedConversation.isKickedFromGroup)
+ ) {
ToastUtils.pushYouLeftTheGroup();
return;
}
diff --git a/ts/components/conversation/message/message-content/MessageReactBar.tsx b/ts/components/conversation/message/message-content/MessageReactBar.tsx
index 9ab0802cb..e53200dbf 100644
--- a/ts/components/conversation/message/message-content/MessageReactBar.tsx
+++ b/ts/components/conversation/message/message-content/MessageReactBar.tsx
@@ -137,7 +137,7 @@ function formatTimeLeft({ timeLeftMs }: { timeLeftMs: number }) {
const weeks = Math.floor(days / 7);
const daysLeft = days % 7;
const extraUnit = daysLeft ? ` ${daysLeft}d` : '';
- return window.i18n('disappearingMessagesCountdownBig', { time_large: `${weeks}w${extraUnit}` });
+ return window.i18n('', { time_large: `${weeks}w${extraUnit}` });
}
return '...';
diff --git a/ts/components/conversation/message/message-item/GroupUpdateMessage.tsx b/ts/components/conversation/message/message-item/GroupUpdateMessage.tsx
index ac8a0c093..0c7e55e2e 100644
--- a/ts/components/conversation/message/message-item/GroupUpdateMessage.tsx
+++ b/ts/components/conversation/message/message-item/GroupUpdateMessage.tsx
@@ -4,6 +4,10 @@ import {
PropsForGroupUpdate,
PropsForGroupUpdateType,
} from '../../../../state/ducks/conversations';
+import {
+ useSelectedDisplayNameInProfile,
+ useSelectedNicknameOrProfileNameOrShortenedPubkey,
+} from '../../../../state/selectors/selectedConversation';
import { assertUnreachable } from '../../../../types/sqlSharedTypes';
import { ExpirableReadableMessage } from './ExpirableReadableMessage';
import { NotificationBubble } from './notification-bubble/NotificationBubble';
@@ -25,10 +29,10 @@ const ChangeItemKicked = (kicked: Array): string => {
throw new Error('Group update kicked is missing contacts');
}
const names = useConversationsUsernameWithQuoteOrFullPubkey(kicked);
+ const groupName = useSelectedNicknameOrProfileNameOrShortenedPubkey();
if (arrayContainsUsOnly(kicked)) {
- // TODO - add group name
- return window.i18n('groupRemovedYou', { group_name: '' });
+ return window.i18n('groupRemovedYou', { group_name: groupName });
}
// TODO - support bold
diff --git a/ts/components/conversation/message/message-item/InteractionNotification.tsx b/ts/components/conversation/message/message-item/InteractionNotification.tsx
index e1b2749b7..bee95c787 100644
--- a/ts/components/conversation/message/message-item/InteractionNotification.tsx
+++ b/ts/components/conversation/message/message-item/InteractionNotification.tsx
@@ -46,9 +46,13 @@ export const InteractionNotification = (props: PropsForInteractionNotification)
break;
case ConversationInteractionType.Leave:
text = isCommunity
- ? window.i18n('communityLeaveError', { community_name: displayName })
+ ? window.i18n('communityLeaveError', {
+ community_name: displayName || window.i18n('communityUnknown'),
+ })
: isGroup
- ? window.i18n('groupLeaveErrorFailed', { group_name: displayName })
+ ? window.i18n('groupLeaveErrorFailed', {
+ group_name: displayName || window.i18n('groupUnknown'),
+ })
: ''; // we cannot fail to do other actions, so not printing anything
break;
default:
diff --git a/ts/components/conversation/message/message-item/MessageRequestResponse.tsx b/ts/components/conversation/message/message-item/MessageRequestResponse.tsx
index eee8c047a..a2fb65742 100644
--- a/ts/components/conversation/message/message-item/MessageRequestResponse.tsx
+++ b/ts/components/conversation/message/message-item/MessageRequestResponse.tsx
@@ -1,27 +1,18 @@
-import { useConversationUsername } from '../../../../hooks/useParamSelector';
+import { useNicknameOrProfileNameOrShortenedPubkey } from '../../../../hooks/useParamSelector';
import { PropsForMessageRequestResponse } from '../../../../models/messageType';
import { UserUtils } from '../../../../session/utils';
import { Flex } from '../../../basic/Flex';
-import { SpacerSM, Text } from '../../../basic/Text';
+import { I18n } from '../../../basic/I18n';
+import { SpacerSM, TextWithChildren } from '../../../basic/Text';
import { ReadableMessage } from './ReadableMessage';
// Note this should not respond to the disappearing message conversation setting so we use the ReadableMessage
export const MessageRequestResponse = (props: PropsForMessageRequestResponse) => {
const { messageId, isUnread, receivedAt, conversationId } = props;
- const profileName = useConversationUsername(conversationId);
+ const profileName = useNicknameOrProfileNameOrShortenedPubkey(conversationId);
const isFromSync = props.source === UserUtils.getOurPubKeyStrFromCache();
- let msgText = '';
- if (isFromSync) {
- msgText = window.i18n('messageRequestYouHaveAccepted', {
- // TODO - check if we can have a better fallback
- name: profileName ?? '',
- });
- } else {
- msgText = window.i18n('messageRequestsAccepted');
- }
-
return (
id={`msg-${messageId}`}
>
-
+
+ {isFromSync ? (
+
+ ) : (
+
+ )}
+
);
diff --git a/ts/components/conversation/message/message-item/notification-bubble/NotificationBubble.tsx b/ts/components/conversation/message/message-item/notification-bubble/NotificationBubble.tsx
index 7f1b7e6ef..7c703d923 100644
--- a/ts/components/conversation/message/message-item/notification-bubble/NotificationBubble.tsx
+++ b/ts/components/conversation/message/message-item/notification-bubble/NotificationBubble.tsx
@@ -1,5 +1,6 @@
import styled from 'styled-components';
import { SessionIcon, SessionIconType } from '../../../../icon';
+import { SessionHtmlRenderer } from '../../../../basic/SessionHTMLRenderer';
const NotificationBubbleFlex = styled.div`
display: flex;
@@ -44,7 +45,9 @@ export const NotificationBubble = (props: {
/>
)}
- {notificationText}
+
+
+
{iconType && }
);
diff --git a/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx b/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx
index 91125079f..25e87817e 100644
--- a/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx
+++ b/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx
@@ -264,8 +264,9 @@ export const OverlayRightPanelSettings = () => {
lastMessage?.interactionStatus === ConversationInteractionStatus.Error
? window.i18n('conversationsDelete')
: isKickedFromGroup
- ? // TODO - add group name
- window.i18n('groupRemovedYou', { group_name: '' })
+ ? window.i18n('groupRemovedYou', {
+ group_name: selectedUsername || window.i18n('groupUnknown'),
+ })
: left
? window.i18n('groupMemberYouLeft')
: window.i18n('groupLeave');
diff --git a/ts/components/dialog/UpdateGroupMembersDialog.tsx b/ts/components/dialog/UpdateGroupMembersDialog.tsx
index 6c7bf8be4..1068b5c8f 100644
--- a/ts/components/dialog/UpdateGroupMembersDialog.tsx
+++ b/ts/components/dialog/UpdateGroupMembersDialog.tsx
@@ -158,7 +158,7 @@ export const UpdateGroupMembersDialog = (props: Props) => {
const onAdd = (member: string) => {
if (!weAreAdmin) {
- ToastUtils.pushOnlyAdminCanRemove();
+ window?.log?.warn('Only group admin can add members!');
return;
}
@@ -168,8 +168,6 @@ export const UpdateGroupMembersDialog = (props: Props) => {
const onRemove = (member: string) => {
if (!weAreAdmin) {
window?.log?.warn('Only group admin can remove members!');
-
- ToastUtils.pushOnlyAdminCanRemove();
return;
}
if (convoProps.groupAdmins?.includes(member)) {
diff --git a/ts/components/dialog/UpdateGroupNameDialog.tsx b/ts/components/dialog/UpdateGroupNameDialog.tsx
index 5135a7dd9..d4240e308 100644
--- a/ts/components/dialog/UpdateGroupNameDialog.tsx
+++ b/ts/components/dialog/UpdateGroupNameDialog.tsx
@@ -98,10 +98,7 @@ export class UpdateGroupNameDialog extends Component {
public render() {
const okText = window.i18n('okay');
const cancelText = window.i18n('cancel');
- // TODO: String localization - remove
- const titleText = window.i18n('updateGroupDialogTitle', {
- name: this.convo.getRealSessionUsername() ?? window.i18n('unknown'),
- });
+ const titleText = window.i18n('groupInformationSet');
const errorMsg = this.state.errorMessage;
const isAdmin = !this.convo.isPublic();
diff --git a/ts/components/leftpane/conversation-list-item/InteractionItem.tsx b/ts/components/leftpane/conversation-list-item/InteractionItem.tsx
index 7165fcde4..16ae06128 100644
--- a/ts/components/leftpane/conversation-list-item/InteractionItem.tsx
+++ b/ts/components/leftpane/conversation-list-item/InteractionItem.tsx
@@ -59,9 +59,9 @@ export const InteractionItem = (props: InteractionItemProps) => {
let text = storedLastMessageText || '';
let errorText = '';
- const name =
- getConversationController().get(conversationId)?.getNicknameOrRealUsernameOrPlaceholder() ||
- window.i18n('unknown');
+ const name = getConversationController()
+ .get(conversationId)
+ ?.getNicknameOrRealUsernameOrPlaceholder();
switch (interactionType) {
case ConversationInteractionType.Hide:
@@ -69,7 +69,9 @@ export const InteractionItem = (props: InteractionItemProps) => {
break;
case ConversationInteractionType.Leave:
errorText = isCommunity
- ? window.i18n('communityLeaveError', { community_name: name })
+ ? window.i18n('communityLeaveError', {
+ community_name: name || window.i18n('unknown'),
+ })
: isGroup
? window.i18n('groupLeaveErrorFailed', { group_name: name })
: ''; // this cannot happen
diff --git a/ts/components/settings/SessionNotificationGroupSettings.tsx b/ts/components/settings/SessionNotificationGroupSettings.tsx
index db6bf3089..07ece6eae 100644
--- a/ts/components/settings/SessionNotificationGroupSettings.tsx
+++ b/ts/components/settings/SessionNotificationGroupSettings.tsx
@@ -57,10 +57,7 @@ export const SessionNotificationGroupSettings = () => {
}
Notifications.addPreviewNotification({
conversationId: `preview-notification-${Date.now()}`,
- message:
- items.find(m => m.value === initialNotificationEnabled)?.label ||
- window?.i18n?.('messageBody') ||
- 'Message body',
+ message: items.find(m => m.value === initialNotificationEnabled)?.label || 'Message body',
title: window.i18n('preview'),
iconUrl: null,
isExpiringMessage: false,
diff --git a/ts/interactions/conversationInteractions.ts b/ts/interactions/conversationInteractions.ts
index 8ecbc8fb2..1cb4d029b 100644
--- a/ts/interactions/conversationInteractions.ts
+++ b/ts/interactions/conversationInteractions.ts
@@ -276,7 +276,9 @@ export function showLeavePrivateConversationbyConvoId(conversationId: string) {
title: isMe ? window.i18n('noteToSelfHide') : window.i18n('conversationsDelete'),
message: isMe
? window.i18n('noteToSelfHideDescription')
- : window.i18n('deleteMessagesDescriptionEveryone'),
+ : window.i18n('conversationsDeleteDescription', {
+ name: conversation.getNicknameOrRealUsernameOrPlaceholder(),
+ }),
onClickOk,
okText: isMe ? window.i18n('hide') : window.i18n('delete'),
okTheme: SessionButtonColor.Danger,
diff --git a/ts/interactions/messageInteractions.ts b/ts/interactions/messageInteractions.ts
index 347090728..56fd75d0d 100644
--- a/ts/interactions/messageInteractions.ts
+++ b/ts/interactions/messageInteractions.ts
@@ -120,7 +120,7 @@ const acceptOpenGroupInvitationV2 = (completeUrl: string, roomName?: string) =>
updateConfirmModal({
title: window.i18n('communityJoin'),
message: window.i18n('communityJoinDescription', {
- community_name: roomName ?? window.i18n('unknown'),
+ community_name: roomName || window.i18n('unknown'),
}),
onClickOk: async () => {
await joinOpenGroupV2WithUIEvents(completeUrl, true, false);
diff --git a/ts/models/conversation.ts b/ts/models/conversation.ts
index 651ede824..4c02a547f 100644
--- a/ts/models/conversation.ts
+++ b/ts/models/conversation.ts
@@ -1337,6 +1337,9 @@ export class ConversationModel extends Backbone.Model {
if (this.isPrivate()) {
return window.i18n('anonymous');
}
+ if (this.isPublic()) {
+ return window.i18n('communityUnknown');
+ }
return window.i18n('unknown');
}
diff --git a/ts/session/apis/open_group_api/opengroupV2/JoinOpenGroupV2.ts b/ts/session/apis/open_group_api/opengroupV2/JoinOpenGroupV2.ts
index 61f4de7cb..68b2cb408 100644
--- a/ts/session/apis/open_group_api/opengroupV2/JoinOpenGroupV2.ts
+++ b/ts/session/apis/open_group_api/opengroupV2/JoinOpenGroupV2.ts
@@ -96,7 +96,9 @@ async function joinOpenGroupV2(
if (!conversation) {
window?.log?.warn('Failed to join open group v2');
// TODO - Check that this is the room name
- throw new Error(window.i18n('groupErrorJoin', { group_name: roomId }));
+ throw new Error(
+ window.i18n('communityJoinError', { community_name: roomId || window.i18n('unknown') })
+ );
}
// here we managed to connect to the group.
@@ -182,12 +184,18 @@ export async function joinOpenGroupV2WithUIEvents(
if (showToasts) {
// TODO - Check that this is the room name
ToastUtils.pushToastError(
- 'connectToServerFail',
- window.i18n('groupErrorJoin', { group_name: parsedRoom.roomId })
+ 'communityJoinError',
+ window.i18n('communityJoinError', {
+ community_name: parsedRoom.roomId || window.i18n('unknown'),
+ })
);
}
if (errorHandler) {
- errorHandler(window.i18n('groupErrorJoin', { group_name: parsedRoom.roomId }));
+ errorHandler(
+ window.i18n('communityJoinError', {
+ community_name: parsedRoom.roomId || window.i18n('unknown'),
+ })
+ );
}
uiCallback?.({ loadingState: 'failed', conversationKey: conversationID });
@@ -196,12 +204,14 @@ export async function joinOpenGroupV2WithUIEvents(
if (showToasts) {
// TODO - Check that this is the room name
ToastUtils.pushToastError(
- 'connectToServerFail',
- window.i18n('groupErrorJoin', { group_name: 'unknown' })
+ 'communityJoinError',
+ window.i18n('communityJoinError', { community_name: window.i18n('unknown') })
);
}
if (errorHandler) {
- errorHandler(window.i18n('groupErrorJoin', { group_name: completeUrl })); // we don't have a parsed room, so let's show the whole url in this case
+ errorHandler(
+ window.i18n('communityJoinError', { community_name: window.i18n('unknown') })
+ ); // we don't have a parsed room, so let's show the whole url in this case
}
uiCallback?.({ loadingState: 'failed', conversationKey: null });
}
diff --git a/ts/session/apis/open_group_api/opengroupV2/OpenGroupManagerV2.ts b/ts/session/apis/open_group_api/opengroupV2/OpenGroupManagerV2.ts
index 133d77347..9822fc1b5 100644
--- a/ts/session/apis/open_group_api/opengroupV2/OpenGroupManagerV2.ts
+++ b/ts/session/apis/open_group_api/opengroupV2/OpenGroupManagerV2.ts
@@ -224,7 +224,6 @@ export class OpenGroupManagerV2 {
} catch (e) {
window?.log?.warn('Failed to join open group v2', e.message);
await OpenGroupData.removeV2OpenGroupRoom(conversationId);
- // throw new Error(window.i18n('connectToServerFail'));
return undefined;
}
}
diff --git a/ts/session/conversations/createClosedGroup.ts b/ts/session/conversations/createClosedGroup.ts
index ab14a7cde..101c2d44d 100644
--- a/ts/session/conversations/createClosedGroup.ts
+++ b/ts/session/conversations/createClosedGroup.ts
@@ -169,7 +169,7 @@ async function sendToGroupMembers(
window.inboxStore?.dispatch(
updateConfirmModal({
- title: window.i18n('groupInviteFailed'),
+ title: window.i18n('groupError'),
message,
okText: window.i18n('resend'),
onClickOk: async () => {
diff --git a/ts/session/utils/Toast.tsx b/ts/session/utils/Toast.tsx
index 8a75a0608..cb35fd754 100644
--- a/ts/session/utils/Toast.tsx
+++ b/ts/session/utils/Toast.tsx
@@ -139,9 +139,6 @@ export function pushedMissedCallCauseOfPermission(conversationName: string) {
);
}
-export function pushedMissedCallNotApproved(name: string) {
- pushToastInfo('missedCall', window.i18n('callsMissedCallFrom', { name }));
-}
export function pushVideoCallPermissionNeeded() {
pushToastInfo(
@@ -193,10 +190,6 @@ export function pushCannotRemoveCreatorFromGroup() {
pushToastWarning('cannotRemoveCreatorFromGroup', window.i18n('adminCannotBeRemoved'));
}
-export function pushOnlyAdminCanRemove() {
- pushToastInfo('onlyAdminCanRemoveMembers', window.i18n('onlyAdminCanRemoveMembersDesc'));
-}
-
export function pushFailedToAddAsModerator() {
pushToastWarning('failedToAddAsModerator', window.i18n('adminPromotionFailed'));
}
diff --git a/ts/session/utils/calling/CallManager.ts b/ts/session/utils/calling/CallManager.ts
index 0c04cdaf7..862b40919 100644
--- a/ts/session/utils/calling/CallManager.ts
+++ b/ts/session/utils/calling/CallManager.ts
@@ -1296,7 +1296,7 @@ export async function handleMissedCall(
ToastUtils.pushedMissedCall(displayname);
break;
case 'not-approved':
- ToastUtils.pushedMissedCallNotApproved(displayname);
+ // no toast for this case
break;
case 'too-old-timestamp':
// no toast for this case, the missed call notification is enough
@@ -1304,7 +1304,9 @@ export async function handleMissedCall(
default:
}
- await addMissedCallMessage(sender, incomingOfferTimestamp, details);
+ if (reason !== 'not-approved') {
+ await addMissedCallMessage(sender, incomingOfferTimestamp, details);
+ }
}
async function addMissedCallMessage(