pleroma-fe/src/modules/chats.js
2026-07-08 17:47:50 +03:00

173 lines
4.9 KiB
JavaScript

import { find, omitBy, orderBy, sumBy } from 'lodash'
import { reactive } from 'vue'
import chatService from '../services/chat_service/chat_service.js'
import { maybeShowChatNotification } from '../services/chat_utils/chat_utils.js'
import { promiseInterval } from '../services/promise_interval/promise_interval.js'
import { useOAuthStore } from 'src/stores/oauth.js'
import { chats, deleteChatMessage } from 'src/api/chats.js'
const emptyChatList = () => ({
data: [],
idStore: {},
})
const defaultState = {
chatList: emptyChatList(),
chatListFetcher: null,
fetcher: undefined,
currentChatId: null,
lastReadMessageId: null,
}
const getChatById = (state, id) => {
return find(state.chatList.data, { id })
}
const sortedChatList = (state) => {
return orderBy(state.chatList.data, ['updated_at'], ['desc'])
}
const unreadChatCount = (state) => {
return sumBy(state.chatList.data, 'unread')
}
const chatsModule = {
state: { ...defaultState },
getters: {
sortedChatList,
unreadChatCount,
},
actions: {
// Chat list
startFetchingChats({ dispatch, commit }) {
const fetcher = () => dispatch('fetchChats', { latest: true })
commit('setChatListFetcher', {
fetcher: () => promiseInterval(fetcher, 5000),
})
},
stopFetchingChats({ commit }) {
commit('setChatListFetcher', { fetcher: undefined })
},
fetchChats({ dispatch, rootState }) {
return chats({
credentials: useOAuthStore().token,
}).then(({ data }) => {
dispatch('addNewChats', { chats: data })
return chats
})
},
addNewChats(store, { chats }) {
const { commit, dispatch, rootGetters } = store
const newChatMessageSideEffects = (chat) => {
maybeShowChatNotification(store, chat)
}
commit(
'addNewUsers',
chats.map((k) => k.account).filter((k) => k),
)
commit('addNewChats', {
dispatch,
chats,
rootGetters,
newChatMessageSideEffects,
})
},
// Opened Chats
addOpenedChat({ commit, dispatch }, { chat }) {
commit('addOpenedChat', { dispatch, chat })
dispatch('addNewUsers', [chat.account])
},
addChatMessages({ commit }, value) {
commit('addChatMessages', { commit, ...value })
},
deleteChatMessage({ rootState, commit }, value) {
deleteChatMessage({
...value,
credentials: useOAuthStore().token,
})
commit('deleteChatMessage', { commit, ...value })
},
resetChats({ commit, dispatch }) {
commit('resetChats', { commit })
},
clearOpenedChats({ commit }) {
commit('clearOpenedChats', { commit })
},
handleMessageError({ commit }, value) {
commit('handleMessageError', { commit, ...value })
},
},
mutations: {
setChatListFetcher(state, { fetcher }) {
const prevFetcher = state.chatListFetcher
if (prevFetcher) {
prevFetcher.stop()
}
state.chatListFetcher = fetcher && fetcher()
},
setCurrentChatId(state, { chatId }) {
state.currentChatId = chatId
},
addNewChats(state, { chats, newChatMessageSideEffects }) {
chats.forEach((updatedChat) => {
const chat = getChatById(state, updatedChat.id)
if (chat) {
const isNewMessage =
(chat.lastMessage && chat.lastMessage.id) !==
(updatedChat.lastMessage && updatedChat.lastMessage.id)
chat.lastMessage = updatedChat.lastMessage
chat.unread = updatedChat.unread
chat.updated_at = updatedChat.updated_at
if (isNewMessage && chat.unread) {
newChatMessageSideEffects(updatedChat)
}
} else {
state.chatList.data.push(updatedChat)
state.chatList.idStore[updatedChat.id] = updatedChat
}
})
},
updateChat(state, { chat: updatedChat }) {
const chat = getChatById(state, updatedChat.id)
if (chat) {
chat.lastMessage = updatedChat.lastMessage
chat.unread = updatedChat.unread
chat.updated_at = updatedChat.updated_at
}
if (!chat) {
state.chatList.data.unshift(updatedChat)
}
state.chatList.idStore[updatedChat.id] = updatedChat
},
deleteChat(state, { id }) {
state.chats.data = state.chats.data.filter(
(conversation) => conversation.last_status.id !== id,
)
state.chats.idStore = omitBy(
state.chats.idStore,
(conversation) => conversation.last_status.id === id,
)
},
resetChats(state, { commit }) {
state.chatList = emptyChatList()
state.currentChatId = null
commit('setChatListFetcher', { fetcher: undefined })
},
setChatsLoading(state, { value }) {
state.chats.loading = value
},
readChat(state, { id, lastReadId }) {
const chat = getChatById(state, id)
if (chat) {
chat.unread = 0
}
},
},
}
export default chatsModule