improvements + bookmarks
This commit is contained in:
parent
a69a85aeb0
commit
0cabe9b0a5
@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
|
|||||||
import { Routes, RouterModule } from '@angular/router';
|
import { Routes, RouterModule } from '@angular/router';
|
||||||
|
|
||||||
import { AuthGuard, AuthUpdateGuard, AuthenticatedGuard, AnonymousGuard } from './auth/auth.guard';
|
import { AuthGuard, AuthUpdateGuard, AuthenticatedGuard, AnonymousGuard } from './auth/auth.guard';
|
||||||
|
import { PageBookmarks } from './pages/bookmarks/bookmarks.page';
|
||||||
import { PageEntry } from './pages/entry/entry.page';
|
import { PageEntry } from './pages/entry/entry.page';
|
||||||
import { PageLogin } from './pages/login/login.page';
|
import { PageLogin } from './pages/login/login.page';
|
||||||
import { PageNew } from './pages/new/new.page';
|
import { PageNew } from './pages/new/new.page';
|
||||||
@ -18,6 +19,7 @@ const routes: Routes = [
|
|||||||
{ path: '', component: PageTop, canActivate: [ AuthenticatedGuard ] },
|
{ path: '', component: PageTop, canActivate: [ AuthenticatedGuard ] },
|
||||||
{ path: 'e/:id', component: PageEntry, canActivate: [ AuthenticatedGuard ] },
|
{ path: 'e/:id', component: PageEntry, canActivate: [ AuthenticatedGuard ] },
|
||||||
{ path: 'new', component: PageNew, canActivate: [ AuthenticatedGuard ] },
|
{ path: 'new', component: PageNew, canActivate: [ AuthenticatedGuard ] },
|
||||||
|
{ path: 'bookmarks', component: PageBookmarks, canActivate: [ AuthenticatedGuard ] },
|
||||||
{ path: 'submit', component: PageSubmission, canActivate: [ AuthenticatedGuard ] },
|
{ path: 'submit', component: PageSubmission, canActivate: [ AuthenticatedGuard ] },
|
||||||
{ path: 'login', component: PageLogin, canActivate: [ AnonymousGuard ] },
|
{ path: 'login', component: PageLogin, canActivate: [ AnonymousGuard ] },
|
||||||
{ path: 'settings', component: PageSettings, canActivate: [ AuthenticatedGuard ] },
|
{ path: 'settings', component: PageSettings, canActivate: [ AuthenticatedGuard ] },
|
||||||
|
@ -17,6 +17,7 @@ import { AutofocusDirective } from './material/autofocus';
|
|||||||
import { I18nPipe } from './utils/i18n.pipe';
|
import { I18nPipe } from './utils/i18n.pipe';
|
||||||
import { MomentPipe } from './utils/moment.pipe';
|
import { MomentPipe } from './utils/moment.pipe';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
import { PageBookmarks } from './pages/bookmarks/bookmarks.page';
|
||||||
import { PageEntry } from './pages/entry/entry.page';
|
import { PageEntry } from './pages/entry/entry.page';
|
||||||
import { PageLogin } from './pages/login/login.page';
|
import { PageLogin } from './pages/login/login.page';
|
||||||
import { PageNew } from './pages/new/new.page';
|
import { PageNew } from './pages/new/new.page';
|
||||||
@ -71,6 +72,7 @@ export class XhrInterceptor implements HttpInterceptor {
|
|||||||
I18nPipe,
|
I18nPipe,
|
||||||
MomentPipe,
|
MomentPipe,
|
||||||
AppComponent,
|
AppComponent,
|
||||||
|
PageBookmarks,
|
||||||
PageEntry,
|
PageEntry,
|
||||||
PageLogin,
|
PageLogin,
|
||||||
PageNew,
|
PageNew,
|
||||||
|
1
src/app/pages/bookmarks/bookmarks.page.html
Normal file
1
src/app/pages/bookmarks/bookmarks.page.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<ui-entries [entries]="entries" [refresh]="boundRefresh" [update]="boundUpdate"></ui-entries>
|
81
src/app/pages/bookmarks/bookmarks.page.ts
Normal file
81
src/app/pages/bookmarks/bookmarks.page.ts
Normal file
@ -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) => { })
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
29
src/app/services/bookmarks.service.ts
Normal file
29
src/app/services/bookmarks.service.ts
Normal file
@ -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, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -43,19 +43,25 @@ export class UiComment implements OnInit {
|
|||||||
|
|
||||||
voteUp() {
|
voteUp() {
|
||||||
this.voteService.voteCommentUp(this.comment.id).subscribe((result) => {
|
this.voteService.voteCommentUp(this.comment.id).subscribe((result) => {
|
||||||
this.change && this.change()
|
this.commentService.getComment(this.comment.id).subscribe((data) => {
|
||||||
|
this.comment = data;
|
||||||
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
voteDown() {
|
voteDown() {
|
||||||
this.voteService.voteCommentDown(this.comment.id).subscribe((result) => {
|
this.voteService.voteCommentDown(this.comment.id).subscribe((result) => {
|
||||||
this.change && this.change()
|
this.commentService.getComment(this.comment.id).subscribe((data) => {
|
||||||
|
this.comment = data;
|
||||||
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unvote() {
|
unvote() {
|
||||||
this.voteService.unvoteComment(this.comment.id).subscribe((result) => {
|
this.voteService.unvoteComment(this.comment.id).subscribe((result) => {
|
||||||
this.change && this.change()
|
this.commentService.getComment(this.comment.id).subscribe((data) => {
|
||||||
|
this.comment = data;
|
||||||
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<div *ngIf="comments" fxLayout="column" fxFlexFill class="comments">
|
<div *ngIf="comments" fxLayout="column" fxFlexFill class="comments">
|
||||||
<ng-container *ngFor="let comment of comments.content; let i = index">
|
<ng-container *ngFor="let comment of comments.content; let i = index">
|
||||||
<mat-divider *ngIf="i > 0"></mat-divider>
|
<mat-divider class="divider" *ngIf="i > 0"></mat-divider>
|
||||||
<ui-comment [comment]="comment" [change]="boundRefresh"></ui-comment>
|
<ui-comment [comment]="comment" [change]="boundRefresh"></ui-comment>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
@ -1,3 +1,7 @@
|
|||||||
.comments {
|
.comments {
|
||||||
padding-left: 15px;
|
padding-left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
margin: 10px 0px;
|
||||||
|
}
|
@ -11,7 +11,11 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
</mat-list>
|
</mat-list>
|
||||||
|
|
||||||
<p *ngIf="entries.totalElements == 0">{{'entries.nothing' | i18n}}</p>
|
<mat-list *ngIf="entries.totalElements == 0">
|
||||||
|
<mat-list-item>
|
||||||
|
<p>{{'entries.nothing' | i18n}}</p>
|
||||||
|
</mat-list-item>
|
||||||
|
</mat-list>
|
||||||
|
|
||||||
<span fxFlexOffset="auto"></span>
|
<span fxFlexOffset="auto"></span>
|
||||||
|
|
||||||
|
@ -27,10 +27,20 @@
|
|||||||
<a routerLink="/e/{{entry.id}}" matTooltip="{{entry.created | datef:'LLLL'}}">{{entry.created
|
<a routerLink="/e/{{entry.id}}" matTooltip="{{entry.created | datef:'LLLL'}}">{{entry.created
|
||||||
| datef}}</a>
|
| datef}}</a>
|
||||||
{{'entry.author' | i18n}}<a routerLink="/u/{{entry.author}}">{{entry.author}}</a>
|
{{'entry.author' | i18n}}<a routerLink="/u/{{entry.author}}">{{entry.author}}</a>
|
||||||
|
|
<span> | </span>
|
||||||
<a routerLink="/e/{{entry.id}}">{{'entry.comments' | i18n:(entry.metadata && entry.metadata.comments)}}</a>
|
<a routerLink="/e/{{entry.id}}">{{'entry.comments' | i18n:(entry.metadata && entry.metadata.comments)}}</a>
|
||||||
|
<span> | </span>
|
||||||
|
<a *ngIf="entry.metadata && !entry.metadata.bookmarked" href="javascript:" (click)="addBookmark()"
|
||||||
|
matTooltip="{{'bookmarks.add' | i18n}}">
|
||||||
|
<mat-icon inline="true">bookmark_border</mat-icon>
|
||||||
|
</a>
|
||||||
|
<a *ngIf="entry.metadata && entry.metadata.bookmarked" href="javascript:" (click)="removeBookmark()"
|
||||||
|
matTooltip="{{'bookmarks.remove' | i18n}}">
|
||||||
|
<mat-icon inline="true">bookmark</mat-icon>
|
||||||
|
</a>
|
||||||
<span *ngIf="entry.metadata && entry.metadata.unvote"> | </span>
|
<span *ngIf="entry.metadata && entry.metadata.unvote"> | </span>
|
||||||
<a *ngIf="entry.metadata && entry.metadata.unvote" href="javascript:" (click)="unvote(entry.id)">{{'entry.unvote' | i18n}}</a>
|
<a *ngIf="entry.metadata && entry.metadata.unvote" href="javascript:" (click)="unvote(entry.id)">{{'entry.unvote' |
|
||||||
|
i18n}}</a>
|
||||||
<span *ngIf="moderator"> | </span>
|
<span *ngIf="moderator"> | </span>
|
||||||
<a *ngIf="moderator" href="javascript:" (click)="deleteEntry(entry)">{{'entry.delete' | i18n}}</a>
|
<a *ngIf="moderator" href="javascript:" (click)="deleteEntry(entry)">{{'entry.delete' | i18n}}</a>
|
||||||
</small>
|
</small>
|
||||||
|
@ -3,7 +3,7 @@ import { MatDialog } from '@angular/material/dialog';
|
|||||||
|
|
||||||
import { AuthService } from '../../services/auth.service';
|
import { AuthService } from '../../services/auth.service';
|
||||||
import { VoteService } from '../../services/vote.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 { ModerationService } from '../../services/moderarion.service';
|
||||||
import { ConfirmDialog } from '../../ui/confirm/confirm.component';
|
import { ConfirmDialog } from '../../ui/confirm/confirm.component';
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ export class UiEntry implements OnInit {
|
|||||||
@Input() change: Function;
|
@Input() change: Function;
|
||||||
|
|
||||||
constructor(private authService: AuthService, private voteService: VoteService,
|
constructor(private authService: AuthService, private voteService: VoteService,
|
||||||
private moderationService: ModerationService, public dialog: MatDialog) { }
|
private moderationService: ModerationService, private bookmarksService: BookmarksService, public dialog: MatDialog) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.authService.auth.subscribe((auth: any) => {
|
this.authService.auth.subscribe((auth: any) => {
|
||||||
@ -36,26 +36,38 @@ export class UiEntry implements OnInit {
|
|||||||
|
|
||||||
voteUp() {
|
voteUp() {
|
||||||
this.voteService.voteEntryUp(this.entry.id).subscribe((result) => {
|
this.voteService.voteEntryUp(this.entry.id).subscribe((result) => {
|
||||||
this.change && this.change()
|
this.change && this.change();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
voteDown() {
|
voteDown() {
|
||||||
this.voteService.voteEntryDown(this.entry.id).subscribe((result) => {
|
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() {
|
unvote() {
|
||||||
this.voteService.unvoteEntry(this.entry.id).subscribe((result) => {
|
this.voteService.unvoteEntry(this.entry.id).subscribe((result) => {
|
||||||
this.change && this.change()
|
this.change && this.change();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteEntry(entry: any) {
|
deleteEntry(entry: any) {
|
||||||
const dialogRef = this.dialog.open(ConfirmDialog, {
|
const dialogRef = this.dialog.open(ConfirmDialog, {
|
||||||
data: {
|
data: {
|
||||||
'label': 'comment.confirmDelete',
|
'label': 'entry.confirmDelete',
|
||||||
'args': [ entry.title, entry.author ]
|
'args': [ entry.title, entry.author ]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -28,6 +28,9 @@
|
|||||||
<a *ngIf="auth && auth.authenticated" routerLink="/new" routerLinkActive="active" mat-list-item>
|
<a *ngIf="auth && auth.authenticated" routerLink="/new" routerLinkActive="active" mat-list-item>
|
||||||
<mat-icon>history</mat-icon> {{'new' | i18n}}
|
<mat-icon>history</mat-icon> {{'new' | i18n}}
|
||||||
</a>
|
</a>
|
||||||
|
<a *ngIf="auth && auth.authenticated" routerLink="/bookmarks" routerLinkActive="active" mat-list-item>
|
||||||
|
<mat-icon>bookmarks</mat-icon> {{'bookmarks' | i18n}}
|
||||||
|
</a>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<a *ngIf="auth && auth.authenticated" routerLink="/settings" routerLinkActive="active" mat-list-item>
|
<a *ngIf="auth && auth.authenticated" routerLink="/settings" routerLinkActive="active" mat-list-item>
|
||||||
<mat-icon>tune</mat-icon> {{'settings' | i18n}}
|
<mat-icon>tune</mat-icon> {{'settings' | i18n}}
|
||||||
|
Loading…
Reference in New Issue
Block a user