parent
4583e3e5d4
commit
b51f45c704
@ -1,13 +1,32 @@
|
|||||||
const utils = require('./utils');
|
const { uuid } = require('uuidv4');
|
||||||
const logger = require('./logger');
|
|
||||||
const db_api = require('./db');
|
const db_api = require('./db');
|
||||||
|
|
||||||
exports.sendNotification = async () => {
|
exports.sendNotification = async (notification) => {
|
||||||
// TODO: hook into third party service
|
// TODO: hook into third party service
|
||||||
|
await db_api.insertRecordIntoTable('notifications', notification);
|
||||||
|
return notification;
|
||||||
|
}
|
||||||
|
|
||||||
const notification = {}
|
exports.sendDownloadNotification = async (file, user_uid) => {
|
||||||
|
const data = {file_uid: file.uid, file_title: file.title};
|
||||||
|
const notification = exports.createNotification('download_complete', ['play'], data, user_uid);
|
||||||
|
return await exports.sendNotification(notification);
|
||||||
|
}
|
||||||
|
|
||||||
await db_api.insertRecordIntoTable('notifications', notification);
|
exports.sendDownloadErrorNotification = async (download, user_uid) => {
|
||||||
|
const data = {download_uid: download.uid, download_url: download.url};
|
||||||
|
const notification = exports.createNotification('download_error', ['view_download_error', 'retry_download'], data, user_uid);
|
||||||
|
return await exports.sendNotification(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.createNotification = (type, actions, data, user_uid) => {
|
||||||
|
const notification = {
|
||||||
|
type: type,
|
||||||
|
actions: actions,
|
||||||
|
data: data,
|
||||||
|
user_uid: user_uid,
|
||||||
|
uid: uuid(),
|
||||||
|
read: false
|
||||||
|
}
|
||||||
return notification;
|
return notification;
|
||||||
}
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
export enum NotificationType {
|
||||||
|
DOWNLOAD_COMPLETE = 'download_complete',
|
||||||
|
DOWNLOAD_ERROR = 'download_error',
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
<div *ngFor="let notification of notifications; let i = index;">
|
||||||
|
<mat-divider class="notification-divider"></mat-divider>
|
||||||
|
<div style="display: inline-block">
|
||||||
|
<ng-container *ngIf="NOTIFICATION_PREFIX[notification.type]">
|
||||||
|
{{NOTIFICATION_PREFIX[notification.type]}}
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="NOTIFICATION_SUFFIX_KEY[notification.type]">
|
||||||
|
{{notification['data'][NOTIFICATION_SUFFIX_KEY[notification.type]]}}
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
<div style="margin-left: 10px; float: right;" *ngIf="notification.actions?.length > 0">
|
||||||
|
<button (click)="emitDeleteNotification(notification.uid)" mat-icon-button><mat-icon>close</mat-icon></button>
|
||||||
|
<span *ngFor="let action of notification.actions">
|
||||||
|
<button [matTooltip]="NOTIFICATION_ACTION_TO_STRING[action]" (click)="emitNotificationAction(notification)" mat-icon-button><mat-icon>{{NOTIFICATION_ICON[action]}}</mat-icon></button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,4 @@
|
|||||||
|
.notification-divider {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { NotificationsListComponent } from './notifications-list.component';
|
||||||
|
|
||||||
|
describe('NotificationsListComponent', () => {
|
||||||
|
let component: NotificationsListComponent;
|
||||||
|
let fixture: ComponentFixture<NotificationsListComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ NotificationsListComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(NotificationsListComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,52 @@
|
|||||||
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
|
import { Notification } from 'api-types';
|
||||||
|
import { NotificationAction } from 'api-types/models/NotificationAction';
|
||||||
|
import { NotificationType } from 'api-types/models/NotificationType';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-notifications-list',
|
||||||
|
templateUrl: './notifications-list.component.html',
|
||||||
|
styleUrls: ['./notifications-list.component.scss']
|
||||||
|
})
|
||||||
|
export class NotificationsListComponent {
|
||||||
|
@Input() notifications = null;
|
||||||
|
@Output() deleteNotification = new EventEmitter<string>();
|
||||||
|
@Output() notificationAction = new EventEmitter<{notification: Notification, action: NotificationAction}>();
|
||||||
|
|
||||||
|
NOTIFICATION_PREFIX: { [key in NotificationType]: string } = {
|
||||||
|
download_complete: $localize`Finished downloading:`,
|
||||||
|
download_error: $localize`Download failed:`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attaches string to the end of the notification text
|
||||||
|
NOTIFICATION_SUFFIX_KEY: { [key in NotificationType]: string } = {
|
||||||
|
download_complete: 'file_title',
|
||||||
|
download_error: 'file_url'
|
||||||
|
}
|
||||||
|
|
||||||
|
NOTIFICATION_ACTION_TO_STRING: { [key in NotificationAction]: string } = {
|
||||||
|
play: $localize`Play`,
|
||||||
|
retry_download: $localize`Retry download`,
|
||||||
|
view_download_error: $localize`View error`
|
||||||
|
}
|
||||||
|
|
||||||
|
NOTIFICATION_COLOR: { [key in NotificationAction]: string } = {
|
||||||
|
play: 'primary',
|
||||||
|
retry_download: 'primary',
|
||||||
|
view_download_error: 'warn'
|
||||||
|
}
|
||||||
|
|
||||||
|
NOTIFICATION_ICON: { [key in NotificationAction]: string } = {
|
||||||
|
play: 'smart_display',
|
||||||
|
retry_download: 'restart_alt',
|
||||||
|
view_download_error: 'warning'
|
||||||
|
}
|
||||||
|
|
||||||
|
emitNotificationAction(notification: Notification, action: NotificationAction): void {
|
||||||
|
this.notificationAction.emit({notification: notification, action: action});
|
||||||
|
}
|
||||||
|
|
||||||
|
emitDeleteNotification(uid: string): void {
|
||||||
|
this.deleteNotification.emit(uid);
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,3 @@
|
|||||||
.notification-divider {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notification-title {
|
.notification-title {
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
text-align: center
|
text-align: center
|
||||||
|
@ -1,32 +1,10 @@
|
|||||||
<h4 *ngIf="notifications !== null && notifications.length === 0 && read_notifications.length === 0" style="text-align: center; margin: 10px;">No notifications available</h4>
|
<h4 *ngIf="notifications !== null && notifications.length === 0 && read_notifications.length === 0" style="text-align: center; margin: 10px;" i18n="No notifications available">No notifications available</h4>
|
||||||
<div style="margin: 10px;" *ngIf="notifications?.length > 0">
|
<div style="margin: 10px;" *ngIf="notifications?.length > 0">
|
||||||
<h4 class="notification-title">New notifications</h4>
|
<h4 class="notification-title" i18n="New notifications">New notifications</h4>
|
||||||
<div *ngFor="let notification of appService.notifications; let i = index;">
|
<app-notifications-list (notificationAction)="notificationAction($event)" (deleteNotification)="deleteNotification($event)" [notifications]="notifications"></app-notifications-list>
|
||||||
<mat-divider class="notification-divider"></mat-divider>
|
|
||||||
<div style="display: inline-block;">
|
|
||||||
<button (click)="deleteNotification(notification.id, i, false)" mat-icon-button><mat-icon>close</mat-icon></button>
|
|
||||||
</div>
|
|
||||||
<div style="display: inline-block">
|
|
||||||
{{notification.title}}
|
|
||||||
</div>
|
|
||||||
<div style="margin-left: 10px; float: right;" *ngIf="notification.action">
|
|
||||||
<button (click)="notificationAction(notification)" [color]="notification.action.warn ? 'warn' : 'primary'" mat-raised-button>{{notification.action.title}}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="margin: 10px;" *ngIf="read_notifications?.length > 0">
|
<div style="margin: 10px;" *ngIf="read_notifications?.length > 0">
|
||||||
<h4 class="notification-title">Old notifications</h4>
|
<h4 class="notification-title" i18n="Old notifications">Old notifications</h4>
|
||||||
<div *ngFor="let notification of appService.read_notifications; let i = index">
|
<app-notifications-list (notificationAction)="notificationAction($event)" (deleteNotification)="deleteNotification($event)" [notifications]="read_notifications"></app-notifications-list>
|
||||||
<mat-divider class="notification-divider"></mat-divider>
|
|
||||||
<div style="display: inline-block;">
|
|
||||||
<button (click)="deleteNotification(notification.id, i, true)" mat-icon-button><mat-icon>close</mat-icon></button>
|
|
||||||
</div>
|
|
||||||
<div style="display: inline-block">
|
|
||||||
{{notification.title}}
|
|
||||||
</div>
|
|
||||||
<div style="margin-left: 10px; float: right" *ngIf="notification.action">
|
|
||||||
<button (click)="notificationAction(notification)" [color]="notification.action.warn ? 'warn' : 'primary'" mat-raised-button>{{notification.action.title}}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
Loading…
Reference in New Issue