Skip to content

Commit 618fbc7

Browse files
AntreesyShGKme
authored andcommitted
fix(sidebar): reduce initial loading size of Talk files sidebar
Signed-off-by: Maksim Sukharev <[email protected]>
1 parent d87d7fb commit 618fbc7

File tree

4 files changed

+142
-32
lines changed

4 files changed

+142
-32
lines changed

src/FilesSidebarTabLoader.vue

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<!--
2+
- SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
3+
- SPDX-License-Identifier: AGPL-3.0-or-later
4+
-->
5+
<template>
6+
<div ref="talkChatPreload" class="talkChatTab">
7+
<div class="emptycontent ui-not-ready-placeholder">
8+
<div class="icon icon-loading" />
9+
</div>
10+
</div>
11+
</template>
12+
13+
<script>
14+
export default {
15+
name: 'FilesSidebarTabLoader',
16+
17+
data() {
18+
return {
19+
sidebarState: OCA.Files.Sidebar.state,
20+
}
21+
},
22+
23+
computed: {
24+
isChatTheActiveTab() {
25+
// FIXME check for empty active tab is currently needed because the
26+
// activeTab is not set when opening the sidebar from the "Details"
27+
// action (which opens the first tab, which is the Chat tab).
28+
return !this.sidebarState.activeTab || this.sidebarState.activeTab === 'chat'
29+
},
30+
},
31+
32+
watch: {
33+
isChatTheActiveTab: {
34+
immediate: true,
35+
handler(value) {
36+
if (value === true && OCA.Talk?.isFirstLoad === true) {
37+
OCA.Talk.isFirstLoad = false
38+
this.replaceAppInTab()
39+
}
40+
},
41+
},
42+
},
43+
44+
methods: {
45+
async replaceAppInTab() {
46+
try {
47+
if (OCA.Files.Sidebar) {
48+
const module = await import(/* webpackChunkName: "files-sidebar-main" */ './mainFilesSidebar.js')
49+
module.mountSidebar(this.$refs.talkChatPreload)
50+
}
51+
} catch (error) {
52+
console.error(error)
53+
}
54+
},
55+
},
56+
}
57+
</script>
58+
59+
<style scoped>
60+
.talkChatTab {
61+
height: 100%;
62+
63+
display: flex;
64+
flex-grow: 1;
65+
flex-direction: column;
66+
}
67+
68+
.emptycontent {
69+
/* Override default top margin set in server and center vertically
70+
* instead. */
71+
margin-top: unset;
72+
73+
height: 100%;
74+
75+
display: flex;
76+
flex-direction: column;
77+
align-items: center;
78+
justify-content: center;
79+
}
80+
</style>

src/mainFilesSidebar.js

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@ import VueObserveVisibility from 'vue-observe-visibility'
99
import VueShortKey from 'vue-shortkey'
1010
import Vuex from 'vuex'
1111

12-
import { getRequestToken } from '@nextcloud/auth'
13-
import { generateFilePath } from '@nextcloud/router'
14-
1512
import FilesSidebarCallViewApp from './FilesSidebarCallViewApp.vue'
1613
import FilesSidebarTabApp from './FilesSidebarTabApp.vue'
1714

1815
import './init.js'
16+
import PrivateTalk from './mainFilesSidebarLoader.js'
1917
import store from './store/index.js'
18+
import FilesSidebarCallView from './views/FilesSidebarCallView.js'
2019

2120
// Leaflet icon patch
2221
import 'leaflet/dist/leaflet.css'
@@ -25,17 +24,6 @@ import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility
2524
// eslint-disable-next-line
2625
import 'leaflet-defaulticon-compatibility'
2726

28-
// CSP config for webpack dynamic chunk loading
29-
// eslint-disable-next-line
30-
__webpack_nonce__ = btoa(getRequestToken())
31-
32-
// Correct the root of the app for chunk loading
33-
// OC.linkTo matches the apps folders
34-
// OC.generateUrl ensure the index.php (or not)
35-
// We do not want the index.php since we're loading files
36-
// eslint-disable-next-line
37-
__webpack_public_path__ = generateFilePath('spreed', '', 'js/')
38-
3927
Vue.prototype.OC = OC
4028
Vue.prototype.OCA = OCA
4129

@@ -61,12 +49,16 @@ const newTab = () => new Vue({
6149
render: h => h(FilesSidebarTabApp),
6250
})
6351

64-
if (!window.OCA.Talk) {
65-
window.OCA.Talk = {}
66-
}
6752
Object.assign(window.OCA.Talk, {
68-
fileInfo: null,
6953
newCallView,
7054
newTab,
7155
store,
7256
})
57+
58+
export const mountSidebar = (mountEl) => {
59+
if (OCA.Files?.Sidebar) {
60+
OCA.Files.Sidebar.registerSecondaryView(new FilesSidebarCallView())
61+
PrivateTalk.tabInstance = OCA.Talk.newTab()
62+
PrivateTalk.tabInstance.$mount(mountEl)
63+
}
64+
}

src/mainFilesSidebarLoader.js

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,83 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55

