diff options
author | Chocobozzz <me@florianbigard.com> | 2022-06-03 14:32:44 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2022-06-03 14:32:44 +0200 |
commit | e771ff815dba3b4a95633f4e1e10dacd222dfe61 (patch) | |
tree | 9e1909e1fff3c602ac894b43dbf72316aca62b70 | |
parent | 8a2166c9bfa452ce707740d99c64d668cd7cedce (diff) | |
parent | 62f53731cf807562ba885b180e71bb75b3902443 (diff) | |
download | PeerTube-e771ff815dba3b4a95633f4e1e10dacd222dfe61.tar.gz PeerTube-e771ff815dba3b4a95633f4e1e10dacd222dfe61.tar.zst PeerTube-e771ff815dba3b4a95633f4e1e10dacd222dfe61.zip |
Merge branch 'release/4.2.0' into develop
14 files changed, 33 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index ca27aa3a5..4638cd6d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md | |||
@@ -17,6 +17,7 @@ | |||
17 | * Add `client.videos.resumable_upload.max_chunk_size` config option [#4857](https://github.com/Chocobozzz/PeerTube/pull/4857) | 17 | * Add `client.videos.resumable_upload.max_chunk_size` config option [#4857](https://github.com/Chocobozzz/PeerTube/pull/4857) |
18 | * Add `object_storage.upload_acl` config option [#4861](https://github.com/Chocobozzz/PeerTube/pull/4861) | 18 | * Add `object_storage.upload_acl` config option [#4861](https://github.com/Chocobozzz/PeerTube/pull/4861) |
19 | * Add ability to set RTMP/RTMPS listening hostname using `rtmp.hostname`/`rtmps.hostname` and public RTMP/RTMPS hostname using `rtmp.public_hostname`/`rtmps.public_hostname` | 19 | * Add ability to set RTMP/RTMPS listening hostname using `rtmp.hostname`/`rtmps.hostname` and public RTMP/RTMPS hostname using `rtmp.public_hostname`/`rtmps.public_hostname` |
20 | * Removed `best` default trending algorithm. It is automatically used if using `hot` algorithm with a logged in user | ||
20 | 21 | ||
21 | ### Docker | 22 | ### Docker |
22 | 23 | ||
diff --git a/client/src/app/+videos/+video-watch/shared/information/video-alert.component.html b/client/src/app/+videos/+video-watch/shared/information/video-alert.component.html index c6ffb1abd..be726c990 100644 --- a/client/src/app/+videos/+video-watch/shared/information/video-alert.component.html +++ b/client/src/app/+videos/+video-watch/shared/information/video-alert.component.html | |||
@@ -34,6 +34,10 @@ | |||
34 | This live has ended. | 34 | This live has ended. |
35 | </div> | 35 | </div> |
36 | 36 | ||
37 | <div i18n class="alert alert-warning" *ngIf="noPlaylistVideoFound"> | ||
38 | There are no videos available in this playlist. | ||
39 | </div> | ||
40 | |||
37 | <div class="alert alert-danger" *ngIf="video?.blacklisted"> | 41 | <div class="alert alert-danger" *ngIf="video?.blacklisted"> |
38 | <div class="blocked-label" i18n>This video is blocked.</div> | 42 | <div class="blocked-label" i18n>This video is blocked.</div> |
39 | {{ video.blacklistedReason }} | 43 | {{ video.blacklistedReason }} |
diff --git a/client/src/app/+videos/+video-watch/shared/information/video-alert.component.ts b/client/src/app/+videos/+video-watch/shared/information/video-alert.component.ts index 79b56705f..ba79fabc8 100644 --- a/client/src/app/+videos/+video-watch/shared/information/video-alert.component.ts +++ b/client/src/app/+videos/+video-watch/shared/information/video-alert.component.ts | |||
@@ -9,6 +9,7 @@ import { VideoState } from '@shared/models' | |||
9 | }) | 9 | }) |
10 | export class VideoAlertComponent { | 10 | export class VideoAlertComponent { |
11 | @Input() video: VideoDetails | 11 | @Input() video: VideoDetails |
12 | @Input() noPlaylistVideoFound: boolean | ||
12 | 13 | ||
13 | isVideoToTranscode () { | 14 | isVideoToTranscode () { |
14 | return this.video && this.video.state.id === VideoState.TO_TRANSCODE | 15 | return this.video && this.video.state.id === VideoState.TO_TRANSCODE |
diff --git a/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.html b/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.html index da81d76d1..f5dd352a3 100644 --- a/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.html +++ b/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.html | |||
@@ -1,5 +1,5 @@ | |||
1 | <div | 1 | <div |
2 | *ngIf="playlist && currentPlaylistPosition" class="playlist" | 2 | *ngIf="playlist && (currentPlaylistPosition || noPlaylistVideos)" class="playlist" |
3 | myInfiniteScroller [onItself]="true" (nearOfBottom)="onPlaylistVideosNearOfBottom()" | 3 | myInfiniteScroller [onItself]="true" (nearOfBottom)="onPlaylistVideosNearOfBottom()" |
4 | > | 4 | > |
5 | <div class="playlist-info"> | 5 | <div class="playlist-info"> |
diff --git a/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.ts b/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.ts index 879d296a7..ec85db0ff 100644 --- a/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.ts +++ b/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.ts | |||
@@ -18,6 +18,7 @@ export class VideoWatchPlaylistComponent { | |||
18 | @Input() playlist: VideoPlaylist | 18 | @Input() playlist: VideoPlaylist |
19 | 19 | ||
20 | @Output() videoFound = new EventEmitter<string>() | 20 | @Output() videoFound = new EventEmitter<string>() |
21 | @Output() noVideoFound = new EventEmitter<void>() | ||
21 | 22 | ||
22 | playlistElements: VideoPlaylistElement[] = [] | 23 | playlistElements: VideoPlaylistElement[] = [] |
23 | playlistPagination: ComponentPagination = { | 24 | playlistPagination: ComponentPagination = { |
@@ -28,10 +29,11 @@ export class VideoWatchPlaylistComponent { | |||
28 | 29 | ||
29 | autoPlayNextVideoPlaylist: boolean | 30 | autoPlayNextVideoPlaylist: boolean |
30 | autoPlayNextVideoPlaylistSwitchText = '' | 31 | autoPlayNextVideoPlaylistSwitchText = '' |
32 | |||
31 | loopPlaylist: boolean | 33 | loopPlaylist: boolean |
32 | loopPlaylistSwitchText = '' | 34 | loopPlaylistSwitchText = '' |
33 | noPlaylistVideos = false | ||
34 | 35 | ||
36 | noPlaylistVideos = false | ||
35 | currentPlaylistPosition: number | 37 | currentPlaylistPosition: number |
36 | 38 | ||
37 | constructor ( | 39 | constructor ( |
@@ -100,6 +102,7 @@ export class VideoWatchPlaylistComponent { | |||
100 | const firstAvailableVideo = this.playlistElements.find(e => !!e.video) | 102 | const firstAvailableVideo = this.playlistElements.find(e => !!e.video) |
101 | if (!firstAvailableVideo) { | 103 | if (!firstAvailableVideo) { |
102 | this.noPlaylistVideos = true | 104 | this.noPlaylistVideos = true |
105 | this.noVideoFound.emit() | ||
103 | return | 106 | return |
104 | } | 107 | } |
105 | 108 | ||
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 4c15ae3d7..1ea0cf6b8 100644 --- a/client/src/app/+videos/+video-watch/video-watch.component.html +++ b/client/src/app/+videos/+video-watch/video-watch.component.html | |||
@@ -11,12 +11,15 @@ | |||
11 | <img class="placeholder-image" *ngIf="playerPlaceholderImgSrc" [src]="playerPlaceholderImgSrc" alt="Placeholder image" i18n-alt> | 11 | <img class="placeholder-image" *ngIf="playerPlaceholderImgSrc" [src]="playerPlaceholderImgSrc" alt="Placeholder image" i18n-alt> |
12 | </div> | 12 | </div> |
13 | 13 | ||
14 | <my-video-watch-playlist #videoWatchPlaylist [playlist]="playlist" (videoFound)="onPlaylistVideoFound($event)"></my-video-watch-playlist> | 14 | <my-video-watch-playlist |
15 | #videoWatchPlaylist [playlist]="playlist" | ||
16 | (noVideoFound)="onPlaylistNoVideoFound()" (videoFound)="onPlaylistVideoFound($event)" | ||
17 | ></my-video-watch-playlist> | ||
15 | 18 | ||
16 | <my-plugin-placeholder pluginId="player-next"></my-plugin-placeholder> | 19 | <my-plugin-placeholder pluginId="player-next"></my-plugin-placeholder> |
17 | </div> | 20 | </div> |
18 | 21 | ||
19 | <my-video-alert [video]="video"></my-video-alert> | 22 | <my-video-alert [video]="video" [noPlaylistVideoFound]="noPlaylistVideoFound"></my-video-alert> |
20 | 23 | ||
21 | <!-- Video information --> | 24 | <!-- Video information --> |
22 | <div *ngIf="video" class="margin-content video-bottom"> | 25 | <div *ngIf="video" class="margin-content video-bottom"> |
diff --git a/client/src/app/+videos/+video-watch/video-watch.component.ts b/client/src/app/+videos/+video-watch/video-watch.component.ts index 5fa31ec63..d05f08a5f 100644 --- a/client/src/app/+videos/+video-watch/video-watch.component.ts +++ b/client/src/app/+videos/+video-watch/video-watch.component.ts | |||
@@ -72,6 +72,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
72 | playlist: VideoPlaylist = null | 72 | playlist: VideoPlaylist = null |
73 | 73 | ||
74 | remoteServerDown = false | 74 | remoteServerDown = false |
75 | noPlaylistVideoFound = false | ||
75 | 76 | ||
76 | private nextVideoUUID = '' | 77 | private nextVideoUUID = '' |
77 | private nextVideoTitle = '' | 78 | private nextVideoTitle = '' |
@@ -178,6 +179,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
178 | this.loadVideo(videoId) | 179 | this.loadVideo(videoId) |
179 | } | 180 | } |
180 | 181 | ||
182 | onPlaylistNoVideoFound () { | ||
183 | this.noPlaylistVideoFound = true | ||
184 | } | ||
185 | |||
181 | isUserLoggedIn () { | 186 | isUserLoggedIn () { |
182 | return this.authService.isLoggedIn() | 187 | return this.authService.isLoggedIn() |
183 | } | 188 | } |
@@ -286,6 +291,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
286 | private loadPlaylist (playlistId: string) { | 291 | private loadPlaylist (playlistId: string) { |
287 | if (this.isSameElement(this.playlist, playlistId)) return | 292 | if (this.isSameElement(this.playlist, playlistId)) return |
288 | 293 | ||
294 | this.noPlaylistVideoFound = false | ||
295 | |||
289 | this.playlistService.getVideoPlaylist(playlistId) | 296 | this.playlistService.getVideoPlaylist(playlistId) |
290 | .subscribe({ | 297 | .subscribe({ |
291 | next: playlist => { | 298 | next: playlist => { |
diff --git a/client/src/app/+videos/video-list/videos-list-common-page.component.ts b/client/src/app/+videos/video-list/videos-list-common-page.component.ts index 72c7e1ef6..d2782036b 100644 --- a/client/src/app/+videos/video-list/videos-list-common-page.component.ts +++ b/client/src/app/+videos/video-list/videos-list-common-page.component.ts | |||
@@ -173,6 +173,10 @@ export class VideosListCommonPageComponent implements OnInit, OnDestroy, Disable | |||
173 | case 'most-liked': | 173 | case 'most-liked': |
174 | return '-likes' | 174 | return '-likes' |
175 | 175 | ||
176 | // We'll automatically apply "best" sort if using "hot" sort with a logged user | ||
177 | case 'best': | ||
178 | return '-hot' | ||
179 | |||
176 | default: | 180 | default: |
177 | return '-' + algorithm as VideoSortField | 181 | return '-' + algorithm as VideoSortField |
178 | } | 182 | } |
diff --git a/config/default.yaml b/config/default.yaml index c0d17decf..f7c9b620c 100644 --- a/config/default.yaml +++ b/config/default.yaml | |||
@@ -181,7 +181,6 @@ trending: | |||
181 | interval_days: 7 # Compute trending videos for the last x days | 181 | interval_days: 7 # Compute trending videos for the last x days |
182 | algorithms: | 182 | algorithms: |
183 | enabled: | 183 | enabled: |
184 | - 'best' # adaptation of Reddit's 'Best' algorithm (Hot minus History) | ||
185 | - 'hot' # adaptation of Reddit's 'Hot' algorithm | 184 | - 'hot' # adaptation of Reddit's 'Hot' algorithm |
186 | - 'most-viewed' # default, used initially by PeerTube as the trending page | 185 | - 'most-viewed' # default, used initially by PeerTube as the trending page |
187 | - 'most-liked' | 186 | - 'most-liked' |
diff --git a/config/production.yaml.example b/config/production.yaml.example index 8fd8d805f..a36f4979b 100644 --- a/config/production.yaml.example +++ b/config/production.yaml.example | |||
@@ -177,7 +177,6 @@ trending: | |||
177 | interval_days: 7 # Compute trending videos for the last x days | 177 | interval_days: 7 # Compute trending videos for the last x days |
178 | algorithms: | 178 | algorithms: |
179 | enabled: | 179 | enabled: |
180 | - 'best' # adaptation of Reddit's 'Best' algorithm (Hot minus History) | ||
181 | - 'hot' # adaptation of Reddit's 'Hot' algorithm | 180 | - 'hot' # adaptation of Reddit's 'Hot' algorithm |
182 | - 'most-viewed' # default, used initially by PeerTube as the trending page | 181 | - 'most-viewed' # default, used initially by PeerTube as the trending page |
183 | - 'most-liked' | 182 | - 'most-liked' |
diff --git a/server/controllers/download.ts b/server/controllers/download.ts index 43d525f83..a270180c0 100644 --- a/server/controllers/download.ts +++ b/server/controllers/download.ts | |||
@@ -86,7 +86,9 @@ async function downloadVideoFile (req: express.Request, res: express.Response) { | |||
86 | } | 86 | } |
87 | 87 | ||
88 | await VideoPathManager.Instance.makeAvailableVideoFile(videoFile.withVideoOrPlaylist(video), path => { | 88 | await VideoPathManager.Instance.makeAvailableVideoFile(videoFile.withVideoOrPlaylist(video), path => { |
89 | const filename = `${video.name}-${videoFile.resolution}p${videoFile.extname}` | 89 | // Express uses basename on filename parameter |
90 | const videoName = video.name.replace(/[/\\]/g, '_') | ||
91 | const filename = `${videoName}-${videoFile.resolution}p${videoFile.extname}` | ||
90 | 92 | ||
91 | return res.download(path, filename) | 93 | return res.download(path, filename) |
92 | }) | 94 | }) |
diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts index c8dbbf797..99fb24a5b 100644 --- a/server/tests/api/check-params/config.ts +++ b/server/tests/api/check-params/config.ts | |||
@@ -165,7 +165,7 @@ describe('Test config API validators', function () { | |||
165 | trending: { | 165 | trending: { |
166 | videos: { | 166 | videos: { |
167 | algorithms: { | 167 | algorithms: { |
168 | enabled: [ 'best', 'hot', 'most-viewed', 'most-liked' ], | 168 | enabled: [ 'hot', 'most-viewed', 'most-liked' ], |
169 | default: 'most-viewed' | 169 | default: 'most-viewed' |
170 | } | 170 | } |
171 | } | 171 | } |
diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts index f31012a5c..0f2fb5493 100644 --- a/server/tests/api/server/config.ts +++ b/server/tests/api/server/config.ts | |||
@@ -367,7 +367,7 @@ const newCustomConfig: CustomConfig = { | |||
367 | trending: { | 367 | trending: { |
368 | videos: { | 368 | videos: { |
369 | algorithms: { | 369 | algorithms: { |
370 | enabled: [ 'best', 'hot', 'most-viewed', 'most-liked' ], | 370 | enabled: [ 'hot', 'most-viewed', 'most-liked' ], |
371 | default: 'hot' | 371 | default: 'hot' |
372 | } | 372 | } |
373 | } | 373 | } |
diff --git a/shared/server-commands/server/config-command.ts b/shared/server-commands/server/config-command.ts index ed4961bc3..5320dead4 100644 --- a/shared/server-commands/server/config-command.ts +++ b/shared/server-commands/server/config-command.ts | |||
@@ -356,7 +356,7 @@ export class ConfigCommand extends AbstractCommand { | |||
356 | trending: { | 356 | trending: { |
357 | videos: { | 357 | videos: { |
358 | algorithms: { | 358 | algorithms: { |
359 | enabled: [ 'best', 'hot', 'most-viewed', 'most-liked' ], | 359 | enabled: [ 'hot', 'most-viewed', 'most-liked' ], |
360 | default: 'hot' | 360 | default: 'hot' |
361 | } | 361 | } |
362 | } | 362 | } |