fix order for open groups message which are out of sync

pull/1321/head
Audric Ackermann 5 years ago
parent 76664d9a11
commit 1e446b0a81
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -1121,10 +1121,15 @@
Whisper.events.on( Whisper.events.on(
'publicMessageSent', 'publicMessageSent',
({ pubKey, timestamp, serverId }) => { ({ pubKey, timestamp, serverId, serverTimestamp }) => {
try { try {
const conversation = ConversationController.get(pubKey); const conversation = ConversationController.get(pubKey);
conversation.onPublicMessageSent(pubKey, timestamp, serverId); conversation.onPublicMessageSent(
pubKey,
timestamp,
serverId,
serverTimestamp
);
} catch (e) { } catch (e) {
window.log.error('Error setting public on message'); window.log.error('Error setting public on message');
} }

@ -540,12 +540,13 @@
await Promise.all(messages.map(m => m.setCalculatingPoW())); await Promise.all(messages.map(m => m.setCalculatingPoW()));
}, },
async onPublicMessageSent(pubKey, timestamp, serverId) { async onPublicMessageSent(pubKey, timestamp, serverId, serverTimestamp) {
const messages = this._getMessagesWithTimestamp(pubKey, timestamp); const messages = this._getMessagesWithTimestamp(pubKey, timestamp);
await Promise.all( await Promise.all(
messages.map(message => [ messages.map(message => [
message.setIsPublic(true), message.setIsPublic(true),
message.setServerId(serverId), message.setServerId(serverId),
message.setServerTimestamp(serverTimestamp),
]) ])
); );
}, },
@ -1295,6 +1296,9 @@
if (this.isPrivate()) { if (this.isPrivate()) {
message.set({ destination }); message.set({ destination });
} }
if (this.isPublic()) {
message.setServerTimestamp(new Date().getTime());
}
const id = await window.Signal.Data.saveMessage(message.attributes, { const id = await window.Signal.Data.saveMessage(message.attributes, {
Message: Whisper.Message, Message: Whisper.Message,

@ -1441,6 +1441,19 @@
Message: Whisper.Message, Message: Whisper.Message,
}); });
}, },
async setServerTimestamp(serverTimestamp) {
if (_.isEqual(this.get('serverTimestamp'), serverTimestamp)) {
return;
}
this.set({
serverTimestamp,
});
await window.Signal.Data.saveMessage(this.attributes, {
Message: Whisper.Message,
});
},
async setIsPublic(isPublic) { async setIsPublic(isPublic) {
if (_.isEqual(this.get('isPublic'), isPublic)) { if (_.isEqual(this.get('isPublic'), isPublic)) {
return; return;

@ -30,7 +30,7 @@ export interface LokiPublicChannelAPI {
body?: string; body?: string;
}, },
timestamp: number timestamp: number
): Promise<number>; ): Promise<{ serverId; serverTimestamp }>;
} }
declare class LokiAppDotNetServerAPI implements LokiAppDotNetServerInterface { declare class LokiAppDotNetServerAPI implements LokiAppDotNetServerInterface {

@ -2345,7 +2345,10 @@ class LokiPublicChannelAPI {
objBody: payload, objBody: payload,
}); });
if (!res.err && res.response) { if (!res.err && res.response) {
return res.response.data.id; return {
serverId: res.response.data.id,
serverTimestamp: new Date(`${res.response.data.created_at}`).getTime(),
};
} }
if (res.err) { if (res.err) {
log.error(`POST ${this.baseChannelUrl}/messages failed`); log.error(`POST ${this.baseChannelUrl}/messages failed`);
@ -2357,9 +2360,8 @@ class LokiPublicChannelAPI {
} else { } else {
log.warn(res.response); log.warn(res.response);
} }
// there's no retry on desktop
// this is supposed to be after retries return { serverId: -1, serverTimestamp: -1 };
return -1;
} }
} }

@ -60,7 +60,8 @@ class LokiMessageAPI {
'Failed to send public chat message' 'Failed to send public chat message'
); );
} }
messageEventData.serverId = res; messageEventData.serverId = res.serverId;
messageEventData.serverTimestamp = res.serverTimestamp;
window.Whisper.events.trigger('publicMessageSent', messageEventData); window.Whisper.events.trigger('publicMessageSent', messageEventData);
return; return;
} }

