pleroma-fe/src/services/chat_service/chat_service.js
eugenijm f05f832bff Address feedback
Use more specific css rules for the emoji dimensions in the chat list status preview.

Use more round em value for chat list item height.
Add global html overflow and height for smoother chat navigation in
the desktop Safari.

Use offsetHeight instad of a computed style when setting the window height on resize.

Remove margin-bottom from the last message to avoid occasional layout shift in the desktop Safari

Use break-word to prevent chat message text overflow

Resize and scroll the textarea when inserting a new line on ctrl+enter

Remove fade transition on route change

Ensure proper border radius at the bottom of the chat, remove unused border-radius

Prevent the chat header "jumping" on the avatar load.
2020-07-08 15:21:31 +03:00

152 lines
3.6 KiB
JavaScript

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