Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add checkbox for locking conversation #4331

Merged
merged 5 commits into from
Oct 15, 2020
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
2 changes: 1 addition & 1 deletion src/components/ChatView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export default {
if (this.isGuest) {
return t('spreed', 'You need to be logged in to upload files')
} else if (this.isReadOnly) {
return t('spreed', 'This conversation is read only')
return t('spreed', 'This conversation is read-only')
} else {
return t('spreed', 'Drop your files to upload')
}
Expand Down
9 changes: 7 additions & 2 deletions src/components/MessagesList/MessagesGroup/Message/Message.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ import RichText from '@juliushaertl/vue-richtext'
import Quote from '../../../Quote'
import { EventBus } from '../../../../services/EventBus'
import emojiRegex from 'emoji-regex'
import { PARTICIPANT } from '../../../../constants'
import { PARTICIPANT, CONVERSATION } from '../../../../constants'
import moment from '@nextcloud/moment'

export default {
Expand Down Expand Up @@ -217,7 +217,12 @@ export default {

computed: {
hasActions() {
return this.isReplyable
return this.isReplyable && !this.isConversationReadOnly
},

isConversationReadOnly() {
const conversation = this.$store.getters.conversation(this.token)
return conversation.readOnly === CONVERSATION.STATE.READ_ONLY
},

isSystemMessage() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export default {
*/
placeholderText: {
type: String,
default: t('spreed', 'Write message, @ to mention someone …'),
default: '',
},

/**
Expand Down
37 changes: 33 additions & 4 deletions src/components/NewMessageForm/NewMessageForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
</Actions>
</div>
<div
v-if="!isReadOnly"
class="new-message-form__button">
<EmojiPicker @select="addEmoji">
<button
Expand All @@ -80,11 +81,14 @@
ref="advancedInput"
v-model="text"
:token="token"
:active-input="!isReadOnly"
:placeholder-text="placeholderText"
@update:contentEditable="contentEditableToParsed"
@submit="handleSubmit"
@files-pasted="handleFiles" />
</div>
<button
:disabled="isReadOnly"
type="submit"
:aria-label="t('spreed', 'Send message')"
class="new-message-form__button submit icon-confirm-fade"
Expand All @@ -96,7 +100,7 @@

<script>
import AdvancedInput from './AdvancedInput/AdvancedInput'
import { getFilePickerBuilder } from '@nextcloud/dialogs'
import { getFilePickerBuilder, showError } from '@nextcloud/dialogs'
import { postNewMessage } from '../../services/messagesService'
import Quote from '../Quote'
import Actions from '@nextcloud/vue/dist/Components/Actions'
Expand Down Expand Up @@ -149,6 +153,16 @@ export default {
}
},

isReadOnly() {
return this.conversation.readOnly === CONVERSATION.STATE.READ_ONLY
},

placeholderText() {
return this.isReadOnly
? t('spreed', 'This conversation has been locked')
: t('spreed', 'Write message, @ to mention someone …')
},

messageToBeReplied() {
return this.$store.getters.getMessageToBeReplied(this.token)
},
Expand All @@ -158,7 +172,7 @@ export default {
},

canShareAndUploadFiles() {
return !this.currentUserIsGuest && this.conversation.readOnly === CONVERSATION.STATE.READ_WRITE
return !this.currentUserIsGuest && !this.isReadOnly
},

attachmentFolder() {
Expand Down Expand Up @@ -238,8 +252,8 @@ export default {
* Sends the new message
*/
async handleSubmit() {

if (this.parsedText !== '') {
const oldMessage = this.parsedText
const temporaryMessage = createTemporaryMessage(this.parsedText, this.token)
this.$store.dispatch('addTemporaryMessage', temporaryMessage)
this.text = ''
Expand Down Expand Up @@ -270,7 +284,22 @@ export default {
})
}
} catch (error) {
console.debug(`error while submitting message ${error}`)
let statusCode = null
console.debug(`error while submitting message ${error}`, error)
if (error.isAxiosError) {
statusCode = error.response.status
}
// 403 when room is read-only, 412 when switched to lobby mode
if (statusCode === 403 || statusCode === 412) {
showError(t('spreed', 'No permission to post messages in this conversation'))
} else {
showError(t('spreed', 'Could not post message: {errorMessage}', { errorMessage: error.message || error }))
}

// restore message to allow re-sending
this.$store.dispatch('deleteMessage', temporaryMessage)
this.text = oldMessage
this.parsedText = oldMessage
}
}
},
Expand Down
1 change: 1 addition & 0 deletions src/components/TopBar/CallButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export default {
return (!this.conversation.canStartCall
&& !this.conversation.hasCall)
|| this.isBlockedByLobby
|| this.conversation.readOnly
|| this.isNextcloudTalkHashDirty
},

Expand Down
20 changes: 20 additions & 0 deletions src/components/TopBar/TopBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@
{{ t('spreed', 'Enter a password') }}
</ActionInput>
<ActionSeparator />
<ActionCheckbox
:checked="isReadOnly"
:disabled="readOnlyStateLoading"
@change="toggleReadOnly">
{{ t('spreed', 'Lock conversation') }}
</ActionCheckbox>
<ActionCheckbox
:checked="hasLobbyEnabled"
@change="toggleLobby">
Expand Down Expand Up @@ -204,6 +210,7 @@ export default {
// Switch for the password-editing operation
isEditingPassword: false,
lobbyTimerLoading: false,
readOnlyStateLoading: false,
}
},

Expand Down Expand Up @@ -317,6 +324,9 @@ export default {
hasLobbyEnabled() {
return this.conversation.lobbyState === WEBINAR.LOBBY.NON_MODERATORS
},
isReadOnly() {
return this.conversation.readOnly === CONVERSATION.STATE.READ_ONLY
},
isPasswordProtected() {
return this.conversation.hasPassword
},
Expand Down Expand Up @@ -457,6 +467,16 @@ export default {

this.lobbyTimerLoading = false
},

async toggleReadOnly() {
this.readOnlyStateLoading = true
await this.$store.dispatch('setReadOnlyState', {
token: this.token,
readOnly: this.isReadOnly ? CONVERSATION.STATE.READ_WRITE : CONVERSATION.STATE.READ_ONLY,
})
this.readOnlyStateLoading = false
},

async handlePasswordDisable() {
// disable the password protection for the current conversation
if (this.conversation.hasPassword) {
Expand Down
17 changes: 17 additions & 0 deletions src/services/conversationsService.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,22 @@ const changeLobbyState = async function(token, newState, timestamp) {
}
}

/**
* Change the read-only state
* @param {string} token The token of the conversation to be modified
* @param {int} readOnly The new read-only state to set
*/
const changeReadOnlyState = async function(token, readOnly) {
try {
const response = await axios.put(generateOcsUrl('apps/spreed/api/v2', 2) + `room/${token}/read-only`, {
state: readOnly,
})
return response
} catch (error) {
console.debug('Error while updating read-only state: ', error)
}
}

export {
fetchConversations,
fetchConversation,
Expand All @@ -312,6 +328,7 @@ export {
makePublic,
makePrivate,
changeLobbyState,
changeReadOnlyState,
setConversationPassword,
setConversationName,
}
13 changes: 13 additions & 0 deletions src/store/conversationsStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
makePublic,
makePrivate,
changeLobbyState,
changeReadOnlyState,
addToFavorites,
removeFromFavorites,
setConversationName,
Expand Down Expand Up @@ -206,6 +207,18 @@ const actions = {
commit('addConversation', conversation)
},

async setReadOnlyState({ commit, getters }, { token, readOnly }) {
const conversation = Object.assign({}, getters.conversations[token])
if (!conversation) {
return
}

await changeReadOnlyState(token, readOnly)
conversation.readOnly = readOnly

commit('addConversation', conversation)
},

async setLobbyTimer({ commit, getters }, { token, timestamp }) {
const conversation = Object.assign({}, getters.conversations[token])
if (!conversation) {
Expand Down