From 5c20a45518c3afc40c9494cad4a78def92e5e288 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 16 Jun 2020 11:00:35 +0200 Subject: [PATCH] Fix anonymous nsfw policy --- .../account-video-channels.component.html | 2 +- .../account-video-channels.component.ts | 34 ++++----- .../my-account-history.component.html | 3 +- .../video-channel-videos.component.ts | 2 +- client/src/app/app.component.ts | 1 - .../modal/quick-settings-modal.component.html | 13 +++- .../modal/quick-settings-modal.component.ts | 8 ++- client/src/app/search/search.component.html | 2 +- client/src/app/search/search.component.ts | 13 ++-- client/src/app/shared/users/user.service.ts | 51 +++++++++++--- .../app/shared/video/abstract-video-list.html | 2 +- .../app/shared/video/abstract-video-list.ts | 69 ++++++++----------- client/src/app/shared/video/video.service.ts | 50 +++++++++----- .../+video-watch/video-watch.component.html | 8 +-- .../recent-videos-recommendation.service.ts | 58 +++++++++------- .../recommended-videos.component.html | 6 +- .../recommended-videos.component.ts | 28 +++++--- .../video-list/video-local.component.ts | 3 +- .../video-list/video-most-liked.component.ts | 3 +- .../video-list/video-overview.component.html | 6 +- .../video-list/video-overview.component.ts | 29 ++++---- .../video-recently-added.component.ts | 3 +- .../video-list/video-trending.component.ts | 3 +- 23 files changed, 232 insertions(+), 165 deletions(-) diff --git a/client/src/app/+accounts/account-video-channels/account-video-channels.component.html b/client/src/app/+accounts/account-video-channels/account-video-channels.component.html index 73bac5f1d..5dbb341d2 100644 --- a/client/src/app/+accounts/account-video-channels/account-video-channels.component.html +++ b/client/src/app/+accounts/account-video-channels/account-video-channels.component.html @@ -21,7 +21,7 @@ diff --git a/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts b/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts index 5572064c1..2e5c5aae2 100644 --- a/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts +++ b/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts @@ -1,17 +1,17 @@ +import { from, Subject, Subscription } from 'rxjs' +import { concatMap, map, switchMap, tap } from 'rxjs/operators' import { Component, OnDestroy, OnInit } from '@angular/core' -import { ActivatedRoute } from '@angular/router' +import { UserService } from '@app/shared' import { Account } from '@app/shared/account/account.model' import { AccountService } from '@app/shared/account/account.service' -import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' -import { concatMap, map, switchMap, tap } from 'rxjs/operators' -import { from, Subject, Subscription } from 'rxjs' -import { VideoChannel } from '@app/shared/video-channel/video-channel.model' -import { Video } from '@app/shared/video/video.model' -import { AuthService } from '@app/core' -import { VideoService } from '@app/shared/video/video.service' -import { VideoSortField } from '@app/shared/video/sort-field.type' -import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pagination.model' import { ScreenService } from '@app/shared/misc/screen.service' +import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pagination.model' +import { VideoChannel } from '@app/shared/video-channel/video-channel.model' +import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' +import { VideoSortField } from '@app/shared/video/sort-field.type' +import { Video } from '@app/shared/video/video.model' +import { VideoService } from '@app/shared/video/video.service' +import { User } from '@shared/models' @Component({ selector: 'my-account-video-channels', @@ -38,21 +38,18 @@ export class AccountVideoChannelsComponent implements OnInit, OnDestroy { onChannelDataSubject = new Subject() + userMiniature: User + private accountSub: Subscription constructor ( - private route: ActivatedRoute, - private authService: AuthService, private accountService: AccountService, private videoChannelService: VideoChannelService, private videoService: VideoService, - private screenService: ScreenService + private screenService: ScreenService, + private userService: UserService ) { } - get user () { - return this.authService.getUser() - } - ngOnInit () { // Parent get the account for us this.accountSub = this.accountService.accountLoaded @@ -61,6 +58,9 @@ export class AccountVideoChannelsComponent implements OnInit, OnDestroy { this.loadMoreChannels() }) + + this.userService.getAnonymousOrLoggedUser() + .subscribe(user => this.userMiniature = user) } ngOnDestroy () { diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.html b/client/src/app/+my-account/my-account-history/my-account-history.component.html index 6b94d5477..cfa5ca636 100644 --- a/client/src/app/+my-account/my-account-history/my-account-history.component.html +++ b/client/src/app/+my-account/my-account-history/my-account-history.component.html @@ -18,6 +18,7 @@
+ (videoRemoved)="removeVideoFromArray(video)" (videoBlocked)="removeVideoFromArray(video)" + >
diff --git a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts index 6df47d11c..5749701e8 100644 --- a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts +++ b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts @@ -77,7 +77,7 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On const newPagination = immutableAssign(this.pagination, { currentPage: page }) return this.videoService - .getVideoChannelVideos(this.videoChannel, newPagination, this.sort) + .getVideoChannelVideos(this.videoChannel, newPagination, this.sort, this.nsfwPolicy) .pipe( tap(({ total }) => { this.titlePage = this.i18n(`{total, plural, =1 {Published 1 video} other {Published {{total}} videos}}`, { total }) diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts index 5541f5558..c77dc97de 100644 --- a/client/src/app/app.component.ts +++ b/client/src/app/app.component.ts @@ -123,7 +123,6 @@ export class AppComponent implements OnInit, AfterViewInit { const scrollEvent = eventsObs.pipe(filter((e: Event): e is Scroll => e instanceof Scroll)) scrollEvent.subscribe(e => { - console.log(e) if (e.position) { return this.viewportScroller.scrollToPosition(e.position) } diff --git a/client/src/app/modal/quick-settings-modal.component.html b/client/src/app/modal/quick-settings-modal.component.html index e2ea51b92..188a51173 100644 --- a/client/src/app/modal/quick-settings-modal.component.html +++ b/client/src/app/modal/quick-settings-modal.component.html @@ -3,11 +3,15 @@ - + diff --git a/client/src/app/modal/quick-settings-modal.component.ts b/client/src/app/modal/quick-settings-modal.component.ts index 41d6c9f47..155794d1b 100644 --- a/client/src/app/modal/quick-settings-modal.component.ts +++ b/client/src/app/modal/quick-settings-modal.component.ts @@ -32,9 +32,11 @@ export class QuickSettingsModalComponent extends FormReactive implements OnInit ngOnInit () { this.user = this.userService.getAnonymousUser() - this.localStorageService.watch().subscribe( - () => this.user = this.userService.getAnonymousUser() - ) + this.localStorageService.watch() + .subscribe( + () => this.user = this.userService.getAnonymousUser() + ) + this.userInformationLoaded.next(true) this.authService.loginChangedSource diff --git a/client/src/app/search/search.component.html b/client/src/app/search/search.component.html index 6acdedf92..9bff024ad 100644 --- a/client/src/app/search/search.component.html +++ b/client/src/app/search/search.component.html @@ -53,7 +53,7 @@
diff --git a/client/src/app/search/search.component.ts b/client/src/app/search/search.component.ts index eea015c2e..bed5de79e 100644 --- a/client/src/app/search/search.component.ts +++ b/client/src/app/search/search.component.ts @@ -5,6 +5,7 @@ import { AuthService, Notifier, ServerService } from '@app/core' import { HooksService } from '@app/core/plugins/hooks.service' import { AdvancedSearch } from '@app/search/advanced-search.model' import { SearchService } from '@app/search/search.service' +import { UserService } from '@app/shared' import { immutableAssign } from '@app/shared/misc/utils' import { ComponentPagination } from '@app/shared/rest/component-pagination.model' import { VideoChannel } from '@app/shared/video-channel/video-channel.model' @@ -12,7 +13,7 @@ import { MiniatureDisplayOptions } from '@app/shared/video/video-miniature.compo import { Video } from '@app/shared/video/video.model' import { MetaService } from '@ngx-meta/core' import { I18n } from '@ngx-translate/i18n-polyfill' -import { ServerConfig } from '@shared/models' +import { ServerConfig, User } from '@shared/models' import { SearchTargetType } from '@shared/models/search/search-target-query.model' @Component({ @@ -46,6 +47,8 @@ export class SearchComponent implements OnInit, OnDestroy { errorMessage: string serverConfig: ServerConfig + userMiniature: User + private subActivatedRoute: Subscription private isInitialLoad = false // set to false to show the search filters on first arrival private firstSearch = true @@ -62,14 +65,11 @@ export class SearchComponent implements OnInit, OnDestroy { private notifier: Notifier, private searchService: SearchService, private authService: AuthService, + private userService: UserService, private hooks: HooksService, private serverService: ServerService ) { } - get user () { - return this.authService.getUser() - } - ngOnInit () { this.serverService.getConfig() .subscribe(config => this.serverConfig = config) @@ -103,6 +103,9 @@ export class SearchComponent implements OnInit, OnDestroy { err => this.notifier.error(err.text) ) + this.userService.getAnonymousOrLoggedUser() + .subscribe(user => this.userMiniature = user) + this.hooks.runAction('action:search.init', 'search') } diff --git a/client/src/app/shared/users/user.service.ts b/client/src/app/shared/users/user.service.ts index 7c1ae5799..de1c8ec94 100644 --- a/client/src/app/shared/users/user.service.ts +++ b/client/src/app/shared/users/user.service.ts @@ -1,19 +1,20 @@ -import { from, Observable } from 'rxjs' -import { catchError, concatMap, map, shareReplay, toArray } from 'rxjs/operators' +import { has } from 'lodash-es' +import { BytesPipe } from 'ngx-pipes' +import { SortMeta } from 'primeng/api' +import { from, Observable, of } from 'rxjs' +import { catchError, concatMap, first, map, shareReplay, toArray, throttleTime, filter } from 'rxjs/operators' import { HttpClient, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' -import { ResultList, User as UserServerModel, UserCreate, UserRole, UserUpdate, UserUpdateMe, UserVideoQuota } from '../../../../../shared' -import { environment } from '../../../environments/environment' -import { RestExtractor, RestPagination, RestService } from '../rest' -import { Avatar } from '../../../../../shared/models/avatars/avatar.model' -import { SortMeta } from 'primeng/api' -import { BytesPipe } from 'ngx-pipes' +import { AuthService } from '@app/core/auth' import { I18n } from '@ngx-translate/i18n-polyfill' import { UserRegister } from '@shared/models/users/user-register.model' -import { User } from './user.model' import { NSFWPolicyType } from '@shared/models/videos/nsfw-policy.type' -import { has } from 'lodash-es' +import { ResultList, User as UserServerModel, UserCreate, UserRole, UserUpdate, UserUpdateMe, UserVideoQuota } from '../../../../../shared' +import { Avatar } from '../../../../../shared/models/avatars/avatar.model' +import { environment } from '../../../environments/environment' import { LocalStorageService, SessionStorageService } from '../misc/storage.service' +import { RestExtractor, RestPagination, RestService } from '../rest' +import { User } from './user.model' @Injectable() export class UserService { @@ -25,6 +26,7 @@ export class UserService { constructor ( private authHttp: HttpClient, + private authService: AuthService, private restExtractor: RestExtractor, private restService: RestService, private localStorageService: LocalStorageService, @@ -94,6 +96,21 @@ export class UserService { } } + listenAnonymousUpdate () { + return this.localStorageService.watch([ + User.KEYS.NSFW_POLICY, + User.KEYS.WEBTORRENT_ENABLED, + User.KEYS.AUTO_PLAY_VIDEO, + User.KEYS.AUTO_PLAY_VIDEO_PLAYLIST, + User.KEYS.THEME, + User.KEYS.VIDEO_LANGUAGES + ]).pipe( + throttleTime(200), + filter(() => this.authService.isLoggedIn() !== true), + map(() => this.getAnonymousUser()) + ) + } + deleteMe () { const url = UserService.BASE_USERS_URL + 'me' @@ -241,7 +258,7 @@ export class UserService { } getAnonymousUser () { - let videoLanguages + let videoLanguages: string[] try { videoLanguages = JSON.parse(this.localStorageService.getItem(User.KEYS.VIDEO_LANGUAGES)) @@ -313,6 +330,18 @@ export class UserService { ) } + getAnonymousOrLoggedUser () { + if (!this.authService.isLoggedIn()) { + return of(this.getAnonymousUser()) + } + + return this.authService.userInformationLoaded + .pipe( + first(), + map(() => this.authService.getUser()) + ) + } + private formatUser (user: UserServerModel) { let videoQuota if (user.videoQuota === -1) { diff --git a/client/src/app/shared/video/abstract-video-list.html b/client/src/app/shared/video/abstract-video-list.html index 548370843..1e919ee72 100644 --- a/client/src/app/shared/video/abstract-video-list.html +++ b/client/src/app/shared/video/abstract-video-list.html @@ -38,7 +38,7 @@
diff --git a/client/src/app/shared/video/abstract-video-list.ts b/client/src/app/shared/video/abstract-video-list.ts index 76aa683fc..0bc339ff6 100644 --- a/client/src/app/shared/video/abstract-video-list.ts +++ b/client/src/app/shared/video/abstract-video-list.ts @@ -1,22 +1,23 @@ -import { debounceTime, first, tap, throttleTime } from 'rxjs/operators' +import { fromEvent, Observable, of, Subject, Subscription } from 'rxjs' +import { debounceTime, tap, throttleTime, switchMap } from 'rxjs/operators' import { OnDestroy, OnInit } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' -import { fromEvent, Observable, of, Subject, Subscription } from 'rxjs' -import { AuthService } from '../../core/auth' -import { ComponentPaginationLight } from '../rest/component-pagination.model' -import { VideoSortField } from './sort-field.type' -import { Video } from './video.model' -import { ScreenService } from '@app/shared/misc/screen.service' -import { MiniatureDisplayOptions, OwnerDisplayType } from '@app/shared/video/video-miniature.component' -import { Syndication } from '@app/shared/video/syndication.model' import { Notifier, ServerService } from '@app/core' import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook' +import { GlobalIconName } from '@app/shared/images/global-icon.component' +import { ScreenService } from '@app/shared/misc/screen.service' +import { Syndication } from '@app/shared/video/syndication.model' +import { MiniatureDisplayOptions, OwnerDisplayType } from '@app/shared/video/video-miniature.component' import { I18n } from '@ngx-translate/i18n-polyfill' import { isLastMonth, isLastWeek, isToday, isYesterday } from '@shared/core-utils/miscs/date' import { ServerConfig } from '@shared/models' -import { GlobalIconName } from '@app/shared/images/global-icon.component' -import { UserService, User } from '../users' +import { NSFWPolicyType } from '@shared/models/videos/nsfw-policy.type' +import { AuthService } from '../../core/auth' import { LocalStorageService } from '../misc/storage.service' +import { ComponentPaginationLight } from '../rest/component-pagination.model' +import { User, UserService } from '../users' +import { VideoSortField } from './sort-field.type' +import { Video } from './video.model' enum GroupDate { UNKNOWN = 0, @@ -34,14 +35,15 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor } sort: VideoSortField = '-publishedAt' - categoryOneOf?: number + categoryOneOf?: number[] languageOneOf?: string[] + nsfwPolicy?: NSFWPolicyType defaultSort: VideoSortField = '-publishedAt' syndicationItems: Syndication[] = [] loadOnInit = true - useUserVideoLanguagePreferences = false + useUserVideoPreferences = false ownerDisplayType: OwnerDisplayType = 'account' displayModerationBlock = false titleTooltip: string @@ -71,6 +73,8 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor onDataSubject = new Subject() + userMiniature: User + protected serverConfig: ServerConfig protected abstract notifier: Notifier @@ -96,10 +100,6 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor abstract generateSyndicationList (): void - get user () { - return this.authService.getUser() - } - ngOnInit () { this.serverConfig = this.serverService.getTmpConfig() this.serverService.getConfig() @@ -124,21 +124,17 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor this.calcPageSizes() - const loadUserObservable = this.loadUserVideoLanguagesIfNeeded() + const loadUserObservable = this.loadUserAndSettings() if (this.loadOnInit === true) { loadUserObservable.subscribe(() => this.loadMoreVideos()) } - this.storageService.watch([ - User.KEYS.NSFW_POLICY, - User.KEYS.VIDEO_LANGUAGES - ]).pipe(throttleTime(200)).subscribe( - () => { - this.loadUserVideoLanguagesIfNeeded() + this.userService.listenAnonymousUpdate() + .pipe(switchMap(() => this.loadUserAndSettings())) + .subscribe(() => { if (this.hasDoneFirstQuery) this.reloadVideos() - } - ) + }) // Display avatar in mobile view if (this.screenService.isInMobileView()) { @@ -298,20 +294,15 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor this.router.navigate([ path ], { queryParams, replaceUrl: true, queryParamsHandling: 'merge' }) } - private loadUserVideoLanguagesIfNeeded () { - if (!this.useUserVideoLanguagePreferences) { - return of(true) - } + private loadUserAndSettings () { + return this.userService.getAnonymousOrLoggedUser() + .pipe(tap(user => { + this.userMiniature = user - if (!this.authService.isLoggedIn()) { - this.languageOneOf = this.userService.getAnonymousUser().videoLanguages - return of(true) - } + if (!this.useUserVideoPreferences) return - return this.authService.userInformationLoaded - .pipe( - first(), - tap(() => this.languageOneOf = this.user.videoLanguages) - ) + this.languageOneOf = user.videoLanguages + this.nsfwPolicy = user.nsfwPolicy + })) } } diff --git a/client/src/app/shared/video/video.service.ts b/client/src/app/shared/video/video.service.ts index 3aaf14990..d66a1f809 100644 --- a/client/src/app/shared/video/video.service.ts +++ b/client/src/app/shared/video/video.service.ts @@ -39,8 +39,9 @@ export interface VideosProvider { videoPagination: ComponentPaginationLight, sort: VideoSortField, filter?: VideoFilter, - categoryOneOf?: number, + categoryOneOf?: number[], languageOneOf?: string[] + nsfwPolicy: NSFWPolicyType }): Observable> } @@ -161,13 +162,18 @@ export class VideoService implements VideosProvider { getVideoChannelVideos ( videoChannel: VideoChannel, videoPagination: ComponentPaginationLight, - sort: VideoSortField + sort: VideoSortField, + nsfwPolicy?: NSFWPolicyType ): Observable> { const pagination = this.restService.componentPaginationToRestPagination(videoPagination) let params = new HttpParams() params = this.restService.addRestGetParams(params, pagination, sort) + if (nsfwPolicy) { + params = params.set('nsfw', this.nsfwPolicyToParam(nsfwPolicy)) + } + return this.authHttp .get>(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.nameWithHost + '/videos', { params }) .pipe( @@ -201,12 +207,12 @@ export class VideoService implements VideosProvider { videoPagination: ComponentPaginationLight, sort: VideoSortField, filter?: VideoFilter, - categoryOneOf?: number, + categoryOneOf?: number[], languageOneOf?: string[], skipCount?: boolean, - nsfw?: boolean + nsfwPolicy?: NSFWPolicyType }): Observable> { - const { videoPagination, sort, filter, categoryOneOf, languageOneOf, skipCount, nsfw } = parameters + const { videoPagination, sort, filter, categoryOneOf, languageOneOf, skipCount, nsfwPolicy } = parameters const pagination = this.restService.componentPaginationToRestPagination(videoPagination) @@ -214,16 +220,10 @@ export class VideoService implements VideosProvider { params = this.restService.addRestGetParams(params, pagination, sort) if (filter) params = params.set('filter', filter) - if (categoryOneOf) params = params.set('categoryOneOf', categoryOneOf + '') if (skipCount) params = params.set('skipCount', skipCount + '') - if (nsfw) { - params = params.set('nsfw', nsfw + '') - } else { - const nsfwPolicy = this.authService.isLoggedIn() - ? this.authService.getUser().nsfwPolicy - : this.userService.getAnonymousUser().nsfwPolicy - if (this.nsfwPolicyToFilter(nsfwPolicy)) params.set('nsfw', 'false') + if (nsfwPolicy) { + params = params.set('nsfw', this.nsfwPolicyToParam(nsfwPolicy)) } if (languageOneOf) { @@ -232,6 +232,12 @@ export class VideoService implements VideosProvider { } } + if (categoryOneOf) { + for (const c of categoryOneOf) { + params = params.append('categoryOneOf[]', c + '') + } + } + return this.authHttp .get>(VideoService.BASE_VIDEO_URL, { params }) .pipe( @@ -268,12 +274,16 @@ export class VideoService implements VideosProvider { return feeds } - getVideoFeedUrls (sort: VideoSortField, filter?: VideoFilter, categoryOneOf?: number) { + getVideoFeedUrls (sort: VideoSortField, filter?: VideoFilter, categoryOneOf?: number[]) { let params = this.restService.addRestGetParams(new HttpParams(), undefined, sort) if (filter) params = params.set('filter', filter) - if (categoryOneOf) params = params.set('categoryOneOf', categoryOneOf + '') + if (categoryOneOf) { + for (const c of categoryOneOf) { + params = params.append('categoryOneOf[]', c + '') + } + } return this.buildBaseFeedUrls(params) } @@ -377,6 +387,12 @@ export class VideoService implements VideosProvider { return base.filter(o => !!privacies.find(p => p.id === o.id)) } + nsfwPolicyToParam (nsfwPolicy: NSFWPolicyType) { + return nsfwPolicy === 'do_not_list' + ? 'false' + : 'both' + } + private setVideoRate (id: number, rateType: UserVideoRateType) { const url = VideoService.BASE_VIDEO_URL + id + '/rate' const body: UserVideoRateUpdate = { @@ -390,8 +406,4 @@ export class VideoService implements VideosProvider { catchError(err => this.restExtractor.handleError(err)) ) } - - private nsfwPolicyToFilter (policy: NSFWPolicyType) { - return policy === 'do_not_list' - } } 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 589aba603..89e696fe9 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.html +++ b/client/src/app/videos/+video-watch/video-watch.component.html @@ -248,10 +248,10 @@
diff --git a/client/src/app/videos/recommendations/recent-videos-recommendation.service.ts b/client/src/app/videos/recommendations/recent-videos-recommendation.service.ts index f06c35f9a..0abf938b7 100644 --- a/client/src/app/videos/recommendations/recent-videos-recommendation.service.ts +++ b/client/src/app/videos/recommendations/recent-videos-recommendation.service.ts @@ -1,15 +1,15 @@ -import { Injectable, OnInit } from '@angular/core' -import { RecommendationService } from '@app/videos/recommendations/recommendations.service' -import { Video } from '@app/shared/video/video.model' -import { RecommendationInfo } from '@app/shared/video/recommendation-info.model' -import { VideoService } from '@app/shared/video/video.service' -import { map, switchMap } from 'rxjs/operators' import { Observable, of } from 'rxjs' -import { SearchService } from '@app/search/search.service' -import { AdvancedSearch } from '@app/search/advanced-search.model' +import { map, switchMap } from 'rxjs/operators' +import { Injectable } from '@angular/core' import { ServerService } from '@app/core' +import { AdvancedSearch } from '@app/search/advanced-search.model' +import { SearchService } from '@app/search/search.service' +import { UserService } from '@app/shared' +import { RecommendationInfo } from '@app/shared/video/recommendation-info.model' +import { Video } from '@app/shared/video/video.model' +import { VideoService } from '@app/shared/video/video.service' +import { RecommendationService } from '@app/videos/recommendations/recommendations.service' import { ServerConfig } from '@shared/models' -import { truncate } from 'lodash' /** * Provides "recommendations" by providing the most recently uploaded videos. @@ -23,13 +23,14 @@ export class RecentVideosRecommendationService implements RecommendationService constructor ( private videos: VideoService, private searchService: SearchService, + private userService: UserService, private serverService: ServerService ) { this.config = this.serverService.getTmpConfig() this.serverService.getConfig() .subscribe(config => this.config = config) - } + } getRecommendations (recommendation: RecommendationInfo): Observable { return this.fetchPage(1, recommendation) @@ -55,20 +56,29 @@ export class RecentVideosRecommendationService implements RecommendationService return defaultSubscription } - const params = { - search: '', - componentPagination: pagination, - advancedSearch: new AdvancedSearch({ tagsOneOf: recommendation.tags.join(','), sort: '-createdAt', searchTarget: 'local' }) - } + return this.userService.getAnonymousOrLoggedUser() + .pipe( + map(user => { + return { + search: '', + componentPagination: pagination, + advancedSearch: new AdvancedSearch({ + tagsOneOf: recommendation.tags.join(','), + sort: '-createdAt', + searchTarget: 'local', + nsfw: user.nsfwPolicy + ? this.videos.nsfwPolicyToParam(user.nsfwPolicy) + : undefined + }) + } + }), + switchMap(params => this.searchService.searchVideos(params)), + map(v => v.data), + switchMap(videos => { + if (videos.length <= 1) return defaultSubscription - return this.searchService.searchVideos(params) - .pipe( - map(v => v.data), - switchMap(videos => { - if (videos.length <= 1) return defaultSubscription - - return of(videos) - }) - ) + return of(videos) + }) + ) } } diff --git a/client/src/app/videos/recommendations/recommended-videos.component.html b/client/src/app/videos/recommendations/recommended-videos.component.html index 17e19c083..0467cabf5 100644 --- a/client/src/app/videos/recommendations/recommended-videos.component.html +++ b/client/src/app/videos/recommendations/recommended-videos.component.html @@ -13,11 +13,11 @@ - - +
diff --git a/client/src/app/videos/recommendations/recommended-videos.component.ts b/client/src/app/videos/recommendations/recommended-videos.component.ts index d4a5df19a..a6f3bce3d 100644 --- a/client/src/app/videos/recommendations/recommended-videos.component.ts +++ b/client/src/app/videos/recommendations/recommended-videos.component.ts @@ -1,24 +1,23 @@ -import { Component, Input, Output, OnChanges, EventEmitter } from '@angular/core' import { Observable } from 'rxjs' -import { Video } from '@app/shared/video/video.model' +import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core' +import { AuthService, Notifier } from '@app/core' +import { User } from '@app/shared' +import { SessionStorageService } from '@app/shared/misc/storage.service' +import { UserService } from '@app/shared/users/user.service' import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' import { RecommendationInfo } from '@app/shared/video/recommendation-info.model' -import { RecommendedVideosStore } from '@app/videos/recommendations/recommended-videos.store' -import { User } from '@app/shared' -import { AuthService, Notifier } from '@app/core' -import { UserService } from '@app/shared/users/user.service' -import { I18n } from '@ngx-translate/i18n-polyfill' -import { SessionStorageService } from '@app/shared/misc/storage.service' import { MiniatureDisplayOptions } from '@app/shared/video/video-miniature.component' +import { Video } from '@app/shared/video/video.model' +import { RecommendedVideosStore } from '@app/videos/recommendations/recommended-videos.store' +import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-recommended-videos', templateUrl: './recommended-videos.component.html', styleUrls: [ './recommended-videos.component.scss' ] }) -export class RecommendedVideosComponent implements OnChanges { +export class RecommendedVideosComponent implements OnInit, OnChanges { @Input() inputRecommendation: RecommendationInfo - @Input() user: User @Input() playlist: VideoPlaylist @Output() gotRecommendations = new EventEmitter() @@ -32,6 +31,8 @@ export class RecommendedVideosComponent implements OnChanges { avatar: true } + userMiniature: User + readonly hasVideos$: Observable readonly videos$: Observable @@ -59,7 +60,12 @@ export class RecommendedVideosComponent implements OnChanges { this.autoPlayNextVideoTooltip = this.i18n('When active, the next video is automatically played after the current one.') } - public ngOnChanges (): void { + ngOnInit () { + this.userService.getAnonymousOrLoggedUser() + .subscribe(user => this.userMiniature = user) + } + + ngOnChanges () { if (this.inputRecommendation) { this.store.requestNewRecommendations(this.inputRecommendation) } diff --git a/client/src/app/videos/video-list/video-local.component.ts b/client/src/app/videos/video-list/video-local.component.ts index 757b0e498..960523cd7 100644 --- a/client/src/app/videos/video-list/video-local.component.ts +++ b/client/src/app/videos/video-list/video-local.component.ts @@ -24,7 +24,7 @@ export class VideoLocalComponent extends AbstractVideoList implements OnInit, On sort = '-publishedAt' as VideoSortField filter: VideoFilter = 'local' - useUserVideoLanguagePreferences = true + useUserVideoPreferences = true constructor ( protected i18n: I18n, @@ -67,6 +67,7 @@ export class VideoLocalComponent extends AbstractVideoList implements OnInit, On filter: this.filter, categoryOneOf: this.categoryOneOf, languageOneOf: this.languageOneOf, + nsfwPolicy: this.nsfwPolicy, skipCount: true } diff --git a/client/src/app/videos/video-list/video-most-liked.component.ts b/client/src/app/videos/video-list/video-most-liked.component.ts index b69fad05f..cc91a2330 100644 --- a/client/src/app/videos/video-list/video-most-liked.component.ts +++ b/client/src/app/videos/video-list/video-most-liked.component.ts @@ -21,7 +21,7 @@ export class VideoMostLikedComponent extends AbstractVideoList implements OnInit titlePage: string defaultSort: VideoSortField = '-likes' - useUserVideoLanguagePreferences = true + useUserVideoPreferences = true constructor ( protected i18n: I18n, @@ -55,6 +55,7 @@ export class VideoMostLikedComponent extends AbstractVideoList implements OnInit sort: this.sort, categoryOneOf: this.categoryOneOf, languageOneOf: this.languageOneOf, + nsfwPolicy: this.nsfwPolicy, skipCount: true } diff --git a/client/src/app/videos/video-list/video-overview.component.html b/client/src/app/videos/video-list/video-overview.component.html index 19d03b5c5..6de2fc292 100644 --- a/client/src/app/videos/video-list/video-overview.component.html +++ b/client/src/app/videos/video-list/video-overview.component.html @@ -14,7 +14,7 @@
- +
@@ -25,7 +25,7 @@
- +
@@ -40,7 +40,7 @@
- +
diff --git a/client/src/app/videos/video-list/video-overview.component.ts b/client/src/app/videos/video-list/video-overview.component.ts index 101073949..8ff8400db 100644 --- a/client/src/app/videos/video-list/video-overview.component.ts +++ b/client/src/app/videos/video-list/video-overview.component.ts @@ -1,11 +1,11 @@ -import { Component, OnInit } from '@angular/core' -import { AuthService, Notifier } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' -import { VideosOverview } from '@app/shared/overview/videos-overview.model' -import { OverviewService } from '@app/shared/overview' -import { Video } from '@app/shared/video/video.model' -import { ScreenService } from '@app/shared/misc/screen.service' import { Subject } from 'rxjs' +import { Component, OnInit } from '@angular/core' +import { Notifier } from '@app/core' +import { User, UserService } from '@app/shared' +import { ScreenService } from '@app/shared/misc/screen.service' +import { OverviewService } from '@app/shared/overview' +import { VideosOverview } from '@app/shared/overview/videos-overview.model' +import { Video } from '@app/shared/video/video.model' @Component({ selector: 'my-video-overview', @@ -18,6 +18,8 @@ export class VideoOverviewComponent implements OnInit { overviews: VideosOverview[] = [] notResults = false + userMiniature: User + private loaded = false private currentPage = 1 private maxPage = 20 @@ -25,19 +27,20 @@ export class VideoOverviewComponent implements OnInit { private isLoading = false constructor ( - private i18n: I18n, private notifier: Notifier, - private authService: AuthService, + private userService: UserService, private overviewService: OverviewService, private screenService: ScreenService ) { } - get user () { - return this.authService.getUser() - } - ngOnInit () { this.loadMoreResults() + + this.userService.getAnonymousOrLoggedUser() + .subscribe(user => this.userMiniature = user) + + this.userService.listenAnonymousUpdate() + .subscribe(user => this.userMiniature = user) } buildVideoChannelBy (object: { videos: Video[] }) { diff --git a/client/src/app/videos/video-list/video-recently-added.component.ts b/client/src/app/videos/video-list/video-recently-added.component.ts index c1ddd4fd4..9f57a61e3 100644 --- a/client/src/app/videos/video-list/video-recently-added.component.ts +++ b/client/src/app/videos/video-list/video-recently-added.component.ts @@ -22,7 +22,7 @@ export class VideoRecentlyAddedComponent extends AbstractVideoList implements On sort: VideoSortField = '-publishedAt' groupByDate = true - useUserVideoLanguagePreferences = true + useUserVideoPreferences = true constructor ( protected i18n: I18n, @@ -59,6 +59,7 @@ export class VideoRecentlyAddedComponent extends AbstractVideoList implements On sort: this.sort, categoryOneOf: this.categoryOneOf, languageOneOf: this.languageOneOf, + nsfwPolicy: this.nsfwPolicy, skipCount: true } diff --git a/client/src/app/videos/video-list/video-trending.component.ts b/client/src/app/videos/video-list/video-trending.component.ts index fbe052277..62e0f4e69 100644 --- a/client/src/app/videos/video-list/video-trending.component.ts +++ b/client/src/app/videos/video-list/video-trending.component.ts @@ -21,7 +21,7 @@ export class VideoTrendingComponent extends AbstractVideoList implements OnInit, titlePage: string defaultSort: VideoSortField = '-trending' - useUserVideoLanguagePreferences = true + useUserVideoPreferences = true constructor ( protected i18n: I18n, @@ -72,6 +72,7 @@ export class VideoTrendingComponent extends AbstractVideoList implements OnInit, sort: this.sort, categoryOneOf: this.categoryOneOf, languageOneOf: this.languageOneOf, + nsfwPolicy: this.nsfwPolicy, skipCount: true }