fix: unread count and forced unread is synced

pull/2620/head
Audric Ackermann 1 year ago
parent c3a9d19882
commit c3e9d503e4

@ -3,6 +3,8 @@ const { Storage } = require('./ts/util/storage');
const url = require('url');
const _ = require('lodash');
const config = url.parse(window.location.toString(), true).query;
const configAny = config;
@ -29,6 +31,7 @@ window.sessionFeatureFlags = {
useTestNet: Boolean(
process.env.NODE_APP_INSTANCE && process.env.NODE_APP_INSTANCE.includes('testnet')
),
useDebugLogging: !_.isEmpty(process.env.SESSION_DEBUG),
useClosedGroupV3: false || process.env.USE_CLOSED_GROUP_V3,
useSharedUtilForUserConfig: true,
debug: {
@ -234,6 +237,7 @@ const { setupi18n } = require('./ts/util/i18n');
window.Signal = data.initData();
const { getConversationController } = require('./ts/session/conversations/ConversationController');
const { isEmpty } = require('lodash');
window.getConversationController = getConversationController;
// Linux seems to periodically let the event loop stop, so this is a global workaround
setInterval(() => {

@ -1,7 +1,7 @@
import { ipcRenderer } from 'electron';
import React from 'react';
import styled from 'styled-components';
import { MessageDeliveryStatus } from '../../../../models/messageType';
import { LastMessageStatusType } from '../../../../state/ducks/conversations';
import { SessionIcon } from '../../../icon';
const MessageStatusSendingContainer = styled.div`
@ -56,7 +56,7 @@ const MessageStatusError = ({ dataTestId }: { dataTestId?: string }) => {
};
export const OutgoingMessageStatus = (props: {
status?: MessageDeliveryStatus | null;
status: LastMessageStatusType | null;
dataTestId?: string;
}) => {
const { status, dataTestId } = props;

@ -62,14 +62,14 @@ const ContactItem = (props: { contact: ContactPropsMessageDetail }) => {
const { contact } = props;
const errors = contact.errors || [];
const statusComponent = !contact.isOutgoingKeyError ? (
const statusComponent = (
<div
className={classNames(
'module-message-detail__contact__status-icon',
`module-message-detail__contact__status-icon--${contact.status}`
)}
/>
) : null;
);
return (
<div key={contact.pubkey} className="module-message-detail__contact">

@ -117,7 +117,6 @@ import {
type InMemoryConvoInfos = {
mentionedUs: boolean;
unreadCount: number;
lastReadTimestampMessage: number | null;
};
// TODO decide it it makes sense to move this to a redux slice?
@ -275,7 +274,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
public getGroupAdmins(): Array<string> {
const groupAdmins = this.get('groupAdmins');
return groupAdmins && groupAdmins?.length > 0 ? groupAdmins : [];
return groupAdmins && groupAdmins.length > 0 ? groupAdmins : [];
}
// tslint:disable-next-line: cyclomatic-complexity max-func-body-length
@ -291,8 +290,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
const weAreModerator = this.isModerator(ourNumber); // only used for sogs
const isMe = this.isMe();
const isTyping = !!this.typingTimer;
// const unreadCount = this.get('unreadCount') || undefined;
// const mentionedUs = this.get('mentionedUs') || undefined;
const isKickedFromGroup = !!this.get('isKickedFromGroup');
const left = !!this.get('left');
const currentNotificationSetting = this.get('triggerNotificationsFor');
@ -337,7 +334,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
toRet.avatarPath = avatarPath;
}
const foundContact = SessionUtilContact.getMappedValue(this.id);
const foundContact = SessionUtilContact.getContactCached(this.id);
const foundCommunity = SessionUtilUserGroups.getCommunityByConvoIdCached(this.id);
const foundLegacyGroup = SessionUtilUserGroups.getLegacyGroupCached(this.id);
const foundVolatileInfo = SessionUtilConvoInfoVolatile.getVolatileInfoCached(this.id);
@ -498,13 +495,10 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
inMemoryConvoInfos.delete(this.id);
return;
}
console.warn('memoryDetails', memoryDetails);
if (!inMemoryConvoInfos.get(this.id)) {
inMemoryConvoInfos.set(this.id, {
mentionedUs: false,
unreadCount: 0,
lastReadTimestampMessage: null,
});
}
@ -517,10 +511,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
existing.unreadCount = memoryDetails.unreadCount;
changes = true;
}
if (existing.lastReadTimestampMessage !== memoryDetails.lastReadTimestampMessage) {
existing.lastReadTimestampMessage = memoryDetails.lastReadTimestampMessage;
changes = true;
}
if (existing.mentionedUs !== memoryDetails.mentionedUs) {
existing.mentionedUs = memoryDetails.mentionedUs;
changes = true;
@ -531,10 +522,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
}
}
public getCachedLastReadTimestampMessage() {
return inMemoryConvoInfos.get(this.id)?.lastReadTimestampMessage || null;
}
public async queueJob(callback: () => Promise<void>) {
// tslint:disable-next-line: no-promise-as-boolean
const previous = this.pending || Promise.resolve();
@ -1855,8 +1842,8 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
return;
}
const lastMessageModel = messages.at(0);
const lastMessageStatus = lastMessageModel?.getMessagePropStatus() || undefined;
const lastMessageNotificationText = lastMessageModel?.getNotificationText() || undefined;
const lastMessageStatus = lastMessageModel.getMessagePropStatus() || undefined;
const lastMessageNotificationText = lastMessageModel.getNotificationText() || undefined;
// we just want to set the `status` to `undefined` if there are no `lastMessageNotificationText`
const lastMessageUpdate =
!!lastMessageNotificationText && !isEmpty(lastMessageNotificationText)

@ -713,7 +713,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
// We include numbers we didn't successfully send to so we can display errors.
// Older messages don't have the recipients included on the message, so we fall
// back to the conversation's current recipients
const phoneNumbers: Array<string> = this.isIncoming()
const contacts: Array<string> = this.isIncoming()
? [this.get('source')]
: this.get('sent_to') || [];
@ -727,30 +727,21 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
const errors = reject(allErrors, error => Boolean(error.number));
const errorsGroupedById = groupBy(allErrors, 'number');
const finalContacts = await Promise.all(
(phoneNumbers || []).map(async id => {
(contacts || []).map(async id => {
const errorsForContact = errorsGroupedById[id];
const isOutgoingKeyError = false;
const contact = this.findAndFormatContact(id);
return {
...contact,
// fallback to the message status if we do not have a status with a user
// this is useful for medium groups.
status: this.getStatus(id) || this.getMessagePropStatus(),
status: this.getMessagePropStatus(),
errors: errorsForContact,
isOutgoingKeyError,
isPrimaryDevice: true,
profileName: contact.profileName,
};
})
);
// The prefix created here ensures that contacts with errors are listed
// first; otherwise it's alphabetical
const sortedContacts = sortBy(
finalContacts,
contact => `${contact.isPrimaryDevice ? '0' : '1'}${contact.pubkey}`
);
// sort by pubkey
const sortedContacts = sortBy(finalContacts, contact => contact.pubkey);
const toRet: MessagePropsDetails = {
sentAt: this.get('sent_at') || 0,
@ -1013,19 +1004,6 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
return lodashSize(this.get('errors')) > 0;
}
public getStatus(pubkey: string) {
const readBy = this.get('read_by') || [];
if (readBy.indexOf(pubkey) >= 0) {
return 'read';
}
const sentTo = this.get('sent_to') || [];
if (sentTo.indexOf(pubkey) >= 0) {
return 'sent';
}
return null;
}
public async updateMessageHash(messageHash: string) {
if (!messageHash) {
window?.log?.error('Message hash not provided to update message hash');

@ -1,11 +1,14 @@
import { defaultsDeep } from 'lodash';
import { v4 as uuidv4 } from 'uuid';
import { CallNotificationType, PropsForMessageWithConvoProps } from '../state/ducks/conversations';
import {
CallNotificationType,
LastMessageStatusType,
PropsForMessageWithConvoProps,
} from '../state/ducks/conversations';
import { AttachmentTypeWithPath } from '../types/Attachment';
import { Reaction, ReactionList, SortedReactionList } from '../types/Reaction';
export type MessageModelType = 'incoming' | 'outgoing';
export type MessageDeliveryStatus = 'sending' | 'sent' | 'read' | 'error';
export interface MessageAttributes {
// the id of the message
@ -48,7 +51,7 @@ export interface MessageAttributes {
* timestamp is the sent_at timestamp, which is the envelope.timestamp
*/
timestamp?: number;
status?: MessageDeliveryStatus;
status?: LastMessageStatusType;
sent_to: Array<string>;
sent: boolean;
@ -196,7 +199,7 @@ export interface MessageAttributesOptionals {
unread?: number;
group?: any;
timestamp?: number;
status?: MessageDeliveryStatus;
status?: LastMessageStatusType;
sent_to?: Array<string>;
sent?: boolean;
serverId?: number;

@ -19,6 +19,7 @@ import {
CONVERSATIONS_TABLE,
dropFtsAndTriggers,
GUARD_NODE_TABLE,
jsonToObject,
LAST_HASHES_TABLE,
MESSAGES_TABLE,
NODES_FOR_PUBKEY_TABLE,
@ -1486,11 +1487,16 @@ function updateToSessionSchemaVersion30(currentVersion: number, db: BetterSqlite
* Setup up the User profile wrapper with what is stored in our own conversation
*/
const ourConversation = sqlNode.getConversationById(publicKeyHex, db);
if (!ourConversation) {
const ourConvoRow = db.prepare(`SELECT * FROM ${CONVERSATIONS_TABLE} WHERE id = $id;`).get({
id: publicKeyHex,
});
if (!ourConvoRow) {
throw new Error('Failed to find our logged in conversation while migrating');
}
const ourConversation = jsonToObject(ourConvoRow);
// Insert the user profile into the userWrappoer
const ourDbName = ourConversation.displayNameInProfile || '';
const ourDbProfileUrl = ourConversation.avatarPointer || '';

@ -309,7 +309,7 @@ async function handleLegacyGroupUpdate(latestEnvelopeTimestamp: number) {
const legacyGroupsToLeaveInDB = allLegacyGroupsInDb.filter(m => {
return !allLegacyGroupsIdsInWrapper.includes(m.id);
});
// TODO we need to store the encryption keypair if needed
window.log.info(
`we have to join ${legacyGroupsToJoinInDB.length} legacy groups in DB compared to what is in the wrapper`
);
@ -456,6 +456,39 @@ async function handleUserGroupsUpdate(result: IncomingConfResult): Promise<Incom
return result;
}
async function applyConvoVolatileUpdateFromWrapper(
convoId: string,
forcedUnread: boolean,
lastReadMessageTimestamp: number
) {
const foundConvo = getConversationController().get(convoId);
if (foundConvo) {
try {
window.log.debug(
`applyConvoVolatileUpdateFromWrapper: ${convoId}: forcedUnread:${forcedUnread}, lastReadMessage:${lastReadMessageTimestamp}`
);
// this should mark all the messages sent before fromWrapper.lastRead as read and update the unreadCount
await foundConvo.markReadFromConfigMessage(lastReadMessageTimestamp);
// this commits to the DB, if needed
await foundConvo.markAsUnread(forcedUnread, true);
if (SessionUtilConvoInfoVolatile.isConvoToStoreInWrapper(foundConvo)) {
await SessionUtilConvoInfoVolatile.refreshConvoVolatileCached(
foundConvo.id,
foundConvo.isClosedGroup(),
false
);
await foundConvo.refreshInMemoryDetails();
}
} catch (e) {
window.log.warn(
`applyConvoVolatileUpdateFromWrapper of "${convoId}" failed with error ${e.message}`
);
}
}
}
async function handleConvoInfoVolatileUpdate(
result: IncomingConfResult
): Promise<IncomingConfResult> {
@ -463,50 +496,71 @@ async function handleConvoInfoVolatileUpdate(
// if (!result.needsDump) {
// return result;
// }
console.error('handleConvoInfoVolatileUpdate : TODO ');
const types = SessionUtilConvoInfoVolatile.getConvoInfoVolatileTypes();
for (let typeIndex = 0; typeIndex < types.length; typeIndex++) {
const type = types[typeIndex];
switch (type) {
case '1o1':
// Note: "Note to Self" comes here too
const privateChats = await ConvoInfoVolatileWrapperActions.getAll1o1();
for (let index = 0; index < privateChats.length; index++) {
const fromWrapper = privateChats[index];
const foundConvo = getConversationController().get(fromWrapper.pubkeyHex);
// TODO should we create the conversation if the conversation does not exist locally? Or assume that it should be coming from a contacts update?
if (foundConvo) {
console.warn(
`fromWrapper from getAll1o1: ${fromWrapper.pubkeyHex}: ${fromWrapper.unread}`
try {
// Note: "Note to Self" comes here too
const wrapper1o1s = await ConvoInfoVolatileWrapperActions.getAll1o1();
for (let index = 0; index < wrapper1o1s.length; index++) {
const fromWrapper = wrapper1o1s[index];
await applyConvoVolatileUpdateFromWrapper(
fromWrapper.pubkeyHex,
fromWrapper.unread,
fromWrapper.lastRead
);
// this should mark all the messages sent before fromWrapper.lastRead as read and update the unreadCount
await foundConvo.markReadFromConfigMessage(fromWrapper.lastRead);
// this commits to the DB, if needed
await foundConvo.markAsUnread(fromWrapper.unread, true);
if (SessionUtilConvoInfoVolatile.isConvoToStoreInWrapper(foundConvo)) {
await SessionUtilConvoInfoVolatile.refreshConvoVolatileCached(
foundConvo.id,
foundConvo.isClosedGroup(),
false
);
await foundConvo.refreshInMemoryDetails();
}
}
} catch (e) {
window.log.warn('handleConvoInfoVolatileUpdate of "1o1" failed with error: ', e.message);
}
console.warn('handleConvoInfoVolatileUpdate: privateChats', privateChats);
break;
case 'Community':
const comms = await ConvoInfoVolatileWrapperActions.getAllCommunities();
console.warn('handleConvoInfoVolatileUpdate: comms', comms);
try {
const wrapperComms = await ConvoInfoVolatileWrapperActions.getAllCommunities();
for (let index = 0; index < wrapperComms.length; index++) {
const fromWrapper = wrapperComms[index];
const convoId = getOpenGroupV2ConversationId(
fromWrapper.baseUrl,
fromWrapper.roomCasePreserved
);
await applyConvoVolatileUpdateFromWrapper(
convoId,
fromWrapper.unread,
fromWrapper.lastRead
);
}
} catch (e) {
window.log.warn(
'handleConvoInfoVolatileUpdate of "Community" failed with error: ',
e.message
);
}
break;
case 'LegacyGroup':
const legacyGroup = await ConvoInfoVolatileWrapperActions.getAllLegacyGroups();
console.warn('handleConvoInfoVolatileUpdate: legacyGroup', legacyGroup);
try {
const legacyGroups = await ConvoInfoVolatileWrapperActions.getAllLegacyGroups();
for (let index = 0; index < legacyGroups.length; index++) {
const fromWrapper = legacyGroups[index];
await applyConvoVolatileUpdateFromWrapper(
fromWrapper.pubkeyHex,
fromWrapper.unread,
fromWrapper.lastRead
);
}
} catch (e) {
window.log.warn(
'handleConvoInfoVolatileUpdate of "LegacyGroup" failed with error: ',
e.message
);
}
break;
default:

@ -380,7 +380,6 @@ export const getRoomAndUpdateLastFetchTimestamp = async (
if (!newMessages.length) {
// if we got no new messages, just write our last update timestamp to the db
roomInfos.lastFetchTimestamp = Date.now();
window?.log?.info();
await OpenGroupData.saveV2OpenGroupRoom(roomInfos);
return null;
}

@ -221,26 +221,28 @@ export class ConversationController {
// open group v2
} else if (conversation.isPublic()) {
window?.log?.info('leaving open group v2', conversation.id);
// 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);
await SessionUtilConvoInfoVolatile.removeCommunityFromWrapper(
conversation.id,
conversation.id
);
} catch (e) {
window?.log?.info('SessionUtilUserGroups.removeCommunityFromWrapper failed:', e);
}
const roomInfos = OpenGroupData.getV2OpenGroupRoom(conversation.id);
if (roomInfos) {
getOpenGroupManager().removeRoomFromPolledRooms(roomInfos);
}
// remove the roomInfos locally for this open group room
// remove the roomInfos locally for this open group room including the pubkey
try {
await OpenGroupData.removeV2OpenGroupRoom(conversation.id);
} catch (e) {
window?.log?.info('removeV2OpenGroupRoom failed:', e);
}
try {
await SessionUtilUserGroups.removeCommunityFromWrapper(conversation.id, conversation.id);
await SessionUtilConvoInfoVolatile.removeCommunityFromWrapper(
conversation.id,
conversation.id
);
} catch (e) {
window?.log?.info('SessionUtilUserGroups.removeCommunityFromWrapper failed:', e);
}
} else if (conversation.isPrivate()) {
// if this conversation is a private conversation it's in fact a `contact` for desktop.
// we just want to remove everything related to it and set the hidden field to true

@ -130,11 +130,7 @@ async function buildAndSaveDumpsToDB(changes: Array<SuccessfulChange>): Promise<
for (let i = 0; i < changes.length; i++) {
const change = changes[i];
const variant = LibSessionUtil.kindToVariant(change.message.kind);
console.warn(
`ConfigurationSyncJob.saveDumpToDB: "${variant}" updatedHash: "${
change.updatedHash
}:${change.message.seqno.toNumber()}"`
);
const needsDump = await LibSessionUtil.markAsPushed(
variant,
change.publicKey,
@ -302,11 +298,13 @@ async function queueNewJobIfNeeded() {
await runners.configurationSyncRunner.addJob(
new ConfigurationSyncJob({ nextAttemptTimestamp: Date.now() })
);
window.log.debug('Scheduling ConfSyncJob: ASAP');
} else {
// if we did run at t=100, and it is currently t=110, diff is 10
const diff = Math.max(Date.now() - lastRunConfigSyncJobTimestamp, 0);
// but we want to run every 30, so what we need is actually `30-10` from now = 20
const leftBeforeNextTick = Math.max(defaultMsBetweenRetries - diff, 0);
window.log.debug('Scheduling ConfSyncJob: LATER');
// TODO we need to make the addJob wait for the previous addJob to be done before it can be called.
await runners.configurationSyncRunner.addJob(

@ -112,6 +112,7 @@ async function pendingChangesForPubkey(pubkey: string): Promise<Array<OutgoingCo
const variant = dump.variant;
const needsPush = await GenericWrapperActions.needsPush(variant);
if (!needsPush) {
console.info('needsPush false for ', variant);
continue;
}

@ -126,7 +126,7 @@ function setMappedValue(info: ContactInfo) {
mappedContactWrapperValues.set(info.id, info);
}
function getMappedValue(id: string) {
function getContactCached(id: string) {
return mappedContactWrapperValues.get(id);
}
@ -134,6 +134,6 @@ export const SessionUtilContact = {
isContactToStoreInContactsWrapper,
insertAllContactsIntoContactsWrapper,
insertContactFromDBIntoWrapperAndRefresh,
getMappedValue,
getContactCached,
refreshMappedValue,
};

@ -1,4 +1,4 @@
import { uniq } from 'lodash';
import { isEmpty, uniq } from 'lodash';
import { BaseConvoInfoVolatile, ConvoVolatileType } from 'session_util_wrapper';
import { Data } from '../../../data/data';
import { OpenGroupData } from '../../../data/opengroups';
@ -87,12 +87,12 @@ async function insertConvoFromDBIntoWrapperAndRefresh(convoId: string): Promise<
if (!foundConvo || !isConvoToStoreInWrapper(foundConvo)) {
return;
}
const isForcedUnread = foundConvo.isMarkedUnread();
const lastReadTimestampMessage = foundConvo.getCachedLastReadTimestampMessage() || 0;
const lastReadMessageTimestamp =
(await Data.fetchConvoMemoryDetails(convoId))?.lastReadTimestampMessage || 0;
console.info(
`convoInfoVolatile:insert "${convoId}";lastMessageReadTimestamp:${lastReadTimestampMessage};forcedUnread:${isForcedUnread}...`
`convoInfoVolatile:insert "${convoId}";lastMessageReadTimestamp:${lastReadMessageTimestamp};forcedUnread:${isForcedUnread}...`
);
const convoType = getConvoType(foundConvo);
@ -102,7 +102,7 @@ async function insertConvoFromDBIntoWrapperAndRefresh(convoId: string): Promise<
// this saves the details for contacts and `Note To Self`
await ConvoInfoVolatileWrapperActions.set1o1(
convoId,
lastReadTimestampMessage,
lastReadMessageTimestamp,
isForcedUnread
);
await refreshConvoVolatileCached(convoId, false, false);
@ -116,7 +116,7 @@ async function insertConvoFromDBIntoWrapperAndRefresh(convoId: string): Promise<
try {
await ConvoInfoVolatileWrapperActions.setLegacyGroup(
convoId,
lastReadTimestampMessage,
lastReadMessageTimestamp,
isForcedUnread
);
await refreshConvoVolatileCached(convoId, true, false);
@ -124,14 +124,13 @@ async function insertConvoFromDBIntoWrapperAndRefresh(convoId: string): Promise<
window.log.warn(
`ConvoInfoVolatileWrapperActions.setLegacyGroup of ${convoId} failed with ${e.message}`
);
// we stil let this go through
}
break;
case 'Community':
try {
const asOpengroup = foundConvo.toOpenGroupV2();
const roomDetails = OpenGroupData.getV2OpenGroupRoomByRoomId(asOpengroup);
if (!roomDetails) {
if (!roomDetails || isEmpty(roomDetails.serverPublicKey)) {
return;
}
@ -141,18 +140,19 @@ async function insertConvoFromDBIntoWrapperAndRefresh(convoId: string): Promise<
roomDetails.roomId,
roomDetails.serverPublicKey
);
// this does the create or the update of the matching existing community
await ConvoInfoVolatileWrapperActions.setCommunityByFullUrl(
fullUrlWithPubkey,
lastReadTimestampMessage,
lastReadMessageTimestamp,
isForcedUnread
);
await refreshConvoVolatileCached(convoId, false, false);
} catch (e) {
window.log.warn(
`ConvoInfoVolatileWrapperActions.setCommunityByFullUrl of ${convoId} failed with ${e.message}`
);
// we still let this go through
}
break;
default:
@ -173,29 +173,46 @@ async function refreshConvoVolatileCached(
duringAppStart: boolean
) {
try {
let convoType: ConvoVolatileType = '1o1';
let refreshed = false;
if (OpenGroupUtils.isOpenGroupV2(convoId)) {
const fromWrapper = await ConvoInfoVolatileWrapperActions.getCommunity(convoId);
if (fromWrapper && fromWrapper.fullUrlWithPubkey) {
mappedCommunityWrapperValues.set(convoId, fromWrapper);
}
refreshed = true;
convoType = 'Community';
} else if (convoId.startsWith('05') && isLegacyGroup) {
const fromWrapper = await ConvoInfoVolatileWrapperActions.getLegacyGroup(convoId);
if (fromWrapper) {
mappedLegacyGroupWrapperValues.set(convoId, fromWrapper);
}
refreshed = true;
convoType = 'LegacyGroup';
} else if (convoId.startsWith('05')) {
const fromWrapper = await ConvoInfoVolatileWrapperActions.get1o1(convoId);
console.warn(
`refreshConvoVolatileCached from get1o1 ${fromWrapper?.pubkeyHex} : ${fromWrapper?.unread}`
);
if (fromWrapper) {
mapped1o1WrapperValues.set(convoId, fromWrapper);
}
refreshed = true;
} // TODO handle the new closed groups once we got them ready
convoType = '1o1';
}
switch (convoType) {
case '1o1':
const fromWrapper1o1 = await ConvoInfoVolatileWrapperActions.get1o1(convoId);
if (fromWrapper1o1) {
mapped1o1WrapperValues.set(convoId, fromWrapper1o1);
}
refreshed = true;
break;
case 'LegacyGroup':
const fromWrapperLegacyGroup = await ConvoInfoVolatileWrapperActions.getLegacyGroup(
convoId
);
if (fromWrapperLegacyGroup) {
mappedLegacyGroupWrapperValues.set(convoId, fromWrapperLegacyGroup);
}
refreshed = true;
break;
case 'Community':
const fromWrapperCommunity = await ConvoInfoVolatileWrapperActions.getCommunity(convoId);
if (fromWrapperCommunity && fromWrapperCommunity.fullUrlWithPubkey) {
mappedCommunityWrapperValues.set(convoId, fromWrapperCommunity);
}
refreshed = true;
break;
default:
assertUnreachable(convoType, `refreshConvoVolatileCached unhandled case "${convoType}"`);
}
// TODO handle the new closed groups once we got them ready
if (refreshed && !duringAppStart) {
getConversationController()

@ -2,7 +2,6 @@ import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';
import { getConversationController } from '../../session/conversations';
import { Data } from '../../data/data';
import {
MessageDeliveryStatus,
MessageModelType,
PropsForDataExtractionNotification,
PropsForMessageRequestResponse,
@ -45,8 +44,6 @@ export type ContactPropsMessageDetail = {
name?: string | null;
profileName?: string | null;
avatarPath?: string | null;
isOutgoingKeyError: boolean;
errors?: Array<Error>;
};
@ -60,7 +57,7 @@ export type MessagePropsDetails = {
direction: MessageModelType;
};
export type LastMessageStatusType = MessageDeliveryStatus | undefined;
export type LastMessageStatusType = 'sending' | 'sent' | 'read' | 'error' | undefined;
export type FindAndFormatContactType = {
pubkey: string;

@ -110,6 +110,9 @@ const development = window && window?.getEnvironment && window?.getEnvironment()
// The Bunyan API: https://github.com/trentm/node-bunyan#log-method-api
function logAtLevel(level: string, prefix: string, ...args: any) {
if (prefix === 'DEBUG' && window.sessionFeatureFlags.useDebugLogging) {
return;
}
if (development) {
const fn = `_${level}`;
(console as any)[fn](prefix, now(), ...args);

1
ts/window.d.ts vendored

@ -43,6 +43,7 @@ declare global {
debugNonSnodeRequests: boolean;
debugOnionRequests: boolean;
};
useDebugLogging: boolean;
};
SessionSnodeAPI: SessionSnodeAPI;
onLogin: (pw: string) => Promise<void>;

Loading…
Cancel
Save