Move postNewMessage to a store action

Removes the store usage in messagesService

Signed-off-by: Vincent Petry <vincent@nextcloud.com>
This commit is contained in:
Vincent Petry 2021-04-28 10:49:20 +02:00
Родитель e5bfb5753c
Коммит 15c6b7cb68
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: E055D6A4D513575C
3 изменённых файлов: 117 добавлений и 85 удалений

Просмотреть файл

@ -116,8 +116,7 @@
<script>
import AdvancedInput from './AdvancedInput/AdvancedInput'
import { getFilePickerBuilder, showError } from '@nextcloud/dialogs'
import { postNewMessage } from '../../services/messagesService'
import { getFilePickerBuilder } from '@nextcloud/dialogs'
import { getCapabilities } from '@nextcloud/capabilities'
import Quote from '../Quote'
import Actions from '@nextcloud/vue/dist/Components/Actions'
@ -128,7 +127,6 @@ import { shareFile } from '../../services/filesSharingServices'
import { CONVERSATION } from '../../constants'
import EmoticonOutline from 'vue-material-design-icons/EmoticonOutline'
import Send from 'vue-material-design-icons/Send'
import CancelableRequest from '../../utils/cancelableRequest'
const picker = getFilePickerBuilder(t('spreed', 'File to share'))
.setMultiSelect(false)
@ -322,76 +320,7 @@ export default {
EventBus.$emit('smoothScrollChatToBottom')
// Also remove the message to be replied for this conversation
this.$store.dispatch('removeMessageToBeReplied', this.token)
let timeout
try {
// Posts the message to the server
const { request, cancel } = CancelableRequest(postNewMessage)
timeout = setTimeout(() => {
cancel('canceled')
this.$store.dispatch('markTemporaryMessageAsFailed', {
message: temporaryMessage,
reason: 'timeout',
})
}, 30000)
const response = await request(temporaryMessage)
clearTimeout(timeout)
// If successful, deletes the temporary message from the store
this.$store.dispatch('removeTemporaryMessageFromStore', temporaryMessage)
const message = response.data.ocs.data
// And adds the complete version of the message received
// by the server
this.$store.dispatch('processMessage', message)
// update lastMessage and lastReadMessage
// do it conditionally because there could have been more messages appearing concurrently
if (this.conversation.lastMessage && message.id > this.conversation.lastMessage.id) {
this.$store.dispatch('updateConversationLastMessage', {
token: this.token,
lastMessage: message,
})
}
if (message.id > this.conversation.lastReadMessage) {
this.$store.dispatch('updateLastReadMessage', {
token: this.token,
id: message.id,
updateVisually: true,
})
}
} catch (error) {
let statusCode = null
console.debug(`error while submitting message ${error}`, error)
if (error.isAxiosError) {
statusCode = error?.response?.status
}
if (timeout) {
clearTimeout(timeout)
}
// 403 when room is read-only, 412 when switched to lobby mode
if (statusCode === 403) {
showError(t('spreed', 'No permission to post messages in this conversation'))
this.$store.dispatch('markTemporaryMessageAsFailed', {
message: temporaryMessage,
reason: 'read-only',
})
} else if (statusCode === 412) {
showError(t('spreed', 'No permission to post messages in this conversation'))
this.$store.dispatch('markTemporaryMessageAsFailed', {
message: temporaryMessage,
reason: 'lobby',
})
} else {
showError(t('spreed', 'Could not post message: {errorMessage}', { errorMessage: error.message || error }))
this.$store.dispatch('markTemporaryMessageAsFailed', {
message: temporaryMessage,
reason: 'other',
})
}
}
await this.$store.dispatch('postNewMessage', temporaryMessage)
}
},

Просмотреть файл

