fix: run tests for libsession-util integration and fix issue
This commit is contained in:
parent
faea0501bb
commit
cbffc29950
|
@ -3,16 +3,15 @@ import React from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { SectionType } from '../../state/ducks/section';
|
import { SectionType } from '../../state/ducks/section';
|
||||||
import { SessionTheme } from '../../themes/SessionTheme';
|
|
||||||
import { getLeftPaneLists } from '../../state/selectors/conversations';
|
import { getLeftPaneLists } from '../../state/selectors/conversations';
|
||||||
import { getSearchResults, isSearching } from '../../state/selectors/search';
|
import { getSearchResults, isSearching } from '../../state/selectors/search';
|
||||||
import { getFocusedSection, getOverlayMode } from '../../state/selectors/section';
|
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 { CallInFullScreenContainer } from '../calling/CallInFullScreenContainer';
|
||||||
import { DraggableCallContainer } from '../calling/DraggableCallContainer';
|
import { DraggableCallContainer } from '../calling/DraggableCallContainer';
|
||||||
import { IncomingCallDialog } from '../calling/IncomingCallDialog';
|
import { IncomingCallDialog } from '../calling/IncomingCallDialog';
|
||||||
import { ModalContainer } from '../dialog/ModalContainer';
|
import { ModalContainer } from '../dialog/ModalContainer';
|
||||||
import { SessionToastContainer } from '../SessionToastContainer';
|
|
||||||
import { ActionsPanel } from './ActionsPanel';
|
import { ActionsPanel } from './ActionsPanel';
|
||||||
import { LeftPaneMessageSection } from './LeftPaneMessageSection';
|
import { LeftPaneMessageSection } from './LeftPaneMessageSection';
|
||||||
import { LeftPaneSettingSection } from './LeftPaneSettingSection';
|
import { LeftPaneSettingSection } from './LeftPaneSettingSection';
|
||||||
|
@ -28,7 +27,6 @@ const InnerLeftPaneMessageSection = () => {
|
||||||
const searchResults = showSearch ? useSelector(getSearchResults) : undefined;
|
const searchResults = showSearch ? useSelector(getSearchResults) : undefined;
|
||||||
|
|
||||||
const lists = showSearch ? undefined : useSelector(getLeftPaneLists);
|
const lists = showSearch ? undefined : useSelector(getLeftPaneLists);
|
||||||
const messageRequestsEnabled = useSelector(getHideMessageRequestBanner);
|
|
||||||
const overlayMode = useSelector(getOverlayMode);
|
const overlayMode = useSelector(getOverlayMode);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -37,7 +35,6 @@ const InnerLeftPaneMessageSection = () => {
|
||||||
conversations={lists?.conversations || []}
|
conversations={lists?.conversations || []}
|
||||||
contacts={lists?.contacts || []}
|
contacts={lists?.contacts || []}
|
||||||
searchResults={searchResults}
|
searchResults={searchResults}
|
||||||
messageRequestsEnabled={messageRequestsEnabled}
|
|
||||||
overlayMode={overlayMode}
|
overlayMode={overlayMode}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -27,8 +27,6 @@ export interface Props {
|
||||||
contacts: Array<ReduxConversationType>;
|
contacts: Array<ReduxConversationType>;
|
||||||
conversations?: Array<ConversationListItemProps>;
|
conversations?: Array<ConversationListItemProps>;
|
||||||
searchResults?: SearchResultsProps;
|
searchResults?: SearchResultsProps;
|
||||||
|
|
||||||
messageRequestsEnabled?: boolean;
|
|
||||||
overlayMode: OverlayMode | undefined;
|
overlayMode: OverlayMode | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +68,6 @@ const ClosableOverlay = () => {
|
||||||
export class LeftPaneMessageSection extends React.Component<Props> {
|
export class LeftPaneMessageSection extends React.Component<Props> {
|
||||||
public constructor(props: Props) {
|
public constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
autoBind(this);
|
autoBind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { getUnreadConversationRequests } from '../../state/selectors/conversatio
|
||||||
import { getHideMessageRequestBanner } from '../../state/selectors/userConfig';
|
import { getHideMessageRequestBanner } from '../../state/selectors/userConfig';
|
||||||
import { SessionIcon, SessionIconSize, SessionIconType } from '../icon';
|
import { SessionIcon, SessionIconSize, SessionIconType } from '../icon';
|
||||||
import { MessageRequestBannerContextMenu } from '../menu/MessageRequestBannerContextMenu';
|
import { MessageRequestBannerContextMenu } from '../menu/MessageRequestBannerContextMenu';
|
||||||
|
import { isSearching } from '../../state/selectors/search';
|
||||||
|
|
||||||
const StyledMessageRequestBanner = styled.div`
|
const StyledMessageRequestBanner = styled.div`
|
||||||
height: 64px;
|
height: 64px;
|
||||||
|
@ -87,7 +88,10 @@ export const MessageRequestsBanner = (props: { handleOnClick: () => any }) => {
|
||||||
const conversationRequestsUnread = useSelector(getUnreadConversationRequests).length;
|
const conversationRequestsUnread = useSelector(getUnreadConversationRequests).length;
|
||||||
const hideRequestBanner = useSelector(getHideMessageRequestBanner);
|
const hideRequestBanner = useSelector(getHideMessageRequestBanner);
|
||||||
|
|
||||||
if (!conversationRequestsUnread || hideRequestBanner) {
|
// when searching hide the message request banner
|
||||||
|
const isCurrentlySearching = useSelector(isSearching);
|
||||||
|
|
||||||
|
if (!conversationRequestsUnread || hideRequestBanner || isCurrentlySearching) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ const SessionJoinableRoomAvatar = (props: JoinableRoomProps) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window?.log?.warn(e);
|
window?.log?.warn(e.message);
|
||||||
}
|
}
|
||||||
return () => {
|
return () => {
|
||||||
isCancelled = true;
|
isCancelled = true;
|
||||||
|
|
|
@ -41,12 +41,10 @@ import {
|
||||||
updateUserDetailsModal,
|
updateUserDetailsModal,
|
||||||
} from '../../state/ducks/modalDialog';
|
} from '../../state/ducks/modalDialog';
|
||||||
import { getIsMessageSection } from '../../state/selectors/section';
|
import { getIsMessageSection } from '../../state/selectors/section';
|
||||||
import {
|
import { useSelectedConversationKey } from '../../state/selectors/selectedConversation';
|
||||||
useSelectedConversationKey,
|
|
||||||
useSelectedIsPrivateFriend,
|
|
||||||
} from '../../state/selectors/selectedConversation';
|
|
||||||
import { SessionButtonColor } from '../basic/SessionButton';
|
import { SessionButtonColor } from '../basic/SessionButton';
|
||||||
import { useConvoIdFromContext } from '../leftpane/conversation-list-item/ConvoIdContext';
|
import { useConvoIdFromContext } from '../leftpane/conversation-list-item/ConvoIdContext';
|
||||||
|
import { PubKey } from '../../session/types';
|
||||||
|
|
||||||
function showDeleteContact(
|
function showDeleteContact(
|
||||||
isGroup: boolean,
|
isGroup: boolean,
|
||||||
|
@ -339,7 +337,7 @@ export const CopyMenuItem = (): JSX.Element | null => {
|
||||||
export const MarkAllReadMenuItem = (): JSX.Element | null => {
|
export const MarkAllReadMenuItem = (): JSX.Element | null => {
|
||||||
const convoId = useConvoIdFromContext();
|
const convoId = useConvoIdFromContext();
|
||||||
const isIncomingRequest = useIsIncomingRequest(convoId);
|
const isIncomingRequest = useIsIncomingRequest(convoId);
|
||||||
if (!isIncomingRequest) {
|
if (!isIncomingRequest && !PubKey.hasBlindedPrefix(convoId)) {
|
||||||
return (
|
return (
|
||||||
<Item onClick={() => markAllReadByConvoId(convoId)}>{window.i18n('markAllAsRead')}</Item>
|
<Item onClick={() => markAllReadByConvoId(convoId)}>{window.i18n('markAllAsRead')}</Item>
|
||||||
);
|
);
|
||||||
|
@ -361,7 +359,7 @@ export const BlockMenuItem = (): JSX.Element | null => {
|
||||||
const isPrivate = useIsPrivate(convoId);
|
const isPrivate = useIsPrivate(convoId);
|
||||||
const isIncomingRequest = useIsIncomingRequest(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 blockTitle = isBlocked ? window.i18n('unblock') : window.i18n('block');
|
||||||
const blockHandler = isBlocked
|
const blockHandler = isBlocked
|
||||||
? () => unblockConvoById(convoId)
|
? () => unblockConvoById(convoId)
|
||||||
|
@ -391,7 +389,7 @@ export const ChangeNicknameMenuItem = () => {
|
||||||
const convoId = useConvoIdFromContext();
|
const convoId = useConvoIdFromContext();
|
||||||
const isMe = useIsMe(convoId);
|
const isMe = useIsMe(convoId);
|
||||||
const isPrivate = useIsPrivate(convoId);
|
const isPrivate = useIsPrivate(convoId);
|
||||||
const isPrivateAndFriend = useSelectedIsPrivateFriend();
|
const isPrivateAndFriend = useIsPrivateAndFriend(convoId);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
if (isMe || !isPrivate || !isPrivateAndFriend) {
|
if (isMe || !isPrivate || !isPrivateAndFriend) {
|
||||||
|
|
|
@ -105,7 +105,7 @@ export const approveConvoAndSendResponse = async (
|
||||||
) => {
|
) => {
|
||||||
const convoToApprove = getConversationController().get(conversationId);
|
const convoToApprove = getConversationController().get(conversationId);
|
||||||
|
|
||||||
if (!convoToApprove || convoToApprove.isApproved()) {
|
if (!convoToApprove) {
|
||||||
window?.log?.info('Conversation is already approved.');
|
window?.log?.info('Conversation is already approved.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -134,8 +134,8 @@ export async function declineConversationWithoutConfirm({
|
||||||
}) {
|
}) {
|
||||||
const conversationToDecline = getConversationController().get(conversationId);
|
const conversationToDecline = getConversationController().get(conversationId);
|
||||||
|
|
||||||
if (!conversationToDecline || !conversationToDecline.isApproved()) {
|
if (!conversationToDecline || !conversationToDecline.isPrivate()) {
|
||||||
window?.log?.info('Conversation is already declined.');
|
window?.log?.info('No conversation to decline.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ export function banUser(userToBan: string, conversationId: string) {
|
||||||
try {
|
try {
|
||||||
pubKeyToBan = PubKey.cast(userToBan);
|
pubKeyToBan = PubKey.cast(userToBan);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window?.log?.warn(e);
|
window?.log?.warn(e.message);
|
||||||
ToastUtils.pushUserBanFailure();
|
ToastUtils.pushUserBanFailure();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ export function unbanUser(userToUnBan: string, conversationId: string) {
|
||||||
try {
|
try {
|
||||||
pubKeyToUnban = PubKey.cast(userToUnBan);
|
pubKeyToUnban = PubKey.cast(userToUnBan);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window?.log?.warn(e);
|
window?.log?.warn(e.message);
|
||||||
ToastUtils.pushUserBanFailure();
|
ToastUtils.pushUserBanFailure();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -982,11 +982,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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({
|
return this.addSingleMessage({
|
||||||
...messageAttributes,
|
...messageAttributes,
|
||||||
conversationId: this.id,
|
conversationId: this.id,
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import * as BetterSqlite3 from 'better-sqlite3';
|
import * as BetterSqlite3 from 'better-sqlite3';
|
||||||
import { compact, isArray, isEmpty, isNumber, isString, map, pick } from 'lodash';
|
|
||||||
import {
|
import {
|
||||||
ContactsConfigWrapperInsideWorker,
|
ContactsConfigWrapperInsideWorker,
|
||||||
ConvoInfoVolatileWrapperInsideWorker,
|
ConvoInfoVolatileWrapperInsideWorker,
|
||||||
UserConfigWrapperInsideWorker,
|
UserConfigWrapperInsideWorker,
|
||||||
UserGroupsWrapperInsideWorker,
|
UserGroupsWrapperInsideWorker,
|
||||||
} from 'libsession_util_nodejs';
|
} from 'libsession_util_nodejs';
|
||||||
|
import { compact, isArray, isEmpty, isNumber, isString, map, pick } from 'lodash';
|
||||||
import {
|
import {
|
||||||
CONVERSATION_PRIORITIES,
|
CONVERSATION_PRIORITIES,
|
||||||
ConversationAttributes,
|
ConversationAttributes,
|
||||||
|
@ -21,13 +21,13 @@ import {
|
||||||
import {
|
import {
|
||||||
CLOSED_GROUP_V2_KEY_PAIRS_TABLE,
|
CLOSED_GROUP_V2_KEY_PAIRS_TABLE,
|
||||||
CONVERSATIONS_TABLE,
|
CONVERSATIONS_TABLE,
|
||||||
dropFtsAndTriggers,
|
|
||||||
GUARD_NODE_TABLE,
|
GUARD_NODE_TABLE,
|
||||||
LAST_HASHES_TABLE,
|
LAST_HASHES_TABLE,
|
||||||
MESSAGES_TABLE,
|
MESSAGES_TABLE,
|
||||||
NODES_FOR_PUBKEY_TABLE,
|
NODES_FOR_PUBKEY_TABLE,
|
||||||
objectToJSON,
|
|
||||||
OPEN_GROUP_ROOMS_V2_TABLE,
|
OPEN_GROUP_ROOMS_V2_TABLE,
|
||||||
|
dropFtsAndTriggers,
|
||||||
|
objectToJSON,
|
||||||
rebuildFtsTable,
|
rebuildFtsTable,
|
||||||
toSqliteBoolean,
|
toSqliteBoolean,
|
||||||
} from '../database_utility';
|
} from '../database_utility';
|
||||||
|
@ -1572,13 +1572,23 @@ function updateToSessionSchemaVersion30(currentVersion: number, db: BetterSqlite
|
||||||
const ourDbName = ourConversation.displayNameInProfile || '';
|
const ourDbName = ourConversation.displayNameInProfile || '';
|
||||||
const ourDbProfileUrl = ourConversation.avatarPointer || '';
|
const ourDbProfileUrl = ourConversation.avatarPointer || '';
|
||||||
const ourDbProfileKey = fromHexToArray(ourConversation.profileKey || '');
|
const ourDbProfileKey = fromHexToArray(ourConversation.profileKey || '');
|
||||||
userProfileWrapper.setName(ourDbName);
|
const ourConvoPriority = ourConversation.priority;
|
||||||
|
|
||||||
if (ourDbProfileUrl && !isEmpty(ourDbProfileKey)) {
|
if (ourDbProfileUrl && !isEmpty(ourDbProfileKey)) {
|
||||||
userProfileWrapper.setProfilePicture(ourDbProfileUrl, ourDbProfileKey);
|
userProfileWrapper.setUserInfo(
|
||||||
|
ourDbName,
|
||||||
|
ourConvoPriority,
|
||||||
|
ourDbProfileUrl || '',
|
||||||
|
ourDbProfileKey
|
||||||
|
);
|
||||||
} else {
|
} 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(
|
insertContactIntoContactWrapper(
|
||||||
ourConversation,
|
ourConversation,
|
||||||
blockedNumbers,
|
blockedNumbers,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import _, { compact, isEmpty, toNumber } from 'lodash';
|
import { compact, isEmpty, toNumber } from 'lodash';
|
||||||
import { ConfigDumpData } from '../data/configDump/configDump';
|
import { ConfigDumpData } from '../data/configDump/configDump';
|
||||||
import { Data, hasSyncedInitialConfigurationItem } from '../data/data';
|
import { Data, hasSyncedInitialConfigurationItem } from '../data/data';
|
||||||
import { ConversationInteraction } from '../interactions';
|
import { ConversationInteraction } from '../interactions';
|
||||||
|
@ -12,15 +12,17 @@ import {
|
||||||
import { getOpenGroupManager } from '../session/apis/open_group_api/opengroupV2/OpenGroupManagerV2';
|
import { getOpenGroupManager } from '../session/apis/open_group_api/opengroupV2/OpenGroupManagerV2';
|
||||||
import { OpenGroupUtils } from '../session/apis/open_group_api/utils';
|
import { OpenGroupUtils } from '../session/apis/open_group_api/utils';
|
||||||
import { getOpenGroupV2ConversationId } from '../session/apis/open_group_api/utils/OpenGroupUtils';
|
import { getOpenGroupV2ConversationId } from '../session/apis/open_group_api/utils/OpenGroupUtils';
|
||||||
|
import { getSwarmPollingInstance } from '../session/apis/snode_api';
|
||||||
import { getConversationController } from '../session/conversations';
|
import { getConversationController } from '../session/conversations';
|
||||||
import { IncomingMessage } from '../session/messages/incoming/IncomingMessage';
|
import { IncomingMessage } from '../session/messages/incoming/IncomingMessage';
|
||||||
import { ProfileManager } from '../session/profile_manager/ProfileManager';
|
import { ProfileManager } from '../session/profile_manager/ProfileManager';
|
||||||
|
import { PubKey } from '../session/types';
|
||||||
import { UserUtils } from '../session/utils';
|
import { UserUtils } from '../session/utils';
|
||||||
|
import { toHex } from '../session/utils/String';
|
||||||
import { ConfigurationSync } from '../session/utils/job_runners/jobs/ConfigurationSyncJob';
|
import { ConfigurationSync } from '../session/utils/job_runners/jobs/ConfigurationSyncJob';
|
||||||
import { IncomingConfResult, LibSessionUtil } from '../session/utils/libsession/libsession_utils';
|
import { IncomingConfResult, LibSessionUtil } from '../session/utils/libsession/libsession_utils';
|
||||||
import { SessionUtilConvoInfoVolatile } from '../session/utils/libsession/libsession_utils_convo_info_volatile';
|
import { SessionUtilConvoInfoVolatile } from '../session/utils/libsession/libsession_utils_convo_info_volatile';
|
||||||
import { SessionUtilUserGroups } from '../session/utils/libsession/libsession_utils_user_groups';
|
import { SessionUtilUserGroups } from '../session/utils/libsession/libsession_utils_user_groups';
|
||||||
import { toHex } from '../session/utils/String';
|
|
||||||
import { configurationMessageReceived, trigger } from '../shims/events';
|
import { configurationMessageReceived, trigger } from '../shims/events';
|
||||||
import { assertUnreachable } from '../types/sqlSharedTypes';
|
import { assertUnreachable } from '../types/sqlSharedTypes';
|
||||||
import { BlockedNumberController } from '../util';
|
import { BlockedNumberController } from '../util';
|
||||||
|
@ -37,6 +39,7 @@ import {
|
||||||
import { removeFromCache } from './cache';
|
import { removeFromCache } from './cache';
|
||||||
import { addKeyPairToCacheAndDBIfNeeded, handleNewClosedGroup } from './closedGroups';
|
import { addKeyPairToCacheAndDBIfNeeded, handleNewClosedGroup } from './closedGroups';
|
||||||
import { HexKeyPair } from './keypairs';
|
import { HexKeyPair } from './keypairs';
|
||||||
|
import { queueAllCachedFromSource } from './receiver';
|
||||||
import { EnvelopePlus } from './types';
|
import { EnvelopePlus } from './types';
|
||||||
|
|
||||||
function groupByVariant(
|
function groupByVariant(
|
||||||
|
@ -89,7 +92,7 @@ async function mergeConfigsWithIncomingUpdates(
|
||||||
const needsDump = await GenericWrapperActions.needsDump(variant);
|
const needsDump = await GenericWrapperActions.needsDump(variant);
|
||||||
const latestEnvelopeTimestamp = Math.max(...sameVariant.map(m => m.envelopeTimestamp));
|
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 = {
|
const incomingConfResult: IncomingConfResult = {
|
||||||
needsDump,
|
needsDump,
|
||||||
|
@ -109,20 +112,23 @@ async function mergeConfigsWithIncomingUpdates(
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleUserProfileUpdate(result: IncomingConfResult): Promise<IncomingConfResult> {
|
async function handleUserProfileUpdate(result: IncomingConfResult): Promise<IncomingConfResult> {
|
||||||
const updatedUserName = await UserConfigWrapperActions.getName();
|
|
||||||
if (!result.needsDump) {
|
if (!result.needsDump) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
const updateUserInfo = await UserConfigWrapperActions.getUserInfo();
|
||||||
const updatedProfilePicture = await UserConfigWrapperActions.getProfilePicture();
|
if (!updateUserInfo) {
|
||||||
const picUpdate = !isEmpty(updatedProfilePicture.key) && !isEmpty(updatedProfilePicture.url);
|
return result;
|
||||||
|
}
|
||||||
|
const picUpdate = !isEmpty(updateUserInfo.key) && !isEmpty(updateUserInfo.url);
|
||||||
|
|
||||||
await updateOurProfileLegacyOrViaLibSession(
|
await updateOurProfileLegacyOrViaLibSession(
|
||||||
result.latestEnvelopeTimestamp,
|
result.latestEnvelopeTimestamp,
|
||||||
updatedUserName,
|
updateUserInfo.name,
|
||||||
picUpdate ? updatedProfilePicture.url : null,
|
picUpdate ? updateUserInfo.url : null,
|
||||||
picUpdate ? updatedProfilePicture.key : null
|
picUpdate ? updateUserInfo.key : null,
|
||||||
|
updateUserInfo.priority
|
||||||
);
|
);
|
||||||
|
|
||||||
return result;
|
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
|
// 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();
|
const allCommunitiesInWrapper = await UserGroupsWrapperActions.getAllCommunities();
|
||||||
|
window.log.debug(
|
||||||
|
'allCommunitiesInWrapper',
|
||||||
|
allCommunitiesInWrapper.map(m => m.fullUrl)
|
||||||
|
);
|
||||||
const allCommunitiesConversation = getConversationController()
|
const allCommunitiesConversation = getConversationController()
|
||||||
.getConversations()
|
.getConversations()
|
||||||
.filter(SessionUtilUserGroups.isCommunityToStoreInWrapper);
|
.filter(SessionUtilUserGroups.isCommunityToStoreInWrapper);
|
||||||
|
|
||||||
const allCommunitiesIdsInDB = allCommunitiesConversation.map(m => m.id as string);
|
const allCommunitiesIdsInDB = allCommunitiesConversation.map(m => m.id as string);
|
||||||
|
window.log.debug('allCommunitiesIdsInDB', allCommunitiesIdsInDB);
|
||||||
|
|
||||||
const communitiesIdsInWrapper = compact(
|
const communitiesIdsInWrapper = compact(
|
||||||
allCommunitiesInWrapper.map(m => {
|
allCommunitiesInWrapper.map(m => {
|
||||||
|
@ -291,7 +302,7 @@ async function handleLegacyGroupUpdate(latestEnvelopeTimestamp: number) {
|
||||||
const allLegacyGroupsInWrapper = await UserGroupsWrapperActions.getAllLegacyGroups();
|
const allLegacyGroupsInWrapper = await UserGroupsWrapperActions.getAllLegacyGroups();
|
||||||
const allLegacyGroupsInDb = getConversationController()
|
const allLegacyGroupsInDb = getConversationController()
|
||||||
.getConversations()
|
.getConversations()
|
||||||
.filter(SessionUtilUserGroups.isLegacyGroupToStoreInWrapper);
|
.filter(SessionUtilUserGroups.isLegacyGroupToRemoveFromDBIfNotInWrapper);
|
||||||
|
|
||||||
const allLegacyGroupsIdsInDB = allLegacyGroupsInDb.map(m => m.id as string);
|
const allLegacyGroupsIdsInDB = allLegacyGroupsInDb.map(m => m.id as string);
|
||||||
const allLegacyGroupsIdsInWrapper = allLegacyGroupsInWrapper.map(m => m.pubkeyHex);
|
const allLegacyGroupsIdsInWrapper = allLegacyGroupsInWrapper.map(m => m.pubkeyHex);
|
||||||
|
@ -300,6 +311,9 @@ async function handleLegacyGroupUpdate(latestEnvelopeTimestamp: number) {
|
||||||
return !allLegacyGroupsIdsInDB.includes(m.pubkeyHex);
|
return !allLegacyGroupsIdsInDB.includes(m.pubkeyHex);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.log.debug(`allLegacyGroupsInWrapper: ${allLegacyGroupsInWrapper.map(m => m.pubkeyHex)} `);
|
||||||
|
window.log.debug(`allLegacyGroupsIdsInDB: ${allLegacyGroupsIdsInDB} `);
|
||||||
|
|
||||||
const legacyGroupsToLeaveInDB = allLegacyGroupsInDb.filter(m => {
|
const legacyGroupsToLeaveInDB = allLegacyGroupsInDb.filter(m => {
|
||||||
return !allLegacyGroupsIdsInWrapper.includes(m.id);
|
return !allLegacyGroupsIdsInWrapper.includes(m.id);
|
||||||
});
|
});
|
||||||
|
@ -385,6 +399,11 @@ async function handleLegacyGroupUpdate(latestEnvelopeTimestamp: number) {
|
||||||
);
|
);
|
||||||
changes = true;
|
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) {
|
if (changes) {
|
||||||
await legacyGroupConvo.commit();
|
await legacyGroupConvo.commit();
|
||||||
|
@ -578,6 +597,7 @@ async function processMergingResults(results: Map<ConfigWrapperObjectTypes, Inco
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
try {
|
try {
|
||||||
|
// we catch errors here because an old client knowing about a new type of config coming from the network should not just crash
|
||||||
assertUnreachable(kind, `processMergingResults unsupported kind: "${kind}"`);
|
assertUnreachable(kind, `processMergingResults unsupported kind: "${kind}"`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window.log.warn('assertUnreachable failed', e.message);
|
window.log.warn('assertUnreachable failed', e.message);
|
||||||
|
@ -623,7 +643,7 @@ async function handleConfigMessagesViaLibSession(
|
||||||
}
|
}
|
||||||
|
|
||||||
window?.log?.info(
|
window?.log?.info(
|
||||||
`Handling our sharedConfig message via libsession_util: ${configMessages.length}`
|
`Handling our sharedConfig message via libsession_util; count: ${configMessages.length}`
|
||||||
);
|
);
|
||||||
|
|
||||||
const incomingMergeResult = await mergeConfigsWithIncomingUpdates(configMessages);
|
const incomingMergeResult = await mergeConfigsWithIncomingUpdates(configMessages);
|
||||||
|
@ -635,9 +655,10 @@ async function updateOurProfileLegacyOrViaLibSession(
|
||||||
sentAt: number,
|
sentAt: number,
|
||||||
displayName: string,
|
displayName: string,
|
||||||
profileUrl: string | null,
|
profileUrl: string | null,
|
||||||
profileKey: Uint8Array | null
|
profileKey: Uint8Array | null,
|
||||||
|
priority: number | null // passing null means to not update the priority at all (used for legacy config message for now)
|
||||||
) {
|
) {
|
||||||
await ProfileManager.updateOurProfileSync(displayName, profileUrl, profileKey);
|
await ProfileManager.updateOurProfileSync(displayName, profileUrl, profileKey, priority);
|
||||||
|
|
||||||
await setLastProfileUpdateTimestamp(toNumber(sentAt));
|
await setLastProfileUpdateTimestamp(toNumber(sentAt));
|
||||||
// do not trigger a signin by linking if the display name is empty
|
// do not trigger a signin by linking if the display name is empty
|
||||||
|
@ -667,7 +688,8 @@ async function handleOurProfileUpdateLegacy(
|
||||||
toNumber(sentAt),
|
toNumber(sentAt),
|
||||||
displayName,
|
displayName,
|
||||||
profilePicture,
|
profilePicture,
|
||||||
profileKey
|
profileKey,
|
||||||
|
null // passing null to say do not the prioroti, as we do not get one from the legacy config message
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ export async function handleSwarmContentMessage(envelope: EnvelopePlus, messageH
|
||||||
// the sogs messages do not come as milliseconds but just seconds, so we override it
|
// the sogs messages do not come as milliseconds but just seconds, so we override it
|
||||||
await innerHandleSwarmContentMessage(envelope, sentAtTimestamp, plaintext, messageHash);
|
await innerHandleSwarmContentMessage(envelope, sentAtTimestamp, plaintext, messageHash);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window?.log?.warn(e);
|
window?.log?.warn(e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,7 +466,7 @@ export async function innerHandleSwarmContentMessage(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window?.log?.warn(e);
|
window?.log?.warn(e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,10 @@ import {
|
||||||
import { SignalService } from '../protobuf';
|
import { SignalService } from '../protobuf';
|
||||||
import { OpenGroupRequestCommonType } from '../session/apis/open_group_api/opengroupV2/ApiUtil';
|
import { OpenGroupRequestCommonType } from '../session/apis/open_group_api/opengroupV2/ApiUtil';
|
||||||
import { OpenGroupMessageV4 } from '../session/apis/open_group_api/opengroupV2/OpenGroupServerPoller';
|
import { OpenGroupMessageV4 } from '../session/apis/open_group_api/opengroupV2/OpenGroupServerPoller';
|
||||||
|
import { isUsAnySogsFromCache } from '../session/apis/open_group_api/sogsv3/knownBlindedkeys';
|
||||||
import { getOpenGroupV2ConversationId } from '../session/apis/open_group_api/utils/OpenGroupUtils';
|
import { getOpenGroupV2ConversationId } from '../session/apis/open_group_api/utils/OpenGroupUtils';
|
||||||
import { getConversationController } from '../session/conversations';
|
import { getConversationController } from '../session/conversations';
|
||||||
import { removeMessagePadding } from '../session/crypto/BufferPadding';
|
import { removeMessagePadding } from '../session/crypto/BufferPadding';
|
||||||
import { UserUtils } from '../session/utils';
|
|
||||||
import { perfEnd, perfStart } from '../session/utils/Performance';
|
import { perfEnd, perfStart } from '../session/utils/Performance';
|
||||||
import { fromBase64ToArray } from '../session/utils/String';
|
import { fromBase64ToArray } from '../session/utils/String';
|
||||||
import { cleanIncomingDataMessage, messageHasVisibleContent } from './dataMessage';
|
import { cleanIncomingDataMessage, messageHasVisibleContent } from './dataMessage';
|
||||||
|
@ -85,7 +85,7 @@ const handleOpenGroupMessage = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
void groupConvo.queueJob(async () => {
|
void groupConvo.queueJob(async () => {
|
||||||
const isMe = UserUtils.isUsFromCache(sender);
|
const isMe = isUsAnySogsFromCache(sender);
|
||||||
|
|
||||||
// this timestamp has already been forced to ms by the handleMessagesResponseV4() function
|
// this timestamp has already been forced to ms by the handleMessagesResponseV4() function
|
||||||
const commonAttributes = { serverTimestamp: sentTimestamp, serverId, conversationId };
|
const commonAttributes = { serverTimestamp: sentTimestamp, serverId, conversationId };
|
||||||
|
|
|
@ -311,6 +311,20 @@ async function handleExpirationTimerUpdateNoCommit(
|
||||||
await conversation.updateExpireTimer(expireTimer, source, message.get('received_at'), {}, false);
|
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(
|
export async function handleMessageJob(
|
||||||
messageModel: MessageModel,
|
messageModel: MessageModel,
|
||||||
conversation: ConversationModel,
|
conversation: ConversationModel,
|
||||||
|
@ -386,6 +400,7 @@ export async function handleMessageJob(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await markConvoAsReadIfOutgoingMessage(conversation, messageModel);
|
||||||
if (messageModel.get('unread')) {
|
if (messageModel.get('unread')) {
|
||||||
conversation.throttledNotify(messageModel);
|
conversation.throttledNotify(messageModel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,17 +7,18 @@ import { getOpenGroupManager } from '../apis/open_group_api/opengroupV2/OpenGrou
|
||||||
import { getSwarmFor } from '../apis/snode_api/snodePool';
|
import { getSwarmFor } from '../apis/snode_api/snodePool';
|
||||||
import { PubKey } from '../types';
|
import { PubKey } from '../types';
|
||||||
|
|
||||||
|
import { ConvoVolatileType } from 'libsession_util_nodejs';
|
||||||
import { deleteAllMessagesByConvoIdNoConfirmation } from '../../interactions/conversationInteractions';
|
import { deleteAllMessagesByConvoIdNoConfirmation } from '../../interactions/conversationInteractions';
|
||||||
import { CONVERSATION_PRIORITIES, ConversationTypeEnum } from '../../models/conversationAttributes';
|
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 { leaveClosedGroup } from '../group/closed-group';
|
||||||
|
import { ConfigurationDumpSync } from '../utils/job_runners/jobs/ConfigurationSyncDumpJob';
|
||||||
import { ConfigurationSync } from '../utils/job_runners/jobs/ConfigurationSyncJob';
|
import { ConfigurationSync } from '../utils/job_runners/jobs/ConfigurationSyncJob';
|
||||||
|
import { LibSessionUtil } from '../utils/libsession/libsession_utils';
|
||||||
import { SessionUtilContact } from '../utils/libsession/libsession_utils_contacts';
|
import { SessionUtilContact } from '../utils/libsession/libsession_utils_contacts';
|
||||||
import { SessionUtilConvoInfoVolatile } from '../utils/libsession/libsession_utils_convo_info_volatile';
|
import { SessionUtilConvoInfoVolatile } from '../utils/libsession/libsession_utils_convo_info_volatile';
|
||||||
import { SessionUtilUserGroups } from '../utils/libsession/libsession_utils_user_groups';
|
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;
|
let instance: ConversationController | null;
|
||||||
|
|
||||||
|
@ -235,6 +236,18 @@ export class ConversationController {
|
||||||
break;
|
break;
|
||||||
case 'Community':
|
case 'Community':
|
||||||
window?.log?.info('leaving open group v2', conversation.id);
|
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
|
// remove from the wrapper the entries before we remove the roomInfos, as we won't have the required community pubkey afterwards
|
||||||
try {
|
try {
|
||||||
await SessionUtilUserGroups.removeCommunityFromWrapper(conversation.id, conversation.id);
|
await SessionUtilUserGroups.removeCommunityFromWrapper(conversation.id, conversation.id);
|
||||||
|
@ -242,15 +255,6 @@ export class ConversationController {
|
||||||
window?.log?.info('SessionUtilUserGroups.removeCommunityFromWrapper failed:', e);
|
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);
|
const roomInfos = OpenGroupData.getV2OpenGroupRoom(conversation.id);
|
||||||
if (roomInfos) {
|
if (roomInfos) {
|
||||||
getOpenGroupManager().removeRoomFromPolledRooms(roomInfos);
|
getOpenGroupManager().removeRoomFromPolledRooms(roomInfos);
|
||||||
|
@ -264,7 +268,7 @@ export class ConversationController {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'LegacyGroup':
|
case 'LegacyGroup':
|
||||||
window.log.info(`deleteContact ClosedGroup case: ${id}`);
|
window.log.info(`deleteContact ClosedGroup case: ${conversation.id}`);
|
||||||
await leaveClosedGroup(conversation.id);
|
await leaveClosedGroup(conversation.id);
|
||||||
await SessionUtilUserGroups.removeLegacyGroupFromWrapper(conversation.id);
|
await SessionUtilUserGroups.removeLegacyGroupFromWrapper(conversation.id);
|
||||||
await SessionUtilConvoInfoVolatile.removeLegacyGroupFromWrapper(conversation.id);
|
await SessionUtilConvoInfoVolatile.removeLegacyGroupFromWrapper(conversation.id);
|
||||||
|
|
|
@ -10,7 +10,8 @@ import { toHex } from '../utils/String';
|
||||||
async function updateOurProfileSync(
|
async function updateOurProfileSync(
|
||||||
displayName: string | undefined,
|
displayName: string | undefined,
|
||||||
profileUrl: string | null,
|
profileUrl: string | null,
|
||||||
profileKey: Uint8Array | null
|
profileKey: Uint8Array | null,
|
||||||
|
priority: number | null
|
||||||
) {
|
) {
|
||||||
const us = UserUtils.getOurPubKeyStrFromCache();
|
const us = UserUtils.getOurPubKeyStrFromCache();
|
||||||
const ourConvo = getConversationController().get(us);
|
const ourConvo = getConversationController().get(us);
|
||||||
|
@ -19,7 +20,11 @@ async function updateOurProfileSync(
|
||||||
return;
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -99,7 +99,7 @@ class ConfigurationSyncDumpJob extends PersistedJob<ConfigurationSyncDumpPersist
|
||||||
// so when we call needsDump(), we know for sure that we are up to date
|
// so when we call needsDump(), we know for sure that we are up to date
|
||||||
|
|
||||||
// TODOLATER we need to add the dump of the wrappers of other destination than ourself once we had the closed group handling of config sync job
|
// TODOLATER we need to add the dump of the wrappers of other destination than ourself once we had the closed group handling of config sync job
|
||||||
|
// I think dumping should not fetch data from the DB again, but instead just use the data already in the wrapper.
|
||||||
for (let index = 0; index < LibSessionUtil.requiredUserVariants.length; index++) {
|
for (let index = 0; index < LibSessionUtil.requiredUserVariants.length; index++) {
|
||||||
const variant = LibSessionUtil.requiredUserVariants[index];
|
const variant = LibSessionUtil.requiredUserVariants[index];
|
||||||
switch (variant) {
|
switch (variant) {
|
||||||
|
@ -174,7 +174,7 @@ async function queueNewJobIfNeeded() {
|
||||||
|
|
||||||
// this call will make sure that there is only one configuration sync job at all times
|
// this call will make sure that there is only one configuration sync job at all times
|
||||||
await runners.configurationSyncDumpRunner.addJob(
|
await runners.configurationSyncDumpRunner.addJob(
|
||||||
new ConfigurationSyncDumpJob({ nextAttemptTimestamp: Date.now() })
|
new ConfigurationSyncDumpJob({ nextAttemptTimestamp: Date.now() + 1000 }) // we postpone by 1000ms to make sure whoever is adding this job is done with what is needs to do first
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// if we did run at 100, and it is currently 110, diff is 10
|
// if we did run at 100, and it is currently 110, diff is 10
|
||||||
|
|
|
@ -168,6 +168,7 @@ class ConfigurationSyncJob extends PersistedJob<ConfigurationSyncPersistedData>
|
||||||
window.log.warn('did not find our own conversation');
|
window.log.warn('did not find our own conversation');
|
||||||
return RunJobResult.PermanentFailure;
|
return RunJobResult.PermanentFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let index = 0; index < LibSessionUtil.requiredUserVariants.length; index++) {
|
for (let index = 0; index < LibSessionUtil.requiredUserVariants.length; index++) {
|
||||||
const variant = LibSessionUtil.requiredUserVariants[index];
|
const variant = LibSessionUtil.requiredUserVariants[index];
|
||||||
switch (variant) {
|
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
|
// this call will make sure that there is only one configuration sync job at all times
|
||||||
await runners.configurationSyncRunner.addJob(
|
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 {
|
} else {
|
||||||
// if we did run at t=100, and it is currently t=110, the difference is 10
|
// 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);
|
const diff = Math.max(Date.now() - lastRunConfigSyncJobTimestamp, 0);
|
||||||
|
|
|
@ -98,17 +98,18 @@ async function pendingChangesForPubkey(pubkey: string): Promise<Array<OutgoingCo
|
||||||
}
|
}
|
||||||
|
|
||||||
const results: Array<OutgoingConfResult> = [];
|
const results: Array<OutgoingConfResult> = [];
|
||||||
|
const variantsNeedingPush = new Set<ConfigWrapperObjectTypes>();
|
||||||
|
|
||||||
for (let index = 0; index < dumps.length; index++) {
|
for (let index = 0; index < dumps.length; index++) {
|
||||||
const dump = dumps[index];
|
const dump = dumps[index];
|
||||||
const variant = dump.variant;
|
const variant = dump.variant;
|
||||||
const needsPush = await GenericWrapperActions.needsPush(variant);
|
const needsPush = await GenericWrapperActions.needsPush(variant);
|
||||||
window.log.debug(`needsPush ${needsPush} for variant: ${variant}`);
|
|
||||||
|
|
||||||
if (!needsPush) {
|
if (!needsPush) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variantsNeedingPush.add(variant);
|
||||||
const { data, seqno, hashes } = await GenericWrapperActions.push(variant);
|
const { data, seqno, hashes } = await GenericWrapperActions.push(variant);
|
||||||
|
|
||||||
const kind = variantToKind(variant);
|
const kind = variantToKind(variant);
|
||||||
|
@ -124,6 +125,7 @@ async function pendingChangesForPubkey(pubkey: string): Promise<Array<OutgoingCo
|
||||||
namespace,
|
namespace,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
window.log.debug(`those variants needs push: "${[...variantsNeedingPush]}"`);
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,9 +242,9 @@ function getVolatileInfoCached(convoId: string): BaseConvoInfoVolatile | undefin
|
||||||
/**
|
/**
|
||||||
* Removes the matching community from the wrapper and from the cached list of communities
|
* Removes the matching community from the wrapper and from the cached list of communities
|
||||||
*/
|
*/
|
||||||
async function removeCommunityFromWrapper(convoId: string, fullUrlWithOrWithoutPubkey: string) {
|
async function removeCommunityFromWrapper(convoId: string, fullUrlWithPubkey: string) {
|
||||||
try {
|
try {
|
||||||
await ConvoInfoVolatileWrapperActions.eraseCommunityByFullUrl(fullUrlWithOrWithoutPubkey);
|
await ConvoInfoVolatileWrapperActions.eraseCommunityByFullUrl(fullUrlWithPubkey);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window.log.warn('removeCommunityFromWrapper failed with ', e.message);
|
window.log.warn('removeCommunityFromWrapper failed with ', e.message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,27 @@ function isLegacyGroupToStoreInWrapper(convo: ConversationModel): boolean {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We do not want to include groups left in the wrapper, but when receiving a list of wrappers from the network we need to check against the one present locally but already left, to know we need to remove them.
|
||||||
|
*
|
||||||
|
* This is to take care of this case:
|
||||||
|
* - deviceA creates group
|
||||||
|
* - deviceB joins group
|
||||||
|
* - deviceA leaves the group
|
||||||
|
* - deviceB leaves the group
|
||||||
|
* - deviceA removes the group entirely from the wrapper
|
||||||
|
* - deviceB receives the wrapper update and needs to remove the group from the DB
|
||||||
|
*
|
||||||
|
* But, as the group was already left, it would not be accounted for by `isLegacyGroupToStoreInWrapper`
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function isLegacyGroupToRemoveFromDBIfNotInWrapper(convo: ConversationModel): boolean {
|
||||||
|
// this filter is based on `isLegacyGroupToStoreInWrapper`
|
||||||
|
return (
|
||||||
|
convo.isGroup() && !convo.isPublic() && convo.id.startsWith('05') // new closed groups won't start with 05
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the specified convo and updates the required field in the wrapper.
|
* Fetches the specified convo and updates the required field in the wrapper.
|
||||||
* If that community does not exist in the wrapper, it is created before being updated.
|
* If that community does not exist in the wrapper, it is created before being updated.
|
||||||
|
@ -221,10 +242,13 @@ function getAllLegacyGroups(): Array<LegacyGroupInfo> {
|
||||||
* Remove the matching legacy group from the wrapper and from the cached list of legacy groups
|
* Remove the matching legacy group from the wrapper and from the cached list of legacy groups
|
||||||
*/
|
*/
|
||||||
async function removeLegacyGroupFromWrapper(groupPk: string) {
|
async function removeLegacyGroupFromWrapper(groupPk: string) {
|
||||||
const fromWrapper = await UserGroupsWrapperActions.getLegacyGroup(groupPk);
|
try {
|
||||||
|
|
||||||
if (fromWrapper) {
|
|
||||||
await UserGroupsWrapperActions.eraseLegacyGroup(groupPk);
|
await UserGroupsWrapperActions.eraseLegacyGroup(groupPk);
|
||||||
|
} catch (e) {
|
||||||
|
window.log.warn(
|
||||||
|
`UserGroupsWrapperActions.eraseLegacyGroup with = ${groupPk} failed with`,
|
||||||
|
e.message
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
mappedLegacyGroupWrapperValues.delete(groupPk);
|
mappedLegacyGroupWrapperValues.delete(groupPk);
|
||||||
|
@ -257,6 +281,7 @@ export const SessionUtilUserGroups = {
|
||||||
|
|
||||||
// legacy group
|
// legacy group
|
||||||
isLegacyGroupToStoreInWrapper,
|
isLegacyGroupToStoreInWrapper,
|
||||||
|
isLegacyGroupToRemoveFromDBIfNotInWrapper,
|
||||||
getLegacyGroupCached,
|
getLegacyGroupCached,
|
||||||
getAllLegacyGroups,
|
getAllLegacyGroups,
|
||||||
removeLegacyGroupFromWrapper, // a group can be removed but also just marked hidden, so only call this function when the group is completely removed // TODOLATER
|
removeLegacyGroupFromWrapper, // a group can be removed but also just marked hidden, so only call this function when the group is completely removed // TODOLATER
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { UserUtils } from '..';
|
||||||
import { UserConfigWrapperActions } from '../../../webworker/workers/browser/libsession_worker_interface';
|
import { UserConfigWrapperActions } from '../../../webworker/workers/browser/libsession_worker_interface';
|
||||||
import { getConversationController } from '../../conversations';
|
import { getConversationController } from '../../conversations';
|
||||||
import { fromHexToArray } from '../String';
|
import { fromHexToArray } from '../String';
|
||||||
|
import { CONVERSATION_PRIORITIES } from '../../../models/conversationAttributes';
|
||||||
|
|
||||||
async function insertUserProfileIntoWrapper(convoId: string) {
|
async function insertUserProfileIntoWrapper(convoId: string) {
|
||||||
if (!isUserProfileToStoreInWrapper(convoId)) {
|
if (!isUserProfileToStoreInWrapper(convoId)) {
|
||||||
|
@ -18,12 +19,21 @@ async function insertUserProfileIntoWrapper(convoId: string) {
|
||||||
const dbName = ourConvo.get('displayNameInProfile') || '';
|
const dbName = ourConvo.get('displayNameInProfile') || '';
|
||||||
const dbProfileUrl = ourConvo.get('avatarPointer') || '';
|
const dbProfileUrl = ourConvo.get('avatarPointer') || '';
|
||||||
const dbProfileKey = fromHexToArray(ourConvo.get('profileKey') || '');
|
const dbProfileKey = fromHexToArray(ourConvo.get('profileKey') || '');
|
||||||
await UserConfigWrapperActions.setName(dbName);
|
|
||||||
|
|
||||||
if (dbProfileUrl && !isEmpty(dbProfileKey)) {
|
if (dbProfileUrl && !isEmpty(dbProfileKey)) {
|
||||||
await UserConfigWrapperActions.setProfilePicture(dbProfileUrl, dbProfileKey);
|
await UserConfigWrapperActions.setUserInfo(
|
||||||
|
dbName,
|
||||||
|
ourConvo.get('priority') || CONVERSATION_PRIORITIES.default,
|
||||||
|
dbProfileUrl,
|
||||||
|
dbProfileKey
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
await UserConfigWrapperActions.setProfilePicture('', new Uint8Array());
|
await UserConfigWrapperActions.setUserInfo(
|
||||||
|
dbName,
|
||||||
|
ourConvo.get('priority') || CONVERSATION_PRIORITIES.default,
|
||||||
|
'',
|
||||||
|
new Uint8Array()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -288,6 +288,11 @@ const _getLeftPaneLists = (
|
||||||
directConversations.push(conversation);
|
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 =
|
const isPrivateButHidden =
|
||||||
conversation.isPrivate &&
|
conversation.isPrivate &&
|
||||||
conversation.priority &&
|
conversation.priority &&
|
||||||
|
|
|
@ -58,7 +58,7 @@ const getMessageByReaction = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!originalMessage) {
|
if (!originalMessage) {
|
||||||
window?.log?.warn(`Cannot find the original reacted message ${originalMessageId}.`);
|
window?.log?.debug(`Cannot find the original reacted message ${originalMessageId}.`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ const handleMessageReaction = async ({
|
||||||
const handleClearReaction = async (conversationId: string, serverId: number, emoji: string) => {
|
const handleClearReaction = async (conversationId: string, serverId: number, emoji: string) => {
|
||||||
const originalMessage = await Data.getMessageByServerId(conversationId, serverId);
|
const originalMessage = await Data.getMessageByServerId(conversationId, serverId);
|
||||||
if (!originalMessage) {
|
if (!originalMessage) {
|
||||||
window?.log?.warn(
|
window?.log?.debug(
|
||||||
`Cannot find the original reacted message ${serverId} in conversation ${conversationId}.`
|
`Cannot find the original reacted message ${serverId} in conversation ${conversationId}.`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -269,7 +269,7 @@ const handleOpenGroupMessageReactions = async (
|
||||||
) => {
|
) => {
|
||||||
const originalMessage = await Data.getMessageByServerId(conversationId, serverId);
|
const originalMessage = await Data.getMessageByServerId(conversationId, serverId);
|
||||||
if (!originalMessage) {
|
if (!originalMessage) {
|
||||||
window?.log?.warn(
|
window?.log?.debug(
|
||||||
`Cannot find the original reacted message ${serverId} in conversation ${conversationId}.`
|
`Cannot find the original reacted message ${serverId} in conversation ${conversationId}.`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -92,21 +92,13 @@ export const UserConfigWrapperActions: UserConfigWrapperActionsCalls = {
|
||||||
storageNamespace: async () => GenericWrapperActions.storageNamespace('UserConfig'),
|
storageNamespace: async () => GenericWrapperActions.storageNamespace('UserConfig'),
|
||||||
|
|
||||||
/** UserConfig wrapper specific actions */
|
/** UserConfig wrapper specific actions */
|
||||||
getName: async () =>
|
getUserInfo: async () =>
|
||||||
callLibSessionWorker(['UserConfig', 'getName']) as Promise<
|
callLibSessionWorker(['UserConfig', 'getUserInfo']) as Promise<
|
||||||
ReturnType<UserConfigWrapperActionsCalls['getName']>
|
ReturnType<UserConfigWrapperActionsCalls['getUserInfo']>
|
||||||
>,
|
>,
|
||||||
getProfilePicture: async () =>
|
setUserInfo: async (name: string, priority: number, url: string, key: Uint8Array) =>
|
||||||
callLibSessionWorker(['UserConfig', 'getProfilePicture']) as Promise<
|
callLibSessionWorker(['UserConfig', 'setUserInfo', name, priority, url, key]) as Promise<
|
||||||
ReturnType<UserConfigWrapperActionsCalls['getProfilePicture']>
|
ReturnType<UserConfigWrapperActionsCalls['setUserInfo']>
|
||||||
>,
|
|
||||||
setName: async (name: string) =>
|
|
||||||
callLibSessionWorker(['UserConfig', 'setName', name]) as Promise<
|
|
||||||
ReturnType<UserConfigWrapperActionsCalls['setName']>
|
|
||||||
>,
|
|
||||||
setProfilePicture: async (url: string, key: Uint8Array) =>
|
|
||||||
callLibSessionWorker(['UserConfig', 'setProfilePicture', url, key]) as Promise<
|
|
||||||
ReturnType<UserConfigWrapperActionsCalls['setProfilePicture']>
|
|
||||||
>,
|
>,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue