aboutsummaryrefslogtreecommitdiff
path: root/src/app/components/comment
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/components/comment')
-rw-r--r--src/app/components/comment/comment.component.css54
-rw-r--r--src/app/components/comment/comment.component.html57
-rw-r--r--src/app/components/comment/comment.component.ts82
3 files changed, 132 insertions, 61 deletions
diff --git a/src/app/components/comment/comment.component.css b/src/app/components/comment/comment.component.css
index 419cbf8..48d9174 100644
--- a/src/app/components/comment/comment.component.css
+++ b/src/app/components/comment/comment.component.css
@@ -1,56 +1,30 @@
-.comment {
- display: flex;
- flex-direction: column;
- width: 100%;
-
- margin: .5em auto;
+.left-pane {
box-sizing: border-box;
- padding: .5em;
- background-color: var(--card-bg);
-}
-
-.comment:first-child {
- margin-top: 0;
}
/* Author */
-.author {
- display: flex;
- margin-bottom: .2em;
-}
-
-.author:hover {
- cursor: pointer;
-}
-
-.author > img {
- width: 1.7em;
- height: 1.7em;
- margin-right: .2em;
+.author-picture {
+ width: 2.2em;
+ height: 2.2em;
}
-.author-info > .name {
- font-size: .8em;
-}
+/* Content */
-.author-info > .handle {
- font-size: .6em;
- color: gray;
+.content {
+ padding: 0 var(--card-padding);
}
-/* Content */
-
.message {
- margin: .3em 0;
- word-break: break-all;
+ word-break: break-word;
}
-.timestamp {
- font-size: .5em;
- color: gray;
+.comment-details {
+ margin-bottom: calc(var(--card-padding) / 1.5);
+ padding: 0.2em 0;
}
-.message:hover, .timestamp:hover {
- cursor: pointer;
+.comment-details > * {
+ margin-left: 1.1em;
}
+
diff --git a/src/app/components/comment/comment.component.html b/src/app/components/comment/comment.component.html
index e46bdb7..9403ea2 100644
--- a/src/app/components/comment/comment.component.html
+++ b/src/app/components/comment/comment.component.html
@@ -1,21 +1,46 @@
<app-loading *ngIf="!loaded"></app-loading>
-<section class="comment rounded-border" *ngIf="loaded">
- <summary class="author" (click)="goToAuthorProfile()">
- <img class="round-image" [src]="user.profilePictureURL">
- <div class="author-info">
- <div class="name">
+<section class="card flex-row" [hidden]="loaded" (mouseleave)="resetShareBtn()">
+ <aside class="left-pane">
+ <img class="author-picture round-image hover-half-opacity" [src]="user.profilePictureURL" (click)="goToAuthorProfile()">
+ </aside>
+ <main class="content flexible">
+ <summary class="font-size-dot8 text-vertical-middle hover-half-opacity" (click)="goToAuthorProfile()">
+ <span>
{{ user.firstName }} {{ user.lastName }}
- </div>
- <div class="handle">
+ </span>
+ <span class="fg-faded">
@{{ user.userName }}
- </div>
- </div>
- </summary>
- <article class="message" (click)="goToCommentPage()">
- {{ comment.message }}
- </article>
- <time class="timestamp" (click)="goToCommentPage()">
- {{ timeCreated }}
- </time>
+ </span>
+ </summary>
+ <form [formGroup]="editCommentFormGroup" *ngIf="editingComment" (ngSubmit)="editComment()">
+ <textarea class="textarea-new-msg width-full border-faded-slim border-bottom-only padding-dot2 margin-bot-dot5" rows="1" formControlName="newCommentMessage" placeholder="What's on your mind?"></textarea>
+ <button type="submit" class="border-faded-slim width-full padding-dot2 lighter-hover click-effect border-radius-dot3 margin-bot-dot5">
+ Update Comment
+ </button>
+ </form>
+ <article class="message margin-top-bot-dot2" *ngIf="!editingComment">
+ {{ comment.message }}
+ </article>
+ <section class="comment-details flex-row flex-justify-end font-size-dot7 border-faded-slim border-bottom-only">
+ <time class="flex-row flex-center-align-items">
+ <img class="height-font" src="/assets/icons/tabler-icon-calendar-time.svg">&nbsp;
+ <span>
+ {{ timeCreated }}
+ </span>
+ </time>
+ </section>
+ <section class="flex-row justify-children-center align-children-center">
+ <button class="padding-dot2 lighter-hover click-effect border-radius-dot3" *ngIf="loggedInAuthor" (click)="toggleEditing()">
+ <img src="/assets/icons/tabler-icon-edit.svg">
+ </button>
+ <button #share ngxClipboard [cbContent]="getPostLink()" class="flexible padding-dot2 lighter-hover click-effect border-radius-dot3" (click)="showCopiedMessage()">
+ <img src="/assets/icons/tabler-icon-link.svg">
+ &nbsp;Share
+ </button>
+ <button class="padding-dot2 lighter-hover click-effect border-radius-dot3" *ngIf="loggedInAuthor" (click)="deleteComment()">
+ <img src="/assets/icons/tabler-icon-trash.svg">
+ </button>
+ </section>
+ </main>
</section>
diff --git a/src/app/components/comment/comment.component.ts b/src/app/components/comment/comment.component.ts
index 7da896d..2a54f92 100644
--- a/src/app/components/comment/comment.component.ts
+++ b/src/app/components/comment/comment.component.ts
@@ -1,7 +1,9 @@
-import { Component, Input, OnInit } from '@angular/core';
+import { AfterViewInit, Component, ElementRef, Input, OnInit, Renderer2, ViewChild } from '@angular/core';
+import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { Router } from '@angular/router';
import { Guid } from 'guid-typescript';
import { CommentService } from 'src/app/services/comment.service';
+import { TokenService } from 'src/app/services/token.service';
import { UserService } from 'src/app/services/user.service';
import { Comment } from 'src/models/comment.model';
import { User } from 'src/models/identity/user.model';
@@ -11,14 +13,20 @@ import { User } from 'src/models/identity/user.model';
templateUrl: './comment.component.html',
styleUrls: ['./comment.component.css']
})
-export class CommentComponent implements OnInit {
+export class CommentComponent implements OnInit, AfterViewInit {
public loaded = false;
+ public loggedInAuthor = false;
+ public editingComment = false;
public user: User;
public comment: Comment;
public timeCreated: string;
@Input() paramId: string;
+ public editCommentFormGroup: FormGroup;
+ @ViewChild('share') shareBtn: ElementRef;
+ private _defaultShareBtnInnerHTML: string;
+ private _linkShared = false;
- constructor(private _router: Router, private _commentService: CommentService, private _userService: UserService)
+ constructor(private _router: Router, private _commentService: CommentService, private _userService: UserService, private _tokenService: TokenService, private _fb: FormBuilder, private _elem: ElementRef, private _renderer: Renderer2)
{ }
ngOnInit(): void {
@@ -33,22 +41,86 @@ export class CommentComponent implements OnInit {
this.loadUser();
}
});
+
+ this.editCommentFormGroup = this._fb.group({
+ newCommentMessage: new FormControl('')
+ });
}
private loadUser(): void {
this._userService.getUserByUsernameRequest(this.comment.issuerUsername).subscribe({
next: (result: object) => {
Object.assign(this.user, result);
+
+ if (this._tokenService.getTokenFromSessionStorage() !== '') {
+ this.loggedInAuthor = this._tokenService.getUsernameFromSessionStorageToken() === this.comment.issuerUsername;
+ this.editCommentFormGroup.get('newCommentMessage')?.setValue(this.comment.message);
+ }
+
this.loaded = true;
}
});
}
+ ngAfterViewInit(): void {
+ this._defaultShareBtnInnerHTML = this.shareBtn.nativeElement.innerHTML;
+ }
+
goToAuthorProfile(): void {
this._router.navigate(['/profile/' + this.comment.issuerUsername]);
}
- goToCommentPage(): void {
- this._router.navigate(['/comment/' + this.comment.commentId]);
+ toggleEditing(): void {
+ this.editingComment = !this.editingComment;
+ }
+
+ editComment(): void {
+ if (this._tokenService.getTokenFromSessionStorage() === '') {
+ this._router.navigate(['/login']);
+ return;
+ }
+
+ if (this.editingComment) {
+ const newMessage = this.editCommentFormGroup.get('newCommentMessage')?.value;
+
+ if (newMessage !== '' && newMessage !== this.comment.message) {
+ this._commentService.putCommentWithSessionStorageRequest(Guid.parse(this.paramId), this.comment.postId, newMessage).subscribe({
+ next: () => {
+ this.reloadPage();
+ }
+ });
+ }
+ }
+ this.editingComment = !this.editingComment;
+ }
+
+ deleteComment(): void {
+ this._commentService.deleteCommentWithSessionStorage(Guid.parse(this.paramId)).subscribe({
+ next: () => {
+ this.reloadPage();
+ }
+ });
+ }
+
+ private reloadPage(): void {
+ this._router.routeReuseStrategy.shouldReuseRoute = () => false;
+ this._router.onSameUrlNavigation = 'reload';
+ this._router.navigate([this._router.url]);
+ }
+
+ resetShareBtn(): void {
+ if (this._linkShared) {
+ this._renderer.setProperty(this.shareBtn.nativeElement, 'innerHTML', this._defaultShareBtnInnerHTML);
+ this._linkShared = false;
+ }
+ }
+
+ showCopiedMessage(): void {
+ this._renderer.setProperty(this.shareBtn.nativeElement, 'innerHTML', 'Link copied to clipboard!');
+ this._linkShared = true;
+ }
+
+ getPostLink(): string {
+ return location.origin + '/comment/' + this.paramId;
}
}