From 55a2767fce9309c80782159520778b7a7f226a28 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Thu, 6 Apr 2023 16:11:36 +1000 Subject: [PATCH] feat: do not approve a convo before sending the first message but still sync it's state through the createdAt with libsession util --- .../ConversationListItem.tsx | 17 ++--- .../conversation-list-item/ConvoIdContext.tsx | 14 ++++ .../conversation-list-item/HeaderItem.tsx | 10 +-- .../conversation-list-item/MessageItem.tsx | 14 ++-- .../conversation-list-item/UserItem.tsx | 6 +- .../leftpane/overlay/OverlayMessage.tsx | 4 +- ts/components/menu/ConversationHeaderMenu.tsx | 6 +- .../menu/ConversationListItemContextMenu.tsx | 39 +++++++++-- ts/components/menu/Menu.tsx | 67 +++++++------------ ts/components/settings/BlockedList.tsx | 2 +- ts/interactions/conversationInteractions.ts | 8 +-- ts/models/conversation.ts | 4 +- ts/node/migration/sessionMigrations.ts | 2 +- ts/receiver/configMessage.ts | 6 -- .../conversations/ConversationController.ts | 2 +- .../libsession/libsession_utils_contacts.ts | 24 +++---- .../libsession_utils_convo_info_volatile.ts | 8 +-- .../libsession_utils_user_profile.ts | 6 +- ts/state/ducks/conversations.ts | 4 +- ts/state/selectors/conversations.ts | 17 +++-- .../libsession_wrapper_contacts_test.ts | 33 ++++++--- 21 files changed, 161 insertions(+), 132 deletions(-) create mode 100644 ts/components/leftpane/conversation-list-item/ConvoIdContext.tsx diff --git a/ts/components/leftpane/conversation-list-item/ConversationListItem.tsx b/ts/components/leftpane/conversation-list-item/ConversationListItem.tsx index 2158a3197..ccd66c89e 100644 --- a/ts/components/leftpane/conversation-list-item/ConversationListItem.tsx +++ b/ts/components/leftpane/conversation-list-item/ConversationListItem.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames'; -import React, { useCallback, useContext } from 'react'; +import React, { useCallback } from 'react'; import { contextMenu } from 'react-contexify'; import { Avatar, AvatarSize } from '../../avatar/Avatar'; @@ -7,8 +7,8 @@ import { Avatar, AvatarSize } from '../../avatar/Avatar'; import { createPortal } from 'react-dom'; import { useDispatch, useSelector } from 'react-redux'; import { - openConversationWithMessages, ReduxConversationType, + openConversationWithMessages, } from '../../../state/ducks/conversations'; import { updateUserDetailsModal } from '../../../state/ducks/modalDialog'; @@ -24,18 +24,13 @@ import { import { isSearching } from '../../../state/selectors/search'; import { useSelectedConversationKey } from '../../../state/selectors/selectedConversation'; import { MemoConversationListItemContextMenu } from '../../menu/ConversationListItemContextMenu'; +import { ContextConversationProvider, useConvoIdFromContext } from './ConvoIdContext'; import { ConversationListItemHeaderItem } from './HeaderItem'; import { MessageItem } from './MessageItem'; // tslint:disable-next-line: no-empty-interface export type ConversationListItemProps = Pick; -/** - * This React context is used to share deeply in the tree of the ConversationListItem what is the ID we are currently rendering. - * This is to avoid passing the prop to all the subtree component - */ -export const ContextConversationId = React.createContext(''); - type PropsHousekeeping = { style?: Object; }; @@ -48,7 +43,7 @@ const Portal = ({ children }: { children: any }) => { }; const AvatarItem = () => { - const conversationId = useContext(ContextConversationId); + const conversationId = useConvoIdFromContext(); const userName = useConversationUsername(conversationId); const isPrivate = useIsPrivate(conversationId); const avatarPath = useAvatarPath(conversationId); @@ -107,7 +102,7 @@ const ConversationListItem = (props: Props) => { ); return ( - +
{
- + ); }; diff --git a/ts/components/leftpane/conversation-list-item/ConvoIdContext.tsx b/ts/components/leftpane/conversation-list-item/ConvoIdContext.tsx new file mode 100644 index 000000000..685460f63 --- /dev/null +++ b/ts/components/leftpane/conversation-list-item/ConvoIdContext.tsx @@ -0,0 +1,14 @@ +import React, { useContext } from 'react'; + +/** + * This React context is used to share deeply in the tree of the ConversationListItem what is the ID we are currently rendering. + * This is to avoid passing the prop to all the subtree component + */ +const ContextConversationId = React.createContext(''); + +export const ContextConversationProvider = ContextConversationId.Provider; + +export function useConvoIdFromContext() { + const convoId = useContext(ContextConversationId); + return convoId; +} diff --git a/ts/components/leftpane/conversation-list-item/HeaderItem.tsx b/ts/components/leftpane/conversation-list-item/HeaderItem.tsx index aff79b258..45e4d64fe 100644 --- a/ts/components/leftpane/conversation-list-item/HeaderItem.tsx +++ b/ts/components/leftpane/conversation-list-item/HeaderItem.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames'; -import React, { useContext } from 'react'; +import React from 'react'; import { useSelector } from 'react-redux'; import styled from 'styled-components'; import { Data } from '../../../data/data'; @@ -20,12 +20,12 @@ import { isSearching } from '../../../state/selectors/search'; import { getIsMessageSection } from '../../../state/selectors/section'; import { Timestamp } from '../../conversation/Timestamp'; import { SessionIcon } from '../../icon'; -import { ContextConversationId } from './ConversationListItem'; +import { useConvoIdFromContext } from './ConvoIdContext'; import { UserItem } from './UserItem'; const NotificationSettingIcon = () => { const isMessagesSection = useSelector(getIsMessageSection); - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const convoSetting = useConversationPropsById(convoId)?.currentNotificationSetting; if (!isMessagesSection) { @@ -66,7 +66,7 @@ const StyledConversationListItemIconWrapper = styled.div` `; const PinIcon = () => { - const conversationId = useContext(ContextConversationId); + const conversationId = useConvoIdFromContext(); const isMessagesSection = useSelector(getIsMessageSection); const isPinned = useIsPinned(conversationId); @@ -165,7 +165,7 @@ const UnreadCount = ({ convoId }: { convoId: string }) => { }; export const ConversationListItemHeaderItem = () => { - const conversationId = useContext(ContextConversationId); + const conversationId = useConvoIdFromContext(); const isSearchingMode = useSelector(isSearching); diff --git a/ts/components/leftpane/conversation-list-item/MessageItem.tsx b/ts/components/leftpane/conversation-list-item/MessageItem.tsx index ba50e0147..dbffb1b45 100644 --- a/ts/components/leftpane/conversation-list-item/MessageItem.tsx +++ b/ts/components/leftpane/conversation-list-item/MessageItem.tsx @@ -1,19 +1,19 @@ import classNames from 'classnames'; -import React, { useContext } from 'react'; import { isEmpty } from 'lodash'; +import React from 'react'; +import { useSelector } from 'react-redux'; import { useConversationPropsById, useHasUnread, useIsPrivate, useIsTyping, } from '../../../hooks/useParamSelector'; -import { MessageBody } from '../../conversation/message/message-content/MessageBody'; -import { OutgoingMessageStatus } from '../../conversation/message/message-content/OutgoingMessageStatus'; -import { TypingAnimation } from '../../conversation/TypingAnimation'; -import { ContextConversationId } from './ConversationListItem'; -import { useSelector } from 'react-redux'; import { isSearching } from '../../../state/selectors/search'; import { getIsMessageRequestOverlayShown } from '../../../state/selectors/section'; +import { TypingAnimation } from '../../conversation/TypingAnimation'; +import { MessageBody } from '../../conversation/message/message-content/MessageBody'; +import { OutgoingMessageStatus } from '../../conversation/message/message-content/OutgoingMessageStatus'; +import { useConvoIdFromContext } from './ConvoIdContext'; function useLastMessageFromConvo(convoId: string) { const convoProps = useConversationPropsById(convoId); @@ -24,7 +24,7 @@ function useLastMessageFromConvo(convoId: string) { } export const MessageItem = () => { - const conversationId = useContext(ContextConversationId); + const conversationId = useConvoIdFromContext(); const lastMessage = useLastMessageFromConvo(conversationId); const isGroup = !useIsPrivate(conversationId); diff --git a/ts/components/leftpane/conversation-list-item/UserItem.tsx b/ts/components/leftpane/conversation-list-item/UserItem.tsx index 22ee22564..0526bcb2f 100644 --- a/ts/components/leftpane/conversation-list-item/UserItem.tsx +++ b/ts/components/leftpane/conversation-list-item/UserItem.tsx @@ -1,4 +1,4 @@ -import React, { useContext } from 'react'; +import React from 'react'; import { useSelector } from 'react-redux'; import { useConversationRealName, @@ -9,10 +9,10 @@ import { import { PubKey } from '../../../session/types'; import { isSearching } from '../../../state/selectors/search'; import { ContactName } from '../../conversation/ContactName'; -import { ContextConversationId } from './ConversationListItem'; +import { useConvoIdFromContext } from './ConvoIdContext'; export const UserItem = () => { - const conversationId = useContext(ContextConversationId); + const conversationId = useConvoIdFromContext(); // we want to show the nickname in brackets if a nickname is set for search results const isSearchResultsMode = useSelector(isSearching); diff --git a/ts/components/leftpane/overlay/OverlayMessage.tsx b/ts/components/leftpane/overlay/OverlayMessage.tsx index 0314c02c0..5fefc0f29 100644 --- a/ts/components/leftpane/overlay/OverlayMessage.tsx +++ b/ts/components/leftpane/overlay/OverlayMessage.tsx @@ -63,15 +63,13 @@ export const OverlayMessage = () => { ); // we now want to show a conversation we just started on the leftpane, even if we did not send a message to it yet - if (!convo.isActive() || !convo.isApproved() || convo.isHidden()) { + if (!convo.isActive() || convo.isHidden()) { // bump the timestamp only if we were not active before if (!convo.isActive()) { convo.set({ active_at: Date.now() }); } await convo.unhideIfNeeded(false); - // TODO find a way to make this not a hack to show it in the list - convo.set({ isApproved: true }); await convo.commit(); } diff --git a/ts/components/menu/ConversationHeaderMenu.tsx b/ts/components/menu/ConversationHeaderMenu.tsx index 170c42c0b..7108413f4 100644 --- a/ts/components/menu/ConversationHeaderMenu.tsx +++ b/ts/components/menu/ConversationHeaderMenu.tsx @@ -22,7 +22,6 @@ import { } from '../../state/selectors/selectedConversation'; import { getTimerOptions } from '../../state/selectors/timerOptions'; import { LocalizerKeys } from '../../types/LocalizerKeys'; -import { ContextConversationId } from '../leftpane/conversation-list-item/ConversationListItem'; import { SessionContextMenuContainer } from '../SessionContextMenuContainer'; import { AddModeratorsMenuItem, @@ -40,6 +39,7 @@ import { UnbanMenuItem, UpdateGroupNameMenuItem, } from './Menu'; +import { ContextConversationProvider } from '../leftpane/conversation-list-item/ConvoIdContext'; export type PropsConversationHeaderMenu = { triggerId: string; @@ -62,7 +62,7 @@ export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => { } return ( - + @@ -83,7 +83,7 @@ export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => { - + ); }; diff --git a/ts/components/menu/ConversationListItemContextMenu.tsx b/ts/components/menu/ConversationListItemContextMenu.tsx index 5d37c90f4..7704286a5 100644 --- a/ts/components/menu/ConversationListItemContextMenu.tsx +++ b/ts/components/menu/ConversationListItemContextMenu.tsx @@ -1,7 +1,13 @@ -import React from 'react'; -import { animation, Menu } from 'react-contexify'; import _ from 'lodash'; +import React from 'react'; +import { animation, Item, Menu } from 'react-contexify'; +import { useSelector } from 'react-redux'; +import { useIsPinned, useIsPrivate, useIsPrivateAndFriend } from '../../hooks/useParamSelector'; +import { getConversationController } from '../../session/conversations'; +import { getIsMessageSection } from '../../state/selectors/section'; +import { useConvoIdFromContext } from '../leftpane/conversation-list-item/ConvoIdContext'; +import { SessionContextMenuContainer } from '../SessionContextMenuContainer'; import { AcceptMsgRequestMenuItem, BanMenuItem, @@ -17,11 +23,9 @@ import { LeaveGroupMenuItem, MarkAllReadMenuItem, MarkConversationUnreadMenuItem, - PinConversationMenuItem, ShowUserDetailsMenuItem, UnbanMenuItem, } from './Menu'; -import { SessionContextMenuContainer } from '../SessionContextMenuContainer'; export type PropsContextConversationItem = { triggerId: string; @@ -33,17 +37,22 @@ const ConversationListItemContextMenu = (props: PropsContextConversationItem) => return ( + {/* Message request related actions */} + {/* Generic actions */} + {/* Read state actions */} + + {/* Nickname actions */} - + {/* Communities actions */} @@ -62,3 +71,23 @@ export const MemoConversationListItemContextMenu = React.memo( ConversationListItemContextMenu, propsAreEqual ); + +export const PinConversationMenuItem = (): JSX.Element | null => { + const conversationId = useConvoIdFromContext(); + const isMessagesSection = useSelector(getIsMessageSection); + const isPrivateAndFriend = useIsPrivateAndFriend(conversationId); + const isPrivate = useIsPrivate(conversationId); + const isPinned = useIsPinned(conversationId); + + if (isMessagesSection && (!isPrivate || (isPrivate && isPrivateAndFriend))) { + const conversation = getConversationController().get(conversationId); + + const togglePinConversation = async () => { + await conversation?.togglePinned(); + }; + + const menuText = isPinned ? window.i18n('unpinConversation') : window.i18n('pinConversation'); + return {menuText}; + } + return null; +}; diff --git a/ts/components/menu/Menu.tsx b/ts/components/menu/Menu.tsx index 6512a6828..384a2549f 100644 --- a/ts/components/menu/Menu.tsx +++ b/ts/components/menu/Menu.tsx @@ -1,4 +1,4 @@ -import React, { useContext } from 'react'; +import React from 'react'; import { Item } from 'react-contexify'; import { useDispatch, useSelector } from 'react-redux'; @@ -12,7 +12,6 @@ import { useIsKickedFromGroup, useIsLeft, useIsMe, - useIsPinned, useIsPrivate, useIsPrivateAndFriend, useIsPublic, @@ -47,7 +46,7 @@ import { useSelectedIsPrivateFriend, } from '../../state/selectors/selectedConversation'; import { SessionButtonColor } from '../basic/SessionButton'; -import { ContextConversationId } from '../leftpane/conversation-list-item/ConversationListItem'; +import { useConvoIdFromContext } from '../leftpane/conversation-list-item/ConvoIdContext'; function showDeleteContact( isGroup: boolean, @@ -84,7 +83,7 @@ function showInviteContact(isPublic: boolean): boolean { /** Menu items standardized */ export const InviteContactMenuItem = (): JSX.Element | null => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isPublic = useIsPublic(convoId); if (showInviteContact(isPublic)) { @@ -101,31 +100,13 @@ export const InviteContactMenuItem = (): JSX.Element | null => { return null; }; -export const PinConversationMenuItem = (): JSX.Element | null => { - const conversationId = useContext(ContextConversationId); - const isMessagesSection = useSelector(getIsMessageSection); - const isRequest = useIsIncomingRequest(conversationId); - const isPinned = useIsPinned(conversationId); - - if (isMessagesSection && !isRequest) { - const conversation = getConversationController().get(conversationId); - - const togglePinConversation = async () => { - await conversation?.togglePinned(); - }; - - const menuText = isPinned ? window.i18n('unpinConversation') : window.i18n('pinConversation'); - return {menuText}; - } - return null; -}; - export const MarkConversationUnreadMenuItem = (): JSX.Element | null => { - const conversationId = useContext(ContextConversationId); + const conversationId = useConvoIdFromContext(); const isMessagesSection = useSelector(getIsMessageSection); - const isRequest = useIsIncomingRequest(conversationId); + const isPrivate = useIsPrivate(conversationId); + const isPrivateAndFriend = useIsPrivateAndFriend(conversationId); - if (isMessagesSection && !isRequest) { + if (isMessagesSection && (!isPrivate || (isPrivate && isPrivateAndFriend))) { const conversation = getConversationController().get(conversationId); const markUnread = async () => { @@ -139,7 +120,7 @@ export const MarkConversationUnreadMenuItem = (): JSX.Element | null => { export const DeleteContactMenuItem = () => { const dispatch = useDispatch(); - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isPublic = useIsPublic(convoId); const isLeft = useIsLeft(convoId); const isKickedFromGroup = useIsKickedFromGroup(convoId); @@ -182,7 +163,7 @@ export const DeleteContactMenuItem = () => { }; export const LeaveGroupMenuItem = () => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isPublic = useIsPublic(convoId); const isLeft = useIsLeft(convoId); const isKickedFromGroup = useIsKickedFromGroup(convoId); @@ -205,7 +186,7 @@ export const LeaveGroupMenuItem = () => { export const ShowUserDetailsMenuItem = () => { const dispatch = useDispatch(); - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isPrivate = useIsPrivate(convoId); const avatarPath = useAvatarPath(convoId); const userName = useConversationUsername(convoId) || convoId; @@ -233,7 +214,7 @@ export const ShowUserDetailsMenuItem = () => { }; export const UpdateGroupNameMenuItem = () => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const left = useIsLeft(convoId); const isKickedFromGroup = useIsKickedFromGroup(convoId); const weAreAdmin = useWeAreAdmin(convoId); @@ -253,7 +234,7 @@ export const UpdateGroupNameMenuItem = () => { }; export const RemoveModeratorsMenuItem = (): JSX.Element | null => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isPublic = useIsPublic(convoId); const isKickedFromGroup = useIsKickedFromGroup(convoId); const weAreAdmin = useWeAreAdmin(convoId); @@ -273,7 +254,7 @@ export const RemoveModeratorsMenuItem = (): JSX.Element | null => { }; export const AddModeratorsMenuItem = (): JSX.Element | null => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isPublic = useIsPublic(convoId); const isKickedFromGroup = useIsKickedFromGroup(convoId); const weAreAdmin = useWeAreAdmin(convoId); @@ -293,7 +274,7 @@ export const AddModeratorsMenuItem = (): JSX.Element | null => { }; export const UnbanMenuItem = (): JSX.Element | null => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isPublic = useIsPublic(convoId); const isKickedFromGroup = useIsKickedFromGroup(convoId); const weAreAdmin = useWeAreAdmin(convoId); @@ -313,7 +294,7 @@ export const UnbanMenuItem = (): JSX.Element | null => { }; export const BanMenuItem = (): JSX.Element | null => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isPublic = useIsPublic(convoId); const isKickedFromGroup = useIsKickedFromGroup(convoId); const weAreAdmin = useWeAreAdmin(convoId); @@ -333,7 +314,7 @@ export const BanMenuItem = (): JSX.Element | null => { }; export const CopyMenuItem = (): JSX.Element | null => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isPublic = useIsPublic(convoId); const isPrivate = useIsPrivate(convoId); const isBlinded = useIsBlinded(convoId); @@ -356,7 +337,7 @@ export const CopyMenuItem = (): JSX.Element | null => { }; export const MarkAllReadMenuItem = (): JSX.Element | null => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isIncomingRequest = useIsIncomingRequest(convoId); if (!isIncomingRequest) { return ( @@ -374,7 +355,7 @@ export function isRtlBody(): boolean { } export const BlockMenuItem = (): JSX.Element | null => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isMe = useIsMe(convoId); const isBlocked = useIsBlocked(convoId); const isPrivate = useIsPrivate(convoId); @@ -391,7 +372,7 @@ export const BlockMenuItem = (): JSX.Element | null => { }; export const ClearNicknameMenuItem = (): JSX.Element | null => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isMe = useIsMe(convoId); const hasNickname = useHasNickname(convoId); const isPrivate = useIsPrivate(convoId); @@ -407,7 +388,7 @@ export const ClearNicknameMenuItem = (): JSX.Element | null => { }; export const ChangeNicknameMenuItem = () => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isMe = useIsMe(convoId); const isPrivate = useIsPrivate(convoId); const isPrivateAndFriend = useSelectedIsPrivateFriend(); @@ -428,7 +409,7 @@ export const ChangeNicknameMenuItem = () => { }; export const DeleteMessagesMenuItem = () => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); if (!convoId) { return null; @@ -446,7 +427,7 @@ export const DeleteMessagesMenuItem = () => { }; export const AcceptMsgRequestMenuItem = () => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isRequest = useIsIncomingRequest(convoId); const convo = getConversationController().get(convoId); const isPrivate = useIsPrivate(convoId); @@ -468,7 +449,7 @@ export const AcceptMsgRequestMenuItem = () => { }; export const DeclineMsgRequestMenuItem = () => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isRequest = useIsIncomingRequest(convoId); const isPrivate = useIsPrivate(convoId); const selected = useSelectedConversationKey(); @@ -493,7 +474,7 @@ export const DeclineMsgRequestMenuItem = () => { }; export const DeclineAndBlockMsgRequestMenuItem = () => { - const convoId = useContext(ContextConversationId); + const convoId = useConvoIdFromContext(); const isRequest = useIsIncomingRequest(convoId); const selected = useSelectedConversationKey(); const isPrivate = useIsPrivate(convoId); diff --git a/ts/components/settings/BlockedList.tsx b/ts/components/settings/BlockedList.tsx index b9083d7ca..93179c37c 100644 --- a/ts/components/settings/BlockedList.tsx +++ b/ts/components/settings/BlockedList.tsx @@ -32,7 +32,7 @@ const BlockedEntriesRoundedContainer = styled.div` const BlockedContactsSection = styled.div` display: flex; flex-direction: column; - min-height: 0; + min-height: 80px; background: var(--settings-tab-background-color); color: var(--settings-tab-text-color); diff --git a/ts/interactions/conversationInteractions.ts b/ts/interactions/conversationInteractions.ts index 32a3e90cc..0b840c08f 100644 --- a/ts/interactions/conversationInteractions.ts +++ b/ts/interactions/conversationInteractions.ts @@ -134,14 +134,12 @@ export async function declineConversationWithoutConfirm({ }) { const conversationToDecline = getConversationController().get(conversationId); - if (!conversationToDecline || conversationToDecline.isApproved()) { + if (!conversationToDecline || !conversationToDecline.isApproved()) { window?.log?.info('Conversation is already declined.'); return; } - // we mark the conversation as inactive. This way it wont' show up in the UI. - // we cannot delete it completely on desktop, because we might need the convo details for sogs/group convos. - conversationToDecline.set('active_at', undefined); + // Note: do not set the active_at undefined as this would make that conversation not synced with the libsession wrapper await conversationToDecline.setIsApproved(false, false); await conversationToDecline.setDidApproveMe(false, false); // this will update the value in the wrapper if needed but not remove the entry if we want it gone. The remove is done below with removeContactFromWrapper @@ -154,7 +152,7 @@ export async function declineConversationWithoutConfirm({ if ( conversationToDecline.isPrivate() && - !SessionUtilContact.isContactToStoreInContactsWrapper(conversationToDecline) + !SessionUtilContact.isContactToStoreInWrapper(conversationToDecline) ) { await SessionUtilContact.removeContactFromWrapper(conversationToDecline.id); } diff --git a/ts/models/conversation.ts b/ts/models/conversation.ts index 372321c50..584d2d68b 100644 --- a/ts/models/conversation.ts +++ b/ts/models/conversation.ts @@ -2256,12 +2256,12 @@ export async function commitConversationAndRefreshWrapper(id: string) { switch (variant) { case 'UserConfig': - if (SessionUtilUserProfile.isUserProfileToStoreInContactsWrapper(convo.id)) { + if (SessionUtilUserProfile.isUserProfileToStoreInWrapper(convo.id)) { await SessionUtilUserProfile.insertUserProfileIntoWrapper(convo.id); } break; case 'ContactsConfig': - if (SessionUtilContact.isContactToStoreInContactsWrapper(convo)) { + if (SessionUtilContact.isContactToStoreInWrapper(convo)) { await SessionUtilContact.insertContactFromDBIntoWrapperAndRefresh(convo.id); } break; diff --git a/ts/node/migration/sessionMigrations.ts b/ts/node/migration/sessionMigrations.ts index 8c2c30a3e..701f4c2bf 100644 --- a/ts/node/migration/sessionMigrations.ts +++ b/ts/node/migration/sessionMigrations.ts @@ -1610,7 +1610,7 @@ function updateToSessionSchemaVersion30(currentVersion: number, db: BetterSqlite * Setup up the Contacts Wrapper with all the contact details which needs to be stored in it. */ - // this filter is based on the `isContactToStoreInContactsWrapper` function. Note, blocked contacts won't be added to the wrapper at first, but will on the first start + // this filter is based on the `isContactToStoreInWrapper` function. Note, blocked contacts won't be added to the wrapper at first, but will on the first start const contactsToWriteInWrapper = db .prepare( `SELECT * FROM ${CONVERSATIONS_TABLE} WHERE type = 'private' AND active_at > 0 AND NOT hidden AND (didApproveMe OR isApproved) AND id <> '$us' AND id NOT LIKE '15%' ;` diff --git a/ts/receiver/configMessage.ts b/ts/receiver/configMessage.ts index 1f739ea2f..f57ffefe6 100644 --- a/ts/receiver/configMessage.ts +++ b/ts/receiver/configMessage.ts @@ -142,7 +142,6 @@ async function handleContactsUpdate(result: IncomingConfResult): Promise(); async function insertAllContactsIntoContactsWrapper() { const idsToInsert = getConversationController() .getConversations() - .filter(isContactToStoreInContactsWrapper) + .filter(isContactToStoreInWrapper) .map(m => m.id); window.log.debug(`ContactsWrapper keep tracks of ${idsToInsert.length} contacts: ${idsToInsert}`); @@ -44,17 +44,13 @@ async function insertAllContactsIntoContactsWrapper() { } /** - * Returns true if that conversation is not us, is private, is not blinded and has either the - * `isApproved` or `didApproveMe` field set. - * So that would be all the private conversations we either sent or receive a message from, not blinded + * Returns true if that conversation is not us, is private, is not blinded. + * + * We want to sync the message request status so we need to allow a contact even if it's not approved, did not approve us and is not blocked. */ -function isContactToStoreInContactsWrapper(convo: ConversationModel): boolean { +function isContactToStoreInWrapper(convo: ConversationModel): boolean { return ( - !convo.isMe() && - convo.isPrivate() && - convo.isActive() && - !PubKey.hasBlindedPrefix(convo.id) && - (convo.isApproved() || convo.didApproveMe() || convo.isBlocked()) + !convo.isMe() && convo.isPrivate() && convo.isActive() && !PubKey.hasBlindedPrefix(convo.id) ); } // TODOLATER should we allow a blinded pubkey to be in the contact wrapper when we blocked it (can we block a blinded message request?) @@ -70,8 +66,10 @@ async function insertContactFromDBIntoWrapperAndRefresh(id: string): Promise