Additional logging, new ability to force Conversation 'change' event
This commit is contained in:
parent
e9ef239ff0
commit
250a89d953
5 changed files with 45 additions and 85 deletions
|
@ -123,7 +123,7 @@ window.addEventListener('unhandledrejection', rejectionEvent => {
|
||||||
});
|
});
|
||||||
|
|
||||||
initLogger(
|
initLogger(
|
||||||
SignalClientLogLevel.Warn,
|
SignalClientLogLevel.Info,
|
||||||
(
|
(
|
||||||
level: unknown,
|
level: unknown,
|
||||||
target: string,
|
target: string,
|
||||||
|
|
|
@ -286,23 +286,28 @@ export class ConversationModel extends window.Backbone
|
||||||
|
|
||||||
// We clear our cached props whenever we change so that the next call to format() will
|
// We clear our cached props whenever we change so that the next call to format() will
|
||||||
// result in refresh via a getProps() call. See format() below.
|
// result in refresh via a getProps() call. See format() below.
|
||||||
this.on('change', () => {
|
this.on(
|
||||||
const changedKeys = Object.keys(this.changed || {});
|
'change',
|
||||||
const isPropsCacheStillValid = Boolean(
|
(_model: MessageModel, options: { force?: boolean } = {}) => {
|
||||||
changedKeys.length &&
|
const changedKeys = Object.keys(this.changed || {});
|
||||||
changedKeys.every(key =>
|
const isPropsCacheStillValid =
|
||||||
ATTRIBUTES_THAT_DONT_INVALIDATE_PROPS_CACHE.has(key)
|
!options.force &&
|
||||||
)
|
Boolean(
|
||||||
);
|
changedKeys.length &&
|
||||||
if (isPropsCacheStillValid) {
|
changedKeys.every(key =>
|
||||||
return;
|
ATTRIBUTES_THAT_DONT_INVALIDATE_PROPS_CACHE.has(key)
|
||||||
}
|
)
|
||||||
|
);
|
||||||
|
if (isPropsCacheStillValid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.cachedProps) {
|
if (this.cachedProps) {
|
||||||
this.oldCachedProps = this.cachedProps;
|
this.oldCachedProps = this.cachedProps;
|
||||||
|
}
|
||||||
|
this.cachedProps = null;
|
||||||
}
|
}
|
||||||
this.cachedProps = null;
|
);
|
||||||
});
|
|
||||||
|
|
||||||
// Set `isFetchingUUID` eagerly to avoid UI flicker when opening the
|
// Set `isFetchingUUID` eagerly to avoid UI flicker when opening the
|
||||||
// conversation for the first time.
|
// conversation for the first time.
|
||||||
|
@ -1039,7 +1044,7 @@ export class ConversationModel extends window.Backbone
|
||||||
);
|
);
|
||||||
|
|
||||||
this.isFetchingUUID = true;
|
this.isFetchingUUID = true;
|
||||||
this.trigger('change', this);
|
this.trigger('change', this, { force: true });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Attempt to fetch UUID
|
// Attempt to fetch UUID
|
||||||
|
@ -1051,7 +1056,7 @@ export class ConversationModel extends window.Backbone
|
||||||
} finally {
|
} finally {
|
||||||
// No redux update here
|
// No redux update here
|
||||||
this.isFetchingUUID = false;
|
this.isFetchingUUID = false;
|
||||||
this.trigger('change', this);
|
this.trigger('change', this, { force: true });
|
||||||
|
|
||||||
log.info(
|
log.info(
|
||||||
`Done fetching uuid for a sms-only conversation ${this.idForLogging()}`
|
`Done fetching uuid for a sms-only conversation ${this.idForLogging()}`
|
||||||
|
@ -2449,7 +2454,7 @@ export class ConversationModel extends window.Backbone
|
||||||
// If the verified state of a member changes, our aggregate state changes.
|
// If the verified state of a member changes, our aggregate state changes.
|
||||||
// We trigger both events to replicate the behavior of window.Backbone.Model.set()
|
// We trigger both events to replicate the behavior of window.Backbone.Model.set()
|
||||||
this.trigger('change:verified', this);
|
this.trigger('change:verified', this);
|
||||||
this.trigger('change', this);
|
this.trigger('change', this, { force: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
async toggleVerified(): Promise<unknown> {
|
async toggleVerified(): Promise<unknown> {
|
||||||
|
@ -2859,10 +2864,7 @@ export class ConversationModel extends window.Backbone
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async onReadMessage(
|
async onReadMessage(message: MessageModel, readAt?: number): Promise<void> {
|
||||||
message: MessageModel,
|
|
||||||
readAt?: number
|
|
||||||
): Promise<WhatIsThis> {
|
|
||||||
// We mark as read everything older than this message - to clean up old stuff
|
// We mark as read everything older than this message - to clean up old stuff
|
||||||
// still marked unread in the database. If the user generally doesn't read in
|
// still marked unread in the database. If the user generally doesn't read in
|
||||||
// the desktop app, so the desktop app only gets read syncs, we can very
|
// the desktop app, so the desktop app only gets read syncs, we can very
|
||||||
|
@ -3397,7 +3399,7 @@ export class ConversationModel extends window.Backbone
|
||||||
targetAuthorUuid: string;
|
targetAuthorUuid: string;
|
||||||
targetTimestamp: number;
|
targetTimestamp: number;
|
||||||
}
|
}
|
||||||
): Promise<WhatIsThis> {
|
): Promise<void> {
|
||||||
const { messageId } = target;
|
const { messageId } = target;
|
||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
const outgoingReaction = { ...reaction, ...target };
|
const outgoingReaction = { ...reaction, ...target };
|
||||||
|
@ -4950,13 +4952,13 @@ export class ConversationModel extends window.Backbone
|
||||||
);
|
);
|
||||||
if (!record) {
|
if (!record) {
|
||||||
// User was not previously typing before. State change!
|
// User was not previously typing before. State change!
|
||||||
this.trigger('change', this);
|
this.trigger('change', this, { force: true });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
delete this.contactTypingTimers[typingToken];
|
delete this.contactTypingTimers[typingToken];
|
||||||
if (record) {
|
if (record) {
|
||||||
// User was previously typing, and is no longer. State change!
|
// User was previously typing, and is no longer. State change!
|
||||||
this.trigger('change', this);
|
this.trigger('change', this, { force: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4970,7 +4972,7 @@ export class ConversationModel extends window.Backbone
|
||||||
delete this.contactTypingTimers[typingToken];
|
delete this.contactTypingTimers[typingToken];
|
||||||
|
|
||||||
// User was previously typing, but timed out or we received message. State change!
|
// User was previously typing, but timed out or we received message. State change!
|
||||||
this.trigger('change', this);
|
this.trigger('change', this, { force: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5061,7 +5063,8 @@ window.Whisper.ConversationCollection = window.Backbone.Collection.extend({
|
||||||
this.eraseLookups();
|
this.eraseLookups();
|
||||||
this.on(
|
this.on(
|
||||||
'idUpdated',
|
'idUpdated',
|
||||||
(model: WhatIsThis, idProp: string, oldValue: WhatIsThis) => {
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(model: ConversationModel, idProp: string, oldValue: any) => {
|
||||||
if (oldValue) {
|
if (oldValue) {
|
||||||
if (idProp === 'e164') {
|
if (idProp === 'e164') {
|
||||||
delete this._byE164[oldValue];
|
delete this._byE164[oldValue];
|
||||||
|
@ -5073,14 +5076,17 @@ window.Whisper.ConversationCollection = window.Backbone.Collection.extend({
|
||||||
delete this._byGroupId[oldValue];
|
delete this._byGroupId[oldValue];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (model.get('e164')) {
|
const e164 = model.get('e164');
|
||||||
this._byE164[model.get('e164')] = model;
|
if (e164) {
|
||||||
|
this._byE164[e164] = model;
|
||||||
}
|
}
|
||||||
if (model.get('uuid')) {
|
const uuid = model.get('uuid');
|
||||||
this._byUuid[model.get('uuid')] = model;
|
if (uuid) {
|
||||||
|
this._byUuid[uuid] = model;
|
||||||
}
|
}
|
||||||
if (model.get('groupId')) {
|
const groupId = model.get('groupId');
|
||||||
this._byGroupId[model.get('groupId')] = model;
|
if (groupId) {
|
||||||
|
this._byGroupId[groupId] = model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -5185,51 +5191,6 @@ window.Whisper.ConversationCollection = window.Backbone.Collection.extend({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// This is a wrapper model used to display group members in the member list view, within
|
|
||||||
// the world of backbone, but layering another bit of group-specific data top of base
|
|
||||||
// conversation data.
|
|
||||||
window.Whisper.GroupMemberConversation = window.Backbone.Model.extend({
|
|
||||||
initialize(attributes: { conversation: boolean; isAdmin: boolean }) {
|
|
||||||
const { conversation, isAdmin } = attributes;
|
|
||||||
|
|
||||||
if (!conversation) {
|
|
||||||
throw new Error(
|
|
||||||
'GroupMemberConversation.initialize: conversation required!'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (!window._.isBoolean(isAdmin)) {
|
|
||||||
throw new Error('GroupMemberConversation.initialize: isAdmin required!');
|
|
||||||
}
|
|
||||||
|
|
||||||
// If our underlying conversation changes, we change too
|
|
||||||
this.listenTo(conversation, 'change', () => {
|
|
||||||
this.trigger('change', this);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.conversation = conversation;
|
|
||||||
this.isAdmin = isAdmin;
|
|
||||||
},
|
|
||||||
|
|
||||||
format() {
|
|
||||||
return {
|
|
||||||
...this.conversation.format(),
|
|
||||||
isAdmin: this.isAdmin,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
get(...params: Array<string>) {
|
|
||||||
return this.conversation.get(...params);
|
|
||||||
},
|
|
||||||
|
|
||||||
getTitle() {
|
|
||||||
return this.conversation.getTitle();
|
|
||||||
},
|
|
||||||
|
|
||||||
isMe() {
|
|
||||||
return isMe(this.conversation.attributes);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
type SortableByTitle = {
|
type SortableByTitle = {
|
||||||
getTitle: () => string;
|
getTitle: () => string;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1320,7 +1320,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
async send(
|
async send(
|
||||||
promise: Promise<CallbackResultType | void | null>,
|
promise: Promise<CallbackResultType | void | null>,
|
||||||
saveErrors?: (errors: Array<Error>) => void
|
saveErrors?: (errors: Array<Error>) => void
|
||||||
): Promise<void | Array<void>> {
|
): Promise<void> {
|
||||||
const updateLeftPane =
|
const updateLeftPane =
|
||||||
this.getConversation()?.debouncedUpdateLastMessage || noop;
|
this.getConversation()?.debouncedUpdateLastMessage || noop;
|
||||||
|
|
||||||
|
|
|
@ -1164,8 +1164,8 @@ export default class MessageReceiver
|
||||||
|
|
||||||
if (envelope.serverTimestamp > certificate.expiration()) {
|
if (envelope.serverTimestamp > certificate.expiration()) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`MessageReceiver.validateUnsealedEnvelope: ' +
|
'MessageReceiver.validateUnsealedEnvelope: ' +
|
||||||
'Sender certificate is expired for envelope ${logId}`
|
`Sender certificate is expired for envelope ${logId}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,8 @@ export async function onRetryRequest(event: RetryRequestEvent): Promise<void> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await archiveSessionOnMatch(retryRequest);
|
||||||
|
|
||||||
if (isOlderThan(sentAt, retryRespondMaxAge)) {
|
if (isOlderThan(sentAt, retryRespondMaxAge)) {
|
||||||
log.info(
|
log.info(
|
||||||
`onRetryRequest/${logId}: Message is too old, refusing to send again.`
|
`onRetryRequest/${logId}: Message is too old, refusing to send again.`
|
||||||
|
@ -92,7 +94,6 @@ export async function onRetryRequest(event: RetryRequestEvent): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info(`onRetryRequest/${logId}: Resending message`);
|
log.info(`onRetryRequest/${logId}: Resending message`);
|
||||||
await archiveSessionOnMatch(retryRequest);
|
|
||||||
|
|
||||||
const { contentHint, messageIds, proto, timestamp } = sentProto;
|
const { contentHint, messageIds, proto, timestamp } = sentProto;
|
||||||
|
|
||||||
|
@ -206,8 +207,6 @@ async function sendDistributionMessageOrNullMessage(
|
||||||
let sentDistributionMessage = false;
|
let sentDistributionMessage = false;
|
||||||
log.info(`sendDistributionMessageOrNullMessage/${logId}: Starting...`);
|
log.info(`sendDistributionMessageOrNullMessage/${logId}: Starting...`);
|
||||||
|
|
||||||
await archiveSessionOnMatch(options);
|
|
||||||
|
|
||||||
const conversation = window.ConversationController.getOrCreate(
|
const conversation = window.ConversationController.getOrCreate(
|
||||||
requesterUuid,
|
requesterUuid,
|
||||||
'private'
|
'private'
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue