зеркало из https://github.com/nextcloud/spreed.git
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:
Родитель
e5bfb5753c
Коммит
15c6b7cb68
|
@ -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 }
|
||||
|
|
Загрузка…
Ссылка в новой задаче