feat: add support for sub routes under /my-account

closes #6217
pull/6218/head
kontrollanten 2024-02-12 15:12:39 +01:00
parent 7eb0189b73
commit 8b47a94ec0
11 changed files with 74 additions and 16 deletions

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core'
import { AuthUser, ScreenService } from '@app/core'
import { AuthUser, PluginService, ScreenService } from '@app/core'
import { TopMenuDropdownParam, TopMenuDropdownComponent } from '../shared/shared-main/misc/top-menu-dropdown.component'
import { RouterOutlet } from '@angular/router'
import { NgClass } from '@angular/common'
@ -15,17 +15,23 @@ export class MyAccountComponent implements OnInit {
menuEntries: TopMenuDropdownParam[] = []
user: AuthUser
constructor (private screenService: ScreenService) { }
constructor (
private pluginService: PluginService,
private screenService: ScreenService
) { }
get isBroadcastMessageDisplayed () {
return this.screenService.isBroadcastMessageDisplayed
}
ngOnInit (): void {
this.pluginService.ensurePluginsAreLoaded('my-account')
.then(() => this.buildMenu())
this.buildMenu()
}
private buildMenu () {
const clientRoutes = this.pluginService.getRegisteredClientRouteSForParent('/my-account') || {}
const moderationEntries: TopMenuDropdownParam = {
label: $localize`Moderation`,
children: [
@ -68,7 +74,14 @@ export class MyAccountComponent implements OnInit {
routerLink: '/my-account/applications'
},
moderationEntries
moderationEntries,
...Object.values(clientRoutes)
.filter((clientRoute) => clientRoute.menuItem?.label)
.map((clientRoute) => ({
label: clientRoute.menuItem.label,
routerLink: '/my-account/p/' + clientRoute.route
}))
]
}
}

View File

@ -14,6 +14,7 @@ import { BlocklistService } from '@app/shared/shared-moderation/blocklist.servic
import { VideoBlockService } from '@app/shared/shared-moderation/video-block.service'
import { TwoFactorService } from '@app/shared/shared-users/two-factor.service'
import { VideoCommentService } from '@app/shared/shared-video-comment/video-comment.service'
import { SharedPluginPagesComponent } from '@app/shared/shared-plugin-pages/plugin-pages.component'
export default [
{
@ -160,6 +161,19 @@ export default [
title: $localize`Import/Export`
}
}
},
{
path: 'p',
children: [
{
path: '**',
component: SharedPluginPagesComponent,
data: {
parentRoute: '/my-account',
pluginScope: 'my-account'
}
}
]
}
]
}

View File

@ -62,8 +62,11 @@ const routes: Routes = [
},
{
path: 'p',
loadChildren: () => import('./+plugin-pages/routes'),
canActivateChild: [ MetaGuard ]
loadChildren: () => import('./shared/shared-plugin-pages/routes'),
canActivateChild: [ MetaGuard ],
data: {
parentRoute: '/'
}
},
{

View File

@ -50,7 +50,11 @@ export class PluginService implements ClientHook {
video: []
}
private settingsScripts: { [ npmName: string ]: RegisterClientSettingsScriptOptions } = {}
private clientRoutes: { [ route: string ]: RegisterClientRouteOptions } = {}
private clientRoutes: {
[ parentRoute: string ]: {
[ route: string ]: RegisterClientRouteOptions
}
} = {}
private pluginsManager: PluginsManager
@ -126,12 +130,24 @@ export class PluginService implements ClientHook {
return this.settingsScripts[npmName]
}
getRegisteredClientRoute (route: string) {
return this.clientRoutes[route]
getRegisteredClientRoute (route: string, parentRoute: string) {
if (!this.clientRoutes[parentRoute]) {
return undefined
}
return this.clientRoutes[parentRoute][route]
}
getRegisteredClientRouteSForParent (parentRoute: string) {
return this.clientRoutes[parentRoute]
}
getAllRegisteredClientRoutes () {
return Object.keys(this.clientRoutes)
.map((parentRoute) =>
Object.keys(this.clientRoutes[parentRoute]).map((route) => parentRoute === '/' ? route : parentRoute + route)
)
.flat()
}
async translateSetting (npmName: string, setting: RegisterClientFormFieldOptions) {
@ -183,8 +199,13 @@ export class PluginService implements ClientHook {
const route = options.route.startsWith('/')
? options.route
: `/${options.route}`
const parentRoute = options.parentRoute || '/'
this.clientRoutes[route] = options
if (!this.clientRoutes[parentRoute]) {
this.clientRoutes[parentRoute] = {}
}
this.clientRoutes[parentRoute][route] = options
}
private buildPeerTubeHelpers (pluginInfo: PluginInfo): RegisterClientHelpers {

View File

@ -0,0 +1 @@
export * from './plugin-pages.component'

View File

@ -7,7 +7,7 @@ import { logger } from '@root-helpers/logger'
templateUrl: './plugin-pages.component.html',
standalone: true
})
export class PluginPagesComponent implements AfterViewInit {
export class SharedPluginPagesComponent implements AfterViewInit {
@ViewChild('root') root: ElementRef
constructor (
@ -19,14 +19,14 @@ export class PluginPagesComponent implements AfterViewInit {
}
ngAfterViewInit () {
this.pluginService.ensurePluginsAreLoaded('common')
this.pluginService.ensurePluginsAreLoaded(this.route.snapshot.data.pluginScope || 'common')
.then(() => this.loadRoute())
}
private loadRoute () {
const path = '/' + this.route.snapshot.url.map(u => u.path).join('/')
const registered = this.pluginService.getRegisteredClientRoute(path)
const registered = this.pluginService.getRegisteredClientRoute(path, this.route.snapshot.data.parentRoute)
if (!registered) {
logger.info(`Could not find registered route ${path}`, this.pluginService.getAllRegisteredClientRoutes())

View File

@ -1,10 +1,10 @@
import { Routes } from '@angular/router'
import { PluginPagesComponent } from './plugin-pages.component'
import { SharedPluginPagesComponent } from './plugin-pages.component'
export default [
{
path: '**',
component: PluginPagesComponent,
component: SharedPluginPagesComponent,
data: {
reloadOnSameNavigation: true
}

View File

@ -70,7 +70,8 @@ class PluginsManager {
'video-edit': new ReplaySubject<boolean>(1),
'embed': new ReplaySubject<boolean>(1),
'my-library': new ReplaySubject<boolean>(1),
'video-channel': new ReplaySubject<boolean>(1)
'video-channel': new ReplaySubject<boolean>(1),
'my-account': new ReplaySubject<boolean>(1)
}
private readonly peertubeHelpersFactory: PeertubeHelpersFactory

View File

@ -8,4 +8,5 @@ export type PluginClientScope =
'video-edit' |
'admin-plugin' |
'my-library' |
'video-channel'
'video-channel' |
'my-account'

View File

@ -1,5 +1,9 @@
export interface RegisterClientRouteOptions {
route: string
parentRoute?: string
menuItem?: {
label?: string
}
onMount (options: {
rootEl: HTMLElement