diff --git a/js/background.js b/js/background.js
index 7648e5553..7ec8803d4 100644
--- a/js/background.js
+++ b/js/background.js
@@ -740,15 +740,6 @@
}
});
- Whisper.events.on('calculatingPoW', ({ pubKey, timestamp }) => {
- try {
- const conversation = window.getConversationController().get(pubKey);
- conversation.onCalculatingPoW(pubKey, timestamp);
- } catch (e) {
- window.log.error('Error showing PoW cog');
- }
- });
-
Whisper.events.on('password-updated', () => {
if (appView && appView.inboxView) {
appView.inboxView.trigger('password-updated');
diff --git a/js/expiring_messages.js b/js/expiring_messages.js
index fe676b4a1..f18feec33 100644
--- a/js/expiring_messages.js
+++ b/js/expiring_messages.js
@@ -37,7 +37,7 @@
const conversation = message.getConversation();
if (conversation) {
- conversation.trigger('expired', message);
+ conversation.onExpired(message);
}
})
);
diff --git a/ts/components/conversation/message/MessageMetadata.tsx b/ts/components/conversation/message/MessageMetadata.tsx
index f11b87b06..25802ff18 100644
--- a/ts/components/conversation/message/MessageMetadata.tsx
+++ b/ts/components/conversation/message/MessageMetadata.tsx
@@ -22,7 +22,7 @@ type Props = {
direction: 'incoming' | 'outgoing';
timestamp: number;
serverTimestamp?: number;
- status?: 'sending' | 'sent' | 'delivered' | 'read' | 'error' | 'pow';
+ status?: 'sending' | 'sent' | 'delivered' | 'read' | 'error';
expirationLength?: number;
expirationTimestamp?: number;
isPublic?: boolean;
diff --git a/ts/components/conversation/message/OutgoingMessageStatus.tsx b/ts/components/conversation/message/OutgoingMessageStatus.tsx
index 0a4e4c5f6..225c057be 100644
--- a/ts/components/conversation/message/OutgoingMessageStatus.tsx
+++ b/ts/components/conversation/message/OutgoingMessageStatus.tsx
@@ -94,13 +94,12 @@ const MessageStatusError = (props: { theme: DefaultTheme }) => {
};
export const OutgoingMessageStatus = (props: {
- status?: 'sending' | 'sent' | 'delivered' | 'read' | 'error' | 'pow';
+ status?: 'sending' | 'sent' | 'delivered' | 'read' | 'error';
theme: DefaultTheme;
iconColor: string;
isInMessageView?: boolean;
}) => {
switch (props.status) {
- case 'pow':
case 'sending':
return ;
case 'sent':
diff --git a/ts/components/session/settings/SessionSettings.tsx b/ts/components/session/settings/SessionSettings.tsx
index d3e05d082..63d005cbd 100644
--- a/ts/components/session/settings/SessionSettings.tsx
+++ b/ts/components/session/settings/SessionSettings.tsx
@@ -312,18 +312,6 @@ class SettingsViewInner extends React.Component {
}
}
- private getPubkeyName(pubKey: string | null) {
- if (!pubKey) {
- return {};
- }
-
- const secretWords = window.mnemonic.pubkey_to_secret_words(pubKey);
- const conv = ConversationController.getInstance().get(pubKey);
- const deviceAlias = conv ? conv.getNickname() : 'Unnamed Device';
-
- return { deviceAlias, secretWords };
- }
-
// tslint:disable-next-line: max-func-body-length
private getLocalSettings(): Array {
const { Settings } = window.Signal.Types;
diff --git a/ts/models/conversation.ts b/ts/models/conversation.ts
index f007a59a6..92848a3a7 100644
--- a/ts/models/conversation.ts
+++ b/ts/models/conversation.ts
@@ -140,7 +140,6 @@ export const fillConvoAttributesWithDefaults = (
export class ConversationModel extends Backbone.Model {
public updateLastMessage: () => any;
- public messageCollection: MessageCollection;
public throttledBumpTyping: any;
public throttledNotify: any;
public markRead: any;
@@ -158,10 +157,6 @@ export class ConversationModel extends Backbone.Model {
// This may be overridden by ConversationController.getOrCreate, and signify
// our first save to the database. Or first fetch from the database.
this.initialPromise = Promise.resolve();
-
- this.messageCollection = new MessageCollection([], {
- conversation: this,
- });
autoBind(this);
this.throttledBumpTyping = _.throttle(this.bumpTyping, 300);
@@ -170,10 +165,9 @@ export class ConversationModel extends Backbone.Model {
1000
);
this.throttledNotify = _.debounce(this.notify, 500, { maxWait: 1000 });
- this.markRead = _.debounce(this.markReadBouncy, 1000);
+ //start right away the function is called, and wait 1sec before calling it again
+ this.markRead = _.debounce(this.markReadBouncy, 1000, { leading: true });
// Listening for out-of-band data updates
- this.on('expired', this.onExpired);
-
this.on('ourAvatarChanged', avatar =>
this.updateAvatarOnPublicChat(avatar)
);
@@ -376,42 +370,10 @@ export class ConversationModel extends Backbone.Model {
}
}
- public async onExpired(message: any) {
+ public async onExpired(message: MessageModel) {
await this.updateLastMessage();
- const removeMessage = () => {
- const { id } = message;
- const existing = this.messageCollection.get(id);
- if (!existing) {
- return;
- }
-
- window.log.info('Remove expired message from collection', {
- sentAt: existing.get('sent_at'),
- });
-
- this.messageCollection.remove(id);
- existing.trigger('expired');
- };
-
- removeMessage();
- }
-
- // Get messages with the given timestamp
- public getMessagesWithTimestamp(pubKey: string, timestamp: number) {
- if (this.id !== pubKey) {
- return [];
- }
-
- // Go through our messages and find the one that we need to update
- return this.messageCollection.models.filter(
- (m: any) => m.get('sent_at') === timestamp
- );
- }
-
- public async onCalculatingPoW(pubKey: string, timestamp: number) {
- const messages = this.getMessagesWithTimestamp(pubKey, timestamp);
- await Promise.all(messages.map((m: any) => m.setCalculatingPoW()));
+ // removeMessage();
}
public getGroupAdmins() {
@@ -915,7 +877,7 @@ export class ConversationModel extends Backbone.Model {
const messageAttributes = {
// Even though this isn't reflected to the user, we want to place the last seen
// indicator above it. We set it to 'unread' to trigger that placement.
- unread: true,
+ unread: 1,
conversationId: this.id,
// No type; 'incoming' messages are specially treated by conversation.markRead()
sent_at: timestamp,
@@ -1048,37 +1010,29 @@ export class ConversationModel extends Backbone.Model {
);
let read = [];
- console.time('markReadNOCommit');
// Build the list of updated message models so we can mark them all as read on a single sqlite call
for (const nowRead of oldUnreadNowRead) {
- const m = MessageController.getInstance().register(nowRead.id, nowRead);
- await m.markRead(options.readAt);
+ nowRead.markReadNoCommit(options.readAt);
- const errors = m.get('errors');
+ const errors = nowRead.get('errors');
read.push({
- sender: m.get('source'),
- timestamp: m.get('sent_at'),
+ sender: nowRead.get('source'),
+ timestamp: nowRead.get('sent_at'),
hasErrors: Boolean(errors && errors.length),
});
}
- console.timeEnd('markReadNOCommit');
-
- console.warn('oldUnreadNowRead', oldUnreadNowRead);
const oldUnreadNowReadAttrs = oldUnreadNowRead.map(m => m.attributes);
- console.warn('oldUnreadNowReadAttrs', oldUnreadNowReadAttrs);
await saveMessages(oldUnreadNowReadAttrs);
- console.time('trigger');
for (const nowRead of oldUnreadNowRead) {
nowRead.generateProps(false);
}
window.inboxStore?.dispatch(
conversationActions.messagesChanged(oldUnreadNowRead)
);
- console.timeEnd('trigger');
// Some messages we're marking read are local notifications with no sender
read = _.filter(read, m => Boolean(m.sender));
diff --git a/ts/models/message.ts b/ts/models/message.ts
index a7d78ca32..74bbfef42 100644
--- a/ts/models/message.ts
+++ b/ts/models/message.ts
@@ -72,13 +72,9 @@ export class MessageModel extends Backbone.Model {
this.propsForMessage = this.getPropsForMessage();
}
- console.time(`messageChanged ${this.id}`);
-
if (triggerEvent) {
window.inboxStore?.dispatch(conversationActions.messageChanged(this));
}
-
- console.timeEnd(`messageChanged ${this.id}`);
}
public idForLogging() {
@@ -117,7 +113,7 @@ export class MessageModel extends Backbone.Model {
const { unread } = attributes;
if (unread === undefined) {
- this.set({ unread: false });
+ this.set({ unread: 0 });
}
this.set(attributes);
@@ -432,10 +428,6 @@ export class MessageModel extends Backbone.Model {
if (sent || sentTo.length > 0) {
return 'sent';
}
- const calculatingPoW = this.get('calculatingPoW');
- if (calculatingPoW) {
- return 'pow';
- }
return 'sending';
}
@@ -1009,18 +1001,6 @@ export class MessageModel extends Backbone.Model {
return null;
}
- public async setCalculatingPoW() {
- if (this.get('calculatingPoW')) {
- return;
- }
-
- this.set({
- calculatingPoW: true,
- });
-
- await this.commit();
- }
-
public async sendSyncMessageOnly(dataMessage: DataMessage) {
const now = Date.now();
this.set({
@@ -1124,7 +1104,7 @@ export class MessageModel extends Backbone.Model {
}
public markReadNoCommit(readAt: number) {
- this.set({ unread: false });
+ this.set({ unread: 0 });
if (this.get('expireTimer') && !this.get('expirationStartTimestamp')) {
const expirationStartTimestamp = Math.min(
diff --git a/ts/models/messageType.ts b/ts/models/messageType.ts
index 7a7cbf589..53ea4b076 100644
--- a/ts/models/messageType.ts
+++ b/ts/models/messageType.ts
@@ -50,20 +50,57 @@ export interface MessageAttributes {
fromSync?: boolean;
fromGroupUpdate?: boolean;
};
- unread: boolean;
+ /**
+ * 1 means unread, 0 or anything else is read.
+ */
+ unread: number;
group?: any;
+ /**
+ * timestamp is the sent_at timestamp, which is the envelope.timestamp
+ */
timestamp?: number;
status: MessageDeliveryStatus;
dataMessage: any;
sent_to: any;
sent: boolean;
- calculatingPoW: boolean;
+
+ /**
+ * The serverId is the id on the open group server itself.
+ * Each message sent to an open group gets a serverId.
+ * This is not the id for the server, but the id ON the server.
+ *
+ * This field is not set for a message not on an opengroup server.
+ */
serverId?: number;
+ /**
+ * This is the timestamp of that messages as it was saved by the Open group server.
+ * We rely on this one to order Open Group messages.
+ * This field is not set for a message not on an opengroup server.
+ */
serverTimestamp?: number;
+ /**
+ * This field is set to true if the message is for a public server.
+ * This is useful to make the Badge `Public` Appear on a sent message to a server, even if we did not get
+ * the response from the server yet that this message was successfully added.
+ */
isPublic: boolean;
+
+ /**
+ * sentSync set to true means we just triggered the sync message for this Private Chat message.
+ * We did not yet get the message sent confirmation, it was just added to the Outgoing MessageQueue
+ */
sentSync: boolean;
+
+ /**
+ * synced set to true means that this message was successfully sent by our current device to our other devices.
+ * It is set to true when the MessageQueue did effectively sent our sync message without errors.
+ */
synced: boolean;
sync: boolean;
+
+ /**
+ * This field is used for search only
+ */
snippet?: any;
direction: any;
}
@@ -103,14 +140,13 @@ export interface MessageAttributesOptionals {
fromSync?: boolean;
fromGroupUpdate?: boolean;
};
- unread?: boolean;
+ unread?: number;
group?: any;
timestamp?: number;
status?: MessageDeliveryStatus;
dataMessage?: any;
sent_to?: Array;
sent?: boolean;
- calculatingPoW?: boolean;
serverId?: number;
serverTimestamp?: number;
isPublic?: boolean;
@@ -133,6 +169,7 @@ export const fillMessageAttributesWithDefaults = (
expireTimer: 0, // disabled
id: uuidv4(),
schemaVersion: window.Signal.Types.Message.CURRENT_SCHEMA_VERSION,
+ unread: 0, // if nothing is set, this message is considered read
});
};
@@ -147,7 +184,7 @@ export interface MessageRegularProps {
direction: 'incoming' | 'outgoing';
timestamp: number;
serverTimestamp?: number;
- status?: 'sending' | 'sent' | 'delivered' | 'read' | 'error' | 'pow';
+ status?: 'sending' | 'sent' | 'delivered' | 'read' | 'error';
// What if changed this over to a single contact like quote, and put the events on it?
contact?: Contact & {
onSendMessage?: () => void;
diff --git a/ts/receiver/queuedJob.ts b/ts/receiver/queuedJob.ts
index 3c4c2a8d9..276cdd00b 100644
--- a/ts/receiver/queuedJob.ts
+++ b/ts/receiver/queuedJob.ts
@@ -289,7 +289,7 @@ function updateReadStatus(
}
}
if (readSync || message.isExpirationTimerUpdate()) {
- message.set({ unread: false });
+ message.set({ unread: 0 });
// This is primarily to allow the conversation to mark all older
// messages as read, as is done when we receive a read sync for
diff --git a/ts/session/group/index.ts b/ts/session/group/index.ts
index 1a969890c..bfd102331 100644
--- a/ts/session/group/index.ts
+++ b/ts/session/group/index.ts
@@ -206,7 +206,7 @@ export async function addUpdateMessage(
sent_at: sentAt,
received_at: now,
group_update: groupUpdate,
- unread,
+ unread: unread ? 1 : 0,
expireTimer: 0,
});
diff --git a/ts/state/ducks/conversations.ts b/ts/state/ducks/conversations.ts
index 151039676..a842c8333 100644
--- a/ts/state/ducks/conversations.ts
+++ b/ts/state/ducks/conversations.ts
@@ -536,7 +536,6 @@ function handleMessageChanged(
action: MessageChangedActionType
) {
const { payload } = action;
- console.time('handleMessageChanged' + payload.id);
const messageInStoreIndex = state?.messages?.findIndex(
m => m.id === payload.id