</div>
</div>
+ <div class="form-group">
+ <label for="instanceDefaultClientRoute">Default client route</label>
+ <div class="peertube-select-container">
+ <select id="instanceDefaultClientRoute" formControlName="instanceDefaultClientRoute">
+ <option value="/videos/trending">Videos Trending</option>
+ <option value="/videos/recently-added">Videos Recently Added</option>
+ </select>
+ </div>
+ </div>
+
<div class="inner-form-title">Cache</div>
<div class="form-group">
instanceName: '',
instanceDescription: '',
instanceTerms: '',
+ instanceDefaultClientRoute: '',
cachePreviewsSize: '',
signupLimit: '',
adminEmail: '',
instanceName: [ '', INSTANCE_NAME.VALIDATORS ],
instanceDescription: [ '' ],
instanceTerms: [ '' ],
+ instanceDefaultClientRoute: [ '' ],
cachePreviewsSize: [ '', CACHE_PREVIEWS_SIZE.VALIDATORS ],
signupEnabled: [ ],
signupLimit: [ '', SIGNUP_LIMIT.VALIDATORS ],
if (confirmRes === false) return
}
- const data = {
+ const data: CustomConfig = {
instance: {
name: this.form.value['instanceName'],
description: this.form.value['instanceDescription'],
terms: this.form.value['instanceTerms'],
+ defaultClientRoute: this.form.value['instanceDefaultClientRoute'],
customizations: {
javascript: this.form.value['customizationJavascript'],
css: this.form.value['customizationCSS']
instanceName: this.customConfig.instance.name,
instanceDescription: this.customConfig.instance.description,
instanceTerms: this.customConfig.instance.terms,
+ instanceDefaultClientRoute: this.customConfig.instance.defaultClientRoute,
cachePreviewsSize: this.customConfig.cache.previews.size,
signupEnabled: this.customConfig.signup.enabled,
signupLimit: this.customConfig.signup.limit,
import { NgModule } from '@angular/core'
import { Routes, RouterModule } from '@angular/router'
+import { RedirectService } from '@app/core/routing/redirect.service'
import { PreloadSelectedModulesList } from './core'
const routes: Routes = [
- {
- path: '',
- redirectTo: '/videos/trending',
- pathMatch: 'full'
- },
{
path: 'admin',
loadChildren: './+admin/admin.module#AdminModule'
preloadingStrategy: PreloadSelectedModulesList
})
],
- providers: [ PreloadSelectedModulesList ],
+ providers: [
+ PreloadSelectedModulesList
+ ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}
import { Component, OnInit } from '@angular/core'
import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
import { GuardsCheckStart, Router } from '@angular/router'
-import { AuthService, ServerService } from '@app/core'
+import { AuthService, RedirectService, ServerService } from '@app/core'
import { isInSmallView } from '@app/shared/misc/utils'
@Component({
private router: Router,
private authService: AuthService,
private serverService: ServerService,
- private domSanitizer: DomSanitizer
+ private domSanitizer: DomSanitizer,
+ private redirectService: RedirectService
) {}
get serverVersion () {
}
ngOnInit () {
+ if (this.router.url === '/') {
+ this.redirectService.redirectToHomepage()
+ }
+
this.authService.loadClientCredentials()
if (this.authService.isLoggedIn()) {
import { AuthService } from './auth'
import { ConfirmComponent, ConfirmService } from './confirm'
import { throwIfAlreadyLoaded } from './module-import-guard'
-import { LoginGuard, UserRightGuard } from './routing'
+import { LoginGuard, RedirectService, UserRightGuard } from './routing'
import { ServerService } from './server'
@NgModule({
ConfirmService,
ServerService,
LoginGuard,
- UserRightGuard
+ UserRightGuard,
+ RedirectService
]
})
export class CoreModule {
export * from './login-guard.service'
export * from './user-right-guard.service'
export * from './preload-selected-modules-list'
+export * from './redirect.service'
--- /dev/null
+import { Injectable } from '@angular/core'
+import { Router } from '@angular/router'
+import { ServerService } from '../server'
+
+@Injectable()
+export class RedirectService {
+ // Default route could change according to the instance configuration
+ static INIT_DEFAULT_ROUTE = '/videos/trending'
+ static DEFAULT_ROUTE = RedirectService.INIT_DEFAULT_ROUTE
+
+ constructor (
+ private router: Router,
+ private serverService: ServerService
+ ) {
+ // The config is first loaded from the cache so try to get the default route
+ const config = this.serverService.getConfig()
+ if (config && config.instance && config.instance.defaultClientRoute) {
+ RedirectService.DEFAULT_ROUTE = config.instance.defaultClientRoute
+ }
+
+ this.serverService.configLoaded
+ .subscribe(() => {
+ const defaultRouteConfig = this.serverService.getConfig().instance.defaultClientRoute
+
+ if (defaultRouteConfig) {
+ RedirectService.DEFAULT_ROUTE = defaultRouteConfig
+ }
+ })
+ }
+
+ redirectToHomepage () {
+ console.log('Redirecting to %s...', RedirectService.DEFAULT_ROUTE)
+
+ this.router.navigate([ RedirectService.DEFAULT_ROUTE ])
+ .catch(() => {
+ console.error(
+ 'Cannot navigate to %s, resetting default route to %s.',
+ RedirectService.DEFAULT_ROUTE,
+ RedirectService.INIT_DEFAULT_ROUTE
+ )
+
+ RedirectService.DEFAULT_ROUTE = RedirectService.INIT_DEFAULT_ROUTE
+ return this.router.navigate([ RedirectService.DEFAULT_ROUTE ])
+ })
+
+ }
+
+}
private config: ServerConfig = {
instance: {
name: 'PeerTube',
+ defaultClientRoute: '',
customizations: {
javascript: '',
css: ''
import { Component, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
+import { RedirectService } from '@app/core/routing/redirect.service'
import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component'
import { MetaService } from '@ngx-meta/core'
import { NotificationsService } from 'angular2-notifications'
-import { Observable } from 'rxjs/Observable'
import { Subscription } from 'rxjs/Subscription'
import * as videojs from 'video.js'
import 'videojs-hotkeys'
private authService: AuthService,
private notificationsService: NotificationsService,
private markdownService: MarkdownService,
- private zone: NgZone
+ private zone: NgZone,
+ private redirectService: RedirectService
) {}
get user () {
.subscribe(
status => {
this.notificationsService.success('Success', `Video ${this.video.name} had been blacklisted.`)
- this.router.navigate(['/videos/list'])
+ this.redirectService.redirectToHomepage()
},
error => this.notificationsService.error('Error', error.message)
this.notificationsService.success('Success', `Video ${this.video.name} deleted.`)
// Go back to the video-list.
- this.router.navigate([ '/videos/list' ])
+ this.redirectService.redirectToHomepage()
},
error => this.notificationsService.error('Error', error.message)
'This video contains mature or explicit content. Are you sure you want to watch it?',
'Mature or explicit content'
)
- if (res === false) return this.router.navigate([ '/videos/list' ])
+ if (res === false) return this.redirectService.redirectToHomepage()
}
if (!this.hasAlreadyAcceptedPrivacyConcern()) {
'Privacy concern',
'I accept!'
)
- if (res === false) return this.router.navigate([ '/videos/list' ])
+ if (res === false) return this.redirectService.redirectToHomepage()
}
this.acceptedPrivacyConcern()
name: 'PeerTube'
description: 'Welcome to this PeerTube instance!' # Support markdown
terms: 'No terms for now.' # Support markdown
+ default_client_route: '/videos/trending'
customizations:
javascript: '' # Directly your JavaScript code (without <script> tags). Will be eval at runtime
css: '' # Directly your CSS code (without <style> tags). Will be injected at runtime
name: 'PeerTube'
description: '' # Support markdown
terms: '' # Support markdown
+ default_client_route: '/videos/trending'
customizations:
javascript: '' # Directly your JavaScript code (without <script> tags). Will be eval at runtime
css: '' # Directly your CSS code (without <style> tags). Will be injected at runtime
const json: ServerConfig = {
instance: {
name: CONFIG.INSTANCE.NAME,
+ defaultClientRoute: CONFIG.INSTANCE.DEFAULT_CLIENT_ROUTE,
customizations: {
javascript: CONFIG.INSTANCE.CUSTOMIZATIONS.JAVASCRIPT,
css: CONFIG.INSTANCE.CUSTOMIZATIONS.CSS
// Need to change the videoQuota key a little bit
const toUpdateJSON = omit(toUpdate, 'videoQuota')
toUpdateJSON.user['video_quota'] = toUpdate.user.videoQuota
+ toUpdateJSON.instance['default_client_route'] = toUpdate.instance.defaultClientRoute
delete toUpdate.user.videoQuota
+ delete toUpdate.instance.defaultClientRoute
await writeFilePromise(CONFIG.CUSTOM_FILE, JSON.stringify(toUpdateJSON, undefined, 2))
name: CONFIG.INSTANCE.NAME,
description: CONFIG.INSTANCE.DESCRIPTION,
terms: CONFIG.INSTANCE.TERMS,
+ defaultClientRoute: CONFIG.INSTANCE.DEFAULT_CLIENT_ROUTE,
customizations: {
css: CONFIG.INSTANCE.CUSTOMIZATIONS.CSS,
javascript: CONFIG.INSTANCE.CUSTOMIZATIONS.JAVASCRIPT
get NAME () { return config.get<string>('instance.name') },
get DESCRIPTION () { return config.get<string>('instance.description') },
get TERMS () { return config.get<string>('instance.terms') },
+ get DEFAULT_CLIENT_ROUTE () { return config.get<string>('instance.default_client_route') },
CUSTOMIZATIONS: {
get JAVASCRIPT () { return config.get<string>('instance.customizations.javascript') },
get CSS () { return config.get<string>('instance.customizations.css') }
import { areValidationErrors } from './utils'
const customConfigUpdateValidator = [
+ body('instance.name').exists().withMessage('Should have a valid instance name'),
+ body('instance.description').exists().withMessage('Should have a valid instance description'),
+ body('instance.terms').exists().withMessage('Should have a valid instance terms'),
+ body('instance.defaultClientRoute').exists().withMessage('Should have a valid instance default client route'),
+ body('instance.customizations.css').exists().withMessage('Should have a valid instance CSS customization'),
+ body('instance.customizations.javascript').exists().withMessage('Should have a valid instance JavaScript customization'),
body('cache.previews.size').isInt().withMessage('Should have a valid previews size'),
body('signup.enabled').isBoolean().withMessage('Should have a valid signup enabled boolean'),
body('signup.limit').isInt().withMessage('Should have a valid signup limit'),
name: 'PeerTube updated',
description: 'my super description',
terms: 'my super terms',
+ defaultClientRoute: '/videos/recently-added',
customizations: {
javascript: 'alert("coucou")',
css: 'body { background-color: red; }'
expect(data.instance.name).to.equal('PeerTube')
expect(data.instance.description).to.equal('Welcome to this PeerTube instance!')
expect(data.instance.terms).to.equal('No terms for now.')
+ expect(data.instance.defaultClientRoute).to.equal('/videos/trending')
expect(data.instance.customizations.css).to.be.empty
expect(data.instance.customizations.javascript).to.be.empty
expect(data.cache.previews.size).to.equal(1)
name: 'PeerTube updated',
description: 'my super description',
terms: 'my super terms',
+ defaultClientRoute: '/videos/recently-added',
customizations: {
javascript: 'alert("coucou")',
css: 'body { background-color: red; }'
expect(data.instance.name).to.equal('PeerTube updated')
expect(data.instance.description).to.equal('my super description')
expect(data.instance.terms).to.equal('my super terms')
+ expect(data.instance.defaultClientRoute).to.equal('/videos/recently-added')
expect(data.instance.customizations.javascript).to.equal('alert("coucou")')
expect(data.instance.customizations.css).to.equal('body { background-color: red; }')
expect(data.cache.previews.size).to.equal(2)
expect(data.instance.name).to.equal('PeerTube updated')
expect(data.instance.description).to.equal('my super description')
expect(data.instance.terms).to.equal('my super terms')
+ expect(data.instance.defaultClientRoute).to.equal('/videos/recently-added')
expect(data.instance.customizations.javascript).to.equal('alert("coucou")')
expect(data.instance.customizations.css).to.equal('body { background-color: red; }')
expect(data.cache.previews.size).to.equal(2)
expect(data.instance.name).to.equal('PeerTube')
expect(data.instance.description).to.equal('Welcome to this PeerTube instance!')
expect(data.instance.terms).to.equal('No terms for now.')
+ expect(data.instance.defaultClientRoute).to.equal('/videos/trending')
expect(data.instance.customizations.css).to.be.empty
expect(data.instance.customizations.javascript).to.be.empty
expect(data.cache.previews.size).to.equal(1)
name: string
description: string
terms: string
+ defaultClientRoute: string
customizations: {
javascript?: string
css?: string
serverVersion: string
instance: {
- name: string;
+ name: string
+ defaultClientRoute: string
customizations: {
javascript: string
css: string