diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b2193dfed..222e591ec 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,6 +47,12 @@ sudo apt install cmake npm install cmake-js ``` +In Fedora, you may also need to install +``` +sudo dnf install make automake gcc gcc-c++ kernel-devel +``` + + ### All platforms Now, run these commands in your preferred terminal in a good directory for development: diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 9ed90c87d..bb39c5d57 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -202,6 +202,7 @@ "expirationType": "Expiration Type", "expirationDuration": "Expiration Duration", "disappears": "Disappears", + "messageWillDisappear": "Messages will disappear in $countAndUnit$", "followSetting": "Follow Setting", "followSettingDisabled": "Messages you send will no longer disappear. Are you sure you want to turn off disappearing messages?", "followSettingTimeAndType": "Set your messages to disappear $time$ after they have been $type$?", diff --git a/package.json b/package.json index d24eaef6f..e718e48a9 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "session-desktop", "productName": "Session", "description": "Private messaging from your desktop", - "version": "1.11.7", + "version": "1.11.8", "license": "GPL-3.0", "author": { "name": "Oxen Labs", diff --git a/ts/components/conversation/TimerNotification.tsx b/ts/components/conversation/TimerNotification.tsx index e14425ab3..16ff26720 100644 --- a/ts/components/conversation/TimerNotification.tsx +++ b/ts/components/conversation/TimerNotification.tsx @@ -9,13 +9,15 @@ import { useSelectedConversationDisappearingMode, useSelectedConversationKey, useSelectedExpireTimer, + useSelectedIsGroupOrCommunity, + useSelectedIsGroupV2, useSelectedIsNoteToSelf, useSelectedIsPrivate, useSelectedIsPrivateFriend, } from '../../state/selectors/selectedConversation'; import { ReleasedFeatures } from '../../util/releaseFeature'; import { Flex } from '../basic/Flex'; -import { TextWithChildren } from '../basic/Text'; +import { SpacerMD, TextWithChildren } from '../basic/Text'; import { ExpirableReadableMessage } from './message/message-item/ExpirableReadableMessage'; // eslint-disable-next-line import/order import { ConversationInteraction } from '../../interactions'; @@ -23,6 +25,7 @@ import { getConversationController } from '../../session/conversations'; import { updateConfirmModal } from '../../state/ducks/modalDialog'; import { SessionButtonColor } from '../basic/SessionButton'; import { SessionHtmlRenderer } from '../basic/SessionHTMLRenderer'; +import { SessionIcon } from '../icon'; const FollowSettingButton = styled.button` color: var(--primary-color); @@ -180,6 +183,9 @@ export const TimerNotification = (props: PropsForExpirationTimer) => { const { messageId } = props; const textToRender = useTextToRender(props); + const isGroupOrCommunity = useSelectedIsGroupOrCommunity(); + const isGroupV2 = useSelectedIsGroupV2(); + const renderOffIcon = props.disabled || (isGroupOrCommunity && !isGroupV2); if (!textToRender || textToRender.length === 0) { throw new Error('textToRender invalid key used TimerNotification'); @@ -203,6 +209,16 @@ export const TimerNotification = (props: PropsForExpirationTimer) => { padding="5px 10px" style={{ textAlign: 'center' }} > + {renderOffIcon && ( + <> + + + + )} diff --git a/ts/components/conversation/header/ConversationHeaderSubtitle.tsx b/ts/components/conversation/header/ConversationHeaderSubtitle.tsx index c086bde7e..742ce17d1 100644 --- a/ts/components/conversation/header/ConversationHeaderSubtitle.tsx +++ b/ts/components/conversation/header/ConversationHeaderSubtitle.tsx @@ -122,7 +122,7 @@ export const ConversationHeaderSubtitle = (props: ConversationHeaderSubtitleProp )} diff --git a/ts/components/conversation/header/ConversationHeaderTitle.tsx b/ts/components/conversation/header/ConversationHeaderTitle.tsx index 2a371e2e9..4f40808ae 100644 --- a/ts/components/conversation/header/ConversationHeaderTitle.tsx +++ b/ts/components/conversation/header/ConversationHeaderTitle.tsx @@ -8,7 +8,7 @@ import { resetRightOverlayMode, setRightOverlayMode } from '../../../state/ducks import { useSelectedConversationDisappearingMode, useSelectedConversationKey, - useSelectedIsGroup, + useSelectedIsGroupOrCommunity, useSelectedIsKickedFromGroup, useSelectedIsNoteToSelf, useSelectedIsPublic, @@ -42,7 +42,7 @@ export const ConversationHeaderTitle = () => { const isPublic = useSelectedIsPublic(); const isKickedFromGroup = useSelectedIsKickedFromGroup(); const isMe = useSelectedIsNoteToSelf(); - const isGroup = useSelectedIsGroup(); + const isGroup = useSelectedIsGroupOrCommunity(); const members = useSelectedMembers(); const expirationMode = useSelectedConversationDisappearingMode(); diff --git a/ts/components/conversation/message/message-content/MessageAuthorText.tsx b/ts/components/conversation/message/message-content/MessageAuthorText.tsx index 575b0390d..845c5f3d5 100644 --- a/ts/components/conversation/message/message-content/MessageAuthorText.tsx +++ b/ts/components/conversation/message/message-content/MessageAuthorText.tsx @@ -9,7 +9,7 @@ import { useMessageDirection, } from '../../../../state/selectors'; import { - useSelectedIsGroup, + useSelectedIsGroupOrCommunity, useSelectedIsPublic, } from '../../../../state/selectors/selectedConversation'; import { Flex } from '../../../basic/Flex'; @@ -27,7 +27,7 @@ const StyledAuthorContainer = styled(Flex)<{ hideAvatar: boolean }>` export const MessageAuthorText = (props: Props) => { const isPublic = useSelectedIsPublic(); - const isGroup = useSelectedIsGroup(); + const isGroup = useSelectedIsGroupOrCommunity(); const authorProfileName = useAuthorProfileName(props.messageId); const authorName = useAuthorName(props.messageId); const sender = useMessageAuthor(props.messageId); diff --git a/ts/components/conversation/message/message-content/MessageAvatar.tsx b/ts/components/conversation/message/message-content/MessageAvatar.tsx index 8bc7682b2..5c1a9faa3 100644 --- a/ts/components/conversation/message/message-content/MessageAvatar.tsx +++ b/ts/components/conversation/message/message-content/MessageAvatar.tsx @@ -38,10 +38,10 @@ export type MessageAvatarSelectorProps = Pick< 'sender' | 'isSenderAdmin' | 'lastMessageOfSeries' >; -type Props = { messageId: string; hideAvatar: boolean; isPrivate: boolean }; +type Props = { messageId: string; hideAvatar: boolean; isPrivate: boolean; isDetailView?: boolean }; export const MessageAvatar = (props: Props) => { - const { messageId, hideAvatar, isPrivate } = props; + const { messageId, hideAvatar, isPrivate, isDetailView } = props; const dispatch = useDispatch(); const selectedConvoKey = useSelectedConversationKey(); @@ -143,7 +143,7 @@ export const MessageAvatar = (props: Props) => { }} > - {isSenderAdmin && } + {!isDetailView && isSenderAdmin ? : null} ); }; diff --git a/ts/components/conversation/message/message-content/MessageContent.tsx b/ts/components/conversation/message/message-content/MessageContent.tsx index 7d6949868..052ec381e 100644 --- a/ts/components/conversation/message/message-content/MessageContent.tsx +++ b/ts/components/conversation/message/message-content/MessageContent.tsx @@ -183,6 +183,7 @@ export const MessageContent = (props: Props) => { messageId={props.messageId} hideAvatar={hideAvatar} isPrivate={selectedIsPrivate} + isDetailView={props.isDetailView} /> diff --git a/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx b/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx index ea364de2f..a64651cfb 100644 --- a/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx +++ b/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx @@ -151,7 +151,7 @@ export const MessageContentWithStatuses = (props: Props) => { /> )} - {enableReactions && ( + {!isDetailView && enableReactions ? ( { noAvatar={hideAvatar} isDetailView={isDetailView} /> - )} + ) : null} ); }; diff --git a/ts/components/conversation/message/message-content/MessageReactBar.tsx b/ts/components/conversation/message/message-content/MessageReactBar.tsx index 475ab85ec..e6a5826a4 100644 --- a/ts/components/conversation/message/message-content/MessageReactBar.tsx +++ b/ts/components/conversation/message/message-content/MessageReactBar.tsx @@ -101,25 +101,23 @@ function formatTimeLeft({ timeLeftMs }: { timeLeftMs: number }) { return `0s`; } - const prefix = 'Message will expire in'; - if (timeLeft.isBefore(moment.utc(0).add(1, 'minute'))) { - return `${prefix} ${timeLeft.seconds()}s`; + return window.i18n('messageWillDisappear', [`${timeLeft.seconds()}s`]); } if (timeLeft.isBefore(moment.utc(0).add(1, 'hour'))) { const extraUnit = timeLeft.seconds() ? ` ${timeLeft.seconds()}s` : ''; - return `${prefix} ${timeLeft.minutes()}m${extraUnit}`; + return window.i18n('messageWillDisappear', [`${timeLeft.minutes()}m${extraUnit}`]); } if (timeLeft.isBefore(moment.utc(0).add(1, 'day'))) { const extraUnit = timeLeft.minutes() ? ` ${timeLeft.minutes()}m` : ''; - return `${prefix} ${timeLeft.hours()}h${extraUnit}`; + return window.i18n('messageWillDisappear', [`${timeLeft.hours()}h${extraUnit}`]); } if (timeLeft.isBefore(moment.utc(0).add(7, 'day'))) { const extraUnit = timeLeft.hours() ? ` ${timeLeft.hours()}h` : ''; - return `${prefix} ${timeLeft.dayOfYear() - 1}d${extraUnit}`; + return window.i18n('messageWillDisappear', [`${timeLeft.dayOfYear() - 1}d${extraUnit}`]); } if (timeLeft.isBefore(moment.utc(0).add(31, 'day'))) { @@ -127,7 +125,7 @@ function formatTimeLeft({ timeLeftMs }: { timeLeftMs: number }) { const weeks = Math.floor(days / 7); const daysLeft = days % 7; const extraUnit = daysLeft ? ` ${daysLeft}d` : ''; - return `${prefix} ${weeks}w${extraUnit}`; + return window.i18n('messageWillDisappear', [`${weeks}w${extraUnit}`]); } return '...'; @@ -142,10 +140,10 @@ const ExpiresInItem = ({ expirationTimestamp }: { expirationTimestamp?: number | () => { setRefresh(!refresh); }, - // We want to force refresh this component a lot more if the message has more than 2 minutes before disappearing, - // because when that's the case we also display the seconds left (i.e. 1min 23s) and we want that 23s to be dynamic. + // We want to force refresh this component a lot more if the message has less than 1h before disappearing, + // because when that's the case we also display the seconds left (i.e. 59min 23s) and we want that 23s to be dynamic. // Also, we use a refresh interval of 500 rather than 1s so that the counter is a bit smoother - timeLeftMs > 0 && timeLeftMs <= 2 * DURATION.MINUTES ? 500 : null + timeLeftMs > 0 && timeLeftMs <= 1 * DURATION.HOURS ? 500 : null ); if (!expirationTimestamp || timeLeftMs < 0) { return null; @@ -153,7 +151,7 @@ const ExpiresInItem = ({ expirationTimestamp }: { expirationTimestamp?: number | return ( - + {formatTimeLeft({ timeLeftMs })} diff --git a/ts/components/conversation/message/message-content/MessageReactions.tsx b/ts/components/conversation/message/message-content/MessageReactions.tsx index 22ea520ac..6d7fd5b6e 100644 --- a/ts/components/conversation/message/message-content/MessageReactions.tsx +++ b/ts/components/conversation/message/message-content/MessageReactions.tsx @@ -4,7 +4,7 @@ import styled from 'styled-components'; import { useMessageReactsPropsById } from '../../../../hooks/useParamSelector'; import { MessageRenderingProps } from '../../../../models/messageType'; import { REACT_LIMIT } from '../../../../session/constants'; -import { useSelectedIsGroup } from '../../../../state/selectors/selectedConversation'; +import { useSelectedIsGroupOrCommunity } from '../../../../state/selectors/selectedConversation'; import { SortedReactionList } from '../../../../types/Reaction'; import { nativeEmojiData } from '../../../../util/emoji'; import { Flex } from '../../../basic/Flex'; @@ -175,7 +175,7 @@ export const MessageReactions = (props: Props) => { const msgProps = useMessageReactsPropsById(messageId); - const inGroup = useSelectedIsGroup(); + const inGroup = useSelectedIsGroupOrCommunity(); useEffect(() => { if (msgProps?.sortedReacts && !isEqual(reactions, msgProps?.sortedReacts)) { diff --git a/ts/components/conversation/message/message-content/MessageStatus.tsx b/ts/components/conversation/message/message-content/MessageStatus.tsx index 9ab816aa6..fbeb32b98 100644 --- a/ts/components/conversation/message/message-content/MessageStatus.tsx +++ b/ts/components/conversation/message/message-content/MessageStatus.tsx @@ -6,7 +6,7 @@ import { useMessageExpirationPropsById } from '../../../../hooks/useParamSelecto import { useMessageStatus } from '../../../../state/selectors'; import { getMostRecentMessageId } from '../../../../state/selectors/conversations'; -import { useSelectedIsGroup } from '../../../../state/selectors/selectedConversation'; +import { useSelectedIsGroupOrCommunity } from '../../../../state/selectors/selectedConversation'; import { SpacerXS } from '../../../basic/Text'; import { SessionIcon, SessionIconType } from '../../../icon'; import { ExpireTimer } from '../../ExpireTimer'; @@ -179,7 +179,7 @@ function IconForExpiringMessageId({ const MessageStatusSent = ({ dataTestId, messageId }: Omit) => { const isExpiring = useIsExpiring(messageId); const isMostRecentMessage = useIsMostRecentMessage(messageId); - const isGroup = useSelectedIsGroup(); + const isGroup = useSelectedIsGroupOrCommunity(); // we hide a "sent" message status which is not expiring except for the most recent message if (!isExpiring && !isMostRecentMessage) { @@ -204,7 +204,7 @@ const MessageStatusRead = ({ isIncoming, }: Omit & { isIncoming: boolean }) => { const isExpiring = useIsExpiring(messageId); - const isGroup = useSelectedIsGroup(); + const isGroup = useSelectedIsGroupOrCommunity(); const isMostRecentMessage = useIsMostRecentMessage(messageId); @@ -231,7 +231,7 @@ const MessageStatusError = ({ dataTestId }: Omit) => { ipcRenderer.send('show-debug-log'); }, []); // when on error, we do not display the expire timer at all. - const isGroup = useSelectedIsGroup(); + const isGroup = useSelectedIsGroupOrCommunity(); return ( { const { text, attachment, isIncoming, referencedMessageNotFound } = props; - const isGroup = useSelectedIsGroup(); + const isGroup = useSelectedIsGroupOrCommunity(); if (!referencedMessageNotFound && attachment && !isEmpty(attachment)) { const { contentType, isVoiceMessage } = attachment; diff --git a/ts/components/conversation/message/message-item/GenericReadableMessage.tsx b/ts/components/conversation/message/message-item/GenericReadableMessage.tsx index 1f712b518..24cc2be8c 100644 --- a/ts/components/conversation/message/message-item/GenericReadableMessage.tsx +++ b/ts/components/conversation/message/message-item/GenericReadableMessage.tsx @@ -58,10 +58,9 @@ const StyledReadableMessage = styled.div<{ } ${props => + !props.selected && props.isRightClicked && - ` - background-color: var(--conversation-tab-background-selected-color); - `} + `background-color: var(--conversation-tab-background-selected-color);`} `; export const GenericReadableMessage = (props: Props) => { diff --git a/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx b/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx index beb8b85fa..2bad0bbed 100644 --- a/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx +++ b/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx @@ -30,7 +30,7 @@ import { useSelectedDisplayNameInProfile, useSelectedIsActive, useSelectedIsBlocked, - useSelectedIsGroup, + useSelectedIsGroupOrCommunity, useSelectedIsKickedFromGroup, useSelectedIsLeft, useSelectedIsPublic, @@ -128,7 +128,7 @@ const HeaderItem = () => { const isBlocked = useSelectedIsBlocked(); const isKickedFromGroup = useSelectedIsKickedFromGroup(); const left = useSelectedIsLeft(); - const isGroup = useSelectedIsGroup(); + const isGroup = useSelectedIsGroupOrCommunity(); const subscriberCount = useSelectedSubscriberCount(); if (!selectedConvoKey) { @@ -201,7 +201,7 @@ export const OverlayRightPanelSettings = () => { const isBlocked = useSelectedIsBlocked(); const isKickedFromGroup = useSelectedIsKickedFromGroup(); const left = useSelectedIsLeft(); - const isGroup = useSelectedIsGroup(); + const isGroup = useSelectedIsGroupOrCommunity(); const isPublic = useSelectedIsPublic(); const weAreAdmin = useSelectedWeAreAdmin(); const disappearingMessagesSubtitle = useDisappearingMessageSettingText({ diff --git a/ts/components/conversation/right-panel/overlay/disappearing-messages/OverlayDisappearingMessages.tsx b/ts/components/conversation/right-panel/overlay/disappearing-messages/OverlayDisappearingMessages.tsx index 3aebe1246..48b80230b 100644 --- a/ts/components/conversation/right-panel/overlay/disappearing-messages/OverlayDisappearingMessages.tsx +++ b/ts/components/conversation/right-panel/overlay/disappearing-messages/OverlayDisappearingMessages.tsx @@ -12,8 +12,8 @@ import { useSelectedConversationDisappearingMode, useSelectedConversationKey, useSelectedExpireTimer, - useSelectedIsGroup, - useSelectedWeAreAdmin, + useSelectedIsGroupOrCommunity, + useSelectedWeAreAdmin } from '../../../../../state/selectors/selectedConversation'; import { ReleasedFeatures } from '../../../../../util/releaseFeature'; import { Flex } from '../../../../basic/Flex'; @@ -23,9 +23,13 @@ import { Header, HeaderSubtitle, HeaderTitle, StyledScrollContainer } from '../c import { DisappearingModes } from './DisappearingModes'; import { TimeOptions } from './TimeOptions'; +const ButtonSpacer = styled.div` + height: 80px; +`; + const StyledButtonContainer = styled.div` - background: linear-gradient(0deg, black, transparent); - position: sticky; + background: linear-gradient(0deg, var(--background-primary-color), transparent); + position: absolute; width: 100%; bottom: 0px; @@ -110,7 +114,7 @@ export const OverlayDisappearingMessages = () => { const disappearingModeOptions = useSelector(getSelectedConversationExpirationModes); const { singleMode, hasOnlyOneMode } = useSingleMode(disappearingModeOptions); - const isGroup = useSelectedIsGroup(); + const isGroup = useSelectedIsGroupOrCommunity(); const expirationMode = useSelectedConversationDisappearingMode(); const expireTimer = useSelectedExpireTimer(); const weAreAdmin = useSelectedWeAreAdmin(); @@ -210,6 +214,8 @@ export const OverlayDisappearingMessages = () => { )} + + { */ const onClickCancelHandler = () => { onClickCancel?.(); - onClickClose?.(); + window.inboxStore?.dispatch(updateConfirmModal(null)); }; return ( diff --git a/ts/components/icon/Icons.tsx b/ts/components/icon/Icons.tsx index 78967591e..36a9c7ebb 100644 --- a/ts/components/icon/Icons.tsx +++ b/ts/components/icon/Icons.tsx @@ -62,7 +62,6 @@ export type SessionIconType = | 'shield' | 'star' | 'sun' - | 'stopwatch' | 'qr' | 'users' | 'warning' @@ -71,6 +70,7 @@ export type SessionIconType = | 'gallery' | 'stop' | 'thumbnail' + | 'timerFixed' | 'timer00' | 'timer05' | 'timer10' @@ -450,12 +450,6 @@ export const icons: Record { await forceSyncConfigurationNowIfNeeded(); }, + onClickClose: () => { + window.inboxStore?.dispatch(updateConfirmModal(null)); + }, }) ); } diff --git a/ts/components/settings/section/CategoryPermissions.tsx b/ts/components/settings/section/CategoryPermissions.tsx index a880b3bc5..e8c4d2ef1 100644 --- a/ts/components/settings/section/CategoryPermissions.tsx +++ b/ts/components/settings/section/CategoryPermissions.tsx @@ -26,6 +26,9 @@ const toggleCallMediaPermissions = async (triggerUIUpdate: () => void) => { await window.toggleCallMediaPermissionsTo(false); triggerUIUpdate(); }, + onClickClose: () => { + window.inboxStore?.dispatch(updateConfirmModal(null)); + }, }) ); } else { diff --git a/ts/interactions/conversations/unsendingInteractions.ts b/ts/interactions/conversations/unsendingInteractions.ts index c73c77117..bb4b6e043 100644 --- a/ts/interactions/conversations/unsendingInteractions.ts +++ b/ts/interactions/conversations/unsendingInteractions.ts @@ -364,6 +364,7 @@ export async function deleteMessagesByIdForEveryone( closeDialog(); }, onClickCancel: closeDialog, + onClickClose: closeDialog, closeAfterInput: false, }) ); @@ -375,6 +376,8 @@ export async function deleteMessagesById(messageIds: Array, conversation await Promise.all(messageIds.map(m => Data.getMessageById(m, false))) ); + const isMe = conversation.isMe(); + const messageCount = selectedMessages.length; const moreThanOne = selectedMessages.length > 1; const closeDialog = () => window.inboxStore?.dispatch(updateConfirmModal(null)); @@ -385,10 +388,12 @@ export async function deleteMessagesById(messageIds: Array, conversation message: moreThanOne ? window.i18n('deleteMessagesQuestion', [messageCount.toString()]) : window.i18n('deleteMessageQuestion'), - radioOptions: [ - { label: window.i18n('deleteJustForMe'), value: 'deleteJustForMe' }, - { label: window.i18n('deleteForEveryone'), value: 'deleteForEveryone' }, - ], + radioOptions: !isMe + ? [ + { label: window.i18n('deleteJustForMe'), value: 'deleteJustForMe' }, + { label: window.i18n('deleteForEveryone'), value: 'deleteForEveryone' }, + ] + : undefined, okText: window.i18n('delete'), okTheme: SessionButtonColor.Danger, onClickOk: async args => { diff --git a/ts/models/conversation.ts b/ts/models/conversation.ts index e6d84d3f9..93b053402 100644 --- a/ts/models/conversation.ts +++ b/ts/models/conversation.ts @@ -870,7 +870,6 @@ export class ConversationModel extends Backbone.Model { ); // we don't add an update message when this comes from a config message, as we already have the SyncedMessage itself with the right timestamp to display - const shouldAddExpireUpdateMessage = !fromConfigMessage; if (this.isPublic()) { throw new Error("updateExpireTimer() Disappearing messages aren't supported in communities"); @@ -883,6 +882,15 @@ export class ConversationModel extends Backbone.Model { expirationMode = 'off'; expireTimer = 0; } + const shouldAddExpireUpdateMessage = + (this.isPrivate() && !fromConfigMessage) || + (this.isClosedGroup() && + !PubKey.isClosedGroupV3(this.id) && + !fromConfigMessage && + expirationMode !== this.get('expirationMode') && + expireTimer !== this.get('expireTimer') && + expirationMode !== 'off' && + expireTimer !== 0); // When we add a disappearing messages notification to the conversation, we want it // to be above the message that initiated that change, hence the subtraction. diff --git a/ts/state/selectors/selectedConversation.ts b/ts/state/selectors/selectedConversation.ts index f6a118272..5aca5a79f 100644 --- a/ts/state/selectors/selectedConversation.ts +++ b/ts/state/selectors/selectedConversation.ts @@ -121,16 +121,25 @@ function getSelectedBlindedDisabledMsgRequests(state: StateType) { return isBlindedAndDisabledMsgRequests; } -/** - * Returns true if the current conversation selected is a group conversation. - * Returns false if the current conversation selected is not a group conversation, or none are selected - */ -const getSelectedConversationIsGroup = (state: StateType): boolean => { +const getSelectedConversationType = (state: StateType): ConversationTypeEnum | null => { + const selected = getSelectedConversation(state); + if (!selected || !selected.type) { + return null; + } + return selected.type; +}; + +const getSelectedConversationIsGroupOrCommunity = (state: StateType): boolean => { + const type = getSelectedConversationType(state); + return type ? isOpenOrClosedGroup(type) : false; +}; + +const getSelectedConversationIsGroupV2 = (state: StateType): boolean => { const selected = getSelectedConversation(state); if (!selected || !selected.type) { return false; } - return selected.type ? isOpenOrClosedGroup(selected.type) : false; + return selected.type === ConversationTypeEnum.GROUPV3; }; /** @@ -232,8 +241,12 @@ export function useSelectedConversationKey() { return useSelector(getSelectedConversationKey); } -export function useSelectedIsGroup() { - return useSelector(getSelectedConversationIsGroup); +export function useSelectedIsGroupOrCommunity() { + return useSelector(getSelectedConversationIsGroupOrCommunity); +} + +export function useSelectedIsGroupV2() { + return useSelector(getSelectedConversationIsGroupV2); } export function useSelectedIsPublic() { diff --git a/ts/types/LocalizerKeys.ts b/ts/types/LocalizerKeys.ts index a21a90eb0..5d5cfe153 100644 --- a/ts/types/LocalizerKeys.ts +++ b/ts/types/LocalizerKeys.ts @@ -306,6 +306,7 @@ export type LocalizerKeys = | 'messageRequestAcceptedOursNoName' | 'messageRequestPending' | 'messageRequests' + | 'messageWillDisappear' | 'messagesHeader' | 'moreInformation' | 'multipleJoinedTheGroup'