From: Chocobozzz Date: Wed, 9 May 2018 07:26:41 +0000 (+0200) Subject: Load my-account module lazily X-Git-Tag: v1.0.0-beta.5~60 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=62e62f118d5da57acd3494fece2e8ed357564ffe;p=oweals%2Fpeertube.git Load my-account module lazily --- diff --git a/client/src/app/+my-account/index.ts b/client/src/app/+my-account/index.ts new file mode 100644 index 000000000..3df96dd7a --- /dev/null +++ b/client/src/app/+my-account/index.ts @@ -0,0 +1,3 @@ +export * from './my-account-routing.module' +export * from './my-account.component' +export * from './my-account.module' diff --git a/client/src/app/+my-account/my-account-routing.module.ts b/client/src/app/+my-account/my-account-routing.module.ts new file mode 100644 index 000000000..7e19cd994 --- /dev/null +++ b/client/src/app/+my-account/my-account-routing.module.ts @@ -0,0 +1,71 @@ +import { NgModule } from '@angular/core' +import { RouterModule, Routes } from '@angular/router' +import { MetaGuard } from '@ngx-meta/core' +import { LoginGuard } from '../core' +import { MyAccountComponent } from './my-account.component' +import { MyAccountSettingsComponent } from './my-account-settings/my-account-settings.component' +import { MyAccountVideosComponent } from './my-account-videos/my-account-videos.component' +import { MyAccountVideoChannelsComponent } from '@app/+my-account/my-account-video-channels/my-account-video-channels.component' +import { MyAccountVideoChannelCreateComponent } from '@app/+my-account/my-account-video-channels/my-account-video-channel-create.component' +import { MyAccountVideoChannelUpdateComponent } from '@app/+my-account/my-account-video-channels/my-account-video-channel-update.component' + +const myAccountRoutes: Routes = [ + { + path: '', + component: MyAccountComponent, + canActivateChild: [ MetaGuard, LoginGuard ], + children: [ + { + path: 'settings', + component: MyAccountSettingsComponent, + data: { + meta: { + title: 'Account settings' + } + } + }, + { + path: 'video-channels', + component: MyAccountVideoChannelsComponent, + data: { + meta: { + title: 'Account video channels' + } + } + }, + { + path: 'video-channels/create', + component: MyAccountVideoChannelCreateComponent, + data: { + meta: { + title: 'Create new video channel' + } + } + }, + { + path: 'video-channels/update/:videoChannelId', + component: MyAccountVideoChannelUpdateComponent, + data: { + meta: { + title: 'Update video channel' + } + } + }, + { + path: 'videos', + component: MyAccountVideosComponent, + data: { + meta: { + title: 'Account videos' + } + } + } + ] + } +] + +@NgModule({ + imports: [ RouterModule.forChild(myAccountRoutes) ], + exports: [ RouterModule ] +}) +export class MyAccountRoutingModule {} diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-password/index.ts b/client/src/app/+my-account/my-account-settings/my-account-change-password/index.ts new file mode 100644 index 000000000..644047c5f --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-change-password/index.ts @@ -0,0 +1 @@ +export * from './my-account-change-password.component' diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html new file mode 100644 index 000000000..b0e3cada4 --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html @@ -0,0 +1,20 @@ +
{{ error }}
+ +
+ + + +
+ {{ formErrors['new-password'] }} +
+ + + + +
diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.scss b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.scss new file mode 100644 index 000000000..f8279ffd3 --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.scss @@ -0,0 +1,19 @@ +@import '_variables'; +@import '_mixins'; + +input[type=password] { + @include peertube-input-text(340px); + display: block; + + &#new-confirmed-password { + margin-top: 15px; + } +} + +input[type=submit] { + @include peertube-button; + @include orange-button; + + margin-top: 15px; +} + diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts new file mode 100644 index 000000000..80af668f9 --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts @@ -0,0 +1,62 @@ +import { Component, OnInit } from '@angular/core' +import { FormBuilder, FormGroup } from '@angular/forms' +import { NotificationsService } from 'angular2-notifications' +import { FormReactive, USER_PASSWORD, UserService } from '../../../shared' + +@Component({ + selector: 'my-account-change-password', + templateUrl: './my-account-change-password.component.html', + styleUrls: [ './my-account-change-password.component.scss' ] +}) +export class MyAccountChangePasswordComponent extends FormReactive implements OnInit { + error: string = null + + form: FormGroup + formErrors = { + 'new-password': '', + 'new-confirmed-password': '' + } + validationMessages = { + 'new-password': USER_PASSWORD.MESSAGES, + 'new-confirmed-password': USER_PASSWORD.MESSAGES + } + + constructor ( + private formBuilder: FormBuilder, + private notificationsService: NotificationsService, + private userService: UserService + ) { + super() + } + + buildForm () { + this.form = this.formBuilder.group({ + 'new-password': [ '', USER_PASSWORD.VALIDATORS ], + 'new-confirmed-password': [ '', USER_PASSWORD.VALIDATORS ] + }) + + this.form.valueChanges.subscribe(data => this.onValueChanged(data)) + } + + ngOnInit () { + this.buildForm() + } + + changePassword () { + const newPassword = this.form.value['new-password'] + const newConfirmedPassword = this.form.value['new-confirmed-password'] + + this.error = null + + if (newPassword !== newConfirmedPassword) { + this.error = 'The new password and the confirmed password do not correspond.' + return + } + + this.userService.changePassword(newPassword).subscribe( + () => this.notificationsService.success('Success', 'Password updated.'), + + err => this.error = err.message + ) + } +} diff --git a/client/src/app/+my-account/my-account-settings/my-account-profile/index.ts b/client/src/app/+my-account/my-account-settings/my-account-profile/index.ts new file mode 100644 index 000000000..3cc049f8f --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-profile/index.ts @@ -0,0 +1 @@ +export * from './my-account-profile.component' diff --git a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.html b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.html new file mode 100644 index 000000000..306f3a12c --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.html @@ -0,0 +1,24 @@ +
{{ error }}
+ +
+ + + +
+ {{ formErrors['display-name'] }} +
+ + + +
+ {{ formErrors.description }} +
+ + +
diff --git a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.scss b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.scss new file mode 100644 index 000000000..fc2b92c89 --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.scss @@ -0,0 +1,23 @@ +@import '_variables'; +@import '_mixins'; + +input[type=text] { + @include peertube-input-text(340px); + + display: block; + margin-bottom: 15px; +} + +textarea { + @include peertube-textarea(500px, 150px); + + display: block; +} + +input[type=submit] { + @include peertube-button; + @include orange-button; + + margin-top: 15px; +} + diff --git a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts new file mode 100644 index 000000000..2b7ba353c --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts @@ -0,0 +1,65 @@ +import { Component, Input, OnInit } from '@angular/core' +import { FormBuilder, FormGroup } from '@angular/forms' +import { NotificationsService } from 'angular2-notifications' +import { FormReactive, USER_DESCRIPTION, USER_DISPLAY_NAME, UserService } from '../../../shared' +import { User } from '@app/shared' + +@Component({ + selector: 'my-account-profile', + templateUrl: './my-account-profile.component.html', + styleUrls: [ './my-account-profile.component.scss' ] +}) +export class MyAccountProfileComponent extends FormReactive implements OnInit { + @Input() user: User = null + + error: string = null + + form: FormGroup + formErrors = { + 'display-name': '', + 'description': '' + } + validationMessages = { + 'display-name': USER_DISPLAY_NAME.MESSAGES, + 'description': USER_DESCRIPTION.MESSAGES + } + + constructor ( + private formBuilder: FormBuilder, + private notificationsService: NotificationsService, + private userService: UserService + ) { + super() + } + + buildForm () { + this.form = this.formBuilder.group({ + 'display-name': [ this.user.account.displayName, USER_DISPLAY_NAME.VALIDATORS ], + 'description': [ this.user.account.description, USER_DESCRIPTION.VALIDATORS ] + }) + + this.form.valueChanges.subscribe(data => this.onValueChanged(data)) + } + + ngOnInit () { + this.buildForm() + } + + updateMyProfile () { + const displayName = this.form.value['display-name'] + const description = this.form.value['description'] + + this.error = null + + this.userService.updateMyProfile({ displayName, description }).subscribe( + () => { + this.user.account.displayName = displayName + this.user.account.description = description + + this.notificationsService.success('Success', 'Profile updated.') + }, + + err => this.error = err.message + ) + } +} diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.html b/client/src/app/+my-account/my-account-settings/my-account-settings.component.html new file mode 100644 index 000000000..0fcc7782e --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.html @@ -0,0 +1,32 @@ +
+ Avatar + + +
+ +
+ Change your avatar + +
+
(extensions: {{ avatarExtensions }}, max size: {{ maxAvatarSize | bytes }})
+ +
+ Video quota: {{ userVideoQuotaUsed | bytes: 0 }} / {{ userVideoQuota }} +
+ + + + + + +
Password
+ + +
Video settings
+ diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.scss b/client/src/app/+my-account/my-account-settings/my-account-settings.component.scss new file mode 100644 index 000000000..ec0d40b93 --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.scss @@ -0,0 +1,67 @@ +@import '_variables'; +@import '_mixins'; + +.user { + display: flex; + + img { + @include avatar(50px); + + margin-right: 15px; + } + + .user-info { + .user-info-names { + display: flex; + align-items: center; + + .user-info-display-name { + font-size: 20px; + font-weight: $font-bold; + } + + .user-info-username { + margin-left: 7px; + position: relative; + top: 2px; + font-size: 14px; + color: #777272; + } + } + + .user-info-followers { + font-size: 15px; + } + } +} + +.button-file { + @include peertube-button-file(160px); + + margin-top: 10px; + margin-bottom: 5px; +} + +.file-max-size { + display: inline-block; + font-size: 13px; + + position: relative; + top: -10px; +} + +.user-quota { + font-size: 15px; + margin-top: 20px; + + .user-quota-label { + font-weight: $font-semibold; + } +} + +.account-title { + @include in-content-small-title; + + margin-top: 55px; + margin-bottom: 30px; +} diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts new file mode 100644 index 000000000..06d1138e7 --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts @@ -0,0 +1,70 @@ +import { Component, OnInit, ViewChild } from '@angular/core' +import { NotificationsService } from 'angular2-notifications' +import { BytesPipe } from 'ngx-pipes' +import { AuthService } from '../../core' +import { ServerService } from '../../core/server' +import { User } from '../../shared' +import { UserService } from '../../shared/users' + +@Component({ + selector: 'my-account-settings', + templateUrl: './my-account-settings.component.html', + styleUrls: [ './my-account-settings.component.scss' ] +}) +export class MyAccountSettingsComponent implements OnInit { + @ViewChild('avatarfileInput') avatarfileInput + + user: User = null + userVideoQuota = '0' + userVideoQuotaUsed = 0 + + constructor ( + private userService: UserService, + private authService: AuthService, + private serverService: ServerService, + private notificationsService: NotificationsService + ) {} + + ngOnInit () { + this.user = this.authService.getUser() + + this.authService.userInformationLoaded.subscribe( + () => { + if (this.user.videoQuota !== -1) { + this.userVideoQuota = new BytesPipe().transform(this.user.videoQuota, 0).toString() + } else { + this.userVideoQuota = 'Unlimited' + } + } + ) + + this.userService.getMyVideoQuotaUsed() + .subscribe(data => this.userVideoQuotaUsed = data.videoQuotaUsed) + } + + changeAvatar () { + const avatarfile = this.avatarfileInput.nativeElement.files[ 0 ] + + const formData = new FormData() + formData.append('avatarfile', avatarfile) + + this.userService.changeAvatar(formData) + .subscribe( + data => { + this.notificationsService.success('Success', 'Avatar changed.') + + this.user.account.avatar = data.avatar + }, + + err => this.notificationsService.error('Error', err.message) + ) + } + + get maxAvatarSize () { + return this.serverService.getConfig().avatar.file.size.max + } + + get avatarExtensions () { + return this.serverService.getConfig().avatar.file.extensions.join(',') + } +} diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/index.ts b/client/src/app/+my-account/my-account-settings/my-account-video-settings/index.ts new file mode 100644 index 000000000..1253bd369 --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/index.ts @@ -0,0 +1 @@ +export * from './my-account-video-settings.component' diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html new file mode 100644 index 000000000..0e8598e9e --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html @@ -0,0 +1,25 @@ +
+
+ + + +
+ +
+
+ +
+ + + +
+ + +
diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.scss b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.scss new file mode 100644 index 000000000..ed59e4689 --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.scss @@ -0,0 +1,20 @@ +@import '_variables'; +@import '_mixins'; + +input[type=checkbox] { + @include peertube-checkbox(1px); +} + +input[type=submit] { + @include peertube-button; + @include orange-button; + + display: block; + margin-top: 15px; +} + +.peertube-select-container { + @include peertube-select-container(340px); + + margin-bottom: 30px; +} \ No newline at end of file diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts new file mode 100644 index 000000000..acc70c14d --- /dev/null +++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts @@ -0,0 +1,60 @@ +import { Component, Input, OnInit } from '@angular/core' +import { FormBuilder, FormGroup } from '@angular/forms' +import { NotificationsService } from 'angular2-notifications' +import { UserUpdateMe } from '../../../../../../shared' +import { AuthService } from '../../../core' +import { FormReactive, User, UserService } from '../../../shared' + +@Component({ + selector: 'my-account-video-settings', + templateUrl: './my-account-video-settings.component.html', + styleUrls: [ './my-account-video-settings.component.scss' ] +}) +export class MyAccountVideoSettingsComponent extends FormReactive implements OnInit { + @Input() user: User = null + + form: FormGroup + formErrors = {} + validationMessages = {} + + constructor ( + private authService: AuthService, + private formBuilder: FormBuilder, + private notificationsService: NotificationsService, + private userService: UserService + ) { + super() + } + + buildForm () { + this.form = this.formBuilder.group({ + nsfwPolicy: [ this.user.nsfwPolicy ], + autoPlayVideo: [ this.user.autoPlayVideo ] + }) + + this.form.valueChanges.subscribe(data => this.onValueChanged(data)) + } + + ngOnInit () { + this.buildForm() + } + + updateDetails () { + const nsfwPolicy = this.form.value['nsfwPolicy'] + const autoPlayVideo = this.form.value['autoPlayVideo'] + const details: UserUpdateMe = { + nsfwPolicy, + autoPlayVideo + } + + this.userService.updateMyProfile(details).subscribe( + () => { + this.notificationsService.success('Success', 'Information updated.') + + this.authService.refreshUserInformation() + }, + + err => this.notificationsService.error('Error', err.message) + ) + } +} 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 new file mode 100644 index 000000000..0f03548ad --- /dev/null +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts @@ -0,0 +1,89 @@ +import { Component, OnInit } from '@angular/core' +import { Router } from '@angular/router' +import { NotificationsService } from 'angular2-notifications' +import 'rxjs/add/observable/from' +import 'rxjs/add/operator/concatAll' +import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' +import { FormBuilder, FormGroup } from '@angular/forms' +import { VideoChannelCreate } from '../../../../../shared/models/videos' +import { + VIDEO_CHANNEL_DESCRIPTION, + VIDEO_CHANNEL_DISPLAY_NAME, + VIDEO_CHANNEL_SUPPORT +} from '@app/shared/forms/form-validators/video-channel' +import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' +import { AuthService } from '@app/core' + +@Component({ + selector: 'my-account-video-channel-create', + templateUrl: './my-account-video-channel-edit.component.html', + styleUrls: [ './my-account-video-channel-edit.component.scss' ] +}) +export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelEdit implements OnInit { + error: string + + form: FormGroup + formErrors = { + 'display-name': '', + 'description': '', + 'support': '' + } + validationMessages = { + 'display-name': VIDEO_CHANNEL_DISPLAY_NAME.MESSAGES, + 'description': VIDEO_CHANNEL_DESCRIPTION.MESSAGES, + 'support': VIDEO_CHANNEL_SUPPORT.MESSAGES + } + + constructor ( + private authService: AuthService, + private notificationsService: NotificationsService, + private router: Router, + private formBuilder: FormBuilder, + private videoChannelService: VideoChannelService + ) { + super() + } + + buildForm () { + this.form = this.formBuilder.group({ + 'display-name': [ '', VIDEO_CHANNEL_DISPLAY_NAME.VALIDATORS ], + description: [ '', VIDEO_CHANNEL_DESCRIPTION.VALIDATORS ], + support: [ '', VIDEO_CHANNEL_SUPPORT.VALIDATORS ] + }) + + this.form.valueChanges.subscribe(data => this.onValueChanged(data)) + } + + ngOnInit () { + this.buildForm() + } + + formValidated () { + this.error = undefined + + const body = this.form.value + const videoChannelCreate: VideoChannelCreate = { + displayName: body['display-name'], + description: body.description || undefined, + support: body.support || undefined + } + + this.videoChannelService.createVideoChannel(videoChannelCreate).subscribe( + () => { + this.authService.refreshUserInformation() + this.notificationsService.success('Success', `Video channel ${videoChannelCreate.displayName} created.`) + this.router.navigate([ '/my-account', 'video-channels' ]) + }, + + err => this.error = err.message + ) + } + + isCreation () { + return true + } + + getFormButtonTitle () { + return 'Create' + } +} 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 new file mode 100644 index 000000000..d5fb6262a --- /dev/null +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html @@ -0,0 +1,42 @@ +
Create a video channel
+
Update {{ videoChannel?.displayName }}
+ +
{{ error }}
+ +
+
+ + +
+ {{ formErrors['display-name'] }} +
+
+ +
+ + +
+ {{ formErrors.description }} +
+
+ +
+ + + +
+ {{ formErrors.support }} +
+
+ + +
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 new file mode 100644 index 000000000..6fbb8ae8b --- /dev/null +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.scss @@ -0,0 +1,27 @@ +@import '_variables'; +@import '_mixins'; + +.form-sub-title { + margin-bottom: 20px; +} + +input[type=text] { + @include peertube-input-text(340px); + + display: block; +} + +textarea { + @include peertube-textarea(500px, 150px); + + display: block; +} + +.peertube-select-container { + @include peertube-select-container(340px); +} + +input[type=submit] { + @include peertube-button; + @include orange-button; +} \ No newline at end of file diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.ts new file mode 100644 index 000000000..e56f46262 --- /dev/null +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.ts @@ -0,0 +1,6 @@ +import { FormReactive } from '@app/shared' + +export abstract class MyAccountVideoChannelEdit extends FormReactive { + abstract isCreation (): boolean + abstract getFormButtonTitle (): string +} diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts new file mode 100644 index 000000000..c0dc6a939 --- /dev/null +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts @@ -0,0 +1,117 @@ +import { Component, OnInit, OnDestroy } from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' +import { NotificationsService } from 'angular2-notifications' +import 'rxjs/add/observable/from' +import 'rxjs/add/operator/concatAll' +import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' +import { FormBuilder, FormGroup } from '@angular/forms' +import { VideoChannelUpdate } from '../../../../../shared/models/videos' +import { + VIDEO_CHANNEL_DESCRIPTION, + VIDEO_CHANNEL_DISPLAY_NAME, + VIDEO_CHANNEL_SUPPORT +} from '@app/shared/forms/form-validators/video-channel' +import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' +import { Subscription } from 'rxjs/Subscription' +import { VideoChannel } from '@app/shared/video-channel/video-channel.model' +import { AuthService } from '@app/core' + +@Component({ + selector: 'my-account-video-channel-update', + templateUrl: './my-account-video-channel-edit.component.html', + styleUrls: [ './my-account-video-channel-edit.component.scss' ] +}) +export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelEdit implements OnInit, OnDestroy { + error: string + + form: FormGroup + formErrors = { + 'display-name': '', + 'description': '', + 'support': '' + } + validationMessages = { + 'display-name': VIDEO_CHANNEL_DISPLAY_NAME.MESSAGES, + 'description': VIDEO_CHANNEL_DESCRIPTION.MESSAGES, + 'support': VIDEO_CHANNEL_SUPPORT.MESSAGES + } + + private videoChannelToUpdate: VideoChannel + private paramsSub: Subscription + + constructor ( + private authService: AuthService, + private notificationsService: NotificationsService, + private router: Router, + private route: ActivatedRoute, + private formBuilder: FormBuilder, + private videoChannelService: VideoChannelService + ) { + super() + } + + buildForm () { + this.form = this.formBuilder.group({ + 'display-name': [ '', VIDEO_CHANNEL_DISPLAY_NAME.VALIDATORS ], + description: [ '', VIDEO_CHANNEL_DESCRIPTION.VALIDATORS ], + support: [ '', VIDEO_CHANNEL_SUPPORT.VALIDATORS ] + }) + + this.form.valueChanges.subscribe(data => this.onValueChanged(data)) + } + + ngOnInit () { + this.buildForm() + + this.paramsSub = this.route.params.subscribe(routeParams => { + const videoChannelId = routeParams['videoChannelId'] + + this.videoChannelService.getVideoChannel(videoChannelId).subscribe( + videoChannelToUpdate => { + this.videoChannelToUpdate = videoChannelToUpdate + + this.form.patchValue({ + 'display-name': videoChannelToUpdate.displayName, + description: videoChannelToUpdate.description, + support: videoChannelToUpdate.support + }) + }, + + err => this.error = err.message + ) + }) + } + + ngOnDestroy () { + if (this.paramsSub) this.paramsSub.unsubscribe() + } + + formValidated () { + this.error = undefined + + const body = this.form.value + const videoChannelUpdate: VideoChannelUpdate = { + displayName: body['display-name'], + description: body.description || undefined, + support: body.support || undefined + } + + this.videoChannelService.updateVideoChannel(this.videoChannelToUpdate.uuid, videoChannelUpdate).subscribe( + () => { + this.authService.refreshUserInformation() + this.notificationsService.success('Success', `Video channel ${videoChannelUpdate.displayName} updated.`) + this.router.navigate([ '/my-account', 'video-channels' ]) + }, + + err => this.error = err.message + ) + } + + isCreation () { + return false + } + + getFormButtonTitle () { + return 'Update' + } +} 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 new file mode 100644 index 000000000..90c401bc5 --- /dev/null +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html @@ -0,0 +1,30 @@ +
+ + + Create another video channel + +
+ +
+
+ + Avatar + + +
+ +
{{ videoChannel.displayName }}
+ + +
+ +
{{ videoChannel.followersCount }} subscribers
+
+ +
+ + + +
+
+
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 new file mode 100644 index 000000000..bcb58eac2 --- /dev/null +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.scss @@ -0,0 +1,72 @@ +@import '_variables'; +@import '_mixins'; + +.create-button { + @include create-button; +} + +/deep/ .action-button { + &.action-button-delete { + margin-right: 10px; + } +} + +.video-channel { + display: flex; + min-height: 130px; + padding-bottom: 20px; + margin-bottom: 20px; + border-bottom: 1px solid #C6C6C6; + + img { + @include avatar(80px); + + margin-right: 10px; + } + + .video-channel-info { + flex-grow: 1; + + a.video-channel-names { + @include disable-default-a-behaviour; + + display: flex; + color: #000; + + .video-channel-display-name { + font-weight: $font-semibold; + font-size: 18px; + } + + .video-channel-name { + font-size: 14px; + color: #777272; + } + } + } + + .video-channel-buttons { + min-width: 190px; + } +} + +.video-channels-header { + text-align: right; + margin: 20px 0 50px; +} + +@media screen and (max-width: 800px) { + .video-channel { + flex-direction: column; + height: auto; + text-align: center; + + img { + margin-right: 0; + } + + .video-channel-buttons { + margin-top: 10px; + } + } +} diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts new file mode 100644 index 000000000..eeaca11df --- /dev/null +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts @@ -0,0 +1,59 @@ +import { Component, OnInit } from '@angular/core' +import { NotificationsService } from 'angular2-notifications' +import 'rxjs/add/observable/from' +import 'rxjs/add/operator/concatAll' +import { AuthService } from '../../core/auth' +import { ConfirmService } from '../../core/confirm' +import { VideoChannel } from '@app/shared/video-channel/video-channel.model' +import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' +import { User } from '@app/shared' + +@Component({ + selector: 'my-account-video-channels', + templateUrl: './my-account-video-channels.component.html', + styleUrls: [ './my-account-video-channels.component.scss' ] +}) +export class MyAccountVideoChannelsComponent implements OnInit { + videoChannels: VideoChannel[] = [] + + private user: User + + constructor ( + private authService: AuthService, + private notificationsService: NotificationsService, + private confirmService: ConfirmService, + private videoChannelService: VideoChannelService + ) {} + + ngOnInit () { + this.user = this.authService.getUser() + + this.loadVideoChannels() + } + + async deleteVideoChannel (videoChannel: VideoChannel) { + const res = await this.confirmService.confirmWithInput( + `Do you really want to delete ${videoChannel.displayName}? It will delete all videos uploaded in this channel too.`, + 'Please type the name of the video channel to confirm', + videoChannel.displayName, + 'Delete' + ) + if (res === false) return + + this.videoChannelService.removeVideoChannel(videoChannel) + .subscribe( + status => { + this.loadVideoChannels() + this.notificationsService.success('Success', `Video channel ${videoChannel.name} deleted.`) + }, + + error => this.notificationsService.error('Error', error.message) + ) + } + + private loadVideoChannels () { + this.authService.userInformationLoaded + .flatMap(() => this.videoChannelService.listAccountVideoChannels(this.user.account.id)) + .subscribe(res => this.videoChannels = res.data) + } +} diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html new file mode 100644 index 000000000..66ce3a77b --- /dev/null +++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html @@ -0,0 +1,45 @@ +
No results.
+ +
+
+
+
+ + +
+ + + +
+ {{ video.name }} + {{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views +
{{ video.privacy.label }}
+
+ + +
+
+ + Cancel + + + + + Delete + +
+
+ +
+ + + +
+
+
+
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss b/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss new file mode 100644 index 000000000..f276ea389 --- /dev/null +++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss @@ -0,0 +1,114 @@ +@import '_variables'; +@import '_mixins'; + +.action-selection-mode { + width: 174px; + display: flex; + justify-content: flex-end; + + .action-selection-mode-child { + position: fixed; + + .action-button { + display: inline-block; + } + + .action-button-cancel-selection { + @include peertube-button; + @include grey-button; + + margin-right: 10px; + } + + .action-button-delete-selection { + @include peertube-button; + @include orange-button; + } + + .icon.icon-delete-white { + @include icon(21px); + + position: relative; + top: -2px; + background-image: url('../../../assets/images/global/delete-white.svg'); + } + } +} + +/deep/ .action-button { + &.action-button-delete { + margin-right: 10px; + } +} + +.video { + display: flex; + min-height: 130px; + padding-bottom: 20px; + margin-bottom: 20px; + border-bottom: 1px solid #C6C6C6; + + &:first-child { + margin-top: 47px; + } + + .checkbox-container { + display: flex; + align-items: center; + margin-right: 20px; + margin-left: 12px; + + input[type=checkbox] { + @include peertube-checkbox(2px); + } + } + + my-video-thumbnail { + margin-right: 10px; + } + + .video-info { + flex-grow: 1; + + .video-info-name { + @include disable-default-a-behaviour; + + color: #000; + display: block; + font-size: 16px; + font-weight: $font-semibold; + } + + .video-info-date-views, .video-info-private { + font-size: 13px; + + &.video-info-private { + font-weight: $font-semibold; + } + } + } + + .video-buttons { + min-width: 190px; + } +} + +@media screen and (max-width: 800px) { + .video { + flex-direction: column; + height: auto; + text-align: center; + + input[type=checkbox] { + display: none; + } + + my-video-thumbnail { + margin-right: 0; + } + + .video-buttons { + margin-top: 10px; + } + } +} diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts b/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts new file mode 100644 index 000000000..c1b53bcd5 --- /dev/null +++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts @@ -0,0 +1,131 @@ +import { Component, OnInit, OnDestroy } from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' +import { Location } from '@angular/common' +import { immutableAssign } from '@app/shared/misc/utils' +import { ComponentPagination } from '@app/shared/rest/component-pagination.model' +import { NotificationsService } from 'angular2-notifications' +import 'rxjs/add/observable/from' +import 'rxjs/add/operator/concatAll' +import { Observable } from 'rxjs/Observable' +import { AuthService } from '../../core/auth' +import { ConfirmService } from '../../core/confirm' +import { AbstractVideoList } from '../../shared/video/abstract-video-list' +import { Video } from '../../shared/video/video.model' +import { VideoService } from '../../shared/video/video.service' + +@Component({ + selector: 'my-account-videos', + templateUrl: './my-account-videos.component.html', + styleUrls: [ './my-account-videos.component.scss' ] +}) +export class MyAccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { + titlePage = 'My videos' + currentRoute = '/my-account/videos' + checkedVideos: { [ id: number ]: boolean } = {} + pagination: ComponentPagination = { + currentPage: 1, + itemsPerPage: 5, + totalItems: null + } + + protected baseVideoWidth = -1 + protected baseVideoHeight = 155 + + constructor (protected router: Router, + protected route: ActivatedRoute, + protected authService: AuthService, + protected notificationsService: NotificationsService, + protected confirmService: ConfirmService, + protected location: Location, + private videoService: VideoService) { + super() + } + + ngOnInit () { + super.ngOnInit() + } + + ngOnDestroy () { + super.ngOnDestroy() + } + + abortSelectionMode () { + this.checkedVideos = {} + } + + isInSelectionMode () { + return Object.keys(this.checkedVideos).some(k => this.checkedVideos[k] === true) + } + + getVideosObservable (page: number) { + const newPagination = immutableAssign(this.pagination, { currentPage: page }) + + return this.videoService.getMyVideos(newPagination, this.sort) + } + + generateSyndicationList () { + throw new Error('Method not implemented.') + } + + async deleteSelectedVideos () { + const toDeleteVideosIds = Object.keys(this.checkedVideos) + .filter(k => this.checkedVideos[k] === true) + .map(k => parseInt(k, 10)) + + const res = await this.confirmService.confirm(`Do you really want to delete ${toDeleteVideosIds.length} videos?`, 'Delete') + if (res === false) return + + const observables: Observable[] = [] + for (const videoId of toDeleteVideosIds) { + const o = this.videoService + .removeVideo(videoId) + .do(() => this.spliceVideosById(videoId)) + + observables.push(o) + } + + Observable.from(observables) + .concatAll() + .subscribe( + res => { + this.notificationsService.success('Success', `${toDeleteVideosIds.length} videos deleted.`) + this.buildVideoPages() + }, + + err => this.notificationsService.error('Error', err.message) + ) + } + + async deleteVideo (video: Video) { + const res = await this.confirmService.confirm(`Do you really want to delete ${video.name}?`, 'Delete') + if (res === false) return + + this.videoService.removeVideo(video.id) + .subscribe( + status => { + this.notificationsService.success('Success', `Video ${video.name} deleted.`) + this.spliceVideosById(video.id) + this.buildVideoPages() + }, + + error => this.notificationsService.error('Error', error.message) + ) + } + + protected buildVideoHeight () { + // In account videos, the video height is fixed + return this.baseVideoHeight + } + + private spliceVideosById (id: number) { + for (const key of Object.keys(this.loadedPages)) { + const videos = this.loadedPages[key] + const index = videos.findIndex(v => v.id === id) + + if (index !== -1) { + videos.splice(index, 1) + return + } + } + } +} diff --git a/client/src/app/+my-account/my-account.component.html b/client/src/app/+my-account/my-account.component.html new file mode 100644 index 000000000..591d58cf9 --- /dev/null +++ b/client/src/app/+my-account/my-account.component.html @@ -0,0 +1,13 @@ +
+ + +
+ +
+
diff --git a/client/src/app/+my-account/my-account.component.ts b/client/src/app/+my-account/my-account.component.ts new file mode 100644 index 000000000..7bb461d3c --- /dev/null +++ b/client/src/app/+my-account/my-account.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core' + +@Component({ + selector: 'my-my-account', + templateUrl: './my-account.component.html' +}) +export class MyAccountComponent {} diff --git a/client/src/app/+my-account/my-account.module.ts b/client/src/app/+my-account/my-account.module.ts new file mode 100644 index 000000000..7e6b8c03e --- /dev/null +++ b/client/src/app/+my-account/my-account.module.ts @@ -0,0 +1,38 @@ +import { NgModule } from '@angular/core' +import { SharedModule } from '../shared' +import { MyAccountRoutingModule } from './my-account-routing.module' +import { MyAccountChangePasswordComponent } from './my-account-settings/my-account-change-password/my-account-change-password.component' +import { MyAccountVideoSettingsComponent } from './my-account-settings/my-account-video-settings/my-account-video-settings.component' +import { MyAccountSettingsComponent } from './my-account-settings/my-account-settings.component' +import { MyAccountComponent } from './my-account.component' +import { MyAccountVideosComponent } from './my-account-videos/my-account-videos.component' +import { MyAccountProfileComponent } from '@app/+my-account/my-account-settings/my-account-profile/my-account-profile.component' +import { MyAccountVideoChannelsComponent } from '@app/+my-account/my-account-video-channels/my-account-video-channels.component' +import { MyAccountVideoChannelCreateComponent } from '@app/+my-account/my-account-video-channels/my-account-video-channel-create.component' +import { MyAccountVideoChannelUpdateComponent } from '@app/+my-account/my-account-video-channels/my-account-video-channel-update.component' + +@NgModule({ + imports: [ + MyAccountRoutingModule, + SharedModule + ], + + declarations: [ + MyAccountComponent, + MyAccountSettingsComponent, + MyAccountChangePasswordComponent, + MyAccountVideoSettingsComponent, + MyAccountProfileComponent, + MyAccountVideosComponent, + MyAccountVideoChannelsComponent, + MyAccountVideoChannelCreateComponent, + MyAccountVideoChannelUpdateComponent + ], + + exports: [ + MyAccountComponent + ], + + providers: [] +}) +export class MyAccountModule { } diff --git a/client/src/app/app-routing.module.ts b/client/src/app/app-routing.module.ts index 799748cfa..936912d28 100644 --- a/client/src/app/app-routing.module.ts +++ b/client/src/app/app-routing.module.ts @@ -8,6 +8,10 @@ const routes: Routes = [ path: 'admin', loadChildren: './+admin/admin.module#AdminModule' }, + { + path: 'my-account', + loadChildren: './+my-account/my-account.module#MyAccountModule' + }, { path: 'accounts', loadChildren: './+accounts/accounts.module#AccountsModule' diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts index c22632fb8..f0d2be279 100644 --- a/client/src/app/app.module.ts +++ b/client/src/app/app.module.ts @@ -6,8 +6,6 @@ import { ResetPasswordModule } from '@app/reset-password' import { MetaLoader, MetaModule, MetaStaticLoader, PageTitlePositioning } from '@ngx-meta/core' -import { MyAccountModule } from './my-account' - import { AppRoutingModule } from './app-routing.module' import { AppComponent } from './app.component' import { CoreModule } from './core' @@ -46,7 +44,6 @@ export function metaFactory (serverService: ServerService): MetaLoader { AppRoutingModule, - MyAccountModule, CoreModule, LoginModule, ResetPasswordModule, diff --git a/client/src/app/my-account/index.ts b/client/src/app/my-account/index.ts deleted file mode 100644 index 3df96dd7a..000000000 --- a/client/src/app/my-account/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './my-account-routing.module' -export * from './my-account.component' -export * from './my-account.module' diff --git a/client/src/app/my-account/my-account-routing.module.ts b/client/src/app/my-account/my-account-routing.module.ts deleted file mode 100644 index 96f52c1da..000000000 --- a/client/src/app/my-account/my-account-routing.module.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { NgModule } from '@angular/core' -import { RouterModule, Routes } from '@angular/router' -import { MetaGuard } from '@ngx-meta/core' -import { LoginGuard } from '../core' -import { MyAccountComponent } from './my-account.component' -import { MyAccountSettingsComponent } from './my-account-settings/my-account-settings.component' -import { MyAccountVideosComponent } from './my-account-videos/my-account-videos.component' -import { MyAccountVideoChannelsComponent } from '@app/my-account/my-account-video-channels/my-account-video-channels.component' -import { MyAccountVideoChannelCreateComponent } from '@app/my-account/my-account-video-channels/my-account-video-channel-create.component' -import { MyAccountVideoChannelUpdateComponent } from '@app/my-account/my-account-video-channels/my-account-video-channel-update.component' - -const myAccountRoutes: Routes = [ - { - path: 'my-account', - component: MyAccountComponent, - canActivateChild: [ MetaGuard, LoginGuard ], - children: [ - { - path: 'settings', - component: MyAccountSettingsComponent, - data: { - meta: { - title: 'Account settings' - } - } - }, - { - path: 'video-channels', - component: MyAccountVideoChannelsComponent, - data: { - meta: { - title: 'Account video channels' - } - } - }, - { - path: 'video-channels/create', - component: MyAccountVideoChannelCreateComponent, - data: { - meta: { - title: 'Create new video channel' - } - } - }, - { - path: 'video-channels/update/:videoChannelId', - component: MyAccountVideoChannelUpdateComponent, - data: { - meta: { - title: 'Update video channel' - } - } - }, - { - path: 'videos', - component: MyAccountVideosComponent, - data: { - meta: { - title: 'Account videos' - } - } - } - ] - } -] - -@NgModule({ - imports: [ RouterModule.forChild(myAccountRoutes) ], - exports: [ RouterModule ] -}) -export class MyAccountRoutingModule {} diff --git a/client/src/app/my-account/my-account-settings/my-account-change-password/index.ts b/client/src/app/my-account/my-account-settings/my-account-change-password/index.ts deleted file mode 100644 index 644047c5f..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-change-password/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './my-account-change-password.component' diff --git a/client/src/app/my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html b/client/src/app/my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html deleted file mode 100644 index b0e3cada4..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html +++ /dev/null @@ -1,20 +0,0 @@ -
{{ error }}
- -
- - - -
- {{ formErrors['new-password'] }} -
- - - - -
diff --git a/client/src/app/my-account/my-account-settings/my-account-change-password/my-account-change-password.component.scss b/client/src/app/my-account/my-account-settings/my-account-change-password/my-account-change-password.component.scss deleted file mode 100644 index f8279ffd3..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-change-password/my-account-change-password.component.scss +++ /dev/null @@ -1,19 +0,0 @@ -@import '_variables'; -@import '_mixins'; - -input[type=password] { - @include peertube-input-text(340px); - display: block; - - &#new-confirmed-password { - margin-top: 15px; - } -} - -input[type=submit] { - @include peertube-button; - @include orange-button; - - margin-top: 15px; -} - diff --git a/client/src/app/my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts b/client/src/app/my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts deleted file mode 100644 index 80af668f9..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Component, OnInit } from '@angular/core' -import { FormBuilder, FormGroup } from '@angular/forms' -import { NotificationsService } from 'angular2-notifications' -import { FormReactive, USER_PASSWORD, UserService } from '../../../shared' - -@Component({ - selector: 'my-account-change-password', - templateUrl: './my-account-change-password.component.html', - styleUrls: [ './my-account-change-password.component.scss' ] -}) -export class MyAccountChangePasswordComponent extends FormReactive implements OnInit { - error: string = null - - form: FormGroup - formErrors = { - 'new-password': '', - 'new-confirmed-password': '' - } - validationMessages = { - 'new-password': USER_PASSWORD.MESSAGES, - 'new-confirmed-password': USER_PASSWORD.MESSAGES - } - - constructor ( - private formBuilder: FormBuilder, - private notificationsService: NotificationsService, - private userService: UserService - ) { - super() - } - - buildForm () { - this.form = this.formBuilder.group({ - 'new-password': [ '', USER_PASSWORD.VALIDATORS ], - 'new-confirmed-password': [ '', USER_PASSWORD.VALIDATORS ] - }) - - this.form.valueChanges.subscribe(data => this.onValueChanged(data)) - } - - ngOnInit () { - this.buildForm() - } - - changePassword () { - const newPassword = this.form.value['new-password'] - const newConfirmedPassword = this.form.value['new-confirmed-password'] - - this.error = null - - if (newPassword !== newConfirmedPassword) { - this.error = 'The new password and the confirmed password do not correspond.' - return - } - - this.userService.changePassword(newPassword).subscribe( - () => this.notificationsService.success('Success', 'Password updated.'), - - err => this.error = err.message - ) - } -} diff --git a/client/src/app/my-account/my-account-settings/my-account-profile/index.ts b/client/src/app/my-account/my-account-settings/my-account-profile/index.ts deleted file mode 100644 index 3cc049f8f..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-profile/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './my-account-profile.component' diff --git a/client/src/app/my-account/my-account-settings/my-account-profile/my-account-profile.component.html b/client/src/app/my-account/my-account-settings/my-account-profile/my-account-profile.component.html deleted file mode 100644 index 306f3a12c..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-profile/my-account-profile.component.html +++ /dev/null @@ -1,24 +0,0 @@ -
{{ error }}
- -
- - - -
- {{ formErrors['display-name'] }} -
- - - -
- {{ formErrors.description }} -
- - -
diff --git a/client/src/app/my-account/my-account-settings/my-account-profile/my-account-profile.component.scss b/client/src/app/my-account/my-account-settings/my-account-profile/my-account-profile.component.scss deleted file mode 100644 index fc2b92c89..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-profile/my-account-profile.component.scss +++ /dev/null @@ -1,23 +0,0 @@ -@import '_variables'; -@import '_mixins'; - -input[type=text] { - @include peertube-input-text(340px); - - display: block; - margin-bottom: 15px; -} - -textarea { - @include peertube-textarea(500px, 150px); - - display: block; -} - -input[type=submit] { - @include peertube-button; - @include orange-button; - - margin-top: 15px; -} - diff --git a/client/src/app/my-account/my-account-settings/my-account-profile/my-account-profile.component.ts b/client/src/app/my-account/my-account-settings/my-account-profile/my-account-profile.component.ts deleted file mode 100644 index 2b7ba353c..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-profile/my-account-profile.component.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Component, Input, OnInit } from '@angular/core' -import { FormBuilder, FormGroup } from '@angular/forms' -import { NotificationsService } from 'angular2-notifications' -import { FormReactive, USER_DESCRIPTION, USER_DISPLAY_NAME, UserService } from '../../../shared' -import { User } from '@app/shared' - -@Component({ - selector: 'my-account-profile', - templateUrl: './my-account-profile.component.html', - styleUrls: [ './my-account-profile.component.scss' ] -}) -export class MyAccountProfileComponent extends FormReactive implements OnInit { - @Input() user: User = null - - error: string = null - - form: FormGroup - formErrors = { - 'display-name': '', - 'description': '' - } - validationMessages = { - 'display-name': USER_DISPLAY_NAME.MESSAGES, - 'description': USER_DESCRIPTION.MESSAGES - } - - constructor ( - private formBuilder: FormBuilder, - private notificationsService: NotificationsService, - private userService: UserService - ) { - super() - } - - buildForm () { - this.form = this.formBuilder.group({ - 'display-name': [ this.user.account.displayName, USER_DISPLAY_NAME.VALIDATORS ], - 'description': [ this.user.account.description, USER_DESCRIPTION.VALIDATORS ] - }) - - this.form.valueChanges.subscribe(data => this.onValueChanged(data)) - } - - ngOnInit () { - this.buildForm() - } - - updateMyProfile () { - const displayName = this.form.value['display-name'] - const description = this.form.value['description'] - - this.error = null - - this.userService.updateMyProfile({ displayName, description }).subscribe( - () => { - this.user.account.displayName = displayName - this.user.account.description = description - - this.notificationsService.success('Success', 'Profile updated.') - }, - - err => this.error = err.message - ) - } -} diff --git a/client/src/app/my-account/my-account-settings/my-account-settings.component.html b/client/src/app/my-account/my-account-settings/my-account-settings.component.html deleted file mode 100644 index 0fcc7782e..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-settings.component.html +++ /dev/null @@ -1,32 +0,0 @@ -
- Avatar - - -
- -
- Change your avatar - -
-
(extensions: {{ avatarExtensions }}, max size: {{ maxAvatarSize | bytes }})
- -
- Video quota: {{ userVideoQuotaUsed | bytes: 0 }} / {{ userVideoQuota }} -
- - - - - - - - - - - diff --git a/client/src/app/my-account/my-account-settings/my-account-settings.component.scss b/client/src/app/my-account/my-account-settings/my-account-settings.component.scss deleted file mode 100644 index ec0d40b93..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-settings.component.scss +++ /dev/null @@ -1,67 +0,0 @@ -@import '_variables'; -@import '_mixins'; - -.user { - display: flex; - - img { - @include avatar(50px); - - margin-right: 15px; - } - - .user-info { - .user-info-names { - display: flex; - align-items: center; - - .user-info-display-name { - font-size: 20px; - font-weight: $font-bold; - } - - .user-info-username { - margin-left: 7px; - position: relative; - top: 2px; - font-size: 14px; - color: #777272; - } - } - - .user-info-followers { - font-size: 15px; - } - } -} - -.button-file { - @include peertube-button-file(160px); - - margin-top: 10px; - margin-bottom: 5px; -} - -.file-max-size { - display: inline-block; - font-size: 13px; - - position: relative; - top: -10px; -} - -.user-quota { - font-size: 15px; - margin-top: 20px; - - .user-quota-label { - font-weight: $font-semibold; - } -} - -.account-title { - @include in-content-small-title; - - margin-top: 55px; - margin-bottom: 30px; -} diff --git a/client/src/app/my-account/my-account-settings/my-account-settings.component.ts b/client/src/app/my-account/my-account-settings/my-account-settings.component.ts deleted file mode 100644 index 06d1138e7..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-settings.component.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Component, OnInit, ViewChild } from '@angular/core' -import { NotificationsService } from 'angular2-notifications' -import { BytesPipe } from 'ngx-pipes' -import { AuthService } from '../../core' -import { ServerService } from '../../core/server' -import { User } from '../../shared' -import { UserService } from '../../shared/users' - -@Component({ - selector: 'my-account-settings', - templateUrl: './my-account-settings.component.html', - styleUrls: [ './my-account-settings.component.scss' ] -}) -export class MyAccountSettingsComponent implements OnInit { - @ViewChild('avatarfileInput') avatarfileInput - - user: User = null - userVideoQuota = '0' - userVideoQuotaUsed = 0 - - constructor ( - private userService: UserService, - private authService: AuthService, - private serverService: ServerService, - private notificationsService: NotificationsService - ) {} - - ngOnInit () { - this.user = this.authService.getUser() - - this.authService.userInformationLoaded.subscribe( - () => { - if (this.user.videoQuota !== -1) { - this.userVideoQuota = new BytesPipe().transform(this.user.videoQuota, 0).toString() - } else { - this.userVideoQuota = 'Unlimited' - } - } - ) - - this.userService.getMyVideoQuotaUsed() - .subscribe(data => this.userVideoQuotaUsed = data.videoQuotaUsed) - } - - changeAvatar () { - const avatarfile = this.avatarfileInput.nativeElement.files[ 0 ] - - const formData = new FormData() - formData.append('avatarfile', avatarfile) - - this.userService.changeAvatar(formData) - .subscribe( - data => { - this.notificationsService.success('Success', 'Avatar changed.') - - this.user.account.avatar = data.avatar - }, - - err => this.notificationsService.error('Error', err.message) - ) - } - - get maxAvatarSize () { - return this.serverService.getConfig().avatar.file.size.max - } - - get avatarExtensions () { - return this.serverService.getConfig().avatar.file.extensions.join(',') - } -} diff --git a/client/src/app/my-account/my-account-settings/my-account-video-settings/index.ts b/client/src/app/my-account/my-account-settings/my-account-video-settings/index.ts deleted file mode 100644 index 1253bd369..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-video-settings/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './my-account-video-settings.component' diff --git a/client/src/app/my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html b/client/src/app/my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html deleted file mode 100644 index 0e8598e9e..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html +++ /dev/null @@ -1,25 +0,0 @@ -
-
- - - -
- -
-
- -
- - - -
- - -
diff --git a/client/src/app/my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.scss b/client/src/app/my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.scss deleted file mode 100644 index ed59e4689..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.scss +++ /dev/null @@ -1,20 +0,0 @@ -@import '_variables'; -@import '_mixins'; - -input[type=checkbox] { - @include peertube-checkbox(1px); -} - -input[type=submit] { - @include peertube-button; - @include orange-button; - - display: block; - margin-top: 15px; -} - -.peertube-select-container { - @include peertube-select-container(340px); - - margin-bottom: 30px; -} \ No newline at end of file diff --git a/client/src/app/my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts b/client/src/app/my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts deleted file mode 100644 index acc70c14d..000000000 --- a/client/src/app/my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Component, Input, OnInit } from '@angular/core' -import { FormBuilder, FormGroup } from '@angular/forms' -import { NotificationsService } from 'angular2-notifications' -import { UserUpdateMe } from '../../../../../../shared' -import { AuthService } from '../../../core' -import { FormReactive, User, UserService } from '../../../shared' - -@Component({ - selector: 'my-account-video-settings', - templateUrl: './my-account-video-settings.component.html', - styleUrls: [ './my-account-video-settings.component.scss' ] -}) -export class MyAccountVideoSettingsComponent extends FormReactive implements OnInit { - @Input() user: User = null - - form: FormGroup - formErrors = {} - validationMessages = {} - - constructor ( - private authService: AuthService, - private formBuilder: FormBuilder, - private notificationsService: NotificationsService, - private userService: UserService - ) { - super() - } - - buildForm () { - this.form = this.formBuilder.group({ - nsfwPolicy: [ this.user.nsfwPolicy ], - autoPlayVideo: [ this.user.autoPlayVideo ] - }) - - this.form.valueChanges.subscribe(data => this.onValueChanged(data)) - } - - ngOnInit () { - this.buildForm() - } - - updateDetails () { - const nsfwPolicy = this.form.value['nsfwPolicy'] - const autoPlayVideo = this.form.value['autoPlayVideo'] - const details: UserUpdateMe = { - nsfwPolicy, - autoPlayVideo - } - - this.userService.updateMyProfile(details).subscribe( - () => { - this.notificationsService.success('Success', 'Information updated.') - - this.authService.refreshUserInformation() - }, - - err => this.notificationsService.error('Error', err.message) - ) - } -} 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 deleted file mode 100644 index 0f03548ad..000000000 --- a/client/src/app/my-account/my-account-video-channels/my-account-video-channel-create.component.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Component, OnInit } from '@angular/core' -import { Router } from '@angular/router' -import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' -import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' -import { FormBuilder, FormGroup } from '@angular/forms' -import { VideoChannelCreate } from '../../../../../shared/models/videos' -import { - VIDEO_CHANNEL_DESCRIPTION, - VIDEO_CHANNEL_DISPLAY_NAME, - VIDEO_CHANNEL_SUPPORT -} from '@app/shared/forms/form-validators/video-channel' -import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' -import { AuthService } from '@app/core' - -@Component({ - selector: 'my-account-video-channel-create', - templateUrl: './my-account-video-channel-edit.component.html', - styleUrls: [ './my-account-video-channel-edit.component.scss' ] -}) -export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelEdit implements OnInit { - error: string - - form: FormGroup - formErrors = { - 'display-name': '', - 'description': '', - 'support': '' - } - validationMessages = { - 'display-name': VIDEO_CHANNEL_DISPLAY_NAME.MESSAGES, - 'description': VIDEO_CHANNEL_DESCRIPTION.MESSAGES, - 'support': VIDEO_CHANNEL_SUPPORT.MESSAGES - } - - constructor ( - private authService: AuthService, - private notificationsService: NotificationsService, - private router: Router, - private formBuilder: FormBuilder, - private videoChannelService: VideoChannelService - ) { - super() - } - - buildForm () { - this.form = this.formBuilder.group({ - 'display-name': [ '', VIDEO_CHANNEL_DISPLAY_NAME.VALIDATORS ], - description: [ '', VIDEO_CHANNEL_DESCRIPTION.VALIDATORS ], - support: [ '', VIDEO_CHANNEL_SUPPORT.VALIDATORS ] - }) - - this.form.valueChanges.subscribe(data => this.onValueChanged(data)) - } - - ngOnInit () { - this.buildForm() - } - - formValidated () { - this.error = undefined - - const body = this.form.value - const videoChannelCreate: VideoChannelCreate = { - displayName: body['display-name'], - description: body.description || undefined, - support: body.support || undefined - } - - this.videoChannelService.createVideoChannel(videoChannelCreate).subscribe( - () => { - this.authService.refreshUserInformation() - this.notificationsService.success('Success', `Video channel ${videoChannelCreate.displayName} created.`) - this.router.navigate([ '/my-account', 'video-channels' ]) - }, - - err => this.error = err.message - ) - } - - isCreation () { - return true - } - - getFormButtonTitle () { - return 'Create' - } -} 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 deleted file mode 100644 index d5fb6262a..000000000 --- a/client/src/app/my-account/my-account-video-channels/my-account-video-channel-edit.component.html +++ /dev/null @@ -1,42 +0,0 @@ -
Create a video channel
-
Update {{ videoChannel?.displayName }}
- -
{{ error }}
- -
-
- - -
- {{ formErrors['display-name'] }} -
-
- -
- - -
- {{ formErrors.description }} -
-
- -
- - - -
- {{ formErrors.support }} -
-
- - -
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 deleted file mode 100644 index 6fbb8ae8b..000000000 --- a/client/src/app/my-account/my-account-video-channels/my-account-video-channel-edit.component.scss +++ /dev/null @@ -1,27 +0,0 @@ -@import '_variables'; -@import '_mixins'; - -.form-sub-title { - margin-bottom: 20px; -} - -input[type=text] { - @include peertube-input-text(340px); - - display: block; -} - -textarea { - @include peertube-textarea(500px, 150px); - - display: block; -} - -.peertube-select-container { - @include peertube-select-container(340px); -} - -input[type=submit] { - @include peertube-button; - @include orange-button; -} \ No newline at end of file diff --git a/client/src/app/my-account/my-account-video-channels/my-account-video-channel-edit.ts b/client/src/app/my-account/my-account-video-channels/my-account-video-channel-edit.ts deleted file mode 100644 index e56f46262..000000000 --- a/client/src/app/my-account/my-account-video-channels/my-account-video-channel-edit.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { FormReactive } from '@app/shared' - -export abstract class MyAccountVideoChannelEdit extends FormReactive { - abstract isCreation (): boolean - abstract getFormButtonTitle (): string -} diff --git a/client/src/app/my-account/my-account-video-channels/my-account-video-channel-update.component.ts b/client/src/app/my-account/my-account-video-channels/my-account-video-channel-update.component.ts deleted file mode 100644 index c0dc6a939..000000000 --- a/client/src/app/my-account/my-account-video-channels/my-account-video-channel-update.component.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { Component, OnInit, OnDestroy } from '@angular/core' -import { ActivatedRoute, Router } from '@angular/router' -import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' -import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' -import { FormBuilder, FormGroup } from '@angular/forms' -import { VideoChannelUpdate } from '../../../../../shared/models/videos' -import { - VIDEO_CHANNEL_DESCRIPTION, - VIDEO_CHANNEL_DISPLAY_NAME, - VIDEO_CHANNEL_SUPPORT -} from '@app/shared/forms/form-validators/video-channel' -import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' -import { Subscription } from 'rxjs/Subscription' -import { VideoChannel } from '@app/shared/video-channel/video-channel.model' -import { AuthService } from '@app/core' - -@Component({ - selector: 'my-account-video-channel-update', - templateUrl: './my-account-video-channel-edit.component.html', - styleUrls: [ './my-account-video-channel-edit.component.scss' ] -}) -export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelEdit implements OnInit, OnDestroy { - error: string - - form: FormGroup - formErrors = { - 'display-name': '', - 'description': '', - 'support': '' - } - validationMessages = { - 'display-name': VIDEO_CHANNEL_DISPLAY_NAME.MESSAGES, - 'description': VIDEO_CHANNEL_DESCRIPTION.MESSAGES, - 'support': VIDEO_CHANNEL_SUPPORT.MESSAGES - } - - private videoChannelToUpdate: VideoChannel - private paramsSub: Subscription - - constructor ( - private authService: AuthService, - private notificationsService: NotificationsService, - private router: Router, - private route: ActivatedRoute, - private formBuilder: FormBuilder, - private videoChannelService: VideoChannelService - ) { - super() - } - - buildForm () { - this.form = this.formBuilder.group({ - 'display-name': [ '', VIDEO_CHANNEL_DISPLAY_NAME.VALIDATORS ], - description: [ '', VIDEO_CHANNEL_DESCRIPTION.VALIDATORS ], - support: [ '', VIDEO_CHANNEL_SUPPORT.VALIDATORS ] - }) - - this.form.valueChanges.subscribe(data => this.onValueChanged(data)) - } - - ngOnInit () { - this.buildForm() - - this.paramsSub = this.route.params.subscribe(routeParams => { - const videoChannelId = routeParams['videoChannelId'] - - this.videoChannelService.getVideoChannel(videoChannelId).subscribe( - videoChannelToUpdate => { - this.videoChannelToUpdate = videoChannelToUpdate - - this.form.patchValue({ - 'display-name': videoChannelToUpdate.displayName, - description: videoChannelToUpdate.description, - support: videoChannelToUpdate.support - }) - }, - - err => this.error = err.message - ) - }) - } - - ngOnDestroy () { - if (this.paramsSub) this.paramsSub.unsubscribe() - } - - formValidated () { - this.error = undefined - - const body = this.form.value - const videoChannelUpdate: VideoChannelUpdate = { - displayName: body['display-name'], - description: body.description || undefined, - support: body.support || undefined - } - - this.videoChannelService.updateVideoChannel(this.videoChannelToUpdate.uuid, videoChannelUpdate).subscribe( - () => { - this.authService.refreshUserInformation() - this.notificationsService.success('Success', `Video channel ${videoChannelUpdate.displayName} updated.`) - this.router.navigate([ '/my-account', 'video-channels' ]) - }, - - err => this.error = err.message - ) - } - - isCreation () { - return false - } - - getFormButtonTitle () { - return 'Update' - } -} 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 deleted file mode 100644 index 90c401bc5..000000000 --- a/client/src/app/my-account/my-account-video-channels/my-account-video-channels.component.html +++ /dev/null @@ -1,30 +0,0 @@ - - -
-
- - Avatar - - -
- -
{{ videoChannel.displayName }}
- - -
- -
{{ videoChannel.followersCount }} subscribers
-
- -
- - - -
-
-
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 deleted file mode 100644 index bcb58eac2..000000000 --- a/client/src/app/my-account/my-account-video-channels/my-account-video-channels.component.scss +++ /dev/null @@ -1,72 +0,0 @@ -@import '_variables'; -@import '_mixins'; - -.create-button { - @include create-button; -} - -/deep/ .action-button { - &.action-button-delete { - margin-right: 10px; - } -} - -.video-channel { - display: flex; - min-height: 130px; - padding-bottom: 20px; - margin-bottom: 20px; - border-bottom: 1px solid #C6C6C6; - - img { - @include avatar(80px); - - margin-right: 10px; - } - - .video-channel-info { - flex-grow: 1; - - a.video-channel-names { - @include disable-default-a-behaviour; - - display: flex; - color: #000; - - .video-channel-display-name { - font-weight: $font-semibold; - font-size: 18px; - } - - .video-channel-name { - font-size: 14px; - color: #777272; - } - } - } - - .video-channel-buttons { - min-width: 190px; - } -} - -.video-channels-header { - text-align: right; - margin: 20px 0 50px; -} - -@media screen and (max-width: 800px) { - .video-channel { - flex-direction: column; - height: auto; - text-align: center; - - img { - margin-right: 0; - } - - .video-channel-buttons { - margin-top: 10px; - } - } -} diff --git a/client/src/app/my-account/my-account-video-channels/my-account-video-channels.component.ts b/client/src/app/my-account/my-account-video-channels/my-account-video-channels.component.ts deleted file mode 100644 index eeaca11df..000000000 --- a/client/src/app/my-account/my-account-video-channels/my-account-video-channels.component.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Component, OnInit } from '@angular/core' -import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' -import { AuthService } from '../../core/auth' -import { ConfirmService } from '../../core/confirm' -import { VideoChannel } from '@app/shared/video-channel/video-channel.model' -import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' -import { User } from '@app/shared' - -@Component({ - selector: 'my-account-video-channels', - templateUrl: './my-account-video-channels.component.html', - styleUrls: [ './my-account-video-channels.component.scss' ] -}) -export class MyAccountVideoChannelsComponent implements OnInit { - videoChannels: VideoChannel[] = [] - - private user: User - - constructor ( - private authService: AuthService, - private notificationsService: NotificationsService, - private confirmService: ConfirmService, - private videoChannelService: VideoChannelService - ) {} - - ngOnInit () { - this.user = this.authService.getUser() - - this.loadVideoChannels() - } - - async deleteVideoChannel (videoChannel: VideoChannel) { - const res = await this.confirmService.confirmWithInput( - `Do you really want to delete ${videoChannel.displayName}? It will delete all videos uploaded in this channel too.`, - 'Please type the name of the video channel to confirm', - videoChannel.displayName, - 'Delete' - ) - if (res === false) return - - this.videoChannelService.removeVideoChannel(videoChannel) - .subscribe( - status => { - this.loadVideoChannels() - this.notificationsService.success('Success', `Video channel ${videoChannel.name} deleted.`) - }, - - error => this.notificationsService.error('Error', error.message) - ) - } - - private loadVideoChannels () { - this.authService.userInformationLoaded - .flatMap(() => this.videoChannelService.listAccountVideoChannels(this.user.account.id)) - .subscribe(res => this.videoChannels = res.data) - } -} diff --git a/client/src/app/my-account/my-account-videos/my-account-videos.component.html b/client/src/app/my-account/my-account-videos/my-account-videos.component.html deleted file mode 100644 index 66ce3a77b..000000000 --- a/client/src/app/my-account/my-account-videos/my-account-videos.component.html +++ /dev/null @@ -1,45 +0,0 @@ -
No results.
- -
-
-
-
- - -
- - - -
- {{ video.name }} - {{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views -
{{ video.privacy.label }}
-
- - -
-
- - Cancel - - - - - Delete - -
-
- -
- - - -
-
-
-
diff --git a/client/src/app/my-account/my-account-videos/my-account-videos.component.scss b/client/src/app/my-account/my-account-videos/my-account-videos.component.scss deleted file mode 100644 index f276ea389..000000000 --- a/client/src/app/my-account/my-account-videos/my-account-videos.component.scss +++ /dev/null @@ -1,114 +0,0 @@ -@import '_variables'; -@import '_mixins'; - -.action-selection-mode { - width: 174px; - display: flex; - justify-content: flex-end; - - .action-selection-mode-child { - position: fixed; - - .action-button { - display: inline-block; - } - - .action-button-cancel-selection { - @include peertube-button; - @include grey-button; - - margin-right: 10px; - } - - .action-button-delete-selection { - @include peertube-button; - @include orange-button; - } - - .icon.icon-delete-white { - @include icon(21px); - - position: relative; - top: -2px; - background-image: url('../../../assets/images/global/delete-white.svg'); - } - } -} - -/deep/ .action-button { - &.action-button-delete { - margin-right: 10px; - } -} - -.video { - display: flex; - min-height: 130px; - padding-bottom: 20px; - margin-bottom: 20px; - border-bottom: 1px solid #C6C6C6; - - &:first-child { - margin-top: 47px; - } - - .checkbox-container { - display: flex; - align-items: center; - margin-right: 20px; - margin-left: 12px; - - input[type=checkbox] { - @include peertube-checkbox(2px); - } - } - - my-video-thumbnail { - margin-right: 10px; - } - - .video-info { - flex-grow: 1; - - .video-info-name { - @include disable-default-a-behaviour; - - color: #000; - display: block; - font-size: 16px; - font-weight: $font-semibold; - } - - .video-info-date-views, .video-info-private { - font-size: 13px; - - &.video-info-private { - font-weight: $font-semibold; - } - } - } - - .video-buttons { - min-width: 190px; - } -} - -@media screen and (max-width: 800px) { - .video { - flex-direction: column; - height: auto; - text-align: center; - - input[type=checkbox] { - display: none; - } - - my-video-thumbnail { - margin-right: 0; - } - - .video-buttons { - margin-top: 10px; - } - } -} diff --git a/client/src/app/my-account/my-account-videos/my-account-videos.component.ts b/client/src/app/my-account/my-account-videos/my-account-videos.component.ts deleted file mode 100644 index c1b53bcd5..000000000 --- a/client/src/app/my-account/my-account-videos/my-account-videos.component.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { Component, OnInit, OnDestroy } from '@angular/core' -import { ActivatedRoute, Router } from '@angular/router' -import { Location } from '@angular/common' -import { immutableAssign } from '@app/shared/misc/utils' -import { ComponentPagination } from '@app/shared/rest/component-pagination.model' -import { NotificationsService } from 'angular2-notifications' -import 'rxjs/add/observable/from' -import 'rxjs/add/operator/concatAll' -import { Observable } from 'rxjs/Observable' -import { AuthService } from '../../core/auth' -import { ConfirmService } from '../../core/confirm' -import { AbstractVideoList } from '../../shared/video/abstract-video-list' -import { Video } from '../../shared/video/video.model' -import { VideoService } from '../../shared/video/video.service' - -@Component({ - selector: 'my-account-videos', - templateUrl: './my-account-videos.component.html', - styleUrls: [ './my-account-videos.component.scss' ] -}) -export class MyAccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { - titlePage = 'My videos' - currentRoute = '/my-account/videos' - checkedVideos: { [ id: number ]: boolean } = {} - pagination: ComponentPagination = { - currentPage: 1, - itemsPerPage: 5, - totalItems: null - } - - protected baseVideoWidth = -1 - protected baseVideoHeight = 155 - - constructor (protected router: Router, - protected route: ActivatedRoute, - protected authService: AuthService, - protected notificationsService: NotificationsService, - protected confirmService: ConfirmService, - protected location: Location, - private videoService: VideoService) { - super() - } - - ngOnInit () { - super.ngOnInit() - } - - ngOnDestroy () { - super.ngOnDestroy() - } - - abortSelectionMode () { - this.checkedVideos = {} - } - - isInSelectionMode () { - return Object.keys(this.checkedVideos).some(k => this.checkedVideos[k] === true) - } - - getVideosObservable (page: number) { - const newPagination = immutableAssign(this.pagination, { currentPage: page }) - - return this.videoService.getMyVideos(newPagination, this.sort) - } - - generateSyndicationList () { - throw new Error('Method not implemented.') - } - - async deleteSelectedVideos () { - const toDeleteVideosIds = Object.keys(this.checkedVideos) - .filter(k => this.checkedVideos[k] === true) - .map(k => parseInt(k, 10)) - - const res = await this.confirmService.confirm(`Do you really want to delete ${toDeleteVideosIds.length} videos?`, 'Delete') - if (res === false) return - - const observables: Observable[] = [] - for (const videoId of toDeleteVideosIds) { - const o = this.videoService - .removeVideo(videoId) - .do(() => this.spliceVideosById(videoId)) - - observables.push(o) - } - - Observable.from(observables) - .concatAll() - .subscribe( - res => { - this.notificationsService.success('Success', `${toDeleteVideosIds.length} videos deleted.`) - this.buildVideoPages() - }, - - err => this.notificationsService.error('Error', err.message) - ) - } - - async deleteVideo (video: Video) { - const res = await this.confirmService.confirm(`Do you really want to delete ${video.name}?`, 'Delete') - if (res === false) return - - this.videoService.removeVideo(video.id) - .subscribe( - status => { - this.notificationsService.success('Success', `Video ${video.name} deleted.`) - this.spliceVideosById(video.id) - this.buildVideoPages() - }, - - error => this.notificationsService.error('Error', error.message) - ) - } - - protected buildVideoHeight () { - // In account videos, the video height is fixed - return this.baseVideoHeight - } - - private spliceVideosById (id: number) { - for (const key of Object.keys(this.loadedPages)) { - const videos = this.loadedPages[key] - const index = videos.findIndex(v => v.id === id) - - if (index !== -1) { - videos.splice(index, 1) - return - } - } - } -} diff --git a/client/src/app/my-account/my-account.component.html b/client/src/app/my-account/my-account.component.html deleted file mode 100644 index 591d58cf9..000000000 --- a/client/src/app/my-account/my-account.component.html +++ /dev/null @@ -1,13 +0,0 @@ -
- - -
- -
-
diff --git a/client/src/app/my-account/my-account.component.ts b/client/src/app/my-account/my-account.component.ts deleted file mode 100644 index 7bb461d3c..000000000 --- a/client/src/app/my-account/my-account.component.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Component } from '@angular/core' - -@Component({ - selector: 'my-my-account', - templateUrl: './my-account.component.html' -}) -export class MyAccountComponent {} diff --git a/client/src/app/my-account/my-account.module.ts b/client/src/app/my-account/my-account.module.ts deleted file mode 100644 index ba9dea71e..000000000 --- a/client/src/app/my-account/my-account.module.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { NgModule } from '@angular/core' -import { SharedModule } from '../shared' -import { MyAccountRoutingModule } from './my-account-routing.module' -import { MyAccountChangePasswordComponent } from './my-account-settings/my-account-change-password/my-account-change-password.component' -import { MyAccountVideoSettingsComponent } from './my-account-settings/my-account-video-settings/my-account-video-settings.component' -import { MyAccountSettingsComponent } from './my-account-settings/my-account-settings.component' -import { MyAccountComponent } from './my-account.component' -import { MyAccountVideosComponent } from './my-account-videos/my-account-videos.component' -import { MyAccountProfileComponent } from '@app/my-account/my-account-settings/my-account-profile/my-account-profile.component' -import { MyAccountVideoChannelsComponent } from '@app/my-account/my-account-video-channels/my-account-video-channels.component' -import { MyAccountVideoChannelCreateComponent } from '@app/my-account/my-account-video-channels/my-account-video-channel-create.component' -import { MyAccountVideoChannelUpdateComponent } from '@app/my-account/my-account-video-channels/my-account-video-channel-update.component' - -@NgModule({ - imports: [ - MyAccountRoutingModule, - SharedModule - ], - - declarations: [ - MyAccountComponent, - MyAccountSettingsComponent, - MyAccountChangePasswordComponent, - MyAccountVideoSettingsComponent, - MyAccountProfileComponent, - MyAccountVideosComponent, - MyAccountVideoChannelsComponent, - MyAccountVideoChannelCreateComponent, - MyAccountVideoChannelUpdateComponent - ], - - exports: [ - MyAccountComponent - ], - - providers: [] -}) -export class MyAccountModule { }