diff options
Diffstat (limited to 'client/src/assets')
4 files changed, 83 insertions, 28 deletions
diff --git a/client/src/assets/player/peertube-player-manager.ts b/client/src/assets/player/peertube-player-manager.ts index b071a0938..6f0b804cd 100644 --- a/client/src/assets/player/peertube-player-manager.ts +++ b/client/src/assets/player/peertube-player-manager.ts | |||
@@ -33,13 +33,14 @@ import { getStoredP2PEnabled } from './peertube-player-local-storage' | |||
33 | import { | 33 | import { |
34 | NextPreviousVideoButtonOptions, | 34 | NextPreviousVideoButtonOptions, |
35 | P2PMediaLoaderPluginOptions, | 35 | P2PMediaLoaderPluginOptions, |
36 | PeerTubeLinkButtonOptions, | ||
36 | PlaylistPluginOptions, | 37 | PlaylistPluginOptions, |
37 | UserWatching, | 38 | UserWatching, |
38 | VideoJSCaption, | 39 | VideoJSCaption, |
39 | VideoJSPluginOptions | 40 | VideoJSPluginOptions |
40 | } from './peertube-videojs-typings' | 41 | } from './peertube-videojs-typings' |
41 | import { TranslationsManager } from './translations-manager' | 42 | import { TranslationsManager } from './translations-manager' |
42 | import { buildVideoLink, buildVideoOrPlaylistEmbed, getRtcConfig, isIOS, isSafari } from './utils' | 43 | import { buildVideoLink, buildVideoOrPlaylistEmbed, decorateVideoLink, getRtcConfig, isIOS, isSafari } from './utils' |
43 | 44 | ||
44 | // Change 'Playback Rate' to 'Speed' (smaller for our settings menu) | 45 | // Change 'Playback Rate' to 'Speed' (smaller for our settings menu) |
45 | (videojs.getComponent('PlaybackRateMenuButton') as any).prototype.controlText_ = 'Speed' | 46 | (videojs.getComponent('PlaybackRateMenuButton') as any).prototype.controlText_ = 'Speed' |
@@ -110,6 +111,7 @@ export interface CommonOptions extends CustomizationOptions { | |||
110 | videoCaptions: VideoJSCaption[] | 111 | videoCaptions: VideoJSCaption[] |
111 | 112 | ||
112 | videoUUID: string | 113 | videoUUID: string |
114 | videoShortUUID: string | ||
113 | 115 | ||
114 | userWatching?: UserWatching | 116 | userWatching?: UserWatching |
115 | 117 | ||
@@ -175,7 +177,13 @@ export class PeertubePlayerManager { | |||
175 | PeertubePlayerManager.alreadyPlayed = true | 177 | PeertubePlayerManager.alreadyPlayed = true |
176 | }) | 178 | }) |
177 | 179 | ||
178 | self.addContextMenu(mode, player, options.common.embedUrl, options.common.embedTitle) | 180 | self.addContextMenu({ |
181 | mode, | ||
182 | player, | ||
183 | videoShortUUID: options.common.videoShortUUID, | ||
184 | videoEmbedUrl: options.common.embedUrl, | ||
185 | videoEmbedTitle: options.common.embedTitle | ||
186 | }) | ||
179 | 187 | ||
180 | player.bezels() | 188 | player.bezels() |
181 | player.stats({ | 189 | player.stats({ |
@@ -218,7 +226,13 @@ export class PeertubePlayerManager { | |||
218 | videojs(newVideoElement, videojsOptions, function (this: videojs.Player) { | 226 | videojs(newVideoElement, videojsOptions, function (this: videojs.Player) { |
219 | const player = this | 227 | const player = this |
220 | 228 | ||
221 | self.addContextMenu(mode, player, options.common.embedUrl, options.common.embedTitle) | 229 | self.addContextMenu({ |
230 | mode, | ||
231 | player, | ||
232 | videoShortUUID: options.common.videoShortUUID, | ||
233 | videoEmbedUrl: options.common.embedUrl, | ||
234 | videoEmbedTitle: options.common.embedTitle | ||
235 | }) | ||
222 | 236 | ||
223 | PeertubePlayerManager.onPlayerChange(player) | 237 | PeertubePlayerManager.onPlayerChange(player) |
224 | }) | 238 | }) |
@@ -295,6 +309,8 @@ export class PeertubePlayerManager { | |||
295 | 309 | ||
296 | controlBar: { | 310 | controlBar: { |
297 | children: this.getControlBarChildren(mode, { | 311 | children: this.getControlBarChildren(mode, { |
312 | videoShortUUID: commonOptions.videoShortUUID, | ||
313 | |||
298 | captions: commonOptions.captions, | 314 | captions: commonOptions.captions, |
299 | peertubeLink: commonOptions.peertubeLink, | 315 | peertubeLink: commonOptions.peertubeLink, |
300 | theaterButton: commonOptions.theaterButton, | 316 | theaterButton: commonOptions.theaterButton, |
@@ -409,6 +425,8 @@ export class PeertubePlayerManager { | |||
409 | } | 425 | } |
410 | 426 | ||
411 | private static getControlBarChildren (mode: PlayerMode, options: { | 427 | private static getControlBarChildren (mode: PlayerMode, options: { |
428 | videoShortUUID: string | ||
429 | |||
412 | peertubeLink: boolean | 430 | peertubeLink: boolean |
413 | theaterButton: boolean | 431 | theaterButton: boolean |
414 | captions: boolean | 432 | captions: boolean |
@@ -497,7 +515,7 @@ export class PeertubePlayerManager { | |||
497 | 515 | ||
498 | if (options.peertubeLink === true) { | 516 | if (options.peertubeLink === true) { |
499 | Object.assign(children, { | 517 | Object.assign(children, { |
500 | 'peerTubeLinkButton': {} | 518 | 'peerTubeLinkButton': { shortUUID: options.videoShortUUID } as PeerTubeLinkButtonOptions |
501 | }) | 519 | }) |
502 | } | 520 | } |
503 | 521 | ||
@@ -514,7 +532,15 @@ export class PeertubePlayerManager { | |||
514 | return children | 532 | return children |
515 | } | 533 | } |
516 | 534 | ||
517 | private static addContextMenu (mode: PlayerMode, player: videojs.Player, videoEmbedUrl: string, videoEmbedTitle: string) { | 535 | private static addContextMenu (options: { |
536 | mode: PlayerMode | ||
537 | player: videojs.Player | ||
538 | videoShortUUID: string | ||
539 | videoEmbedUrl: string | ||
540 | videoEmbedTitle: string | ||
541 | }) { | ||
542 | const { mode, player, videoEmbedTitle, videoEmbedUrl, videoShortUUID } = options | ||
543 | |||
518 | const content = () => { | 544 | const content = () => { |
519 | const isLoopEnabled = player.options_['loop'] | 545 | const isLoopEnabled = player.options_['loop'] |
520 | const items = [ | 546 | const items = [ |
@@ -528,13 +554,15 @@ export class PeertubePlayerManager { | |||
528 | { | 554 | { |
529 | label: player.localize('Copy the video URL'), | 555 | label: player.localize('Copy the video URL'), |
530 | listener: function () { | 556 | listener: function () { |
531 | copyToClipboard(buildVideoLink()) | 557 | copyToClipboard(buildVideoLink({ shortUUID: videoShortUUID })) |
532 | } | 558 | } |
533 | }, | 559 | }, |
534 | { | 560 | { |
535 | label: player.localize('Copy the video URL at the current time'), | 561 | label: player.localize('Copy the video URL at the current time'), |
536 | listener: function (this: videojs.Player) { | 562 | listener: function (this: videojs.Player) { |
537 | copyToClipboard(buildVideoLink({ startTime: this.currentTime() })) | 563 | const url = buildVideoLink({ shortUUID: videoShortUUID }) |
564 | |||
565 | copyToClipboard(decorateVideoLink({ url, startTime: this.currentTime() })) | ||
538 | } | 566 | } |
539 | }, | 567 | }, |
540 | { | 568 | { |
diff --git a/client/src/assets/player/peertube-videojs-typings.ts b/client/src/assets/player/peertube-videojs-typings.ts index 8afb424a7..d3c75990b 100644 --- a/client/src/assets/player/peertube-videojs-typings.ts +++ b/client/src/assets/player/peertube-videojs-typings.ts | |||
@@ -132,6 +132,10 @@ type NextPreviousVideoButtonOptions = { | |||
132 | isDisabled: () => boolean | 132 | isDisabled: () => boolean |
133 | } | 133 | } |
134 | 134 | ||
135 | type PeerTubeLinkButtonOptions = { | ||
136 | shortUUID: string | ||
137 | } | ||
138 | |||
135 | type WebtorrentPluginOptions = { | 139 | type WebtorrentPluginOptions = { |
136 | playerElement: HTMLVideoElement | 140 | playerElement: HTMLVideoElement |
137 | 141 | ||
@@ -225,5 +229,6 @@ export { | |||
225 | VideoJSPluginOptions, | 229 | VideoJSPluginOptions, |
226 | LoadedQualityData, | 230 | LoadedQualityData, |
227 | QualityLevelRepresentation, | 231 | QualityLevelRepresentation, |
232 | PeerTubeLinkButtonOptions, | ||
228 | QualityLevels | 233 | QualityLevels |
229 | } | 234 | } |
diff --git a/client/src/assets/player/utils.ts b/client/src/assets/player/utils.ts index 2bb70d1fa..eb9302493 100644 --- a/client/src/assets/player/utils.ts +++ b/client/src/assets/player/utils.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { VideoFile } from '@shared/models' | 1 | import { Video, VideoFile, VideoPlaylist } from '@shared/models' |
2 | import { escapeHTML } from '@shared/core-utils/renderer' | 2 | import { escapeHTML } from '@shared/core-utils/renderer' |
3 | 3 | ||
4 | function toTitleCase (str: string) { | 4 | function toTitleCase (str: string) { |
@@ -43,8 +43,24 @@ function isMobile () { | |||
43 | return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) | 43 | return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) |
44 | } | 44 | } |
45 | 45 | ||
46 | function buildVideoLink (options: { | 46 | function buildPlaylistLink (playlist: Pick<VideoPlaylist, 'shortUUID'>, base?: string) { |
47 | baseUrl?: string | 47 | return (base ?? window.location.origin) + '/w/p/' + playlist.shortUUID |
48 | } | ||
49 | |||
50 | function buildVideoLink (video: Pick<Video, 'shortUUID'>, base?: string) { | ||
51 | return (base ?? window.location.origin) + '/w/' + video.shortUUID | ||
52 | } | ||
53 | |||
54 | function buildPlaylistEmbedLink (playlist: Pick<VideoPlaylist, 'uuid'>, base?: string) { | ||
55 | return (base ?? window.location.origin) + '/video-playlists/embed/' + playlist.uuid | ||
56 | } | ||
57 | |||
58 | function buildVideoEmbedLink (video: Pick<Video, 'uuid'>, base?: string) { | ||
59 | return (base ?? window.location.origin) + '/videos/embed/' + video.uuid | ||
60 | } | ||
61 | |||
62 | function decorateVideoLink (options: { | ||
63 | url: string | ||
48 | 64 | ||
49 | startTime?: number | 65 | startTime?: number |
50 | stopTime?: number | 66 | stopTime?: number |
@@ -60,12 +76,8 @@ function buildVideoLink (options: { | |||
60 | warningTitle?: boolean | 76 | warningTitle?: boolean |
61 | controls?: boolean | 77 | controls?: boolean |
62 | peertubeLink?: boolean | 78 | peertubeLink?: boolean |
63 | } = {}) { | 79 | }) { |
64 | const { baseUrl } = options | 80 | const { url } = options |
65 | |||
66 | const url = baseUrl | ||
67 | ? baseUrl | ||
68 | : window.location.origin + window.location.pathname.replace('/embed/', '/w/') | ||
69 | 81 | ||
70 | const params = generateParams(window.location.search) | 82 | const params = generateParams(window.location.search) |
71 | 83 | ||
@@ -92,16 +104,12 @@ function buildVideoLink (options: { | |||
92 | return buildUrl(url, params) | 104 | return buildUrl(url, params) |
93 | } | 105 | } |
94 | 106 | ||
95 | function buildPlaylistLink (options: { | 107 | function decoratePlaylistLink (options: { |
96 | baseUrl?: string | 108 | url: string |
97 | 109 | ||
98 | playlistPosition?: number | 110 | playlistPosition?: number |
99 | }) { | 111 | }) { |
100 | const { baseUrl } = options | 112 | const { url } = options |
101 | |||
102 | const url = baseUrl | ||
103 | ? baseUrl | ||
104 | : window.location.origin + window.location.pathname.replace('/video-playlists/embed/', '/w/p/') | ||
105 | 113 | ||
106 | const params = generateParams(window.location.search) | 114 | const params = generateParams(window.location.search) |
107 | 115 | ||
@@ -224,8 +232,14 @@ export { | |||
224 | timeToInt, | 232 | timeToInt, |
225 | secondsToTime, | 233 | secondsToTime, |
226 | isWebRTCDisabled, | 234 | isWebRTCDisabled, |
235 | |||
227 | buildPlaylistLink, | 236 | buildPlaylistLink, |
228 | buildVideoLink, | 237 | buildVideoLink, |
238 | decorateVideoLink, | ||
239 | decoratePlaylistLink, | ||
240 | buildPlaylistEmbedLink, | ||
241 | buildVideoEmbedLink, | ||
242 | |||
229 | buildVideoOrPlaylistEmbed, | 243 | buildVideoOrPlaylistEmbed, |
230 | videoFileMaxByResolution, | 244 | videoFileMaxByResolution, |
231 | videoFileMinByResolution, | 245 | videoFileMinByResolution, |
diff --git a/client/src/assets/player/videojs-components/peertube-link-button.ts b/client/src/assets/player/videojs-components/peertube-link-button.ts index e73c95900..f47c165d9 100644 --- a/client/src/assets/player/videojs-components/peertube-link-button.ts +++ b/client/src/assets/player/videojs-components/peertube-link-button.ts | |||
@@ -1,11 +1,13 @@ | |||
1 | import { buildVideoLink } from '../utils' | ||
2 | import videojs from 'video.js' | 1 | import videojs from 'video.js' |
2 | import { PeerTubeLinkButtonOptions } from '../peertube-videojs-typings' | ||
3 | import { buildVideoLink, decorateVideoLink } from '../utils' | ||
3 | 4 | ||
4 | const Button = videojs.getComponent('Button') | 5 | const Button = videojs.getComponent('Button') |
5 | class PeerTubeLinkButton extends Button { | 6 | class PeerTubeLinkButton extends Button { |
7 | private shortUUID: string | ||
6 | 8 | ||
7 | constructor (player: videojs.Player, options?: videojs.ComponentOptions) { | 9 | constructor (player: videojs.Player, options?: PeerTubeLinkButtonOptions) { |
8 | super(player, options) | 10 | super(player, options as any) |
9 | } | 11 | } |
10 | 12 | ||
11 | createEl () { | 13 | createEl () { |
@@ -13,7 +15,7 @@ class PeerTubeLinkButton extends Button { | |||
13 | } | 15 | } |
14 | 16 | ||
15 | updateHref () { | 17 | updateHref () { |
16 | this.el().setAttribute('href', buildVideoLink({ startTime: this.player().currentTime() })) | 18 | this.el().setAttribute('href', this.buildLink()) |
17 | } | 19 | } |
18 | 20 | ||
19 | handleClick () { | 21 | handleClick () { |
@@ -22,7 +24,7 @@ class PeerTubeLinkButton extends Button { | |||
22 | 24 | ||
23 | private buildElement () { | 25 | private buildElement () { |
24 | const el = videojs.dom.createEl('a', { | 26 | const el = videojs.dom.createEl('a', { |
25 | href: buildVideoLink(), | 27 | href: this.buildLink(), |
26 | innerHTML: 'PeerTube', | 28 | innerHTML: 'PeerTube', |
27 | title: this.player().localize('Video page (new window)'), | 29 | title: this.player().localize('Video page (new window)'), |
28 | className: 'vjs-peertube-link', | 30 | className: 'vjs-peertube-link', |
@@ -33,6 +35,12 @@ class PeerTubeLinkButton extends Button { | |||
33 | 35 | ||
34 | return el as HTMLButtonElement | 36 | return el as HTMLButtonElement |
35 | } | 37 | } |
38 | |||
39 | private buildLink () { | ||
40 | const url = buildVideoLink({ shortUUID: this.shortUUID }) | ||
41 | |||
42 | return decorateVideoLink({ url, startTime: this.player().currentTime() }) | ||
43 | } | ||
36 | } | 44 | } |
37 | 45 | ||
38 | videojs.registerComponent('PeerTubeLinkButton', PeerTubeLinkButton) | 46 | videojs.registerComponent('PeerTubeLinkButton', PeerTubeLinkButton) |