1
0
Fork 0

Add ability to change the homepage

This commit is contained in:
Chocobozzz 2018-03-01 13:57:29 +01:00
parent a73c582e5b
commit 901637bb87
No known key found for this signature in database
GPG key ID: 583A612D890159BE
18 changed files with 108 additions and 18 deletions

View file

@ -37,6 +37,16 @@
</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">

View file

@ -46,6 +46,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
instanceName: '',
instanceDescription: '',
instanceTerms: '',
instanceDefaultClientRoute: '',
cachePreviewsSize: '',
signupLimit: '',
adminEmail: '',
@ -85,6 +86,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
instanceName: [ '', INSTANCE_NAME.VALIDATORS ],
instanceDescription: [ '' ],
instanceTerms: [ '' ],
instanceDefaultClientRoute: [ '' ],
cachePreviewsSize: [ '', CACHE_PREVIEWS_SIZE.VALIDATORS ],
signupEnabled: [ ],
signupLimit: [ '', SIGNUP_LIMIT.VALIDATORS ],
@ -153,11 +155,12 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
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']
@ -213,6 +216,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
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,

View file

@ -1,14 +1,10 @@
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'
@ -22,7 +18,9 @@ const routes: Routes = [
preloadingStrategy: PreloadSelectedModulesList
})
],
providers: [ PreloadSelectedModulesList ],
providers: [
PreloadSelectedModulesList
],
exports: [ RouterModule ]
})
export class AppRoutingModule {}

View file

@ -1,7 +1,7 @@
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({
@ -31,7 +31,8 @@ export class AppComponent implements OnInit {
private router: Router,
private authService: AuthService,
private serverService: ServerService,
private domSanitizer: DomSanitizer
private domSanitizer: DomSanitizer,
private redirectService: RedirectService
) {}
get serverVersion () {
@ -43,6 +44,10 @@ export class AppComponent implements OnInit {
}
ngOnInit () {
if (this.router.url === '/') {
this.redirectService.redirectToHomepage()
}
this.authService.loadClientCredentials()
if (this.authService.isLoggedIn()) {

View file

@ -13,7 +13,7 @@ import { ModalModule } from 'ngx-bootstrap/modal'
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({
@ -48,7 +48,8 @@ import { ServerService } from './server'
ConfirmService,
ServerService,
LoginGuard,
UserRightGuard
UserRightGuard,
RedirectService
]
})
export class CoreModule {

View file

@ -1,3 +1,4 @@
export * from './login-guard.service'
export * from './user-right-guard.service'
export * from './preload-selected-modules-list'
export * from './redirect.service'

View file

@ -0,0 +1,48 @@
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 ])
})
}
}

View file

@ -21,6 +21,7 @@ export class ServerService {
private config: ServerConfig = {
instance: {
name: 'PeerTube',
defaultClientRoute: '',
customizations: {
javascript: '',
css: ''

View file

@ -1,9 +1,9 @@
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'
@ -64,7 +64,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
private authService: AuthService,
private notificationsService: NotificationsService,
private markdownService: MarkdownService,
private zone: NgZone
private zone: NgZone,
private redirectService: RedirectService
) {}
get user () {
@ -142,7 +143,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
.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)
@ -247,7 +248,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
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)
@ -313,7 +314,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
'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()) {
@ -323,7 +324,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
'Privacy concern',
'I accept!'
)
if (res === false) return this.router.navigate([ '/videos/list' ])
if (res === false) return this.redirectService.redirectToHomepage()
}
this.acceptedPrivacyConcern()

View file

@ -74,6 +74,7 @@ instance:
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

View file

@ -87,6 +87,7 @@ instance:
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

View file

@ -44,6 +44,7 @@ async function getConfig (req: express.Request, res: express.Response, next: exp
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
@ -114,7 +115,9 @@ async function updateCustomConfig (req: express.Request, res: express.Response,
// 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))
@ -138,6 +141,7 @@ function customConfig (): CustomConfig {
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

View file

@ -159,6 +159,7 @@ const CONFIG = {
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') }

View file

@ -5,6 +5,12 @@ import { logger } from '../../helpers/logger'
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'),

View file

@ -18,6 +18,7 @@ describe('Test config API validators', function () {
name: 'PeerTube updated',
description: 'my super description',
terms: 'my super terms',
defaultClientRoute: '/videos/recently-added',
customizations: {
javascript: 'alert("coucou")',
css: 'body { background-color: red; }'

View file

@ -54,6 +54,7 @@ describe('Test config', function () {
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)
@ -76,6 +77,7 @@ describe('Test config', function () {
name: 'PeerTube updated',
description: 'my super description',
terms: 'my super terms',
defaultClientRoute: '/videos/recently-added',
customizations: {
javascript: 'alert("coucou")',
css: 'body { background-color: red; }'
@ -116,6 +118,7 @@ describe('Test config', function () {
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)
@ -145,6 +148,7 @@ describe('Test config', function () {
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)
@ -181,6 +185,7 @@ describe('Test config', function () {
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)

View file

@ -3,6 +3,7 @@ export interface CustomConfig {
name: string
description: string
terms: string
defaultClientRoute: string
customizations: {
javascript?: string
css?: string

View file

@ -2,7 +2,8 @@ export interface ServerConfig {
serverVersion: string
instance: {
name: string;
name: string
defaultClientRoute: string
customizations: {
javascript: string
css: string