diff options
Diffstat (limited to 'src/store/sharedItemsStore.js')
-rw-r--r-- | src/store/sharedItemsStore.js | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/src/store/sharedItemsStore.js b/src/store/sharedItemsStore.js new file mode 100644 index 000000000..b5ce88754 --- /dev/null +++ b/src/store/sharedItemsStore.js @@ -0,0 +1,170 @@ +/** + * @copyright Copyright (c) 2022 Marco Ambrosini <marcoambrosini@pm.me> + * + * @author Marco Ambrosini <marcoambrosini@pm.me> + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +import Vue from 'vue' +import { getSharedItemsOverview, getSharedItems } from '../services/sharedItemsService' +import { SHARED_ITEM } from '../constants' + +const getItemTypeFromMessage = function(message) { + if (message.message === '{object}') { + if (message.messageParameters.object.type === 'geo-location') { + return SHARED_ITEM.TYPES.LOCATION + } else if (message.messageParameters.object.type === 'deck-card') { + return SHARED_ITEM.TYPES.DECK_CARD + } else { + return SHARED_ITEM.TYPES.OTHER + } + } else { + const messageType = message.messageType || '' + const mimetype = message.messageParameters.file?.mimetype || '' + + if (messageType === 'voice-message') { + return SHARED_ITEM.TYPES.VOICE + } else if (mimetype.startsWith('audio/')) { + return SHARED_ITEM.TYPES.AUDIO + } else if (mimetype.startsWith('image/') || mimetype.startsWith('video/')) { + return SHARED_ITEM.TYPES.MEDIA + } else { + return SHARED_ITEM.TYPES.FILE + } + } +} + +// sharedItemsByConversationAndType structure +// token: { +// media: {}, +// file: {}, +// voice: {}, +// audio: {}, +// location: {} +// deckcard: {}, +// other: {}, +// }, + +const state = { + sharedItemsByConversationAndType: {}, + overviewLoaded: {}, +} + +const getters = { + sharedItems: state => token => { + const sharedItems = {} + if (!state.sharedItemsByConversationAndType[token]) { + return {} + } + for (const type of Object.keys(state.sharedItemsByConversationAndType[token])) { + if (Object.keys(state.sharedItemsByConversationAndType[token][type]).length !== 0) { + sharedItems[type] = state.sharedItemsByConversationAndType[token][type] + } + } + return sharedItems + }, +} + +export const mutations = { + addSharedItemsOverview: (state, { token, data }) => { + Vue.set(state.overviewLoaded, token, true) + + if (!state.sharedItemsByConversationAndType[token]) { + Vue.set(state.sharedItemsByConversationAndType, token, {}) + } + + for (const type of Object.keys(data)) { + if (!state.sharedItemsByConversationAndType[token][type]) { + Vue.set(state.sharedItemsByConversationAndType[token], type, {}) + } + + for (const message of data[type]) { + Vue.set(state.sharedItemsByConversationAndType[token][type], message.id, message) + } + } + }, + + addSharedItemMessage: (state, { token, type, message }) => { + if (!state.sharedItemsByConversationAndType[token]) { + Vue.set(state.sharedItemsByConversationAndType, token, {}) + } + if (!state.sharedItemsByConversationAndType[token][type]) { + Vue.set(state.sharedItemsByConversationAndType[token], type, {}) + } + if (!state.sharedItemsByConversationAndType[token][type]?.[message.id]) { + Vue.set(state.sharedItemsByConversationAndType[token][type], message.id, message) + } + }, +} + +const actions = { + async getSharedItems({ commit, state }, { token, type }) { + if (!state.sharedItemsByConversationAndType[token] + || !state.sharedItemsByConversationAndType[token][type]) { + console.error('Missing overview for shared items in ', token) + return false + } + + const limit = 20 + const lastKnownMessageId = Math.min.apply(Math, Object.keys(state.sharedItemsByConversationAndType[token][type])) + try { + const response = await getSharedItems(token, type, lastKnownMessageId, limit) + const messages = response.data.ocs.data + const hasMore = messages.length >= limit + // loop over the response elements and add them to the store + for (const message in messages) { + + commit('addSharedItemMessage', { + token, + type, + message: messages[message], + }) + } + return hasMore + } catch (error) { + console.error(error) + return false + } + }, + + async getSharedItemsOverview({ commit, state }, { token }) { + if (state.overviewLoaded[token]) { + return + } + + try { + const response = await getSharedItemsOverview(token, 7) + commit('addSharedItemsOverview', { + token, + data: response.data.ocs.data, + }) + } catch (error) { + console.error(error) + } + }, + + async addSharedItemMessage({ commit }, { message }) { + commit('addSharedItemMessage', { + token: message.token, + type: getItemTypeFromMessage(message), + message, + }) + }, +} + +export default { state, mutations, getters, actions } |