From 2b0d17ccf46cfdba4103b7287f0dadf289ad4faf Mon Sep 17 00:00:00 2001
From: Chocobozzz <me@florianbigard.com>
Date: Fri, 15 Apr 2022 15:07:20 +0200
Subject: Reduce videos sort complexity

Automatically use best sort if user is logged in and chose hot algorithm
---
 .../edit-basic-configuration.component.html         |  1 -
 .../video-list/videos-list-common-page.component.ts |  3 +--
 client/src/app/core/rest/rest.service.ts            | 18 +++++++++---------
 .../app/shared/shared-main/video/video.service.ts   | 21 +++++++++++++++++++--
 .../video-filters-header.component.html             |  1 -
 .../video-filters-header.component.ts               |  9 ++-------
 6 files changed, 31 insertions(+), 22 deletions(-)

(limited to 'client/src')

diff --git a/client/src/app/+admin/config/edit-custom-config/edit-basic-configuration.component.html b/client/src/app/+admin/config/edit-custom-config/edit-basic-configuration.component.html
index 3673a805b..bae9d9775 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-basic-configuration.component.html
+++ b/client/src/app/+admin/config/edit-custom-config/edit-basic-configuration.component.html
@@ -44,7 +44,6 @@
 
             <div class="peertube-select-container">
               <select id="trendingVideosAlgorithmsDefault" formControlName="default" class="form-control">
-                <option i18n value="best">Best videos</option>
                 <option i18n value="hot">Hot videos</option>
                 <option i18n value="most-viewed">Most viewed videos</option>
                 <option i18n value="most-liked">Most liked videos</option>
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 d03b09610..32737ef1c 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
@@ -197,10 +197,9 @@ export class VideosListCommonPageComponent implements OnInit, OnDestroy, Disable
       return
     }
 
