.pipe(map(data => ({ data, translations })))
}),
map(({ data, translations }) => {
- const hashToPopulate: VideoConstant<T>[] = []
-
- Object.keys(data)
- .forEach(dataKey => {
- const label = data[ dataKey ]
-
- hashToPopulate.push({
- id: (attributeName === 'languages' ? dataKey : parseInt(dataKey, 10)) as T,
- label: peertubeTranslate(label, translations)
- })
- })
+ const hashToPopulate: VideoConstant<T>[] = Object.keys(data)
+ .map(dataKey => {
+ const label = data[ dataKey ]
+
+ const id = attributeName === 'languages'
+ ? dataKey as T
+ : parseInt(dataKey, 10) as T
+
+ return {
+ id,
+ label: peertubeTranslate(label, translations)
+ }
+ })
if (sort === true) sortBy(hashToPopulate, 'label')
getCurrentLanguage () {
const english = 'English'
const locale = isOnDevLocale() ? getDevLocale() : getCompleteLocale(this.localeId)
+
if (locale) return I18N_LOCALES[locale] || english
return english
}
userHasAdminAccess = false
helpVisible = false
- languages: VideoConstant<string>[] = []
+ videoLanguages: string[] = []
+
+ private languages: VideoConstant<string>[] = []
private serverConfig: ServerConfig
private routesPerRight: { [ role in UserRight ]?: string } = {
[UserRight.MANAGE_USERS]: '/admin/users',
}
)
- this.hotkeysService.cheatSheetToggle.subscribe(isOpen => this.helpVisible = isOpen)
+ this.hotkeysService.cheatSheetToggle
+ .subscribe(isOpen => this.helpVisible = isOpen)
+
+ this.serverService.getVideoLanguages()
+ .subscribe(languages => {
+ this.languages = languages
- this.serverService.getVideoLanguages().subscribe(languages => this.languages = languages)
+ this.authService.userInformationLoaded
+ .subscribe(() => this.buildUserLanguages())
+ })
}
get language () {
return this.languageChooserModal.getCurrentLanguage()
}
- get videoLanguages (): string[] {
- if (!this.user) return
- if (!this.user.videoLanguages) return [this.i18n('any language')]
- return this.user.videoLanguages
- .map(locale => this.langForLocale(locale))
- .map(value => value === undefined ? '?' : value)
- }
-
get nsfwPolicy () {
if (!this.user) return
+
switch (this.user.nsfwPolicy) {
case 'do_not_list':
return this.i18n('hide')
+
case 'blur':
return this.i18n('blur')
+
case 'display':
return this.i18n('display')
}
toggleUseP2P () {
if (!this.user) return
this.user.webTorrentEnabled = !this.user.webTorrentEnabled
- this.userService.updateMyProfile({
- webTorrentEnabled: this.user.webTorrentEnabled
- }).subscribe(() => this.authService.refreshUserInformation())
+
+ this.userService.updateMyProfile({ webTorrentEnabled: this.user.webTorrentEnabled })
+ .subscribe(() => this.authService.refreshUserInformation())
}
langForLocale (localeId: string) {
- return this.languages.find(lang => lang.id = localeId).label
+ return this.languages.find(lang => lang.id === localeId).label
+ }
+
+ private buildUserLanguages () {
+ if (!this.user) {
+ this.videoLanguages = []
+ return
+ }
+
+ if (!this.user.videoLanguages) {
+ this.videoLanguages = [ this.i18n('any language') ]
+ return
+ }
+
+ this.videoLanguages = this.user.videoLanguages
+ .map(locale => this.langForLocale(locale))
+ .map(value => value === undefined ? '?' : value)
}
private computeIsUserHasAdminAccess () {
import { catchError, map, switchMap, tap } from 'rxjs/operators'
-import { HttpClient } from '@angular/common/http'
+import { HttpClient, HttpParams } from '@angular/common/http'
import { Injectable } from '@angular/core'
import { forkJoin, Observable, of } from 'rxjs'
import { VideosOverview as VideosOverviewServer, peertubeTranslate } from '../../../../../shared/models'
private serverService: ServerService
) {}
- getVideosOverview (): Observable<VideosOverview> {
+ getVideosOverview (page: number): Observable<VideosOverview> {
+ let params = new HttpParams()
+ params = params.append('page', page + '')
+
return this.authHttp
- .get<VideosOverviewServer>(OverviewService.BASE_OVERVIEW_URL + 'videos')
+ .get<VideosOverviewServer>(OverviewService.BASE_OVERVIEW_URL + 'videos', { params })
.pipe(
switchMap(serverVideosOverview => this.updateVideosOverview(serverVideosOverview)),
catchError(err => this.restExtractor.handleError(err))
<div class="no-results" i18n *ngIf="notResults">No results.</div>
- <div class="section" *ngFor="let object of overview.categories">
- <div class="section-title">
- <a routerLink="/search" [queryParams]="{ categoryOneOf: [ object.category.id ] }">{{ object.category.label }}</a>
- </div>
+ <div
+ myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" [dataObservable]="onDataSubject.asObservable()"
+ >
+ <ng-container *ngFor="let overview of overviews">
- <my-video-miniature *ngFor="let video of buildVideos(object.videos)" [video]="video" [user]="user" [displayVideoActions]="false">
- </my-video-miniature>
- </div>
+ <div class="section" *ngFor="let object of overview.categories">
+ <div class="section-title">
+ <a routerLink="/search" [queryParams]="{ categoryOneOf: [ object.category.id ] }">{{ object.category.label }}</a>
+ </div>
- <div class="section" *ngFor="let object of overview.tags">
- <div class="section-title">
- <a routerLink="/search" [queryParams]="{ tagsOneOf: [ object.tag ] }">#{{ object.tag }}</a>
- </div>
+ <my-video-miniature *ngFor="let video of buildVideos(object.videos)" [video]="video" [user]="user" [displayVideoActions]="false">
+ </my-video-miniature>
+ </div>
- <my-video-miniature *ngFor="let video of buildVideos(object.videos)" [video]="video" [user]="user" [displayVideoActions]="false">
- </my-video-miniature>
- </div>
+ <div class="section" *ngFor="let object of overview.tags">
+ <div class="section-title">
+ <a routerLink="/search" [queryParams]="{ tagsOneOf: [ object.tag ] }">#{{ object.tag }}</a>
+ </div>
+
+ <my-video-miniature *ngFor="let video of buildVideos(object.videos)" [video]="video" [user]="user" [displayVideoActions]="false">
+ </my-video-miniature>
+ </div>
+
+ <div class="section channel" *ngFor="let object of overview.channels">
+ <div class="section-title">
+ <a [routerLink]="[ '/video-channels', buildVideoChannelBy(object) ]">
+ <img [src]="buildVideoChannelAvatarUrl(object)" alt="Avatar" />
+
+ <div>{{ object.channel.displayName }}</div>
+ </a>
+ </div>
- <div class="section channel" *ngFor="let object of overview.channels">
- <div class="section-title">
- <a [routerLink]="[ '/video-channels', buildVideoChannelBy(object) ]">
- <img [src]="buildVideoChannelAvatarUrl(object)" alt="Avatar" />
+ <my-video-miniature *ngFor="let video of buildVideos(object.videos)" [video]="video" [user]="user" [displayVideoActions]="false">
+ </my-video-miniature>
+ </div>
- <div>{{ object.channel.displayName }}</div>
- </a>
- </div>
+ </ng-container>
- <my-video-miniature *ngFor="let video of buildVideos(object.videos)" [video]="video" [user]="user" [displayVideoActions]="false">
- </my-video-miniature>
</div>
</div>
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'
@Component({
selector: 'my-video-overview',
styleUrls: [ './video-overview.component.scss' ]
})
export class VideoOverviewComponent implements OnInit {
- overview: VideosOverview = {
- categories: [],
- channels: [],
- tags: []
- }
+ onDataSubject = new Subject<any>()
+
+ overviews: VideosOverview[] = []
notResults = false
+ private loaded = false
+ private currentPage = 1
+ private maxPage = 20
+ private lastWasEmpty = false
+ private isLoading = false
+
constructor (
private i18n: I18n,
private notifier: Notifier,
}
ngOnInit () {
- this.overviewService.getVideosOverview()
- .subscribe(
- overview => {
- this.overview = overview
-
- if (
- this.overview.categories.length === 0 &&
- this.overview.channels.length === 0 &&
- this.overview.tags.length === 0
- ) this.notResults = true
- },
-
- err => this.notifier.error(err.message)
- )
+ this.loadMoreResults()
}
buildVideoChannelBy (object: { videos: Video[] }) {
return videos.slice(0, numberOfVideos * 2)
}
+
+ onNearOfBottom () {
+ if (this.currentPage >= this.maxPage) return
+ if (this.lastWasEmpty) return
+ if (this.isLoading) return
+
+ this.currentPage++
+ this.loadMoreResults()
+ }
+
+ private loadMoreResults () {
+ this.isLoading = true
+
+ this.overviewService.getVideosOverview(this.currentPage)
+ .subscribe(
+ overview => {
+ this.isLoading = false
+
+ if (overview.tags.length === 0 && overview.channels.length === 0 && overview.categories.length === 0) {
+ this.lastWasEmpty = true
+ if (this.loaded === false) this.notResults = true
+
+ return
+ }
+
+ this.loaded = true
+ this.onDataSubject.next(overview)
+
+ this.overviews.push(overview)
+ },
+
+ err => {
+ this.notifier.error(err.message)
+ this.isLoading = false
+ }
+ )
+ }
}