diff options
| author | HJ <30-hj@users.noreply.git.pleroma.social> | 2020-07-10 09:04:45 +0000 |
|---|---|---|
| committer | HJ <30-hj@users.noreply.git.pleroma.social> | 2020-07-10 09:04:45 +0000 |
| commit | c1a20079bef51dc38cb9826cee5bb2fbfe2cf68b (patch) | |
| tree | deed4aa330bcc8b983855df3a24c23ddb4bfeeb8 /src/services/chat_service/chat_service.js | |
| parent | d2f0e4e7d515afe4b15d4e6a0e52d9fee2349c4a (diff) | |
| parent | b756c83e8d275c0f9d210c15a319d36dca56d3c8 (diff) | |
Merge branch 'direct-conversations' into 'develop'
Chats
Closes #201
See merge request pleroma/pleroma-fe!1019
Diffstat (limited to 'src/services/chat_service/chat_service.js')
| -rw-r--r-- | src/services/chat_service/chat_service.js | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/services/chat_service/chat_service.js b/src/services/chat_service/chat_service.js new file mode 100644 index 00000000..b60a889b --- /dev/null +++ b/src/services/chat_service/chat_service.js @@ -0,0 +1,151 @@ +import _ from 'lodash' + +const empty = (chatId) => { + return { + idIndex: {}, + messages: [], + newMessageCount: 0, + lastSeenTimestamp: 0, + chatId: chatId, + minId: undefined, + lastMessage: undefined + } +} + +const clear = (storage) => { + storage.idIndex = {} + storage.messages.splice(0, storage.messages.length) + storage.newMessageCount = 0 + storage.lastSeenTimestamp = 0 + storage.minId = undefined + storage.lastMessage = undefined +} + +const deleteMessage = (storage, messageId) => { + if (!storage) { return } + storage.messages = storage.messages.filter(m => m.id !== messageId) + delete storage.idIndex[messageId] + + if (storage.lastMessage && (storage.lastMessage.id === messageId)) { + storage.lastMessage = _.maxBy(storage.messages, 'id') + } + + if (storage.minId === messageId) { + const firstMessage = _.minBy(storage.messages, 'id') + storage.minId = firstMessage.id + } +} + +const add = (storage, { messages: newMessages }) => { + if (!storage) { return } + for (let i = 0; i < newMessages.length; i++) { + const message = newMessages[i] + + // sanity check + if (message.chat_id !== storage.chatId) { return } + + if (!storage.minId || message.id < storage.minId) { + storage.minId = message.id + } + + if (!storage.lastMessage || message.id > storage.lastMessage.id) { + storage.lastMessage = message + } + + if (!storage.idIndex[message.id]) { + if (storage.lastSeenTimestamp < message.created_at) { + storage.newMessageCount++ + } + storage.messages.push(message) + storage.idIndex[message.id] = message + } + } +} + +const resetNewMessageCount = (storage) => { + if (!storage) { return } + storage.newMessageCount = 0 + storage.lastSeenTimestamp = new Date() +} + +// Inserts date separators and marks the head and tail if it's the chain of messages made by the same user +const getView = (storage) => { + if (!storage) { return [] } + + const result = [] + const messages = _.sortBy(storage.messages, ['id', 'desc']) + const firstMessage = messages[0] + let previousMessage = messages[messages.length - 1] + let currentMessageChainId + + if (firstMessage) { + const date = new Date(firstMessage.created_at) + date.setHours(0, 0, 0, 0) + result.push({ + type: 'date', + date, + id: date.getTime().toString() + }) + } + + let afterDate = false + + for (let i = 0; i < messages.length; i++) { + const message = messages[i] + const nextMessage = messages[i + 1] + + const date = new Date(message.created_at) + date.setHours(0, 0, 0, 0) + + // insert date separator and start a new message chain + if (previousMessage && previousMessage.date < date) { + result.push({ + type: 'date', + date, + id: date.getTime().toString() + }) + + previousMessage['isTail'] = true + currentMessageChainId = undefined + afterDate = true + } + + const object = { + type: 'message', + data: message, + date, + id: message.id, + messageChainId: currentMessageChainId + } + + // end a message chian + if ((nextMessage && nextMessage.account_id) !== message.account_id) { + object['isTail'] = true + currentMessageChainId = undefined + } + + // start a new message chain + if ((previousMessage && previousMessage.data && previousMessage.data.account_id) !== message.account_id || afterDate) { + currentMessageChainId = _.uniqueId() + object['isHead'] = true + object['messageChainId'] = currentMessageChainId + } + + result.push(object) + previousMessage = object + afterDate = false + } + + return result +} + +const ChatService = { + add, + empty, + getView, + deleteMessage, + resetNewMessageCount, + clear +} + +export default ChatService |
