Skip to content

Commit

Permalink
Don't use collaboration endpoint to trigger RoomSelector
Browse files Browse the repository at this point in the history
Deck plugin now creates its own Vue VM to instantiate the
RoomSelector.
RoomSelector now allows to specify properties for dialog title and
whether the result list should be filtered.

Signed-off-by: Vincent Petry <vincent@nextcloud.com>
  • Loading branch information
PVince81 committed Feb 12, 2021
1 parent 163290f commit 023bc23
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 43 deletions.
117 changes: 75 additions & 42 deletions src/deck.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,53 +26,86 @@ import { getRequestToken } from '@nextcloud/auth'
import { translate, translatePlural } from '@nextcloud/l10n'
import { showSuccess, showError } from '@nextcloud/dialogs'
import { postRichObjectToConversation } from './services/messagesService'
import RoomSelector from './views/RoomSelector'

// CSP config for webpack dynamic chunk loading
// eslint-disable-next-line
__webpack_nonce__ = btoa(getRequestToken())
(function(OC, OCA, t, n) {
async function postCardToRoom(card, token) {
try {
const response = await postRichObjectToConversation(token, {
objectType: 'deck-card',
objectId: card.id,
metaData: JSON.stringify(card),
})
const messageId = response.data.ocs.data.id
const targetUrl = generateUrl('/call/{token}#message_{messageId}', { token, messageId })
showSuccess(t('spreed', 'Deck card has been posted to the selected <a href="{link}">conversation</a>.', {
link: targetUrl,
}), {
isHTML: true,
})
} catch (exception) {
console.error('Error posting deck card to conversation', exception, exception.response?.status)
if (exception.response?.status === 403) {
showError(t('spreed', 'No permission to post messages in this conversation'))
} else {
showError(t('spreed', 'An error occurred while posting deck card to conversation.'))
}
}
}

function init() {
if (!OCA.Deck) {
return
}

// Correct the root of the app for chunk loading
// OC.linkTo matches the apps folders
// OC.generateUrl ensure the index.php (or not)
// We do not want the index.php since we're loading files
// eslint-disable-next-line
__webpack_public_path__ = generateFilePath('spreed', '', 'js/')
OCA.Deck.registerCardAction({
label: t('spreed', 'Post to a conversation'),
icon: 'icon-talk',
callback: (card) => {
const container = document.createElement('div')
container.id = 'spreed-post-card-to-room-select'
const body = document.getElementById('body-user')
body.appendChild(container)

Vue.prototype.t = translate
Vue.prototype.n = translatePlural
Vue.prototype.OC = OC
Vue.prototype.OCA = OCA
const ComponentVM = Vue.extend(RoomSelector)
const vm = new ComponentVM({
el: container,
propsData: {
dialogTitle: t('spreed', 'Post to conversation'),
showPostableOnly: true,
},
})

document.addEventListener('DOMContentLoaded', function() {
vm.$root.$on('close', () => {
vm.$el.remove()
vm.$destroy()
})
vm.$root.$on('select', (token) => {
vm.$el.remove()
vm.$destroy()

if (!window.OCA.Deck) {
return
postCardToRoom(card, token)
})
},
})
}

window.OCA.Deck.registerCardAction({
label: t('spreed', 'Post to a conversation'),
icon: 'icon-talk',
callback: (card) => {
OCP.Collaboration.trigger('room').then(async(token) => {
try {
const response = await postRichObjectToConversation(token, {
objectType: 'deck-card',
objectId: card.id,
metaData: JSON.stringify(card),
})
const messageId = response.data.ocs.data.id
const targetUrl = generateUrl('/call/{token}#message_{messageId}', { token, messageId })
showSuccess(t('spreed', 'Deck card has been posted to the selected <a href="{link}">conversation</a>.', {
link: targetUrl,
}), {
isHTML: true,
})
} catch (exception) {
console.error('Error posting deck card to conversation', exception, exception.response?.status)
showError(t('spreed', 'An error occurred while posting deck card to conversation.'))
}
})
},
})
// CSP config for webpack dynamic chunk loading
// eslint-disable-next-line
__webpack_nonce__ = btoa(getRequestToken())

// Correct the root of the app for chunk loading
// OC.linkTo matches the apps folders
// OC.generateUrl ensure the index.php (or not)
// We do not want the index.php since we're loading files
// eslint-disable-next-line
__webpack_public_path__ = generateFilePath('spreed', '', 'js/')

Vue.prototype.t = translate
Vue.prototype.n = translatePlural
Vue.prototype.OC = OC
Vue.prototype.OCA = OCA

document.addEventListener('DOMContentLoaded', init)

})
})(window.OC, window.OCA, t, n)
17 changes: 16 additions & 1 deletion src/views/RoomSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<Modal @close="close">
<div id="modal-inner" class="talk-modal" :class="{ 'icon-loading': loading }">
<div id="modal-content">
<h2>{{ t('spreed', 'Select a conversation') }}</h2>
<h2>{{ dialogTitle }}</h2>
<div id="room-list">
<ul v-if="!loading && availableRooms.length > 0">
<li v-for="room in availableRooms"
Expand Down Expand Up @@ -69,6 +69,20 @@ export default {
ConversationIcon,
Modal,
},
props: {
dialogTitle: {
type: String,
default: t('spreed', 'Link to a conversation'),
},
/**
* Whether to only show conversations to which
* the user can post messages.
*/
showPostableOnly: {
type: Boolean,
default: false,
},
},
data() {
return {
rooms: [],
Expand All @@ -80,6 +94,7 @@ export default {
availableRooms() {
return this.rooms.filter((room) => {
return room.type !== CONVERSATION.TYPE.CHANGELOG
&& (!this.showPostableOnly || room.readOnly === CONVERSATION.STATE.READ_WRITE)
&& room.objectType !== 'file'
&& room.objectType !== 'share:password'
})
Expand Down

0 comments on commit 023bc23

Please sign in to comment.