diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 7fc01ea..2a390dc 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AuthGuard, AuthUpdateGuard, AuthenticatedGuard, AnonymousGuard } from './auth/auth.guard';
+import { PageBookmarks } from './pages/bookmarks/bookmarks.page';
import { PageEntry } from './pages/entry/entry.page';
import { PageLogin } from './pages/login/login.page';
import { PageNew } from './pages/new/new.page';
@@ -18,6 +19,7 @@ const routes: Routes = [
{ path: '', component: PageTop, canActivate: [ AuthenticatedGuard ] },
{ path: 'e/:id', component: PageEntry, canActivate: [ AuthenticatedGuard ] },
{ path: 'new', component: PageNew, canActivate: [ AuthenticatedGuard ] },
+ { path: 'bookmarks', component: PageBookmarks, canActivate: [ AuthenticatedGuard ] },
{ path: 'submit', component: PageSubmission, canActivate: [ AuthenticatedGuard ] },
{ path: 'login', component: PageLogin, canActivate: [ AnonymousGuard ] },
{ path: 'settings', component: PageSettings, canActivate: [ AuthenticatedGuard ] },
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index b441d76..4248ab9 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -17,6 +17,7 @@ import { AutofocusDirective } from './material/autofocus';
import { I18nPipe } from './utils/i18n.pipe';
import { MomentPipe } from './utils/moment.pipe';
import { AppComponent } from './app.component';
+import { PageBookmarks } from './pages/bookmarks/bookmarks.page';
import { PageEntry } from './pages/entry/entry.page';
import { PageLogin } from './pages/login/login.page';
import { PageNew } from './pages/new/new.page';
@@ -71,6 +72,7 @@ export class XhrInterceptor implements HttpInterceptor {
I18nPipe,
MomentPipe,
AppComponent,
+ PageBookmarks,
PageEntry,
PageLogin,
PageNew,
diff --git a/src/app/pages/bookmarks/bookmarks.page.html b/src/app/pages/bookmarks/bookmarks.page.html
new file mode 100644
index 0000000..24cc006
--- /dev/null
+++ b/src/app/pages/bookmarks/bookmarks.page.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/app/pages/bookmarks/bookmarks.page.ts b/src/app/pages/bookmarks/bookmarks.page.ts
new file mode 100644
index 0000000..1120ab8
--- /dev/null
+++ b/src/app/pages/bookmarks/bookmarks.page.ts
@@ -0,0 +1,81 @@
+import { Component, OnInit, Input } from '@angular/core';
+import { Router, ActivatedRoute } from '@angular/router';
+import { PageEvent } from '@angular/material/paginator';
+
+import { BookmarksService } from '../../services/bookmarks.service';
+
+@Component({
+ selector: 'page-bookmarks',
+ templateUrl: './bookmarks.page.html'
+})
+export class PageBookmarks implements OnInit {
+
+ @Input() entries: any;
+ boundRefresh: Function;
+ boundUpdate: Function;
+ init: boolean = true;
+
+ constructor(private bookmarksService: BookmarksService, private router: Router, private route: ActivatedRoute) { }
+
+ ngOnInit(): void {
+ this.boundRefresh = this.refresh.bind(this);
+ this.boundUpdate = this.update.bind(this);
+ this.route.queryParams.subscribe(params => {
+ if (this.init) {
+ this.entries = {};
+ if (params[ 'p' ]) {
+ this.entries.number = +params[ 'p' ] - 1;
+ if (this.entries.number < 0) {
+ this.entries.number = 0;
+ }
+ }
+
+ if (params[ 's' ]) {
+ this.entries.size = +params[ 's' ];
+ }
+
+ this.refresh();
+ this.init = false;
+ }
+ });
+ }
+
+ refresh(): void {
+ if (!this.entries) {
+ this.entries = {};
+ }
+
+ this.entries.content = null;
+ this.bookmarksService.getEntriesPages(this.entries.number || 0, this.entries.size || 30).subscribe((data: any) => {
+ this.entries = data;
+ this.entries.bookmarks = true;
+ }, (error) => { })
+
+ }
+
+ update(event: PageEvent) {
+ this.entries.content = null;
+ const params: any = { p: null, s: null };
+
+ if (event.pageIndex != 0) {
+ params.p = event.pageIndex + 1;
+ }
+
+ if (event.pageSize != 30) {
+ params.s = event.pageSize;
+ }
+
+ this.router.navigate(
+ [],
+ {
+ relativeTo: this.route,
+ queryParams: params,
+ queryParamsHandling: 'merge'
+ });
+
+ this.bookmarksService.getEntriesPages(event.pageIndex, event.pageSize).subscribe((data: any) => {
+ this.entries = data;
+ }, (error) => { })
+ }
+
+}
diff --git a/src/app/services/bookmarks.service.ts b/src/app/services/bookmarks.service.ts
new file mode 100644
index 0000000..7e023d3
--- /dev/null
+++ b/src/app/services/bookmarks.service.ts
@@ -0,0 +1,29 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { environment } from '../../environments/environment';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class BookmarksService {
+
+ constructor(private http: HttpClient) {
+ }
+
+ getEntries() {
+ return this.http.get(environment.apiUrl + "/b");
+ }
+
+ getEntriesPages(page: number, size: number) {
+ return this.http.get(environment.apiUrl + "/b" + "?page=" + page + "&size=" + size);
+ }
+
+ addEntry(id: number) {
+ return this.http.put(environment.apiUrl + "/b/" + id, {});
+ }
+
+ removeEntry(id: number) {
+ return this.http.delete(environment.apiUrl + "/b/" + id, {});
+ }
+
+}
\ No newline at end of file
diff --git a/src/app/ui/comment/comment.ui.ts b/src/app/ui/comment/comment.ui.ts
index 6ef7a51..877688a 100644
--- a/src/app/ui/comment/comment.ui.ts
+++ b/src/app/ui/comment/comment.ui.ts
@@ -43,19 +43,25 @@ export class UiComment implements OnInit {
voteUp() {
this.voteService.voteCommentUp(this.comment.id).subscribe((result) => {
- this.change && this.change()
+ this.commentService.getComment(this.comment.id).subscribe((data) => {
+ this.comment = data;
+ })
});
}
voteDown() {
this.voteService.voteCommentDown(this.comment.id).subscribe((result) => {
- this.change && this.change()
+ this.commentService.getComment(this.comment.id).subscribe((data) => {
+ this.comment = data;
+ })
});
}
unvote() {
this.voteService.unvoteComment(this.comment.id).subscribe((result) => {
- this.change && this.change()
+ this.commentService.getComment(this.comment.id).subscribe((data) => {
+ this.comment = data;
+ })
});
}
diff --git a/src/app/ui/comments/comments.ui.html b/src/app/ui/comments/comments.ui.html
index 2b98bc4..bc18b5a 100644
--- a/src/app/ui/comments/comments.ui.html
+++ b/src/app/ui/comments/comments.ui.html
@@ -1,6 +1,6 @@
\ No newline at end of file
diff --git a/src/app/ui/comments/comments.ui.scss b/src/app/ui/comments/comments.ui.scss
index d67975e..ce7688c 100644
--- a/src/app/ui/comments/comments.ui.scss
+++ b/src/app/ui/comments/comments.ui.scss
@@ -1,3 +1,7 @@
.comments {
padding-left: 15px;
}
+
+.divider {
+ margin: 10px 0px;
+}
\ No newline at end of file
diff --git a/src/app/ui/entries/entries.ui.html b/src/app/ui/entries/entries.ui.html
index e06801a..707951c 100644
--- a/src/app/ui/entries/entries.ui.html
+++ b/src/app/ui/entries/entries.ui.html
@@ -11,7 +11,11 @@
- {{'entries.nothing' | i18n}}
+
+
+ {{'entries.nothing' | i18n}}
+
+
diff --git a/src/app/ui/entry/entry.ui.html b/src/app/ui/entry/entry.ui.html
index 0d704cb..a2de45d 100644
--- a/src/app/ui/entry/entry.ui.html
+++ b/src/app/ui/entry/entry.ui.html
@@ -19,18 +19,28 @@
-->
- thumb_up
- thumb_down
+ thumb_up
+ thumb_down
{{'points' | i18n:(entry.metadata && entry.metadata.points)}}
{{entry.created
| datef}}
{{'entry.author' | i18n}}{{entry.author}}
- |
+ |
{{'entry.comments' | i18n:(entry.metadata && entry.metadata.comments)}}
+ |
+
+ bookmark_border
+
+
+ bookmark
+
|
- {{'entry.unvote' | i18n}}
+ {{'entry.unvote' |
+ i18n}}
|
{{'entry.delete' | i18n}}
diff --git a/src/app/ui/entry/entry.ui.ts b/src/app/ui/entry/entry.ui.ts
index 8755e34..6a19440 100644
--- a/src/app/ui/entry/entry.ui.ts
+++ b/src/app/ui/entry/entry.ui.ts
@@ -3,7 +3,7 @@ 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 { BookmarksService } from '../../services/bookmarks.service';
import { ModerationService } from '../../services/moderarion.service';
import { ConfirmDialog } from '../../ui/confirm/confirm.component';
@@ -20,7 +20,7 @@ export class UiEntry implements OnInit {
@Input() change: Function;
constructor(private authService: AuthService, private voteService: VoteService,
- private moderationService: ModerationService, public dialog: MatDialog) { }
+ private moderationService: ModerationService, private bookmarksService: BookmarksService, public dialog: MatDialog) { }
ngOnInit(): void {
this.authService.auth.subscribe((auth: any) => {
@@ -36,26 +36,38 @@ export class UiEntry implements OnInit {
voteUp() {
this.voteService.voteEntryUp(this.entry.id).subscribe((result) => {
- this.change && this.change()
+ this.change && this.change();
});
}
voteDown() {
this.voteService.voteEntryDown(this.entry.id).subscribe((result) => {
- this.change && this.change()
+ this.change && this.change();
+ });
+ }
+
+ addBookmark() {
+ this.bookmarksService.addEntry(this.entry.id).subscribe((result) => {
+ this.entry.metadata.bookmarked = true;
+ });
+ }
+
+ removeBookmark() {
+ this.bookmarksService.removeEntry(this.entry.id).subscribe((result) => {
+ this.entry.metadata.bookmarked = false;
});
}
unvote() {
this.voteService.unvoteEntry(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',
+ 'label': 'entry.confirmDelete',
'args': [ entry.title, entry.author ]
}
})
diff --git a/src/app/ui/main/main.ui.html b/src/app/ui/main/main.ui.html
index 7afbcfb..30b027f 100644
--- a/src/app/ui/main/main.ui.html
+++ b/src/app/ui/main/main.ui.html
@@ -28,6 +28,9 @@
history {{'new' | i18n}}
+
+ bookmarks {{'bookmarks' | i18n}}
+
tune {{'settings' | i18n}}