diff --git a/src/FilesSidebarTabLoader.vue b/src/FilesSidebarTabLoader.vue new file mode 100644 index 000000000000..d9193db19098 --- /dev/null +++ b/src/FilesSidebarTabLoader.vue @@ -0,0 +1,96 @@ + + + + + + diff --git a/src/mainFilesSidebar.js b/src/mainFilesSidebar.js index 1b362769180d..ddddec90180a 100644 --- a/src/mainFilesSidebar.js +++ b/src/mainFilesSidebar.js @@ -31,15 +31,14 @@ import vOutsideEvents from 'vue-outside-events' import VueShortKey from 'vue-shortkey' import Vuex from 'vuex' -import { getRequestToken } from '@nextcloud/auth' import { translate, translatePlural } from '@nextcloud/l10n' -import { generateFilePath } from '@nextcloud/router' import FilesSidebarCallViewApp from './FilesSidebarCallViewApp.vue' import FilesSidebarTabApp from './FilesSidebarTabApp.vue' import './init.js' import store from './store/index.js' +import FilesSidebarCallView from './views/FilesSidebarCallView.js' // Leaflet icon patch import 'leaflet/dist/leaflet.css' @@ -48,17 +47,6 @@ import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility // eslint-disable-next-line import 'leaflet-defaulticon-compatibility' -// 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 @@ -87,12 +75,16 @@ const newTab = () => new Vue({ render: h => h(FilesSidebarTabApp), }) -if (!window.OCA.Talk) { - window.OCA.Talk = {} -} Object.assign(window.OCA.Talk, { - fileInfo: null, newCallView, newTab, store, }) + +export const mountSidebar = (mountEl) => { + if (OCA.Files?.Sidebar) { + OCA.Files.Sidebar.registerSecondaryView(new FilesSidebarCallView()) + OCA.Talk.tabInstance = OCA.Talk.newTab() + OCA.Talk.tabInstance.$mount(mountEl) + } +} diff --git a/src/mainFilesSidebarLoader.js b/src/mainFilesSidebarLoader.js index c48c66bf910b..80f261538988 100644 --- a/src/mainFilesSidebarLoader.js +++ b/src/mainFilesSidebarLoader.js @@ -20,24 +20,47 @@ * */ -import './init.js' -import FilesSidebarCallView from './views/FilesSidebarCallView.js' +import Vue from 'vue' + +import { getRequestToken } from '@nextcloud/auth' +import { generateFilePath } from '@nextcloud/router' + +import FilesSidebarTabLoader from './FilesSidebarTabLoader.vue' + +// 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.OC = OC +Vue.prototype.OCA = OCA + +const loaderTab = () => new Vue({ + id: 'talk-chat-tab', + render: h => h(FilesSidebarTabLoader), +}) const isEnabled = function(fileInfo) { if (fileInfo && !fileInfo.isDirectory()) { return true } - const token = OCA.Talk.store.getters.getToken() + const token = OCA.Talk.store?.getters.getToken() // If the Talk tab can not be displayed then the current conversation is // left; this must be done here because "setFileInfo" will not get // called with the new file if the tab can not be displayed. if (token) { - OCA.Talk.store.dispatch('leaveConversation', { token }) + OCA.Talk.store?.dispatch('leaveConversation', { token }) } - OCA.Talk.store.dispatch('updateTokenAndFileIdForToken', { + OCA.Talk.store?.dispatch('updateTokenAndFileIdForToken', { newToken: null, newFileId: null, }) @@ -45,16 +68,23 @@ const isEnabled = function(fileInfo) { return false } -// It might be enough to keep the instance only in the Tab object itself, -// without using a shared variable that can be destroyed if a new tab is -// mounted and the previous one was not destroyed yet, as the tabs seem to -// always be properly destroyed. However, this is how it is done for tabs in -// server, so it is done here too just to be safe. -let tabInstance = null +if (!window.OCA.Talk) { + window.OCA.Talk = {} +} +Object.assign(window.OCA.Talk, { + fileInfo: null, + loaderTab, + isFirstLoad: true, + // It might be enough to keep the instance only in the Tab object itself, + // without using a shared variable that can be destroyed if a new tab is + // mounted and the previous one was not destroyed yet, as the tabs seem to + // always be properly destroyed. However, this is how it is done for tabs in + // server, so it is done here too just to be safe. + tabInstance: null, +}) window.addEventListener('DOMContentLoaded', () => { if (OCA.Files && OCA.Files.Sidebar) { - OCA.Files.Sidebar.registerSecondaryView(new FilesSidebarCallView()) OCA.Files.Sidebar.registerTab(new OCA.Files.Sidebar.Tab({ id: 'chat', name: t('spreed', 'Chat'), @@ -62,8 +92,8 @@ window.addEventListener('DOMContentLoaded', () => { enabled: isEnabled, async mount(el, fileInfo, context) { - if (tabInstance) { - tabInstance.$destroy() + if (OCA.Talk.tabInstance) { + OCA.Talk.tabInstance.$destroy() } // Dirty hack to force the style on parent component @@ -73,16 +103,20 @@ window.addEventListener('DOMContentLoaded', () => { tabChat.style.padding = '0' OCA.Talk.fileInfo = this.fileInfo - tabInstance = OCA.Talk.newTab() - tabInstance.$mount(el) + if (OCA.Talk.isFirstLoad === true) { + OCA.Talk.tabInstance = OCA.Talk.loaderTab() + } else { + OCA.Talk.tabInstance = OCA.Talk.newTab() + } + OCA.Talk.tabInstance.$mount(el) }, update(fileInfo) { OCA.Talk.fileInfo = fileInfo }, destroy() { OCA.Talk.fileInfo = null - tabInstance.$destroy() - tabInstance = null + OCA.Talk.tabInstance.$destroy() + OCA.Talk.tabInstance = null }, })) } diff --git a/webpack.config.js b/webpack.config.js index da6e74015903..1bc3f451c892 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -23,7 +23,6 @@ module.exports = mergeWithRules({ main: path.join(__dirname, 'src', 'main.js'), recording: path.join(__dirname, 'src', 'mainRecording.js'), 'files-sidebar': [ - path.join(__dirname, 'src', 'mainFilesSidebar.js'), path.join(__dirname, 'src', 'mainFilesSidebarLoader.js'), ], 'public-share-auth-sidebar': path.join(__dirname, 'src', 'mainPublicShareAuthSidebar.js'),