From cbffc299507be57adaebca4c81e330da406dc974 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Fri, 21 Apr 2023 15:17:24 +1000 Subject: [PATCH] fix: run tests for libsession-util integration and fix issue --- ts/components/leftpane/LeftPane.tsx | 7 +-- .../leftpane/LeftPaneMessageSection.tsx | 3 -- .../leftpane/MessageRequestsBanner.tsx | 6 ++- .../overlay/SessionJoinableDefaultRooms.tsx | 2 +- ts/components/menu/Menu.tsx | 12 ++--- ts/interactions/conversationInteractions.ts | 6 +-- ts/interactions/messageInteractions.ts | 4 +- ts/models/conversation.ts | 5 -- ts/node/migration/sessionMigrations.ts | 24 ++++++--- ts/receiver/configMessage.ts | 52 +++++++++++++------ ts/receiver/contentMessage.ts | 4 +- ts/receiver/opengroup.ts | 4 +- ts/receiver/queuedJob.ts | 15 ++++++ .../conversations/ConversationController.ts | 32 +++++++----- ts/session/profile_manager/ProfileManager.ts | 9 +++- .../jobs/ConfigurationSyncDumpJob.ts | 4 +- .../job_runners/jobs/ConfigurationSyncJob.ts | 5 +- .../utils/libsession/libsession_utils.ts | 4 +- .../libsession_utils_convo_info_volatile.ts | 4 +- .../libsession_utils_user_groups.ts | 31 +++++++++-- .../libsession_utils_user_profile.ts | 16 ++++-- ts/state/selectors/conversations.ts | 5 ++ ts/util/reactions.ts | 6 +-- .../browser/libsession_worker_interface.ts | 20 +++---- 24 files changed, 181 insertions(+), 99 deletions(-) diff --git a/ts/components/leftpane/LeftPane.tsx b/ts/components/leftpane/LeftPane.tsx index 26aa9a9ee..ff2c91347 100644 --- a/ts/components/leftpane/LeftPane.tsx +++ b/ts/components/leftpane/LeftPane.tsx @@ -3,16 +3,15 @@ import React from 'react'; import { useSelector } from 'react-redux'; import styled from 'styled-components'; import { SectionType } from '../../state/ducks/section'; -import { SessionTheme } from '../../themes/SessionTheme'; import { getLeftPaneLists } from '../../state/selectors/conversations'; import { getSearchResults, isSearching } from '../../state/selectors/search'; import { getFocusedSection, getOverlayMode } from '../../state/selectors/section'; -import { getHideMessageRequestBanner } from '../../state/selectors/userConfig'; +import { SessionTheme } from '../../themes/SessionTheme'; +import { SessionToastContainer } from '../SessionToastContainer'; import { CallInFullScreenContainer } from '../calling/CallInFullScreenContainer'; import { DraggableCallContainer } from '../calling/DraggableCallContainer'; import { IncomingCallDialog } from '../calling/IncomingCallDialog'; import { ModalContainer } from '../dialog/ModalContainer'; -import { SessionToastContainer } from '../SessionToastContainer'; import { ActionsPanel } from './ActionsPanel'; import { LeftPaneMessageSection } from './LeftPaneMessageSection'; import { LeftPaneSettingSection } from './LeftPaneSettingSection'; @@ -28,7 +27,6 @@ const InnerLeftPaneMessageSection = () => { const searchResults = showSearch ? useSelector(getSearchResults) : undefined; const lists = showSearch ? undefined : useSelector(getLeftPaneLists); - const messageRequestsEnabled = useSelector(getHideMessageRequestBanner); const overlayMode = useSelector(getOverlayMode); return ( @@ -37,7 +35,6 @@ const InnerLeftPaneMessageSection = () => { conversations={lists?.conversations || []} contacts={lists?.contacts || []} searchResults={searchResults} - messageRequestsEnabled={messageRequestsEnabled} overlayMode={overlayMode} /> ); diff --git a/ts/components/leftpane/LeftPaneMessageSection.tsx b/ts/components/leftpane/LeftPaneMessageSection.tsx index 1d0ac4e49..e439957ac 100644 --- a/ts/components/leftpane/LeftPaneMessageSection.tsx +++ b/ts/components/leftpane/LeftPaneMessageSection.tsx @@ -27,8 +27,6 @@ export interface Props { contacts: Array; conversations?: Array; searchResults?: SearchResultsProps; - - messageRequestsEnabled?: boolean; overlayMode: OverlayMode | undefined; } @@ -70,7 +68,6 @@ const ClosableOverlay = () => { export class LeftPaneMessageSection extends React.Component { public constructor(props: Props) { super(props); - autoBind(this); } diff --git a/ts/components/leftpane/MessageRequestsBanner.tsx b/ts/components/leftpane/MessageRequestsBanner.tsx index ece893518..8f06088d3 100644 --- a/ts/components/leftpane/MessageRequestsBanner.tsx +++ b/ts/components/leftpane/MessageRequestsBanner.tsx @@ -7,6 +7,7 @@ import { getUnreadConversationRequests } from '../../state/selectors/conversatio import { getHideMessageRequestBanner } from '../../state/selectors/userConfig'; import { SessionIcon, SessionIconSize, SessionIconType } from '../icon'; import { MessageRequestBannerContextMenu } from '../menu/MessageRequestBannerContextMenu'; +import { isSearching } from '../../state/selectors/search'; const StyledMessageRequestBanner = styled.div` height: 64px; @@ -87,7 +88,10 @@ export const MessageRequestsBanner = (props: { handleOnClick: () => any }) => { const conversationRequestsUnread = useSelector(getUnreadConversationRequests).length; const hideRequestBanner = useSelector(getHideMessageRequestBanner); - if (!conversationRequestsUnread || hideRequestBanner) { + // when searching hide the message request banner + const isCurrentlySearching = useSelector(isSearching); + + if (!conversationRequestsUnread || hideRequestBanner || isCurrentlySearching) { return null; } diff --git a/ts/components/leftpane/overlay/SessionJoinableDefaultRooms.tsx b/ts/components/leftpane/overlay/SessionJoinableDefaultRooms.tsx index 4c782bad1..cae773e81 100644 --- a/ts/components/leftpane/overlay/SessionJoinableDefaultRooms.tsx +++ b/ts/components/leftpane/overlay/SessionJoinableDefaultRooms.tsx @@ -61,7 +61,7 @@ const SessionJoinableRoomAvatar = (props: JoinableRoomProps) => { }); } } catch (e) { - window?.log?.warn(e); + window?.log?.warn(e.message); } return () => { isCancelled = true; diff --git a/ts/components/menu/Menu.tsx b/ts/components/menu/Menu.tsx index 384a2549f..813047bd9 100644 --- a/ts/components/menu/Menu.tsx +++ b/ts/components/menu/Menu.tsx @@ -41,12 +41,10 @@ import { updateUserDetailsModal, } from '../../state/ducks/modalDialog'; import { getIsMessageSection } from '../../state/selectors/section'; -import { - useSelectedConversationKey, - useSelectedIsPrivateFriend, -} from '../../state/selectors/selectedConversation'; +import { useSelectedConversationKey } from '../../state/selectors/selectedConversation'; import { SessionButtonColor } from '../basic/SessionButton'; import { useConvoIdFromContext } from '../leftpane/conversation-list-item/ConvoIdContext'; +import { PubKey } from '../../session/types'; function showDeleteContact( isGroup: boolean, @@ -339,7 +337,7 @@ export const CopyMenuItem = (): JSX.Element | null => { export const MarkAllReadMenuItem = (): JSX.Element | null => { const convoId = useConvoIdFromContext(); const isIncomingRequest = useIsIncomingRequest(convoId); - if (!isIncomingRequest) { + if (!isIncomingRequest && !PubKey.hasBlindedPrefix(convoId)) { return ( markAllReadByConvoId(convoId)}>{window.i18n('markAllAsRead')} ); @@ -361,7 +359,7 @@ export const BlockMenuItem = (): JSX.Element | null => { const isPrivate = useIsPrivate(convoId); const isIncomingRequest = useIsIncomingRequest(convoId); - if (!isMe && isPrivate && !isIncomingRequest) { + if (!isMe && isPrivate && !isIncomingRequest && !PubKey.hasBlindedPrefix(convoId)) { const blockTitle = isBlocked ? window.i18n('unblock') : window.i18n('block'); const blockHandler = isBlocked ? () => unblockConvoById(convoId) @@ -391,7 +389,7 @@ export const ChangeNicknameMenuItem = () => { const convoId = useConvoIdFromContext(); const isMe = useIsMe(convoId); const isPrivate = useIsPrivate(convoId); - const isPrivateAndFriend = useSelectedIsPrivateFriend(); + const isPrivateAndFriend = useIsPrivateAndFriend(convoId); const dispatch = useDispatch(); if (isMe || !isPrivate || !isPrivateAndFriend) { diff --git a/ts/interactions/conversationInteractions.ts b/ts/interactions/conversationInteractions.ts index 0b840c08f..cc0353f8a 100644 --- a/ts/interactions/conversationInteractions.ts +++ b/ts/interactions/conversationInteractions.ts @@ -105,7 +105,7 @@ export const approveConvoAndSendResponse = async ( ) => { const convoToApprove = getConversationController().get(conversationId); - if (!convoToApprove || convoToApprove.isApproved()) { + if (!convoToApprove) { window?.log?.info('Conversation is already approved.'); return; } @@ -134,8 +134,8 @@ export async function declineConversationWithoutConfirm({ }) { const conversationToDecline = getConversationController().get(conversationId); - if (!conversationToDecline || !conversationToDecline.isApproved()) { - window?.log?.info('Conversation is already declined.'); + if (!conversationToDecline || !conversationToDecline.isPrivate()) { + window?.log?.info('No conversation to decline.'); return; } diff --git a/ts/interactions/messageInteractions.ts b/ts/interactions/messageInteractions.ts index 76cfccec9..0b05c9fb9 100644 --- a/ts/interactions/messageInteractions.ts +++ b/ts/interactions/messageInteractions.ts @@ -19,7 +19,7 @@ export function banUser(userToBan: string, conversationId: string) { try { pubKeyToBan = PubKey.cast(userToBan); } catch (e) { - window?.log?.warn(e); + window?.log?.warn(e.message); ToastUtils.pushUserBanFailure(); return; } @@ -44,7 +44,7 @@ export function unbanUser(userToUnBan: string, conversationId: string) { try { pubKeyToUnban = PubKey.cast(userToUnBan); } catch (e) { - window?.log?.warn(e); + window?.log?.warn(e.message); ToastUtils.pushUserBanFailure(); return; } diff --git a/ts/models/conversation.ts b/ts/models/conversation.ts index 5f2587d6d..7c9a6a83c 100644 --- a/ts/models/conversation.ts +++ b/ts/models/conversation.ts @@ -982,11 +982,6 @@ export class ConversationModel extends Backbone.Model { } } - // TODOLATER we should maybe mark things here as read, but we need a readAt timestamp, and I am not too sure what we should use (considering that disappearing messages needs a real readAt) - // const sentAt = messageAttributes.sent_at || messageAttributes.serverTimestamp; - // if (sentAt) { - // await this.markConversationRead(sentAt); - // } return this.addSingleMessage({ ...messageAttributes, conversationId: this.id, diff --git a/ts/node/migration/sessionMigrations.ts b/ts/node/migration/sessionMigrations.ts index ebd0bada4..05f45bc6d 100644 --- a/ts/node/migration/sessionMigrations.ts +++ b/ts/node/migration/sessionMigrations.ts @@ -1,11 +1,11 @@ import * as BetterSqlite3 from 'better-sqlite3'; -import { compact, isArray, isEmpty, isNumber, isString, map, pick } from 'lodash'; import { ContactsConfigWrapperInsideWorker, ConvoInfoVolatileWrapperInsideWorker, UserConfigWrapperInsideWorker, UserGroupsWrapperInsideWorker, } from 'libsession_util_nodejs'; +import { compact, isArray, isEmpty, isNumber, isString, map, pick } from 'lodash'; import { CONVERSATION_PRIORITIES, ConversationAttributes, @@ -21,13 +21,13 @@ import { import { CLOSED_GROUP_V2_KEY_PAIRS_TABLE, CONVERSATIONS_TABLE, - dropFtsAndTriggers, GUARD_NODE_TABLE, LAST_HASHES_TABLE, MESSAGES_TABLE, NODES_FOR_PUBKEY_TABLE, - objectToJSON, OPEN_GROUP_ROOMS_V2_TABLE, + dropFtsAndTriggers, + objectToJSON, rebuildFtsTable, toSqliteBoolean, } from '../database_utility'; @@ -1572,13 +1572,23 @@ function updateToSessionSchemaVersion30(currentVersion: number, db: BetterSqlite const ourDbName = ourConversation.displayNameInProfile || ''; const ourDbProfileUrl = ourConversation.avatarPointer || ''; const ourDbProfileKey = fromHexToArray(ourConversation.profileKey || ''); - userProfileWrapper.setName(ourDbName); - + const ourConvoPriority = ourConversation.priority; if (ourDbProfileUrl && !isEmpty(ourDbProfileKey)) { - userProfileWrapper.setProfilePicture(ourDbProfileUrl, ourDbProfileKey); + userProfileWrapper.setUserInfo( + ourDbName, + ourConvoPriority, + ourDbProfileUrl || '', + ourDbProfileKey + ); } else { - userProfileWrapper.setProfilePicture('', new Uint8Array()); + userProfileWrapper.setUserInfo( + ourDbName, + ourConvoPriority, // consider that the Note to self is hidden on a fresh account (without avatar set) + '', + new Uint8Array() + ); } + insertContactIntoContactWrapper( ourConversation, blockedNumbers, diff --git a/ts/receiver/configMessage.ts b/ts/receiver/configMessage.ts index c1eeaee60..ed2e49212 100644 --- a/ts/receiver/configMessage.ts +++ b/ts/receiver/configMessage.ts @@ -1,4 +1,4 @@ -import _, { compact, isEmpty, toNumber } from 'lodash'; +import { compact, isEmpty, toNumber } from 'lodash'; import { ConfigDumpData } from '../data/configDump/configDump'; import { Data, hasSyncedInitialConfigurationItem } from '../data/data'; import { ConversationInteraction } from '../interactions'; @@ -12,15 +12,17 @@ import { import { getOpenGroupManager } from '../session/apis/open_group_api/opengroupV2/OpenGroupManagerV2'; import { OpenGroupUtils } from '../session/apis/open_group_api/utils'; import { getOpenGroupV2ConversationId } from '../session/apis/open_group_api/utils/OpenGroupUtils'; +import { getSwarmPollingInstance } from '../session/apis/snode_api'; import { getConversationController } from '../session/conversations'; import { IncomingMessage } from '../session/messages/incoming/IncomingMessage'; import { ProfileManager } from '../session/profile_manager/ProfileManager'; +import { PubKey } from '../session/types'; import { UserUtils } from '../session/utils'; +import { toHex } from '../session/utils/String'; import { ConfigurationSync } from '../session/utils/job_runners/jobs/ConfigurationSyncJob'; import { IncomingConfResult, LibSessionUtil } from '../session/utils/libsession/libsession_utils'; import { SessionUtilConvoInfoVolatile } from '../session/utils/libsession/libsession_utils_convo_info_volatile'; import { SessionUtilUserGroups } from '../session/utils/libsession/libsession_utils_user_groups'; -import { toHex } from '../session/utils/String'; import { configurationMessageReceived, trigger } from '../shims/events'; import { assertUnreachable } from '../types/sqlSharedTypes'; import { BlockedNumberController } from '../util'; @@ -37,6 +39,7 @@ import { import { removeFromCache } from './cache'; import { addKeyPairToCacheAndDBIfNeeded, handleNewClosedGroup } from './closedGroups'; import { HexKeyPair } from './keypairs'; +import { queueAllCachedFromSource } from './receiver'; import { EnvelopePlus } from './types'; function groupByVariant( @@ -89,7 +92,7 @@ async function mergeConfigsWithIncomingUpdates( const needsDump = await GenericWrapperActions.needsDump(variant); const latestEnvelopeTimestamp = Math.max(...sameVariant.map(m => m.envelopeTimestamp)); - window.log.info(`${variant}: "${publicKey}" needsPush:${needsPush} needsDump:${needsDump} `); + window.log.debug(`${variant}: "${publicKey}" needsPush:${needsPush} needsDump:${needsDump} `); const incomingConfResult: IncomingConfResult = { needsDump, @@ -109,20 +112,23 @@ async function mergeConfigsWithIncomingUpdates( } async function handleUserProfileUpdate(result: IncomingConfResult): Promise { - const updatedUserName = await UserConfigWrapperActions.getName(); if (!result.needsDump) { return result; } - - const updatedProfilePicture = await UserConfigWrapperActions.getProfilePicture(); - const picUpdate = !isEmpty(updatedProfilePicture.key) && !isEmpty(updatedProfilePicture.url); + const updateUserInfo = await UserConfigWrapperActions.getUserInfo(); + if (!updateUserInfo) { + return result; + } + const picUpdate = !isEmpty(updateUserInfo.key) && !isEmpty(updateUserInfo.url); await updateOurProfileLegacyOrViaLibSession( result.latestEnvelopeTimestamp, - updatedUserName, - picUpdate ? updatedProfilePicture.url : null, - picUpdate ? updatedProfilePicture.key : null + updateUserInfo.name, + picUpdate ? updateUserInfo.url : null, + picUpdate ? updateUserInfo.key : null, + updateUserInfo.priority ); + return result; } @@ -205,11 +211,16 @@ async function handleCommunitiesUpdate() { // first let's check which communities needs to be joined or left by doing a diff of what is in the wrapper and what is in the DB const allCommunitiesInWrapper = await UserGroupsWrapperActions.getAllCommunities(); + window.log.debug( + 'allCommunitiesInWrapper', + allCommunitiesInWrapper.map(m => m.fullUrl) + ); const allCommunitiesConversation = getConversationController() .getConversations() .filter(SessionUtilUserGroups.isCommunityToStoreInWrapper); const allCommunitiesIdsInDB = allCommunitiesConversation.map(m => m.id as string); + window.log.debug('allCommunitiesIdsInDB', allCommunitiesIdsInDB); const communitiesIdsInWrapper = compact( allCommunitiesInWrapper.map(m => { @@ -291,7 +302,7 @@ async function handleLegacyGroupUpdate(latestEnvelopeTimestamp: number) { const allLegacyGroupsInWrapper = await UserGroupsWrapperActions.getAllLegacyGroups(); const allLegacyGroupsInDb = getConversationController() .getConversations() - .filter(SessionUtilUserGroups.isLegacyGroupToStoreInWrapper); + .filter(SessionUtilUserGroups.isLegacyGroupToRemoveFromDBIfNotInWrapper); const allLegacyGroupsIdsInDB = allLegacyGroupsInDb.map(m => m.id as string); const allLegacyGroupsIdsInWrapper = allLegacyGroupsInWrapper.map(m => m.pubkeyHex); @@ -300,6 +311,9 @@ async function handleLegacyGroupUpdate(latestEnvelopeTimestamp: number) { return !allLegacyGroupsIdsInDB.includes(m.pubkeyHex); }); + window.log.debug(`allLegacyGroupsInWrapper: ${allLegacyGroupsInWrapper.map(m => m.pubkeyHex)} `); + window.log.debug(`allLegacyGroupsIdsInDB: ${allLegacyGroupsIdsInDB} `); + const legacyGroupsToLeaveInDB = allLegacyGroupsInDb.filter(m => { return !allLegacyGroupsIdsInWrapper.includes(m.id); }); @@ -385,6 +399,11 @@ async function handleLegacyGroupUpdate(latestEnvelopeTimestamp: number) { ); changes = true; } + // start polling for this new group + getSwarmPollingInstance().addGroupId(PubKey.cast(fromWrapper.pubkeyHex)); + + // trigger decrypting of all this group messages we did not decrypt successfully yet. + await queueAllCachedFromSource(fromWrapper.pubkeyHex); if (changes) { await legacyGroupConvo.commit(); @@ -578,6 +597,7 @@ async function processMergingResults(results: Map { - const isMe = UserUtils.isUsFromCache(sender); + const isMe = isUsAnySogsFromCache(sender); // this timestamp has already been forced to ms by the handleMessagesResponseV4() function const commonAttributes = { serverTimestamp: sentTimestamp, serverId, conversationId }; diff --git a/ts/receiver/queuedJob.ts b/ts/receiver/queuedJob.ts index 1eb9db419..807a63a79 100644 --- a/ts/receiver/queuedJob.ts +++ b/ts/receiver/queuedJob.ts @@ -311,6 +311,20 @@ async function handleExpirationTimerUpdateNoCommit( await conversation.updateExpireTimer(expireTimer, source, message.get('received_at'), {}, false); } +async function markConvoAsReadIfOutgoingMessage( + conversation: ConversationModel, + message: MessageModel +) { + const isOutgoingMessage = + message.get('type') === 'outgoing' || message.get('direction') === 'outgoing'; + if (isOutgoingMessage) { + const sentAt = message.get('sent_at') || message.get('serverTimestamp'); + if (sentAt) { + conversation.markConversationRead(sentAt); + } + } +} + export async function handleMessageJob( messageModel: MessageModel, conversation: ConversationModel, @@ -386,6 +400,7 @@ export async function handleMessageJob( ); } + await markConvoAsReadIfOutgoingMessage(conversation, messageModel); if (messageModel.get('unread')) { conversation.throttledNotify(messageModel); } diff --git a/ts/session/conversations/ConversationController.ts b/ts/session/conversations/ConversationController.ts index 860fac017..83238ad60 100644 --- a/ts/session/conversations/ConversationController.ts +++ b/ts/session/conversations/ConversationController.ts @@ -7,17 +7,18 @@ import { getOpenGroupManager } from '../apis/open_group_api/opengroupV2/OpenGrou import { getSwarmFor } from '../apis/snode_api/snodePool'; import { PubKey } from '../types'; +import { ConvoVolatileType } from 'libsession_util_nodejs'; import { deleteAllMessagesByConvoIdNoConfirmation } from '../../interactions/conversationInteractions'; import { CONVERSATION_PRIORITIES, ConversationTypeEnum } from '../../models/conversationAttributes'; +import { assertUnreachable } from '../../types/sqlSharedTypes'; +import { UserGroupsWrapperActions } from '../../webworker/workers/browser/libsession_worker_interface'; import { leaveClosedGroup } from '../group/closed-group'; +import { ConfigurationDumpSync } from '../utils/job_runners/jobs/ConfigurationSyncDumpJob'; import { ConfigurationSync } from '../utils/job_runners/jobs/ConfigurationSyncJob'; +import { LibSessionUtil } from '../utils/libsession/libsession_utils'; import { SessionUtilContact } from '../utils/libsession/libsession_utils_contacts'; import { SessionUtilConvoInfoVolatile } from '../utils/libsession/libsession_utils_convo_info_volatile'; import { SessionUtilUserGroups } from '../utils/libsession/libsession_utils_user_groups'; -import { ConfigurationDumpSync } from '../utils/job_runners/jobs/ConfigurationSyncDumpJob'; -import { LibSessionUtil } from '../utils/libsession/libsession_utils'; -import { assertUnreachable } from '../../types/sqlSharedTypes'; -import { ConvoVolatileType } from 'libsession_util_nodejs'; let instance: ConversationController | null; @@ -235,6 +236,18 @@ export class ConversationController { break; case 'Community': window?.log?.info('leaving open group v2', conversation.id); + + try { + const fromWrapper = await UserGroupsWrapperActions.getCommunityByFullUrl(conversation.id); + + await SessionUtilConvoInfoVolatile.removeCommunityFromWrapper( + conversation.id, + fromWrapper?.fullUrl || '' + ); + } catch (e) { + window?.log?.info('SessionUtilConvoInfoVolatile.removeCommunityFromWrapper failed:', e); + } + // remove from the wrapper the entries before we remove the roomInfos, as we won't have the required community pubkey afterwards try { await SessionUtilUserGroups.removeCommunityFromWrapper(conversation.id, conversation.id); @@ -242,15 +255,6 @@ export class ConversationController { window?.log?.info('SessionUtilUserGroups.removeCommunityFromWrapper failed:', e); } - try { - await SessionUtilConvoInfoVolatile.removeCommunityFromWrapper( - conversation.id, - conversation.id - ); - } catch (e) { - window?.log?.info('SessionUtilConvoInfoVolatile.removeCommunityFromWrapper failed:', e); - } - const roomInfos = OpenGroupData.getV2OpenGroupRoom(conversation.id); if (roomInfos) { getOpenGroupManager().removeRoomFromPolledRooms(roomInfos); @@ -264,7 +268,7 @@ export class ConversationController { } break; case 'LegacyGroup': - window.log.info(`deleteContact ClosedGroup case: ${id}`); + window.log.info(`deleteContact ClosedGroup case: ${conversation.id}`); await leaveClosedGroup(conversation.id); await SessionUtilUserGroups.removeLegacyGroupFromWrapper(conversation.id); await SessionUtilConvoInfoVolatile.removeLegacyGroupFromWrapper(conversation.id); diff --git a/ts/session/profile_manager/ProfileManager.ts b/ts/session/profile_manager/ProfileManager.ts index a7f2c0299..de418c279 100644 --- a/ts/session/profile_manager/ProfileManager.ts +++ b/ts/session/profile_manager/ProfileManager.ts @@ -10,7 +10,8 @@ import { toHex } from '../utils/String'; async function updateOurProfileSync( displayName: string | undefined, profileUrl: string | null, - profileKey: Uint8Array | null + profileKey: Uint8Array | null, + priority: number | null ) { const us = UserUtils.getOurPubKeyStrFromCache(); const ourConvo = getConversationController().get(us); @@ -19,7 +20,11 @@ async function updateOurProfileSync( return; } - return updateProfileOfContact(us, displayName, profileUrl, profileKey); + await updateProfileOfContact(us, displayName, profileUrl, profileKey); + if (priority !== null && ourConvo.get('priority') !== priority) { + ourConvo.set('priority', priority); + await ourConvo.commit(); + } } /** diff --git a/ts/session/utils/job_runners/jobs/ConfigurationSyncDumpJob.ts b/ts/session/utils/job_runners/jobs/ConfigurationSyncDumpJob.ts index 616ac2fa5..10bab65e2 100644 --- a/ts/session/utils/job_runners/jobs/ConfigurationSyncDumpJob.ts +++ b/ts/session/utils/job_runners/jobs/ConfigurationSyncDumpJob.ts @@ -99,7 +99,7 @@ class ConfigurationSyncDumpJob extends PersistedJob window.log.warn('did not find our own conversation'); return RunJobResult.PermanentFailure; } + for (let index = 0; index < LibSessionUtil.requiredUserVariants.length; index++) { const variant = LibSessionUtil.requiredUserVariants[index]; switch (variant) { @@ -292,9 +293,9 @@ async function queueNewJobIfNeeded() { ) { // this call will make sure that there is only one configuration sync job at all times await runners.configurationSyncRunner.addJob( - new ConfigurationSyncJob({ nextAttemptTimestamp: Date.now() }) + new ConfigurationSyncJob({ nextAttemptTimestamp: Date.now() + 1000 }) ); - window.log.debug('Scheduling ConfSyncJob: ASAP'); + window.log.debug('Scheduling ConfSyncJob: ASAP'); // we postpone by 1000ms to make sure whoever is adding this job is done with what is needs to do first } else { // if we did run at t=100, and it is currently t=110, the difference is 10 const diff = Math.max(Date.now() - lastRunConfigSyncJobTimestamp, 0); diff --git a/ts/session/utils/libsession/libsession_utils.ts b/ts/session/utils/libsession/libsession_utils.ts index f648a505b..c703f8058 100644 --- a/ts/session/utils/libsession/libsession_utils.ts +++ b/ts/session/utils/libsession/libsession_utils.ts @@ -98,17 +98,18 @@ async function pendingChangesForPubkey(pubkey: string): Promise = []; + const variantsNeedingPush = new Set(); for (let index = 0; index < dumps.length; index++) { const dump = dumps[index]; const variant = dump.variant; const needsPush = await GenericWrapperActions.needsPush(variant); - window.log.debug(`needsPush ${needsPush} for variant: ${variant}`); if (!needsPush) { continue; } + variantsNeedingPush.add(variant); const { data, seqno, hashes } = await GenericWrapperActions.push(variant); const kind = variantToKind(variant); @@ -124,6 +125,7 @@ async function pendingChangesForPubkey(pubkey: string): Promise { * Remove the matching legacy group from the wrapper and from the cached list of legacy groups */ async function removeLegacyGroupFromWrapper(groupPk: string) { - const fromWrapper = await UserGroupsWrapperActions.getLegacyGroup(groupPk); - - if (fromWrapper) { + try { await UserGroupsWrapperActions.eraseLegacyGroup(groupPk); + } catch (e) { + window.log.warn( + `UserGroupsWrapperActions.eraseLegacyGroup with = ${groupPk} failed with`, + e.message + ); } mappedLegacyGroupWrapperValues.delete(groupPk); @@ -257,6 +281,7 @@ export const SessionUtilUserGroups = { // legacy group isLegacyGroupToStoreInWrapper, + isLegacyGroupToRemoveFromDBIfNotInWrapper, getLegacyGroupCached, getAllLegacyGroups, removeLegacyGroupFromWrapper, // a group can be removed but also just marked hidden, so only call this function when the group is completely removed // TODOLATER diff --git a/ts/session/utils/libsession/libsession_utils_user_profile.ts b/ts/session/utils/libsession/libsession_utils_user_profile.ts index 1991b3ea5..ab81913d8 100644 --- a/ts/session/utils/libsession/libsession_utils_user_profile.ts +++ b/ts/session/utils/libsession/libsession_utils_user_profile.ts @@ -3,6 +3,7 @@ import { UserUtils } from '..'; import { UserConfigWrapperActions } from '../../../webworker/workers/browser/libsession_worker_interface'; import { getConversationController } from '../../conversations'; import { fromHexToArray } from '../String'; +import { CONVERSATION_PRIORITIES } from '../../../models/conversationAttributes'; async function insertUserProfileIntoWrapper(convoId: string) { if (!isUserProfileToStoreInWrapper(convoId)) { @@ -18,12 +19,21 @@ async function insertUserProfileIntoWrapper(convoId: string) { const dbName = ourConvo.get('displayNameInProfile') || ''; const dbProfileUrl = ourConvo.get('avatarPointer') || ''; const dbProfileKey = fromHexToArray(ourConvo.get('profileKey') || ''); - await UserConfigWrapperActions.setName(dbName); if (dbProfileUrl && !isEmpty(dbProfileKey)) { - await UserConfigWrapperActions.setProfilePicture(dbProfileUrl, dbProfileKey); + await UserConfigWrapperActions.setUserInfo( + dbName, + ourConvo.get('priority') || CONVERSATION_PRIORITIES.default, + dbProfileUrl, + dbProfileKey + ); } else { - await UserConfigWrapperActions.setProfilePicture('', new Uint8Array()); + await UserConfigWrapperActions.setUserInfo( + dbName, + ourConvo.get('priority') || CONVERSATION_PRIORITIES.default, + '', + new Uint8Array() + ); } } diff --git a/ts/state/selectors/conversations.ts b/ts/state/selectors/conversations.ts index ea294aef3..88396aa9b 100644 --- a/ts/state/selectors/conversations.ts +++ b/ts/state/selectors/conversations.ts @@ -288,6 +288,11 @@ const _getLeftPaneLists = ( directConversations.push(conversation); } + // a private conversation not approved is a message request. Exclude them from the left pane lists + if (conversation.isPrivate && !conversation.isApproved) { + continue; + } + const isPrivateButHidden = conversation.isPrivate && conversation.priority && diff --git a/ts/util/reactions.ts b/ts/util/reactions.ts index 06451e852..f1f40d46c 100644 --- a/ts/util/reactions.ts +++ b/ts/util/reactions.ts @@ -58,7 +58,7 @@ const getMessageByReaction = async ( } if (!originalMessage) { - window?.log?.warn(`Cannot find the original reacted message ${originalMessageId}.`); + window?.log?.debug(`Cannot find the original reacted message ${originalMessageId}.`); return null; } @@ -236,7 +236,7 @@ const handleMessageReaction = async ({ const handleClearReaction = async (conversationId: string, serverId: number, emoji: string) => { const originalMessage = await Data.getMessageByServerId(conversationId, serverId); if (!originalMessage) { - window?.log?.warn( + window?.log?.debug( `Cannot find the original reacted message ${serverId} in conversation ${conversationId}.` ); return; @@ -269,7 +269,7 @@ const handleOpenGroupMessageReactions = async ( ) => { const originalMessage = await Data.getMessageByServerId(conversationId, serverId); if (!originalMessage) { - window?.log?.warn( + window?.log?.debug( `Cannot find the original reacted message ${serverId} in conversation ${conversationId}.` ); return; diff --git a/ts/webworker/workers/browser/libsession_worker_interface.ts b/ts/webworker/workers/browser/libsession_worker_interface.ts index 996ba408d..dfb58369a 100644 --- a/ts/webworker/workers/browser/libsession_worker_interface.ts +++ b/ts/webworker/workers/browser/libsession_worker_interface.ts @@ -92,21 +92,13 @@ export const UserConfigWrapperActions: UserConfigWrapperActionsCalls = { storageNamespace: async () => GenericWrapperActions.storageNamespace('UserConfig'), /** UserConfig wrapper specific actions */ - getName: async () => - callLibSessionWorker(['UserConfig', 'getName']) as Promise< - ReturnType + getUserInfo: async () => + callLibSessionWorker(['UserConfig', 'getUserInfo']) as Promise< + ReturnType >, - getProfilePicture: async () => - callLibSessionWorker(['UserConfig', 'getProfilePicture']) as Promise< - ReturnType - >, - setName: async (name: string) => - callLibSessionWorker(['UserConfig', 'setName', name]) as Promise< - ReturnType - >, - setProfilePicture: async (url: string, key: Uint8Array) => - callLibSessionWorker(['UserConfig', 'setProfilePicture', url, key]) as Promise< - ReturnType + setUserInfo: async (name: string, priority: number, url: string, key: Uint8Array) => + callLibSessionWorker(['UserConfig', 'setUserInfo', name, priority, url, key]) as Promise< + ReturnType >, };