зеркало из https://github.com/nextcloud/spreed.git
Merge pull request #2407 from nextcloud/feature/vuejs/participants-list
Participants list in the sidebar
This commit is contained in:
Коммит
041f2499a1
|
@ -22,8 +22,7 @@
|
|||
<template>
|
||||
<AppContentListItem
|
||||
:title="item.displayName"
|
||||
:to="{ name: 'conversation', params: { token: item.token }}"
|
||||
@click.prevent.exact="joinConversation">
|
||||
:to="{ name: 'conversation', params: { token: item.token }}">
|
||||
<ConversationIcon
|
||||
slot="icon"
|
||||
:item="item"
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
import Conversation from './Conversation'
|
||||
import Hint from '../Hint/Hint'
|
||||
import { fetchConversations } from '../../../services/conversationsService'
|
||||
import { joinConversation, leaveConversation } from '../../../services/participantsService'
|
||||
import { EventBus } from '../../../services/EventBus'
|
||||
|
||||
export default {
|
||||
|
@ -68,6 +69,15 @@ export default {
|
|||
window.setInterval(() => {
|
||||
this.fetchConversations()
|
||||
}, 30000)
|
||||
|
||||
EventBus.$on('routeChange', ({ from, to }) => {
|
||||
if (from.name === 'conversation') {
|
||||
leaveConversation(from.params.token)
|
||||
}
|
||||
if (to.name === 'conversation') {
|
||||
joinConversation(to.params.token)
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
sortConversations(conversation1, conversation2) {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
<template>
|
||||
<AppNavigation class="vue navigation">
|
||||
<AppNavigationSearch
|
||||
<SearchBox
|
||||
v-model="searchText"
|
||||
@input="debounceFetchSearchResults" />
|
||||
<ul>
|
||||
|
@ -57,7 +57,6 @@
|
|||
|
||||
<script>
|
||||
import AppNavigation from '@nextcloud/vue/dist/Components/AppNavigation'
|
||||
import AppNavigationSearch from './AppNavigationSearch/AppNavigationSearch'
|
||||
import Caption from './Caption/Caption'
|
||||
import ContactsList from './ContactsList/ContactsList'
|
||||
import ConversationsList from './ConversationsList/ConversationsList'
|
||||
|
@ -65,6 +64,7 @@ import GroupsList from './GroupsList/GroupsList'
|
|||
import Hint from './Hint/Hint'
|
||||
import NewPrivateConversation from './NewConversation/NewPrivateConversation'
|
||||
import NewPublicConversation from './NewConversation/NewPublicConversation'
|
||||
import SearchBox from '../SearchBox/SearchBox'
|
||||
import debounce from 'debounce'
|
||||
import { EventBus } from '../../services/EventBus'
|
||||
import { searchPossibleConversations } from '../../services/conversationsService'
|
||||
|
@ -77,7 +77,6 @@ export default {
|
|||
|
||||
components: {
|
||||
AppNavigation,
|
||||
AppNavigationSearch,
|
||||
Caption,
|
||||
ContactsList,
|
||||
ConversationsList,
|
||||
|
@ -85,6 +84,7 @@ export default {
|
|||
Hint,
|
||||
NewPrivateConversation,
|
||||
NewPublicConversation,
|
||||
SearchBox,
|
||||
},
|
||||
|
||||
data() {
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import AppNavigationNew from 'nextcloud-vue/dist/Components/AppNavigationNew'
|
||||
import Multiselect from 'nextcloud-vue/dist/Components/Multiselect'
|
||||
import AppNavigationNew from '@nextcloud/vue/dist/Components/AppNavigationNew'
|
||||
import Multiselect from '@nextcloud/vue/dist/Components/Multiselect'
|
||||
|
||||
export default {
|
||||
name: 'NewConversationForm',
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
<script>
|
||||
|
||||
export default {
|
||||
name: 'AppNavigationSearch',
|
||||
name: 'SearchBox',
|
||||
props: {
|
||||
/**
|
||||
* Refers to the focused state of the input search box when loading the page.
|
||||
|
@ -87,7 +87,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '../../../assets/variables.scss';
|
||||
@import '../../assets/variables.scss';
|
||||
|
||||
.app-navigation-search {
|
||||
height: $top-bar-height !important;
|
|
@ -0,0 +1,216 @@
|
|||
<!--
|
||||
- @copyright Copyright (c) 2019 Joas Schilling <coding@schilljs.com>
|
||||
-
|
||||
- @author Joas Schilling <coding@schilljs.com>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<template>
|
||||
<li class="participant-row"
|
||||
:class="{ offline: isOffline, currentUser: isSelf, guestUser: isGuest }">
|
||||
<div class="participant-row__avatar-wrapper">
|
||||
<Avatar
|
||||
:user="userId"
|
||||
:display-name="displayName" />
|
||||
</div>
|
||||
|
||||
<span class="participant-row__user-name">{{ displayName }}</span>
|
||||
<span v-if="isModerator" class="participant-row__moderator-indicator">({{ t('spreed', 'moderator') }})</span>
|
||||
|
||||
<template v-if="canModerate">
|
||||
<Actions>
|
||||
<ActionButton v-if="canBeDemoted"
|
||||
icon="icon-rename"
|
||||
@click.prevent.exact="demoteFromModerator">
|
||||
{{ t('spreed', 'Demote from moderator') }}
|
||||
</ActionButton>
|
||||
<ActionButton v-if="canBePromoted"
|
||||
icon="icon-rename"
|
||||
@click.prevent.exact="promoteToModerator">
|
||||
{{ t('spreed', 'Promote to moderator') }}
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
icon="icon-delete"
|
||||
@click.prevent.exact="removeParticipant">
|
||||
{{ t('spreed', 'Remove participant') }}
|
||||
</ActionButton>
|
||||
</Actions>
|
||||
</template>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
|
||||
import Actions from '@nextcloud/vue/dist/Components/Actions'
|
||||
import Avatar from '@nextcloud/vue/dist/Components/Avatar'
|
||||
import { PARTICIPANT } from '../../../constants'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
|
||||
export default {
|
||||
name: 'Participant',
|
||||
|
||||
components: {
|
||||
Actions,
|
||||
ActionButton,
|
||||
Avatar,
|
||||
},
|
||||
|
||||
props: {
|
||||
userId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
displayName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
participantType: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
lastPing: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
sessionId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
token() {
|
||||
return this.$route.params.token
|
||||
},
|
||||
currentParticipant() {
|
||||
return this.$store.getters.conversations[this.token]
|
||||
},
|
||||
|
||||
isSelf() {
|
||||
// User
|
||||
if (this.userId) {
|
||||
return getCurrentUser().uid === this.userId
|
||||
}
|
||||
|
||||
// Guest
|
||||
return this.sessionId !== '0' && this.sessionId === this.currentParticipant.sessionId
|
||||
},
|
||||
selfIsModerator() {
|
||||
return this.participantTypeIsModerator(this.currentParticipant.participantType)
|
||||
},
|
||||
|
||||
isOffline() {
|
||||
return this.sessionId === '0'
|
||||
},
|
||||
isGuest() {
|
||||
return [PARTICIPANT.TYPE.GUEST, PARTICIPANT.TYPE.GUEST_MODERATOR].indexOf(this.participantType) !== -1
|
||||
},
|
||||
isModerator() {
|
||||
return this.participantTypeIsModerator(this.participantType)
|
||||
},
|
||||
canModerate() {
|
||||
return this.participantType !== PARTICIPANT.TYPE.OWNER && !this.isSelf && this.selfIsModerator
|
||||
},
|
||||
canBeDemoted() {
|
||||
return this.canModerate
|
||||
&& [PARTICIPANT.TYPE.MODERATOR, PARTICIPANT.TYPE.GUEST_MODERATOR].indexOf(this.participantType) !== -1
|
||||
},
|
||||
canBePromoted() {
|
||||
return this.canModerate && !this.isModerator
|
||||
},
|
||||
|
||||
participantIdentifier() {
|
||||
let data = {}
|
||||
|
||||
if (this.isGuest) {
|
||||
data = {
|
||||
sessionId: this.sessionId,
|
||||
}
|
||||
} else {
|
||||
data = {
|
||||
participant: this.userId,
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
participantTypeIsModerator(participantType) {
|
||||
return [PARTICIPANT.TYPE.OWNER, PARTICIPANT.TYPE.MODERATOR, PARTICIPANT.TYPE.GUEST_MODERATOR].indexOf(participantType) !== -1
|
||||
},
|
||||
|
||||
async promoteToModerator() {
|
||||
await this.$store.dispatch('promoteToModerator', {
|
||||
token: this.token,
|
||||
participantIdentifier: this.participantIdentifier,
|
||||
})
|
||||
},
|
||||
async demoteFromModerator() {
|
||||
await this.$store.dispatch('demoteFromModerator', {
|
||||
token: this.token,
|
||||
participantIdentifier: this.participantIdentifier,
|
||||
})
|
||||
},
|
||||
async removeParticipant() {
|
||||
await this.$store.dispatch('removeParticipant', {
|
||||
token: this.token,
|
||||
participantIdentifier: this.participantIdentifier,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.participant-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&__avatar-wrapper {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
}
|
||||
&__user-name {
|
||||
margin-left: 6px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
line-height: normal;
|
||||
}
|
||||
&__moderator-indicator {
|
||||
color: var(--color-text-maxcontrast);
|
||||
font-weight: 300;
|
||||
padding-left: 5px;
|
||||
}
|
||||
&__icon {
|
||||
width: 32px;
|
||||
height: 44px;
|
||||
}
|
||||
}
|
||||
|
||||
.offline {
|
||||
& > .participant-row__avatar-wrapper {
|
||||
opacity: .4;
|
||||
}
|
||||
& > span {
|
||||
color: var(--color-text-maxcontrast);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,144 @@
|
|||
<!--
|
||||
- @copyright Copyright (c) 2019 Joas Schilling <coding@schilljs.com>
|
||||
-
|
||||
- @author Joas Schilling <coding@schilljs.com>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<ul>
|
||||
<Participant
|
||||
v-for="participant in participantsList"
|
||||
:key="participant.userId"
|
||||
:user-id="participant.userId"
|
||||
:display-name="participant.displayName"
|
||||
:participant-type="participant.participantType"
|
||||
:last-ping="participant.lastPing"
|
||||
:session-id="participant.sessionId" />
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import Participant from './Participant'
|
||||
import { fetchParticipants } from '../../../services/participantsService'
|
||||
import { EventBus } from '../../../services/EventBus'
|
||||
import { PARTICIPANT } from '../../../constants'
|
||||
|
||||
export default {
|
||||
name: 'ParticipantsTab',
|
||||
|
||||
components: {
|
||||
Participant,
|
||||
},
|
||||
|
||||
computed: {
|
||||
token() {
|
||||
return this.$route.params.token
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the participants array.
|
||||
*
|
||||
* @returns {array}
|
||||
*/
|
||||
participantsList() {
|
||||
const participants = this.$store.getters.participantsList(this.token)
|
||||
|
||||
return participants.slice().sort(this.sortParticipants)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetches the messages when the MessageList created. The router mounts this
|
||||
* component only if the token is passed in so there's no need to check the
|
||||
* token prop.
|
||||
*/
|
||||
created() {
|
||||
this.onRouteChange()
|
||||
|
||||
/**
|
||||
* Add a listener for routeChange event emitted by the App.vue component.
|
||||
* Call the onRouteChange method function whenever the route changes.
|
||||
*/
|
||||
EventBus.$on('routeChange', () => {
|
||||
this.$nextTick(() => {
|
||||
this.onRouteChange()
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
onRouteChange() {
|
||||
this.getParticipants()
|
||||
},
|
||||
|
||||
/**
|
||||
* Sort two participants by:
|
||||
* - type (moderators before normal participants)
|
||||
* - online status
|
||||
* - display name
|
||||
*
|
||||
* @param {object} participant1 First participant
|
||||
* @param {int} participant1.participantType First participant type
|
||||
* @param {string} participant1.sessionId First participant session
|
||||
* @param {string} participant1.displayName First participant display name
|
||||
* @param {object} participant2 Second participant
|
||||
* @param {int} participant2.participantType Second participant type
|
||||
* @param {string} participant2.sessionId Second participant session
|
||||
* @param {string} participant2.displayName Second participant display name
|
||||
* @returns {number}
|
||||
*/
|
||||
sortParticipants(participant1, participant2) {
|
||||
const moderatorTypes = [PARTICIPANT.TYPE.OWNER, PARTICIPANT.TYPE.MODERATOR, PARTICIPANT.TYPE.GUEST_MODERATOR]
|
||||
const moderator1 = moderatorTypes.indexOf(participant1.participantType) !== -1
|
||||
const moderator2 = moderatorTypes.indexOf(participant2.participantType) !== -1
|
||||
|
||||
if (moderator1 !== moderator2) {
|
||||
return moderator1 ? -1 : 1
|
||||
}
|
||||
|
||||
if (participant1.sessionId === '0') {
|
||||
if (participant2.sessionId !== '0') {
|
||||
return 1
|
||||
}
|
||||
} else if (participant2.sessionId === '0') {
|
||||
return -1
|
||||
}
|
||||
|
||||
return participant2.displayName - participant1.displayName
|
||||
},
|
||||
|
||||
async getParticipants() {
|
||||
const participants = await fetchParticipants(this.token)
|
||||
this.$store.dispatch('purgeParticipantsStore', this.token)
|
||||
participants.data.ocs.data.forEach(participant => {
|
||||
this.$store.dispatch('addParticipant', {
|
||||
token: this.token,
|
||||
participant: participant,
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -26,7 +26,7 @@
|
|||
:starred.sync="conversation.isFavorite"
|
||||
@close="handleClose">
|
||||
<AppSidebarTab :name="t('spreed', 'Participants')" icon="icon-contacts-dark">
|
||||
Participants
|
||||
<ParticipantsTab />
|
||||
</AppSidebarTab>
|
||||
<AppSidebarTab :name="t('spreed', 'Projects')" icon="icon-projects">
|
||||
<CollectionList v-if="conversation.token"
|
||||
|
@ -40,7 +40,7 @@
|
|||
<script>
|
||||
import AppSidebar from '@nextcloud/vue/dist/Components/AppSidebar'
|
||||
import AppSidebarTab from '@nextcloud/vue/dist/Components/AppSidebarTab'
|
||||
// import ParticipantsTab from './ParticipantsTab/ParticipantsTab'
|
||||
import ParticipantsTab from './ParticipantsTab/ParticipantsTab'
|
||||
import { CollectionList } from 'nextcloud-vue-collections'
|
||||
|
||||
export default {
|
||||
|
@ -49,7 +49,7 @@ export default {
|
|||
AppSidebar,
|
||||
AppSidebarTab,
|
||||
CollectionList,
|
||||
// ParticipantsTab,
|
||||
ParticipantsTab,
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
|
|
@ -29,9 +29,9 @@ import { generateOcsUrl } from '@nextcloud/router'
|
|||
*
|
||||
* @param {string} token The conversation token;
|
||||
*/
|
||||
const joinConversation = async function(token) {
|
||||
const joinConversation = async(token) => {
|
||||
try {
|
||||
const response = await axios.post(generateOcsUrl(`room/${token}/participants/active`))
|
||||
const response = await axios.post(generateOcsUrl('apps/spreed/api/v1', 2) + `room/${token}/participants/active`)
|
||||
return response
|
||||
} catch (error) {
|
||||
console.debug(error)
|
||||
|
@ -66,8 +66,56 @@ const removeCurrentUserFromConversation = async function(token) {
|
|||
}
|
||||
}
|
||||
|
||||
const removeUserFromConversation = async function(token, userId) {
|
||||
try {
|
||||
const response = await axios.delete(generateOcsUrl('apps/spreed/api/v1', 2) + `room/${token}/participants`, {
|
||||
params: {
|
||||
participant: userId,
|
||||
},
|
||||
})
|
||||
return response
|
||||
} catch (error) {
|
||||
console.debug(error)
|
||||
}
|
||||
}
|
||||
|
||||
const removeGuestFromConversation = async function(token, sessionId) {
|
||||
try {
|
||||
const response = await axios.delete(generateOcsUrl('apps/spreed/api/v1', 2) + `room/${token}/participants/guests`, {
|
||||
params: {
|
||||
participant: sessionId,
|
||||
},
|
||||
})
|
||||
return response
|
||||
} catch (error) {
|
||||
console.debug(error)
|
||||
}
|
||||
}
|
||||
|
||||
const promoteToModerator = async(token, options) => {
|
||||
const response = await axios.post(generateOcsUrl('apps/spreed/api/v1/room', 2) + token + '/moderators', options)
|
||||
return response
|
||||
}
|
||||
|
||||
const demoteFromModerator = async(token, options) => {
|
||||
const response = await axios.delete(generateOcsUrl('apps/spreed/api/v1/room', 2) + token + '/moderators', {
|
||||
params: options,
|
||||
})
|
||||
return response
|
||||
}
|
||||
|
||||
const fetchParticipants = async(token) => {
|
||||
const response = await axios.get(generateOcsUrl('apps/spreed/api/v1/room', 2) + token + '/participants')
|
||||
return response
|
||||
}
|
||||
|
||||
export {
|
||||
joinConversation,
|
||||
leaveConversation,
|
||||
removeCurrentUserFromConversation,
|
||||
removeUserFromConversation,
|
||||
removeGuestFromConversation,
|
||||
promoteToModerator,
|
||||
demoteFromModerator,
|
||||
fetchParticipants,
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import Vue from 'vue'
|
|||
import Vuex, { Store } from 'vuex'
|
||||
import conversationsStore from './conversationsStore'
|
||||
import messagesStore from './messagesStore'
|
||||
import participantsStore from './participantsStore'
|
||||
import quoteReplyStore from './quoteReplyStore'
|
||||
import sidebarStore from './sidebarStore'
|
||||
|
||||
|
@ -35,6 +36,7 @@ export default new Store({
|
|||
modules: {
|
||||
conversationsStore,
|
||||
messagesStore,
|
||||
participantsStore,
|
||||
quoteReplyStore,
|
||||
sidebarStore,
|
||||
},
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import Vue from 'vue'
|
||||
import {
|
||||
promoteToModerator,
|
||||
demoteFromModerator,
|
||||
removeUserFromConversation,
|
||||
removeGuestFromConversation,
|
||||
} from '../services/participantsService'
|
||||
import { PARTICIPANT } from '../constants'
|
||||
|
||||
const state = {
|
||||
participants: {
|
||||
},
|
||||
}
|
||||
|
||||
const getters = {
|
||||
/**
|
||||
* Gets the participants array
|
||||
* @param {object} state the state object.
|
||||
* @returns {array} the participants array (if there are participants in the store)
|
||||
*/
|
||||
participantsList: (state) => (token) => {
|
||||
if (state.participants[token]) {
|
||||
return state.participants[token]
|
||||
}
|
||||
return []
|
||||
},
|
||||
getParticipant: (state) => (token, index) => {
|
||||
if (state.participants[token] && state.participants[token][index]) {
|
||||
return state.participants[token][index]
|
||||
}
|
||||
return {}
|
||||
},
|
||||
getParticipantIndex: (state) => (token, participantIdentifier) => {
|
||||
let index
|
||||
|
||||
if (participantIdentifier.hasOwnProperty('participant')) {
|
||||
index = state.participants[token].findIndex(participant => participant.userId === participantIdentifier.participant)
|
||||
} else {
|
||||
index = state.participants[token].findIndex(participant => participant.sessionId === participantIdentifier.sessionId)
|
||||
}
|
||||
|
||||
return index
|
||||
},
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
/**
|
||||
* Adds a message to the store.
|
||||
* @param {object} state current store state;
|
||||
* @param {object} token the token of the conversation;
|
||||
* @param {object} participant the participant;
|
||||
*/
|
||||
addParticipant(state, { token, participant }) {
|
||||
if (!state.participants[token]) {
|
||||
Vue.set(state.participants, token, [])
|
||||
}
|
||||
state.participants[token].push(participant)
|
||||
},
|
||||
updateParticipant(state, { token, index, updatedData }) {
|
||||
if (state.participants[token] && state.participants[token][index]) {
|
||||
state.participants[token][index] = Object.assign(state.participants[token][index], updatedData)
|
||||
}
|
||||
},
|
||||
deleteParticipant(state, { token, index }) {
|
||||
if (state.participants[token] && state.participants[token][index]) {
|
||||
Vue.delete(state.participants[token], index)
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Resets the store to it's original state
|
||||
* @param {object} state current store state;
|
||||
* @param {string} token the conversation to purge;
|
||||
*/
|
||||
purgeParticipantsStore(state, token) {
|
||||
Vue.delete(state.participants, token)
|
||||
},
|
||||
}
|
||||
|
||||
const actions = {
|
||||
|
||||
/**
|
||||
* Adds participant to the store.
|
||||
*
|
||||
* @param {object} context default store context;
|
||||
* @param {string} token the conversation to purge;
|
||||
* @param {object} participant the participant;
|
||||
*/
|
||||
addParticipant({ commit }, { token, participant }) {
|
||||
commit('addParticipant', { token, participant })
|
||||
},
|
||||
async promoteToModerator({ commit, getters }, { token, participantIdentifier }) {
|
||||
const index = getters.getParticipantIndex(token, participantIdentifier)
|
||||
if (index === -1) {
|
||||
return
|
||||
}
|
||||
|
||||
await promoteToModerator(token, participantIdentifier)
|
||||
|
||||
const participant = getters.getParticipant(token, index)
|
||||
const updatedData = {
|
||||
participantType: participant.participantType === PARTICIPANT.TYPE.GUEST ? PARTICIPANT.TYPE.GUEST_MODERATOR : PARTICIPANT.TYPE.MODERATOR,
|
||||
}
|
||||
commit('updateParticipant', { token, index, updatedData })
|
||||
},
|
||||
async demoteFromModerator({ commit, getters }, { token, participantIdentifier }) {
|
||||
const index = getters.getParticipantIndex(token, participantIdentifier)
|
||||
if (index === -1) {
|
||||
return
|
||||
}
|
||||
|
||||
await demoteFromModerator(token, participantIdentifier)
|
||||
|
||||
const participant = getters.getParticipant(token, index)
|
||||
const updatedData = {
|
||||
participantType: participant.participantType === PARTICIPANT.TYPE.GUEST_MODERATOR ? PARTICIPANT.TYPE.GUEST : PARTICIPANT.TYPE.USER,
|
||||
}
|
||||
commit('updateParticipant', { token, index, updatedData })
|
||||
},
|
||||
async removeParticipant({ commit, getters }, { token, participantIdentifier }) {
|
||||
const index = getters.getParticipantIndex(token, participantIdentifier)
|
||||
if (index === -1) {
|
||||
return
|
||||
}
|
||||
|
||||
const participant = getters.getParticipant(token, index)
|
||||
if (participant.userId) {
|
||||
await removeUserFromConversation(token, participant.userId)
|
||||
} else {
|
||||
await removeGuestFromConversation(token, participant.sessionId)
|
||||
}
|
||||
commit('deleteParticipant', { token, index })
|
||||
},
|
||||
/**
|
||||
* Resets the store to it's original state.
|
||||
* @param {object} context default store context;
|
||||
* @param {string} token the conversation to purge;
|
||||
*/
|
||||
purgeParticipantsStore({ commit }, token) {
|
||||
commit('purgeParticipantsStore', token)
|
||||
},
|
||||
}
|
||||
|
||||
export default { state, mutations, getters, actions }
|
Загрузка…
Ссылка в новой задаче