From c5911fd347c76e8bdc05ea9f3ee9efed4a58c236 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 29 Dec 2017 19:10:13 +0100 Subject: Begin to add avatar to actors --- .../account-settings.component.html | 6 +++- .../account-settings.component.scss | 6 ++++ .../account-settings/account-settings.component.ts | 36 +++++++++++++++++++--- .../account-videos/account-videos.component.ts | 4 +-- client/src/app/core/auth/auth.service.ts | 35 +++------------------ client/src/app/menu/menu.component.html | 2 +- client/src/app/menu/menu.component.ts | 4 +-- client/src/app/shared/account/account.model.ts | 10 ++++-- client/src/app/shared/misc/utils.ts | 14 ++++++++- client/src/app/shared/users/user.model.ts | 4 +-- client/src/app/shared/users/user.service.ts | 16 ++++++++++ client/src/app/shared/video/abstract-video-list.ts | 2 +- client/src/app/shared/video/video.model.ts | 7 ++--- .../+video-edit/shared/video-edit.component.scss | 5 --- .../videos/+video-edit/video-add.component.scss | 25 ++------------- .../videos/+video-watch/video-watch.component.ts | 8 ++--- client/src/sass/include/_mixins.scss | 26 ++++++++++++++++ 17 files changed, 125 insertions(+), 85 deletions(-) (limited to 'client') diff --git a/client/src/app/account/account-settings/account-settings.component.html b/client/src/app/account/account-settings/account-settings.component.html index f14eadd49..fe345207a 100644 --- a/client/src/app/account/account-settings/account-settings.component.html +++ b/client/src/app/account/account-settings/account-settings.component.html @@ -1,5 +1,5 @@
- Avatar + Avatar
+
+ Change your avatar + +
Account settings
diff --git a/client/src/app/account/account-settings/account-settings.component.scss b/client/src/app/account/account-settings/account-settings.component.scss index 7f1ade377..accd65214 100644 --- a/client/src/app/account/account-settings/account-settings.component.scss +++ b/client/src/app/account/account-settings/account-settings.component.scss @@ -21,6 +21,12 @@ } } +.button-file { + @include peertube-button-file(auto); + + margin-top: 10px; +} + .account-title { text-transform: uppercase; color: $orange-color; diff --git a/client/src/app/account/account-settings/account-settings.component.ts b/client/src/app/account/account-settings/account-settings.component.ts index cba251000..3e03085ce 100644 --- a/client/src/app/account/account-settings/account-settings.component.ts +++ b/client/src/app/account/account-settings/account-settings.component.ts @@ -1,6 +1,10 @@ -import { Component, OnInit } from '@angular/core' +import { HttpEventType, HttpResponse } from '@angular/common/http' +import { Component, OnInit, ViewChild } from '@angular/core' +import { NotificationsService } from 'angular2-notifications' +import { VideoPrivacy } from '../../../../../shared/models/videos' import { User } from '../../shared' import { AuthService } from '../../core' +import { UserService } from '../../shared/users' @Component({ selector: 'my-account-settings', @@ -8,15 +12,39 @@ import { AuthService } from '../../core' styleUrls: [ './account-settings.component.scss' ] }) export class AccountSettingsComponent implements OnInit { + @ViewChild('avatarfileInput') avatarfileInput + user: User = null - constructor (private authService: AuthService) {} + constructor ( + private userService: UserService, + private authService: AuthService, + private notificationsService: NotificationsService + ) {} ngOnInit () { this.user = this.authService.getUser() } - getAvatarPath () { - return this.user.getAvatarPath() + getAvatarUrl () { + return this.user.getAvatarUrl() + } + + 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) + ) } } diff --git a/client/src/app/account/account-videos/account-videos.component.ts b/client/src/app/account/account-videos/account-videos.component.ts index 22941619d..d51b70e06 100644 --- a/client/src/app/account/account-videos/account-videos.component.ts +++ b/client/src/app/account/account-videos/account-videos.component.ts @@ -68,7 +68,7 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit .subscribe( res => this.notificationsService.success('Success', `${toDeleteVideosIds.length} videos deleted.`), - err => this.notificationsService.error('Error', err.text) + err => this.notificationsService.error('Error', err.message) ) } ) @@ -86,7 +86,7 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit this.spliceVideosById(video.id) }, - error => this.notificationsService.error('Error', error.text) + error => this.notificationsService.error('Error', error.message) ) } ) diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts index c914848ae..8a2ba77d6 100644 --- a/client/src/app/core/auth/auth.service.ts +++ b/client/src/app/core/auth/auth.service.ts @@ -9,8 +9,8 @@ import 'rxjs/add/operator/mergeMap' import { Observable } from 'rxjs/Observable' import { ReplaySubject } from 'rxjs/ReplaySubject' import { Subject } from 'rxjs/Subject' -import { OAuthClientLocal, User as UserServerModel, UserRefreshToken, UserRole, VideoChannel } from '../../../../../shared' -import { Account } from '../../../../../shared/models/actors' +import { OAuthClientLocal, User as UserServerModel, UserRefreshToken } from '../../../../../shared' +import { User } from '../../../../../shared/models/users' import { UserLogin } from '../../../../../shared/models/users/user-login.model' import { environment } from '../../../environments/environment' import { RestExtractor } from '../../shared/rest' @@ -25,20 +25,7 @@ interface UserLoginWithUsername extends UserLogin { username: string } -interface UserLoginWithUserInformation extends UserLogin { - access_token: string - refresh_token: string - token_type: string - username: string - id: number - role: UserRole - displayNSFW: boolean - autoPlayVideo: boolean - email: string - videoQuota: number - account: Account - videoChannels: VideoChannel[] -} +type UserLoginWithUserInformation = UserLoginWithUsername & User @Injectable() export class AuthService { @@ -209,21 +196,7 @@ export class AuthService { const headers = new HttpHeaders().set('Authorization', `${obj.token_type} ${obj.access_token}`) return this.http.get(AuthService.BASE_USER_INFORMATION_URL, { headers }) - .map(res => { - const newProperties = { - id: res.id, - role: res.role, - displayNSFW: res.displayNSFW, - autoPlayVideo: res.autoPlayVideo, - email: res.email, - videoQuota: res.videoQuota, - account: res.account, - videoChannels: res.videoChannels - } - - return Object.assign(obj, newProperties) - } - ) + .map(res => Object.assign(obj, res)) } private handleLogin (obj: UserLoginWithUserInformation) { diff --git a/client/src/app/menu/menu.component.html b/client/src/app/menu/menu.component.html index 6f52f4f45..5ea859fd2 100644 --- a/client/src/app/menu/menu.component.html +++ b/client/src/app/menu/menu.component.html @@ -1,6 +1,6 @@
- Avatar + Avatar
{{ user.username }} diff --git a/client/src/app/menu/menu.component.ts b/client/src/app/menu/menu.component.ts index 8b8b714a8..1f66e3754 100644 --- a/client/src/app/menu/menu.component.ts +++ b/client/src/app/menu/menu.component.ts @@ -51,8 +51,8 @@ export class MenuComponent implements OnInit { ) } - getUserAvatarPath () { - return this.user.getAvatarPath() + getUserAvatarUrl () { + return this.user.getAvatarUrl() } isRegistrationAllowed () { diff --git a/client/src/app/shared/account/account.model.ts b/client/src/app/shared/account/account.model.ts index bacaa208a..cc46dad77 100644 --- a/client/src/app/shared/account/account.model.ts +++ b/client/src/app/shared/account/account.model.ts @@ -1,11 +1,13 @@ import { Account as ServerAccount } from '../../../../../shared/models/actors/account.model' import { Avatar } from '../../../../../shared/models/avatars/avatar.model' import { environment } from '../../../environments/environment' +import { getAbsoluteAPIUrl } from '../misc/utils' export class Account implements ServerAccount { id: number uuid: string name: string + displayName: string host: string followingCount: number followersCount: number @@ -13,9 +15,11 @@ export class Account implements ServerAccount { updatedAt: Date avatar: Avatar - static GET_ACCOUNT_AVATAR_PATH (account: Account) { - if (account && account.avatar) return account.avatar.path + static GET_ACCOUNT_AVATAR_URL (account: Account) { + const absoluteAPIUrl = getAbsoluteAPIUrl() - return '/client/assets/images/default-avatar.png' + if (account && account.avatar) return absoluteAPIUrl + account.avatar.path + + return window.location.origin + '/client/assets/images/default-avatar.png' } } diff --git a/client/src/app/shared/misc/utils.ts b/client/src/app/shared/misc/utils.ts index 5525e4efb..2739ff81a 100644 --- a/client/src/app/shared/misc/utils.ts +++ b/client/src/app/shared/misc/utils.ts @@ -1,5 +1,6 @@ // Thanks: https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript +import { environment } from '../../../environments/environment' import { AuthService } from '../../core/auth' function getParameterByName (name: string, url: string) { @@ -38,8 +39,19 @@ function populateAsyncUserVideoChannels (authService: AuthService, channel: any[ }) } +function getAbsoluteAPIUrl () { + let absoluteAPIUrl = environment.apiUrl + if (!absoluteAPIUrl) { + // The API is on the same domain + absoluteAPIUrl = window.location.origin + } + + return absoluteAPIUrl +} + export { viewportHeight, getParameterByName, - populateAsyncUserVideoChannels + populateAsyncUserVideoChannels, + getAbsoluteAPIUrl } diff --git a/client/src/app/shared/users/user.model.ts b/client/src/app/shared/users/user.model.ts index 7a962ae3e..83aae4463 100644 --- a/client/src/app/shared/users/user.model.ts +++ b/client/src/app/shared/users/user.model.ts @@ -57,7 +57,7 @@ export class User implements UserServerModel { return hasUserRight(this.role, right) } - getAvatarPath () { - return Account.GET_ACCOUNT_AVATAR_PATH(this.account) + getAvatarUrl () { + return Account.GET_ACCOUNT_AVATAR_URL(this.account) } } diff --git a/client/src/app/shared/users/user.service.ts b/client/src/app/shared/users/user.service.ts index d97edbcbe..58ddaa5ee 100644 --- a/client/src/app/shared/users/user.service.ts +++ b/client/src/app/shared/users/user.service.ts @@ -5,6 +5,7 @@ import 'rxjs/add/operator/map' import { UserCreate, UserUpdateMe } from '../../../../../shared' import { environment } from '../../../environments/environment' import { RestExtractor } from '../rest' +import { User } from './user.model' @Injectable() export class UserService { @@ -34,9 +35,24 @@ export class UserService { .catch(res => this.restExtractor.handleError(res)) } + changeAvatar (avatarForm: FormData) { + const url = UserService.BASE_USERS_URL + 'me/avatar/pick' + + return this.authHttp.post(url, avatarForm) + .catch(this.restExtractor.handleError) + } + signup (userCreate: UserCreate) { return this.authHttp.post(UserService.BASE_USERS_URL + 'register', userCreate) .map(this.restExtractor.extractDataBool) .catch(res => this.restExtractor.handleError(res)) } + + getMyInformation () { + const url = UserService.BASE_USERS_URL + 'me' + + return this.authHttp.get(url) + .map((userHash: any) => new User(userHash)) + .catch(res => this.restExtractor.handleError(res)) + } } diff --git a/client/src/app/shared/video/abstract-video-list.ts b/client/src/app/shared/video/abstract-video-list.ts index bfe46bcdd..354373776 100644 --- a/client/src/app/shared/video/abstract-video-list.ts +++ b/client/src/app/shared/video/abstract-video-list.ts @@ -83,7 +83,7 @@ export abstract class AbstractVideoList implements OnInit { this.videos = this.videos.concat(videos) } }, - error => this.notificationsService.error('Error', error.text) + error => this.notificationsService.error('Error', error.message) ) } diff --git a/client/src/app/shared/video/video.model.ts b/client/src/app/shared/video/video.model.ts index f159464c5..060bf933f 100644 --- a/client/src/app/shared/video/video.model.ts +++ b/client/src/app/shared/video/video.model.ts @@ -2,6 +2,7 @@ import { User } from '../' import { Video as VideoServerModel } from '../../../../../shared' import { Account } from '../../../../../shared/models/actors' import { environment } from '../../../environments/environment' +import { getAbsoluteAPIUrl } from '../misc/utils' export class Video implements VideoServerModel { accountName: string @@ -48,11 +49,7 @@ export class Video implements VideoServerModel { } constructor (hash: VideoServerModel) { - let absoluteAPIUrl = environment.apiUrl - if (!absoluteAPIUrl) { - // The API is on the same domain - absoluteAPIUrl = window.location.origin - } + const absoluteAPIUrl = getAbsoluteAPIUrl() this.accountName = hash.accountName this.createdAt = new Date(hash.createdAt.toString()) diff --git a/client/src/app/videos/+video-edit/shared/video-edit.component.scss b/client/src/app/videos/+video-edit/shared/video-edit.component.scss index 81e3a0d19..0fefcee28 100644 --- a/client/src/app/videos/+video-edit/shared/video-edit.component.scss +++ b/client/src/app/videos/+video-edit/shared/video-edit.component.scss @@ -144,8 +144,3 @@ } } } - -.little-information { - font-size: 0.8em; - font-style: italic; -} diff --git a/client/src/app/videos/+video-edit/video-add.component.scss b/client/src/app/videos/+video-edit/video-add.component.scss index 891f38819..4bb509009 100644 --- a/client/src/app/videos/+video-edit/video-add.component.scss +++ b/client/src/app/videos/+video-edit/video-add.component.scss @@ -34,30 +34,9 @@ } .button-file { - position: relative; - overflow: hidden; - display: inline-block; - margin-bottom: 45px; - width: 190px; - - @include peertube-button; - @include orange-button; + @include peertube-button-file(190px); - input[type=file] { - position: absolute; - top: 0; - right: 0; - min-width: 100%; - min-height: 100%; - font-size: 100px; - text-align: right; - filter: alpha(opacity=0); - opacity: 0; - outline: none; - background: white; - cursor: inherit; - display: block; - } + margin-bottom: 45px; } } } diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts index 4afd6160c..0f44d3dd7 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts @@ -148,7 +148,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { this.router.navigate(['/videos/list']) }, - error => this.notificationsService.error('Error', error.text) + error => this.notificationsService.error('Error', error.message) ) } ) @@ -185,7 +185,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { error => { this.descriptionLoading = false - this.notificationsService.error('Error', error.text) + this.notificationsService.error('Error', error.message) } ) } @@ -217,7 +217,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { } getAvatarPath () { - return Account.GET_ACCOUNT_AVATAR_PATH(this.video.account) + return Account.GET_ACCOUNT_AVATAR_URL(this.video.account) } getVideoTags () { @@ -247,7 +247,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { this.router.navigate([ '/videos/list' ]) }, - error => this.notificationsService.error('Error', error.text) + error => this.notificationsService.error('Error', error.message) ) } ) diff --git a/client/src/sass/include/_mixins.scss b/client/src/sass/include/_mixins.scss index 252cf2173..140de1b2c 100644 --- a/client/src/sass/include/_mixins.scss +++ b/client/src/sass/include/_mixins.scss @@ -84,6 +84,32 @@ @include peertube-button; } +@mixin peertube-button-file ($width) { + position: relative; + overflow: hidden; + display: inline-block; + width: $width; + + @include peertube-button; + @include orange-button; + + input[type=file] { + position: absolute; + top: 0; + right: 0; + min-width: 100%; + min-height: 100%; + font-size: 100px; + text-align: right; + filter: alpha(opacity=0); + opacity: 0; + outline: none; + background: white; + cursor: inherit; + display: block; + } +} + @mixin avatar ($size) { width: $size; height: $size; -- cgit v1.2.3