]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - client/src/standalone/videos/embed.ts
Translated using Weblate (Occitan)
[github/Chocobozzz/PeerTube.git] / client / src / standalone / videos / embed.ts
index 1dca84f72c1d53e6230e11536210e0973258a270..995e8c27781b4df05080751555d72ed6967dae18 100644 (file)
@@ -1,7 +1,5 @@
 import './embed.scss'
 import videojs from 'video.js'
-import { objectToUrlEncoded, peertubeLocalStorage } from '@root-helpers/index'
-import { Tokens } from '@root-helpers/users'
 import { peertubeTranslate } from '../../../../shared/core-utils/i18n'
 import {
   ResultList,
@@ -11,12 +9,19 @@ import {
   VideoDetails,
   VideoPlaylist,
   VideoPlaylistElement,
-  VideoStreamingPlaylistType
+  VideoStreamingPlaylistType,
+  PluginType,
+  ClientHookName
 } from '../../../../shared/models'
 import { P2PMediaLoaderOptions, PeertubePlayerManagerOptions, PlayerMode } from '../../assets/player/peertube-player-manager'
 import { VideoJSCaption } from '../../assets/player/peertube-videojs-typings'
 import { TranslationsManager } from '../../assets/player/translations-manager'
+import { Hooks, loadPlugin, runHook } from '../../root-helpers/plugins'
+import { Tokens } from '../../root-helpers/users'
+import { peertubeLocalStorage } from '../../root-helpers/peertube-web-storage'
+import { objectToUrlEncoded } from '../../root-helpers/utils'
 import { PeerTubeEmbedApi } from './embed-api'
+import { RegisterClientHelpers } from '../../types/register-client-option.model'
 
 type Translations = { [ id: string ]: string }
 
@@ -60,6 +65,9 @@ export class PeerTubeEmbed {
 
   private wrapperElement: HTMLElement
 
+  private peertubeHooks: Hooks = {}
+  private loadedScripts = new Set<string>()
+
   static async main () {
     const videoContainerId = 'video-wrapper'
     const embed = new PeerTubeEmbed(videoContainerId)
@@ -79,9 +87,6 @@ export class PeerTubeEmbed {
       .then((res: Response) => {
         if (res.status !== 401) return res
 
-        // 401 unauthorized is not catch-ed, but then-ed
-        const error = res
-
         const refreshingTokenPromise = new Promise((resolve, reject) => {
           const clientId: string = peertubeLocalStorage.getItem(this.LOCAL_STORAGE_OAUTH_CLIENT_KEYS.CLIENT_ID)
           const clientSecret: string = peertubeLocalStorage.getItem(this.LOCAL_STORAGE_OAUTH_CLIENT_KEYS.CLIENT_SECRET)
@@ -101,24 +106,37 @@ export class PeerTubeEmbed {
             headers,
             method: 'POST',
             body: objectToUrlEncoded(data)
-          }).then(res => res.json())
-            .then((obj: UserRefreshToken) => {
-              this.userTokens.accessToken = obj.access_token
-              this.userTokens.refreshToken = obj.refresh_token
-              this.userTokens.save()
+          }).then(res => {
+            if (res.status === 401) return undefined
 
-              this.setHeadersFromTokens()
+            return res.json()
+          }).then((obj: UserRefreshToken & { code: 'invalid_grant'}) => {
+            if (!obj || obj.code === 'invalid_grant') {
+              Tokens.flush()
+              this.removeTokensFromHeaders()
 
-              resolve()
-            })
+              return resolve()
+            }
+
+            this.userTokens.accessToken = obj.access_token
+            this.userTokens.refreshToken = obj.refresh_token
+            this.userTokens.save()
+
+            this.setHeadersFromTokens()
+
+            resolve()
+          })
             .catch((refreshTokenError: any) => {
               reject(refreshTokenError)
             })
         })
 
         return refreshingTokenPromise
-          .catch(() => this.removeTokensFromHeaders())
-          .then(() => fetch(url, {
+          .catch(() => {
+            Tokens.flush()
+
+            this.removeTokensFromHeaders()
+          }).then(() => fetch(url, {
             ...options,
             headers: this.headers
           }))
@@ -463,6 +481,8 @@ export class PeerTubeEmbed {
       this.PeertubePlayerManagerModulePromise
     ])
 
+    await this.ensurePluginsAreLoaded(config, serverTranslations)
+
     const videoInfo: VideoDetails = videoInfoTmp
 
     const PeertubePlayerManager = PeertubePlayerManagerModule.PeertubePlayerManager
@@ -567,6 +587,8 @@ export class PeerTubeEmbed {
         this.playNextVideo()
       })
     }
+
+    this.runHook('action:embed.player.loaded', undefined, { player: this.player, videojs, video: videoInfo })
   }
 
   private async initCore () {
@@ -704,6 +726,73 @@ export class PeerTubeEmbed {
   private isPlaylistEmbed () {
     return window.location.pathname.split('/')[1] === 'video-playlists'
   }
+
+  private async ensurePluginsAreLoaded (config: ServerConfig, translations?: { [ id: string ]: string }) {
+    if (config.plugin.registered.length === 0) return
+
+    for (const plugin of config.plugin.registered) {
+      for (const key of Object.keys(plugin.clientScripts)) {
+        const clientScript = plugin.clientScripts[key]
+
+        if (clientScript.scopes.includes('embed') === false) continue
+
+        const script = `/plugins/${plugin.name}/${plugin.version}/client-scripts/${clientScript.script}`
+
+        if (this.loadedScripts.has(script)) continue
+
+        const pluginInfo = {
+          plugin,
+          clientScript: {
+            script,
+            scopes: clientScript.scopes
+          },
+          pluginType: PluginType.PLUGIN,
+          isTheme: false
+        }
+
+        await loadPlugin({
+          hooks: this.peertubeHooks,
+          pluginInfo,
+          peertubeHelpersFactory: _ => this.buildPeerTubeHelpers(translations)
+        })
+      }
+    }
+  }
+
+  private buildPeerTubeHelpers (translations?: { [ id: string ]: string }): RegisterClientHelpers {
+    function unimplemented (): any {
+      throw new Error('This helper is not implemented in embed.')
+    }
+
+    return {
+      getBaseStaticRoute: unimplemented,
+
+      getSettings: unimplemented,
+
+      isLoggedIn: unimplemented,
+
+      notifier: {
+        info: unimplemented,
+        error: unimplemented,
+        success: unimplemented
+      },
+
+      showModal: unimplemented,
+
+      markdownRenderer: {
+        textMarkdownToHTML: unimplemented,
+        enhancedMarkdownToHTML: unimplemented
+      },
+
+      translate: (value: string) => {
+        return Promise.resolve(peertubeTranslate(value, translations))
+      }
+    }
+  }
+
+  private runHook <T> (hookName: ClientHookName, result?: T, params?: any): Promise<T> {
+    return runHook(this.peertubeHooks, hookName, result, params)
+  }
 }
 
 PeerTubeEmbed.main()