diff options
| author | Henry Jameson <me@hjkos.com> | 2021-02-01 19:39:57 +0200 |
|---|---|---|
| committer | Henry Jameson <me@hjkos.com> | 2021-02-01 19:39:57 +0200 |
| commit | 8958f386bef9317ff5782fa0f16164d7fbc2af21 (patch) | |
| tree | 8c33fed5331c18023d608fbb366c464783559220 /src/services/chat_service/chat_service.js | |
| parent | e695506c514e49964dfd81c7db5c5b4d4918f47d (diff) | |
| parent | de66267a07eb018cc0309ff6f9dd896d53ba3ff4 (diff) | |
Merge remote-tracking branch 'origin/develop' into settings-changed
* origin/develop: (306 commits)
fallback if shadows aren't defined
Translated using Weblate (Chinese (Traditional))
Translated using Weblate (Ukrainian)
Translated using Weblate (Italian)
Translated using Weblate (Ukrainian)
Translated using Weblate (Portuguese)
Translated using Weblate (Italian)
Translated using Weblate (Russian)
Translated using Weblate (Portuguese)
Translated using Weblate (Russian)
Translated using Weblate (Portuguese)
Translated using Weblate (Portuguese)
Translated using Weblate (Portuguese)
Translated using Weblate (Portuguese)
Translated using Weblate (Portuguese)
Translated using Weblate (Portuguese)
Translated using Weblate (Portuguese)
Translated using Weblate (Portuguese)
Translated using Weblate (Portuguese)
Translated using Weblate (Portuguese)
...
Diffstat (limited to 'src/services/chat_service/chat_service.js')
| -rw-r--r-- | src/services/chat_service/chat_service.js | 77 |
1 files changed, 66 insertions, 11 deletions
diff --git a/src/services/chat_service/chat_service.js b/src/services/chat_service/chat_service.js index 95c69482..e653ebc1 100644 --- a/src/services/chat_service/chat_service.js +++ b/src/services/chat_service/chat_service.js @@ -3,9 +3,10 @@ import _ from 'lodash' const empty = (chatId) => { return { idIndex: {}, + idempotencyKeyIndex: {}, messages: [], newMessageCount: 0, - lastSeenTimestamp: 0, + lastSeenMessageId: '0', chatId: chatId, minId: undefined, maxId: undefined @@ -13,10 +14,20 @@ const empty = (chatId) => { } const clear = (storage) => { - storage.idIndex = {} - storage.messages.splice(0, storage.messages.length) + const failedMessageIds = [] + + for (const message of storage.messages) { + if (message.error) { + failedMessageIds.push(message.id) + } else { + delete storage.idIndex[message.id] + delete storage.idempotencyKeyIndex[message.idempotency_key] + } + } + + storage.messages = storage.messages.filter(m => failedMessageIds.includes(m.id)) storage.newMessageCount = 0 - storage.lastSeenTimestamp = 0 + storage.lastSeenMessageId = '0' storage.minId = undefined storage.maxId = undefined } @@ -37,6 +48,25 @@ const deleteMessage = (storage, messageId) => { } } +const handleMessageError = (storage, fakeId, isRetry) => { + if (!storage) { return } + const fakeMessage = storage.idIndex[fakeId] + if (fakeMessage) { + fakeMessage.error = true + fakeMessage.pending = false + if (!isRetry) { + // Ensure the failed message doesn't stay at the bottom of the list. + const lastPersistedMessage = _.orderBy(storage.messages, ['pending', 'id'], ['asc', 'desc'])[0] + if (lastPersistedMessage) { + const oldId = fakeMessage.id + fakeMessage.id = `${lastPersistedMessage.id}-${new Date().getTime()}` + storage.idIndex[fakeMessage.id] = fakeMessage + delete storage.idIndex[oldId] + } + } + } +} + const add = (storage, { messages: newMessages, updateMaxId = true }) => { if (!storage) { return } for (let i = 0; i < newMessages.length; i++) { @@ -45,7 +75,25 @@ const add = (storage, { messages: newMessages, updateMaxId = true }) => { // sanity check if (message.chat_id !== storage.chatId) { return } - if (!storage.minId || message.id < storage.minId) { + if (message.fakeId) { + const fakeMessage = storage.idIndex[message.fakeId] + if (fakeMessage) { + // In case the same id exists (chat update before POST response) + // make sure to remove the older duplicate message. + if (storage.idIndex[message.id]) { + delete storage.idIndex[message.id] + storage.messages = storage.messages.filter(msg => msg.id !== message.id) + } + Object.assign(fakeMessage, message, { error: false }) + delete fakeMessage['fakeId'] + storage.idIndex[fakeMessage.id] = fakeMessage + delete storage.idIndex[message.fakeId] + + return + } + } + + if (!storage.minId || (!message.pending && message.id < storage.minId)) { storage.minId = message.id } @@ -55,20 +103,26 @@ const add = (storage, { messages: newMessages, updateMaxId = true }) => { } } - if (!storage.idIndex[message.id]) { - if (storage.lastSeenTimestamp < message.created_at) { + if (!storage.idIndex[message.id] && !isConfirmation(storage, message)) { + if (storage.lastSeenMessageId < message.id) { storage.newMessageCount++ } - storage.messages.push(message) storage.idIndex[message.id] = message + storage.messages.push(storage.idIndex[message.id]) + storage.idempotencyKeyIndex[message.idempotency_key] = true } } } +const isConfirmation = (storage, message) => { + if (!message.idempotency_key) return + return storage.idempotencyKeyIndex[message.idempotency_key] +} + const resetNewMessageCount = (storage) => { if (!storage) { return } storage.newMessageCount = 0 - storage.lastSeenTimestamp = new Date() + storage.lastSeenMessageId = storage.maxId } // Inserts date separators and marks the head and tail if it's the chain of messages made by the same user @@ -76,7 +130,7 @@ const getView = (storage) => { if (!storage) { return [] } const result = [] - const messages = _.sortBy(storage.messages, ['id', 'desc']) + const messages = _.orderBy(storage.messages, ['pending', 'id'], ['asc', 'asc']) const firstMessage = messages[0] let previousMessage = messages[messages.length - 1] let currentMessageChainId @@ -148,7 +202,8 @@ const ChatService = { getView, deleteMessage, resetNewMessageCount, - clear + clear, + handleMessageError } export default ChatService |
