From cf117aaafc1e9ae1ab4c388fc5d2e5ba9349efee Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 3 Jan 2018 17:25:47 +0100 Subject: [PATCH] Add avatar in comments --- client/src/app/menu/menu.component.html | 4 +- .../comment/video-comment-add.component.html | 14 +++-- .../comment/video-comment-add.component.scss | 21 ++++++-- .../comment/video-comment-add.component.ts | 6 +++ .../comment/video-comment.component.html | 54 +++++++++++-------- .../comment/video-comment.component.scss | 51 +++++++++--------- .../comment/video-comment.component.ts | 11 +++- .../comment/video-comment.model.ts | 6 +-- .../comment/video-comments.component.html | 1 + .../comment/video-comments.component.scss | 1 + .../comment/video-comments.component.ts | 1 - .../+video-watch/video-watch.component.html | 10 ++-- .../+video-watch/video-watch.component.scss | 6 +-- .../custom-validators/activitypub/actor.ts | 6 --- server/models/video/video-comment.ts | 10 ++-- server/tests/api/videos/video-comments.ts | 16 +++++- shared/models/videos/video-comment.model.ts | 7 ++- 17 files changed, 140 insertions(+), 85 deletions(-) diff --git a/client/src/app/menu/menu.component.html b/client/src/app/menu/menu.component.html index 5ea859fd2..d138d2ba7 100644 --- a/client/src/app/menu/menu.component.html +++ b/client/src/app/menu/menu.component.html @@ -1,6 +1,8 @@
- Avatar + + Avatar +
{{ user.username }} diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.html b/client/src/app/videos/+video-watch/comment/video-comment-add.component.html index 365fc8f6c..0eaa0d447 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment-add.component.html +++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.html @@ -1,9 +1,13 @@
-
- -
- {{ formErrors.text }} +
+ Avatar + +
+ +
+ {{ formErrors.text }} +
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.scss b/client/src/app/videos/+video-watch/comment/video-comment-add.component.scss index 9661062e8..37097da72 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment-add.component.scss +++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.scss @@ -1,12 +1,25 @@ @import '_variables'; @import '_mixins'; -.form-group { +.avatar-and-textarea { + display: flex; margin-bottom: 10px; -} -textarea { - @include peertube-textarea(100%, 150px); + img { + @include avatar(36px); + + vertical-align: top; + margin-right: 20px; + } + + .form-group { + flex-grow: 1; + margin: 0; + + textarea { + @include peertube-textarea(100%, 60px); + } + } } .submit-comment { diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts index a6525987e..27655eca7 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts +++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts @@ -5,6 +5,7 @@ import { Observable } from 'rxjs/Observable' import { VideoCommentCreate } from '../../../../../../shared/models/videos/video-comment.model' import { FormReactive } from '../../../shared' import { VIDEO_COMMENT_TEXT } from '../../../shared/forms/form-validators/video-comment' +import { User } from '../../../shared/users' import { Video } from '../../../shared/video/video.model' import { VideoComment } from './video-comment.model' import { VideoCommentService } from './video-comment.service' @@ -15,6 +16,7 @@ import { VideoCommentService } from './video-comment.service' styleUrls: ['./video-comment-add.component.scss'] }) export class VideoCommentAddComponent extends FormReactive implements OnInit { + @Input() user: User @Input() video: Video @Input() parentComment: VideoComment @Input() focusOnInit = false @@ -79,6 +81,10 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit { return this.form.value['text'] } + getUserAvatarUrl () { + return this.user.getAvatarUrl() + } + private addCommentReply (commentCreate: VideoCommentCreate) { return this.videoCommentService .addCommentReply(this.video.id, this.parentComment.id, commentCreate) diff --git a/client/src/app/videos/+video-watch/comment/video-comment.component.html b/client/src/app/videos/+video-watch/comment/video-comment.component.html index ffaf722cd..e9c23929c 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment.component.html +++ b/client/src/app/videos/+video-watch/comment/video-comment.component.html @@ -1,29 +1,37 @@ -
- -
{{ comment.text }}
+
+ Avatar -
-
Reply
-
+
+ +
{{ comment.text }}
+ +
+
Reply
+
- + -
-
- +
+
+ +
diff --git a/client/src/app/videos/+video-watch/comment/video-comment.component.scss b/client/src/app/videos/+video-watch/comment/video-comment.component.scss index 7e1a32f48..aae03ab6d 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment.component.scss +++ b/client/src/app/videos/+video-watch/comment/video-comment.component.scss @@ -1,38 +1,41 @@ @import '_variables'; @import '_mixins'; -.comment { +.root-comment { font-size: 15px; - margin-top: 30px; + display: flex; - .comment-account-date { - display: flex; - margin-bottom: 4px; + img { + @include avatar(36px); - .comment-account { - font-weight: $font-bold; - } - - .comment-date { - color: #585858; - margin-left: 10px; - } + margin-top: 5px; + margin-right: 20px; } - .comment-actions { - margin: 10px 0; + .comment { + flex-grow: 1; + + .comment-account-date { + display: flex; + margin-bottom: 4px; - .comment-action-reply { - color: #585858; - cursor: pointer; + .comment-account { + font-weight: $font-bold; + } + + .comment-date { + color: #585858; + margin-left: 10px; + } } - } -} -.children { - margin-left: 20px; + .comment-actions { + margin: 10px 0; - .comment { - margin-top: 15px; + .comment-action-reply { + color: #585858; + cursor: pointer; + } + } } } diff --git a/client/src/app/videos/+video-watch/comment/video-comment.component.ts b/client/src/app/videos/+video-watch/comment/video-comment.component.ts index 5af6e3335..b305c639a 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment.component.ts +++ b/client/src/app/videos/+video-watch/comment/video-comment.component.ts @@ -1,6 +1,8 @@ import { Component, EventEmitter, Input, Output } from '@angular/core' +import { Account as AccountInterface } from '../../../../../../shared/models/actors' import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model' import { AuthService } from '../../../core/auth' +import { Account } from '../../../shared/account/account.model' import { Video } from '../../../shared/video/video.model' import { VideoComment } from './video-comment.model' @@ -18,7 +20,10 @@ export class VideoCommentComponent { @Output() wantedToReply = new EventEmitter() @Output() resetReply = new EventEmitter() - constructor (private authService: AuthService) { + constructor (private authService: AuthService) {} + + get user () { + return this.authService.getUser() } onCommentReplyCreated (createdComment: VideoComment) { @@ -52,4 +57,8 @@ export class VideoCommentComponent { onResetReply () { this.resetReply.emit() } + + getAvatarUrl (account: AccountInterface) { + return Account.GET_ACCOUNT_AVATAR_URL(account) + } } diff --git a/client/src/app/videos/+video-watch/comment/video-comment.model.ts b/client/src/app/videos/+video-watch/comment/video-comment.model.ts index df7d5244c..abecae303 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment.model.ts +++ b/client/src/app/videos/+video-watch/comment/video-comment.model.ts @@ -1,3 +1,4 @@ +import { Account } from '../../../../../../shared/models/actors' import { VideoComment as VideoCommentServerModel } from '../../../../../../shared/models/videos/video-comment.model' export class VideoComment implements VideoCommentServerModel { @@ -9,10 +10,7 @@ export class VideoComment implements VideoCommentServerModel { videoId: number createdAt: Date | string updatedAt: Date | string - account: { - name: string - host: string - } + account: Account totalReplies: number by: string diff --git a/client/src/app/videos/+video-watch/comment/video-comments.component.html b/client/src/app/videos/+video-watch/comment/video-comments.component.html index 078900e06..4a4248073 100644 --- a/client/src/app/videos/+video-watch/comment/video-comments.component.html +++ b/client/src/app/videos/+video-watch/comment/video-comments.component.html @@ -7,6 +7,7 @@ diff --git a/client/src/app/videos/+video-watch/comment/video-comments.component.scss b/client/src/app/videos/+video-watch/comment/video-comments.component.scss index 2f6e4663b..be122eb2c 100644 --- a/client/src/app/videos/+video-watch/comment/video-comments.component.scss +++ b/client/src/app/videos/+video-watch/comment/video-comments.component.scss @@ -5,6 +5,7 @@ font-weight: $font-semibold; font-size: 15px; cursor: pointer; + margin-left: 56px; } .glyphicon, .comment-thread-loading { diff --git a/client/src/app/videos/+video-watch/comment/video-comments.component.ts b/client/src/app/videos/+video-watch/comment/video-comments.component.ts index 4d801c970..1230725c1 100644 --- a/client/src/app/videos/+video-watch/comment/video-comments.component.ts +++ b/client/src/app/videos/+video-watch/comment/video-comments.component.ts @@ -6,7 +6,6 @@ import { ComponentPagination } from '../../../shared/rest/component-pagination.m import { User } from '../../../shared/users' import { SortField } from '../../../shared/video/sort-field.type' import { VideoDetails } from '../../../shared/video/video-details.model' -import { Video } from '../../../shared/video/video.model' import { VideoComment } from './video-comment.model' import { VideoCommentService } from './video-comment.service' diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html index 48d1bb474..514a86e28 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.html +++ b/client/src/app/videos/+video-watch/video-watch.component.html @@ -14,14 +14,16 @@
+ *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'like' }" (click)="setLike()" + class="action-button action-button-like" + >
+ *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'dislike' }" (click)="setDislike()" + class="action-button action-button-dislike" + >
diff --git a/client/src/app/videos/+video-watch/video-watch.component.scss b/client/src/app/videos/+video-watch/video-watch.component.scss index c101aa04e..7ebdfc0c4 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.scss +++ b/client/src/app/videos/+video-watch/video-watch.component.scss @@ -176,9 +176,9 @@ font-size: 13px; img { - width: 16px; - height: 16px; - margin-left: 3px; + @include avatar(18px); + + margin-left: 7px; } } diff --git a/server/helpers/custom-validators/activitypub/actor.ts b/server/helpers/custom-validators/activitypub/actor.ts index 8820bb2a4..e1a4b5b8f 100644 --- a/server/helpers/custom-validators/activitypub/actor.ts +++ b/server/helpers/custom-validators/activitypub/actor.ts @@ -1,8 +1,6 @@ import * as validator from 'validator' import { CONSTRAINTS_FIELDS } from '../../../initializers' -import { isAccountNameValid } from '../accounts' import { exists } from '../misc' -import { isVideoChannelNameValid } from '../video-channels' import { isActivityPubUrlValid, isBaseActivityValid, setValidAttributedTo } from './misc' function isActorEndpointsObjectValid (endpointObject: any) { @@ -32,10 +30,6 @@ function isActorPreferredUsernameValid (preferredUsername: string) { return exists(preferredUsername) && validator.matches(preferredUsername, actorNameRegExp) } -function isActorNameValid (name: string) { - return isAccountNameValid(name) || isVideoChannelNameValid(name) -} - function isActorPrivateKeyValid (privateKey: string) { return exists(privateKey) && typeof privateKey === 'string' && diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts index 63675c20b..d2d8945c3 100644 --- a/server/models/video/video-comment.ts +++ b/server/models/video/video-comment.ts @@ -9,6 +9,7 @@ import { isActivityPubUrlValid } from '../../helpers/custom-validators/activityp import { CONSTRAINTS_FIELDS } from '../../initializers' import { AccountModel } from '../account/account' import { ActorModel } from '../activitypub/actor' +import { AvatarModel } from '../avatar/avatar' import { ServerModel } from '../server/server' import { getSort, throwIfNotValid } from '../utils' import { VideoModel } from './video' @@ -46,6 +47,10 @@ enum ScopeNames { { model: () => ServerModel, required: false + }, + { + model: () => AvatarModel, + required: false } ] } @@ -243,10 +248,7 @@ export class VideoCommentModel extends Model { createdAt: this.createdAt, updatedAt: this.updatedAt, totalReplies: this.get('totalReplies') || 0, - account: { - name: this.Account.name, - host: this.Account.Actor.getHost() - } + account: this.Account.toFormattedJSON() } as VideoComment } diff --git a/server/tests/api/videos/video-comments.ts b/server/tests/api/videos/video-comments.ts index 3b6578f04..604a3027d 100644 --- a/server/tests/api/videos/video-comments.ts +++ b/server/tests/api/videos/video-comments.ts @@ -3,7 +3,11 @@ import * as chai from 'chai' import 'mocha' import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' -import { dateIsValid, flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils/index' +import { testVideoImage } from '../../utils' +import { + dateIsValid, flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, updateMyAvatar, + uploadVideo +} from '../../utils/index' import { addVideoCommentReply, addVideoCommentThread, getVideoCommentThreads, getVideoThreadComments @@ -29,6 +33,12 @@ describe('Test video comments', function () { const res = await uploadVideo(server.url, server.accessToken, {}) videoUUID = res.body.video.uuid videoId = res.body.video.id + + await updateMyAvatar({ + url: server.url, + accessToken: server.accessToken, + fixture: 'avatar.png' + }) }) it('Should not have threads on this video', async function () { @@ -70,6 +80,10 @@ describe('Test video comments', function () { expect(comment.id).to.equal(comment.threadId) expect(comment.account.name).to.equal('root') expect(comment.account.host).to.equal('localhost:9001') + + const test = await testVideoImage(server.url, 'avatar-resized', comment.account.avatar.path, '.png') + expect(test).to.equal(true) + expect(comment.totalReplies).to.equal(0) expect(dateIsValid(comment.createdAt as string)).to.be.true expect(dateIsValid(comment.updatedAt as string)).to.be.true diff --git a/shared/models/videos/video-comment.model.ts b/shared/models/videos/video-comment.model.ts index d572927c2..7ac4024fb 100644 --- a/shared/models/videos/video-comment.model.ts +++ b/shared/models/videos/video-comment.model.ts @@ -1,3 +1,5 @@ +import { Account } from '../actors' + export interface VideoComment { id: number url: string @@ -8,10 +10,7 @@ export interface VideoComment { createdAt: Date | string updatedAt: Date | string totalReplies: number - account: { - name: string - host: string - } + account: Account } export interface VideoCommentThreadTree { -- 2.25.1