fix(router): implement memory router for integrations

Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
This commit is contained in:
Maksim Sukharev 2025-07-31 17:51:33 +02:00
parent 85727011d7
commit f2f6ce8a16
8 changed files with 58 additions and 9 deletions

View file

@ -178,6 +178,7 @@ export default {
// if this conversation is joined again.
await this.$store.dispatch('purgeParticipantsStore', this.token)
await this.$router.push({ name: 'conversation', params: { token: this.token } })
await this.$store.dispatch('joinConversation', { token: this.token })
// The current participant (which is automatically set when fetching

View file

@ -14,7 +14,7 @@
<TopBar is-in-call is-sidebar />
<CallView :token="token" is-sidebar />
<InternalSignalingHint />
<ChatView is-sidebar />
<RouterView />
<PollManager />
<PollViewer />
<MediaSettings v-model:recording-consent-given="recordingConsentGiven" />
@ -29,7 +29,6 @@ import { emit } from '@nextcloud/event-bus'
import { loadState } from '@nextcloud/initial-state'
import { t } from '@nextcloud/l10n'
import CallView from './components/CallView/CallView.vue'
import ChatView from './components/ChatView.vue'
import MediaSettings from './components/MediaSettings/MediaSettings.vue'
import PollManager from './components/PollViewer/PollManager.vue'
import PollViewer from './components/PollViewer/PollViewer.vue'
@ -56,7 +55,6 @@ export default {
components: {
InternalSignalingHint,
CallView,
ChatView,
MediaSettings,
PollManager,
PollViewer,
@ -136,6 +134,7 @@ export default {
this.actorStore.setDisplayName(guestNickname)
}
await this.$router.push({ name: 'conversation', params: { token: this.token } })
await this.$store.dispatch('joinConversation', { token: this.token })
// Add guest name to the store, only possible after joining the conversation

View file

@ -25,7 +25,7 @@
<InternalSignalingHint />
<CallButton v-if="!isInCall" class="call-button" />
<CallFailedDialog v-if="connectionFailed" :token="token" />
<ChatView is-sidebar />
<RouterView />
<PollManager />
<PollViewer />
<MediaSettings v-model:recording-consent-given="recordingConsentGiven" />
@ -42,7 +42,6 @@ import NcButton from '@nextcloud/vue/components/NcButton'
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
import CallFailedDialog from './components/CallView/CallFailedDialog.vue'
import CallView from './components/CallView/CallView.vue'
import ChatView from './components/ChatView.vue'
import MediaSettings from './components/MediaSettings/MediaSettings.vue'
import PollManager from './components/PollViewer/PollManager.vue'
import PollViewer from './components/PollViewer/PollViewer.vue'
@ -73,7 +72,6 @@ export default {
CallButton,
CallFailedDialog,
CallView,
ChatView,
MediaSettings,
NcButton,
NcLoadingIcon,
@ -173,6 +171,7 @@ export default {
try {
await this.getPublicShareConversationData()
await this.$router.push({ name: 'conversation', params: { token: this.token } })
await this.$store.dispatch('joinConversation', { token: this.token })
} catch (exception) {
this.joiningConversation = false

View file

@ -8,6 +8,7 @@ import { generateFilePath } from '@nextcloud/router'
import { createApp, reactive } from 'vue'
import FilesSidebarCallViewApp from './FilesSidebarCallViewApp.vue'
import FilesSidebarTabApp from './FilesSidebarTabApp.vue'
import { createMemoryRouter } from './router/router.ts'
import store from './store/index.js'
import pinia from './stores/pinia.ts'
import { NextcloudGlobalsVuePlugin } from './utils/NextcloudGlobalsVuePlugin.js'
@ -27,14 +28,18 @@ __webpack_nonce__ = getCSPNonce()
// We do not want the index.php since we're loading files
__webpack_public_path__ = generateFilePath('spreed', '', 'js/')
const router = createMemoryRouter()
const newCallView = () => createApp(FilesSidebarCallViewApp)
.use(store)
.use(pinia)
.use(router)
.use(NextcloudGlobalsVuePlugin)
const newTab = () => createApp(FilesSidebarTabApp)
.use(store)
.use(pinia)
.use(router)
.use(NextcloudGlobalsVuePlugin)
if (!window.OCA.Talk) {

View file

@ -8,6 +8,7 @@ import { generateFilePath } from '@nextcloud/router'
import { createApp } from 'vue'
import PublicShareAuthRequestPasswordButton from './PublicShareAuthRequestPasswordButton.vue'
import PublicShareAuthSidebar from './PublicShareAuthSidebar.vue'
import { createMemoryRouter } from './router/router.ts'
import store from './store/index.js'
import pinia from './stores/pinia.ts'
import { NextcloudGlobalsVuePlugin } from './utils/NextcloudGlobalsVuePlugin.js'
@ -87,14 +88,18 @@ function getShareToken() {
return shareTokenElement.value
}
const router = createMemoryRouter()
createApp(PublicShareAuthRequestPasswordButton, { shareToken: getShareToken() })
.use(pinia)
.use(store)
.use(router)
.use(NextcloudGlobalsVuePlugin)
.mount('#request-password')
createApp(PublicShareAuthSidebar)
.use(pinia)
.use(store)
.use(router)
.use(NextcloudGlobalsVuePlugin)
.mount(document.querySelector('#talk-sidebar'))

View file

@ -9,6 +9,7 @@ import { getSharingToken } from '@nextcloud/sharing/public'
import { createApp, reactive } from 'vue'
import PublicShareSidebar from './PublicShareSidebar.vue'
import PublicShareSidebarTrigger from './PublicShareSidebarTrigger.vue'
import { createMemoryRouter } from './router/router.ts'
import store from './store/index.js'
import pinia from './stores/pinia.ts'
import { NextcloudGlobalsVuePlugin } from './utils/NextcloudGlobalsVuePlugin.js'
@ -69,12 +70,15 @@ function addTalkSidebar() {
talkSidebarElement.setAttribute('id', 'talk-sidebar')
document.getElementById('content-vue').appendChild(talkSidebarElement)
const router = createMemoryRouter()
createApp(PublicShareSidebar, {
shareToken: getSharingToken(),
state: sidebarState,
})
.use(pinia)
.use(store)
.use(router)
.use(NextcloudGlobalsVuePlugin)
.mount(document.querySelector('#talk-sidebar'))
}

View file

@ -7,16 +7,19 @@ import type { RouteRecordRaw } from 'vue-router'
import { generateUrl, getRootUrl } from '@nextcloud/router'
import {
createMemoryHistory,
createRouter,
createWebHashHistory,
createWebHistory,
} from 'vue-router'
import CallView from '../components/CallView/CallView.vue'
import ChatView from '../components/ChatView.vue'
import ForbiddenView from '../views/ForbiddenView.vue'
import MainView from '../views/MainView.vue'
import NotFoundView from '../views/NotFoundView.vue'
import SessionConflictView from '../views/SessionConflictView.vue'
import WelcomeView from '../views/WelcomeView.vue'
import { EventBus } from '../services/EventBus.ts'
/**
* Generate base url for Talk Web app based on server's root
@ -83,3 +86,38 @@ export function createTalkRouter() {
routes,
})
}
/**
* Returns a router object for the integration app (Files Sidebar, Files Share authentication)
*/
export function createMemoryRouter() {
const routes: RouteRecordRaw[] = [
{
path: '/call/:token',
name: 'conversation',
component: ChatView,
props: { isSidebar: true },
},
]
const router = createRouter({
history: createMemoryHistory(generateTalkWebBasePath()),
routes,
})
router.beforeEach((to, from) => {
if (to.name === 'conversation' && (from.params.token && from.params.token !== to.params.token)) {
// in case of a link to a different conversation, open it in a new tab
window.open(window.location.origin + router.resolve(to).href, '_blank', 'noopener,noreferrer')
// cancel the navigation in current tab
return false
} else if (to.name !== 'conversation') {
// cancel the navigation in current tab
return false
}
EventBus.emit('route-change', { from, to })
})
return router
}

View file

@ -8,7 +8,7 @@
<InternalSignalingHint />
<CallButton v-if="!isInCall" class="talk-tab__call-button" />
<CallFailedDialog v-if="connectionFailed" :token="token" />
<ChatView class="talk-tab__chat-view" is-sidebar />
<RouterView class="talk-tab__chat-view" />
<PollManager />
<PollViewer />
<MediaSettings v-model:recording-consent-given="recordingConsentGiven" />
@ -18,7 +18,6 @@
<script>
import CallFailedDialog from '../components/CallView/CallFailedDialog.vue'
import ChatView from '../components/ChatView.vue'
import MediaSettings from '../components/MediaSettings/MediaSettings.vue'
import PollManager from '../components/PollViewer/PollManager.vue'
import PollViewer from '../components/PollViewer/PollViewer.vue'
@ -36,7 +35,6 @@ export default {
InternalSignalingHint,
CallButton,
CallFailedDialog,
ChatView,
MediaSettings,
PollManager,
PollViewer,