diff options
author | kontrollanten <6680299+kontrollanten@users.noreply.github.com> | 2021-12-13 15:29:13 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-13 15:29:13 +0100 |
commit | a37e9e74ff07b057370d1ed6c0b391a02be8a6d2 (patch) | |
tree | 30d59e12518149a309bbd10bee1485f8be523c75 /client/src/app/+my-library | |
parent | 11e520b50d791a0dd48cbb2d0fc681b25eb7cd53 (diff) | |
download | PeerTube-a37e9e74ff07b057370d1ed6c0b391a02be8a6d2.tar.gz PeerTube-a37e9e74ff07b057370d1ed6c0b391a02be8a6d2.tar.zst PeerTube-a37e9e74ff07b057370d1ed6c0b391a02be8a6d2.zip |
Give moderators access to edit channels (#4608)
* give admins access to edit all channels
closes #4598
* test(channels): +admin update another users channel
* Fix tests
* fix(server): delete another users channel
Since the channel owner isn't necessary the auth user we need to check
the right account whether it's the last video or not.
* REMOVE_ANY_VIDEO_CHANNEL > MANAGE_ANY_VIDEO_CHANNEL
Merge REMOVE_ANY_VIDEO_CHANNEL and MANY_VIDEO_CHANNELS to
MANAGE_ANY_VIDEO_CHANNEL.
* user-right: moderator can't manage admins channel
* client: MyVideoChannelCreateComponent > VideoChannelCreateComponent
* client: MyVideoChannelEdit > VideoChannelEdit
* Revert "user-right: moderator can't manage admins channel"
This reverts commit 2c627c154e2bfe6af2e0f45efb27faf4117572f3.
* server: clean dupl validator functionality
* fix ensureUserCanManageChannel usage
It's not async anymore.
* server: merge channel validator middleares
ensureAuthUserOwnsChannelValidator & ensureUserCanManageChannel gets
merged into one middleware.
* client(VideoChannelEdit): redirect to prev route
* fix(VideoChannels): handle anon users
* client: new routes for create/update channel
* Refactor channel validators
Co-authored-by: Chocobozzz <me@florianbigard.com>
Diffstat (limited to 'client/src/app/+my-library')
8 files changed, 6 insertions, 535 deletions
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts b/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts deleted file mode 100644 index fd00720d8..000000000 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts +++ /dev/null | |||
@@ -1,120 +0,0 @@ | |||
1 | import { of } from 'rxjs' | ||
2 | import { switchMap } from 'rxjs/operators' | ||
3 | import { Component, OnInit } from '@angular/core' | ||
4 | import { Router } from '@angular/router' | ||
5 | import { AuthService, Notifier } from '@app/core' | ||
6 | import { | ||
7 | VIDEO_CHANNEL_DESCRIPTION_VALIDATOR, | ||
8 | VIDEO_CHANNEL_DISPLAY_NAME_VALIDATOR, | ||
9 | VIDEO_CHANNEL_NAME_VALIDATOR, | ||
10 | VIDEO_CHANNEL_SUPPORT_VALIDATOR | ||
11 | } from '@app/shared/form-validators/video-channel-validators' | ||
12 | import { FormValidatorService } from '@app/shared/shared-forms' | ||
13 | import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' | ||
14 | import { HttpStatusCode, VideoChannelCreate } from '@shared/models' | ||
15 | import { MyVideoChannelEdit } from './my-video-channel-edit' | ||
16 | |||
17 | @Component({ | ||
18 | templateUrl: './my-video-channel-edit.component.html', | ||
19 | styleUrls: [ './my-video-channel-edit.component.scss' ] | ||
20 | }) | ||
21 | export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements OnInit { | ||
22 | error: string | ||
23 | videoChannel = new VideoChannel({}) | ||
24 | |||
25 | private avatar: FormData | ||
26 | private banner: FormData | ||
27 | |||
28 | constructor ( | ||
29 | protected formValidatorService: FormValidatorService, | ||
30 | private authService: AuthService, | ||
31 | private notifier: Notifier, | ||
32 | private router: Router, | ||
33 | private videoChannelService: VideoChannelService | ||
34 | ) { | ||
35 | super() | ||
36 | } | ||
37 | |||
38 | ngOnInit () { | ||
39 | this.buildForm({ | ||
40 | name: VIDEO_CHANNEL_NAME_VALIDATOR, | ||
41 | 'display-name': VIDEO_CHANNEL_DISPLAY_NAME_VALIDATOR, | ||
42 | description: VIDEO_CHANNEL_DESCRIPTION_VALIDATOR, | ||
43 | support: VIDEO_CHANNEL_SUPPORT_VALIDATOR | ||
44 | }) | ||
45 | } | ||
46 | |||
47 | formValidated () { | ||
48 | this.error = undefined | ||
49 | |||
50 | const body = this.form.value | ||
51 | const videoChannelCreate: VideoChannelCreate = { | ||
52 | name: body.name, | ||
53 | displayName: body['display-name'], | ||
54 | description: body.description || null, | ||
55 | support: body.support || null | ||
56 | } | ||
57 | |||
58 | this.videoChannelService.createVideoChannel(videoChannelCreate) | ||
59 | .pipe( | ||
60 | switchMap(() => this.uploadAvatar()), | ||
61 | switchMap(() => this.uploadBanner()) | ||
62 | ).subscribe({ | ||
63 | next: () => { | ||
64 | this.authService.refreshUserInformation() | ||
65 | |||
66 | this.notifier.success($localize`Video channel ${videoChannelCreate.displayName} created.`) | ||
67 | this.router.navigate([ '/my-library', 'video-channels' ]) | ||
68 | }, | ||
69 | |||
70 | error: err => { | ||
71 | if (err.status === HttpStatusCode.CONFLICT_409) { | ||
72 | this.error = $localize`This name already exists on this instance.` | ||
73 | return | ||
74 | } | ||
75 | |||
76 | this.error = err.message | ||
77 | } | ||
78 | }) | ||
79 | } | ||
80 | |||
81 | onAvatarChange (formData: FormData) { | ||
82 | this.avatar = formData | ||
83 | } | ||
84 | |||
85 | onAvatarDelete () { | ||
86 | this.avatar = null | ||
87 | } | ||
88 | |||
89 | onBannerChange (formData: FormData) { | ||
90 | this.banner = formData | ||
91 | } | ||
92 | |||
93 | onBannerDelete () { | ||
94 | this.banner = null | ||
95 | } | ||
96 | |||
97 | isCreation () { | ||
98 | return true | ||
99 | } | ||
100 | |||
101 | getFormButtonTitle () { | ||
102 | return $localize`Create` | ||
103 | } | ||
104 | |||
105 | getUsername () { | ||
106 | return this.form.value.name | ||
107 | } | ||
108 | |||
109 | private uploadAvatar () { | ||
110 | if (!this.avatar) return of(undefined) | ||
111 | |||
112 | return this.videoChannelService.changeVideoChannelImage(this.getUsername(), this.avatar, 'avatar') | ||
113 | } | ||
114 | |||
115 | private uploadBanner () { | ||
116 | if (!this.banner) return of(undefined) | ||
117 | |||
118 | return this.videoChannelService.changeVideoChannelImage(this.getUsername(), this.banner, 'banner') | ||
119 | } | ||
120 | } | ||
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html deleted file mode 100644 index 2910dffad..000000000 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html +++ /dev/null | |||
@@ -1,112 +0,0 @@ | |||
1 | <nav aria-label="breadcrumb"> | ||
2 | <ol class="breadcrumb"> | ||
3 | <li class="breadcrumb-item"> | ||
4 | <a routerLink="/my-library/video-channels" i18n>My Channels</a> | ||
5 | </li> | ||
6 | |||
7 | <ng-container *ngIf="isCreation()"> | ||
8 | <li class="breadcrumb-item active" i18n>Create</li> | ||
9 | </ng-container> | ||
10 | <ng-container *ngIf="!isCreation()"> | ||
11 | <li class="breadcrumb-item active" i18n>Edit</li> | ||
12 | <li class="breadcrumb-item active" aria-current="page"> | ||
13 | <a *ngIf="videoChannel" [routerLink]="[ '/my-library/video-channels/update', videoChannel?.nameWithHost ]">{{ videoChannel?.displayName }}</a> | ||
14 | </li> | ||
15 | </ng-container> | ||
16 | </ol> | ||
17 | </nav> | ||
18 | |||
19 | <div *ngIf="error" class="alert alert-danger">{{ error }}</div> | ||
20 | |||
21 | <form role="form" (ngSubmit)="formValidated()" [formGroup]="form"> | ||
22 | |||
23 | <div class="form-row"> <!-- channel grid --> | ||
24 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
25 | <div *ngIf="isCreation()" class="video-channel-title" i18n>NEW CHANNEL</div> | ||
26 | <div *ngIf="!isCreation() && videoChannel" class="video-channel-title" i18n>CHANNEL</div> | ||
27 | </div> | ||
28 | |||
29 | <div class="form-group col-12 col-lg-8 col-xl-9"> | ||
30 | <h6 i18n>Banner image of your channel</h6> | ||
31 | |||
32 | <my-actor-banner-edit | ||
33 | *ngIf="videoChannel" [previewImage]="isCreation()" | ||
34 | [actor]="videoChannel" (bannerChange)="onBannerChange($event)" (bannerDelete)="onBannerDelete()" | ||
35 | ></my-actor-banner-edit> | ||
36 | |||
37 | <my-actor-avatar-edit | ||
38 | *ngIf="videoChannel" [previewImage]="isCreation()" | ||
39 | [actor]="videoChannel" (avatarChange)="onAvatarChange($event)" (avatarDelete)="onAvatarDelete()" | ||
40 | [displayUsername]="!isCreation()" [displaySubscribers]="!isCreation()" | ||
41 | ></my-actor-avatar-edit> | ||
42 | |||
43 | <div class="form-group" *ngIf="isCreation()"> | ||
44 | <label i18n for="name">Name</label> | ||
45 | <div class="input-group"> | ||
46 | <input | ||
47 | type="text" id="name" i18n-placeholder placeholder="Example: my_channel" | ||
48 | formControlName="name" [ngClass]="{ 'input-error': formErrors['name'] }" class="form-control" | ||
49 | > | ||
50 | <div class="input-group-append"> | ||
51 | <span class="input-group-text">@{{ instanceHost }}</span> | ||
52 | </div> | ||
53 | </div> | ||
54 | <div *ngIf="formErrors['name']" class="form-error"> | ||
55 | {{ formErrors['name'] }} | ||
56 | </div> | ||
57 | </div> | ||
58 | |||
59 | <div class="form-group"> | ||
60 | <label i18n for="display-name">Display name</label> | ||
61 | <input | ||
62 | type="text" id="display-name" class="form-control" | ||
63 | formControlName="display-name" [ngClass]="{ 'input-error': formErrors['display-name'] }" | ||
64 | > | ||
65 | <div *ngIf="formErrors['display-name']" class="form-error"> | ||
66 | {{ formErrors['display-name'] }} | ||
67 | </div> | ||
68 | </div> | ||
69 | |||
70 | <div class="form-group"> | ||
71 | <label i18n for="description">Description</label> | ||
72 | <textarea | ||
73 | id="description" formControlName="description" class="form-control" | ||
74 | [ngClass]="{ 'input-error': formErrors['description'] }" | ||
75 | ></textarea> | ||
76 | <div *ngIf="formErrors.description" class="form-error"> | ||
77 | {{ formErrors.description }} | ||
78 | </div> | ||
79 | </div> | ||
80 | |||
81 | <div class="form-group"> | ||
82 | <label for="support">Support</label> | ||
83 | <my-help | ||
84 | helpType="markdownEnhanced" i18n-preHtml preHtml="Short text to tell people how they can support your channel (membership platform...).<br /><br /> | ||
85 | When you will upload a video in this channel, the video support field will be automatically filled by this text." | ||
86 | ></my-help> | ||
87 | <my-markdown-textarea | ||
88 | id="support" formControlName="support" textareaMaxWidth="500px" markdownType="enhanced" | ||
89 | [classes]="{ 'input-error': formErrors['support'] }" | ||
90 | ></my-markdown-textarea> | ||
91 | <div *ngIf="formErrors.support" class="form-error"> | ||
92 | {{ formErrors.support }} | ||
93 | </div> | ||
94 | </div> | ||
95 | |||
96 | <div class="form-group" *ngIf="isBulkUpdateVideosDisplayed()"> | ||
97 | <my-peertube-checkbox | ||
98 | inputName="bulkVideosSupportUpdate" formControlName="bulkVideosSupportUpdate" | ||
99 | i18n-labelText labelText="Overwrite support field of all videos of this channel" | ||
100 | ></my-peertube-checkbox> | ||
101 | </div> | ||
102 | |||
103 | </div> | ||
104 | </div> | ||
105 | |||
106 | <div class="form-row"> <!-- submit placement block --> | ||
107 | <div class="col-md-7 col-xl-5"></div> | ||
108 | <div class="col-md-5 col-xl-5 d-inline-flex"> | ||
109 | <input type="submit" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid"> | ||
110 | </div> | ||
111 | </div> | ||
112 | </form> | ||
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.scss b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.scss deleted file mode 100644 index d8bfe71b6..000000000 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.scss +++ /dev/null | |||
@@ -1,73 +0,0 @@ | |||
1 | @use '_variables' as *; | ||
2 | @use '_mixins' as *; | ||
3 | |||
4 | label { | ||
5 | font-weight: $font-regular; | ||
6 | font-size: 100%; | ||
7 | } | ||
8 | |||
9 | .video-channel-title { | ||
10 | @include settings-big-title; | ||
11 | } | ||
12 | |||
13 | my-actor-avatar-edit, | ||
14 | my-actor-banner-edit { | ||
15 | display: block; | ||
16 | margin-bottom: 20px; | ||
17 | } | ||
18 | |||
19 | my-actor-banner-edit { | ||
20 | max-width: 500px; | ||
21 | } | ||
22 | |||
23 | .input-group { | ||
24 | @include peertube-input-group(fit-content); | ||
25 | } | ||
26 | |||
27 | .input-group-append { | ||
28 | height: 30px; | ||
29 | } | ||
30 | |||
31 | input { | ||
32 | &[type=text] { | ||
33 | @include peertube-input-text(340px); | ||
34 | |||
35 | display: block; | ||
36 | |||
37 | &#name { | ||
38 | width: auto; | ||
39 | flex-grow: 1; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | &[type=submit] { | ||
44 | @include peertube-button; | ||
45 | @include orange-button; | ||
46 | @include margin-left(auto); | ||
47 | } | ||
48 | } | ||
49 | |||
50 | textarea { | ||
51 | @include peertube-textarea(500px, 150px); | ||
52 | |||
53 | display: block; | ||
54 | } | ||
55 | |||
56 | .peertube-select-container { | ||
57 | @include peertube-select-container(340px); | ||
58 | } | ||
59 | |||
60 | .breadcrumb { | ||
61 | @include breadcrumb; | ||
62 | } | ||
63 | |||
64 | @media screen and (max-width: $small-view) { | ||
65 | input[type=text]#name { | ||
66 | width: auto !important; | ||
67 | } | ||
68 | |||
69 | label[for=name] + div, | ||
70 | textarea { | ||
71 | width: 100%; | ||
72 | } | ||
73 | } | ||
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts deleted file mode 100644 index 33bb90f14..000000000 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | import { FormReactive } from '@app/shared/shared-forms' | ||
2 | import { VideoChannel } from '@app/shared/shared-main' | ||
3 | |||
4 | export abstract class MyVideoChannelEdit extends FormReactive { | ||
5 | videoChannel: VideoChannel | ||
6 | |||
7 | abstract isCreation (): boolean | ||
8 | abstract getFormButtonTitle (): string | ||
9 | |||
10 | get instanceHost () { | ||
11 | return window.location.host | ||
12 | } | ||
13 | |||
14 | // Should be implemented by the child | ||
15 | isBulkUpdateVideosDisplayed () { | ||
16 | return false | ||
17 | } | ||
18 | } | ||
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts b/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts deleted file mode 100644 index f9521b8b5..000000000 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts +++ /dev/null | |||
@@ -1,188 +0,0 @@ | |||
1 | import { Subscription } from 'rxjs' | ||
2 | import { HttpErrorResponse } from '@angular/common/http' | ||
3 | import { Component, OnDestroy, OnInit } from '@angular/core' | ||
4 | import { ActivatedRoute, Router } from '@angular/router' | ||
5 | import { AuthService, Notifier, ServerService } from '@app/core' | ||
6 | import { genericUploadErrorHandler } from '@app/helpers' | ||
7 | import { | ||
8 | VIDEO_CHANNEL_DESCRIPTION_VALIDATOR, | ||
9 | VIDEO_CHANNEL_DISPLAY_NAME_VALIDATOR, | ||
10 | VIDEO_CHANNEL_SUPPORT_VALIDATOR | ||
11 | } from '@app/shared/form-validators/video-channel-validators' | ||
12 | import { FormValidatorService } from '@app/shared/shared-forms' | ||
13 | import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' | ||
14 | import { HTMLServerConfig, VideoChannelUpdate } from '@shared/models' | ||
15 | import { MyVideoChannelEdit } from './my-video-channel-edit' | ||
16 | |||
17 | @Component({ | ||
18 | selector: 'my-video-channel-update', | ||
19 | templateUrl: './my-video-channel-edit.component.html', | ||
20 | styleUrls: [ './my-video-channel-edit.component.scss' ] | ||
21 | }) | ||
22 | export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements OnInit, OnDestroy { | ||
23 | error: string | ||
24 | videoChannel: VideoChannel | ||
25 | |||
26 | private paramsSub: Subscription | ||
27 | private oldSupportField: string | ||
28 | private serverConfig: HTMLServerConfig | ||
29 | |||
30 | constructor ( | ||
31 | protected formValidatorService: FormValidatorService, | ||
32 | private authService: AuthService, | ||
33 | private notifier: Notifier, | ||
34 | private router: Router, | ||
35 | private route: ActivatedRoute, | ||
36 | private videoChannelService: VideoChannelService, | ||
37 | private serverService: ServerService | ||
38 | ) { | ||
39 | super() | ||
40 | } | ||
41 | |||
42 | ngOnInit () { | ||
43 | this.serverConfig = this.serverService.getHTMLConfig() | ||
44 | |||
45 | this.buildForm({ | ||
46 | 'display-name': VIDEO_CHANNEL_DISPLAY_NAME_VALIDATOR, | ||
47 | description: VIDEO_CHANNEL_DESCRIPTION_VALIDATOR, | ||
48 | support: VIDEO_CHANNEL_SUPPORT_VALIDATOR, | ||
49 | bulkVideosSupportUpdate: null | ||
50 | }) | ||
51 | |||
52 | this.paramsSub = this.route.params.subscribe(routeParams => { | ||
53 | const videoChannelId = routeParams['videoChannelId'] | ||
54 | |||
55 | this.videoChannelService.getVideoChannel(videoChannelId) | ||
56 | .subscribe({ | ||
57 | next: videoChannelToUpdate => { | ||
58 | this.videoChannel = videoChannelToUpdate | ||
59 | |||
60 | this.oldSupportField = videoChannelToUpdate.support | ||
61 | |||
62 | this.form.patchValue({ | ||
63 | 'display-name': videoChannelToUpdate.displayName, | ||
64 | description: videoChannelToUpdate.description, | ||
65 | support: videoChannelToUpdate.support | ||
66 | }) | ||
67 | }, | ||
68 | |||
69 | error: err => { | ||
70 | this.error = err.message | ||
71 | } | ||
72 | }) | ||
73 | }) | ||
74 | } | ||
75 | |||
76 | ngOnDestroy () { | ||
77 | if (this.paramsSub) this.paramsSub.unsubscribe() | ||
78 | } | ||
79 | |||
80 | formValidated () { | ||
81 | this.error = undefined | ||
82 | |||
83 | const body = this.form.value | ||
84 | const videoChannelUpdate: VideoChannelUpdate = { | ||
85 | displayName: body['display-name'], | ||
86 | description: body.description || null, | ||
87 | support: body.support || null, | ||
88 | bulkVideosSupportUpdate: body.bulkVideosSupportUpdate || false | ||
89 | } | ||
90 | |||
91 | this.videoChannelService.updateVideoChannel(this.videoChannel.name, videoChannelUpdate) | ||
92 | .subscribe({ | ||
93 | next: () => { | ||
94 | this.authService.refreshUserInformation() | ||
95 | |||
96 | this.notifier.success($localize`Video channel ${videoChannelUpdate.displayName} updated.`) | ||
97 | |||
98 | this.router.navigate([ '/my-library', 'video-channels' ]) | ||
99 | }, | ||
100 | |||
101 | error: err => { | ||
102 | this.error = err.message | ||
103 | } | ||
104 | }) | ||
105 | } | ||
106 | |||
107 | onAvatarChange (formData: FormData) { | ||
108 | this.videoChannelService.changeVideoChannelImage(this.videoChannel.name, formData, 'avatar') | ||
109 | .subscribe({ | ||
110 | next: data => { | ||
111 | this.notifier.success($localize`Avatar changed.`) | ||
112 | |||
113 | this.videoChannel.updateAvatar(data.avatar) | ||
114 | }, | ||
115 | |||
116 | error: (err: HttpErrorResponse) => genericUploadErrorHandler({ | ||
117 | err, | ||
118 | name: $localize`avatar`, | ||
119 | notifier: this.notifier | ||
120 | }) | ||
121 | }) | ||
122 | } | ||
123 | |||
124 | onAvatarDelete () { | ||
125 | this.videoChannelService.deleteVideoChannelImage(this.videoChannel.name, 'avatar') | ||
126 | .subscribe({ | ||
127 | next: () => { | ||
128 | this.notifier.success($localize`Avatar deleted.`) | ||
129 | |||
130 | this.videoChannel.resetAvatar() | ||
131 | }, | ||
132 | |||
133 | error: err => this.notifier.error(err.message) | ||
134 | }) | ||
135 | } | ||
136 | |||
137 | onBannerChange (formData: FormData) { | ||
138 | this.videoChannelService.changeVideoChannelImage(this.videoChannel.name, formData, 'banner') | ||
139 | .subscribe({ | ||
140 | next: data => { | ||
141 | this.notifier.success($localize`Banner changed.`) | ||
142 | |||
143 | this.videoChannel.updateBanner(data.banner) | ||
144 | }, | ||
145 | |||
146 | error: (err: HttpErrorResponse) => genericUploadErrorHandler({ | ||
147 | err, | ||
148 | name: $localize`banner`, | ||
149 | notifier: this.notifier | ||
150 | }) | ||
151 | }) | ||
152 | } | ||
153 | |||
154 | onBannerDelete () { | ||
155 | this.videoChannelService.deleteVideoChannelImage(this.videoChannel.name, 'banner') | ||
156 | .subscribe({ | ||
157 | next: () => { | ||
158 | this.notifier.success($localize`Banner deleted.`) | ||
159 | |||
160 | this.videoChannel.resetBanner() | ||
161 | }, | ||
162 | |||
163 | error: err => this.notifier.error(err.message) | ||
164 | }) | ||
165 | } | ||
166 | |||
167 | get maxAvatarSize () { | ||
168 | return this.serverConfig.avatar.file.size.max | ||
169 | } | ||
170 | |||
171 | get avatarExtensions () { | ||
172 | return this.serverConfig.avatar.file.extensions.join(',') | ||
173 | } | ||
174 | |||
175 | isCreation () { | ||
176 | return false | ||
177 | } | ||
178 | |||
179 | getFormButtonTitle () { | ||
180 | return $localize`Update` | ||
181 | } | ||
182 | |||
183 | isBulkUpdateVideosDisplayed () { | ||
184 | if (this.oldSupportField === undefined) return false | ||
185 | |||
186 | return this.oldSupportField !== this.form.value['support'] | ||
187 | } | ||
188 | } | ||
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels-routing.module.ts b/client/src/app/+my-library/+my-video-channels/my-video-channels-routing.module.ts index 6b8efad0b..b4962ed35 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channels-routing.module.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channels-routing.module.ts | |||
@@ -1,7 +1,5 @@ | |||
1 | import { NgModule } from '@angular/core' | 1 | import { NgModule } from '@angular/core' |
2 | import { RouterModule, Routes } from '@angular/router' | 2 | import { RouterModule, Routes } from '@angular/router' |
3 | import { MyVideoChannelUpdateComponent } from './my-video-channel-update.component' | ||
4 | import { MyVideoChannelCreateComponent } from './my-video-channel-create.component' | ||
5 | import { MyVideoChannelsComponent } from './my-video-channels.component' | 3 | import { MyVideoChannelsComponent } from './my-video-channels.component' |
6 | 4 | ||
7 | const myVideoChannelsRoutes: Routes = [ | 5 | const myVideoChannelsRoutes: Routes = [ |
@@ -16,21 +14,11 @@ const myVideoChannelsRoutes: Routes = [ | |||
16 | }, | 14 | }, |
17 | { | 15 | { |
18 | path: 'create', | 16 | path: 'create', |
19 | component: MyVideoChannelCreateComponent, | 17 | redirectTo: '/manage/create' |
20 | data: { | ||
21 | meta: { | ||
22 | title: $localize`Create a new video channel` | ||
23 | } | ||
24 | } | ||
25 | }, | 18 | }, |
26 | { | 19 | { |
27 | path: 'update/:videoChannelId', | 20 | path: 'update/:videoChannelName', |
28 | component: MyVideoChannelUpdateComponent, | 21 | redirectTo: '/manage/update/:videoChannelName' |
29 | data: { | ||
30 | meta: { | ||
31 | title: $localize`Update video channel` | ||
32 | } | ||
33 | } | ||
34 | } | 22 | } |
35 | ] | 23 | ] |
36 | 24 | ||
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html index bbe583971..77947315b 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html +++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html | |||
@@ -9,7 +9,7 @@ | |||
9 | <div class="video-channels-header d-flex justify-content-between"> | 9 | <div class="video-channels-header d-flex justify-content-between"> |
10 | <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter> | 10 | <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter> |
11 | 11 | ||
12 | <a class="create-button" routerLink="create"> | 12 | <a class="create-button" routerLink="/manage/create"> |
13 | <my-global-icon iconName="add" aria-hidden="true"></my-global-icon> | 13 | <my-global-icon iconName="add" aria-hidden="true"></my-global-icon> |
14 | <ng-container i18n>Create video channel</ng-container> | 14 | <ng-container i18n>Create video channel</ng-container> |
15 | </a> | 15 | </a> |
@@ -37,7 +37,7 @@ | |||
37 | <div i18n class="video-channel-videos">{videoChannel.videosCount, plural, =0 {No videos} =1 {1 video} other {{{ videoChannel.videosCount }} videos}}</div> | 37 | <div i18n class="video-channel-videos">{videoChannel.videosCount, plural, =0 {No videos} =1 {1 video} other {{{ videoChannel.videosCount }} videos}}</div> |
38 | 38 | ||
39 | <div class="video-channel-buttons"> | 39 | <div class="video-channel-buttons"> |
40 | <my-edit-button label [routerLink]="[ 'update', videoChannel.nameWithHost ]"></my-edit-button> | 40 | <my-edit-button label [routerLink]="[ '/manage/update', videoChannel.nameWithHost ]"></my-edit-button> |
41 | <my-delete-button label (click)="deleteVideoChannel(videoChannel)"></my-delete-button> | 41 | <my-delete-button label (click)="deleteVideoChannel(videoChannel)"></my-delete-button> |
42 | </div> | 42 | </div> |
43 | 43 | ||
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts b/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts index c775bfdee..a17eb9f10 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts | |||
@@ -1,11 +1,8 @@ | |||
1 | import { ChartModule } from 'primeng/chart' | 1 | import { ChartModule } from 'primeng/chart' |
2 | import { NgModule } from '@angular/core' | 2 | import { NgModule } from '@angular/core' |
3 | import { SharedActorImageEditModule } from '@app/shared/shared-actor-image-edit' | ||
4 | import { SharedFormModule } from '@app/shared/shared-forms' | 3 | import { SharedFormModule } from '@app/shared/shared-forms' |
5 | import { SharedGlobalIconModule } from '@app/shared/shared-icons' | 4 | import { SharedGlobalIconModule } from '@app/shared/shared-icons' |
6 | import { SharedMainModule } from '@app/shared/shared-main' | 5 | import { SharedMainModule } from '@app/shared/shared-main' |
7 | import { MyVideoChannelCreateComponent } from './my-video-channel-create.component' | ||
8 | import { MyVideoChannelUpdateComponent } from './my-video-channel-update.component' | ||
9 | import { MyVideoChannelsRoutingModule } from './my-video-channels-routing.module' | 6 | import { MyVideoChannelsRoutingModule } from './my-video-channels-routing.module' |
10 | import { MyVideoChannelsComponent } from './my-video-channels.component' | 7 | import { MyVideoChannelsComponent } from './my-video-channels.component' |
11 | import { SharedActorImageModule } from '@app/shared/shared-actor-image/shared-actor-image.module' | 8 | import { SharedActorImageModule } from '@app/shared/shared-actor-image/shared-actor-image.module' |
@@ -19,14 +16,11 @@ import { SharedActorImageModule } from '@app/shared/shared-actor-image/shared-ac | |||
19 | SharedMainModule, | 16 | SharedMainModule, |
20 | SharedFormModule, | 17 | SharedFormModule, |
21 | SharedGlobalIconModule, | 18 | SharedGlobalIconModule, |
22 | SharedActorImageEditModule, | ||
23 | SharedActorImageModule | 19 | SharedActorImageModule |
24 | ], | 20 | ], |
25 | 21 | ||
26 | declarations: [ | 22 | declarations: [ |
27 | MyVideoChannelsComponent, | 23 | MyVideoChannelsComponent |
28 | MyVideoChannelCreateComponent, | ||
29 | MyVideoChannelUpdateComponent | ||
30 | ], | 24 | ], |
31 | 25 | ||
32 | exports: [], | 26 | exports: [], |