Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 33 additions & 22 deletions src/components/LeftSidebar/ConversationsList/Conversation.spec.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { createLocalVue, shallowMount, mount } from '@vue/test-utils'
import flushPromises from 'flush-promises' // TODO fix after migration to @vue/test-utils v2.0.0
import { cloneDeep } from 'lodash'
import VueRouter from 'vue-router'
import Vuex from 'vuex'

import { showSuccess, showError } from '@nextcloud/dialogs'

import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcListItem from '@nextcloud/vue/dist/Components/NcListItem.js'

import Conversation from './Conversation.vue'

import router from '../../../__mocks__/router.js'
import { CONVERSATION, PARTICIPANT, ATTENDEE } from '../../../constants.js'
import storeConfig from '../../../store/storeConfig.js'

Expand Down Expand Up @@ -274,7 +277,36 @@ describe('Conversation.vue', () => {
})
})

describe('actions', () => {
describe('actions (real router)', () => {
beforeEach(() => {
localVue.use(VueRouter)
})

test('change route on click event', async () => {
const wrapper = mount(Conversation, {
localVue,
router,
store,
stubs: {
NcListItem,
},
propsData: {
isSearchResult: false,
item,
},
})

const el = wrapper.findComponent({ name: 'NcListItem' })
expect(el.exists()).toBe(true)

await el.find('a').trigger('click')

expect(wrapper.vm.$route.name).toBe('conversation')
expect(wrapper.vm.$route.params).toStrictEqual({ token: TOKEN })
})
})

describe('actions (mock router)', () => {
let $router

beforeEach(() => {
Expand Down Expand Up @@ -321,27 +353,6 @@ describe('Conversation.vue', () => {
return findNcActionButton(el, actionName)
}

test('forwards click event on list item', async () => {
const wrapper = mount(Conversation, {
localVue,
store,
stubs: {
RouterLink: RouterLinkStub,
},
propsData: {
isSearchResult: false,
item,
},
})

const el = wrapper.findComponent({ name: 'NcListItem' })
expect(el.exists()).toBe(true)

await el.find('a').trigger('click')

expect(wrapper.emitted().click).toBeTruthy()
})

describe('leaving conversation', () => {
test('leaves conversation', async () => {
const actionHandler = jest.fn()
Expand Down
21 changes: 15 additions & 6 deletions src/components/LeftSidebar/ConversationsList/Conversation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
</NcActionButton>
</template>
<template v-else-if="item.token" #actions>
<NcActionButton close-after-click @click="onClick">
<NcActionButton close-after-click @click="onActionClick">
<template #icon>
<ArrowRight :size="16" />
</template>
Expand Down Expand Up @@ -180,8 +180,6 @@ export default {
},
},

emits: ['click'],

computed: {
counterType() {
if (this.item.unreadMentionDirect || (this.item.unreadMessages !== 0 && (
Expand Down Expand Up @@ -430,9 +428,20 @@ export default {
})
},

// forward click event
onClick(event) {
this.$emit('click', event)
onClick() {
// add as temporary item that will refresh after the joining process is complete
if (this.isSearchResult) {
this.$store.dispatch('addConversation', this.item)
}
},

onActionClick() {
this.onClick()
// NcActionButton is not a RouterLink, so we should route user manually
this.$router.push({
name: 'conversation',
params: { token: this.item.token },
}).catch(err => console.debug(`Error while pushing the new conversation's route: ${err}`))
},
},
}
Expand Down
3 changes: 3 additions & 0 deletions src/components/LeftSidebar/LeftSidebar.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,9 @@ describe('LeftSidebar.vue', () => {
expect(resultsListItems).toHaveLength(resultsList.length)

await resultsListItems.at(0).findAll('a').trigger('click')
// FIXME Real router and store should work at this place to execute following:
// click => route-change => participantsStore.joinConversation() => joined-conversation
EventBus.$emit('joined-conversation', { token: 'new-conversation' })
await flushPromises()

expect(searchBoxEl.exists()).toBeTruthy()
Expand Down
52 changes: 13 additions & 39 deletions src/components/LeftSidebar/LeftSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@
:title="t('spreed', 'Conversations')" />
<Conversation v-for="item of conversationsList"
:key="item.id"
:item="item"
@click="handleClickSearchResult(item)" />
:item="item" />
<template v-if="!initialisedConversations">
<LoadingPlaceholder type="conversations" />
</template>
Expand All @@ -54,8 +53,7 @@
<Conversation v-for="item of searchResultsListedConversations"
:key="item.id"
:item="item"
:is-search-result="true"
@click="joinListedConversation(item)" />
is-search-result />
</template>
<template v-if="searchResultsUsers.length !== 0">
<NcAppNavigationCaption :title="t('spreed', 'Users')" />
Expand Down Expand Up @@ -287,9 +285,7 @@ export default {
EventBus.$on('should-refresh-conversations', this.handleShouldRefreshConversations)
EventBus.$once('conversations-received', this.handleUnreadMention)
EventBus.$on('route-change', this.onRouteChange)
EventBus.$once('joined-conversation', ({ token }) => {
this.scrollToConversation(token)
})
EventBus.$on('joined-conversation', this.handleJoinedConversation)
this.mountArrowNavigation()
},

Expand Down Expand Up @@ -408,10 +404,6 @@ export default {
if (item.source === 'users') {
// Create one-to-one conversation directly
const conversation = await this.$store.dispatch('createOneToOneConversation', item.id)
this.abortSearch()
EventBus.$once('joined-conversation', ({ token }) => {
this.scrollToConversation(token)
})
this.$router.push({
name: 'conversation',
params: { token: conversation.token },
Expand All @@ -422,19 +414,6 @@ export default {
}
},

async joinListedConversation(conversation) {
this.abortSearch()
EventBus.$once('joined-conversation', ({ token }) => {
this.scrollToConversation(token)
})
// add as temporary item that will refresh after the joining process is complete
this.$store.dispatch('addConversation', conversation)
this.$router.push({
name: 'conversation',
params: { token: conversation.token },
}).catch(err => console.debug(`Error while pushing the new conversation's route: ${err}`))
},

hasOneToOneConversationWith(userId) {
return !!this.conversationsList.find(conversation => conversation.type === CONVERSATION.TYPE.ONE_TO_ONE && conversation.name === userId)
},
Expand All @@ -455,21 +434,6 @@ export default {
emit('show-settings')
},

handleClickSearchResult(conversation) {
if (this.searchText !== '') {
EventBus.$once('joined-conversation', ({ token }) => {
if (this.isMobile) {
emit('toggle-navigation', {
open: false,
})
}
this.scrollToConversation(token)
})
}
// End the search operation
this.abortSearch()
},

sortConversations(conversation1, conversation2) {
if (conversation1.isFavorite !== conversation2.isFavorite) {
return conversation1.isFavorite ? -1 : 1
Expand Down Expand Up @@ -616,6 +580,16 @@ export default {
}
},

handleJoinedConversation({ token }) {
this.abortSearch()
this.scrollToConversation(token)
if (this.isMobile) {
emit('toggle-navigation', {
open: false,
})
}
},

iconData(item) {
if (item.source === 'users') {
return {
Expand Down