Respect last-chat header and make sure that messages are received to the correct token

Before the header was not respected and instead the last message id of the known
chat messages was used. This ment that when there were too many commands
which are not visible to the user, the chat would load for ever.

Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Joas Schilling 2020-01-30 14:59:51 +01:00
Родитель 583e812143
Коммит 27cfb82d8b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 7076EA9751AACDDA
3 изменённых файлов: 90 добавлений и 12 удалений

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

@ -309,6 +309,16 @@ export default {
handleStartGettingMessagesPreconditions() {
if (this.token && this.isParticipant && !this.isInLobby) {
if (this.$store.getters.getFirstKnownMessageId(this.token) === null) {
this.$store.dispatch('setFirstKnownMessageId', {
token: this.token,
id: this.conversation.lastReadMessage,
})
this.$store.dispatch('setLastKnownMessageId', {
token: this.token,
id: this.conversation.lastReadMessage,
})
}
this.getMessages()
} else {
this.cancelLookForNewMessages()
@ -321,7 +331,7 @@ export default {
*/
async getMessages() {
// Gets the history of the conversation.
await this.getOldMessages()
await this.getOldMessages(true)
// Once the history is loaded, scroll to bottom
this.scrollToBottom()
// Once the history is received, startslooking for new messages.
@ -337,11 +347,9 @@ export default {
/**
* Get messages history.
* @param {int} lastKnownMessageId The id of the last known messages.
* @param {int} includeLastKnown Include or exclude the last known message in the response.
* (0 for exclude, 1 for include)
* @param {boolean} includeLastKnown Include or exclude the last known message in the response
*/
async getOldMessages(lastKnownMessageId, includeLastKnown) {
async getOldMessages(includeLastKnown) {
/**
* Clear previous requests if there's one pending
*/
@ -353,7 +361,9 @@ export default {
this.cancelFetchMessages = cancel
// Make the request
try {
const messages = await request({ token: this.token, lastKnownMessageId, includeLastKnown })
const token = this.token
const lastKnownMessageId = this.$store.getters.getFirstKnownMessageId(token)
const messages = await request({ token, lastKnownMessageId, includeLastKnown: includeLastKnown ? '1' : '0' })
// Process each messages and adds it to the store
messages.data.ocs.data.forEach(message => {
if (message.actorType === 'guests') {
@ -361,6 +371,13 @@ export default {
}
this.$store.dispatch('processMessage', message)
})
if (messages.headers['x-chat-last-given']) {
this.$store.dispatch('setFirstKnownMessageId', {
token: token,
id: messages.headers['x-chat-last-given'],
})
}
} catch (exception) {
if (Axios.isCancel(exception)) {
console.debug('The request has been canceled', exception)
@ -379,10 +396,12 @@ export default {
// Assign the new cancel function to our data value
this.cancelLookForNewMessages = cancel
// Get the last message's id
const lastKnownMessageId = this.getLastKnownMessageId()
const token = this.token
const lastKnownMessageId = this.$store.getters.getLastKnownMessageId(token)
// Make the request
try {
const messages = await request({ token: this.token, lastKnownMessageId })
const messages = await request({ token, lastKnownMessageId })
// Process each messages and adds it to the store
messages.data.ocs.data.forEach(message => {
if (message.actorType === 'guests') {
@ -390,6 +409,12 @@ export default {
}
this.$store.dispatch('processMessage', message)
})
this.$store.dispatch('setLastKnownMessageId', {
token: token,
id: messages.headers['x-chat-last-given'],
})
// Scroll to the last message if sticky
if (this.isSticky) {
this.scrollToBottom()
@ -438,11 +463,10 @@ export default {
this.displayMessagesLoader = false
this.previousScrollTopValue = scrollTop
} else if (scrollHeight > elementHeight && scrollTop < 800 && scrollTop <= this.previousScrollTopValue) {
const firstMessageId = this.getFirstKnownMessageId()
if (scrollTop === 0) {
this.displayMessagesLoader = true
}
await this.getOldMessages(firstMessageId)
await this.getOldMessages(false)
this.displayMessagesLoader = false
this.previousScrollTopValue = scrollTop
} else {

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

@ -44,7 +44,7 @@ const fetchMessages = async function({ token, lastKnownMessageId, includeLastKno
* @param {int} lastKnownMessageId The id of the last message in the store.
*/
const lookForNewMessages = async({ token, lastKnownMessageId }, options) => {
const response = await axios.get(generateOcsUrl('apps/spreed/api/v1/chat', 2) + token + '?lookIntoFuture=1' + '&includeLastKnown=0' + `&lastKnownMessageId=${lastKnownMessageId}`, options)
const response = await axios.get(generateOcsUrl('apps/spreed/api/v1/chat', 2) + token + '?lookIntoFuture=1' + `&lastKnownMessageId=${lastKnownMessageId}` + '&includeLastKnown=0', options)
return response
}

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

@ -24,6 +24,10 @@ import Vue from 'vue'
const state = {
messages: {
},
firstKnown: {
},
lastKnown: {
},
}
const getters = {
@ -63,6 +67,20 @@ const getters = {
}
return {}
},
getFirstKnownMessageId: (state) => (token) => {
if (state.firstKnown[token]) {
return state.firstKnown[token]
}
return null
},
getLastKnownMessageId: (state) => (token) => {
if (state.lastKnown[token]) {
return state.lastKnown[token]
}
return null
},
}
const mutations = {
@ -99,6 +117,24 @@ const mutations = {
addTemporaryMessage(state, message) {
Vue.set(state.messages[message.token], message.id, message)
},
/**
* @param {object} state current store state;
* @param {string} token Token of the conversation
* @param {string} id Id of the first known chat message
*/
setFirstKnownMessageId(state, { token, id }) {
Vue.set(state.firstKnown, token, id)
},
/**
* @param {object} state current store state;
* @param {string} token Token of the conversation
* @param {string} id Id of the last known chat message
*/
setLastKnownMessageId(state, { token, id }) {
Vue.set(state.lastKnown, token, id)
},
}
const actions = {
@ -133,7 +169,7 @@ const actions = {
/**
* Add a temporary message generated in the client to
* the store, these messages are deleted once the full
* message object is recived from the server.
* message object is received from the server.
*
* @param {object} context default store context;
* @param {object} message the temporary message;
@ -141,6 +177,24 @@ const actions = {
addTemporaryMessage(context, message) {
context.commit('addTemporaryMessage', message)
},
/**
* @param {object} context default store context;
* @param {string} token Token of the conversation
* @param {string} id Id of the first known chat message
*/
setFirstKnownMessageId(context, { token, id }) {
context.commit('setFirstKnownMessageId', { token, id })
},
/**
* @param {object} context default store context;
* @param {string} token Token of the conversation
* @param {string} id Id of the last known chat message
*/
setLastKnownMessageId(context, { token, id }) {
context.commit('setLastKnownMessageId', { token, id })
},
}
export default { state, mutations, getters, actions }