mirror of https://github.com/Squidex/squidex.git
8 changed files with 139 additions and 115 deletions
@ -0,0 +1,26 @@ |
|||||
|
<li class="nav-item nav-icon dropdown position-relative" #button> |
||||
|
<span class="nav-link dropdown-toggle" (click)="modalMenu.show()"> |
||||
|
<i class="icon-comments"></i> |
||||
|
|
||||
|
<span class="badge rounded-pill badge-danger" *ngIf="unread">{{unread}}</span> |
||||
|
</span> |
||||
|
</li> |
||||
|
|
||||
|
<ng-container *sqxModal="modalMenu;onRoot:false"> |
||||
|
<sqx-dropdown-menu [scrollTop]="scrollMe.nativeElement.scrollHeight" [sqxAnchoredTo]="button" [offsetY]="10" #scrollMe> |
||||
|
<ng-container *ngIf="commentsState.comments | async; let comments"> |
||||
|
<small class="text-muted" *ngIf="comments.length === 0"> |
||||
|
{{ 'notifications.empty' | sqxTranslate}} |
||||
|
</small> |
||||
|
|
||||
|
<sqx-comment *ngFor="let comment of comments; trackBy: trackByComment" |
||||
|
[comment]="comment" |
||||
|
[commentsState]="commentsState" |
||||
|
[confirmDelete]="false" |
||||
|
[canDelete]="true" |
||||
|
[canFollow]="true" |
||||
|
[userToken]="userToken"> |
||||
|
</sqx-comment> |
||||
|
</ng-container> |
||||
|
</sqx-dropdown-menu> |
||||
|
</ng-container> |
||||
@ -0,0 +1,16 @@ |
|||||
|
@import 'mixins'; |
||||
|
@import 'vars'; |
||||
|
|
||||
|
.dropdown-menu { |
||||
|
max-height: 500px; |
||||
|
min-height: 4rem; |
||||
|
overflow-y: scroll; |
||||
|
padding: 1.25rem; |
||||
|
padding-bottom: 1rem; |
||||
|
width: 300px; |
||||
|
} |
||||
|
|
||||
|
.badge { |
||||
|
@include absolute(-.5rem, 0, null, null); |
||||
|
font-size: 80%; |
||||
|
} |
||||
@ -0,0 +1,88 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
||||
|
*/ |
||||
|
|
||||
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core'; |
||||
|
import { timer } from 'rxjs'; |
||||
|
import { onErrorResumeNext, switchMap, tap } from 'rxjs/operators'; |
||||
|
import { AuthService, CommentDto, CommentsService, CommentsState, DialogService, LocalStoreService, ModalModel, ResourceOwner, Settings } from '@app/shared'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'sqx-notification-dropdown', |
||||
|
styleUrls: ['./notification-dropdown.component.scss'], |
||||
|
templateUrl: './notification-dropdown.component.html', |
||||
|
changeDetection: ChangeDetectionStrategy.OnPush, |
||||
|
}) |
||||
|
export class NotificationDropdownComponent extends ResourceOwner implements OnInit { |
||||
|
public modalMenu = new ModalModel(); |
||||
|
|
||||
|
public commentsState: CommentsState; |
||||
|
|
||||
|
public versionRead = -1; |
||||
|
public versionReceived = -1; |
||||
|
public unread = 0; |
||||
|
|
||||
|
public userToken = ''; |
||||
|
|
||||
|
constructor(authService: AuthService, commentsService: CommentsService, dialogs: DialogService, |
||||
|
private readonly changeDetector: ChangeDetectorRef, |
||||
|
private readonly localStore: LocalStoreService, |
||||
|
) { |
||||
|
super(); |
||||
|
|
||||
|
this.userToken = authService.user!.token; |
||||
|
|
||||
|
this.versionRead = localStore.getInt(Settings.Local.NOTIFICATION_VERSION, -1); |
||||
|
this.versionReceived = this.versionRead; |
||||
|
|
||||
|
this.updateVersion(); |
||||
|
|
||||
|
const commentsUrl = `users/${authService.user!.id}/notifications`; |
||||
|
|
||||
|
this.commentsState = |
||||
|
new CommentsState( |
||||
|
commentsUrl, |
||||
|
commentsService, |
||||
|
dialogs, |
||||
|
true, |
||||
|
this.versionRead); |
||||
|
} |
||||
|
|
||||
|
public ngOnInit() { |
||||
|
this.own( |
||||
|
this.modalMenu.isOpenChanges.pipe( |
||||
|
tap(_ => { |
||||
|
this.updateVersion(); |
||||
|
}), |
||||
|
)); |
||||
|
|
||||
|
this.own( |
||||
|
this.commentsState.versionNumber.pipe( |
||||
|
tap(version => { |
||||
|
this.versionReceived = version; |
||||
|
|
||||
|
this.updateVersion(); |
||||
|
|
||||
|
this.changeDetector.detectChanges(); |
||||
|
}))); |
||||
|
|
||||
|
this.own(timer(0, 4000).pipe(switchMap(() => this.commentsState.load(true).pipe(onErrorResumeNext())))); |
||||
|
} |
||||
|
|
||||
|
public trackByComment(_index: number, comment: CommentDto) { |
||||
|
return comment.id; |
||||
|
} |
||||
|
|
||||
|
private updateVersion() { |
||||
|
this.unread = Math.max(0, this.versionReceived - this.versionRead); |
||||
|
|
||||
|
if (this.modalMenu.isOpen) { |
||||
|
this.versionRead = this.versionReceived; |
||||
|
|
||||
|
this.localStore.setInt(Settings.Local.NOTIFICATION_VERSION, this.versionRead); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,32 +1,5 @@ |
|||||
<ul class="nav navbar-nav align-items-center"> |
<ul class="nav navbar-nav align-items-center"> |
||||
<sqx-notifo></sqx-notifo> |
<sqx-notifo></sqx-notifo> |
||||
|
|
||||
<ng-container *ngIf="!isNotifoConfigured"> |
|
||||
<li class="nav-item nav-icon dropdown position-relative" #button> |
|
||||
<span class="nav-link dropdown-toggle" (click)="modalMenu.show()"> |
|
||||
<i class="icon-comments"></i> |
|
||||
|
|
||||
<span class="badge rounded-pill badge-danger" *ngIf="unread">{{unread}}</span> |
<sqx-notification-dropdown *ngIf="!isNotifoConfigured"></sqx-notification-dropdown> |
||||
</span> |
|
||||
</li> |
|
||||
|
|
||||
<ng-container *sqxModal="modalMenu;onRoot:false"> |
|
||||
<sqx-dropdown-menu [scrollTop]="scrollMe.nativeElement.scrollHeight" [sqxAnchoredTo]="button" [offsetY]="10" #scrollMe> |
|
||||
<ng-container *ngIf="commentsState.comments | async; let comments"> |
|
||||
<small class="text-muted" *ngIf="comments.length === 0"> |
|
||||
{{ 'notifications.empty' | sqxTranslate}} |
|
||||
</small> |
|
||||
|
|
||||
<sqx-comment *ngFor="let comment of comments; trackBy: trackByComment" |
|
||||
[comment]="comment" |
|
||||
[commentsState]="commentsState" |
|
||||
[confirmDelete]="false" |
|
||||
[canDelete]="true" |
|
||||
[canFollow]="true" |
|
||||
[userToken]="userToken"> |
|
||||
</sqx-comment> |
|
||||
</ng-container> |
|
||||
</sqx-dropdown-menu> |
|
||||
</ng-container> |
|
||||
</ng-container> |
|
||||
</ul> |
</ul> |
||||
@ -1,16 +1,2 @@ |
|||||
@import 'mixins'; |
@import 'mixins'; |
||||
@import 'vars'; |
@import 'vars'; |
||||
|
|
||||
.dropdown-menu { |
|
||||
max-height: 500px; |
|
||||
min-height: 4rem; |
|
||||
overflow-y: scroll; |
|
||||
padding: 1.25rem; |
|
||||
padding-bottom: 1rem; |
|
||||
width: 300px; |
|
||||
} |
|
||||
|
|
||||
.badge { |
|
||||
@include absolute(-.5rem, 0, null, null); |
|
||||
font-size: 80%; |
|
||||
} |
|
||||
Loading…
Reference in new issue