diff options
Diffstat (limited to 'client/src')
17 files changed, 96 insertions, 17 deletions
diff --git a/client/src/app/+accounts/account-video-channels/account-video-channels.component.html b/client/src/app/+accounts/account-video-channels/account-video-channels.component.html index bcd3beaf0..114a9e517 100644 --- a/client/src/app/+accounts/account-video-channels/account-video-channels.component.html +++ b/client/src/app/+accounts/account-video-channels/account-video-channels.component.html | |||
@@ -1,6 +1,6 @@ | |||
1 | <div *ngIf="account" class="row"> | 1 | <div *ngIf="account" class="row"> |
2 | <a | 2 | <a |
3 | *ngFor="let videoChannel of videoChannels" [routerLink]="[ '/video-channels', videoChannel.uuid ]" | 3 | *ngFor="let videoChannel of videoChannels" [routerLink]="[ '/video-channels', videoChannel.name ]" |
4 | class="video-channel" i18n-title title="See this video channel" | 4 | class="video-channel" i18n-title title="See this video channel" |
5 | > | 5 | > |
6 | <img [src]="videoChannel.avatarUrl" alt="Avatar" /> | 6 | <img [src]="videoChannel.avatarUrl" alt="Avatar" /> |
diff --git a/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts b/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts index ebc671113..44f5626bb 100644 --- a/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts +++ b/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts | |||
@@ -2,10 +2,10 @@ import { Component, OnDestroy, OnInit } from '@angular/core' | |||
2 | import { ActivatedRoute } from '@angular/router' | 2 | import { ActivatedRoute } from '@angular/router' |
3 | import { Account } from '@app/shared/account/account.model' | 3 | import { Account } from '@app/shared/account/account.model' |
4 | import { AccountService } from '@app/shared/account/account.service' | 4 | import { AccountService } from '@app/shared/account/account.service' |
5 | import { VideoChannel } from '../../../../../shared/models/videos' | ||
6 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' | 5 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' |
7 | import { flatMap, map, tap } from 'rxjs/operators' | 6 | import { flatMap, map, tap } from 'rxjs/operators' |
8 | import { Subscription } from 'rxjs' | 7 | import { Subscription } from 'rxjs' |
8 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' | ||
9 | 9 | ||
10 | @Component({ | 10 | @Component({ |
11 | selector: 'my-account-video-channels', | 11 | selector: 'my-account-video-channels', |
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts index c0eaa4763..79ac07c93 100644 --- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts | |||
@@ -29,8 +29,13 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE | |||
29 | super() | 29 | super() |
30 | } | 30 | } |
31 | 31 | ||
32 | get instanceHost () { | ||
33 | return window.location.host | ||
34 | } | ||
35 | |||
32 | ngOnInit () { | 36 | ngOnInit () { |
33 | this.buildForm({ | 37 | this.buildForm({ |
38 | name: this.videoChannelValidatorsService.VIDEO_CHANNEL_NAME, | ||
34 | 'display-name': this.videoChannelValidatorsService.VIDEO_CHANNEL_DISPLAY_NAME, | 39 | 'display-name': this.videoChannelValidatorsService.VIDEO_CHANNEL_DISPLAY_NAME, |
35 | description: this.videoChannelValidatorsService.VIDEO_CHANNEL_DESCRIPTION, | 40 | description: this.videoChannelValidatorsService.VIDEO_CHANNEL_DESCRIPTION, |
36 | support: this.videoChannelValidatorsService.VIDEO_CHANNEL_SUPPORT | 41 | support: this.videoChannelValidatorsService.VIDEO_CHANNEL_SUPPORT |
@@ -42,6 +47,7 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE | |||
42 | 47 | ||
43 | const body = this.form.value | 48 | const body = this.form.value |
44 | const videoChannelCreate: VideoChannelCreate = { | 49 | const videoChannelCreate: VideoChannelCreate = { |
50 | name: body.name, | ||
45 | displayName: body['display-name'], | 51 | displayName: body['display-name'], |
46 | description: body.description || null, | 52 | description: body.description || null, |
47 | support: body.support || null | 53 | support: body.support || null |
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html index f7ca2ec43..81fb11f45 100644 --- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html | |||
@@ -8,6 +8,22 @@ | |||
8 | <div *ngIf="error" class="alert alert-danger">{{ error }}</div> | 8 | <div *ngIf="error" class="alert alert-danger">{{ error }}</div> |
9 | 9 | ||
10 | <form role="form" (ngSubmit)="formValidated()" [formGroup]="form"> | 10 | <form role="form" (ngSubmit)="formValidated()" [formGroup]="form"> |
11 | <div class="form-group" *ngIf="isCreation() === true"> | ||
12 | <label i18n for="name">Name</label> | ||
13 | <div class="input-group"> | ||
14 | <input | ||
15 | type="text" id="name" i18n-placeholder placeholder="Example: my_channel" | ||
16 | formControlName="name" [ngClass]="{ 'input-error': formErrors['name'] }" | ||
17 | > | ||
18 | <div class="input-group-append"> | ||
19 | <span class="input-group-text">@{{ instanceHost }}</span> | ||
20 | </div> | ||
21 | </div> | ||
22 | <div *ngIf="formErrors['name']" class="form-error"> | ||
23 | {{ formErrors['name'] }} | ||
24 | </div> | ||
25 | </div> | ||
26 | |||
11 | <div class="form-group"> | 27 | <div class="form-group"> |
12 | <label i18n for="display-name">Display name</label> | 28 | <label i18n for="display-name">Display name</label> |
13 | <input | 29 | <input |
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.scss b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.scss index 86c2598b7..833fda450 100644 --- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.scss +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.scss | |||
@@ -10,10 +10,19 @@ my-actor-avatar-info { | |||
10 | margin-bottom: 20px; | 10 | margin-bottom: 20px; |
11 | } | 11 | } |
12 | 12 | ||
13 | .input-group { | ||
14 | @include peertube-input-group(340px); | ||
15 | } | ||
16 | |||
13 | input[type=text] { | 17 | input[type=text] { |
14 | @include peertube-input-text(340px); | 18 | @include peertube-input-text(340px); |
15 | 19 | ||
16 | display: block; | 20 | display: block; |
21 | |||
22 | &#name { | ||
23 | width: auto; | ||
24 | flex-grow: 1; | ||
25 | } | ||
17 | } | 26 | } |
18 | 27 | ||
19 | textarea { | 28 | textarea { |
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html index d27c3b4ec..548645a76 100644 --- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html | |||
@@ -7,15 +7,14 @@ | |||
7 | 7 | ||
8 | <div class="video-channels"> | 8 | <div class="video-channels"> |
9 | <div *ngFor="let videoChannel of videoChannels" class="video-channel"> | 9 | <div *ngFor="let videoChannel of videoChannels" class="video-channel"> |
10 | <a [routerLink]="[ '/video-channels', videoChannel.uuid ]"> | 10 | <a [routerLink]="[ '/video-channels', videoChannel.name ]"> |
11 | <img [src]="videoChannel.avatarUrl" alt="Avatar" /> | 11 | <img [src]="videoChannel.avatarUrl" alt="Avatar" /> |
12 | </a> | 12 | </a> |
13 | 13 | ||
14 | <div class="video-channel-info"> | 14 | <div class="video-channel-info"> |
15 | <a [routerLink]="[ '/video-channels', videoChannel.uuid ]" class="video-channel-names" i18n-title title="Go to the channel"> | 15 | <a [routerLink]="[ '/video-channels', videoChannel.name ]" class="video-channel-names" i18n-title title="Go to the channel"> |
16 | <div class="video-channel-display-name">{{ videoChannel.displayName }}</div> | 16 | <div class="video-channel-display-name">{{ videoChannel.displayName }}</div> |
17 | <!-- Hide the name for now, because it's an UUID not very friendly --> | 17 | <div class="video-channel-name">{{ videoChannel.name }}</div> |
18 | <!--<div class="video-channel-name">{{ videoChannel.name }}</div>--> | ||
19 | </a> | 18 | </a> |
20 | 19 | ||
21 | <div i18n class="video-channel-followers">{{ videoChannel.followersCount }} subscribers</div> | 20 | <div i18n class="video-channel-followers">{{ videoChannel.followersCount }} subscribers</div> |
@@ -24,7 +23,7 @@ | |||
24 | <div class="video-channel-buttons"> | 23 | <div class="video-channel-buttons"> |
25 | <my-delete-button (click)="deleteVideoChannel(videoChannel)"></my-delete-button> | 24 | <my-delete-button (click)="deleteVideoChannel(videoChannel)"></my-delete-button> |
26 | 25 | ||
27 | <my-edit-button [routerLink]="[ 'update', videoChannel.uuid ]"></my-edit-button> | 26 | <my-edit-button [routerLink]="[ 'update', videoChannel.name ]"></my-edit-button> |
28 | </div> | 27 | </div> |
29 | </div> | 28 | </div> |
30 | </div> | 29 | </div> |
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.scss b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.scss index f047bb411..f8fd2684e 100644 --- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.scss +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.scss | |||
@@ -30,7 +30,9 @@ | |||
30 | a.video-channel-names { | 30 | a.video-channel-names { |
31 | @include disable-default-a-behaviour; | 31 | @include disable-default-a-behaviour; |
32 | 32 | ||
33 | width: fit-content; | ||
33 | display: flex; | 34 | display: flex; |
35 | align-items: baseline; | ||
34 | color: #000; | 36 | color: #000; |
35 | 37 | ||
36 | .video-channel-display-name { | 38 | .video-channel-display-name { |
@@ -41,6 +43,7 @@ | |||
41 | .video-channel-name { | 43 | .video-channel-name { |
42 | font-size: 14px; | 44 | font-size: 14px; |
43 | color: #777272; | 45 | color: #777272; |
46 | margin-left: 5px; | ||
44 | } | 47 | } |
45 | } | 48 | } |
46 | } | 49 | } |
diff --git a/client/src/app/+video-channels/video-channels.component.html b/client/src/app/+video-channels/video-channels.component.html index a52894cac..5a69a82a0 100644 --- a/client/src/app/+video-channels/video-channels.component.html +++ b/client/src/app/+video-channels/video-channels.component.html | |||
@@ -7,6 +7,7 @@ | |||
7 | <div class="actor-info"> | 7 | <div class="actor-info"> |
8 | <div class="actor-names"> | 8 | <div class="actor-names"> |
9 | <div class="actor-display-name">{{ videoChannel.displayName }}</div> | 9 | <div class="actor-display-name">{{ videoChannel.displayName }}</div> |
10 | <div class="actor-name">{{ videoChannel.nameWithHost }}</div> | ||
10 | </div> | 11 | </div> |
11 | <div i18n class="actor-followers">{{ videoChannel.followersCount }} subscribers</div> | 12 | <div i18n class="actor-followers">{{ videoChannel.followersCount }} subscribers</div> |
12 | 13 | ||
diff --git a/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts b/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts index 28b063f89..1ce3a0dca 100644 --- a/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts +++ b/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts | |||
@@ -5,11 +5,27 @@ import { BuildFormValidator } from '@app/shared' | |||
5 | 5 | ||
6 | @Injectable() | 6 | @Injectable() |
7 | export class VideoChannelValidatorsService { | 7 | export class VideoChannelValidatorsService { |
8 | readonly VIDEO_CHANNEL_NAME: BuildFormValidator | ||
8 | readonly VIDEO_CHANNEL_DISPLAY_NAME: BuildFormValidator | 9 | readonly VIDEO_CHANNEL_DISPLAY_NAME: BuildFormValidator |
9 | readonly VIDEO_CHANNEL_DESCRIPTION: BuildFormValidator | 10 | readonly VIDEO_CHANNEL_DESCRIPTION: BuildFormValidator |
10 | readonly VIDEO_CHANNEL_SUPPORT: BuildFormValidator | 11 | readonly VIDEO_CHANNEL_SUPPORT: BuildFormValidator |
11 | 12 | ||
12 | constructor (private i18n: I18n) { | 13 | constructor (private i18n: I18n) { |
14 | this.VIDEO_CHANNEL_NAME = { | ||
15 | VALIDATORS: [ | ||
16 | Validators.required, | ||
17 | Validators.minLength(3), | ||
18 | Validators.maxLength(20), | ||
19 | Validators.pattern(/^[a-z0-9._]+$/) | ||
20 | ], | ||
21 | MESSAGES: { | ||
22 | 'required': this.i18n('Name is required.'), | ||
23 | 'minlength': this.i18n('Name must be at least 3 characters long.'), | ||
24 | 'maxlength': this.i18n('Name cannot be more than 20 characters long.'), | ||
25 | 'pattern': this.i18n('Name should be only lowercase alphanumeric characters.') | ||
26 | } | ||
27 | } | ||
28 | |||
13 | this.VIDEO_CHANNEL_DISPLAY_NAME = { | 29 | this.VIDEO_CHANNEL_DISPLAY_NAME = { |
14 | VALIDATORS: [ | 30 | VALIDATORS: [ |
15 | Validators.required, | 31 | Validators.required, |
diff --git a/client/src/app/shared/video-channel/video-channel.model.ts b/client/src/app/shared/video-channel/video-channel.model.ts index b6862b681..309b614ae 100644 --- a/client/src/app/shared/video-channel/video-channel.model.ts +++ b/client/src/app/shared/video-channel/video-channel.model.ts | |||
@@ -7,6 +7,7 @@ export class VideoChannel extends Actor implements ServerVideoChannel { | |||
7 | description: string | 7 | description: string |
8 | support: string | 8 | support: string |
9 | isLocal: boolean | 9 | isLocal: boolean |
10 | nameWithHost: string | ||
10 | ownerAccount?: Account | 11 | ownerAccount?: Account |
11 | ownerBy?: string | 12 | ownerBy?: string |
12 | ownerAvatarUrl?: string | 13 | ownerAvatarUrl?: string |
@@ -18,6 +19,7 @@ export class VideoChannel extends Actor implements ServerVideoChannel { | |||
18 | this.description = hash.description | 19 | this.description = hash.description |
19 | this.support = hash.support | 20 | this.support = hash.support |
20 | this.isLocal = hash.isLocal | 21 | this.isLocal = hash.isLocal |
22 | this.nameWithHost = Actor.CREATE_BY_STRING(this.name, this.host) | ||
21 | 23 | ||
22 | if (hash.ownerAccount) { | 24 | if (hash.ownerAccount) { |
23 | this.ownerAccount = hash.ownerAccount | 25 | this.ownerAccount = hash.ownerAccount |
diff --git a/client/src/app/shared/video-channel/video-channel.service.ts b/client/src/app/shared/video-channel/video-channel.service.ts index 8c000665f..510dc9c3d 100644 --- a/client/src/app/shared/video-channel/video-channel.service.ts +++ b/client/src/app/shared/video-channel/video-channel.service.ts | |||
@@ -22,8 +22,8 @@ export class VideoChannelService { | |||
22 | private restExtractor: RestExtractor | 22 | private restExtractor: RestExtractor |
23 | ) {} | 23 | ) {} |
24 | 24 | ||
25 | getVideoChannel (videoChannelUUID: string) { | 25 | getVideoChannel (videoChannelName: string) { |
26 | return this.authHttp.get<VideoChannel>(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelUUID) | 26 | return this.authHttp.get<VideoChannel>(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelName) |
27 | .pipe( | 27 | .pipe( |
28 | map(videoChannelHash => new VideoChannel(videoChannelHash)), | 28 | map(videoChannelHash => new VideoChannel(videoChannelHash)), |
29 | tap(videoChannel => this.videoChannelLoaded.next(videoChannel)), | 29 | tap(videoChannel => this.videoChannelLoaded.next(videoChannel)), |
diff --git a/client/src/app/shared/video/video.service.ts b/client/src/app/shared/video/video.service.ts index e2a62c701..e44f1ee65 100644 --- a/client/src/app/shared/video/video.service.ts +++ b/client/src/app/shared/video/video.service.ts | |||
@@ -150,7 +150,7 @@ export class VideoService { | |||
150 | params = this.restService.addRestGetParams(params, pagination, sort) | 150 | params = this.restService.addRestGetParams(params, pagination, sort) |
151 | 151 | ||
152 | return this.authHttp | 152 | return this.authHttp |
153 | .get<ResultList<Video>>(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.uuid + '/videos', { params }) | 153 | .get<ResultList<Video>>(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.name + '/videos', { params }) |
154 | .pipe( | 154 | .pipe( |
155 | switchMap(res => this.extractVideos(res)), | 155 | switchMap(res => this.extractVideos(res)), |
156 | catchError(err => this.restExtractor.handleError(err)) | 156 | catchError(err => this.restExtractor.handleError(err)) |
diff --git a/client/src/app/signup/signup.component.html b/client/src/app/signup/signup.component.html index 565b695d9..5fd630b09 100644 --- a/client/src/app/signup/signup.component.html +++ b/client/src/app/signup/signup.component.html | |||
@@ -23,10 +23,17 @@ | |||
23 | <form role="form" (ngSubmit)="signup()" [formGroup]="form"> | 23 | <form role="form" (ngSubmit)="signup()" [formGroup]="form"> |
24 | <div class="form-group"> | 24 | <div class="form-group"> |
25 | <label for="username" i18n>Username</label> | 25 | <label for="username" i18n>Username</label> |
26 | <input | 26 | |
27 | type="text" id="username" i18n-placeholder placeholder="Username" | 27 | <div class="input-group"> |
28 | formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }" | 28 | <input |
29 | > | 29 | type="text" id="username" i18n-placeholder placeholder="Example: neil_amstrong" |
30 | formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }" | ||
31 | > | ||
32 | <div class="input-group-append"> | ||
33 | <span class="input-group-text">@{{ instanceHost }}</span> | ||
34 | </div> | ||
35 | </div> | ||
36 | |||
30 | <div *ngIf="formErrors.username" class="form-error"> | 37 | <div *ngIf="formErrors.username" class="form-error"> |
31 | {{ formErrors.username }} | 38 | {{ formErrors.username }} |
32 | </div> | 39 | </div> |
diff --git a/client/src/app/signup/signup.component.scss b/client/src/app/signup/signup.component.scss index e6d484297..1c992faf5 100644 --- a/client/src/app/signup/signup.component.scss +++ b/client/src/app/signup/signup.component.scss | |||
@@ -14,9 +14,18 @@ | |||
14 | margin: 30px 0; | 14 | margin: 30px 0; |
15 | } | 15 | } |
16 | 16 | ||
17 | .input-group { | ||
18 | @include peertube-input-group(340px); | ||
19 | } | ||
20 | |||
17 | input:not([type=submit]) { | 21 | input:not([type=submit]) { |
18 | @include peertube-input-text(340px); | 22 | @include peertube-input-text(340px); |
19 | display: block; | 23 | display: block; |
24 | |||
25 | &#username { | ||
26 | width: auto; | ||
27 | flex-grow: 1; | ||
28 | } | ||
20 | } | 29 | } |
21 | 30 | ||
22 | input[type=submit] { | 31 | input[type=submit] { |
diff --git a/client/src/app/signup/signup.component.ts b/client/src/app/signup/signup.component.ts index 076dac454..ed68487ae 100644 --- a/client/src/app/signup/signup.component.ts +++ b/client/src/app/signup/signup.component.ts | |||
@@ -34,6 +34,10 @@ export class SignupComponent extends FormReactive implements OnInit { | |||
34 | return this.serverService.getConfig().user.videoQuota | 34 | return this.serverService.getConfig().user.videoQuota |
35 | } | 35 | } |
36 | 36 | ||
37 | get instanceHost () { | ||
38 | return window.location.host | ||
39 | } | ||
40 | |||
37 | ngOnInit () { | 41 | ngOnInit () { |
38 | this.buildForm({ | 42 | this.buildForm({ |
39 | username: this.userValidatorsService.USER_USERNAME, | 43 | username: this.userValidatorsService.USER_USERNAME, |
diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html index 8d4a4a5ca..c275258ef 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.html +++ b/client/src/app/videos/+video-watch/video-watch.component.html | |||
@@ -37,7 +37,7 @@ | |||
37 | </div> | 37 | </div> |
38 | 38 | ||
39 | <div class="video-info-channel"> | 39 | <div class="video-info-channel"> |
40 | <a [routerLink]="[ '/video-channels', video.channel.uuid ]" i18n-title title="Go the channel page"> | 40 | <a [routerLink]="[ '/video-channels', video.channel.name ]" i18n-title title="Go the channel page"> |
41 | {{ video.channel.displayName }} | 41 | {{ video.channel.displayName }} |
42 | 42 | ||
43 | <img [src]="video.videoChannelAvatarUrl" alt="Video channel avatar" /> | 43 | <img [src]="video.videoChannelAvatarUrl" alt="Video channel avatar" /> |
diff --git a/client/src/sass/include/_mixins.scss b/client/src/sass/include/_mixins.scss index 3d518394a..b0b0f544c 100644 --- a/client/src/sass/include/_mixins.scss +++ b/client/src/sass/include/_mixins.scss | |||
@@ -36,9 +36,16 @@ | |||
36 | border-radius: 3px; | 36 | border-radius: 3px; |
37 | padding-left: 15px; | 37 | padding-left: 15px; |
38 | padding-right: 15px; | 38 | padding-right: 15px; |
39 | } | ||
39 | 40 | ||
40 | &::placeholder { | 41 | @mixin peertube-input-group($width) { |
41 | color: #585858; | 42 | width: $width; |
43 | height: $button-height; | ||
44 | padding-top: 0; | ||
45 | padding-bottom: 0; | ||
46 | |||
47 | .input-group-text{ | ||
48 | font-size: 14px; | ||
42 | } | 49 | } |
43 | } | 50 | } |
44 | 51 | ||