Skip to content
This repository was archived by the owner on Nov 20, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 57 additions & 48 deletions src/app/comments/comment/comment.component.html
Original file line number Diff line number Diff line change
@@ -1,66 +1,75 @@
<!-- display comment -->
<div *ngIf="!isEditing" class="comment-wrapper">

<!-- content of the comment -->
<section class="comment-content">
<app-editor-output [value]="comment.content"></app-editor-output>
</section>
<div *ngIf="!isReaction" class="vote-wrapper">
<app-vote
[votes]="comment.votes"
(vote)="onVote($event)"
>
</app-vote>
</div>

<section class="comment-info">
<div class="body-wrapper">
<!-- content of the comment -->
<section class="comment-content">
<app-editor-output [value]="comment.content"></app-editor-output>
</section>

<!-- comment creator and creationtime -->
<app-user-small [user]="comment.creator"></app-user-small>
<span>{{comment.created | amTimeAgo}}</span>
<section class="comment-info">

<!-- action buttons -->
<!-- comment creator and creationtime -->
<app-user-small [user]="comment.creator"></app-user-small>
<span>{{comment.created | amTimeAgo}}</span>

<!-- reply -->
<button [disabled]="areButtonsDisabled"
*ngIf="!isReaction"
(click)="displayReactionForm(true)">reply</button>
<!-- action buttons -->

<!-- edit (only when logged user is creator) -->
<button [disabled]="areButtonsDisabled"
(click)="editComment(true)"
*ngIf="isCreatorMe">edit</button>

<!-- delete (only when logged user is creator) -->
<!-- when clicked, ask for confirmation -->
<button [disabled]="areButtonsDisabled"
*ngIf="isCreatorMe" (click)="askReallyDelete(true)">delete</button>
<!-- reply -->
<button [disabled]="areButtonsDisabled"
*ngIf="!isReaction"
(click)="displayReactionForm(true)">reply</button>

<!-- delete confirmation -->
<span *ngIf="isDeleteDisplayed">
Really delete?
<!-- yes -->
<!-- edit (only when logged user is creator) -->
<button [disabled]="areButtonsDisabled"
(click)="deleteComment()">yes</button>
<!-- no -->
(click)="editComment(true)"
*ngIf="isCreatorMe">edit</button>

<!-- delete (only when logged user is creator) -->
<!-- when clicked, ask for confirmation -->
<button [disabled]="areButtonsDisabled"
(click)="askReallyDelete(false)">no</button>
</span>
*ngIf="isCreatorMe" (click)="askReallyDelete(true)">delete</button>

<!-- end of action buttons -->
</section>
<!-- delete confirmation -->
<span *ngIf="isDeleteDisplayed">
Really delete?
<!-- yes -->
<button [disabled]="areButtonsDisabled"
(click)="deleteComment()">yes</button>
<!-- no -->
<button [disabled]="areButtonsDisabled"
(click)="askReallyDelete(false)">no</button>
</span>

<!-- replying form -->
<section *ngIf="isReplying">
<app-comment-form
[isNew]="false"
(cancel)="displayReactionForm(false)"
(submitComment)="createReaction($event)"
submitButtonText="Reply"></app-comment-form>
</section>
<!-- end of action buttons -->
</section>

<!-- replies -->
<section *ngIf="!isReaction">
<ul>
<li *ngFor="let reaction of comment.reactions">
<app-comment (remove)="removeReaction(reaction)" [isReaction]="true" [comment]="reaction"></app-comment>
</li>
</ul>
</section>
<!-- replying form -->
<section *ngIf="isReplying">
<app-comment-form
[isNew]="false"
(cancel)="displayReactionForm(false)"
(submitComment)="createReaction($event)"
submitButtonText="Reply"></app-comment-form>
</section>

<!-- replies -->
<section *ngIf="!isReaction">
<ul>
<li *ngFor="let reaction of comment.reactions">
<app-comment (remove)="removeReaction(reaction)" [isReaction]="true" [comment]="reaction"></app-comment>
</li>
</ul>
</section>
</div>
</div>

<!-- edit comment -->
Expand Down
9 changes: 9 additions & 0 deletions src/app/comments/comment/comment.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
margin: 0.5em 0;
padding: 1em;
border: 1px solid gray;
display: flex;
}

.comment-content {
Expand All @@ -12,3 +13,11 @@
font-size: smaller;
color: gray;
}

.vote-wrapper {
margin-right: 1em;
}

.body-wrapper {
flex: 1;
}
4 changes: 3 additions & 1 deletion src/app/comments/comment/comment.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MomentModule } from 'angular2-moment';

