aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2022-02-22 13:48:09 +0100
committerChocobozzz <me@florianbigard.com>2022-02-22 13:48:09 +0100
commitf7298d0dcc247fe3be94ec1e00351942a079a44b (patch)
tree6bcb9935ab00101115be003c988a8211fc260d8c /client/src
parent0d9a327df33e42a0f34caaf2cbff5f74e4d78426 (diff)
parentac5f679ad60fc48db6d9a9534a8ac5fd20eda36f (diff)
downloadPeerTube-f7298d0dcc247fe3be94ec1e00351942a079a44b.tar.gz
PeerTube-f7298d0dcc247fe3be94ec1e00351942a079a44b.tar.zst
PeerTube-f7298d0dcc247fe3be94ec1e00351942a079a44b.zip
Merge branch 'release/4.1.0' into develop
Diffstat (limited to 'client/src')
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts9
-rw-r--r--client/src/app/modal/confirm.component.ts10
-rw-r--r--client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts21
-rw-r--r--client/src/assets/player/p2p-media-loader/segment-url-builder.ts4
-rw-r--r--client/src/assets/player/peertube-player-options-builder.ts61
5 files changed, 76 insertions, 29 deletions
diff --git a/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts b/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts
index 4a46f1ad9..2bae3499e 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts
@@ -19,8 +19,13 @@ export class MyAccountDangerZoneComponent {
19 19
20 async deleteMe () { 20 async deleteMe () {
21 const res = await this.confirmService.confirmWithInput( 21 const res = await this.confirmService.confirmWithInput(
22 // eslint-disable-next-line max-len 22 $localize`Are you sure you want to delete your account?` +
23 $localize`Are you sure you want to delete your account? This will delete all your data, including channels, videos and comments. Content cached by other servers and other third-parties might make longer to be deleted.`, 23 '<br /><br />' +
24 // eslint-disable-next-line max-len
25 $localize`This will delete all your data, including channels, videos, comments and you won't be able to create another user on this instance with "${this.user.username}" username.` +
26 '<br /><br />' +
27 $localize`Content cached by other servers and other third-parties might make longer to be deleted.`,
28
24 $localize`Type your username to confirm`, 29 $localize`Type your username to confirm`,
25 this.user.username, 30 this.user.username,
26 $localize`Delete your account`, 31 $localize`Delete your account`,
diff --git a/client/src/app/modal/confirm.component.ts b/client/src/app/modal/confirm.component.ts
index 457dd1f3f..ec4e1d60f 100644
--- a/client/src/app/modal/confirm.component.ts
+++ b/client/src/app/modal/confirm.component.ts
@@ -1,4 +1,5 @@
1import { Component, ElementRef, OnInit, ViewChild } from '@angular/core' 1import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'
2import { HtmlRendererService } from '@app/core'
2import { ConfirmService } from '@app/core/confirm/confirm.service' 3import { ConfirmService } from '@app/core/confirm/confirm.service'
3import { POP_STATE_MODAL_DISMISS } from '@app/helpers' 4import { POP_STATE_MODAL_DISMISS } from '@app/helpers'
4import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 5import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
@@ -24,6 +25,7 @@ export class ConfirmComponent implements OnInit {
24 25
25 constructor ( 26 constructor (
26 private modalService: NgbModal, 27 private modalService: NgbModal,
28 private html: HtmlRendererService,
27 private confirmService: ConfirmService 29 private confirmService: ConfirmService
28 ) { } 30 ) { }
29 31
@@ -31,14 +33,18 @@ export class ConfirmComponent implements OnInit {
31 this.confirmService.showConfirm.subscribe( 33 this.confirmService.showConfirm.subscribe(
32 ({ title, message, expectedInputValue, inputLabel, confirmButtonText }) => { 34 ({ title, message, expectedInputValue, inputLabel, confirmButtonText }) => {
33 this.title = title 35 this.title = title
34 this.message = message
35 36
36 this.inputLabel = inputLabel 37 this.inputLabel = inputLabel
37 this.expectedInputValue = expectedInputValue 38 this.expectedInputValue = expectedInputValue
38 39
39 this.confirmButtonText = confirmButtonText || $localize`Confirm` 40 this.confirmButtonText = confirmButtonText || $localize`Confirm`
40 41
41 this.showModal() 42 this.html.toSafeHtml(message)
43 .then(message => {
44 this.message = message
45
46 this.showModal()
47 })
42 } 48 }
43 ) 49 )
44 } 50 }
diff --git a/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts b/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts
index 553930595..e4972ec10 100644
--- a/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts
+++ b/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts
@@ -56,6 +56,8 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
56 private listenToPlaylistChangeSub: Subscription 56 private listenToPlaylistChangeSub: Subscription
57 private playlistsData: CachedPlaylist[] = [] 57 private playlistsData: CachedPlaylist[] = []
58 58
59 private pendingAddId: number
60
59 constructor ( 61 constructor (
60 protected formValidatorService: FormValidatorService, 62 protected formValidatorService: FormValidatorService,
61 private authService: AuthService, 63 private authService: AuthService,
@@ -215,8 +217,9 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
215 } 217 }
216 218
217 isPrimaryCheckboxChecked (playlist: PlaylistSummary) { 219 isPrimaryCheckboxChecked (playlist: PlaylistSummary) {
218 return playlist.elements.filter(e => e.enabled) 220 // Reduce latency when adding a video to a playlist using pendingAddId
219 .length !== 0 221 return this.pendingAddId === playlist.id ||
222 playlist.elements.filter(e => e.enabled).length !== 0
220 } 223 }
221 224
222 toggleOptionalRow (playlist: PlaylistSummary) { 225 toggleOptionalRow (playlist: PlaylistSummary) {
@@ -367,6 +370,8 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
367 if (element.startTimestamp) body.startTimestamp = element.startTimestamp 370 if (element.startTimestamp) body.startTimestamp = element.startTimestamp
368 if (element.stopTimestamp && element.stopTimestamp !== this.video.duration) body.stopTimestamp = element.stopTimestamp 371 if (element.stopTimestamp && element.stopTimestamp !== this.video.duration) body.stopTimestamp = element.stopTimestamp
369 372
373 this.pendingAddId = playlist.id
374
370 this.videoPlaylistService.addVideoInPlaylist(playlist.id, body) 375 this.videoPlaylistService.addVideoInPlaylist(playlist.id, body)
371 .subscribe({ 376 .subscribe({
372 next: res => { 377 next: res => {
@@ -379,9 +384,17 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
379 if (element) element.playlistElementId = res.videoPlaylistElement.id 384 if (element) element.playlistElementId = res.videoPlaylistElement.id
380 }, 385 },
381 386
382 error: err => this.notifier.error(err.message), 387 error: err => {
388 this.pendingAddId = undefined
389 this.cd.markForCheck()
390
391 this.notifier.error(err.message)
392 },
383 393
384 complete: () => this.cd.markForCheck() 394 complete: () => {
395 this.pendingAddId = undefined
396 this.cd.markForCheck()
397 }
385 }) 398 })
386 } 399 }
387 400
diff --git a/client/src/assets/player/p2p-media-loader/segment-url-builder.ts b/client/src/assets/player/p2p-media-loader/segment-url-builder.ts
index 5ddc81ff6..9d324078a 100644
--- a/client/src/assets/player/p2p-media-loader/segment-url-builder.ts
+++ b/client/src/assets/player/p2p-media-loader/segment-url-builder.ts
@@ -1,10 +1,10 @@
1import { Segment } from '@peertube/p2p-media-loader-core' 1import { Segment } from '@peertube/p2p-media-loader-core'
2import { RedundancyUrlManager } from './redundancy-url-manager' 2import { RedundancyUrlManager } from './redundancy-url-manager'
3 3
4function segmentUrlBuilderFactory (redundancyUrlManager: RedundancyUrlManager, requiredSegmentsPriority: number) { 4function segmentUrlBuilderFactory (redundancyUrlManager: RedundancyUrlManager, useOriginPriority: number) {
5 return function segmentBuilder (segment: Segment) { 5 return function segmentBuilder (segment: Segment) {
6 // Don't use redundancy for high priority segments 6 // Don't use redundancy for high priority segments
7 if (segment.priority <= requiredSegmentsPriority) return segment.url 7 if (segment.priority <= useOriginPriority) return segment.url
8 8
9 return redundancyUrlManager.buildUrl(segment.url) 9 return redundancyUrlManager.buildUrl(segment.url)
10 } 10 }
diff --git a/client/src/assets/player/peertube-player-options-builder.ts b/client/src/assets/player/peertube-player-options-builder.ts
index 901f6cd3b..71be5ccff 100644
--- a/client/src/assets/player/peertube-player-options-builder.ts
+++ b/client/src/assets/player/peertube-player-options-builder.ts
@@ -19,6 +19,7 @@ import {
19 VideoJSPluginOptions 19 VideoJSPluginOptions
20} from './peertube-videojs-typings' 20} from './peertube-videojs-typings'
21import { buildVideoOrPlaylistEmbed, getRtcConfig, isIOS, isSafari } from './utils' 21import { buildVideoOrPlaylistEmbed, getRtcConfig, isIOS, isSafari } from './utils'
22import { HybridLoaderSettings } from '@peertube/p2p-media-loader-core'
22 23
23export type PlayerMode = 'webtorrent' | 'p2p-media-loader' 24export type PlayerMode = 'webtorrent' | 'p2p-media-loader'
24 25
@@ -198,9 +199,6 @@ export class PeertubePlayerOptionsBuilder {
198 const p2pMediaLoaderOptions = this.options.p2pMediaLoader 199 const p2pMediaLoaderOptions = this.options.p2pMediaLoader
199 const commonOptions = this.options.common 200 const commonOptions = this.options.common
200 201
201 const trackerAnnounce = p2pMediaLoaderOptions.trackerAnnounce
202 .filter(t => t.startsWith('ws'))
203
204 const redundancyUrlManager = new RedundancyUrlManager(this.options.p2pMediaLoader.redundancyBaseUrls) 202 const redundancyUrlManager = new RedundancyUrlManager(this.options.p2pMediaLoader.redundancyBaseUrls)
205 203
206 const p2pMediaLoader: P2PMediaLoaderPluginOptions = { 204 const p2pMediaLoader: P2PMediaLoaderPluginOptions = {
@@ -210,23 +208,8 @@ export class PeertubePlayerOptionsBuilder {
210 src: p2pMediaLoaderOptions.playlistUrl 208 src: p2pMediaLoaderOptions.playlistUrl
211 } 209 }
212 210
213 let consumeOnly = false
214 if ((navigator as any)?.connection?.type === 'cellular') {
215 console.log('We are on a cellular connection: disabling seeding.')
216 consumeOnly = true
217 }
218
219 const p2pMediaLoaderConfig: HlsJsEngineSettings = { 211 const p2pMediaLoaderConfig: HlsJsEngineSettings = {
220 loader: { 212 loader: this.getP2PMediaLoaderOptions(redundancyUrlManager),
221 trackerAnnounce,
222 segmentValidator: segmentValidatorFactory(this.options.p2pMediaLoader.segmentsSha256Url, this.options.common.isLive),
223 rtcConfig: getRtcConfig(),
224 requiredSegmentsPriority: 1,
225 simultaneousHttpDownloads: 1,
226 segmentUrlBuilder: segmentUrlBuilderFactory(redundancyUrlManager, 1),
227 useP2P: commonOptions.p2pEnabled,
228 consumeOnly
229 },
230 segments: { 213 segments: {
231 swarmId: p2pMediaLoaderOptions.playlistUrl 214 swarmId: p2pMediaLoaderOptions.playlistUrl
232 } 215 }
@@ -256,6 +239,46 @@ export class PeertubePlayerOptionsBuilder {
256 return toAssign 239 return toAssign
257 } 240 }
258 241
242 private getP2PMediaLoaderOptions (redundancyUrlManager: RedundancyUrlManager): Partial<HybridLoaderSettings> {
243 let consumeOnly = false
244 if ((navigator as any)?.connection?.type === 'cellular') {
245 console.log('We are on a cellular connection: disabling seeding.')
246 consumeOnly = true
247 }
248
249 const trackerAnnounce = this.options.p2pMediaLoader.trackerAnnounce
250 .filter(t => t.startsWith('ws'))
251
252 const specificLiveOrVODOptions = this.options.common.isLive
253 ? { // Live
254 requiredSegmentsPriority: 1
255 }
256 : { // VOD
257 requiredSegmentsPriority: 3,
258
259 cachedSegmentExpiration: 86400000,
260 cachedSegmentsCount: 100,
261
262 httpDownloadMaxPriority: 9,
263 httpDownloadProbability: 0.06,
264 httpDownloadProbabilitySkipIfNoPeers: true,
265
266 p2pDownloadMaxPriority: 50
267 }
268
269 return {
270 trackerAnnounce,
271 segmentValidator: segmentValidatorFactory(this.options.p2pMediaLoader.segmentsSha256Url, this.options.common.isLive),
272 rtcConfig: getRtcConfig(),
273 simultaneousHttpDownloads: 1,
274 segmentUrlBuilder: segmentUrlBuilderFactory(redundancyUrlManager, 1),
275 useP2P: this.options.common.p2pEnabled,
276 consumeOnly,
277
278 ...specificLiveOrVODOptions
279 }
280 }
281
259 private getHLSOptions (p2pMediaLoaderConfig: HlsJsEngineSettings) { 282 private getHLSOptions (p2pMediaLoaderConfig: HlsJsEngineSettings) {
260 const base = { 283 const base = {
261 capLevelToPlayerSize: true, 284 capLevelToPlayerSize: true,