-    if ([ 'best', 'hot', 'trending', 'likes' ].includes(sanitizedSort)) {
+    if ([ 'hot', 'trending', 'likes' ].includes(sanitizedSort)) {
       this.title = $localize`Trending`
 
-      if (sanitizedSort === 'best') this.titleTooltip = $localize`Videos with the most interactions for recent videos, minus user history`
       if (sanitizedSort === 'hot') this.titleTooltip = $localize`Videos with the most interactions for recent videos`
       if (sanitizedSort === 'likes') this.titleTooltip = $localize`Videos that have the most likes`
 
diff --git a/client/src/app/core/rest/rest.service.ts b/client/src/app/core/rest/rest.service.ts
index b2a5a3f72..fc729f0f6 100644
--- a/client/src/app/core/rest/rest.service.ts
+++ b/client/src/app/core/rest/rest.service.ts
@@ -31,19 +31,19 @@ export class RestService {
     }
 
     if (sort !== undefined) {
-      let sortString = ''
+      newParams = newParams.set('sort', this.buildSortString(sort))
+    }
 
-      if (typeof sort === 'string') {
-        sortString = sort
-      } else {
-        const sortPrefix = sort.order === 1 ? '' : '-'
-        sortString = sortPrefix + sort.field
-      }
+    return newParams
+  }
 
-      newParams = newParams.set('sort', sortString)
+  buildSortString (sort: SortMeta | string) {
+    if (typeof sort === 'string') {
+      return sort
     }
 
-    return newParams
+    const sortPrefix = sort.order === 1 ? '' : '-'
+    return sortPrefix + sort.field
   }
 
   addArrayParams (params: HttpParams, name: string, values: (string | number)[]) {
diff --git a/client/src/app/shared/shared-main/video/video.service.ts b/client/src/app/shared/shared-main/video/video.service.ts
index bc15c326f..142367506 100644
--- a/client/src/app/shared/shared-main/video/video.service.ts
+++ b/client/src/app/shared/shared-main/video/video.service.ts
@@ -3,7 +3,7 @@ import { from, Observable } from 'rxjs'
 import { catchError, concatMap, map, switchMap, toArray } from 'rxjs/operators'
 import { HttpClient, HttpParams, HttpRequest } from '@angular/common/http'
 import { Injectable } from '@angular/core'
-import { ComponentPaginationLight, RestExtractor, RestService, ServerService, UserService } from '@app/core'
+import { AuthService, ComponentPaginationLight, RestExtractor, RestService, ServerService, UserService } from '@app/core'
 import { objectToFormData } from '@app/helpers'
 import {
   BooleanBothQuery,
@@ -55,6 +55,7 @@ export class VideoService {
   static BASE_SUBSCRIPTION_FEEDS_URL = environment.apiUrl + '/feeds/subscriptions.'
 
   constructor (
+    private auth: AuthService,
     private authHttp: HttpClient,
     private restExtractor: RestExtractor,
     private restService: RestService,
@@ -418,7 +419,7 @@ export class VideoService {
       ? this.restService.componentToRestPagination(videoPagination)
       : undefined
 
-    let newParams = this.restService.addRestGetParams(params, pagination, sort)
+    let newParams = this.restService.addRestGetParams(params, pagination, this.buildListSort(sort))
 
     if (skipCount) newParams = newParams.set('skipCount', skipCount + '')
 
@@ -434,6 +435,22 @@ export class VideoService {
     return newParams
   }
 
+  private buildListSort (sortArg: VideoSortField | SortMeta) {
+    const sort = this.restService.buildSortString(sortArg)
+
+    if (typeof sort === 'string') {
+      // Silently use the best algorithm for logged in users if they chose the hot algorithm
+      if (
+        this.auth.isLoggedIn() &&
+        (sort === 'hot' || sort === '-hot')
+      ) {
+        return sort.replace('hot', 'best')
+      }
+
+      return sort
+    }
+  }
+
   private setVideoRate (id: number, rateType: UserVideoRateType) {
     const url = `${VideoService.BASE_VIDEO_URL}/${id}/rate`
     const body: UserVideoRateUpdate = {
diff --git a/client/src/app/shared/shared-video-miniature/video-filters-header.component.html b/client/src/app/shared/shared-video-miniature/video-filters-header.component.html
index 7f5692dd4..fc34b1b29 100644
--- a/client/src/app/shared/shared-video-miniature/video-filters-header.component.html
+++ b/client/src/app/shared/shared-video-miniature/video-filters-header.component.html
@@ -47,7 +47,6 @@
 
       <ng-option i18n *ngIf="isTrendingSortEnabled('most-viewed')" value="-trending">Sort by <strong>"Recent Views"</strong></ng-option>
       <ng-option i18n *ngIf="isTrendingSortEnabled('hot')" value="-hot">Sort by <strong>"Hot"</strong></ng-option>
-      <ng-option i18n *ngIf="isTrendingSortEnabled('best')" value="-best">Sort by <strong>"Best"</strong></ng-option>
       <ng-option i18n *ngIf="isTrendingSortEnabled('most-liked')" value="-likes">Sort by <strong>"Likes"</strong></ng-option>
     </ng-select>
 
diff --git a/client/src/app/shared/shared-video-miniature/video-filters-header.component.ts b/client/src/app/shared/shared-video-miniature/video-filters-header.component.ts
index 2c52e43f7..7b806248b 100644
--- a/client/src/app/shared/shared-video-miniature/video-filters-header.component.ts
+++ b/client/src/app/shared/shared-video-miniature/video-filters-header.component.ts
@@ -72,15 +72,10 @@ export class VideoFiltersHeaderComponent implements OnInit, OnDestroy {
     return this.auth.getUser().hasRight(UserRight.SEE_ALL_VIDEOS)
   }
 
-  isTrendingSortEnabled (sort: 'most-viewed' | 'hot' | 'best' | 'most-liked') {
+  isTrendingSortEnabled (sort: 'most-viewed' | 'hot' | 'most-liked') {
     const serverConfig = this.serverService.getHTMLConfig()
 
-    const enabled = serverConfig.trending.videos.algorithms.enabled.includes(sort)
-
-    // Best is adapted from the user
-    if (sort === 'best') return enabled && this.auth.isLoggedIn()
-
-    return enabled
+    return serverConfig.trending.videos.algorithms.enabled.includes(sort)
   }
 
   resetFilter (key: string, canRemove: boolean) {
-- 
cgit v1.2.3