diff options
author | Joas Schilling <coding@schilljs.com> | 2022-04-27 18:36:48 +0300 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2022-04-27 22:22:43 +0300 |
commit | f810f17ba24f2e57289c9a06bc8346fa4450d56b (patch) | |
tree | 12cda56d9e52fbd0247d7e8c040f1ee190e1b8a2 | |
parent | 7c1268acbce3884cb07a7447dba067d0ddbccfec (diff) |
Disable UI elements which can not be used anymore
Signed-off-by: Joas Schilling <coding@schilljs.com>
5 files changed, 60 insertions, 8 deletions
diff --git a/src/components/MessagesList/MessagesGroup/Message/Message.spec.js b/src/components/MessagesList/MessagesGroup/Message/Message.spec.js index 69cd66042..d9ec96590 100644 --- a/src/components/MessagesList/MessagesGroup/Message/Message.spec.js +++ b/src/components/MessagesList/MessagesGroup/Message/Message.spec.js @@ -3,7 +3,7 @@ import { createLocalVue, mount, shallowMount } from '@vue/test-utils' import { cloneDeep } from 'lodash' import { EventBus } from '../../../../services/EventBus' import storeConfig from '../../../../store/storeConfig' -import { CONVERSATION, ATTENDEE } from '../../../../constants' +import { CONVERSATION, ATTENDEE, PARTICIPANT } from '../../../../constants' // Components import Check from 'vue-material-design-icons/Check' @@ -50,6 +50,7 @@ describe('Message.vue', () => { lastCommonReadMessage: 0, type: CONVERSATION.TYPE.GROUP, readOnly: CONVERSATION.STATE.READ_WRITE, + permissions: PARTICIPANT.PERMISSIONS.MAX_DEFAULT, } testStoreConfig = cloneDeep(storeConfig) @@ -806,6 +807,38 @@ describe('Message.vue', () => { expect(reactionButtons.wrappers[1].text()).toBe('👍 7') }) + test('shows reaction buttons with the right emoji count but without emoji placeholder when no chat permission', () => { + const conversationProps = { + token: TOKEN, + lastCommonReadMessage: 0, + type: CONVERSATION.TYPE.GROUP, + readOnly: CONVERSATION.STATE.READ_WRITE, + permissions: PARTICIPANT.PERMISSIONS.MAX_DEFAULT - PARTICIPANT.PERMISSIONS.CHAT, + } + testStoreConfig.modules.conversationsStore.getters.conversation + = jest.fn().mockReturnValue((token) => conversationProps) + store = new Store(testStoreConfig) + + const wrapper = shallowMount(Message, { + localVue, + store, + propsData: messageProps, + }) + + const reactionsBar = wrapper.find('.message-body__reactions') + + // Array of buttons + const reactionButtons = reactionsBar.findAll('.reaction-button') + + // Number of buttons, 2 passed into the getter and 1 is the emoji + // picker + expect(reactionButtons.length).toBe(2) + + // Text of the buttons + expect(reactionButtons.wrappers[0].text()).toBe('❤️ 1') + expect(reactionButtons.wrappers[1].text()).toBe('👍 7') + }) + test('dispatches store action upon picking an emoji from the emojipicker', () => { const addReactionToMessageAction = jest.fn() const userHasReactedGetter = jest.fn().mockReturnValue(() => false) diff --git a/src/components/MessagesList/MessagesGroup/Message/Message.vue b/src/components/MessagesList/MessagesGroup/Message/Message.vue index bc56e1524..4769068ec 100644 --- a/src/components/MessagesList/MessagesGroup/Message/Message.vue +++ b/src/components/MessagesList/MessagesGroup/Message/Message.vue @@ -136,7 +136,10 @@ the main body of the message as well as a quote. </Popover> <!-- More reactions picker --> - <EmojiPicker :per-line="5" :container="`#message_${id}`" @select="handleReactionClick"> + <EmojiPicker v-if="canReact" + :per-line="5" + :container="`#message_${id}`" + @select="handleReactionClick"> <button class="reaction-button"> <EmoticonOutline :size="15" /> </button> @@ -190,7 +193,7 @@ import EmojiPicker from '@nextcloud/vue/dist/Components/EmojiPicker' import EmoticonOutline from 'vue-material-design-icons/EmoticonOutline.vue' import Popover from '@nextcloud/vue/dist/Components/Popover' import { showError, showSuccess, showWarning, TOAST_DEFAULT_TIMEOUT } from '@nextcloud/dialogs' -import { ATTENDEE } from '../../../../constants' +import { ATTENDEE, CONVERSATION, PARTICIPANT } from '../../../../constants' export default { name: 'Message', @@ -572,6 +575,10 @@ export default { return this.$store.getters.hasReactions(this.token, this.id) }, + canReact() { + return this.conversation.readOnly !== CONVERSATION.STATE.READ_ONLY && (this.conversation.permissions & PARTICIPANT.PERMISSIONS.CHAT) !== 0 + }, + simpleReactions() { return this.messageObject.reactions }, @@ -679,6 +686,11 @@ export default { }, async handleReactionClick(clickedEmoji) { + if (!this.canReact) { + showError(t('spreed', 'No permission to post reactions in this conversation')) + return + } + // Check if current user has already added this reaction to the message if (!this.userHasReacted(clickedEmoji)) { this.$store.dispatch('addReactionToMessage', { diff --git a/src/components/MessagesList/MessagesGroup/Message/MessageButtonsBar/MessageButtonsBar.vue b/src/components/MessagesList/MessagesGroup/Message/MessageButtonsBar/MessageButtonsBar.vue index fb0c58d48..b2f58bfcf 100644 --- a/src/components/MessagesList/MessagesGroup/Message/MessageButtonsBar/MessageButtonsBar.vue +++ b/src/components/MessagesList/MessagesGroup/Message/MessageButtonsBar/MessageButtonsBar.vue @@ -326,7 +326,7 @@ export default { }, acceptsReactions() { - return !this.isConversationReadOnly && !this.isDeletedMessage + return !this.isConversationReadOnly && !this.isDeletedMessage && (this.conversation.permissions & PARTICIPANT.PERMISSIONS.CHAT) !== 0 }, messageActions() { diff --git a/src/components/NewMessageForm/NewMessageForm.vue b/src/components/NewMessageForm/NewMessageForm.vue index 0942e316e..cbf96fc9a 100644 --- a/src/components/NewMessageForm/NewMessageForm.vue +++ b/src/components/NewMessageForm/NewMessageForm.vue @@ -132,7 +132,7 @@ import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import EmojiPicker from '@nextcloud/vue/dist/Components/EmojiPicker' import { EventBus } from '../../services/EventBus' import { shareFile } from '../../services/filesSharingServices' -import { CONVERSATION } from '../../constants' +import { CONVERSATION, PARTICIPANT } from '../../constants' import Paperclip from 'vue-material-design-icons/Paperclip' import EmoticonOutline from 'vue-material-design-icons/EmoticonOutline' import Send from 'vue-material-design-icons/Send' @@ -197,13 +197,19 @@ export default { return this.conversation.readOnly === CONVERSATION.STATE.READ_ONLY }, + noChatPermission() { + return (this.conversation.permissions & PARTICIPANT.PERMISSIONS.CHAT) === 0 + }, + disabled() { - return this.isReadOnly || !this.currentConversationIsJoined || this.isRecordingAudio + return this.isReadOnly || this.noChatPermission || this.isReadOnly || !this.currentConversationIsJoined || this.isRecordingAudio }, placeholderText() { if (this.isReadOnly) { return t('spreed', 'This conversation has been locked') + } else if (this.noChatPermission) { + return t('spreed', 'No permission to post messages in this conversation') } else if (!this.currentConversationIsJoined) { return t('spreed', 'Joining conversation …') } else { diff --git a/src/constants.js b/src/constants.js index f9d72765f..c54a6a5a4 100644 --- a/src/constants.js +++ b/src/constants.js @@ -100,8 +100,9 @@ export const PARTICIPANT = { PUBLISH_AUDIO: 16, PUBLISH_VIDEO: 32, PUBLISH_SCREEN: 64, - MAX_DEFAULT: 126, - MAX_CUSTOM: 127, + CHAT: 128, + MAX_DEFAULT: 254, + MAX_CUSTOM: 255, }, } export const SHARED_ITEM = { |