Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Don't use collaboration endpoint to trigger RoomSelector
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 <[email protected]>
  • Loading branch information
PVince81 committed Feb 12, 2021
commit fa55c6c4c858ac6b0c1c67a7de1caa2716c62ec3
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