@ -22,7 +22,6 @@
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
import store from '../store/index'
import SHA1 from 'crypto-js/sha1'
import Hex from 'crypto-js/enc-hex'
@ -76,22 +75,12 @@ const lookForNewMessages = async({ token, lastKnownMessageId }, options) => {
* @param {object} options request options
*/
const postNewMessage = async function({ token, message, actorDisplayName, referenceId, parent }, options) {
const response = await axios.post(generateOcsUrl('apps/spreed/api/v1/chat', 2) + token, {
return axios.post(generateOcsUrl('apps/spreed/api/v1/chat', 2) + token, {
message,
actorDisplayName,
referenceId,
replyTo: parent,
}, options)
if ('x-chat-last-common-read' in response.headers) {
const lastCommonReadMessage = parseInt(response.headers['x-chat-last-common-read'], 10)
store.dispatch('updateLastCommonReadMessage', {
token,
lastCommonReadMessage,
})
}
return response
}
/**

Просмотреть файл

@ -25,11 +25,13 @@ import {
updateLastReadMessage,
fetchMessages,
lookForNewMessages,
postNewMessage,
} from '../services/messagesService'
import SHA1 from 'crypto-js/sha1'
import Hex from 'crypto-js/enc-hex'
import CancelableRequest from '../utils/cancelableRequest'
import { showError } from '@nextcloud/dialogs'
const state = {
/**
@ -62,6 +64,10 @@ const state = {
* messages before making another one.
*/
cancelLookForNewMessages: null,
/**
* Stores the cancel function for the "postNewMessage" action
*/
cancelPostNewMessage: null,
}
const getters = {
@ -144,6 +150,10 @@ const mutations = {
state.cancelLookForNewMessages = cancelFunction
},
setCancelPostNewMessage(state, cancelFunction) {
state.cancelPostNewMessage = cancelFunction
},
/**
* Adds a message to the store.
* @param {object} state current store state;
@ -640,6 +650,110 @@ const actions = {
}
return false
},
async postNewMessage(context, temporaryMessage) {
const { request, cancel } = CancelableRequest(postNewMessage)
context.commit('setCancelPostNewMessage', cancel)
const timeout = setTimeout(() => {
context.dispatch('cancelPostNewMessage')
context.dispatch('markTemporaryMessageAsFailed', {
message: temporaryMessage,
reason: 'timeout',
})
}, 30000)
try {
const response = await request(temporaryMessage)
clearTimeout(timeout)
if ('x-chat-last-common-read' in response.headers) {
const lastCommonReadMessage = parseInt(response.headers['x-chat-last-common-read'], 10)
context.dispatch('updateLastCommonReadMessage', {
token: temporaryMessage.token,
lastCommonReadMessage,
})
}
// If successful, deletes the temporary message from the store
context.dispatch('removeTemporaryMessageFromStore', temporaryMessage)
const message = response.data.ocs.data
// And adds the complete version of the message received
// by the server
context.dispatch('processMessage', message)
const conversation = context.getters.conversation(temporaryMessage.token)
// update lastMessage and lastReadMessage
// do it conditionally because there could have been more messages appearing concurrently
if (conversation && conversation.lastMessage && message.id > conversation.lastMessage.id) {
context.dispatch('updateConversationLastMessage', {
token: conversation.token,
lastMessage: message,
})
}
if (conversation && message.id > conversation.lastReadMessage) {
context.dispatch('updateLastReadMessage', {
token: conversation.token,
id: message.id,
updateVisually: true,
})
}
return response
} catch (error) {
if (timeout) {
clearTimeout(timeout)
}
let statusCode = null
console.debug(`error while submitting message ${error}`, error)
if (error.isAxiosError) {
statusCode = error?.response?.status
}
// FIXME: don't use showError here but set a flag
// somewhere that makes Vue trigger the error message
// 403 when room is read-only, 412 when switched to lobby mode
if (statusCode === 403) {
showError(t('spreed', 'No permission to post messages in this conversation'))
context.dispatch('markTemporaryMessageAsFailed', {
message: temporaryMessage,
reason: 'read-only',
})
} else if (statusCode === 412) {
showError(t('spreed', 'No permission to post messages in this conversation'))
context.dispatch('markTemporaryMessageAsFailed', {
message: temporaryMessage,
reason: 'lobby',
})
} else {
showError(t('spreed', 'Could not post message: {errorMessage}', { errorMessage: error.message || error }))
context.dispatch('markTemporaryMessageAsFailed', {
message: temporaryMessage,
reason: 'other',
})
}
throw error
}
},
/**
* Cancels a previously running "postNewMessage" action if applicable.
*
* @param {object} context default store context;
* @returns {bool} true if a request got cancelled, false otherwise
*/
cancelPostNewMessage(context) {
if (context.state.cancelPostNewMessage) {
context.state.cancelPostNewMessage('canceled')
context.commit('setCancelPostNewMessage', null)
return true
}
return false
},
}
export default { state, mutations, getters, actions }