mirror of https://github.com/Chocobozzz/PeerTube
Merge branch 'release/4.1.0' into develop
commit
f7298d0dcc
|
@ -19,8 +19,13 @@ export class MyAccountDangerZoneComponent {
|
|||
|
||||
async deleteMe () {
|
||||
const res = await this.confirmService.confirmWithInput(
|
||||
// eslint-disable-next-line max-len
|
||||
$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.`,
|
||||
$localize`Are you sure you want to delete your account?` +
|
||||
'<br /><br />' +
|
||||
// eslint-disable-next-line max-len
|
||||
$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.` +
|
||||
'<br /><br />' +
|
||||
$localize`Content cached by other servers and other third-parties might make longer to be deleted.`,
|
||||
|
||||
$localize`Type your username to confirm`,
|
||||
this.user.username,
|
||||
$localize`Delete your account`,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'
|
||||
import { HtmlRendererService } from '@app/core'
|
||||
import { ConfirmService } from '@app/core/confirm/confirm.service'
|
||||
import { POP_STATE_MODAL_DISMISS } from '@app/helpers'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
|
@ -24,6 +25,7 @@ export class ConfirmComponent implements OnInit {
|
|||
|
||||
constructor (
|
||||
private modalService: NgbModal,
|
||||
private html: HtmlRendererService,
|
||||
private confirmService: ConfirmService
|
||||
) { }
|
||||
|
||||
|
@ -31,14 +33,18 @@ export class ConfirmComponent implements OnInit {
|
|||
this.confirmService.showConfirm.subscribe(
|
||||
({ title, message, expectedInputValue, inputLabel, confirmButtonText }) => {
|
||||
this.title = title
|
||||
this.message = message
|
||||
|
||||
this.inputLabel = inputLabel
|
||||
this.expectedInputValue = expectedInputValue
|
||||
|
||||
this.confirmButtonText = confirmButtonText || $localize`Confirm`
|
||||
|
||||
this.showModal()
|
||||
this.html.toSafeHtml(message)
|
||||
.then(message => {
|
||||
this.message = message
|
||||
|
||||
this.showModal()
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -56,6 +56,8 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
|
|||
private listenToPlaylistChangeSub: Subscription
|
||||
private playlistsData: CachedPlaylist[] = []
|
||||
|
||||
private pendingAddId: number
|
||||
|
||||
constructor (
|
||||
protected formValidatorService: FormValidatorService,
|
||||
private authService: AuthService,
|
||||
|
@ -215,8 +217,9 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
|
|||
}
|
||||
|
||||
isPrimaryCheckboxChecked (playlist: PlaylistSummary) {
|
||||
return playlist.elements.filter(e => e.enabled)
|
||||
.length !== 0
|
||||
// Reduce latency when adding a video to a playlist using pendingAddId
|
||||
return this.pendingAddId === playlist.id ||
|
||||
playlist.elements.filter(e => e.enabled).length !== 0
|
||||
}
|
||||
|
||||
toggleOptionalRow (playlist: PlaylistSummary) {
|
||||
|
@ -367,6 +370,8 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
|
|||
if (element.startTimestamp) body.startTimestamp = element.startTimestamp
|
||||
if (element.stopTimestamp && element.stopTimestamp !== this.video.duration) body.stopTimestamp = element.stopTimestamp
|
||||
|
||||
this.pendingAddId = playlist.id
|
||||
|
||||
this.videoPlaylistService.addVideoInPlaylist(playlist.id, body)
|
||||
.subscribe({
|
||||
next: res => {
|
||||
|
@ -379,9 +384,17 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
|
|||
if (element) element.playlistElementId = res.videoPlaylistElement.id
|
||||
},
|
||||
|
||||
error: err => this.notifier.error(err.message),
|
||||
error: err => {
|
||||
this.pendingAddId = undefined
|
||||
this.cd.markForCheck()
|
||||
|
||||
complete: () => this.cd.markForCheck()
|
||||
this.notifier.error(err.message)
|
||||
},
|
||||
|
||||
complete: () => {
|
||||
this.pendingAddId = undefined
|
||||
this.cd.markForCheck()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Segment } from '@peertube/p2p-media-loader-core'
|
||||
import { RedundancyUrlManager } from './redundancy-url-manager'
|
||||
|
||||
function segmentUrlBuilderFactory (redundancyUrlManager: RedundancyUrlManager, requiredSegmentsPriority: number) {
|
||||
function segmentUrlBuilderFactory (redundancyUrlManager: RedundancyUrlManager, useOriginPriority: number) {
|
||||
return function segmentBuilder (segment: Segment) {
|
||||
// Don't use redundancy for high priority segments
|
||||
if (segment.priority <= requiredSegmentsPriority) return segment.url
|
||||
if (segment.priority <= useOriginPriority) return segment.url
|
||||
|
||||
return redundancyUrlManager.buildUrl(segment.url)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
VideoJSPluginOptions
|
||||
} from './peertube-videojs-typings'
|
||||
import { buildVideoOrPlaylistEmbed, getRtcConfig, isIOS, isSafari } from './utils'
|
||||
import { HybridLoaderSettings } from '@peertube/p2p-media-loader-core'
|
||||
|
||||
export type PlayerMode = 'webtorrent' | 'p2p-media-loader'
|
||||
|
||||
|
@ -198,9 +199,6 @@ export class PeertubePlayerOptionsBuilder {
|
|||
const p2pMediaLoaderOptions = this.options.p2pMediaLoader
|
||||
const commonOptions = this.options.common
|
||||
|
||||
const trackerAnnounce = p2pMediaLoaderOptions.trackerAnnounce
|
||||
.filter(t => t.startsWith('ws'))
|
||||
|
||||
const redundancyUrlManager = new RedundancyUrlManager(this.options.p2pMediaLoader.redundancyBaseUrls)
|
||||
|
||||
const p2pMediaLoader: P2PMediaLoaderPluginOptions = {
|
||||
|
@ -210,23 +208,8 @@ export class PeertubePlayerOptionsBuilder {
|
|||
src: p2pMediaLoaderOptions.playlistUrl
|
||||
}
|
||||
|
||||
let consumeOnly = false
|
||||
if ((navigator as any)?.connection?.type === 'cellular') {
|
||||
console.log('We are on a cellular connection: disabling seeding.')
|
||||
consumeOnly = true
|
||||
}
|
||||
|
||||
const p2pMediaLoaderConfig: HlsJsEngineSettings = {
|
||||
loader: {
|
||||
trackerAnnounce,
|
||||
segmentValidator: segmentValidatorFactory(this.options.p2pMediaLoader.segmentsSha256Url, this.options.common.isLive),
|
||||
rtcConfig: getRtcConfig(),
|
||||
requiredSegmentsPriority: 1,
|
||||
simultaneousHttpDownloads: 1,
|
||||
segmentUrlBuilder: segmentUrlBuilderFactory(redundancyUrlManager, 1),
|
||||
useP2P: commonOptions.p2pEnabled,
|
||||
consumeOnly
|
||||
},
|
||||
loader: this.getP2PMediaLoaderOptions(redundancyUrlManager),
|
||||
segments: {
|
||||
swarmId: p2pMediaLoaderOptions.playlistUrl
|
||||
}
|
||||
|
@ -256,6 +239,46 @@ export class PeertubePlayerOptionsBuilder {
|
|||
return toAssign
|
||||
}
|
||||
|
||||
private getP2PMediaLoaderOptions (redundancyUrlManager: RedundancyUrlManager): Partial<HybridLoaderSettings> {
|
||||
let consumeOnly = false
|
||||
if ((navigator as any)?.connection?.type === 'cellular') {
|
||||
console.log('We are on a cellular connection: disabling seeding.')
|
||||
consumeOnly = true
|
||||
}
|
||||
|
||||
const trackerAnnounce = this.options.p2pMediaLoader.trackerAnnounce
|
||||
.filter(t => t.startsWith('ws'))
|
||||
|
||||
const specificLiveOrVODOptions = this.options.common.isLive
|
||||
? { // Live
|
||||
requiredSegmentsPriority: 1
|
||||
}
|
||||
: { // VOD
|
||||
requiredSegmentsPriority: 3,
|
||||
|
||||
cachedSegmentExpiration: 86400000,
|
||||
cachedSegmentsCount: 100,
|
||||
|
||||
httpDownloadMaxPriority: 9,
|
||||
httpDownloadProbability: 0.06,
|
||||
httpDownloadProbabilitySkipIfNoPeers: true,
|
||||
|
||||
p2pDownloadMaxPriority: 50
|
||||
}
|
||||
|
||||
return {
|
||||
trackerAnnounce,
|
||||
segmentValidator: segmentValidatorFactory(this.options.p2pMediaLoader.segmentsSha256Url, this.options.common.isLive),
|
||||
rtcConfig: getRtcConfig(),
|
||||
simultaneousHttpDownloads: 1,
|
||||
segmentUrlBuilder: segmentUrlBuilderFactory(redundancyUrlManager, 1),
|
||||
useP2P: this.options.common.p2pEnabled,
|
||||
consumeOnly,
|
||||
|
||||
...specificLiveOrVODOptions
|
||||
}
|
||||
}
|
||||
|
||||
private getHLSOptions (p2pMediaLoaderConfig: HlsJsEngineSettings) {
|
||||
const base = {
|
||||
capLevelToPlayerSize: true,
|
||||
|
|
|
@ -104,7 +104,7 @@ async function generateVideoCommentsFeed (req: express.Request, res: express.Res
|
|||
|
||||
// Adding video items to the feed, one at a time
|
||||
for (const comment of comments) {
|
||||
const link = WEBSERVER.URL + comment.getCommentStaticPath()
|
||||
const localLink = WEBSERVER.URL + comment.getCommentStaticPath()
|
||||
|
||||
let title = comment.Video.name
|
||||
const author: { name: string, link: string }[] = []
|
||||
|
@ -119,8 +119,8 @@ async function generateVideoCommentsFeed (req: express.Request, res: express.Res
|
|||
|
||||
feed.addItem({
|
||||
title,
|
||||
id: comment.url,
|
||||
link,
|
||||
id: localLink,
|
||||
link: localLink,
|
||||
content: toSafeHtml(comment.text),
|
||||
author,
|
||||
date: comment.createdAt
|
||||
|
@ -269,7 +269,7 @@ function addVideosToFeed (feed: Feed, videos: VideoModel[]) {
|
|||
size_in_bytes: videoFile.size
|
||||
}))
|
||||
|
||||
const videos = formattedVideoFiles.map(videoFile => {
|
||||
const videoFiles = formattedVideoFiles.map(videoFile => {
|
||||
const result = {
|
||||
type: MIMETYPES.VIDEO.EXT_MIMETYPE[extname(videoFile.fileUrl)],
|
||||
medium: 'video',
|
||||
|
@ -293,10 +293,12 @@ function addVideosToFeed (feed: Feed, videos: VideoModel[]) {
|
|||
})
|
||||
}
|
||||
|
||||
const localLink = WEBSERVER.URL + video.getWatchStaticPath()
|
||||
|
||||
feed.addItem({
|
||||
title: video.name,
|
||||
id: video.url,
|
||||
link: WEBSERVER.URL + video.getWatchStaticPath(),
|
||||
id: localLink,
|
||||
link: localLink,
|
||||
description: mdToOneLinePlainText(video.getTruncatedDescription()),
|
||||
content: toSafeHtml(video.description),
|
||||
author: [
|
||||
|
@ -311,20 +313,20 @@ function addVideosToFeed (feed: Feed, videos: VideoModel[]) {
|
|||
|
||||
// Enclosure
|
||||
video: {
|
||||
url: videos[0].url,
|
||||
length: videos[0].fileSize,
|
||||
type: videos[0].type
|
||||
url: videoFiles[0].url,
|
||||
length: videoFiles[0].fileSize,
|
||||
type: videoFiles[0].type
|
||||
},
|
||||
|
||||
// Media RSS
|
||||
videos,
|
||||
videos: videoFiles,
|
||||
|
||||
embed: {
|
||||
url: video.getEmbedStaticPath(),
|
||||
url: WEBSERVER.URL + video.getEmbedStaticPath(),
|
||||
allowFullscreen: true
|
||||
},
|
||||
player: {
|
||||
url: video.getWatchStaticPath()
|
||||
url: WEBSERVER.URL + video.getWatchStaticPath()
|
||||
},
|
||||
categories,
|
||||
community: {
|
||||
|
|
Loading…
Reference in New Issue