6-
import './init.js'
7-
import FilesSidebarCallView from './views/FilesSidebarCallView.js'
6+
import Vue from 'vue'
7+
8+
import { getRequestToken } from '@nextcloud/auth'
9+
import { generateFilePath } from '@nextcloud/router'
10+
11+
import FilesSidebarTabLoader from './FilesSidebarTabLoader.vue'
12+
13+
// CSP config for webpack dynamic chunk loading
14+
// eslint-disable-next-line
15+
__webpack_nonce__ = btoa(getRequestToken())
16+
17+
// Correct the root of the app for chunk loading
18+
// OC.linkTo matches the apps folders
19+
// OC.generateUrl ensure the index.php (or not)
20+
// We do not want the index.php since we're loading files
21+
// eslint-disable-next-line
22+
__webpack_public_path__ = generateFilePath('spreed', '', 'js/')
23+
24+
Vue.prototype.OC = OC
25+
Vue.prototype.OCA = OCA
26+
27+
const loaderTab = () => new Vue({
28+
id: 'talk-chat-tab',
29+
render: h => h(FilesSidebarTabLoader),
30+
})
831

932
const isEnabled = function(fileInfo) {
1033
if (fileInfo && !fileInfo.isDirectory()) {
1134
return true
1235
}
1336

14-
const token = OCA.Talk.store.getters.getToken()
37+
const token = OCA.Talk.store?.getters.getToken()
1538

1639
// If the Talk tab can not be displayed then the current conversation is
1740
// left; this must be done here because "setFileInfo" will not get
1841
// called with the new file if the tab can not be displayed.
1942
if (token) {
20-
OCA.Talk.store.dispatch('leaveConversation', { token })
43+
OCA.Talk.store?.dispatch('leaveConversation', { token })
2144
}
2245

23-
OCA.Talk.store.dispatch('updateTokenAndFileIdForToken', {
46+
OCA.Talk.store?.dispatch('updateTokenAndFileIdForToken', {
2447
newToken: null,
2548
newFileId: null,
2649
})
2750

2851
return false
2952
}
3053

54+
if (!window.OCA.Talk) {
55+
window.OCA.Talk = {}
56+
}
57+
Object.assign(window.OCA.Talk, {
58+
fileInfo: null,
59+
loaderTab,
60+
isFirstLoad: true,
61+
})
62+
3163
// It might be enough to keep the instance only in the Tab object itself,
3264
// without using a shared variable that can be destroyed if a new tab is
3365
// mounted and the previous one was not destroyed yet, as the tabs seem to
3466
// always be properly destroyed. However, this is how it is done for tabs in
3567
// server, so it is done here too just to be safe.
36-
let tabInstance = null
68+
const PrivateTalk = {
69+
tabInstance: null,
70+
}
3771

3872
window.addEventListener('DOMContentLoaded', () => {
3973
if (OCA.Files && OCA.Files.Sidebar) {
40-
OCA.Files.Sidebar.registerSecondaryView(new FilesSidebarCallView())
4174
OCA.Files.Sidebar.registerTab(new OCA.Files.Sidebar.Tab({
4275
id: 'chat',
4376
name: t('spreed', 'Chat'),
4477
icon: 'icon-talk',
4578
enabled: isEnabled,
4679

4780
async mount(el, fileInfo, context) {
48-
if (tabInstance) {
49-
tabInstance.$destroy()
81+
if (PrivateTalk.tabInstance) {
82+
PrivateTalk.tabInstance.$destroy()
5083
}
5184

5285
// Dirty hack to force the style on parent component
@@ -56,17 +89,23 @@ window.addEventListener('DOMContentLoaded', () => {
5689
tabChat.style.padding = '0'
5790

5891
OCA.Talk.fileInfo = this.fileInfo
59-
tabInstance = OCA.Talk.newTab()
60-
tabInstance.$mount(el)
92+
if (OCA.Talk.isFirstLoad === true) {
93+
PrivateTalk.tabInstance = OCA.Talk.loaderTab()
94+
} else {
95+
PrivateTalk.tabInstance = OCA.Talk.newTab()
96+
}
97+
PrivateTalk.tabInstance.$mount(el)
6198
},
6299
update(fileInfo) {
63100
OCA.Talk.fileInfo = fileInfo
64101
},
65102
destroy() {
66103
OCA.Talk.fileInfo = null
67-
tabInstance.$destroy()
68-
tabInstance = null
104+
PrivateTalk.tabInstance.$destroy()
105+
PrivateTalk.tabInstance = null
69106
},
70107
}))
71108
}
72109
})
110+
111+
export default PrivateTalk

webpack.config.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ module.exports = mergeWithRules({
2727
main: path.join(__dirname, 'src', 'main.js'),
2828
recording: path.join(__dirname, 'src', 'mainRecording.js'),
2929
'files-sidebar': [
30-
path.join(__dirname, 'src', 'mainFilesSidebar.js'),
3130
path.join(__dirname, 'src', 'mainFilesSidebarLoader.js'),
3231
],
3332
'public-share-auth-sidebar': path.join(__dirname, 'src', 'mainPublicShareAuthSidebar.js'),

0 commit comments

Comments
 (0)