@ -1,22 +1,21 @@
import React , { useContext } from 'react' ;
import { Item , Submenu } from 'react-contexify' ;
import { Item } from 'react-contexify' ;
import { useDispatch , useSelector } from 'react-redux' ;
import {
useAvatarPath ,
useConversationUsername ,
useHasNickname ,
useIsActive ,
useIsBlinded ,
useIsBlocked ,
useIsIncomingRequest ,
useIsKickedFromGroup ,
useIsLeft ,
useIsMe ,
useIsPinned ,
useIsPrivate ,
useIsPrivateAndFriend ,
useIsPublic ,
useIsRequest ,
useNotificationSetting ,
useWeAreAdmin ,
} from '../../hooks/useParamSelector' ;
import {
@ -27,8 +26,6 @@ import {
declineConversationWithConfirm ,
deleteAllMessagesByConvoIdWithConfirmation ,
markAllReadByConvoId ,
setDisappearingMessagesByConvoId ,
setNotificationForConvoId ,
showAddModeratorsByConvoId ,
showBanUserByConvoId ,
showInviteContactByConvoId ,
@ -38,65 +35,20 @@ import {
showUpdateGroupNameByConvoId ,
unblockConvoById ,
} from '../../interactions/conversationInteractions' ;
import {
ConversationNotificationSetting ,
ConversationNotificationSettingType ,
} from '../../models/conversationAttributes' ;
import { getConversationController } from '../../session/conversations' ;
import {
changeNickNameModal ,
updateConfirmModal ,
updateUserDetailsModal ,
} from '../../state/ducks/modalDialog' ;
import { hideMessageRequestBanner } from '../../state/ducks/userConfig' ;
import { getIsMessageSection } from '../../state/selectors/section' ;
import { getTimerOptions } from '../../state/selectors/timerOptions' ;
import { LocalizerKeys } from '../../types/LocalizerKeys' ;
import {
useSelectedConversationKey ,
useSelectedIsPrivateFriend ,
} from '../../state/selectors/selectedConversation' ;
import { SessionButtonColor } from '../basic/SessionButton' ;
import { ContextConversationId } from '../leftpane/conversation-list-item/ConversationListItem' ;
function showTimerOptions (
isPublic : boolean ,
isKickedFromGroup : boolean ,
left : boolean ,
isBlocked : boolean ,
isRequest : boolean ,
isActive : boolean
) : boolean {
return ! isPublic && ! left && ! isKickedFromGroup && ! isBlocked && ! isRequest && isActive ;
}
function showNotificationConvo (
isKickedFromGroup : boolean ,
left : boolean ,
isBlocked : boolean ,
isRequest : boolean
) : boolean {
return ! left && ! isKickedFromGroup && ! isBlocked && ! isRequest ;
}
function showBlock ( isMe : boolean , isPrivate : boolean , isRequest : boolean ) : boolean {
return ! isMe && isPrivate && ! isRequest ;
}
function showClearNickname (
isMe : boolean ,
hasNickname : boolean ,
isPrivate : boolean ,
isRequest : boolean
) : boolean {
return ! isMe && hasNickname && isPrivate && ! isRequest ;
}
function showChangeNickname ( isMe : boolean , isPrivate : boolean , isRequest : boolean ) {
return ! isMe && isPrivate && ! isRequest ;
}
// we want to show the copyId for open groups and private chats only
function showCopyId ( isPublic : boolean , isPrivate : boolean , isBlinded : boolean ) : boolean {
return ( isPrivate && ! isBlinded ) || isPublic ;
}
function showDeleteContact (
isGroup : boolean ,
isPublic : boolean ,
@ -108,30 +60,6 @@ function showDeleteContact(
return ( ! isGroup && ! isRequest ) || ( isGroup && ( isGroupLeft || isKickedFromGroup || isPublic ) ) ;
}
const showUnbanUser = ( weAreAdmin : boolean , isPublic : boolean , isKickedFromGroup : boolean ) = > {
return ! isKickedFromGroup && weAreAdmin && isPublic ;
} ;
const showBanUser = ( weAreAdmin : boolean , isPublic : boolean , isKickedFromGroup : boolean ) = > {
return ! isKickedFromGroup && weAreAdmin && isPublic ;
} ;
function showAddModerators (
weAreAdmin : boolean ,
isPublic : boolean ,
isKickedFromGroup : boolean
) : boolean {
return ! isKickedFromGroup && weAreAdmin && isPublic ;
}
function showRemoveModerators (
weAreAdmin : boolean ,
isPublic : boolean ,
isKickedFromGroup : boolean
) : boolean {
return ! isKickedFromGroup && weAreAdmin && isPublic ;
}
function showUpdateGroupName (
weAreAdmin : boolean ,
isKickedFromGroup : boolean ,
@ -176,7 +104,7 @@ export const InviteContactMenuItem = (): JSX.Element | null => {
export const PinConversationMenuItem = ( ) : JSX . Element | null = > {
const conversationId = useContext ( ContextConversationId ) ;
const isMessagesSection = useSelector ( getIsMessageSection ) ;
const isRequest = useIs Request( conversationId ) ;
const isRequest = useIs Incoming Request( conversationId ) ;
const isPinned = useIsPinned ( conversationId ) ;
if ( isMessagesSection && ! isRequest ) {
@ -195,7 +123,7 @@ export const PinConversationMenuItem = (): JSX.Element | null => {
export const MarkConversationUnreadMenuItem = ( ) : JSX . Element | null = > {
const conversationId = useContext ( ContextConversationId ) ;
const isMessagesSection = useSelector ( getIsMessageSection ) ;
const isRequest = useIs Request( conversationId ) ;
const isRequest = useIs Incoming Request( conversationId ) ;
if ( isMessagesSection && ! isRequest ) {
const conversation = getConversationController ( ) . get ( conversationId ) ;
@ -216,7 +144,7 @@ export const DeleteContactMenuItem = () => {
const isLeft = useIsLeft ( convoId ) ;
const isKickedFromGroup = useIsKickedFromGroup ( convoId ) ;
const isPrivate = useIsPrivate ( convoId ) ;
const isRequest = useIs Request( convoId ) ;
const isRequest = useIs Incoming Request( convoId ) ;
if ( showDeleteContact ( ! isPrivate , isPublic , isLeft , isKickedFromGroup , isRequest ) ) {
let menuItemText : string ;
@ -330,7 +258,7 @@ export const RemoveModeratorsMenuItem = (): JSX.Element | null => {
const isKickedFromGroup = useIsKickedFromGroup ( convoId ) ;
const weAreAdmin = useWeAreAdmin ( convoId ) ;
if ( showRemoveModerators ( weAreAdmin , Boolean ( isPublic ) , Boolean ( isKickedFromGroup ) ) ) {
if ( ! isKickedFromGroup && weAreAdmin && isPublic ) {
return (
< Item
onClick = { ( ) = > {
@ -350,7 +278,7 @@ export const AddModeratorsMenuItem = (): JSX.Element | null => {
const isKickedFromGroup = useIsKickedFromGroup ( convoId ) ;
const weAreAdmin = useWeAreAdmin ( convoId ) ;
if ( showAddModerators ( weAreAdmin , isPublic , isKickedFromGroup ) ) {
if ( ! isKickedFromGroup && weAreAdmin && isPublic ) {
return (
< Item
onClick = { ( ) = > {
@ -370,7 +298,7 @@ export const UnbanMenuItem = (): JSX.Element | null => {
const isKickedFromGroup = useIsKickedFromGroup ( convoId ) ;
const weAreAdmin = useWeAreAdmin ( convoId ) ;
if ( showUnbanUser( weAreAdmin , isPublic , isKickedFromGroup ) ) {
if ( isPublic && ! isKickedFromGroup && weAreAdmin ) {
return (
< Item
onClick = { ( ) = > {
@ -390,7 +318,7 @@ export const BanMenuItem = (): JSX.Element | null => {
const isKickedFromGroup = useIsKickedFromGroup ( convoId ) ;
const weAreAdmin = useWeAreAdmin ( convoId ) ;
if ( showBanUser( weAreAdmin , isPublic , isKickedFromGroup ) ) {
if ( isPublic && ! isKickedFromGroup && weAreAdmin ) {
return (
< Item
onClick = { ( ) = > {
@ -410,7 +338,9 @@ export const CopyMenuItem = (): JSX.Element | null => {
const isPrivate = useIsPrivate ( convoId ) ;
const isBlinded = useIsBlinded ( convoId ) ;
if ( showCopyId ( isPublic , isPrivate , isBlinded ) ) {
// we want to show the copyId for open groups and private chats only
if ( ( isPrivate && ! isBlinded ) || isPublic ) {
const copyIdLabel = isPublic ? window . i18n ( 'copyOpenGroupURL' ) : window . i18n ( 'copySessionID' ) ;
return (
< Item
@ -427,8 +357,8 @@ export const CopyMenuItem = (): JSX.Element | null => {
export const MarkAllReadMenuItem = ( ) : JSX . Element | null = > {
const convoId = useContext ( ContextConversationId ) ;
const is Request = useIs Request( convoId ) ;
if ( ! is Request) {
const is Incoming Request = useIs Incoming Request( convoId ) ;
if ( ! is Incoming Request) {
return (
< Item onClick = { ( ) = > markAllReadByConvoId ( convoId ) } > { window . i18n ( 'markAllAsRead' ) } < / Item >
) ;
@ -437,105 +367,6 @@ export const MarkAllReadMenuItem = (): JSX.Element | null => {
}
} ;
export const DisappearingMessageMenuItem = ( ) : JSX . Element | null = > {
const convoId = useContext ( ContextConversationId ) ;
const isBlocked = useIsBlocked ( convoId ) ;
const isActive = useIsActive ( convoId ) ;
const isPublic = useIsPublic ( convoId ) ;
const isLeft = useIsLeft ( convoId ) ;
const isKickedFromGroup = useIsKickedFromGroup ( convoId ) ;
const timerOptions = useSelector ( getTimerOptions ) . timerOptions ;
const isRequest = useIsRequest ( convoId ) ;
if (
showTimerOptions (
Boolean ( isPublic ) ,
Boolean ( isKickedFromGroup ) ,
Boolean ( isLeft ) ,
Boolean ( isBlocked ) ,
isRequest ,
isActive
)
) {
// const isRtlMode = isRtlBody();
return (
// Remove the && false to make context menu work with RTL support
< Submenu
label = { window . i18n ( 'disappearingMessages' ) }
// rtl={isRtlMode && false}
>
{ timerOptions . map ( item = > (
< Item
key = { item . value }
onClick = { async ( ) = > {
await setDisappearingMessagesByConvoId ( convoId , item . value ) ;
} }
>
{ item . name }
< / Item >
) ) }
< / Submenu >
) ;
}
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 isRequest = useIsRequest ( convoId ) ;
const currentNotificationSetting = useNotificationSetting ( convoId ) ;
if (
showNotificationConvo ( Boolean ( isKickedFromGroup ) , Boolean ( left ) , Boolean ( isBlocked ) , isRequest )
) {
// const isRtlMode = isRtlBody();'
// exclude mentions_only settings for private chats as this does not make much sense
const notificationForConvoOptions = ConversationNotificationSetting . filter ( n = >
isPrivate ? n !== 'mentions_only' : true
) . map ( ( n : ConversationNotificationSettingType ) = > {
// do this separately so typescript's compiler likes it
const keyToUse : LocalizerKeys =
n === 'all' || ! n
? 'notificationForConvo_all'
: n === 'disabled'
? 'notificationForConvo_disabled'
: 'notificationForConvo_mentions_only' ;
return { value : n , name : window.i18n ( keyToUse ) } ;
} ) ;
return (
// Remove the && false to make context menu work with RTL support
< Submenu
label = { window . i18n ( 'notificationForConvo' ) as any }
// rtl={isRtlMode && false}
>
{ ( notificationForConvoOptions || [ ] ) . map ( item = > {
const disabled = item . value === currentNotificationSetting ;
return (
< Item
key = { item . value }
onClick = { async ( ) = > {
await setNotificationForConvoId ( convoId , item . value ) ;
} }
disabled = { disabled }
>
{ item . name }
< / Item >
) ;
} ) }
< / Submenu >
) ;
}
return null ;
} ;
export function isRtlBody ( ) : boolean {
const body = document . getElementsByTagName ( 'body' ) . item ( 0 ) ;
@ -547,10 +378,10 @@ export const BlockMenuItem = (): JSX.Element | null => {
const isMe = useIsMe ( convoId ) ;
const isBlocked = useIsBlocked ( convoId ) ;
const isPrivate = useIsPrivate ( convoId ) ;
const is Request = useIs Request( convoId ) ;
const is Incoming Request = useIs Incoming Request( convoId ) ;
if ( showBlock ( Boolean ( isMe ) , Boolean ( isPrivate ) , Boolean ( isRequest ) ) ) {
const blockTitle = isBlocked ? window . i18n ( 'unblock User ') : window . i18n ( 'block User ') ;
if ( ! isMe && isPrivate && ! isIncomingRequest ) {
const blockTitle = isBlocked ? window . i18n ( 'unblock ') : window . i18n ( 'block ') ;
const blockHandler = isBlocked
? ( ) = > unblockConvoById ( convoId )
: ( ) = > blockConvoById ( convoId ) ;
@ -564,75 +395,63 @@ export const ClearNicknameMenuItem = (): JSX.Element | null => {
const isMe = useIsMe ( convoId ) ;
const hasNickname = useHasNickname ( convoId ) ;
const isPrivate = useIsPrivate ( convoId ) ;
const is Request = Boolean ( useIsRequest ( convoId ) ) ; // easier to copy paste
const is PrivateAndFriend = useIsPrivateAndFriend ( convoId ) ;
if ( showClearNickname ( Boolean ( isMe ) , Boolean ( hasNickname ) , Boolean ( isPrivate ) , isRequest ) ) {
return (
< Item onClick = { ( ) = > clearNickNameByConvoId ( convoId ) } > { window . i18n ( 'clearNickname' ) } < / Item >
) ;
if ( isMe || ! hasNickname || ! isPrivate || ! isPrivateAndFriend ) {
return null ;
}
return null ;
return (
< Item onClick = { ( ) = > clearNickNameByConvoId ( convoId ) } > { window . i18n ( 'clearNickname' ) } < / Item >
) ;
} ;
export const ChangeNicknameMenuItem = ( ) = > {
const convoId = useContext ( ContextConversationId ) ;
const isMe = useIsMe ( convoId ) ;
const isPrivate = useIsPrivate ( convoId ) ;
const isRequest = useIsRequest ( convoId ) ;
const isPrivateAndFriend = useSelectedIsPrivateFriend ( ) ;
const dispatch = useDispatch ( ) ;
if ( showChangeNickname ( isMe , isPrivate , isRequest ) ) {
return (
< Item
onClick = { ( ) = > {
dispatch ( changeNickNameModal ( { conversationId : convoId } ) ) ;
} }
>
{ window . i18n ( 'changeNickname' ) }
< / Item >
) ;
}
return null ;
} ;
export const DeleteMessagesMenuItem = ( ) = > {
const convoId = useContext ( ContextConversationId ) ;
const isRequest = useIsRequest ( convoId ) ;
if ( is Request ) {
if ( isMe || ! isPrivate || ! isPrivateAndFriend ) {
return null ;
}
return (
< Item
onClick = { ( ) = > {
d eleteAllMessagesByConvoIdWithConfirmation( convoId ) ;
dispatch ( changeNickNameModal ( { conversationId : convoId } ) ) ;
} }
>
{ window . i18n ( ' deleteMessages ') }
{ window . i18n ( 'changeNickname' ) }
< / Item >
) ;
} ;
export const HideBannerMenuItem = ( ) : JSX . Element = > {
const dispatch = useDispatch ( ) ;
export const DeleteMessagesMenuItem = ( ) = > {
const convoId = useContext ( ContextConversationId ) ;
if ( ! convoId ) {
return null ;
}
return (
< Item
onClick = { ( ) = > {
dispatch ( hideMessageRequestBanner ( ) ) ;
d eleteAllMessagesByConvoIdWithConfirmation( convoId ) ;
} }
>
{ window . i18n ( ' hideBanner ') }
{ window . i18n ( ' deleteMessages ') }
< / Item >
) ;
} ;
export const AcceptM enuItem = ( ) = > {
export const AcceptM sgRequestM enuItem = ( ) = > {
const convoId = useContext ( ContextConversationId ) ;
const isRequest = useIs Request( convoId ) ;
const isRequest = useIs Incoming Request( convoId ) ;
const convo = getConversationController ( ) . get ( convoId ) ;
const isPrivate = useIsPrivate ( convoId ) ;
if ( isRequest ) {
if ( isRequest && isPrivate ) {
return (
< Item
onClick = { async ( ) = > {
@ -648,15 +467,22 @@ export const AcceptMenuItem = () => {
return null ;
} ;
export const DeclineM enuItem = ( ) = > {
export const DeclineM sgRequestM enuItem = ( ) = > {
const convoId = useContext ( ContextConversationId ) ;
const isRequest = useIsRequest ( convoId ) ;
const isRequest = useIsIncomingRequest ( convoId ) ;
const isPrivate = useIsPrivate ( convoId ) ;
const selected = useSelectedConversationKey ( ) ;
if ( isRequest ) {
if ( is Private && is Request) {
return (
< Item
onClick = { ( ) = > {
declineConversationWithConfirm ( convoId , true ) ;
declineConversationWithConfirm ( {
conversationId : convoId ,
syncToDevices : true ,
blockContact : false ,
currentlySelectedConvo : selected || undefined ,
} ) ;
} }
>
{ window . i18n ( 'decline' ) }
@ -665,3 +491,28 @@ export const DeclineMenuItem = () => {
}
return null ;
} ;
export const DeclineAndBlockMsgRequestMenuItem = ( ) = > {
const convoId = useContext ( ContextConversationId ) ;
const isRequest = useIsIncomingRequest ( convoId ) ;
const selected = useSelectedConversationKey ( ) ;
const isPrivate = useIsPrivate ( convoId ) ;
if ( isRequest && isPrivate ) {
return (
< Item
onClick = { ( ) = > {
declineConversationWithConfirm ( {
conversationId : convoId ,
syncToDevices : true ,
blockContact : true ,
currentlySelectedConvo : selected || undefined ,
} ) ;
} }
>
{ window . i18n ( 'block' ) }
< / Item >
) ;
}
return null ;
} ;