зеркало из 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>
|
<script>
|
||||||
import AdvancedInput from './AdvancedInput/AdvancedInput'
|
import AdvancedInput from './AdvancedInput/AdvancedInput'
|
||||||
import { getFilePickerBuilder, showError } from '@nextcloud/dialogs'
|
import { getFilePickerBuilder } from '@nextcloud/dialogs'
|
||||||
import { postNewMessage } from '../../services/messagesService'
|
|
||||||
import { getCapabilities } from '@nextcloud/capabilities'
|
import { getCapabilities } from '@nextcloud/capabilities'
|
||||||
import Quote from '../Quote'
|
import Quote from '../Quote'
|
||||||
import Actions from '@nextcloud/vue/dist/Components/Actions'
|
import Actions from '@nextcloud/vue/dist/Components/Actions'
|
||||||
|
@ -128,7 +127,6 @@ import { shareFile } from '../../services/filesSharingServices'
|
||||||
import { CONVERSATION } from '../../constants'
|
import { CONVERSATION } from '../../constants'
|
||||||
import EmoticonOutline from 'vue-material-design-icons/EmoticonOutline'
|
import EmoticonOutline from 'vue-material-design-icons/EmoticonOutline'
|
||||||
import Send from 'vue-material-design-icons/Send'
|
import Send from 'vue-material-design-icons/Send'
|
||||||
import CancelableRequest from '../../utils/cancelableRequest'
|
|
||||||
|
|
||||||
const picker = getFilePickerBuilder(t('spreed', 'File to share'))
|
const picker = getFilePickerBuilder(t('spreed', 'File to share'))
|
||||||
.setMultiSelect(false)
|
.setMultiSelect(false)
|
||||||
|
@ -322,76 +320,7 @@ export default {
|
||||||
EventBus.$emit('smoothScrollChatToBottom')
|
EventBus.$emit('smoothScrollChatToBottom')
|
||||||
// Also remove the message to be replied for this conversation
|
// Also remove the message to be replied for this conversation
|
||||||
this.$store.dispatch('removeMessageToBeReplied', this.token)
|
this.$store.dispatch('removeMessageToBeReplied', this.token)
|
||||||
let timeout
|
await this.$store.dispatch('postNewMessage', temporaryMessage)
|
||||||
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',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import { generateOcsUrl } from '@nextcloud/router'
|
import { generateOcsUrl } from '@nextcloud/router'
|
||||||
import store from '../store/index'
|
|
||||||
import SHA1 from 'crypto-js/sha1'
|
import SHA1 from 'crypto-js/sha1'
|
||||||
import Hex from 'crypto-js/enc-hex'
|
import Hex from 'crypto-js/enc-hex'
|
||||||
|
|
||||||
|
@ -76,22 +75,12 @@ const lookForNewMessages = async({ token, lastKnownMessageId }, options) => {
|
||||||
* @param {object} options request options
|
* @param {object} options request options
|
||||||
*/
|
*/
|
||||||
const postNewMessage = async function({ token, message, actorDisplayName, referenceId, parent }, 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,
|
message,
|
||||||
actorDisplayName,
|
actorDisplayName,
|
||||||
referenceId,
|
referenceId,
|
||||||
replyTo: parent,
|
replyTo: parent,
|
||||||
}, options)
|
}, 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,
|
updateLastReadMessage,
|
||||||
fetchMessages,
|
fetchMessages,
|
||||||
lookForNewMessages,
|
lookForNewMessages,
|
||||||
|
postNewMessage,
|
||||||
} from '../services/messagesService'
|
} from '../services/messagesService'
|
||||||
|
|
||||||
import SHA1 from 'crypto-js/sha1'
|
import SHA1 from 'crypto-js/sha1'
|
||||||
import Hex from 'crypto-js/enc-hex'
|
import Hex from 'crypto-js/enc-hex'
|
||||||
import CancelableRequest from '../utils/cancelableRequest'
|
import CancelableRequest from '../utils/cancelableRequest'
|
||||||
|
import { showError } from '@nextcloud/dialogs'
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
/**
|
/**
|
||||||
|
@ -62,6 +64,10 @@ const state = {
|
||||||
* messages before making another one.
|
* messages before making another one.
|
||||||
*/
|
*/
|
||||||
cancelLookForNewMessages: null,
|
cancelLookForNewMessages: null,
|
||||||
|
/**
|
||||||
|
* Stores the cancel function for the "postNewMessage" action
|
||||||
|
*/
|
||||||
|
cancelPostNewMessage: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
const getters = {
|
const getters = {
|
||||||
|
@ -144,6 +150,10 @@ const mutations = {
|
||||||
state.cancelLookForNewMessages = cancelFunction
|
state.cancelLookForNewMessages = cancelFunction
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setCancelPostNewMessage(state, cancelFunction) {
|
||||||
|
state.cancelPostNewMessage = cancelFunction
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a message to the store.
|
* Adds a message to the store.
|
||||||
* @param {object} state current store state;
|
* @param {object} state current store state;
|
||||||
|
@ -640,6 +650,110 @@ const actions = {
|
||||||
}
|
}
|
||||||
return false
|
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 }
|
export default { state, mutations, getters, actions }
|
||||||
|
|
Загрузка…
Ссылка в новой задаче