diff --git a/src/app/pages/entry/entry.page.html b/src/app/pages/entry/entry.page.html index 54aae75..c4389c5 100644 --- a/src/app/pages/entry/entry.page.html +++ b/src/app/pages/entry/entry.page.html @@ -4,7 +4,9 @@

{{entry.text}}

- + - + + + \ No newline at end of file diff --git a/src/app/pages/entry/entry.page.ts b/src/app/pages/entry/entry.page.ts index f859f78..71a35ee 100644 --- a/src/app/pages/entry/entry.page.ts +++ b/src/app/pages/entry/entry.page.ts @@ -3,6 +3,7 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { EntriesService } from '../../services/entries.service'; +import { CommentService } from '../../services/comment.service'; @Component({ selector: 'page-entry', @@ -14,13 +15,15 @@ export class PageEntry implements OnInit { entry: any; notfound: boolean = false; boundRefresh: Function; + boundReplyCallback: Function; - constructor(private entriesService: EntriesService, + constructor(private commentService: CommentService, private entriesService: EntriesService, private route: ActivatedRoute) { } ngOnInit(): void { this.id = +this.route.snapshot.paramMap.get('id'); this.boundRefresh = this.refresh.bind(this); + this.boundReplyCallback = this.replyCallback.bind(this); this.refresh(); } @@ -34,4 +37,12 @@ export class PageEntry implements OnInit { }) } + replyCallback(): void { + this.entry.metadata.reply = false; + this.entry.metadata.comments = 0; + this.commentService.count(this.entry.id).subscribe((data) => { + this.entry.metadata.comments = +data; + }); + } + } diff --git a/src/app/services/moderarion.service.ts b/src/app/services/moderarion.service.ts new file mode 100644 index 0000000..4e944ec --- /dev/null +++ b/src/app/services/moderarion.service.ts @@ -0,0 +1,21 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { environment } from '../../environments/environment'; + +@Injectable({ + providedIn: 'root', +}) +export class ModerationService { + + constructor(private http: HttpClient) { + } + + deleteComment(id: number) { + return this.http.delete(environment.apiUrl + "/m/c/" + id); + } + + deleteEntry(id: number) { + return this.http.delete(environment.apiUrl + "/m/e/" + id); + } + +} \ No newline at end of file diff --git a/src/app/ui/comment/comment.ui.html b/src/app/ui/comment/comment.ui.html index 6262840..e38c65d 100644 --- a/src/app/ui/comment/comment.ui.html +++ b/src/app/ui/comment/comment.ui.html @@ -1,16 +1,17 @@
- - expand_less - -   - {{'comment.author' | i18n}}{{comment.author}}  {{comment.created | datef}} + {{'comment.author' | i18n}}{{comment.author}} +   + + thumb_up + +   - remove + thumb_down
@@ -27,6 +28,10 @@ {{'comment.unvote' | i18n}} + | + + {{'comment.delete' | i18n}} + diff --git a/src/app/ui/comment/comment.ui.ts b/src/app/ui/comment/comment.ui.ts index ca77a43..7610905 100644 --- a/src/app/ui/comment/comment.ui.ts +++ b/src/app/ui/comment/comment.ui.ts @@ -1,6 +1,11 @@ import { Component, OnInit, Input } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; + +import { AuthService } from '../../services/auth.service'; import { VoteService } from '../../services/vote.service'; import { CommentService } from '../../services/comment.service'; +import { ModerationService } from '../../services/moderarion.service'; +import { ConfirmDialog } from '../../ui/confirm/confirm.component'; @Component({ selector: 'ui-comment', @@ -9,14 +14,26 @@ import { CommentService } from '../../services/comment.service'; }) export class UiComment implements OnInit { + moderator: boolean = false; @Input() comment: any; @Input() change: Function; boundReplyCallback: Function; - constructor(private commentService: CommentService, private voteService: VoteService) { } + constructor(private authService: AuthService, private commentService: CommentService, private voteService: VoteService, + private moderationService: ModerationService, public dialog: MatDialog) { } ngOnInit(): void { + this.authService.auth.subscribe((auth: any) => { + if (auth && auth.authorities) { + for (let role of auth.authorities) { + if (role.authority == 'ROLE_ADMIN' || role.authority == 'ROLE_MOD') { + this.moderator = true; + } + } + } + }) + this.commentService.countParent(this.comment.target, this.comment.id).subscribe((data) => { this.comment.metadata.comments = +data; }); @@ -36,7 +53,7 @@ export class UiComment implements OnInit { }); } - author(author : string) { + author(author: string) { return '' + author + ''; } @@ -47,4 +64,21 @@ export class UiComment implements OnInit { this.comment.metadata.comments = +data; }); } + + deleteComment(comment: any) { + const dialogRef = this.dialog.open(ConfirmDialog, { + data: { + 'label': 'comment.confirmDelete', + 'args': [ comment.text, comment.author ] + } + }) + + dialogRef.afterClosed().subscribe(result => { + if (result) { + this.moderationService.deleteComment(comment.id).subscribe((result: any) => { + this.change && this.change() + }) + } + }); + } } diff --git a/src/app/ui/commentform/commentform.ui.ts b/src/app/ui/commentform/commentform.ui.ts index f380894..dff1062 100644 --- a/src/app/ui/commentform/commentform.ui.ts +++ b/src/app/ui/commentform/commentform.ui.ts @@ -36,7 +36,7 @@ export class UiCommentForm implements OnInit { comment.text = this.form.get("text").value; this.commentService.create(comment).subscribe((data) => { - this.form.reset(); + this.formDirective.resetForm(); this.change && this.change(); }); } diff --git a/src/app/ui/entry/entry.ui.html b/src/app/ui/entry/entry.ui.html index a7037c3..a23d506 100644 --- a/src/app/ui/entry/entry.ui.html +++ b/src/app/ui/entry/entry.ui.html @@ -1,11 +1,10 @@
{{index}}.  - - expand_less - -   {{'entryType.' + entry.entryType + '.icon' | i18n}}  + + thumb_up + +   {{entry.title}} {{entry.title}}
@@ -21,5 +20,9 @@ {{'entry.comments' | i18n:(entry.metadata && entry.metadata.comments)}} + | + + {{'entry.delete' | i18n}} + \ No newline at end of file diff --git a/src/app/ui/entry/entry.ui.scss b/src/app/ui/entry/entry.ui.scss index e784604..0506103 100644 --- a/src/app/ui/entry/entry.ui.scss +++ b/src/app/ui/entry/entry.ui.scss @@ -1,3 +1,6 @@ +@import '../../../variables.scss'; + + small a { color: inherit !important; text-decoration: none; @@ -6,4 +9,8 @@ small a { small a:hover { color: inherit !important; text-decoration: underline; +} + +a.vote { + color: $light-primary-text; } \ No newline at end of file diff --git a/src/app/ui/entry/entry.ui.ts b/src/app/ui/entry/entry.ui.ts index aaf0028..82cd1c1 100644 --- a/src/app/ui/entry/entry.ui.ts +++ b/src/app/ui/entry/entry.ui.ts @@ -1,5 +1,11 @@ import { Component, OnInit, Input } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; + +import { AuthService } from '../../services/auth.service'; import { VoteService } from '../../services/vote.service'; +import { CommentService } from '../../services/comment.service'; +import { ModerationService } from '../../services/moderarion.service'; +import { ConfirmDialog } from '../../ui/confirm/confirm.component'; @Component({ selector: 'ui-entry', @@ -8,14 +14,24 @@ import { VoteService } from '../../services/vote.service'; }) export class UiEntry implements OnInit { + moderator: boolean = false; @Input() entry: any; - @Input() index : number; - @Input() change : Function; + @Input() index: number; + @Input() change: Function; - constructor(private voteService: VoteService) { } + constructor(private authService: AuthService, private voteService: VoteService, + private moderationService: ModerationService, public dialog: MatDialog) { } ngOnInit(): void { - + this.authService.auth.subscribe((auth: any) => { + if (auth && auth.authorities) { + for (let role of auth.authorities) { + if (role.authority == 'ROLE_ADMIN' || role.authority == 'ROLE_MOD') { + this.moderator = true; + } + } + } + }) } voteUp() { @@ -26,7 +42,25 @@ export class UiEntry implements OnInit { voteDown() { this.voteService.voteEntryDown(this.entry.id).subscribe((result) => { - this.change && this.change() + this.change && this.change() + }); + } + + deleteEntry(entry: any) { + const dialogRef = this.dialog.open(ConfirmDialog, { + data: { + 'label': 'comment.confirmDelete', + 'args': [ entry.title, entry.author ] + } + }) + + dialogRef.afterClosed().subscribe(result => { + if (result) { + this.moderationService.deleteEntry(entry.id).subscribe((result: any) => { + this.entry = null; + this.change && this.change(); + }) + } }); } } \ No newline at end of file diff --git a/src/app/ui/main/main.ui.html b/src/app/ui/main/main.ui.html index 99ba1a6..a92595c 100644 --- a/src/app/ui/main/main.ui.html +++ b/src/app/ui/main/main.ui.html @@ -1,43 +1,67 @@ + + menu + {{'bstlboard' | i18n}} -
- {{'top' | i18n}} - {{'new' | i18n}} + + {{'submission' | i18n}} -
- - - - - + + +
+ + + + + + login {{'login' | i18n}} - + + trending_up {{'top' | i18n}} + + + history {{'new' | i18n}} + + + tune {{'settings' | i18n}} - {{'locale.' + locale + '.long' | - i18n}} done - + + exit_to_app {{'logout' | i18n}} + + + login {{'login' | i18n}} + + + + + + + + + done{{'locale.' + locale + '.long' | + i18n}} + + {{'darkTheme' | i18n}} - - - exit_to_app {{'logout' | i18n}} - - - - -
- -
\ No newline at end of file +
+ + + + +
+ +
+
+ \ No newline at end of file