From 69fcdb75dba0c19c68612e4941c0d4b83d10d1dc Mon Sep 17 00:00:00 2001 From: "Grigorii K. Shartsev" Date: Mon, 20 Jan 2025 18:43:43 +0100 Subject: [PATCH 01/12] refactor: remove CSS loading utils Signed-off-by: Grigorii K. Shartsev --- src/shared/resource.utils.js | 34 ----------------------------- src/talk/renderer/init.js | 42 ------------------------------------ 2 files changed, 76 deletions(-) delete mode 100644 src/shared/resource.utils.js diff --git a/src/shared/resource.utils.js b/src/shared/resource.utils.js deleted file mode 100644 index fe609f07..00000000 --- a/src/shared/resource.utils.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -import { appData } from '../app/AppData.js' - -/** - * Load styles from URL via new element - * - * @param {string} url - Styles URL - * @return {Promise} Created styles link element - */ -export async function loadCss(url) { - return new Promise((resolve, reject) => { - const link = document.createElement('link') - link.rel = 'stylesheet' - link.href = url - document.querySelector('head').appendChild(link) - link.onload = () => resolve(link) - link.onerror = (error) => reject(error) - }) - -} - -/** - * Load styles from URL via loadCss from server host - * - * @param {string} url - Styles URL - * @return {Promise} Created styles link element - */ -export function loadServerCss(url) { - return loadCss(`${appData.serverUrl}${url}`) -} diff --git a/src/talk/renderer/init.js b/src/talk/renderer/init.js index ec748474..68b15a3a 100644 --- a/src/talk/renderer/init.js +++ b/src/talk/renderer/init.js @@ -3,49 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -import { loadServerCss } from '../../shared/resource.utils.js' import { appData } from '../../app/AppData.js' -import { getCapabilities } from '../../shared/ocs.service.js' - -/** - * Fetch and load server styles. - * Currently unused, until this feature is available - * @return {Promise} - */ -export async function initServerStyles() { - // Load application styles from server - await Promise.all([ - loadServerCss('/apps/theming/css/default.css'), - loadServerCss('/index.php/apps/theming/theme/light.css'), - loadServerCss('/index.php/apps/theming/theme/dark.css'), - loadServerCss('/core/css/server.css'), - ]).catch(async () => { - // It is not possible to determine why styles loading failed in a web-browser - // There are 2 the most likely reasons: - // 1. Invalid authentication (401 or 500) - // 2. Server is unavailable - - // Request any data from the server to check - await getCapabilities() - }).catch((error) => { - // Problem #1 is handled globally - // For problem #2 - just quit until the app supports opening offline - if (![401, 500].includes(error.response?.status)) { - // Mark Talk hash dirty to check server availability on the next app start - appData.setTalkHashDirty(true).persist() - alert(t('talk_desktop', 'Cannot connect to the server. Please check your internet connection and try again later.')) - window.TALK_DESKTOP.quit() - } - }) -} - -/** - * @return {Promise} - */ -export async function initLocalStyles() { - // Load styles overrides - await import('./assets/overrides.css') -} /** * @typedef TalkHashStoreAdapter From 6d5127a9b31bb7f9677a358cc68db78d79aefb05 Mon Sep 17 00:00:00 2001 From: "Grigorii K. Shartsev" Date: Mon, 20 Jan 2025 15:13:45 +0100 Subject: [PATCH 02/12] refactor(talk): move route hash init to the setupWebPage Signed-off-by: Grigorii K. Shartsev --- src/shared/setupWebPage.js | 7 ++++++- src/talk/renderer/talk.main.js | 8 +++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/shared/setupWebPage.js b/src/shared/setupWebPage.js index 8f92fd47..a76b69c8 100644 --- a/src/shared/setupWebPage.js +++ b/src/shared/setupWebPage.js @@ -215,8 +215,13 @@ function applyDownloadLinkHandler() { /** * Make all required initial setup for the web page for authorized user: server-rendered data, globals and ect. + * @param {object} options - options + * @param {string} options.routeHash - Initial route hash */ -export async function setupWebPage() { +export async function setupWebPage({ routeHash } = {}) { + if (!window.location.hash && routeHash) { + window.location.hash = routeHash + } document.title = await window.TALK_DESKTOP.getTitle() appData.restore() await initAppConfig() diff --git a/src/talk/renderer/talk.main.js b/src/talk/renderer/talk.main.js index a5799c21..4914211e 100644 --- a/src/talk/renderer/talk.main.js +++ b/src/talk/renderer/talk.main.js @@ -18,11 +18,9 @@ import { registerTalkDesktopSettingsSection } from './Settings/index.ts' import { openConversation } from './utils/talk.service.ts' // Initially open the welcome page, if not specified -if (!window.location.hash) { - window.location.hash = '#/apps/spreed' -} - -await setupWebPage() +await setupWebPage({ + routeHash: '#/apps/spreed', +}) createDesktopApp() From 354da13620d954243d79431dbe7a5f8f5db8063a Mon Sep 17 00:00:00 2001 From: "Grigorii K. Shartsev" Date: Mon, 20 Jan 2025 18:24:24 +0100 Subject: [PATCH 03/12] refactor(talk): move talk.service.ts to TalkWrapper Signed-off-by: Grigorii K. Shartsev --- src/talk/renderer/{utils => TalkWrapper}/talk.service.ts | 0 src/talk/renderer/notifications/notifications.store.js | 2 +- src/talk/renderer/talk.main.js | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/talk/renderer/{utils => TalkWrapper}/talk.service.ts (100%) diff --git a/src/talk/renderer/utils/talk.service.ts b/src/talk/renderer/TalkWrapper/talk.service.ts similarity index 100% rename from src/talk/renderer/utils/talk.service.ts rename to src/talk/renderer/TalkWrapper/talk.service.ts diff --git a/src/talk/renderer/notifications/notifications.store.js b/src/talk/renderer/notifications/notifications.store.js index 3a808572..5d50b3c9 100644 --- a/src/talk/renderer/notifications/notifications.store.js +++ b/src/talk/renderer/notifications/notifications.store.js @@ -23,7 +23,7 @@ import { useUserStatusStore } from '../UserStatus/userStatus.store.ts' import { checkCurrentUserHasPendingCall } from '../../../callbox/renderer/callbox.service.ts' import { getAppConfigValue } from '../../../shared/appConfig.service.ts' import { subscribeBroadcast } from '../../../shared/broadcast.service.ts' -import { openConversation } from '../utils/talk.service.ts' +import { openConversation } from '../TalkWrapper/talk.service.ts' const userStatusStore = useUserStatusStore() diff --git a/src/talk/renderer/talk.main.js b/src/talk/renderer/talk.main.js index 4914211e..78ca0bff 100644 --- a/src/talk/renderer/talk.main.js +++ b/src/talk/renderer/talk.main.js @@ -15,7 +15,7 @@ import { subscribeBroadcast } from '../../shared/broadcast.service.ts' import { createViewer } from './Viewer/Viewer.js' import { createDesktopApp } from './desktop.app.ts' import { registerTalkDesktopSettingsSection } from './Settings/index.ts' -import { openConversation } from './utils/talk.service.ts' +import { openConversation } from './TalkWrapper/talk.service.ts' // Initially open the welcome page, if not specified await setupWebPage({ From 0cfbb03ded0e9a76040a0683c411d38bf5f7caf5 Mon Sep 17 00:00:00 2001 From: "Grigorii K. Shartsev" Date: Mon, 20 Jan 2025 18:36:43 +0100 Subject: [PATCH 04/12] refactor(talk): do not rely on Talk Router reactivity Signed-off-by: Grigorii K. Shartsev --- src/shared/globals/globals.js | 3 -- src/talk/renderer/TalkWrapper/talk.service.ts | 54 ++++++++++++++++--- src/talk/renderer/TitleBar/TitleBar.vue | 12 ++--- .../renderer/TitleBar/components/MainMenu.vue | 10 ++-- src/talk/renderer/talk.main.js | 2 - 5 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/shared/globals/globals.js b/src/shared/globals/globals.js index f001053d..cd62d9b1 100644 --- a/src/shared/globals/globals.js +++ b/src/shared/globals/globals.js @@ -3,8 +3,6 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -import { ref } from 'vue' - import { loadState } from '@nextcloud/initial-state' import { translate, translatePlural } from '@nextcloud/l10n' @@ -110,7 +108,6 @@ const OCA = { getDesktopMediaSource, runWithAbsoluteWebroot, enabledAbsoluteWebroot: false, - talkRouter: ref(null), }, }, } diff --git a/src/talk/renderer/TalkWrapper/talk.service.ts b/src/talk/renderer/TalkWrapper/talk.service.ts index d60e3802..a7d0ea6f 100644 --- a/src/talk/renderer/TalkWrapper/talk.service.ts +++ b/src/talk/renderer/TalkWrapper/talk.service.ts @@ -1,8 +1,42 @@ /* - * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ +import { isNavigationFailure, NavigationFailureType } from '@talk/node_modules/vue-router' + +/** + * Get the Talk instance + */ +function getTalkInstance() { + if (!window.OCA.Talk?.instance) { + throw new Error('Talk is not initialized yet or not available') + } + return window.OCA.Talk.instance +} + +/** + * Get the Talk router + */ +function getTalkRouter() { + return getTalkInstance().$router +} + +/** + * Get the current Talk route path + */ +export function getCurrentTalkRoutePath() { + // TODO: add Vue 3 compatibility + return getTalkRouter().currentRoute.fullPath +} + +/** + * Open the Talk root + */ +export function openRoot() { + getTalkRouter().push({ name: 'root' }).catch(passDuplicatedNavigationError) +} + /** * Open a conversation in Talk * @param token - Conversation token @@ -10,15 +44,21 @@ * @param options.directCall - Use direct call (open media settings to join a call) */ export async function openConversation(token: string, { directCall = false }: { directCall?: boolean } = {}) { - if (!window.OCA.Talk?.instance) { - throw new Error('Talk is not initialized yet or not available') - } - - await window.OCA.Talk.instance.$router.push({ + await getTalkRouter().push({ name: 'conversation', params: { token }, hash: directCall ? '#direct-call' : undefined, - }) + }).catch(passDuplicatedNavigationError) await window.TALK_DESKTOP.focusTalk() } + +/** + * Ignore duplicated navigation error + * @param error - Error + */ +function passDuplicatedNavigationError(error: Error) { + if (!isNavigationFailure(error, NavigationFailureType.duplicated)) { + throw error + } +} diff --git a/src/talk/renderer/TitleBar/TitleBar.vue b/src/talk/renderer/TitleBar/TitleBar.vue index e3001067..87b3af29 100644 --- a/src/talk/renderer/TitleBar/TitleBar.vue +++ b/src/talk/renderer/TitleBar/TitleBar.vue @@ -11,6 +11,7 @@ import { appData } from '../../../app/AppData.js' import { useUserStatusStore } from '../UserStatus/userStatus.store.ts' import { useAppConfigStore } from '../Settings/appConfig.store.ts' import { useUserStatusHeartbeat } from '../UserStatus/useUserStatusHeartbeat.ts' +import { openRoot } from '../TalkWrapper/talk.service.ts' useUserStatusStore() useUserStatusHeartbeat() @@ -22,13 +23,6 @@ const channel = __CHANNEL__ const user = appData.userMetadata! as { id: string; 'display-name': string } const OS = window.systemInfo -/** - * Push to root in Talk app to unselect any chat - */ -function pushToRoot() { - window.OCA.Talk.instance?.$router?.push({ name: 'root' }).catch(() => {}) -} - /** * Logout in Talk Desktop */ @@ -37,7 +31,7 @@ function logout() { } // Unselect chat by escape key -useHotKey('Escape', pushToRoot) +useHotKey('Escape', openRoot)