mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-10 19:43:04 +00:00
Added message board components
This commit is contained in:
67
src/app/shared/message-board/message-board.component.html
Normal file
67
src/app/shared/message-board/message-board.component.html
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<button
|
||||||
|
class="btn btn-primary mt-1 mb-3"
|
||||||
|
ngbTooltip="{{tooltipMessage | translate}}"
|
||||||
|
(click)="openMessageBoard(content)">
|
||||||
|
<i class="fa fa-envelope"></i>
|
||||||
|
<span *ngIf="(messages$ | async)?.length > 0"
|
||||||
|
class="badge badge-pill badge-secondary">{{(messages$ | async)?.length}}</span>
|
||||||
|
</button>
|
||||||
|
<sup class="notification">
|
||||||
|
<span *ngIf="(unreadMessages$ | async)?.length > 0" class="badge badge-pill badge-danger font-italic">New</span>
|
||||||
|
</sup>
|
||||||
|
|
||||||
|
<ng-template #content let-c="close" let-d="dismiss">
|
||||||
|
<div class="modal-header rounded-top">
|
||||||
|
<i class="fa fa-envelope"></i> {{'mydspace.messages.title' | translate}}
|
||||||
|
<div class="btn-group pull-right">
|
||||||
|
<span (click)="modalRef.dismiss('Cross click')">
|
||||||
|
<i class="fa fa-2x fa-times" style="color: white"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<article id="content" class="rounded-bottom">
|
||||||
|
<div id="list">
|
||||||
|
<ul class="chat">
|
||||||
|
<ng-container *ngFor="let m of (messages$ | async); let i = index">
|
||||||
|
<ds-message
|
||||||
|
[m]="m"
|
||||||
|
[isSubmitter]="isSubmitter$ | async"
|
||||||
|
[isLast]="i == (messages$ | async)?.length-1"
|
||||||
|
(emitRead)="markAsRead(m.uuid)"
|
||||||
|
(emitUnread)="markAsUnread(m.uuid)"
|
||||||
|
></ds-message>
|
||||||
|
</ng-container>
|
||||||
|
</ul>
|
||||||
|
<div *ngIf="(messages$ | async)?.length == 0">{{'mydspace.messages.no-messages' | translate}}</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<form *ngVar="(itemUUID$ | async) as itemUuid"
|
||||||
|
[formGroup]="messageForm"
|
||||||
|
(ngSubmit)="sendMessage(itemUuid)">
|
||||||
|
<label *ngIf="!(isSubmitter$ | async)">{{'mydspace.messages.to' | translate}}: <span class="badge badge-pill badge-light">{{(submitter$ | async)?.name}}</span></label>
|
||||||
|
<div class="form-group">
|
||||||
|
<input formControlName="textSubject"
|
||||||
|
class="form-control mb-1"
|
||||||
|
placeholder="{{'mydspace.messages.subject-placeholder' | translate}}"/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<textarea formControlName="textDescription"
|
||||||
|
placeholder="{{'mydspace.messages.description-placeholder' | translate}}"
|
||||||
|
class="form-control"
|
||||||
|
rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
<button id="btn-chat"
|
||||||
|
class="btn btn-warning btn-lg btn-block mt-3"
|
||||||
|
[disabled]="!messageForm.valid || processingMessage"
|
||||||
|
type="submit">
|
||||||
|
<span *ngIf="processingMessage"><i class='fa fa-circle-o-notch fa-spin'></i> {{'mydspace.messages.send-btn' | translate}}</span>
|
||||||
|
<span *ngIf="!processingMessage">{{'mydspace.messages.send-btn' | translate}}</span>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
56
src/app/shared/message-board/message-board.component.scss
Normal file
56
src/app/shared/message-board/message-board.component.scss
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
@import '../../../styles/variables';
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
background-color: #2B4E72;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer {
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer :not(:first-child){
|
||||||
|
margin: 0 auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
right:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
//resize: none;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat
|
||||||
|
{
|
||||||
|
list-style: none;
|
||||||
|
margin: 10px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track
|
||||||
|
{
|
||||||
|
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
||||||
|
background-color: #FAF5F5;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar
|
||||||
|
{
|
||||||
|
width: 12px;
|
||||||
|
background-color: #F5F5FC;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb
|
||||||
|
{
|
||||||
|
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
|
||||||
|
background-color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification {
|
||||||
|
left: -20px;
|
||||||
|
top: -25px
|
||||||
|
}
|
245
src/app/shared/message-board/message-board.component.ts
Normal file
245
src/app/shared/message-board/message-board.component.ts
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
import { Component, EventEmitter, Input, OnDestroy, Output } from '@angular/core';
|
||||||
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
|
|
||||||
|
import { combineLatest, Observable, of as observableOf, Subscription } from 'rxjs';
|
||||||
|
import {
|
||||||
|
distinctUntilChanged,
|
||||||
|
filter,
|
||||||
|
find,
|
||||||
|
first,
|
||||||
|
flatMap,
|
||||||
|
map,
|
||||||
|
mergeMap,
|
||||||
|
reduce,
|
||||||
|
startWith,
|
||||||
|
tap,
|
||||||
|
withLatestFrom
|
||||||
|
} from 'rxjs/operators';
|
||||||
|
import { select, Store } from '@ngrx/store';
|
||||||
|
import { NgbActiveModal, NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
import { Bitstream } from '../../core/shared/bitstream.model';
|
||||||
|
import { MessageService } from '../../core/message/message.service';
|
||||||
|
import { NotificationsService } from '../notifications/notifications.service';
|
||||||
|
import { hasValue, isNotEmpty } from '../empty.util';
|
||||||
|
import { Item } from '../../core/shared/item.model';
|
||||||
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
|
import { MessageDataResponse } from '../../core/message/message-data-response';
|
||||||
|
import { AppState } from '../../app.reducer';
|
||||||
|
import { getAuthenticatedUser } from '../../core/auth/selectors';
|
||||||
|
import { EPerson } from '../../core/eperson/models/eperson.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-message-board',
|
||||||
|
styleUrls: ['./message-board.component.scss'],
|
||||||
|
templateUrl: './message-board.component.html',
|
||||||
|
providers: [
|
||||||
|
NgbActiveModal,
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
export class MessageBoardComponent implements OnDestroy {
|
||||||
|
@Input() dso: any;
|
||||||
|
@Input() tooltipMessage: string;
|
||||||
|
@Output() refresh = new EventEmitter<any>();
|
||||||
|
|
||||||
|
public item$: Observable<Item>;
|
||||||
|
public submitter$: Observable<EPerson>;
|
||||||
|
public user$: Observable<EPerson>;
|
||||||
|
public unreadMessages$: Observable<Bitstream[]> = observableOf([]);
|
||||||
|
public modalRef: NgbModalRef;
|
||||||
|
public itemUUID$: Observable<string>;
|
||||||
|
public messages$: Observable<Bitstream[]> = observableOf([]);
|
||||||
|
public isSubmitter$: Observable<boolean>;
|
||||||
|
public messageForm: FormGroup;
|
||||||
|
public processingMessage = false;
|
||||||
|
|
||||||
|
private subs: Subscription[] = [];
|
||||||
|
private rememberEmitUnread = false;
|
||||||
|
private rememberEmitRead = false;
|
||||||
|
|
||||||
|
constructor(private formBuilder: FormBuilder,
|
||||||
|
public msgService: MessageService,
|
||||||
|
private modalService: NgbModal,
|
||||||
|
private notificationsService: NotificationsService,
|
||||||
|
private store: Store<AppState>,
|
||||||
|
private translate: TranslateService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
// set formGroup
|
||||||
|
this.messageForm = this.formBuilder.group({
|
||||||
|
textSubject: ['', Validators.required],
|
||||||
|
textDescription: ['', Validators.required]
|
||||||
|
});
|
||||||
|
|
||||||
|
this.user$ = this.store.pipe(
|
||||||
|
select(getAuthenticatedUser),
|
||||||
|
find((user: EPerson) => isNotEmpty(user)),
|
||||||
|
map((user: EPerson) => user),
|
||||||
|
tap((u) => console.log(u)));
|
||||||
|
|
||||||
|
this.item$ = this.dso.item.pipe(
|
||||||
|
find((rd: RemoteData<Item>) => (rd.hasSucceeded && isNotEmpty(rd.payload))),
|
||||||
|
map((rd: RemoteData<Item>) => rd.payload),
|
||||||
|
tap((u) => console.log(u)));
|
||||||
|
|
||||||
|
this.submitter$ = (this.dso.submitter as Observable<RemoteData<EPerson[]>>).pipe(
|
||||||
|
find((rd: RemoteData<EPerson>) => rd.hasSucceeded && isNotEmpty(rd.payload)),
|
||||||
|
map((rd: RemoteData<EPerson>) => rd.payload),
|
||||||
|
tap((u) => console.log(u)));
|
||||||
|
|
||||||
|
this.isSubmitter$ = combineLatest(this.user$, this.submitter$).pipe(
|
||||||
|
filter(([user, submitter]) => isNotEmpty(user) && isNotEmpty(submitter)),
|
||||||
|
map(([user, submitter]) => user.uuid === submitter.uuid),
|
||||||
|
tap((u) => console.log(u)));
|
||||||
|
|
||||||
|
this.messages$ = this.item$.pipe(
|
||||||
|
find((item: Item) => isNotEmpty(item)),
|
||||||
|
flatMap((item: Item) => item.getBitstreamsByBundleName('MESSAGE')),
|
||||||
|
filter((bitStreams: Bitstream[]) => isNotEmpty(bitStreams)),
|
||||||
|
startWith([]),
|
||||||
|
distinctUntilChanged(),
|
||||||
|
tap((u) => console.log(u)));
|
||||||
|
|
||||||
|
this.unreadMessages$ = this.messages$.pipe(
|
||||||
|
filter((messages: Bitstream[]) => isNotEmpty(messages)),
|
||||||
|
flatMap((bitStream: Bitstream) =>
|
||||||
|
observableOf(bitStream).pipe(
|
||||||
|
withLatestFrom(this.isUnread(bitStream))
|
||||||
|
)
|
||||||
|
),
|
||||||
|
filter(([bitStream, isUnread]) => isUnread),
|
||||||
|
map(([bitStream, isUnread]) => bitStream),
|
||||||
|
reduce((acc: any, value: any) => [...acc, ...value], []),
|
||||||
|
startWith([])
|
||||||
|
);
|
||||||
|
|
||||||
|
this.itemUUID$ = this.item$.pipe(
|
||||||
|
find((item: Item) => isNotEmpty(item)),
|
||||||
|
map((item: Item) => item.uuid),
|
||||||
|
tap((u) => console.log(u)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMessage(itemUUID) {
|
||||||
|
this.processingMessage = true;
|
||||||
|
const subject: string = this.messageForm.get('textSubject').value;
|
||||||
|
const description: string = this.messageForm.get('textDescription').value;
|
||||||
|
const body = {
|
||||||
|
uuid: itemUUID,
|
||||||
|
subject,
|
||||||
|
description
|
||||||
|
};
|
||||||
|
this.subs.push(
|
||||||
|
this.msgService.createMessage(body).pipe(
|
||||||
|
first()
|
||||||
|
).subscribe((res: MessageDataResponse) => {
|
||||||
|
this.processingMessage = false;
|
||||||
|
this.modalRef.dismiss('Send Message');
|
||||||
|
if (res.hasSucceeded) {
|
||||||
|
// Refresh event
|
||||||
|
this.refresh.emit('read');
|
||||||
|
this.notificationsService.success(null,
|
||||||
|
this.translate.get('submission.workflow.tasks.generic.success'));
|
||||||
|
} else {
|
||||||
|
this.notificationsService.error(null,
|
||||||
|
this.translate.get('submission.workflow.tasks.generic.error'));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
markAsUnread(msgUUID: string) {
|
||||||
|
if (msgUUID) {
|
||||||
|
const body = {
|
||||||
|
uuid: msgUUID
|
||||||
|
};
|
||||||
|
this.subs.push(
|
||||||
|
this.msgService.markAsUnread(body).pipe(
|
||||||
|
find((res) => res.hasSucceeded)
|
||||||
|
).subscribe((res) => {
|
||||||
|
if (!res.error) {
|
||||||
|
this.rememberEmitUnread = true;
|
||||||
|
this.rememberEmitRead = false;
|
||||||
|
} else {
|
||||||
|
this.notificationsService.error(null, this.translate.get('submission.workflow.tasks.generic.error'));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emitRefresh() {
|
||||||
|
if (this.rememberEmitUnread && !this.rememberEmitRead) {
|
||||||
|
// Refresh event for Unread
|
||||||
|
this.refresh.emit('unread');
|
||||||
|
} else if (!this.rememberEmitUnread && this.rememberEmitRead) {
|
||||||
|
// Refresh event for Read
|
||||||
|
this.refresh.emit('read');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
markAsRead(msgUUID?: string) {
|
||||||
|
let ids$: Observable<string[]>;
|
||||||
|
if (msgUUID) {
|
||||||
|
ids$ = observableOf([msgUUID]);
|
||||||
|
} else {
|
||||||
|
ids$ = this.unreadMessages$.pipe(
|
||||||
|
filter((messages: Bitstream[]) => isNotEmpty(messages)),
|
||||||
|
flatMap((message: Bitstream) => message.uuid),
|
||||||
|
reduce((acc: any, value: any) => [...acc, ...value], []),
|
||||||
|
startWith([])
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.subs.push(
|
||||||
|
ids$.pipe(
|
||||||
|
filter((uuids) => isNotEmpty(uuids)),
|
||||||
|
mergeMap((uuid: any) => {
|
||||||
|
const body = { uuid };
|
||||||
|
return this.msgService.markAsRead(body)
|
||||||
|
})
|
||||||
|
).subscribe((res: MessageDataResponse) => {
|
||||||
|
if (res.hasSucceeded) {
|
||||||
|
this.rememberEmitRead = true;
|
||||||
|
this.rememberEmitUnread = false;
|
||||||
|
} else {
|
||||||
|
this.notificationsService.error(null, this.translate.get('submission.workflow.tasks.generic.error'));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
isUnread(m: Bitstream): Observable<boolean> {
|
||||||
|
const accessioned = m.firstMetadataValue('dc.date.accessioned');
|
||||||
|
const type = m.firstMetadataValue('dc.type');
|
||||||
|
return this.isSubmitter$.pipe(
|
||||||
|
filter((isSubmitter) => isNotEmpty(isSubmitter)),
|
||||||
|
map((isSubmitter) => (!accessioned &&
|
||||||
|
((isSubmitter && type === 'outbound') || (!isSubmitter && type === 'inbound')))
|
||||||
|
),
|
||||||
|
startWith(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
openMessageBoard(content) {
|
||||||
|
this.rememberEmitUnread = false;
|
||||||
|
this.rememberEmitRead = false;
|
||||||
|
this.markAsRead();
|
||||||
|
this.modalRef = this.modalService.open(content, { size: 'lg' });
|
||||||
|
this.modalRef.result.then((result) => {
|
||||||
|
this.emitRefresh();
|
||||||
|
}, (reason) => {
|
||||||
|
this.emitRefresh();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.subs
|
||||||
|
.filter((sub) => hasValue(sub))
|
||||||
|
.forEach((sub) => sub.unsubscribe());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
56
src/app/shared/message-board/message/message.component.html
Normal file
56
src/app/shared/message-board/message/message.component.html
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<li *ngVar="m.findMetadata('dc.type') as type"
|
||||||
|
[ngClass]="{'float-left': (type == 'outbound' && isSubmitter) || (type == 'inbound' && !isSubmitter),
|
||||||
|
'float-right': (type == 'outbound' && !isSubmitter) || (type == 'inbound' && isSubmitter),
|
||||||
|
'clearfix':1}">
|
||||||
|
|
||||||
|
<div class="chat-body clearfix">
|
||||||
|
<div class="header clearfix">
|
||||||
|
|
||||||
|
<small class="float-left">
|
||||||
|
<span class="fa fa-clock text-muted ">{{m.findMetadata('dc.date.issued') | date: 'dd/MM/yyyy HH:mm'}}</span>
|
||||||
|
</small>
|
||||||
|
|
||||||
|
<small
|
||||||
|
*ngIf="showUnread"
|
||||||
|
(click)="markAsUnread()"
|
||||||
|
class="text-muted pointer float-right ml-3">
|
||||||
|
<span class="fa fa-envelope"></span> {{'mydspace.messages.mark-as-unread' | translate}}
|
||||||
|
</small>
|
||||||
|
|
||||||
|
<small
|
||||||
|
*ngIf="showRead"
|
||||||
|
(click)="markAsRead()"
|
||||||
|
class="text-muted pointer float-right ml-3">
|
||||||
|
<span class="fa fa-envelope-open"></span> {{'mydspace.messages.mark-as-read' | translate}}
|
||||||
|
</small>
|
||||||
|
|
||||||
|
<div class="truncatable">
|
||||||
|
<ds-truncatable [id]="m.uuid">
|
||||||
|
<ds-truncatable-part [id]="m.uuid" [minLines]="1">
|
||||||
|
<label>From: <span><strong>{{isSubmitter && type == 'inbound' ? 'You' : m.findMetadata('dc.creator')}}</strong></span></label>
|
||||||
|
</ds-truncatable-part>
|
||||||
|
</ds-truncatable>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="truncatable" *ngVar="'obj_'.concat(m.uuid) as obj_id">
|
||||||
|
<ds-truncatable [id]="obj_id">
|
||||||
|
<ds-truncatable-part [id]="obj_id" [minLines]="1">
|
||||||
|
<label>Object: <span>{{m.findMetadata('dc.title')}}</span></label>
|
||||||
|
</ds-truncatable-part>
|
||||||
|
</ds-truncatable>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="btn btn-link" (click)="toggleDescription()">
|
||||||
|
<small *ngIf="showMessage">{{'mydspace.messages.hide-msg' | translate}}</small>
|
||||||
|
<small *ngIf="!showMessage">{{'mydspace.messages.show-msg' | translate}}</small>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div *ngIf="showMessage" class="description">
|
||||||
|
{{messageContent | async}}
|
||||||
|
<ds-loading *ngIf="loadingDescription" message="{{'loading.default' | translate}}"></ds-loading>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</li>
|
54
src/app/shared/message-board/message/message.component.scss
Normal file
54
src/app/shared/message-board/message/message.component.scss
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
$user_bg: #e6f2ff;
|
||||||
|
$other_bg: #EFEFEF;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-body {
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.float-left .chat-body {
|
||||||
|
background: $other_bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.float-right .chat-body {
|
||||||
|
background: $user_bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
li .chat-body p {
|
||||||
|
margin: 0;
|
||||||
|
color: #777777;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
color: #666666;
|
||||||
|
font-style: italic;
|
||||||
|
padding: 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.max250 {
|
||||||
|
max-width: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .float-right div[class^="clamp-"]
|
||||||
|
.content:after {
|
||||||
|
background: linear-gradient(to right, rgba(255, 255, 255, 0), $user_bg 70%) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .float-left div[class^="clamp-"]
|
||||||
|
.content:after {
|
||||||
|
background: linear-gradient(to right, rgba(255, 255, 255, 0), $other_bg 70%) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.truncatable {
|
||||||
|
clear: both;
|
||||||
|
}
|
83
src/app/shared/message-board/message/message.component.ts
Normal file
83
src/app/shared/message-board/message/message.component.ts
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
|
|
||||||
|
import { Observable, of as observableOf } from 'rxjs';
|
||||||
|
import { first, flatMap } from 'rxjs/operators';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
import { Bitstream } from '../../../core/shared/bitstream.model';
|
||||||
|
import { MessageService } from '../../../core/message/message.service';
|
||||||
|
import { isNull } from '../../empty.util';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-message',
|
||||||
|
styleUrls: ['./message.component.scss'],
|
||||||
|
templateUrl: './message.component.html'
|
||||||
|
})
|
||||||
|
|
||||||
|
export class MessageComponent implements OnInit {
|
||||||
|
@Input() m: Bitstream;
|
||||||
|
@Input() isLast: boolean;
|
||||||
|
@Input() isSubmitter: boolean;
|
||||||
|
|
||||||
|
@Output() emitUnread = new EventEmitter<any>();
|
||||||
|
@Output() emitRead = new EventEmitter<any>();
|
||||||
|
|
||||||
|
public showUnread: boolean;
|
||||||
|
public showRead: boolean;
|
||||||
|
public showMessage = false;
|
||||||
|
|
||||||
|
private _messageContent: Observable<string> = null;
|
||||||
|
private loadingDescription = false;
|
||||||
|
|
||||||
|
constructor(private cdr: ChangeDetectorRef,
|
||||||
|
private msgService: MessageService,
|
||||||
|
private translate: TranslateService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
const type = this.m.firstMetadataValue('dc.type');
|
||||||
|
|
||||||
|
if (this.isLast) {
|
||||||
|
if ((this.isSubmitter && type === 'outbound')
|
||||||
|
|| (!this.isSubmitter && type === 'inbound')) {
|
||||||
|
this.showUnread = true;
|
||||||
|
this.showRead = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.showUnread = false;
|
||||||
|
this.showRead = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleDescription() {
|
||||||
|
this.showMessage = !this.showMessage;
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
get messageContent(): Observable<string> {
|
||||||
|
if (isNull(this._messageContent) && !this.loadingDescription) {
|
||||||
|
this.loadingDescription = true;
|
||||||
|
this._messageContent = this.msgService.getMessageContent(this.m.content).pipe(
|
||||||
|
first(),
|
||||||
|
flatMap((res) => {
|
||||||
|
this._messageContent = res.payload ? observableOf(res.payload) : this.translate.get('mydspace.messages.no-content');
|
||||||
|
this.loadingDescription = false;
|
||||||
|
return this._messageContent;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return this._messageContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
markAsRead() {
|
||||||
|
this.emitRead.emit(true);
|
||||||
|
this.showUnread = true;
|
||||||
|
this.showRead = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
markAsUnread() {
|
||||||
|
this.emitUnread.emit(true);
|
||||||
|
this.showUnread = false;
|
||||||
|
this.showRead = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user