import { CommentComponent } from './comment.component';
import { VoteStubComponent } from 'app/shared/vote/vote.component';
import { CommentFormStubComponent } from '../comment-form/comment-form.component';
import { EditorOutputComponent } from 'app/shared/editor-output/editor-output.component';
import { UserSmallStubComponent } from 'app/shared/user-small/user-small.component';
Expand All @@ -21,7 +22,8 @@ describe('CommentComponent', () => {
CommentComponent,
CommentFormStubComponent,
EditorOutputComponent,
UserSmallStubComponent
UserSmallStubComponent,
VoteStubComponent
],
imports: [
MomentModule
Expand Down
19 changes: 19 additions & 0 deletions src/app/comments/comment/comment.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,25 @@ export class CommentComponent implements OnInit {
_.pullAllBy(this.comment.reactions, [reaction], 'id');
}

async onVote(vote: number) {
// when vote doesn't exist, we add it
// when vote exists, we remove it
// and we update the comment.votes object
if (this.comment.votes.me === 0) {
// we add the vote
await this.model.vote({ to: { type: 'comments', id: this.comment.id }, value: vote });

if (vote === 1) { this.comment.votes.up += 1; }
if (vote === -1) { this.comment.votes.down += 1; }
this.comment.votes.me = vote;
} else {
// we remove the vote
await this.model.vote({ to: { type: 'comments', id: this.comment.id }, value: 0 });
if (this.comment.votes.me === 1) { this.comment.votes.up -= 1; }
if (this.comment.votes.me === -1) { this.comment.votes.down -= 1; }
this.comment.votes.me = 0;
}
}
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/app/ideas/idea-form/idea-form.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
input {
width: 100%;
}
33 changes: 21 additions & 12 deletions src/app/ideas/read-idea/read-idea.component.html
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
<!--app-vote></app-vote-->

<nav class="idea-navigation">
<a class="link-button" *ngIf="canEdit" [routerLink]="'/idea/'+idea.id+'/edit'">Edit idea</a>
</nav>

<h2 class="idea-title"><mat-icon>lightbulb_outline</mat-icon> {{idea.title}}</h2>
<section class="idea-tags">
<app-tag-list [tags]="ideaTags"></app-tag-list>
</section>
<section class="idea-detail">
<app-editor-output [value]="idea.detail"></app-editor-output>
</section>
<section class="idea-creator">
<app-user-small [user]="idea.creator"></app-user-small>
</section>
<div class="idea-wrapper">
<section class="side-container">
<mat-icon ngClass="type-icon" title="idea">lightbulb_outline</mat-icon>
<app-vote
[votes]="idea.votes"
(vote)="onVote($event)"
></app-vote>
</section>
<section class="main-container">
<h2 class="idea-title">{{idea.title}}</h2>
<section class="idea-tags">
<app-tag-list [tags]="ideaTags"></app-tag-list>
</section>
<section class="idea-detail">
<app-editor-output [value]="idea.detail"></app-editor-output>
</section>
<section class="idea-creator">
<app-user-small [user]="idea.creator"></app-user-small>
</section>
</section>
</div>

<section class="idea-comments">
<app-comments [comments]="comments" [primary]="idea"></app-comments>
Expand Down
19 changes: 19 additions & 0 deletions src/app/ideas/read-idea/read-idea.component.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
@import "../../shared/styles/colors";

.idea-navigation {
float: right;
}

.idea-wrapper {
display: flex;
}

.side-container {
text-align: center;
margin-right: 0.7em;
margin-top: 33px;
}

.type-icon {
font-size: 32px;
width: 32px;
height: 32px;
color: $darker;
}
10 changes: 6 additions & 4 deletions src/app/ideas/read-idea/read-idea.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ import { ReadIdeaComponent } from './read-idea.component';
import { EditorOutputComponent } from 'app/shared/editor-output/editor-output.component';
import { MaterialModule } from 'app/material.module';
import { AuthService } from 'app/auth.service';
import { ModelService } from 'app/model.service';
import { UserSmallStubComponent } from 'app/shared/user-small/user-small.component';
import { CommentsStubComponent } from 'app/comments/comments.component';

@Component({ selector: 'app-vote', template: '' })
class VoteStubComponent { }
import { VoteStubComponent } from 'app/shared/vote/vote.component';

@Component({ selector: 'app-tag-list', template: '' })
class TagListStubComponent {
Expand All @@ -23,6 +22,8 @@ class AuthStubService {
username = 'user';
}

class ModelStubService { }

class ActivatedRouteStub {
data = Observable.of({
idea: { id: '123', creator: { username: 'user' } },
Expand Down Expand Up @@ -50,7 +51,8 @@ describe('ReadIdeaComponent', () => {
],
providers: [
{ provide: AuthService, useClass: AuthStubService },
{ provide: ActivatedRoute, useClass: ActivatedRouteStub }
{ provide: ActivatedRoute, useClass: ActivatedRouteStub },
{ provide: ModelService, useClass: ModelStubService }
]
})
.compileComponents();
Expand Down
25 changes: 23 additions & 2 deletions src/app/ideas/read-idea/read-idea.component.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import { AuthService } from '../../auth.service';
import { Comment, Idea, Tag } from '../../shared/types';
import { AuthService } from 'app/auth.service';
import { ModelService } from 'app/model.service';
import { Comment, Idea, Tag } from 'app/shared/types';

@Component({
selector: 'app-read-idea',
Expand All @@ -18,6 +19,7 @@ export class ReadIdeaComponent implements OnInit {


constructor(private auth: AuthService,
private model: ModelService,
private route: ActivatedRoute) { }

ngOnInit() {
Expand All @@ -31,4 +33,23 @@ export class ReadIdeaComponent implements OnInit {
});
}

async onVote(vote: number) {
// when vote doesn't exist, we add it
// when vote exists, we remove it
// and we update the idea.votes object
if (this.idea.votes.me === 0) {
// we add the vote
await this.model.vote({ to: { type: 'ideas', id: this.idea.id }, value: vote });

if (vote === 1) { this.idea.votes.up += 1; }
if (vote === -1) { this.idea.votes.down += 1; }
this.idea.votes.me = vote;
} else {
// we remove the vote
await this.model.vote({ to: { type: 'ideas', id: this.idea.id }, value: 0 });
if (this.idea.votes.me === 1) { this.idea.votes.up -= 1; }
if (this.idea.votes.me === -1) { this.idea.votes.down -= 1; }
this.idea.votes.me = 0;
}
}
}
Loading