diff --git a/src/app/components/shared/comment/comment.component.html b/src/app/components/shared/comment/comment.component.html index d1363c0363e71a1e831fa1e5f5227372e785cf82..23494d799cf0c4fb89fe18ae5f70c12a25d9c609 100644 --- a/src/app/components/shared/comment/comment.component.html +++ b/src/app/components/shared/comment/comment.component.html @@ -1,29 +1,30 @@ -<mat-card class="card-container"> - <div fxLayout="column"> - <div fxLayout="row"> - <span class="fill-remaining-space"></span> - <button mat-icon-button *ngIf="comment.correct || !isStudent" [disabled]="isStudent" (click)="setCorrect(comment)" [matTooltip]="comment.correct ? 'Unmark as correct' : 'Mark as correct'"> - <mat-icon [ngClass]="{true : 'correct-icon', false: 'incorrect-icon'}[comment.correct]">check_circle</mat-icon> - </button> - <button mat-icon-button *ngIf="comment.favorite || !isStudent" [disabled]="isStudent" (click)="setFavorite(comment)" [matTooltip]="comment.favorite ? 'Mark as not favorite' : 'Mark as favorite'"> - <mat-icon [ngClass]="{true: 'favorite-icon', false: 'not-favorite-icon'}[comment.favorite]">star</mat-icon> - </button> - <button mat-icon-button [disabled]="isStudent" (click)="setRead(comment)" [matTooltip]="comment.read ? 'Mark as unread' : 'Mark as read'"> - <mat-icon [ngClass]="{true: 'read-icon', false: 'unread-icon'}[comment.read]">visibility</mat-icon> - </button> - </div> - <div fxLayout="row"> - <div class="body" (click)="openPresentDialog(comment.body)">{{comment.body}}</div> - <span class="fill-remaining-space"></span> - <div fxLayout="column"> - <button mat-icon-button [disabled]="!isStudent" (click)="voteUp(comment)"> - <mat-icon class="voting-icon" [ngClass]="{'upvoted' : hasVoted === 1}">keyboard_arrow_up</mat-icon> +<mat-card class="card-container" [@slide]> + <div fxLayout="column"> + <div fxLayout="row"> + <span class="fill-remaining-space"></span> + <button mat-icon-button *ngIf="comment.correct || !isStudent" [disabled]="isStudent" (click)="setCorrect(comment)" [matTooltip]="comment.correct ? 'Unmark as correct' : 'Mark as correct'"> + <mat-icon [ngClass]="{true : 'correct-icon', false: 'incorrect-icon'}[comment.correct]">check_circle</mat-icon> + </button> + <button mat-icon-button *ngIf="comment.favorite || !isStudent" [disabled]="isStudent" (click)="setFavorite(comment)" [matTooltip]="comment.favorite ? 'Mark as not favorite' : 'Mark as favorite'"> + <mat-icon [ngClass]="{true: 'favorite-icon', false: 'not-favorite-icon'}[comment.favorite]">star</mat-icon> </button> - <h2>{{comment.score}}</h2> - <button mat-icon-button [disabled]="!isStudent" (click)="voteDown(comment)"> - <mat-icon class="voting-icon" [ngClass]="{'downvoted' : hasVoted === -1}">keyboard_arrow_down</mat-icon> + <button mat-icon-button [disabled]="isStudent" (click)="setRead(comment)" [matTooltip]="comment.read ? 'Mark as unread' : 'Mark as read'"> + <mat-icon [ngClass]="{true: 'read-icon', false: 'unread-icon'}[comment.read]">visibility</mat-icon> </button> </div> + <div fxLayout="row"> + <div class="body" (click)="openPresentDialog(comment.body)">{{comment.body}}</div> + <span class="fill-remaining-space"></span> + <div fxLayout="column" (tap)="startAnimation('rubberBand')" [@rubberBand]="animationState" (@rubberBand.done)="resetAnimationState()"> + <button mat-icon-button [disabled]="!isStudent" (click)="voteUp(comment)" > + <mat-icon class="voting-icon" [ngClass]="{'upvoted' : hasVoted === 1}">keyboard_arrow_up</mat-icon> + </button> + <h2>{{comment.score}}</h2> + <button mat-icon-button [disabled]="!isStudent" (click)="voteDown(comment)"> + <mat-icon class="voting-icon" [ngClass]="{'downvoted' : hasVoted === -1}">keyboard_arrow_down</mat-icon> + </button> + </div> + </div> </div> - </div> -</mat-card> + </mat-card> + \ No newline at end of file diff --git a/src/app/components/shared/comment/comment.component.ts b/src/app/components/shared/comment/comment.component.ts index 36fbd582fe3fe8fae5f332d26a1e767c1178e665..2af7a5a05e93c80750089c3634b744726693a29f 100644 --- a/src/app/components/shared/comment/comment.component.ts +++ b/src/app/components/shared/comment/comment.component.ts @@ -10,28 +10,51 @@ import { LanguageService } from '../../../services/util/language.service'; import { WsCommentServiceService } from '../../../services/websockets/ws-comment-service.service'; import { PresentCommentComponent } from '../_dialogs/present-comment/present-comment.component'; import { MatDialog } from '@angular/material'; +import { trigger, transition, style, animate, state, keyframes } from '@angular/animations'; + +export const rubberBand = [ + style({ transform: 'scale3d(1, 1, 1)', offset: 0 }), + style({ transform: 'scale3d(1.05, 0.75, 1)', offset: 0.3 }), + style({ transform: 'scale3d(0.75, 1.05, 1)', offset: 0.4 }), + style({ transform: 'scale3d(1.05, 0.95, 1)', offset: 0.5 }), + style({ transform: 'scale3d(0.95, 1.05, 1)', offset: 0.65 }), + style({ transform: 'scale3d(1.05, 0.95, 1)', offset: 0.75 }), + style({ transform: 'scale3d(1, 1, 1)', offset: 1 }) +]; @Component({ selector: 'app-comment', templateUrl: './comment.component.html', - styleUrls: ['./comment.component.scss'] + styleUrls: ['./comment.component.scss'], + animations: [ + trigger('slide', [ + state('void', style({ opacity: 0, transform: 'translateY(-10px)' })), + transition('void <=> *', animate(700)), + ]), + trigger('rubberBand', [ + transition('* => rubberBand', animate(1000, keyframes(rubberBand))), + ]) + ] }) + export class CommentComponent implements OnInit { @Input() comment: Comment; isStudent = false; isLoading = true; hasVoted = 0; + animationState: string; constructor(protected authenticationService: AuthenticationService, - private route: ActivatedRoute, - private location: Location, - private commentService: CommentService, - private notification: NotificationService, - private translateService: TranslateService, - public dialog: MatDialog, - protected langService: LanguageService, - private wsCommentService: WsCommentServiceService) { - langService.langEmitter.subscribe(lang => translateService.use(lang)); } + private route: ActivatedRoute, + private location: Location, + private commentService: CommentService, + private notification: NotificationService, + private translateService: TranslateService, + public dialog: MatDialog, + protected langService: LanguageService, + private wsCommentService: WsCommentServiceService) { + langService.langEmitter.subscribe(lang => translateService.use(lang)); + } ngOnInit() { if (this.authenticationService.getRole() === 0) { @@ -40,6 +63,16 @@ export class CommentComponent implements OnInit { this.translateService.use(localStorage.getItem('currentLang')); } + startAnimation(state_: any): void { + if (!this.animationState) { + this.animationState = state_; + } + } + + resetAnimationState(): void { + this.animationState = ''; + } + setRead(comment: Comment): void { this.comment = this.wsCommentService.toggleRead(comment); }