feat(plugins): add doAction increment/decrement loader

Support for plugins to show application loader.
This commit is contained in:
kontrollanten 2024-10-25 06:10:48 +02:00
parent 8c5c8b7032
commit 373052c2ec
5 changed files with 63 additions and 3 deletions

View File

@ -1,7 +1,7 @@
import { delay, forkJoin } from 'rxjs'
import { delay, forkJoin, from } from 'rxjs'
import { filter, first, map } from 'rxjs/operators'
import { DOCUMENT, getLocaleDirection, PlatformLocation, NgIf, NgClass } from '@angular/common'
import { AfterViewInit, Component, Inject, LOCALE_ID, OnInit, ViewChild } from '@angular/core'
import { AfterViewInit, Component, Inject, LOCALE_ID, OnDestroy, OnInit, ViewChild } from '@angular/core'
import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
import { Event, GuardsCheckStart, RouteConfigLoadEnd, RouteConfigLoadStart, Router, RouterLink, RouterOutlet } from '@angular/router'
import {
@ -65,7 +65,7 @@ import { InstanceService } from './shared/shared-main/instance/instance.service'
CustomModalComponent
]
})
export class AppComponent implements OnInit, AfterViewInit {
export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
private static BROADCAST_MESSAGE_KEY = 'app-broadcast-message-dismissed'
@ViewChild('accountSetupWarningModal') accountSetupWarningModal: AccountSetupWarningModalComponent
@ -152,12 +152,28 @@ export class AppComponent implements OnInit, AfterViewInit {
this.document.documentElement.lang = getShortLocale(this.localeId)
this.document.documentElement.dir = getLocaleDirection(this.localeId)
this.pluginService.addAction('application:increment-loader', () => {
this.loadingBar.useRef('plugins').start()
return from([])
})
this.pluginService.addAction('application:decrement-loader', () => {
this.loadingBar.useRef('plugins').complete()
return from([])
})
}
ngAfterViewInit () {
this.pluginService.initializeCustomModal(this.customModal)
}
ngOnDestroy () {
this.pluginService.removeAction('application:increment-loader')
this.pluginService.removeAction('application:decrement-loader')
}
// ---------------------------------------------------------------------------
getDefaultRoute () {

View File

@ -12,6 +12,8 @@ import { getDevLocale, isOnDevLocale } from '@app/helpers'
import { CustomModalComponent } from '@app/modal/custom-modal.component'
import { getCompleteLocale, getKeys, isDefaultLocale, peertubeTranslate } from '@peertube/peertube-core-utils'
import {
ClientDoActionCallback,
ClientDoActionName,
ClientHook,
ClientHookName,
PluginClientScope,
@ -28,6 +30,7 @@ import {
import { PluginInfo, PluginsManager } from '@root-helpers/plugins-manager'
import { environment } from '../../../environments/environment'
import { RegisterClientHelpers } from '../../../types/register-client-option.model'
import { logger } from '@root-helpers/logger'
type FormFields = {
video: {
@ -58,6 +61,8 @@ export class PluginService implements ClientHook {
private pluginsManager: PluginsManager
private actions: { [name in ClientDoActionName]?: ClientDoActionCallback } = {}
constructor (
private authService: AuthService,
private notifier: Notifier,
@ -71,6 +76,7 @@ export class PluginService implements ClientHook {
this.loadTranslations()
this.pluginsManager = new PluginsManager({
doAction: this.doAction.bind(this),
peertubeHelpersFactory: this.buildPeerTubeHelpers.bind(this),
onFormFields: this.onFormFields.bind(this),
onSettingsScripts: this.onSettingsScripts.bind(this),
@ -78,6 +84,14 @@ export class PluginService implements ClientHook {
})
}
addAction (actionName: ClientDoActionName, callback: ClientDoActionCallback) {
this.actions[actionName] = callback
}
removeAction (actionName: ClientDoActionName) {
delete this.actions[actionName]
}
initializePlugins () {
this.pluginsManager.loadPluginsList(this.server.getHTMLConfig())
@ -184,6 +198,14 @@ export class PluginService implements ClientHook {
return firstValueFrom(obs)
}
private doAction (actionName: ClientDoActionName) {
try {
return this.actions[actionName]()
} catch (err: any) {
logger.warn(`Plugin tried to do unknown action: ${actionName}`)
}
}
private onFormFields (
pluginInfo: PluginInfo,
commonOptions: RegisterClientFormFieldOptions,

View File

@ -5,6 +5,7 @@ import { first, shareReplay } from 'rxjs/operators'
import { RegisterClientHelpers } from 'src/types/register-client-option.model'
import { getExternalAuthHref, getHookType, internalRunHook } from '@peertube/peertube-core-utils'
import {
ClientDoAction,
ClientHookName,
clientHookObject,
ClientScriptJSON,
@ -76,17 +77,20 @@ class PluginsManager {
'admin-comments': new ReplaySubject<boolean>(1)
}
private readonly doAction: ClientDoAction
private readonly peertubeHelpersFactory: PeertubeHelpersFactory
private readonly onFormFields: OnFormFields
private readonly onSettingsScripts: OnSettingsScripts
private readonly onClientRoute: OnClientRoute
constructor (options: {
doAction: ClientDoAction
peertubeHelpersFactory: PeertubeHelpersFactory
onFormFields?: OnFormFields
onSettingsScripts?: OnSettingsScripts
onClientRoute?: OnClientRoute
}) {
this.doAction = options.doAction
this.peertubeHelpersFactory = options.peertubeHelpersFactory
this.onFormFields = options.onFormFields
this.onSettingsScripts = options.onSettingsScripts
@ -270,6 +274,8 @@ class PluginsManager {
return this.onClientRoute(options)
}
const doAction = this.doAction
const peertubeHelpers = this.peertubeHelpersFactory(pluginInfo)
logger.info(`Loading script ${clientScript.script} of plugin ${plugin.name}`)
@ -278,6 +284,7 @@ class PluginsManager {
return dynamicImport(absURL)
.then((script: ClientScript) => {
return script.register({
doAction,
registerHook,
registerVideoField,
registerSettingsScript,

View File

@ -1,4 +1,5 @@
import {
ClientDoAction,
MyUser,
RegisterClientFormFieldOptions,
RegisterClientHookOptions,
@ -9,6 +10,8 @@ import {
} from '@peertube/peertube-models'
export type RegisterClientOptions = {
doAction: ClientDoAction
registerHook: (options: RegisterClientHookOptions) => void
registerVideoField: (commonOptions: RegisterClientFormFieldOptions, videoFormOptions: RegisterClientVideoFieldOptions) => void

View File

@ -1,3 +1,5 @@
import { Observable } from 'rxjs'
// Data from API hooks: {hookType}:api.{location}.{elementType}.{actionType}.{target}
// Data in internal functions: {hookType}:{location}.{elementType}.{actionType}.{target}
@ -208,3 +210,13 @@ export type ClientHookName = keyof typeof clientHookObject
export interface ClientHook {
runHook <T> (hookName: ClientHookName, result?: T, params?: any): Promise<T>
}
export const clientDoActionObject = {
'application:increment-loader': true,
'application:decrement-loader': true
}
export type ClientDoActionName = keyof typeof clientDoActionObject
export type ClientDoActionCallback = () => Observable<any>
export type ClientDoAction = (actionName: ClientDoActionName) => Observable<any>