aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-12-10 15:01:12 +0100
committerChocobozzz <me@florianbigard.com>2021-12-10 15:01:12 +0100
commitd63e6d4604dfbe4938c7d66832c9202364c5bb64 (patch)
tree6bd444be722276ff214d911284a400e374bdddc8 /client/src/app
parent03a65456f44a6152bb68975e29e076c8c5754cd6 (diff)
downloadPeerTube-d63e6d4604dfbe4938c7d66832c9202364c5bb64.tar.gz
PeerTube-d63e6d4604dfbe4938c7d66832c9202364c5bb64.tar.zst
PeerTube-d63e6d4604dfbe4938c7d66832c9202364c5bb64.zip
Add ability for plugins to register client routes
Diffstat (limited to 'client/src/app')
-rw-r--r--client/src/app/+plugin-pages/index.ts3
-rw-r--r--client/src/app/+plugin-pages/plugin-pages-routing.module.ts19
-rw-r--r--client/src/app/+plugin-pages/plugin-pages.component.html1
-rw-r--r--client/src/app/+plugin-pages/plugin-pages.component.ts31
-rw-r--r--client/src/app/+plugin-pages/plugin-pages.module.ts21
-rw-r--r--client/src/app/app-routing.module.ts6
-rw-r--r--client/src/app/core/plugins/plugin.service.ts31
-rw-r--r--client/src/app/core/routing/custom-reuse-strategy.ts2
8 files changed, 109 insertions, 5 deletions
diff --git a/client/src/app/+plugin-pages/index.ts b/client/src/app/+plugin-pages/index.ts
new file mode 100644
index 000000000..b988f13f6
--- /dev/null
+++ b/client/src/app/+plugin-pages/index.ts
@@ -0,0 +1,3 @@
1export * from './plugin-pages-routing.module'
2export * from './plugin-pages.component'
3export * from './plugin-pages.module'
diff --git a/client/src/app/+plugin-pages/plugin-pages-routing.module.ts b/client/src/app/+plugin-pages/plugin-pages-routing.module.ts
new file mode 100644
index 000000000..b47a787e0
--- /dev/null
+++ b/client/src/app/+plugin-pages/plugin-pages-routing.module.ts
@@ -0,0 +1,19 @@
1import { NgModule } from '@angular/core'
2import { RouterModule, Routes } from '@angular/router'
3import { PluginPagesComponent } from './plugin-pages.component'
4
5const pluginPagesRoutes: Routes = [
6 {
7 path: '**',
8 component: PluginPagesComponent,
9 data: {
10 reloadOnSameNavigation: true
11 }
12 }
13]
14
15@NgModule({
16 imports: [ RouterModule.forChild(pluginPagesRoutes) ],
17 exports: [ RouterModule ]
18})
19export class PluginPagesRoutingModule {}
diff --git a/client/src/app/+plugin-pages/plugin-pages.component.html b/client/src/app/+plugin-pages/plugin-pages.component.html
new file mode 100644
index 000000000..cf62d1bd7
--- /dev/null
+++ b/client/src/app/+plugin-pages/plugin-pages.component.html
@@ -0,0 +1 @@
<div #root></div>
diff --git a/client/src/app/+plugin-pages/plugin-pages.component.ts b/client/src/app/+plugin-pages/plugin-pages.component.ts
new file mode 100644
index 000000000..5f294ee13
--- /dev/null
+++ b/client/src/app/+plugin-pages/plugin-pages.component.ts
@@ -0,0 +1,31 @@
1import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router'
3import { PluginService } from '@app/core'
4
5@Component({
6 templateUrl: './plugin-pages.component.html'
7})
8export class PluginPagesComponent implements AfterViewInit {
9 @ViewChild('root') root: ElementRef
10
11 constructor (
12 private route: ActivatedRoute,
13 private router: Router,
14 private pluginService: PluginService
15 ) {
16
17 }
18
19 ngAfterViewInit () {
20 const path = '/' + this.route.snapshot.url.map(u => u.path).join('/')
21
22 const registered = this.pluginService.getRegisteredClientRoute(path)
23 if (!registered) {
24 console.log('Could not find registered route %s.', path, this.pluginService.getAllRegisteredClientRoutes())
25
26 return this.router.navigate([ '/404' ], { skipLocationChange: true })
27 }
28
29 registered.onMount({ rootEl: this.root.nativeElement })
30 }
31}
diff --git a/client/src/app/+plugin-pages/plugin-pages.module.ts b/client/src/app/+plugin-pages/plugin-pages.module.ts
new file mode 100644
index 000000000..86f86c752
--- /dev/null
+++ b/client/src/app/+plugin-pages/plugin-pages.module.ts
@@ -0,0 +1,21 @@
1import { NgModule } from '@angular/core'
2import { PluginPagesRoutingModule } from './plugin-pages-routing.module'
3import { PluginPagesComponent } from './plugin-pages.component'
4
5@NgModule({
6 imports: [
7 PluginPagesRoutingModule
8 ],
9
10 declarations: [
11 PluginPagesComponent
12 ],
13
14 exports: [
15 PluginPagesComponent
16 ],
17
18 providers: [
19 ]
20})
21export class PluginPagesModule { }
diff --git a/client/src/app/app-routing.module.ts b/client/src/app/app-routing.module.ts
index 438cb6512..42328d83d 100644
--- a/client/src/app/app-routing.module.ts
+++ b/client/src/app/app-routing.module.ts
@@ -58,6 +58,12 @@ const routes: Routes = [
58 }, 58 },
59 59
60 { 60 {
61 path: 'p',
62 loadChildren: () => import('./+plugin-pages/plugin-pages.module').then(m => m.PluginPagesModule),
63 canActivateChild: [ MetaGuard ]
64 },
65
66 {
61 path: 'about', 67 path: 'about',
62 loadChildren: () => import('./+about/about.module').then(m => m.AboutModule), 68 loadChildren: () => import('./+about/about.module').then(m => m.AboutModule),
63 canActivateChild: [ MetaGuard ] 69 canActivateChild: [ MetaGuard ]
diff --git a/client/src/app/core/plugins/plugin.service.ts b/client/src/app/core/plugins/plugin.service.ts
index 89391c2c5..fdbbd2d56 100644
--- a/client/src/app/core/plugins/plugin.service.ts
+++ b/client/src/app/core/plugins/plugin.service.ts
@@ -20,7 +20,8 @@ import {
20 PluginType, 20 PluginType,
21 PublicServerSetting, 21 PublicServerSetting,
22 RegisterClientFormFieldOptions, 22 RegisterClientFormFieldOptions,
23 RegisterClientSettingsScript, 23 RegisterClientSettingsScriptOptions,
24 RegisterClientRouteOptions,
24 RegisterClientVideoFieldOptions, 25 RegisterClientVideoFieldOptions,
25 ServerConfigPlugin 26 ServerConfigPlugin
26} from '@shared/models' 27} from '@shared/models'
@@ -48,7 +49,8 @@ export class PluginService implements ClientHook {
48 private formFields: FormFields = { 49 private formFields: FormFields = {
49 video: [] 50 video: []
50 } 51 }
51 private settingsScripts: { [ npmName: string ]: RegisterClientSettingsScript } = {} 52 private settingsScripts: { [ npmName: string ]: RegisterClientSettingsScriptOptions } = {}
53 private clientRoutes: { [ route: string ]: RegisterClientRouteOptions } = {}
52 54
53 private pluginsManager: PluginsManager 55 private pluginsManager: PluginsManager
54 56
@@ -67,7 +69,8 @@ export class PluginService implements ClientHook {
67 this.pluginsManager = new PluginsManager({ 69 this.pluginsManager = new PluginsManager({
68 peertubeHelpersFactory: this.buildPeerTubeHelpers.bind(this), 70 peertubeHelpersFactory: this.buildPeerTubeHelpers.bind(this),
69 onFormFields: this.onFormFields.bind(this), 71 onFormFields: this.onFormFields.bind(this),
70 onSettingsScripts: this.onSettingsScripts.bind(this) 72 onSettingsScripts: this.onSettingsScripts.bind(this),
73 onClientRoute: this.onClientRoute.bind(this)
71 }) 74 })
72 } 75 }
73 76
@@ -123,6 +126,14 @@ export class PluginService implements ClientHook {
123 return this.settingsScripts[npmName] 126 return this.settingsScripts[npmName]
124 } 127 }
125 128
129 getRegisteredClientRoute (route: string) {
130 return this.clientRoutes[route]
131 }
132
133 getAllRegisteredClientRoutes () {
134 return Object.keys(this.clientRoutes)
135 }
136
126 translateBy (npmName: string, toTranslate: string) { 137 translateBy (npmName: string, toTranslate: string) {
127 const helpers = this.helpers[npmName] 138 const helpers = this.helpers[npmName]
128 if (!helpers) { 139 if (!helpers) {
@@ -140,12 +151,20 @@ export class PluginService implements ClientHook {
140 }) 151 })
141 } 152 }
142 153
143 private onSettingsScripts (pluginInfo: PluginInfo, options: RegisterClientSettingsScript) { 154 private onSettingsScripts (pluginInfo: PluginInfo, options: RegisterClientSettingsScriptOptions) {
144 const npmName = this.nameToNpmName(pluginInfo.plugin.name, pluginInfo.pluginType) 155 const npmName = this.nameToNpmName(pluginInfo.plugin.name, pluginInfo.pluginType)
145 156
146 this.settingsScripts[npmName] = options 157 this.settingsScripts[npmName] = options
147 } 158 }
148 159
160 private onClientRoute (options: RegisterClientRouteOptions) {
161 const route = options.route.startsWith('/')
162 ? options.route
163 : `/${options.route}`
164
165 this.clientRoutes[route] = options
166 }
167
149 private buildPeerTubeHelpers (pluginInfo: PluginInfo): RegisterClientHelpers { 168 private buildPeerTubeHelpers (pluginInfo: PluginInfo): RegisterClientHelpers {
150 const { plugin } = pluginInfo 169 const { plugin } = pluginInfo
151 const npmName = this.nameToNpmName(pluginInfo.plugin.name, pluginInfo.pluginType) 170 const npmName = this.nameToNpmName(pluginInfo.plugin.name, pluginInfo.pluginType)
@@ -161,6 +180,10 @@ export class PluginService implements ClientHook {
161 return environment.apiUrl + `${pathPrefix}/${plugin.name}/${plugin.version}/router` 180 return environment.apiUrl + `${pathPrefix}/${plugin.name}/${plugin.version}/router`
162 }, 181 },
163 182
183 getBasePluginClientPath: () => {
184 return '/p'
185 },
186
164 getSettings: () => { 187 getSettings: () => {
165 const path = PluginService.BASE_PLUGIN_API_URL + '/' + npmName + '/public-settings' 188 const path = PluginService.BASE_PLUGIN_API_URL + '/' + npmName + '/public-settings'
166 189
diff --git a/client/src/app/core/routing/custom-reuse-strategy.ts b/client/src/app/core/routing/custom-reuse-strategy.ts
index 1498e221f..5d3ad2e67 100644
--- a/client/src/app/core/routing/custom-reuse-strategy.ts
+++ b/client/src/app/core/routing/custom-reuse-strategy.ts
@@ -58,7 +58,7 @@ export class CustomReuseStrategy implements RouteReuseStrategy {
58 58
59 // Reuse the route if we're going to and from the same route 59 // Reuse the route if we're going to and from the same route
60 shouldReuseRoute (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { 60 shouldReuseRoute (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
61 return future.routeConfig === curr.routeConfig 61 return future.routeConfig === curr.routeConfig && future.routeConfig?.data?.reloadOnSameNavigation !== true
62 } 62 }
63 63
64 private gb () { 64 private gb () {