diff --git a/ts/components/conversation/ConversationHeader.tsx b/ts/components/conversation/ConversationHeader.tsx
index e1d7db689..93d0118d1 100644
--- a/ts/components/conversation/ConversationHeader.tsx
+++ b/ts/components/conversation/ConversationHeader.tsx
@@ -6,7 +6,6 @@ import { contextMenu } from 'react-contexify';
import styled from 'styled-components';
import { ConversationNotificationSettingType } from '../../models/conversation';
import {
- getConversationHeaderProps,
getConversationHeaderTitleProps,
getCurrentNotificationSettingText,
getIsSelectedBlocked,
@@ -33,10 +32,14 @@ import {
} from '../../state/ducks/conversations';
import { callRecipient } from '../../interactions/conversationInteractions';
import { getHasIncomingCall, getHasOngoingCall } from '../../state/selectors/call';
-import { useConversationUsername } from '../../hooks/useParamSelector';
+import {
+ useConversationUsername,
+ useExpireTimer,
+ useIsKickedFromGroup,
+} from '../../hooks/useParamSelector';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
import { SessionIconButton } from '../icon';
-import { MemoConversationHeaderMenu } from '../menu/ConversationHeaderMenu';
+import { ConversationHeaderMenu } from '../menu/ConversationHeaderMenu';
export interface TimerOption {
name: string;
@@ -328,33 +331,20 @@ export const ConversationHeaderSubtitle = (props: { text?: string | null }): JSX
};
export const ConversationHeaderWithDetails = () => {
- const headerProps = useSelector(getConversationHeaderProps);
-
const isSelectionMode = useSelector(isMessageSelectionMode);
const isMessageDetailOpened = useSelector(isMessageDetailView);
-
+ const selectedConvoKey = useSelector(getSelectedConversationKey);
const dispatch = useDispatch();
- if (!headerProps) {
+ if (!selectedConvoKey) {
return null;
}
- const {
- isKickedFromGroup,
- expirationSettingName,
- avatarPath,
- name,
- profileName,
- isMe,
- isPublic,
- currentNotificationSetting,
- hasNickname,
- weAreAdmin,
- isBlocked,
- left,
- conversationKey,
- isPrivate,
- isGroup,
- } = headerProps;
+
+ const isKickedFromGroup = useIsKickedFromGroup(selectedConvoKey);
+ const expireTimerSetting = useExpireTimer(selectedConvoKey);
+ const expirationSettingName = expireTimerSetting
+ ? window.Whisper.ExpirationTimerOptions.getName(expireTimerSetting || 0)
+ : null;
const triggerId = 'conversation-header';
@@ -383,29 +373,13 @@ export const ConversationHeaderWithDetails = () => {
onAvatarClick={() => {
dispatch(openRightPanel());
}}
- pubkey={conversationKey}
+ pubkey={selectedConvoKey}
showBackButton={isMessageDetailOpened}
/>
>
)}
-
+
{isSelectionMode && }
diff --git a/ts/components/dialog/UpdateGroupMembersDialog.tsx b/ts/components/dialog/UpdateGroupMembersDialog.tsx
index bb3919cbf..32fe0a7c0 100644
--- a/ts/components/dialog/UpdateGroupMembersDialog.tsx
+++ b/ts/components/dialog/UpdateGroupMembersDialog.tsx
@@ -9,10 +9,9 @@ import { SessionButton, SessionButtonColor } from '../basic/SessionButton';
import { MemberListItem } from '../MemberListItem';
import { SessionWrapperModal } from '../SessionWrapperModal';
import { useDispatch } from 'react-redux';
-import { useConversationPropsById } from '../../hooks/useParamSelector';
+import { useConversationPropsById, useWeAreAdmin } from '../../hooks/useParamSelector';
// tslint:disable-next-line: no-submodule-imports
import useKey from 'react-use/lib/useKey';
-import { useWeAreAdmin } from '../../hooks/useWeAreAdmin';
import { useSet } from '../../hooks/useSet';
import { ClosedGroup } from '../../session';
import { getConversationController } from '../../session/conversations';
diff --git a/ts/components/menu/ConversationHeaderMenu.tsx b/ts/components/menu/ConversationHeaderMenu.tsx
index 05348ae85..4ea167c7f 100644
--- a/ts/components/menu/ConversationHeaderMenu.tsx
+++ b/ts/components/menu/ConversationHeaderMenu.tsx
@@ -1,98 +1,64 @@
import React from 'react';
import { animation, Menu } from 'react-contexify';
import {
- getAddModeratorsMenuItem,
- getBanMenuItem,
- getBlockMenuItem,
- getChangeNicknameMenuItem,
- getClearNicknameMenuItem,
- getCopyMenuItem,
- getDeleteContactMenuItem,
- getDeleteMessagesMenuItem,
- getDisappearingMenuItem,
- getInviteContactMenuItem,
- getLeaveGroupMenuItem,
- getMarkAllReadMenuItem,
- getNotificationForConvoMenuItem,
- getPinConversationMenuItem,
- getRemoveModeratorsMenuItem,
- getShowUserDetailsMenuItem,
- getUnbanMenuItem,
- getUpdateGroupNameMenuItem,
+ AddModeratorsMenuItem,
+ BanMenuItem,
+ BlockMenuItem,
+ ChangeNicknameMenuItem,
+ ClearNicknameMenuItem,
+ CopyMenuItem,
+ DeleteContactMenuItem,
+ DeleteMessagesMenuItem,
+ DisappearingMessageMenuItem,
+ InviteContactMenuItem,
+ LeaveGroupMenuItem,
+ MarkAllReadMenuItem,
+ NotificationForConvoMenuItem,
+ PinConversationMenuItem,
+ RemoveModeratorsMenuItem,
+ ShowUserDetailsMenuItem,
+ UnbanMenuItem,
+ UpdateGroupNameMenuItem,
} from './Menu';
import _ from 'lodash';
-import { ConversationNotificationSettingType } from '../../models/conversation';
+import { ContextConversationId } from '../leftpane/conversation-list-item/ConversationListItem';
+import { getSelectedConversationKey } from '../../state/selectors/conversations';
+import { useSelector } from 'react-redux';
export type PropsConversationHeaderMenu = {
- conversationId: string;
triggerId: string;
- isMe: boolean;
- isPublic: boolean;
- isKickedFromGroup: boolean;
- left: boolean;
- isGroup: boolean;
- weAreAdmin: boolean;
- currentNotificationSetting: ConversationNotificationSettingType;
- isPrivate: boolean;
- isBlocked: boolean;
- hasNickname: boolean;
- name: string | undefined;
- profileName: string | undefined;
- avatarPath: string | null;
};
-const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => {
- const {
- conversationId,
- triggerId,
- isMe,
- isPublic,
- isGroup,
- isKickedFromGroup,
- weAreAdmin,
- isBlocked,
- isPrivate,
- left,
- hasNickname,
- currentNotificationSetting,
- name,
- profileName,
- avatarPath,
- } = props;
- const userName = name || profileName || conversationId;
+export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => {
+ const { triggerId } = props;
+ const selectedConversation = useSelector(getSelectedConversationKey);
+
+ if (!selectedConversation) {
+ throw new Error('selectedConversation must be set for a header to be visible!');
+ }
return (
-
+
+
+
);
};
-
-function propsAreEqual(prev: PropsConversationHeaderMenu, next: PropsConversationHeaderMenu) {
- return _.isEqual(prev, next);
-}
-export const MemoConversationHeaderMenu = React.memo(ConversationHeaderMenu, propsAreEqual);
diff --git a/ts/components/menu/ConversationListItemContextMenu.tsx b/ts/components/menu/ConversationListItemContextMenu.tsx
index cdc45d396..866b31ccf 100644
--- a/ts/components/menu/ConversationListItemContextMenu.tsx
+++ b/ts/components/menu/ConversationListItemContextMenu.tsx
@@ -1,29 +1,22 @@
-import React, { useContext } from 'react';
+import React from 'react';
import { animation, Menu } from 'react-contexify';
import _ from 'underscore';
-import {
- useAvatarPath,
- useConversationPropsById,
- useConversationUsername,
-} from '../../hooks/useParamSelector';
-import { ConversationTypeEnum } from '../../models/conversation';
-import { ContextConversationId } from '../leftpane/conversation-list-item/ConversationListItem';
import {
- getBanMenuItem,
- getBlockMenuItem,
- getChangeNicknameMenuItem,
- getClearNicknameMenuItem,
- getCopyMenuItem,
- getDeleteContactMenuItem,
- getDeleteMessagesMenuItem,
- getInviteContactMenuItem,
- getLeaveGroupMenuItem,
- getMarkAllReadMenuItem,
- getNotificationForConvoMenuItem,
- getPinConversationMenuItem,
- getShowUserDetailsMenuItem,
- getUnbanMenuItem,
+ BanMenuItem,
+ BlockMenuItem,
+ ChangeNicknameMenuItem,
+ ClearNicknameMenuItem,
+ CopyMenuItem,
+ DeleteContactMenuItem,
+ DeleteMessagesMenuItem,
+ InviteContactMenuItem,
+ LeaveGroupMenuItem,
+ MarkAllReadMenuItem,
+ NotificationForConvoMenuItem,
+ PinConversationMenuItem,
+ ShowUserDetailsMenuItem,
+ UnbanMenuItem,
} from './Menu';
export type PropsContextConversationItem = {
@@ -31,54 +24,24 @@ export type PropsContextConversationItem = {
};
const ConversationListItemContextMenu = (props: PropsContextConversationItem) => {
- const conversationId = useContext(ContextConversationId);
-
- const itemMenuProps = useConversationPropsById(conversationId);
const { triggerId } = props;
- if (!itemMenuProps) {
- return null;
- }
- const {
- isBlocked,
- isMe,
- isPublic,
- hasNickname,
- type,
- left,
- isKickedFromGroup,
- currentNotificationSetting,
- isPrivate,
- weAreAdmin,
- } = itemMenuProps;
-
- const isGroup = type === 'group';
-
- const userName = useConversationUsername(conversationId);
- const avatarPath = useAvatarPath(conversationId);
return (
);
};
diff --git a/ts/components/menu/Menu.tsx b/ts/components/menu/Menu.tsx
index 5dafc5445..b80335b50 100644
--- a/ts/components/menu/Menu.tsx
+++ b/ts/components/menu/Menu.tsx
@@ -1,7 +1,20 @@
-import React from 'react';
+import React, { useContext } from 'react';
import { Item, Submenu } from 'react-contexify';
import { useDispatch, useSelector } from 'react-redux';
+import {
+ useAvatarPath,
+ useConversationUsername,
+ useHasNickname,
+ useIsBlocked,
+ useIsKickedFromGroup,
+ useIsLeft,
+ useIsMe,
+ useIsPrivate,
+ useIsPublic,
+ useNotificationSetting,
+ useWeAreAdmin,
+} from '../../hooks/useParamSelector';
import {
blockConvoById,
clearNickNameByConvoId,
@@ -36,6 +49,7 @@ import { getFocusedSection } from '../../state/selectors/section';
import { getTimerOptions } from '../../state/selectors/timerOptions';
import { LocalizerKeys } from '../../types/LocalizerKeys';
import { SessionButtonColor } from '../basic/SessionButton';
+import { ContextConversationId } from '../leftpane/conversation-list-item/ConversationListItem';
const maxNumberOfPinnedConversations = 5;
@@ -60,17 +74,17 @@ function showBlock(isMe: boolean, isPrivate: boolean): boolean {
return !isMe && isPrivate;
}
-function showClearNickname(isMe: boolean, hasNickname: boolean, isGroup: boolean): boolean {
- return !isMe && hasNickname && !isGroup;
+function showClearNickname(isMe: boolean, hasNickname: boolean, isPrivate: boolean): boolean {
+ return !isMe && hasNickname && isPrivate;
}
-function showChangeNickname(isMe: boolean, isGroup: boolean) {
- return !isMe && !isGroup;
+function showChangeNickname(isMe: boolean, isPrivate: boolean) {
+ return !isMe && isPrivate;
}
// we want to show the copyId for open groups and private chats only
-function showCopyId(isPublic: boolean, isGroup: boolean): boolean {
- return !isGroup || isPublic;
+function showCopyId(isPublic: boolean, isPrivate: boolean): boolean {
+ return isPrivate || isPublic;
}
function showDeleteContact(
@@ -83,32 +97,36 @@ function showDeleteContact(
return !isGroup || (isGroup && (isGroupLeft || isKickedFromGroup || isPublic));
}
-const showUnbanUser = (isAdmin: boolean, isPublic: boolean, isKickedFromGroup: boolean) => {
- return !isKickedFromGroup && isAdmin && isPublic;
+const showUnbanUser = (weAreAdmin: boolean, isPublic: boolean, isKickedFromGroup: boolean) => {
+ return !isKickedFromGroup && weAreAdmin && isPublic;
};
-const showBanUser = (isAdmin: boolean, isPublic: boolean, isKickedFromGroup: boolean) => {
- return !isKickedFromGroup && isAdmin && isPublic;
+const showBanUser = (weAreAdmin: boolean, isPublic: boolean, isKickedFromGroup: boolean) => {
+ return !isKickedFromGroup && weAreAdmin && isPublic;
};
function showAddModerators(
- isAdmin: boolean,
+ weAreAdmin: boolean,
isPublic: boolean,
isKickedFromGroup: boolean
): boolean {
- return !isKickedFromGroup && isAdmin && isPublic;
+ return !isKickedFromGroup && weAreAdmin && isPublic;
}
function showRemoveModerators(
- isAdmin: boolean,
+ weAreAdmin: boolean,
isPublic: boolean,
isKickedFromGroup: boolean
): boolean {
- return !isKickedFromGroup && isAdmin && isPublic;
+ return !isKickedFromGroup && weAreAdmin && isPublic;
}
-function showUpdateGroupName(isAdmin: boolean, isKickedFromGroup: boolean, left: boolean): boolean {
- return !isKickedFromGroup && !left && isAdmin;
+function showUpdateGroupName(
+ weAreAdmin: boolean,
+ isKickedFromGroup: boolean,
+ left: boolean
+): boolean {
+ return !isKickedFromGroup && !left && weAreAdmin;
}
function showLeaveGroup(
@@ -120,22 +138,21 @@ function showLeaveGroup(
return !isKickedFromGroup && !left && isGroup && !isPublic;
}
-function showInviteContact(isGroup: boolean, isPublic: boolean): boolean {
- return isGroup && isPublic;
+function showInviteContact(isPublic: boolean): boolean {
+ return isPublic;
}
/** Menu items standardized */
-export function getInviteContactMenuItem(
- isGroup: boolean | undefined,
- isPublic: boolean | undefined,
- conversationId: string
-): JSX.Element | null {
- if (showInviteContact(Boolean(isGroup), Boolean(isPublic))) {
+export const InviteContactMenuItem = (): JSX.Element | null => {
+ const convoId = useContext(ContextConversationId);
+ const isPublic = useIsPublic(convoId);
+
+ if (showInviteContact(isPublic)) {
return (
- {
- showInviteContactByConvoId(conversationId);
+ showInviteContactByConvoId(convoId);
}}
>
{window.i18n('inviteContacts')}
@@ -143,13 +160,10 @@ export function getInviteContactMenuItem(
);
}
return null;
-}
-
-export interface PinConversationMenuItemProps {
- conversationId: string;
-}
+};
-export const getPinConversationMenuItem = (conversationId: string): JSX.Element | null => {
+export const PinConversationMenuItem = (): JSX.Element | null => {
+ const conversationId = useContext(ContextConversationId);
const isMessagesSection = useSelector(getFocusedSection) === SectionType.Message;
const nbOfAlreadyPinnedConvos = useSelector(getNumberOfPinnedConversations);
@@ -175,30 +189,22 @@ export const getPinConversationMenuItem = (conversationId: string): JSX.Element
return null;
};
-export function getDeleteContactMenuItem(
- isGroup: boolean | undefined,
- isPublic: boolean | undefined,
- isLeft: boolean | undefined,
- isKickedFromGroup: boolean | undefined,
- conversationId: string
-): JSX.Element | null {
+export const DeleteContactMenuItem = () => {
const dispatch = useDispatch();
+ const convoId = useContext(ContextConversationId);
+ const isPublic = useIsPublic(convoId);
+ const isLeft = useIsLeft(convoId);
+ const isKickedFromGroup = useIsKickedFromGroup(convoId);
+ const isPrivate = useIsPrivate(convoId);
- if (
- showDeleteContact(
- Boolean(isGroup),
- Boolean(isPublic),
- Boolean(isLeft),
- Boolean(isKickedFromGroup)
- )
- ) {
+ if (showDeleteContact(!isPrivate, isPublic, isLeft, isKickedFromGroup)) {
let menuItemText: string;
if (isPublic) {
menuItemText = window.i18n('leaveGroup');
} else {
- menuItemText = isGroup
- ? window.i18n('editMenuDeleteGroup')
- : window.i18n('editMenuDeleteContact');
+ menuItemText = isPrivate
+ ? window.i18n('editMenuDeleteContact')
+ : window.i18n('editMenuDeleteGroup');
}
const onClickClose = () => {
@@ -209,13 +215,13 @@ export function getDeleteContactMenuItem(
dispatch(
updateConfirmModal({
title: menuItemText,
- message: isGroup
- ? window.i18n('leaveGroupConfirmation')
- : window.i18n('deleteContactConfirmation'),
+ message: isPrivate
+ ? window.i18n('deleteContactConfirmation')
+ : window.i18n('leaveGroupConfirmation'),
onClickClose,
okTheme: SessionButtonColor.Danger,
onClickOk: async () => {
- await getConversationController().deleteContact(conversationId);
+ await getConversationController().deleteContact(convoId);
},
})
);
@@ -224,22 +230,20 @@ export function getDeleteContactMenuItem(
return
- {menuItemText}
;
}
return null;
-}
+};
-export function getLeaveGroupMenuItem(
- isKickedFromGroup: boolean | undefined,
- left: boolean | undefined,
- isGroup: boolean | undefined,
- isPublic: boolean | undefined,
- conversationId: string
-): JSX.Element | null {
- if (
- showLeaveGroup(Boolean(isKickedFromGroup), Boolean(left), Boolean(isGroup), Boolean(isPublic))
- ) {
+export const LeaveGroupMenuItem = () => {
+ const convoId = useContext(ContextConversationId);
+ const isPublic = useIsPublic(convoId);
+ const isLeft = useIsLeft(convoId);
+ const isKickedFromGroup = useIsKickedFromGroup(convoId);
+ const isPrivate = useIsPrivate(convoId);
+
+ if (showLeaveGroup(isKickedFromGroup, isLeft, !isPrivate, isPublic)) {
return (
- {
- showLeaveGroupByConvoId(conversationId);
+ showLeaveGroupByConvoId(convoId);
}}
>
{window.i18n('leaveGroup')}
@@ -248,15 +252,14 @@ export function getLeaveGroupMenuItem(
}
return null;
-}
+};
-export function getShowUserDetailsMenuItem(
- isPrivate: boolean | undefined,
- conversationId: string,
- avatarPath: string | null,
- userName: string
-): JSX.Element | null {
+export const ShowUserDetailsMenuItem = () => {
const dispatch = useDispatch();
+ const convoId = useContext(ContextConversationId);
+ const isPrivate = useIsPrivate(convoId);
+ const avatarPath = useAvatarPath(convoId);
+ const userName = useConversationUsername(convoId) || convoId;
if (isPrivate) {
return (
@@ -264,7 +267,7 @@ export function getShowUserDetailsMenuItem(
onClick={() => {
dispatch(
updateUserDetailsModal({
- conversationId: conversationId,
+ conversationId: convoId,
userName,
authorAvatarPath: avatarPath,
})
@@ -277,19 +280,19 @@ export function getShowUserDetailsMenuItem(
}
return null;
-}
+};
-export function getUpdateGroupNameMenuItem(
- isAdmin: boolean | undefined,
- isKickedFromGroup: boolean | undefined,
- left: boolean | undefined,
- conversationId: string
-): JSX.Element | null {
- if (showUpdateGroupName(Boolean(isAdmin), Boolean(isKickedFromGroup), Boolean(left))) {
+export const UpdateGroupNameMenuItem = () => {
+ const convoId = useContext(ContextConversationId);
+ const left = useIsLeft(convoId);
+ const isKickedFromGroup = useIsKickedFromGroup(convoId);
+ const weAreAdmin = useWeAreAdmin(convoId);
+
+ if (showUpdateGroupName(weAreAdmin, isKickedFromGroup, left)) {
return (
- {
- await showUpdateGroupNameByConvoId(conversationId);
+ await showUpdateGroupNameByConvoId(convoId);
}}
>
{window.i18n('editGroup')}
@@ -297,19 +300,19 @@ export function getUpdateGroupNameMenuItem(
);
}
return null;
-}
+};
+
+export const RemoveModeratorsMenuItem = (): JSX.Element | null => {
+ const convoId = useContext(ContextConversationId);
+ const isPublic = useIsPublic(convoId);
+ const isKickedFromGroup = useIsKickedFromGroup(convoId);
+ const weAreAdmin = useWeAreAdmin(convoId);
-export function getRemoveModeratorsMenuItem(
- isAdmin: boolean | undefined,
- isPublic: boolean | undefined,
- isKickedFromGroup: boolean | undefined,
- conversationId: string
-): JSX.Element | null {
- if (showRemoveModerators(Boolean(isAdmin), Boolean(isPublic), Boolean(isKickedFromGroup))) {
+ if (showRemoveModerators(weAreAdmin, Boolean(isPublic), Boolean(isKickedFromGroup))) {
return (
- {
- showRemoveModeratorsByConvoId(conversationId);
+ showRemoveModeratorsByConvoId(convoId);
}}
>
{window.i18n('removeModerators')}
@@ -317,19 +320,19 @@ export function getRemoveModeratorsMenuItem(
);
}
return null;
-}
+};
-export function getAddModeratorsMenuItem(
- isAdmin: boolean | undefined,
- isPublic: boolean | undefined,
- isKickedFromGroup: boolean | undefined,
- conversationId: string
-): JSX.Element | null {
- if (showAddModerators(Boolean(isAdmin), Boolean(isPublic), Boolean(isKickedFromGroup))) {
+export const AddModeratorsMenuItem = (): JSX.Element | null => {
+ const convoId = useContext(ContextConversationId);
+ const isPublic = useIsPublic(convoId);
+ const isKickedFromGroup = useIsKickedFromGroup(convoId);
+ const weAreAdmin = useWeAreAdmin(convoId);
+
+ if (showAddModerators(weAreAdmin, isPublic, isKickedFromGroup)) {
return (
- {
- showAddModeratorsByConvoId(conversationId);
+ showAddModeratorsByConvoId(convoId);
}}
>
{window.i18n('addModerators')}
@@ -337,40 +340,39 @@ export function getAddModeratorsMenuItem(
);
}
return null;
-}
+};
+
+export const UnbanMenuItem = (): JSX.Element | null => {
+ const convoId = useContext(ContextConversationId);
+ const isPublic = useIsPublic(convoId);
+ const isKickedFromGroup = useIsKickedFromGroup(convoId);
+ const weAreAdmin = useWeAreAdmin(convoId);
-export function getUnbanMenuItem(
- isAdmin: boolean | undefined,
- isPublic: boolean | undefined,
- isKickedFromGroup: boolean | undefined,
- conversationId: string
-): JSX.Element | null {
- if (showUnbanUser(Boolean(isAdmin), Boolean(isPublic), Boolean(isKickedFromGroup))) {
+ if (showUnbanUser(weAreAdmin, isPublic, isKickedFromGroup)) {
return (
- {
- showUnbanUserByConvoId(conversationId);
+ showUnbanUserByConvoId(convoId);
}}
>
{window.i18n('unbanUser')}
);
}
- // TODO: translations
return null;
-}
+};
+
+export const BanMenuItem = (): JSX.Element | null => {
+ const convoId = useContext(ContextConversationId);
+ const isPublic = useIsPublic(convoId);
+ const isKickedFromGroup = useIsKickedFromGroup(convoId);
+ const weAreAdmin = useWeAreAdmin(convoId);
-export function getBanMenuItem(
- isAdmin: boolean | undefined,
- isPublic: boolean | undefined,
- isKickedFromGroup: boolean | undefined,
- conversationId: string
-): JSX.Element | null {
- if (showBanUser(Boolean(isAdmin), Boolean(isPublic), Boolean(isKickedFromGroup))) {
+ if (showBanUser(weAreAdmin, isPublic, isKickedFromGroup)) {
return (
- {
- showBanUserByConvoId(conversationId);
+ showBanUserByConvoId(convoId);
}}
>
{window.i18n('banUser')}
@@ -378,40 +380,38 @@ export function getBanMenuItem(
);
}
return null;
-}
+};
-export function getCopyMenuItem(
- isPublic: boolean | undefined,
- isGroup: boolean | undefined,
- conversationId: string
-): JSX.Element | null {
- if (showCopyId(Boolean(isPublic), Boolean(isGroup))) {
+export const CopyMenuItem = (): JSX.Element | null => {
+ const convoId = useContext(ContextConversationId);
+ const isPublic = useIsPublic(convoId);
+ const isPrivate = useIsPrivate(convoId);
+
+ if (showCopyId(isPublic, isPrivate)) {
const copyIdLabel = isPublic ? window.i18n('copyOpenGroupURL') : window.i18n('copySessionID');
- return
- copyPublicKeyByConvoId(conversationId)}>{copyIdLabel}
;
+ return - copyPublicKeyByConvoId(convoId)}>{copyIdLabel}
;
}
return null;
-}
+};
-export function getMarkAllReadMenuItem(conversationId: string): JSX.Element | null {
- return (
- - markAllReadByConvoId(conversationId)}>{window.i18n('markAllAsRead')}
- );
-}
+export const MarkAllReadMenuItem = (): JSX.Element | null => {
+ const convoId = useContext(ContextConversationId);
+ return - markAllReadByConvoId(convoId)}>{window.i18n('markAllAsRead')}
;
+};
-export function getDisappearingMenuItem(
- isPublic: boolean | undefined,
- isKickedFromGroup: boolean | undefined,
- left: boolean | undefined,
- isBlocked: boolean | undefined,
- conversationId: string
-): JSX.Element | null {
+export const DisappearingMessageMenuItem = (): JSX.Element | null => {
+ const convoId = useContext(ContextConversationId);
+ const isBlocked = useIsBlocked(convoId);
+ const isPublic = useIsPublic(convoId);
+ const isLeft = useIsLeft(convoId);
+ const isKickedFromGroup = useIsKickedFromGroup(convoId);
const timerOptions = useSelector(getTimerOptions).timerOptions;
if (
showTimerOptions(
Boolean(isPublic),
Boolean(isKickedFromGroup),
- Boolean(left),
+ Boolean(isLeft),
Boolean(isBlocked)
)
) {
@@ -427,7 +427,7 @@ export function getDisappearingMenuItem(
- {
- await setDisappearingMessagesByConvoId(conversationId, item.value);
+ await setDisappearingMessagesByConvoId(convoId, item.value);
}}
>
{item.name}
@@ -437,23 +437,16 @@ export function getDisappearingMenuItem(
);
}
return null;
-}
+};
+
+export const NotificationForConvoMenuItem = (): JSX.Element | null => {
+ const convoId = useContext(ContextConversationId);
+ const isKickedFromGroup = useIsKickedFromGroup(convoId);
+ const left = useIsLeft(convoId);
+ const isBlocked = useIsBlocked(convoId);
+ const isPrivate = useIsPrivate(convoId);
+ const currentNotificationSetting = useNotificationSetting(convoId);
-export function getNotificationForConvoMenuItem({
- conversationId,
- currentNotificationSetting,
- isBlocked,
- isKickedFromGroup,
- left,
- isPrivate,
-}: {
- isKickedFromGroup: boolean | undefined;
- left: boolean | undefined;
- isBlocked: boolean | undefined;
- isPrivate: boolean | undefined;
- currentNotificationSetting: ConversationNotificationSettingType | undefined;
- conversationId: string;
-}): JSX.Element | null {
if (showNotificationConvo(Boolean(isKickedFromGroup), Boolean(left), Boolean(isBlocked))) {
// const isRtlMode = isRtlBody();'
@@ -484,7 +477,7 @@ export function getNotificationForConvoMenuItem({
- {
- await setNotificationForConvoId(conversationId, item.value);
+ await setNotificationForConvoId(convoId, item.value);
}}
disabled={disabled}
>
@@ -496,55 +489,53 @@ export function getNotificationForConvoMenuItem({
);
}
return null;
-}
+};
export function isRtlBody(): boolean {
return ($('body') as any).hasClass('rtl');
}
-export function getBlockMenuItem(
- isMe: boolean | undefined,
- isPrivate: boolean | undefined,
- isBlocked: boolean | undefined,
- conversationId: string
-): JSX.Element | null {
+export const BlockMenuItem = (): JSX.Element | null => {
+ const convoId = useContext(ContextConversationId);
+ const isMe = useIsMe(convoId);
+ const isBlocked = useIsBlocked(convoId);
+ const isPrivate = useIsPrivate(convoId);
+
if (showBlock(Boolean(isMe), Boolean(isPrivate))) {
const blockTitle = isBlocked ? window.i18n('unblockUser') : window.i18n('blockUser');
const blockHandler = isBlocked
- ? () => unblockConvoById(conversationId)
- : () => blockConvoById(conversationId);
+ ? () => unblockConvoById(convoId)
+ : () => blockConvoById(convoId);
return
- {blockTitle}
;
}
return null;
-}
+};
-export function getClearNicknameMenuItem(
- isMe: boolean | undefined,
- hasNickname: boolean | undefined,
- isGroup: boolean | undefined,
- conversationId: string
-): JSX.Element | null {
- if (showClearNickname(Boolean(isMe), Boolean(hasNickname), Boolean(isGroup))) {
+export const ClearNicknameMenuItem = (): JSX.Element | null => {
+ const convoId = useContext(ContextConversationId);
+ const isMe = useIsMe(convoId);
+ const hasNickname = useHasNickname(convoId);
+ const isPrivate = useIsPrivate(convoId);
+
+ if (showClearNickname(Boolean(isMe), Boolean(hasNickname), Boolean(isPrivate))) {
return (
- - clearNickNameByConvoId(conversationId)}>
- {window.i18n('clearNickname')}
-
+ - clearNickNameByConvoId(convoId)}>{window.i18n('clearNickname')}
);
}
return null;
-}
+};
+
+export const ChangeNicknameMenuItem = () => {
+ const convoId = useContext(ContextConversationId);
+ const isMe = useIsMe(convoId);
+ const isPrivate = useIsPrivate(convoId);
-export function getChangeNicknameMenuItem(
- isMe: boolean | undefined,
- isGroup: boolean | undefined,
- conversationId: string
-): JSX.Element | null {
const dispatch = useDispatch();
- if (showChangeNickname(Boolean(isMe), Boolean(isGroup))) {
+ if (showChangeNickname(isMe, isPrivate)) {
return (
- {
- dispatch(changeNickNameModal({ conversationId }));
+ dispatch(changeNickNameModal({ conversationId: convoId }));
}}
>
{window.i18n('changeNickname')}
@@ -552,18 +543,18 @@ export function getChangeNicknameMenuItem(
);
}
return null;
-}
+};
+
+export const DeleteMessagesMenuItem = () => {
+ const convoId = useContext(ContextConversationId);
-export function getDeleteMessagesMenuItem(conversationId: string): JSX.Element | null {
return (
- {
- deleteAllMessagesByConvoIdWithConfirmation(conversationId);
+ deleteAllMessagesByConvoIdWithConfirmation(convoId);
}}
>
{window.i18n('deleteMessages')}
);
-
- return null;
-}
+};
diff --git a/ts/hooks/useParamSelector.ts b/ts/hooks/useParamSelector.ts
index 141c2315c..0ea86226d 100644
--- a/ts/hooks/useParamSelector.ts
+++ b/ts/hooks/useParamSelector.ts
@@ -52,7 +52,7 @@ export function useOurConversationUsername() {
}
export function useIsMe(pubkey?: string) {
- return pubkey && pubkey === UserUtils.getOurPubKeyStrFromCache();
+ return Boolean(pubkey && pubkey === UserUtils.getOurPubKeyStrFromCache());
}
export function useIsClosedGroup(convoId?: string) {
@@ -65,6 +65,45 @@ export function useIsPrivate(convoId?: string) {
return Boolean(convoProps && convoProps.isPrivate);
}
+export function useHasNickname(convoId?: string) {
+ const convoProps = useConversationPropsById(convoId);
+ return Boolean(convoProps && convoProps.hasNickname);
+}
+
+export function useNotificationSetting(convoId?: string) {
+ const convoProps = useConversationPropsById(convoId);
+ return convoProps?.currentNotificationSetting || 'all';
+}
+export function useIsPublic(convoId?: string) {
+ const convoProps = useConversationPropsById(convoId);
+ return Boolean(convoProps && convoProps.isPublic);
+}
+
+export function useIsBlocked(convoId?: string) {
+ const convoProps = useConversationPropsById(convoId);
+ return Boolean(convoProps && convoProps.isBlocked);
+}
+
+export function useIsLeft(convoId?: string) {
+ const convoProps = useConversationPropsById(convoId);
+ return Boolean(convoProps && convoProps.left);
+}
+
+export function useIsKickedFromGroup(convoId?: string) {
+ const convoProps = useConversationPropsById(convoId);
+ return Boolean(convoProps && convoProps.isKickedFromGroup);
+}
+
+export function useWeAreAdmin(convoId?: string) {
+ const convoProps = useConversationPropsById(convoId);
+ return Boolean(convoProps && convoProps.weAreAdmin);
+}
+
+export function useExpireTimer(convoId?: string) {
+ const convoProps = useConversationPropsById(convoId);
+ return Boolean(convoProps && convoProps.expireTimer);
+}
+
export function useIsPinned(convoId?: string) {
const convoProps = useConversationPropsById(convoId);
return Boolean(convoProps && convoProps.isPinned);
diff --git a/ts/hooks/useWeAreAdmin.ts b/ts/hooks/useWeAreAdmin.ts
deleted file mode 100644
index da7d6eddd..000000000
--- a/ts/hooks/useWeAreAdmin.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { useSelector } from 'react-redux';
-import { StateType } from '../state/reducer';
-
-export const useWeAreAdmin = (convoId?: string) =>
- useSelector((state: StateType) => {
- if (!convoId) {
- return false;
- }
- const convo = state.conversations.conversationLookup[convoId];
- if (!convo) {
- return false;
- }
- return convo.weAreAdmin;
- });
diff --git a/ts/state/selectors/conversations.ts b/ts/state/selectors/conversations.ts
index a7e94b936..c74b554f2 100644
--- a/ts/state/selectors/conversations.ts
+++ b/ts/state/selectors/conversations.ts
@@ -14,12 +14,9 @@ import {
import { getIntl, getOurNumber } from './user';
import { BlockedNumberController } from '../../util';
-import { ConversationNotificationSetting, ConversationTypeEnum } from '../../models/conversation';
+import { ConversationTypeEnum } from '../../models/conversation';
import { LocalizerType } from '../../types/Util';
-import {
- ConversationHeaderProps,
- ConversationHeaderTitleProps,
-} from '../../components/conversation/ConversationHeader';
+import { ConversationHeaderTitleProps } from '../../components/conversation/ConversationHeader';
import _ from 'lodash';
import { getIsMessageRequestsEnabled } from './userConfig';
import { ReplyingToMessageProps } from '../../components/conversation/composition/CompositionBox';
@@ -532,57 +529,24 @@ export const getCurrentNotificationSettingText = createSelector(getSelectedConve
}
});
-export const getConversationHeaderProps = createSelector(getSelectedConversation, (state):
- | ConversationHeaderProps
- | undefined => {
- if (!state) {
- return undefined;
- }
-
- const expirationSettingName = state.expireTimer
- ? window.Whisper.ExpirationTimerOptions.getName(state.expireTimer || 0)
- : null;
-
- return {
- conversationKey: state.id,
- isPrivate: !!state.isPrivate,
- currentNotificationSetting:
- state.currentNotificationSetting || ConversationNotificationSetting[0], // if undefined, it is 'all'
- isBlocked: !!state.isBlocked,
- left: !!state.left,
- avatarPath: state.avatarPath || null,
- expirationSettingName: expirationSettingName,
- hasNickname: !!state.hasNickname,
- weAreAdmin: !!state.weAreAdmin,
- isKickedFromGroup: !!state.isKickedFromGroup,
- isMe: !!state.isMe,
- members: state.members || [],
- isPublic: !!state.isPublic,
- profileName: state.profileName,
- name: state.name,
- subscriberCount: state.subscriberCount,
- isGroup: !!state.isGroup,
- };
-});
-
export const getIsSelectedPrivate = createSelector(
- getConversationHeaderProps,
- (headerProps): boolean => {
- return headerProps?.isPrivate || false;
+ getSelectedConversation,
+ (selectedProps): boolean => {
+ return selectedProps?.isPrivate || false;
}
);
export const getIsSelectedBlocked = createSelector(
- getConversationHeaderProps,
- (headerProps): boolean => {
- return headerProps?.isBlocked || false;
+ getSelectedConversation,
+ (selectedProps): boolean => {
+ return selectedProps?.isBlocked || false;
}
);
export const getIsSelectedNoteToSelf = createSelector(
- getConversationHeaderProps,
- (headerProps): boolean => {
- return headerProps?.isMe || false;
+ getSelectedConversation,
+ (selectedProps): boolean => {
+ return selectedProps?.isMe || false;
}
);