X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=client%2Fsrc%2Fapp%2Fcore%2Fserver%2Fserver.service.ts;h=bc76bacfcf46f4073b9be9eec755ed9cefe2b1e1;hb=c6c0fa6cd8fe8f752463d8982c3dbcd448739c4e;hp=206ec7bcd9ec446414272e1f5e3147ed5eaed79f;hpb=0bd78bf30b2ae159791bdc90d17ed18e0327f621;p=github%2FChocobozzz%2FPeerTube.git diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts index 206ec7bcd..bc76bacfc 100644 --- a/client/src/app/core/server/server.service.ts +++ b/client/src/app/core/server/server.service.ts @@ -1,41 +1,85 @@ +import { Observable, of, Subject } from 'rxjs' +import { first, map, share, shareReplay, switchMap, tap } from 'rxjs/operators' import { HttpClient } from '@angular/common/http' -import { Injectable } from '@angular/core' -import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' -import 'rxjs/add/operator/do' -import { ReplaySubject } from 'rxjs/ReplaySubject' -import { ServerConfig } from '../../../../../shared' -import { About } from '../../../../../shared/models/server/about.model' +import { Inject, Injectable, LOCALE_ID } from '@angular/core' +import { getDevLocale, isOnDevLocale, sortBy } from '@app/helpers' +import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage' +import { getCompleteLocale, isDefaultLocale, peertubeTranslate } from '@shared/core-utils/i18n' +import { SearchTargetType, ServerConfig, ServerStats, VideoConstant } from '@shared/models' import { environment } from '../../../environments/environment' @Injectable() export class ServerService { private static BASE_CONFIG_URL = environment.apiUrl + '/api/v1/config/' private static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/' + private static BASE_VIDEO_PLAYLIST_URL = environment.apiUrl + '/api/v1/video-playlists/' + private static BASE_LOCALE_URL = environment.apiUrl + '/client/locales/' + private static BASE_STATS_URL = environment.apiUrl + '/api/v1/server/stats' + private static CONFIG_LOCAL_STORAGE_KEY = 'server-config' - configLoaded = new ReplaySubject(1) - videoPrivaciesLoaded = new ReplaySubject(1) - videoCategoriesLoaded = new ReplaySubject(1) - videoLicencesLoaded = new ReplaySubject(1) - videoLanguagesLoaded = new ReplaySubject(1) + configReloaded = new Subject() + + private localeObservable: Observable + private videoLicensesObservable: Observable[]> + private videoCategoriesObservable: Observable[]> + private videoPrivaciesObservable: Observable[]> + private videoPlaylistPrivaciesObservable: Observable[]> + private videoLanguagesObservable: Observable[]> + private configObservable: Observable + + private configReset = false + private configLoaded = false private config: ServerConfig = { instance: { name: 'PeerTube', shortDescription: 'PeerTube, a federated (ActivityPub) video streaming platform ' + 'using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.', defaultClientRoute: '', + isNSFW: false, + defaultNSFWPolicy: 'do_not_list' as 'do_not_list', customizations: { javascript: '', css: '' } }, + plugin: { + registered: [], + registeredExternalAuths: [], + registeredIdAndPassAuths: [] + }, + theme: { + registered: [], + default: 'default' + }, + email: { + enabled: false + }, + contactForm: { + enabled: false + }, serverVersion: 'Unknown', signup: { - allowed: false + allowed: false, + allowedForCurrentIP: false, + requiresEmailVerification: false }, transcoding: { - enabledResolutions: [] + enabledResolutions: [], + hls: { + enabled: false + }, + webtorrent: { + enabled: true + } + }, + live: { + enabled: false, + transcoding: { + enabled: false, + enabledResolutions: [] + } }, avatar: { file: { @@ -51,93 +95,231 @@ export class ServerService { file: { extensions: [] } + }, + videoCaption: { + file: { + size: { max: 0 }, + extensions: [] + } + }, + user: { + videoQuota: -1, + videoQuotaDaily: -1 + }, + import: { + videos: { + http: { + enabled: false + }, + torrent: { + enabled: false + } + } + }, + trending: { + videos: { + intervalDays: 0 + } + }, + autoBlacklist: { + videos: { + ofUsers: { + enabled: false + } + } + }, + tracker: { + enabled: true + }, + followings: { + instance: { + autoFollowIndex: { + indexUrl: 'https://instances.joinpeertube.org' + } + } + }, + broadcastMessage: { + enabled: false, + message: '', + level: 'info', + dismissable: false + }, + search: { + remoteUri: { + users: true, + anonymous: false + }, + searchIndex: { + enabled: false, + url: '', + disableLocalSearch: false, + isDefaultSearch: false + } } } - private videoCategories: Array<{ id: number, label: string }> = [] - private videoLicences: Array<{ id: number, label: string }> = [] - private videoLanguages: Array<{ id: number, label: string }> = [] - private videoPrivacies: Array<{ id: number, label: string }> = [] - constructor (private http: HttpClient) { + constructor ( + private http: HttpClient, + @Inject(LOCALE_ID) private localeId: string + ) { this.loadConfigLocally() } - loadConfig () { - this.http.get(ServerService.BASE_CONFIG_URL) - .do(this.saveConfigLocally) - .subscribe(data => { - this.config = data + getServerVersionAndCommit () { + const serverVersion = this.config.serverVersion + const commit = this.config.serverCommit || '' - this.configLoaded.next(true) - }) - } + let result = serverVersion + if (commit) result += '...' + commit - loadVideoCategories () { - return this.loadVideoAttributeEnum('categories', this.videoCategories, this.videoCategoriesLoaded, true) + return result } - loadVideoLicences () { - return this.loadVideoAttributeEnum('licences', this.videoLicences, this.videoLicencesLoaded) - } + resetConfig () { + this.configLoaded = false + this.configReset = true - loadVideoLanguages () { - return this.loadVideoAttributeEnum('languages', this.videoLanguages, this.videoLanguagesLoaded, true) + // Notify config update + this.getConfig().subscribe(() => { + // empty, to fire a reset config event + }) } - loadVideoPrivacies () { - return this.loadVideoAttributeEnum('privacies', this.videoPrivacies, this.videoPrivaciesLoaded) + getConfig () { + if (this.configLoaded) return of(this.config) + + if (!this.configObservable) { + this.configObservable = this.http.get(ServerService.BASE_CONFIG_URL) + .pipe( + tap(config => this.saveConfigLocally(config)), + tap(config => { + this.config = config + this.configLoaded = true + }), + tap(config => { + if (this.configReset) { + this.configReloaded.next(config) + this.configReset = false + } + }), + share() + ) + } + + return this.configObservable } - getConfig () { + getTmpConfig () { return this.config } getVideoCategories () { - return this.videoCategories + if (!this.videoCategoriesObservable) { + this.videoCategoriesObservable = this.loadAttributeEnum(ServerService.BASE_VIDEO_URL, 'categories', true) + } + + return this.videoCategoriesObservable.pipe(first()) } getVideoLicences () { - return this.videoLicences + if (!this.videoLicensesObservable) { + this.videoLicensesObservable = this.loadAttributeEnum(ServerService.BASE_VIDEO_URL, 'licences') + } + + return this.videoLicensesObservable.pipe(first()) } getVideoLanguages () { - return this.videoLanguages + if (!this.videoLanguagesObservable) { + this.videoLanguagesObservable = this.loadAttributeEnum(ServerService.BASE_VIDEO_URL, 'languages', true) + } + + return this.videoLanguagesObservable.pipe(first()) } getVideoPrivacies () { - return this.videoPrivacies + if (!this.videoPrivaciesObservable) { + this.videoPrivaciesObservable = this.loadAttributeEnum(ServerService.BASE_VIDEO_URL, 'privacies') + } + + return this.videoPrivaciesObservable.pipe(first()) } - getAbout () { - return this.http.get(ServerService.BASE_CONFIG_URL + '/about') + getVideoPlaylistPrivacies () { + if (!this.videoPlaylistPrivaciesObservable) { + this.videoPlaylistPrivaciesObservable = this.loadAttributeEnum(ServerService.BASE_VIDEO_PLAYLIST_URL, 'privacies') + } + + return this.videoPlaylistPrivaciesObservable.pipe(first()) } - private loadVideoAttributeEnum ( + getServerLocale () { + if (!this.localeObservable) { + const completeLocale = isOnDevLocale() ? getDevLocale() : getCompleteLocale(this.localeId) + + // Default locale, nothing to translate + if (isDefaultLocale(completeLocale)) { + this.localeObservable = of({}).pipe(shareReplay()) + } else { + this.localeObservable = this.http + .get(ServerService.BASE_LOCALE_URL + completeLocale + '/server.json') + .pipe(shareReplay()) + } + } + + return this.localeObservable.pipe(first()) + } + + getServerStats () { + return this.http.get(ServerService.BASE_STATS_URL) + } + + getDefaultSearchTarget (): Promise { + return this.getConfig().pipe( + map(config => { + const searchIndexConfig = config.search.searchIndex + + if (searchIndexConfig.enabled && (searchIndexConfig.isDefaultSearch || searchIndexConfig.disableLocalSearch)) { + return 'search-index' + } + + return 'local' + }) + ).toPromise() + } + + private loadAttributeEnum ( + baseUrl: string, attributeName: 'categories' | 'licences' | 'languages' | 'privacies', - hashToPopulate: { id: number, label: string }[], - notifier: ReplaySubject, sort = false ) { - return this.http.get(ServerService.BASE_VIDEO_URL + attributeName) - .subscribe(data => { - Object.keys(data) - .forEach(dataKey => { - hashToPopulate.push({ - id: parseInt(dataKey, 10), - label: data[dataKey] - }) - }) - - if (sort === true) { - hashToPopulate.sort((a, b) => { - if (a.label < b.label) return -1 - if (a.label === b.label) return 0 - return 1 - }) - } - - notifier.next(true) - }) + return this.getServerLocale() + .pipe( + switchMap(translations => { + return this.http.get<{ [ id: string ]: string }>(baseUrl + attributeName) + .pipe(map(data => ({ data, translations }))) + }), + map(({ data, translations }) => { + const hashToPopulate: VideoConstant[] = 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') + + return hashToPopulate + }), + shareReplay() + ) } private saveConfigLocally (config: ServerConfig) {