@ -62,13 +62,14 @@ export class MessageQueue implements MessageQueueInterface {
try { try {
const result = await MessageSender.sendToOpenGroup(message); const result = await MessageSender.sendToOpenGroup(message);
// sendToOpenGroup returns -1 if failed or an id if succeeded // sendToOpenGroup returns -1 if failed or an id if succeeded
if (result < 0) { if (result.serverId < 0) {
this.events.emit('fail', message, error); this.events.emit('fail', message, error);
} else { } else {
const messageEventData = { const messageEventData = {
pubKey: message.group.groupId, pubKey: message.group.groupId,
timestamp: message.timestamp, timestamp: message.timestamp,
serverId: result, serverId: result.serverId,
serverTimestamp: result.serverTimestamp,
}; };
this.events.emit('success', message); this.events.emit('success', message);

@ -98,7 +98,7 @@ function wrapEnvelope(envelope: SignalService.Envelope): Uint8Array {
*/ */
export async function sendToOpenGroup( export async function sendToOpenGroup(
message: OpenGroupMessage message: OpenGroupMessage
): Promise<number> { ): Promise<{ serverId: number; serverTimestamp: number }> {
/* /*
Note: Retrying wasn't added to this but it can be added in the future if needed. Note: Retrying wasn't added to this but it can be added in the future if needed.
The only problem is that `channelAPI.sendMessage` returns true/false and doesn't throw any error so we can never be sure why sending failed. The only problem is that `channelAPI.sendMessage` returns true/false and doesn't throw any error so we can never be sure why sending failed.
@ -112,7 +112,7 @@ export async function sendToOpenGroup(
); );
if (!channelAPI) { if (!channelAPI) {
return -1; return { serverId: -1, serverTimestamp: -1 };
} }
// Returns -1 on fail or an id > 0 on success // Returns -1 on fail or an id > 0 on success

@ -321,12 +321,12 @@ describe('MessageQueue', () => {
describe('open groups', async () => { describe('open groups', async () => {
let sendToOpenGroupStub: sinon.SinonStub< let sendToOpenGroupStub: sinon.SinonStub<
[OpenGroupMessage], [OpenGroupMessage],
Promise<number> Promise<{ serverId: number; serverTimestamp: number }>
>; >;
beforeEach(() => { beforeEach(() => {
sendToOpenGroupStub = sandbox sendToOpenGroupStub = sandbox
.stub(MessageSender, 'sendToOpenGroup') .stub(MessageSender, 'sendToOpenGroup')
.resolves(-1); .resolves({ serverId: -1, serverTimestamp: -1 });
}); });
it('can send to open group', async () => { it('can send to open group', async () => {
@ -336,7 +336,7 @@ describe('MessageQueue', () => {
}); });
it('should emit a success event when send was successful', async () => { it('should emit a success event when send was successful', async () => {
sendToOpenGroupStub.resolves(123456); sendToOpenGroupStub.resolves({ serverId: -1, serverTimestamp: -1 });
const message = TestUtils.generateOpenGroupMessage(); const message = TestUtils.generateOpenGroupMessage();
const eventPromise = PromiseUtils.waitForTask(complete => { const eventPromise = PromiseUtils.waitForTask(complete => {
@ -348,7 +348,7 @@ describe('MessageQueue', () => {
}); });
it('should emit a fail event if something went wrong', async () => { it('should emit a fail event if something went wrong', async () => {
sendToOpenGroupStub.resolves(-1); sendToOpenGroupStub.resolves({ serverId: -1, serverTimestamp: -1 });
const message = TestUtils.generateOpenGroupMessage(); const message = TestUtils.generateOpenGroupMessage();
const eventPromise = PromiseUtils.waitForTask(complete => { const eventPromise = PromiseUtils.waitForTask(complete => {
messageQueueStub.events.once('fail', complete); messageQueueStub.events.once('fail', complete);

Loading…
Cancel
Save