diff --git a/client/src/app/+videos/+video-watch/video-watch.component.html b/client/src/app/+videos/+video-watch/video-watch.component.html index 99103c2c3..c1ba0a755 100644 --- a/client/src/app/+videos/+video-watch/video-watch.component.html +++ b/client/src/app/+videos/+video-watch/video-watch.component.html @@ -16,6 +16,8 @@ [playlist]="playlist" class="playlist" (videoFound)="onPlaylistVideoFound($event)" > + +
diff --git a/client/src/app/core/core.module.ts b/client/src/app/core/core.module.ts index 2392a234c..3152a7003 100644 --- a/client/src/app/core/core.module.ts +++ b/client/src/app/core/core.module.ts @@ -5,8 +5,7 @@ import { CommonModule } from '@angular/common' import { NgModule, Optional, SkipSelf } from '@angular/core' import { BrowserAnimationsModule } from '@angular/platform-browser/animations' import { PeerTubeSocket } from '@app/core/notification/peertube-socket.service' -import { HooksService } from '@app/core/plugins/hooks.service' -import { PluginService } from '@app/core/plugins/plugin.service' +import { HooksService, PluginService } from '@app/core/plugins' import { AuthService } from './auth' import { ConfirmService } from './confirm' import { CheatSheetComponent } from './hotkeys' @@ -15,7 +14,7 @@ import { throwIfAlreadyLoaded } from './module-import-guard' import { Notifier } from './notification' import { HtmlRendererService, LinkifierService, MarkdownService } from './renderer' import { RestExtractor, RestService } from './rest' -import { LoginGuard, RedirectService, UserRightGuard, UnloggedGuard } from './routing' +import { LoginGuard, RedirectService, UnloggedGuard, UserRightGuard } from './routing' import { CanDeactivateGuard } from './routing/can-deactivate-guard.service' import { ServerConfigResolver } from './routing/server-config-resolver.service' import { ScopedTokensService } from './scoped-tokens' diff --git a/client/src/app/shared/shared-main/plugins/index.ts b/client/src/app/shared/shared-main/plugins/index.ts new file mode 100644 index 000000000..f36dab624 --- /dev/null +++ b/client/src/app/shared/shared-main/plugins/index.ts @@ -0,0 +1 @@ +export * from './plugin-placeholder.component' diff --git a/client/src/app/shared/shared-main/plugins/plugin-placeholder.component.ts b/client/src/app/shared/shared-main/plugins/plugin-placeholder.component.ts new file mode 100644 index 000000000..93ba9fb9b --- /dev/null +++ b/client/src/app/shared/shared-main/plugins/plugin-placeholder.component.ts @@ -0,0 +1,15 @@ +import { Component, Input } from '@angular/core' +import { PluginElementPlaceholder } from '@shared/models' + +@Component({ + selector: 'my-plugin-placeholder', + template: '
' +}) + +export class PluginPlaceholderComponent { + @Input() pluginId: PluginElementPlaceholder + + getId () { + return 'plugin-placeholder-' + this.pluginId + } +} diff --git a/client/src/app/shared/shared-main/shared-main.module.ts b/client/src/app/shared/shared-main/shared-main.module.ts index 16d230f46..772198cb2 100644 --- a/client/src/app/shared/shared-main/shared-main.module.ts +++ b/client/src/app/shared/shared-main/shared-main.module.ts @@ -33,6 +33,7 @@ import { DateToggleComponent } from './date' import { FeedComponent } from './feeds' import { LoaderComponent, SmallLoaderComponent } from './loaders' import { HelpComponent, ListOverflowComponent, SimpleSearchInputComponent, TopMenuDropdownComponent } from './misc' +import { PluginPlaceholderComponent } from './plugins' import { UserHistoryService, UserNotificationsComponent, UserNotificationService, UserQuotaComponent } from './users' import { RedundancyService, VideoImportService, VideoOwnershipService, VideoService } from './video' import { VideoCaptionService } from './video-caption' @@ -92,7 +93,9 @@ import { VideoChannelService } from './video-channel' SimpleSearchInputComponent, UserQuotaComponent, - UserNotificationsComponent + UserNotificationsComponent, + + PluginPlaceholderComponent ], exports: [ @@ -144,7 +147,9 @@ import { VideoChannelService } from './video-channel' SimpleSearchInputComponent, UserQuotaComponent, - UserNotificationsComponent + UserNotificationsComponent, + + PluginPlaceholderComponent ], providers: [ diff --git a/shared/models/plugins/index.ts b/shared/models/plugins/index.ts index 740083f0e..03b27f907 100644 --- a/shared/models/plugins/index.ts +++ b/shared/models/plugins/index.ts @@ -7,6 +7,7 @@ export * from './peertube-plugin-index.model' export * from './peertube-plugin-latest-version.model' export * from './peertube-plugin.model' export * from './plugin-client-scope.type' +export * from './plugin-element-placeholder.type' export * from './plugin-package-json.model' export * from './plugin-playlist-privacy-manager.model' export * from './plugin-settings-manager.model' diff --git a/shared/models/plugins/plugin-element-placeholder.type.ts b/shared/models/plugins/plugin-element-placeholder.type.ts new file mode 100644 index 000000000..129099c62 --- /dev/null +++ b/shared/models/plugins/plugin-element-placeholder.type.ts @@ -0,0 +1 @@ +export type PluginElementPlaceholder = 'player-next' diff --git a/support/doc/plugins/guide.md b/support/doc/plugins/guide.md index e30d95fc9..81999bf32 100644 --- a/support/doc/plugins/guide.md +++ b/support/doc/plugins/guide.md @@ -15,7 +15,7 @@ - [Add custom routes](#add-custom-routes) - [Add external auth methods](#add-external-auth-methods) - [Add new transcoding profiles](#add-new-transcoding-profiles) - - [Helpers](#helpers) + - [Server helpers](#server-helpers) - [Client API (themes & plugins)](#client-api-themes--plugins) - [Plugin static route](#plugin-static-route) - [Notifier](#notifier) @@ -26,6 +26,7 @@ - [Get server config](#get-server-config) - [Add custom fields to video form](#add-custom-fields-to-video-form) - [Register settings script](#register-settings-script) + - [HTML placeholder elements](#html-placeholder-elements) - [Publishing](#publishing) - [Write a plugin/theme](#write-a-plugintheme) - [Clone the quickstart repository](#clone-the-quickstart-repository) @@ -424,7 +425,7 @@ async function register ({ During live transcode input options are applied once for each target resolution. Plugins are responsible for detecting such situation and applying input options only once if necessary. -### Helpers +#### Server helpers PeerTube provides your plugin some helpers. For example: @@ -628,6 +629,21 @@ async function register ({ registerSettingsScript }) { } ``` +#### HTML placeholder elements + +PeerTube provides some HTML id so plugins can easily insert their own element: + +``` +async function register (...) { + const elem = document.createElement('div') + elem.className = 'hello-world-h4' + elem.innerHTML = '

Hello everybody! This is an element next to the player

' + + document.getElementById('plugin-placeholder-player-next').appendChild(elem) +} +``` + +See the complete list on https://docs.joinpeertube.org/api-plugins ### Publishing