chore(vue3): migrate to Vue Router 4, adapt NcListItem

- query and hash are not considered when matching active router-link

Signed-off-by: Dorra Jaouad <dorra.jaoued7@gmail.com>
Signed-off-by: Grigorii K. Shartsev <me@shgk.me>
Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
This commit is contained in:
Maksim Sukharev
2025-06-21 15:54:38 +02:00
parent e52ce05387
commit b329eba7b2
11 changed files with 24 additions and 20 deletions

View File

@ -12,7 +12,7 @@ import { imagePath } from '@nextcloud/router'
import usernameToColor from '@nextcloud/vue/functions/usernameToColor'
import { useNow } from '@vueuse/core'
import { computed } from 'vue'
import { useRouter } from 'vue-router/composables'
import { useRouter } from 'vue-router'
import NcButton from '@nextcloud/vue/components/NcButton'
import NcChip from '@nextcloud/vue/components/NcChip'
import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'

View File

@ -8,7 +8,7 @@ import { emit } from '@nextcloud/event-bus'
import { isRTL, t } from '@nextcloud/l10n'
import { generateUrl } from '@nextcloud/router'
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router/composables'
import { useRouter } from 'vue-router'
import NcButton from '@nextcloud/vue/components/NcButton'
import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'
import NcInputField from '@nextcloud/vue/components/NcInputField'

View File

@ -7,7 +7,7 @@
import { showError } from '@nextcloud/dialogs'
import { t } from '@nextcloud/l10n'
import { provide, ref, watch } from 'vue'
import { useRouter } from 'vue-router/composables'
import { useRouter } from 'vue-router'
import NcButton from '@nextcloud/vue/components/NcButton'
import NcPopover from '@nextcloud/vue/components/NcPopover'
import IconAccountMultiplePlus from 'vue-material-design-icons/AccountMultiplePlus.vue'

View File

@ -7,6 +7,7 @@
import { t } from '@nextcloud/l10n'
import moment from '@nextcloud/moment'
import { computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import NcActionButton from '@nextcloud/vue/components/NcActionButton'
import NcDateTime from '@nextcloud/vue/components/NcDateTime'
import NcListItem from '@nextcloud/vue/components/NcListItem'
@ -60,6 +61,8 @@ const props = defineProps({
},
})
const router = useRouter()
const route = useRoute()
const store = useStore()
const dashboardStore = useDashboardStore()
@ -91,12 +94,17 @@ const clearReminderLabel = computed(() => {
}
return t('spreed', 'Clear reminder {timeLocale}', { timeLocale: moment(+props.timestamp * 1000).format('ddd LT') })
})
const active = computed(() => {
return route.fullPath === router.resolve(props.to).fullPath
})
</script>
<template>
<NcListItem :data-nav-id="`message_${messageId}`"
:name="name"
:to="to"
:active="active"
:title="richSubline"
force-menu>
<template #icon>

View File

@ -4,7 +4,7 @@
-->
<script setup lang="ts">
import type { Route } from 'vue-router'
import type { RouteLocation } from 'vue-router'
import type {
Participant,
SearchMessagePayload,
@ -108,7 +108,7 @@ onBeforeUnmount(() => {
abortSearch()
})
const onRouteChange = ({ from, to }: { from: Route, to: Route }): void => {
const onRouteChange = ({ from, to }: { from: RouteLocation, to: RouteLocation }): void => {
if (to.name !== 'conversation' || from.params.token !== to.params.token || (to.hash && isInCall.value)) {
abortSearch()
emit('close')

View File

@ -9,7 +9,7 @@ import { getLanguage, t } from '@nextcloud/l10n'
import { spawnDialog } from '@nextcloud/vue/functions/dialog'
import { computed } from 'vue'
import { isNavigationFailure, NavigationFailureType } from 'vue-router'
import { useRoute, useRouter } from 'vue-router/composables'
import { useRoute, useRouter } from 'vue-router'
import NcButton from '@nextcloud/vue/components/NcButton'
import IconCheckUnderline from 'vue-material-design-icons/CheckUnderline.vue'
import IconDelete from 'vue-material-design-icons/Delete.vue'

View File

@ -3,12 +3,12 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { Route } from 'vue-router'
import type { RouteLocation } from 'vue-router'
import type { Conversation } from '../types/index.ts'
import { t } from '@nextcloud/l10n'
import { computed, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router/composables'
import { useRoute, useRouter } from 'vue-router'
import { EventBus } from '../services/EventBus.ts'
import { useActorStore } from '../stores/actor.ts'
import { hasCall, hasUnreadMentions } from '../utils/conversation.ts'
@ -134,7 +134,7 @@ export function useDocumentTitle() {
*
* @param route current web route
*/
function setPageTitleFromRoute(route: Route) {
function setPageTitleFromRoute(route: RouteLocation) {
switch (route.name) {
case 'conversation':
setPageTitle(store.getters.conversation(route.params.token)?.displayName ?? '')

View File

@ -4,8 +4,7 @@
*/
import { generateUrl, getRootUrl } from '@nextcloud/router'
import Vue from 'vue'
import Router from 'vue-router'
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
import CallView from '../components/CallView/CallView.vue'
import ForbiddenView from '../views/ForbiddenView.vue'
import MainView from '../views/MainView.vue'
@ -13,8 +12,6 @@ import NotFoundView from '../views/NotFoundView.vue'
import SessionConflictView from '../views/SessionConflictView.vue'
import WelcomeView from '../views/WelcomeView.vue'
Vue.use(Router)
/**
* Generate base url for Talk Web app based on server's root
*
@ -30,10 +27,9 @@ function generateTalkWebBasePath(): string {
})
}
export default new Router({
export default createRouter({
// On desktop (Electron) app is open via file:// protocol - History API is not available and no base path
mode: !IS_DESKTOP ? 'history' : 'hash',
base: !IS_DESKTOP ? generateTalkWebBasePath() : '',
history: !IS_DESKTOP ? createWebHistory(generateTalkWebBasePath()) : createWebHashHistory(''),
linkActiveClass: 'active',

View File

@ -4,7 +4,7 @@
*/
import type { Emitter, EventType, Handler, WildcardHandler } from 'mitt'
import type { Route } from 'vue-router'
import type { RouteLocation } from 'vue-router'
import type {
ChatMessage,
Conversation,
@ -37,7 +37,7 @@ export type Events = {
'refresh-peer-list': void
'refresh-talk-dashboard': void
'retry-message': number
'route-change': { from: Route, to: Route }
'route-change': { from: RouteLocation, to: RouteLocation }
'scroll-chat-to-bottom': { smooth?: boolean, force?: boolean }
'should-refresh-chat-messages': void
'should-refresh-conversations': { token: string, properties: Partial<Conversation> } | { all: true } | void

View File

@ -5,7 +5,7 @@
<script lang="ts" setup>
import { emit } from '@nextcloud/event-bus'
import { computed, onMounted, watch, watchEffect } from 'vue'
import { useRoute, useRouter } from 'vue-router/composables'
import { useRoute, useRouter } from 'vue-router'
import CallFailedDialog from '../components/CallView/CallFailedDialog.vue'
import CallView from '../components/CallView/CallView.vue'
import ChatView from '../components/ChatView.vue'

View File

@ -7,7 +7,7 @@
import { showError } from '@nextcloud/dialogs'
import { t } from '@nextcloud/l10n'
import { computed, ref, watchEffect } from 'vue'
import { useRoute, useRouter } from 'vue-router/composables'
import { useRoute, useRouter } from 'vue-router'
import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
import TalkDashboard from '../components/Dashboard/TalkDashboard.vue'