aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app')
-rw-r--r--client/src/app/about/about-routing.module.ts23
-rw-r--r--client/src/app/about/about.component.html17
-rw-r--r--client/src/app/about/about.component.scss12
-rw-r--r--client/src/app/about/about.component.ts38
-rw-r--r--client/src/app/about/about.module.ts24
-rw-r--r--client/src/app/about/index.ts3
-rw-r--r--client/src/app/app.component.html2
-rw-r--r--client/src/app/app.component.ts4
-rw-r--r--client/src/app/app.module.ts2
-rw-r--r--client/src/app/core/server/server.service.ts33
-rw-r--r--client/src/app/menu/menu.component.html9
-rw-r--r--client/src/app/menu/menu.component.scss7
-rw-r--r--client/src/app/shared/forms/form-validators/custom-config.ts2
-rw-r--r--client/src/app/videos/shared/markdown.service.ts3
14 files changed, 172 insertions, 7 deletions
diff --git a/client/src/app/about/about-routing.module.ts b/client/src/app/about/about-routing.module.ts
new file mode 100644
index 000000000..11a650c80
--- /dev/null
+++ b/client/src/app/about/about-routing.module.ts
@@ -0,0 +1,23 @@
1import { NgModule } from '@angular/core'
2import { RouterModule, Routes } from '@angular/router'
3import { MetaGuard } from '@ngx-meta/core'
4import { AboutComponent } from './about.component'
5
6const aboutRoutes: Routes = [
7 {
8 path: 'about',
9 component: AboutComponent,
10 canActivate: [ MetaGuard ],
11 data: {
12 meta: {
13 title: 'About'
14 }
15 }
16 }
17]
18
19@NgModule({
20 imports: [ RouterModule.forChild(aboutRoutes) ],
21 exports: [ RouterModule ]
22})
23export class AboutRoutingModule {}
diff --git a/client/src/app/about/about.component.html b/client/src/app/about/about.component.html
new file mode 100644
index 000000000..c0be53581
--- /dev/null
+++ b/client/src/app/about/about.component.html
@@ -0,0 +1,17 @@
1<div class="margin-content">
2 <div class="title-page title-page-single">
3 Welcome to the {{ instanceName }} instance
4 </div>
5
6 <div class="description">
7 <div class="section-title">Description</div>
8
9 <div [innerHTML]="descriptionHTML"></div>
10 </div>
11
12 <div class="terms">
13 <div class="section-title">Terms</div>
14
15 <div [innerHTML]="termsHTML"></div>
16 </div>
17</div>
diff --git a/client/src/app/about/about.component.scss b/client/src/app/about/about.component.scss
new file mode 100644
index 000000000..dba4df729
--- /dev/null
+++ b/client/src/app/about/about.component.scss
@@ -0,0 +1,12 @@
1@import '_variables';
2@import '_mixins';
3
4.section-title {
5 font-weight: $font-semibold;
6 font-size: 20px;
7 margin-bottom: 5px;
8}
9
10.description {
11 margin-bottom: 30px;
12}
diff --git a/client/src/app/about/about.component.ts b/client/src/app/about/about.component.ts
new file mode 100644
index 000000000..6a2e59be1
--- /dev/null
+++ b/client/src/app/about/about.component.ts
@@ -0,0 +1,38 @@
1import { Component, OnInit } from '@angular/core'
2import { ServerService } from '@app/core'
3import { MarkdownService } from '@app/videos/shared'
4import { NotificationsService } from 'angular2-notifications'
5
6@Component({
7 selector: 'my-about',
8 templateUrl: './about.component.html',
9 styleUrls: [ './about.component.scss' ]
10})
11
12export class AboutComponent implements OnInit {
13 descriptionHTML = ''
14 termsHTML = ''
15
16 constructor (
17 private notificationsService: NotificationsService,
18 private serverService: ServerService,
19 private markdownService: MarkdownService
20 ) {}
21
22 get instanceName () {
23 return this.serverService.getConfig().instance.name
24 }
25
26 ngOnInit () {
27 this.serverService.getAbout()
28 .subscribe(
29 res => {
30 this.descriptionHTML = this.markdownService.markdownToHTML(res.instance.description)
31 this.termsHTML = this.markdownService.markdownToHTML(res.instance.terms)
32 },
33
34 err => this.notificationsService.error('Error', err)
35 )
36 }
37
38}
diff --git a/client/src/app/about/about.module.ts b/client/src/app/about/about.module.ts
new file mode 100644
index 000000000..da3163f43
--- /dev/null
+++ b/client/src/app/about/about.module.ts
@@ -0,0 +1,24 @@
1import { NgModule } from '@angular/core'
2
3import { AboutRoutingModule } from './about-routing.module'
4import { AboutComponent } from './about.component'
5import { SharedModule } from '../shared'
6
7@NgModule({
8 imports: [
9 AboutRoutingModule,
10 SharedModule
11 ],
12
13 declarations: [
14 AboutComponent
15 ],
16
17 exports: [
18 AboutComponent
19 ],
20
21 providers: [
22 ]
23})
24export class AboutModule { }
diff --git a/client/src/app/about/index.ts b/client/src/app/about/index.ts
new file mode 100644
index 000000000..218d09801
--- /dev/null
+++ b/client/src/app/about/index.ts
@@ -0,0 +1,3 @@
1export * from './about-routing.module'
2export * from './about.component'
3export * from './about.module'
diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html
index ba7debc71..3a7aedac6 100644
--- a/client/src/app/app.component.html
+++ b/client/src/app/app.component.html
@@ -6,7 +6,7 @@
6 6
7 <a id="peertube-title" [routerLink]="['/videos/list']" title="Homepage"> 7 <a id="peertube-title" [routerLink]="['/videos/list']" title="Homepage">
8 <span class="icon icon-logo"></span> 8 <span class="icon icon-logo"></span>
9 PeerTube 9 {{ instanceName }}
10 </a> 10 </a>
11 </div> 11 </div>
12 12
diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts
index 55c7bbf99..121e60ffc 100644
--- a/client/src/app/app.component.ts
+++ b/client/src/app/app.component.ts
@@ -34,6 +34,10 @@ export class AppComponent implements OnInit {
34 return this.serverService.getConfig().serverVersion 34 return this.serverService.getConfig().serverVersion
35 } 35 }
36 36
37 get instanceName () {
38 return this.serverService.getConfig().instance.name
39 }
40
37 ngOnInit () { 41 ngOnInit () {
38 this.authService.loadClientCredentials() 42 this.authService.loadClientCredentials()
39 43
diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts
index ddcaf3f48..1134d061b 100644
--- a/client/src/app/app.module.ts
+++ b/client/src/app/app.module.ts
@@ -1,5 +1,6 @@
1import { NgModule } from '@angular/core' 1import { NgModule } from '@angular/core'
2import { BrowserModule } from '@angular/platform-browser' 2import { BrowserModule } from '@angular/platform-browser'
3import { AboutModule } from '@app/about'
3import { ResetPasswordModule } from '@app/reset-password' 4import { ResetPasswordModule } from '@app/reset-password'
4 5
5import { MetaLoader, MetaModule, MetaStaticLoader, PageTitlePositioning } from '@ngx-meta/core' 6import { MetaLoader, MetaModule, MetaStaticLoader, PageTitlePositioning } from '@ngx-meta/core'
@@ -51,6 +52,7 @@ export function metaFactory (): MetaLoader {
51 SignupModule, 52 SignupModule,
52 SharedModule, 53 SharedModule,
53 VideosModule, 54 VideosModule,
55 AboutModule,
54 56
55 MetaModule.forRoot({ 57 MetaModule.forRoot({
56 provide: MetaLoader, 58 provide: MetaLoader,
diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts
index 6df449018..65714fd05 100644
--- a/client/src/app/core/server/server.service.ts
+++ b/client/src/app/core/server/server.service.ts
@@ -3,12 +3,14 @@ import { Injectable } from '@angular/core'
3import 'rxjs/add/operator/do' 3import 'rxjs/add/operator/do'
4import { ReplaySubject } from 'rxjs/ReplaySubject' 4import { ReplaySubject } from 'rxjs/ReplaySubject'
5import { ServerConfig } from '../../../../../shared' 5import { ServerConfig } from '../../../../../shared'
6import { About } from '../../../../../shared/models/config/about.model'
6import { environment } from '../../../environments/environment' 7import { environment } from '../../../environments/environment'
7 8
8@Injectable() 9@Injectable()
9export class ServerService { 10export class ServerService {
10 private static BASE_CONFIG_URL = environment.apiUrl + '/api/v1/config/' 11 private static BASE_CONFIG_URL = environment.apiUrl + '/api/v1/config/'
11 private static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/' 12 private static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/'
13 private static CONFIG_LOCAL_STORAGE_KEY = 'server-config'
12 14
13 videoPrivaciesLoaded = new ReplaySubject<boolean>(1) 15 videoPrivaciesLoaded = new ReplaySubject<boolean>(1)
14 videoCategoriesLoaded = new ReplaySubject<boolean>(1) 16 videoCategoriesLoaded = new ReplaySubject<boolean>(1)
@@ -16,6 +18,9 @@ export class ServerService {
16 videoLanguagesLoaded = new ReplaySubject<boolean>(1) 18 videoLanguagesLoaded = new ReplaySubject<boolean>(1)
17 19
18 private config: ServerConfig = { 20 private config: ServerConfig = {
21 instance: {
22 name: 'PeerTube'
23 },
19 serverVersion: 'Unknown', 24 serverVersion: 'Unknown',
20 signup: { 25 signup: {
21 allowed: false 26 allowed: false
@@ -40,11 +45,14 @@ export class ServerService {
40 private videoLanguages: Array<{ id: number, label: string }> = [] 45 private videoLanguages: Array<{ id: number, label: string }> = []
41 private videoPrivacies: Array<{ id: number, label: string }> = [] 46 private videoPrivacies: Array<{ id: number, label: string }> = []
42 47
43 constructor (private http: HttpClient) {} 48 constructor (private http: HttpClient) {
49 this.loadConfigLocally()
50 }
44 51
45 loadConfig () { 52 loadConfig () {
46 this.http.get<ServerConfig>(ServerService.BASE_CONFIG_URL) 53 this.http.get<ServerConfig>(ServerService.BASE_CONFIG_URL)
47 .subscribe(data => this.config = data) 54 .do(this.saveConfigLocally)
55 .subscribe(data => this.config = data)
48 } 56 }
49 57
50 loadVideoCategories () { 58 loadVideoCategories () {
@@ -83,6 +91,10 @@ export class ServerService {
83 return this.videoPrivacies 91 return this.videoPrivacies
84 } 92 }
85 93
94 getAbout () {
95 return this.http.get<About>(ServerService.BASE_CONFIG_URL + '/about')
96 }
97
86 private loadVideoAttributeEnum ( 98 private loadVideoAttributeEnum (
87 attributeName: 'categories' | 'licences' | 'languages' | 'privacies', 99 attributeName: 'categories' | 'licences' | 'languages' | 'privacies',
88 hashToPopulate: { id: number, label: string }[], 100 hashToPopulate: { id: number, label: string }[],
@@ -101,4 +113,21 @@ export class ServerService {
101 notifier.next(true) 113 notifier.next(true)
102 }) 114 })
103 } 115 }
116
117 private saveConfigLocally (config: ServerConfig) {
118 localStorage.setItem(ServerService.CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config))
119 }
120
121 private loadConfigLocally () {
122 const configString = localStorage.getItem(ServerService.CONFIG_LOCAL_STORAGE_KEY)
123
124 if (configString) {
125 try {
126 const parsed = JSON.parse(configString)
127 Object.assign(this.config, parsed)
128 } catch (err) {
129 console.error('Cannot parse config saved in local storage.', err)
130 }
131 }
132 }
104} 133}
diff --git a/client/src/app/menu/menu.component.html b/client/src/app/menu/menu.component.html
index 94f82e352..d174c76ba 100644
--- a/client/src/app/menu/menu.component.html
+++ b/client/src/app/menu/menu.component.html
@@ -45,12 +45,17 @@
45 </a> 45 </a>
46 </div> 46 </div>
47 47
48 <div *ngIf="userHasAdminAccess" class="panel-block"> 48 <div class="panel-block">
49 <div class="block-title">More</div> 49 <div class="block-title">More</div>
50 50
51 <a [routerLink]="getFirstAdminRouteAvailable()" routerLinkActive="active"> 51 <a *ngIf="userHasAdminAccess" [routerLink]="getFirstAdminRouteAvailable()" routerLinkActive="active">
52 <span class="icon icon-administration"></span> 52 <span class="icon icon-administration"></span>
53 Administration 53 Administration
54 </a> 54 </a>
55
56 <a routerLink="/about" routerLinkActive="active">
57 <span class="icon icon-about"></span>
58 About
59 </a>
55 </div> 60 </div>
56</menu> 61</menu>
diff --git a/client/src/app/menu/menu.component.scss b/client/src/app/menu/menu.component.scss
index 4714a9e87..1f3c889cf 100644
--- a/client/src/app/menu/menu.component.scss
+++ b/client/src/app/menu/menu.component.scss
@@ -132,6 +132,13 @@ menu {
132 132
133 background-image: url('../../assets/images/menu/administration.svg'); 133 background-image: url('../../assets/images/menu/administration.svg');
134 } 134 }
135
136 &.icon-about {
137 width: 23px;
138 height: 23px;
139
140 background-image: url('../../assets/images/menu/about.svg');
141 }
135 } 142 }
136 } 143 }
137 } 144 }
diff --git a/client/src/app/shared/forms/form-validators/custom-config.ts b/client/src/app/shared/forms/form-validators/custom-config.ts
index 9e3fa98d8..a0966a9a7 100644
--- a/client/src/app/shared/forms/form-validators/custom-config.ts
+++ b/client/src/app/shared/forms/form-validators/custom-config.ts
@@ -3,7 +3,7 @@ import { Validators } from '@angular/forms'
3export const INSTANCE_NAME = { 3export const INSTANCE_NAME = {
4 VALIDATORS: [ Validators.required ], 4 VALIDATORS: [ Validators.required ],
5 MESSAGES: { 5 MESSAGES: {
6 'required': 'Instance name is required.', 6 'required': 'Instance name is required.'
7 } 7 }
8} 8}
9 9
diff --git a/client/src/app/videos/shared/markdown.service.ts b/client/src/app/videos/shared/markdown.service.ts
index fd0330f9b..3f51a82ce 100644
--- a/client/src/app/videos/shared/markdown.service.ts
+++ b/client/src/app/videos/shared/markdown.service.ts
@@ -7,12 +7,13 @@ export class MarkdownService {
7 private markdownIt: MarkdownIt.MarkdownIt 7 private markdownIt: MarkdownIt.MarkdownIt
8 8
9 constructor () { 9 constructor () {
10 this.markdownIt = new MarkdownIt('zero', { linkify: true }) 10 this.markdownIt = new MarkdownIt('zero', { linkify: true, breaks: true })
11 .enable('linkify') 11 .enable('linkify')
12 .enable('autolink') 12 .enable('autolink')
13 .enable('emphasis') 13 .enable('emphasis')
14 .enable('link') 14 .enable('link')
15 .enable('newline') 15 .enable('newline')
16 .enable('list')
16 17
17 this.setTargetToLinks() 18 this.setTargetToLinks()
18 } 19 }