mirror of
https://github.com/block-core/angor-hub-old.git
synced 2026-01-04 02:14:21 +01:00
Add Notification Settings
This commit is contained in:
@@ -13,16 +13,16 @@ import { provideAngor } from '@angor';
|
|||||||
import { TranslocoService, provideTransloco } from '@ngneat/transloco';
|
import { TranslocoService, provideTransloco } from '@ngneat/transloco';
|
||||||
import { appRoutes } from 'app/app.routes';
|
import { appRoutes } from 'app/app.routes';
|
||||||
import { provideIcons } from 'app/core/icons/icons.provider';
|
import { provideIcons } from 'app/core/icons/icons.provider';
|
||||||
import { mockApiServices } from 'app/mock-api';
|
|
||||||
import { firstValueFrom } from 'rxjs';
|
import { firstValueFrom } from 'rxjs';
|
||||||
import { TranslocoHttpLoader } from './core/transloco/transloco.http-loader';
|
import { TranslocoHttpLoader } from './core/transloco/transloco.http-loader';
|
||||||
import { provideServiceWorker } from '@angular/service-worker';
|
import { provideServiceWorker } from '@angular/service-worker';
|
||||||
import { HashService } from './services/hash.service';
|
import { HashService } from './services/hash.service';
|
||||||
|
import { navigationServices } from './layout/navigation/navigation.services';
|
||||||
|
|
||||||
export function initializeApp(hashService: HashService) {
|
export function initializeApp(hashService: HashService) {
|
||||||
console.log('initializeApp. Getting hashService.load.');
|
console.log('initializeApp. Getting hashService.load.');
|
||||||
return (): Promise<void> => hashService.load();
|
return (): Promise<void> => hashService.load();
|
||||||
}
|
}
|
||||||
export const appConfig: ApplicationConfig = {
|
export const appConfig: ApplicationConfig = {
|
||||||
providers: [
|
providers: [
|
||||||
provideAnimations(),
|
provideAnimations(),
|
||||||
@@ -36,7 +36,7 @@ export const appConfig: ApplicationConfig = {
|
|||||||
useFactory: initializeApp,
|
useFactory: initializeApp,
|
||||||
deps: [HashService],
|
deps: [HashService],
|
||||||
multi: true,
|
multi: true,
|
||||||
},
|
},
|
||||||
provideRouter(
|
provideRouter(
|
||||||
appRoutes,
|
appRoutes,
|
||||||
withPreloading(PreloadAllModules),
|
withPreloading(PreloadAllModules),
|
||||||
@@ -97,7 +97,7 @@ export const appConfig: ApplicationConfig = {
|
|||||||
provideAngor({
|
provideAngor({
|
||||||
mockApi: {
|
mockApi: {
|
||||||
delay: 0,
|
delay: 0,
|
||||||
services: mockApiServices,
|
services: navigationServices,
|
||||||
},
|
},
|
||||||
angor: JSON.parse(localStorage.getItem('angorConfig')) ?? {
|
angor: JSON.parse(localStorage.getItem('angorConfig')) ?? {
|
||||||
layout: 'classic',
|
layout: 'classic',
|
||||||
|
|||||||
@@ -1,156 +1,51 @@
|
|||||||
<div class="w-full max-w-3xl">
|
<div class="w-full max-w-3xl">
|
||||||
<!-- Form -->
|
<!-- Form -->
|
||||||
<form [formGroup]="notificationsForm">
|
<form [formGroup]="notificationsForm">
|
||||||
<!-- Section -->
|
<div class="w-full text-xl">Notification Settings</div>
|
||||||
<div class="w-full text-xl">Alerts</div>
|
|
||||||
<div class="mt-8 grid w-full grid-cols-1 gap-6">
|
<div class="mt-8 grid w-full grid-cols-1 gap-6">
|
||||||
<!-- Communication -->
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<div
|
|
||||||
class="flex-auto cursor-pointer"
|
|
||||||
(click)="communication.toggle()"
|
|
||||||
>
|
|
||||||
<div class="font-medium leading-6">Communication</div>
|
|
||||||
<div class="text-secondary text-md">
|
|
||||||
Get news, announcements, and product updates.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<mat-slide-toggle
|
|
||||||
class="ml-2"
|
|
||||||
[color]="'primary'"
|
|
||||||
[formControlName]="'communication'"
|
|
||||||
#communication
|
|
||||||
>
|
|
||||||
</mat-slide-toggle>
|
|
||||||
</div>
|
|
||||||
<!-- Security -->
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<div
|
|
||||||
class="flex-auto cursor-pointer"
|
|
||||||
(click)="securityToggle.toggle()"
|
|
||||||
>
|
|
||||||
<div class="font-medium leading-6">Security</div>
|
|
||||||
<div class="text-secondary text-md">
|
|
||||||
Get important notifications about your account security.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<mat-slide-toggle
|
|
||||||
class="ml-2"
|
|
||||||
[color]="'primary'"
|
|
||||||
[formControlName]="'security'"
|
|
||||||
#securityToggle
|
|
||||||
>
|
|
||||||
</mat-slide-toggle>
|
|
||||||
</div>
|
|
||||||
<!-- Meetups -->
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<div
|
|
||||||
class="flex-auto cursor-pointer"
|
|
||||||
(click)="meetupsToggle.toggle()"
|
|
||||||
>
|
|
||||||
<div class="font-medium leading-6">Meetups</div>
|
|
||||||
<div class="text-secondary text-md">
|
|
||||||
Get an email when a Meetup is posted close to my
|
|
||||||
location.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<mat-slide-toggle
|
|
||||||
class="ml-2"
|
|
||||||
[color]="'primary'"
|
|
||||||
[formControlName]="'meetups'"
|
|
||||||
#meetupsToggle
|
|
||||||
>
|
|
||||||
</mat-slide-toggle>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Divider -->
|
|
||||||
<div class="my-10 border-t"></div>
|
|
||||||
|
|
||||||
<!-- Section -->
|
|
||||||
<div class="w-full text-xl">Account Activity</div>
|
|
||||||
<div class="mt-8 w-full font-medium">Email me when:</div>
|
|
||||||
<div class="mt-4 grid w-full grid-cols-1 gap-4">
|
|
||||||
<!-- Comments -->
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<div
|
|
||||||
class="flex-auto cursor-pointer leading-6"
|
|
||||||
(click)="comments.toggle()"
|
|
||||||
>
|
|
||||||
someone comments on one of my items
|
|
||||||
</div>
|
|
||||||
<mat-slide-toggle
|
|
||||||
class="ml-2"
|
|
||||||
[color]="'primary'"
|
|
||||||
[formControlName]="'comments'"
|
|
||||||
#comments
|
|
||||||
>
|
|
||||||
</mat-slide-toggle>
|
|
||||||
</div>
|
|
||||||
<!-- Mention -->
|
<!-- Mention -->
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div
|
<div class="flex-auto cursor-pointer" (click)="mentionToggle.toggle()">
|
||||||
class="flex-auto cursor-pointer leading-6"
|
<div class="font-medium leading-6">Mention</div>
|
||||||
(click)="mention.toggle()"
|
<div class="text-secondary text-md">Receive notifications when someone mentions you.</div>
|
||||||
>
|
|
||||||
someone mentions me
|
|
||||||
</div>
|
</div>
|
||||||
<mat-slide-toggle
|
<mat-slide-toggle class="ml-2" [color]="'primary'" [formControlName]="'mention'" #mentionToggle></mat-slide-toggle>
|
||||||
class="ml-2"
|
|
||||||
[color]="'primary'"
|
|
||||||
[formControlName]="'mention'"
|
|
||||||
#mention
|
|
||||||
>
|
|
||||||
</mat-slide-toggle>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- Follow -->
|
|
||||||
|
<!-- Private Message -->
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div
|
<div class="flex-auto cursor-pointer" (click)="privateMessageToggle.toggle()">
|
||||||
class="flex-auto cursor-pointer leading-6"
|
<div class="font-medium leading-6">Private Message</div>
|
||||||
(click)="follow.toggle()"
|
<div class="text-secondary text-md">Receive notifications for private messages.</div>
|
||||||
>
|
|
||||||
someone follows me
|
|
||||||
</div>
|
</div>
|
||||||
<mat-slide-toggle
|
<mat-slide-toggle class="ml-2" [color]="'primary'" [formControlName]="'privateMessage'" #privateMessageToggle></mat-slide-toggle>
|
||||||
class="ml-2"
|
|
||||||
[color]="'primary'"
|
|
||||||
[formControlName]="'follow'"
|
|
||||||
#follow
|
|
||||||
>
|
|
||||||
</mat-slide-toggle>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- Inquiry -->
|
|
||||||
|
<!-- Zap -->
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div
|
<div class="flex-auto cursor-pointer" (click)="zapToggle.toggle()">
|
||||||
class="flex-auto cursor-pointer leading-6"
|
<div class="font-medium leading-6">Zap</div>
|
||||||
(click)="inquiry.toggle()"
|
<div class="text-secondary text-md">Receive notifications when you get a zap.</div>
|
||||||
>
|
|
||||||
someone replies to my job posting
|
|
||||||
</div>
|
</div>
|
||||||
<mat-slide-toggle
|
<mat-slide-toggle class="ml-2" [color]="'primary'" [formControlName]="'zap'" #zapToggle></mat-slide-toggle>
|
||||||
class="ml-2"
|
</div>
|
||||||
[color]="'primary'"
|
|
||||||
[formControlName]="'inquiry'"
|
<!-- New Follower -->
|
||||||
#inquiry
|
<div class="flex items-center justify-between">
|
||||||
>
|
<div class="flex-auto cursor-pointer" (click)="followerToggle.toggle()">
|
||||||
</mat-slide-toggle>
|
<div class="font-medium leading-6">New Follower</div>
|
||||||
|
<div class="text-secondary text-md">Receive notifications when someone follows you.</div>
|
||||||
|
</div>
|
||||||
|
<mat-slide-toggle class="ml-2" [color]="'primary'" [formControlName]="'follower'" #followerToggle></mat-slide-toggle>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Divider -->
|
|
||||||
<div class="my-10 border-t"></div>
|
<div class="my-10 border-t"></div>
|
||||||
|
|
||||||
<!-- Actions -->
|
<!-- Actions -->
|
||||||
<div class="flex items-center justify-end">
|
<div class="flex items-center justify-end">
|
||||||
<button mat-stroked-button type="button">Cancel</button>
|
<button mat-stroked-button type="button">Cancel</button>
|
||||||
<button
|
<button class="ml-4" mat-flat-button type="button" [color]="'primary'" (click)="saveSettings()">Save</button>
|
||||||
class="ml-4"
|
|
||||||
mat-flat-button
|
|
||||||
type="button"
|
|
||||||
[color]="'primary'"
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -28,29 +28,53 @@ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|||||||
})
|
})
|
||||||
export class SettingsNotificationsComponent implements OnInit {
|
export class SettingsNotificationsComponent implements OnInit {
|
||||||
notificationsForm: UntypedFormGroup;
|
notificationsForm: UntypedFormGroup;
|
||||||
|
notificationKinds: { [key: string]: number } = {
|
||||||
|
mention: 1,
|
||||||
|
privateMessage: 4,
|
||||||
|
zap: 9735,
|
||||||
|
follower: 3,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
constructor(private _formBuilder: UntypedFormBuilder) {}
|
constructor(private _formBuilder: UntypedFormBuilder) {}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Lifecycle hooks
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* On init
|
|
||||||
*/
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
// Create the form
|
const savedSettings = this.loadNotificationSettings();
|
||||||
|
|
||||||
this.notificationsForm = this._formBuilder.group({
|
this.notificationsForm = this._formBuilder.group({
|
||||||
communication: [true],
|
mention: [savedSettings.includes(this.notificationKinds.mention)],
|
||||||
security: [true],
|
privateMessage: [savedSettings.includes(this.notificationKinds.privateMessage)],
|
||||||
meetups: [false],
|
zap: [savedSettings.includes(this.notificationKinds.zap)],
|
||||||
comments: [false],
|
follower: [savedSettings.includes(this.notificationKinds.follower)],
|
||||||
mention: [true],
|
|
||||||
follow: [true],
|
|
||||||
inquiry: [true],
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveSettings(): void {
|
||||||
|
const formValues = this.notificationsForm.value;
|
||||||
|
const enabledKinds: number[] = [];
|
||||||
|
|
||||||
|
if (formValues.mention) {
|
||||||
|
enabledKinds.push(this.notificationKinds.mention);
|
||||||
|
}
|
||||||
|
if (formValues.privateMessage) {
|
||||||
|
enabledKinds.push(this.notificationKinds.privateMessage);
|
||||||
|
}
|
||||||
|
if (formValues.zap) {
|
||||||
|
enabledKinds.push(this.notificationKinds.zap);
|
||||||
|
}
|
||||||
|
if (formValues.follower) {
|
||||||
|
enabledKinds.push(this.notificationKinds.follower);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.saveNotificationSettings(enabledKinds);
|
||||||
|
console.log('Notification settings saved:', enabledKinds);
|
||||||
|
}
|
||||||
|
|
||||||
|
private saveNotificationSettings(settings: number[]): void {
|
||||||
|
localStorage.setItem('notificationSettings', JSON.stringify(settings));
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadNotificationSettings(): number[] {
|
||||||
|
const storedSettings = localStorage.getItem('notificationSettings');
|
||||||
|
return storedSettings ? JSON.parse(storedSettings) : [1, 3, 4, 9735]; // Default to all kinds if not set
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,26 +9,14 @@ export class NavigationService {
|
|||||||
private _navigation: ReplaySubject<Navigation> =
|
private _navigation: ReplaySubject<Navigation> =
|
||||||
new ReplaySubject<Navigation>(1);
|
new ReplaySubject<Navigation>(1);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Accessors
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter for navigation
|
|
||||||
*/
|
|
||||||
get navigation$(): Observable<Navigation> {
|
get navigation$(): Observable<Navigation> {
|
||||||
return this._navigation.asObservable();
|
return this._navigation.asObservable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Public methods
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all navigation data
|
|
||||||
*/
|
|
||||||
get(): Observable<Navigation> {
|
get(): Observable<Navigation> {
|
||||||
return this._httpClient.get<Navigation>('api/common/navigation').pipe(
|
return this._httpClient.get<Navigation>('api/navigation').pipe(
|
||||||
tap((navigation) => {
|
tap((navigation) => {
|
||||||
this._navigation.next(navigation);
|
this._navigation.next(navigation);
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import {
|
|||||||
defaultNavigation,
|
defaultNavigation,
|
||||||
futuristicNavigation,
|
futuristicNavigation,
|
||||||
horizontalNavigation,
|
horizontalNavigation,
|
||||||
} from 'app/mock-api/common/navigation/data';
|
} from 'app/layout/navigation/data';
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class NavigationMockApi {
|
export class NavigationApi {
|
||||||
private readonly _compactNavigation: AngorNavigationItem[] =
|
private readonly _compactNavigation: AngorNavigationItem[] =
|
||||||
compactNavigation;
|
compactNavigation;
|
||||||
private readonly _defaultNavigation: AngorNavigationItem[] =
|
private readonly _defaultNavigation: AngorNavigationItem[] =
|
||||||
@@ -20,26 +20,13 @@ export class NavigationMockApi {
|
|||||||
private readonly _horizontalNavigation: AngorNavigationItem[] =
|
private readonly _horizontalNavigation: AngorNavigationItem[] =
|
||||||
horizontalNavigation;
|
horizontalNavigation;
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
constructor(private _angorMockApiService: AngorMockApiService) {
|
constructor(private _angorMockApiService: AngorMockApiService) {
|
||||||
// Register Mock API handlers
|
// Register Mock API handlers
|
||||||
this.registerHandlers();
|
this.registerHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Public methods
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register Mock API handlers
|
|
||||||
*/
|
|
||||||
registerHandlers(): void {
|
registerHandlers(): void {
|
||||||
// -----------------------------------------------------------------------------------------------------
|
this._angorMockApiService.onGet('api/navigation').reply(() => {
|
||||||
// @ Navigation - GET
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
this._angorMockApiService.onGet('api/common/navigation').reply(() => {
|
|
||||||
// Fill compact navigation children using the default navigation
|
// Fill compact navigation children using the default navigation
|
||||||
this._compactNavigation.forEach((compactNavItem) => {
|
this._compactNavigation.forEach((compactNavItem) => {
|
||||||
this._defaultNavigation.forEach((defaultNavItem) => {
|
this._defaultNavigation.forEach((defaultNavItem) => {
|
||||||
5
src/app/layout/navigation/navigation.services.ts
Normal file
5
src/app/layout/navigation/navigation.services.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { NavigationApi } from "./api";
|
||||||
|
|
||||||
|
export const navigationServices = [
|
||||||
|
NavigationApi,
|
||||||
|
];
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { AngorMockApiService } from '@angor/lib/mock-api';
|
|
||||||
import {
|
|
||||||
chats as chatsData,
|
|
||||||
contacts as contactsData,
|
|
||||||
messages as messagesData,
|
|
||||||
profile as profileData,
|
|
||||||
} from 'app/mock-api/apps/chat/data';
|
|
||||||
import { assign, cloneDeep, omit } from 'lodash-es';
|
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
|
||||||
export class ChatMockApi {
|
|
||||||
private _chats: any[] = chatsData;
|
|
||||||
private _contacts: any[] = contactsData;
|
|
||||||
private _messages: any[] = messagesData;
|
|
||||||
private _profile: any = profileData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
constructor(private _angorMockApiService: AngorMockApiService) {
|
|
||||||
// Register Mock API handlers
|
|
||||||
this.registerHandlers();
|
|
||||||
|
|
||||||
// Modify the chats array to attach certain data to it
|
|
||||||
this._chats = this._chats.map((chat) => ({
|
|
||||||
...chat,
|
|
||||||
// Get the actual contact object from the id and attach it to the chat
|
|
||||||
contact: this._contacts.find(
|
|
||||||
(contact) => contact.id === chat.contactId
|
|
||||||
),
|
|
||||||
// Since we use same set of messages on all chats, we assign them here.
|
|
||||||
messages: this._messages.map((message) => ({
|
|
||||||
...message,
|
|
||||||
chatId: chat.id,
|
|
||||||
contactId:
|
|
||||||
message.contactId === 'me'
|
|
||||||
? this._profile.id
|
|
||||||
: chat.contactId,
|
|
||||||
isMine: message.contactId === 'me',
|
|
||||||
})),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Public methods
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register Mock API handlers
|
|
||||||
*/
|
|
||||||
registerHandlers(): void {
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Chats - GET
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
this._angorMockApiService.onGet('api/apps/chat/chats').reply(() => {
|
|
||||||
// Clone the chats
|
|
||||||
const chats = cloneDeep(this._chats);
|
|
||||||
|
|
||||||
// Return the response
|
|
||||||
return [200, chats];
|
|
||||||
});
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Chat - GET
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
this._angorMockApiService
|
|
||||||
.onGet('api/apps/chat/chat')
|
|
||||||
.reply(({ request }) => {
|
|
||||||
// Get the chat id
|
|
||||||
const id = request.params.get('id');
|
|
||||||
|
|
||||||
// Clone the chats
|
|
||||||
const chats = cloneDeep(this._chats);
|
|
||||||
|
|
||||||
// Find the chat we need
|
|
||||||
const chat = chats.find((item) => item.id === id);
|
|
||||||
|
|
||||||
// Return the response
|
|
||||||
return [200, chat];
|
|
||||||
});
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Chat - PATCH
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
this._angorMockApiService
|
|
||||||
.onPatch('api/apps/chat/chat')
|
|
||||||
.reply(({ request }) => {
|
|
||||||
// Get the id and chat
|
|
||||||
const id = request.body.id;
|
|
||||||
const chat = cloneDeep(request.body.chat);
|
|
||||||
|
|
||||||
// Prepare the updated chat
|
|
||||||
let updatedChat = null;
|
|
||||||
|
|
||||||
// Find the chat and update it
|
|
||||||
this._chats.forEach((item, index, chats) => {
|
|
||||||
if (item.id === id) {
|
|
||||||
// Update the chat
|
|
||||||
chats[index] = assign({}, chats[index], chat);
|
|
||||||
|
|
||||||
// Store the updated chat
|
|
||||||
updatedChat = chats[index];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Return the response
|
|
||||||
return [200, updatedChat];
|
|
||||||
});
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Contacts - GET
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
this._angorMockApiService.onGet('api/apps/chat/contacts').reply(() => {
|
|
||||||
// Clone the contacts
|
|
||||||
let contacts = cloneDeep(this._contacts);
|
|
||||||
|
|
||||||
// Sort the contacts by the name field by default
|
|
||||||
contacts.sort((a, b) => a.name.localeCompare(b.name));
|
|
||||||
|
|
||||||
// Omit details and attachments from contacts
|
|
||||||
contacts = contacts.map((contact) =>
|
|
||||||
omit(contact, ['details', 'attachments'])
|
|
||||||
);
|
|
||||||
|
|
||||||
// Return the response
|
|
||||||
return [200, contacts];
|
|
||||||
});
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Contact Details - GET
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
this._angorMockApiService
|
|
||||||
.onGet('api/apps/chat/contact')
|
|
||||||
.reply(({ request }) => {
|
|
||||||
// Get the contact id
|
|
||||||
const id = request.params.get('id');
|
|
||||||
|
|
||||||
// Clone the contacts
|
|
||||||
const contacts = cloneDeep(this._contacts);
|
|
||||||
|
|
||||||
// Find the contact
|
|
||||||
const contact = contacts.find((item) => item.id === id);
|
|
||||||
|
|
||||||
// Return the response
|
|
||||||
return [200, contact];
|
|
||||||
});
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Profile - GET
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
this._angorMockApiService.onGet('api/apps/chat/profile').reply(() => {
|
|
||||||
// Clone the profile
|
|
||||||
const profile = cloneDeep(this._profile);
|
|
||||||
|
|
||||||
// Return the response
|
|
||||||
return [200, profile];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,266 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
import { DateTime } from 'luxon';
|
|
||||||
|
|
||||||
/* Get the current instant */
|
|
||||||
const now = DateTime.now();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attachments are common and will be filled from here
|
|
||||||
* to keep the demo data maintainable.
|
|
||||||
*/
|
|
||||||
const _attachments = {
|
|
||||||
media: [
|
|
||||||
'images/cards/01-320x200.jpg',
|
|
||||||
'images/cards/02-320x200.jpg',
|
|
||||||
'images/cards/03-320x200.jpg',
|
|
||||||
'images/cards/04-320x200.jpg',
|
|
||||||
'images/cards/05-320x200.jpg',
|
|
||||||
'images/cards/06-320x200.jpg',
|
|
||||||
'images/cards/07-320x200.jpg',
|
|
||||||
'images/cards/08-320x200.jpg',
|
|
||||||
],
|
|
||||||
docs: [],
|
|
||||||
links: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If a message belongs to our user, it's marked by setting it as
|
|
||||||
* 'me'. If it belongs to the user we are chatting with, then it
|
|
||||||
* left empty. We will be using this same conversation for each chat
|
|
||||||
* to keep things more maintainable for the demo.
|
|
||||||
*/
|
|
||||||
export const messages = [
|
|
||||||
{
|
|
||||||
id: 'e6b2b82f-b199-4a60-9696-5f3e40d2715d',
|
|
||||||
contactId: 'me',
|
|
||||||
value: 'Hi!',
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 18, minute: 56 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'eb82cf4b-fa93-4bf4-a88a-99e987ddb7ea',
|
|
||||||
contactId: '',
|
|
||||||
value: 'Hey, dude!',
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 4 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3cf9b2a6-ae54-47db-97b2-ee139a8f84e5',
|
|
||||||
contactId: '',
|
|
||||||
value: 'Long time no see.',
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 4 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2ab91b0f-fafb-45f3-88df-7efaff29134b',
|
|
||||||
contactId: 'me',
|
|
||||||
value: 'Yeah, man... Things were quite busy for me and my family.',
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 6 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '10e81481-378f-49ac-b06b-7c59dcc639ae',
|
|
||||||
contactId: '',
|
|
||||||
value: "What's up? Anything I can help with?",
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 6 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3b334e72-6605-4ebd-a4f6-3850067048de',
|
|
||||||
contactId: 'me',
|
|
||||||
value: "We've been on the move, changed 3 places over 4 months.",
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 7 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '25998113-3a96-4dd0-a7b9-4d2bb58db3f3',
|
|
||||||
contactId: '',
|
|
||||||
value: "Wow! That's crazy! 🤯 What happened?",
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 7 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '30adb3da-0e4f-487e-aec2-6d9f31e097f6',
|
|
||||||
contactId: 'me',
|
|
||||||
value: 'You know I got a job in that big software company. First move was because of that.',
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 8 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'c0d6fd6e-d294-4845-8751-e84b8f2c4d3b',
|
|
||||||
contactId: 'me',
|
|
||||||
value: 'Then they decided to re-locate me after a month.',
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 8 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '8d3c442b-62fa-496f-bffa-210ff5c1866b',
|
|
||||||
contactId: 'me',
|
|
||||||
value: 'It was a pain since we just settled in, house, kids’ school, etc.',
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 8 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3cf26ef0-e81f-4698-ac39-487454413332',
|
|
||||||
contactId: 'me',
|
|
||||||
value: 'So we moved again.',
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 9 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '415151b9-9ee9-40a4-a4ad-2d88146bc71b',
|
|
||||||
contactId: '',
|
|
||||||
value: "It's crazy!",
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 9 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'd6f29648-c85c-4dfb-a6ff-6b7ebc40c993',
|
|
||||||
contactId: 'me',
|
|
||||||
value: 'Then the virus happened, and we went remote after moving again.',
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 10 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '5329c20d-6754-47ec-af8c-660c72be3528',
|
|
||||||
contactId: 'me',
|
|
||||||
value: "So we moved back to the first location, the third time!",
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 10 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '26f2ccbf-aef7-4b49-88df-f6b59381110a',
|
|
||||||
contactId: '',
|
|
||||||
value: "Ohh dude, that's tough in such a short period.",
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 11 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'ea7662d5-7b72-4c19-ad6c-f80320541001',
|
|
||||||
contactId: '',
|
|
||||||
value: '😕',
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 11 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3a2d3a0e-839b-46e7-86ae-ca0826ecda7c',
|
|
||||||
contactId: 'me',
|
|
||||||
value: 'Thanks! It was great catching up.',
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 11 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '562e3524-15b7-464a-bbf6-9b2582e5e0ee',
|
|
||||||
contactId: '',
|
|
||||||
value: 'Yeah! Let’s grab a coffee next week, remotely!',
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 12 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '9269c775-bad5-46e1-b33b-2de8704ec1d6',
|
|
||||||
contactId: 'me',
|
|
||||||
value: 'Sure! See you next week!',
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 12 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '779a27f2-bece-41c6-b9ca-c422570aee68',
|
|
||||||
contactId: '',
|
|
||||||
value: 'See you!',
|
|
||||||
createdAt: now.minus({ week: 1 }).set({ hour: 19, minute: 12 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'bab8ca0e-b8e5-4375-807b-1c91fca25a5d',
|
|
||||||
contactId: 'me',
|
|
||||||
value: 'Hey! Available now? Let’s grab that coffee, remotely! :)',
|
|
||||||
createdAt: now.set({ hour: 12, minute: 45 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '8445a84d-599d-4e2d-a31c-5f4f29ad2b4c',
|
|
||||||
contactId: '',
|
|
||||||
value: 'Hi!',
|
|
||||||
createdAt: now.set({ hour: 12, minute: 56 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '9f506742-50da-4350-af9d-61e53392fa08',
|
|
||||||
contactId: '',
|
|
||||||
value: "Sure! I'll call you in 5, okay?",
|
|
||||||
createdAt: now.set({ hour: 12, minute: 56 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'ca8523d8-faed-45f7-af09-f6bd5c3f3875',
|
|
||||||
contactId: 'me',
|
|
||||||
value: 'Awesome! Call me in 5 minutes.',
|
|
||||||
createdAt: now.set({ hour: 12, minute: 58 }).toISO(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '39944b00-1ffe-4ffb-8ca6-13c292812e06',
|
|
||||||
contactId: '',
|
|
||||||
value: '👍🏻',
|
|
||||||
createdAt: now.set({ hour: 13, minute: 0 }).toISO(),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
export const chats = [
|
|
||||||
{
|
|
||||||
id: 'ff6bc7f1-449a-4419-af62-b89ce6cae0aa',
|
|
||||||
contactId: '9d3f0e7f-dcbd-4e56-a5e8-87b8154e9edf',
|
|
||||||
unreadCount: 2,
|
|
||||||
muted: false,
|
|
||||||
lastMessage: 'See you tomorrow!',
|
|
||||||
lastMessageAt: '26/04/2021',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '4459a3f0-b65e-4df2-8c37-6ec72fcc4b31',
|
|
||||||
contactId: '16b9e696-ea95-4dd8-86c4-3caf705a1dc6',
|
|
||||||
unreadCount: 0,
|
|
||||||
muted: false,
|
|
||||||
lastMessage: 'See you tomorrow!',
|
|
||||||
lastMessageAt: '26/04/2021',
|
|
||||||
}
|
|
||||||
];
|
|
||||||
export const contacts = [
|
|
||||||
{
|
|
||||||
id: '16b9e696-ea95-4dd8-86c4-3caf705a1dc6',
|
|
||||||
avatar: 'images/avatars/avatar-placeholder.png',
|
|
||||||
name: 'Sali',
|
|
||||||
about: "Hi there! I'm using AngorChat.",
|
|
||||||
details: {
|
|
||||||
emails: [
|
|
||||||
{
|
|
||||||
email: 'nunezfaulkner@mail.tv',
|
|
||||||
label: 'Personal',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
phoneNumbers: [
|
|
||||||
{
|
|
||||||
country: 'xk',
|
|
||||||
phoneNumber: '909 552 3327',
|
|
||||||
label: 'Mobile',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
title: 'Hotel Manager',
|
|
||||||
company: 'Buzzopia',
|
|
||||||
birthday: '1982-01-23T12:00:00.000Z',
|
|
||||||
address: '614 Herkimer Court, Darrtown, Nebraska, PO9308',
|
|
||||||
},
|
|
||||||
attachments: _attachments,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '9d3f0e7f-dcbd-4e56-a5e8-87b8154e9edf',
|
|
||||||
avatar: 'images/avatars/avatar-placeholder.png',
|
|
||||||
name: 'John',
|
|
||||||
about: "Hi there! I'm using AngorChat.",
|
|
||||||
details: {
|
|
||||||
emails: [
|
|
||||||
{
|
|
||||||
email: 'bernardlangley@mail.com',
|
|
||||||
label: 'Personal',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
email: 'langley.bernard@boilcat.name',
|
|
||||||
label: 'Work',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
phoneNumbers: [
|
|
||||||
{
|
|
||||||
country: 'md',
|
|
||||||
phoneNumber: '893 548 2862',
|
|
||||||
label: 'Mobile',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
title: 'Electromedical Equipment Technician',
|
|
||||||
company: 'Boilcat',
|
|
||||||
birthday: '1988-05-26T12:00:00.000Z',
|
|
||||||
address: '943 Adler Place, Hamilton, South Dakota, PO5592',
|
|
||||||
},
|
|
||||||
attachments: _attachments,
|
|
||||||
}
|
|
||||||
];
|
|
||||||
export const profile: any = {
|
|
||||||
id: 'cfaad35d-07a3-4447-a6c3-d8c3d54fd5df',
|
|
||||||
name: 'Username',
|
|
||||||
email: 'username@angor.io',
|
|
||||||
avatar: 'images/avatars/avatar-placeholder.png',
|
|
||||||
about: "Hi there! I'm using AngorChat.",
|
|
||||||
};
|
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { AngorMockApiService, AngorMockApiUtils } from '@angor/lib/mock-api';
|
|
||||||
import { notifications as notificationsData } from 'app/mock-api/common/notifications/data';
|
|
||||||
import { assign, cloneDeep } from 'lodash-es';
|
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
|
||||||
export class NotificationsMockApi {
|
|
||||||
private _notifications: any = notificationsData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
constructor(private _angorMockApiService: AngorMockApiService) {
|
|
||||||
// Register Mock API handlers
|
|
||||||
this.registerHandlers();
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Public methods
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register Mock API handlers
|
|
||||||
*/
|
|
||||||
registerHandlers(): void {
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Notifications - GET
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
this._angorMockApiService
|
|
||||||
.onGet('api/common/notifications')
|
|
||||||
.reply(() => [200, cloneDeep(this._notifications)]);
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Notifications - POST
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
this._angorMockApiService
|
|
||||||
.onPost('api/common/notifications')
|
|
||||||
.reply(({ request }) => {
|
|
||||||
// Get the notification
|
|
||||||
const newNotification = cloneDeep(request.body.notification);
|
|
||||||
|
|
||||||
// Generate a new GUID
|
|
||||||
newNotification.id = AngorMockApiUtils.guid();
|
|
||||||
|
|
||||||
// Unshift the new notification
|
|
||||||
this._notifications.unshift(newNotification);
|
|
||||||
|
|
||||||
// Return the response
|
|
||||||
return [200, newNotification];
|
|
||||||
});
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Notifications - PATCH
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
this._angorMockApiService
|
|
||||||
.onPatch('api/common/notifications')
|
|
||||||
.reply(({ request }) => {
|
|
||||||
// Get the id and notification
|
|
||||||
const id = request.body.id;
|
|
||||||
const notification = cloneDeep(request.body.notification);
|
|
||||||
|
|
||||||
// Prepare the updated notification
|
|
||||||
let updatedNotification = null;
|
|
||||||
|
|
||||||
// Find the notification and update it
|
|
||||||
this._notifications.forEach(
|
|
||||||
(item: any, index: number, notifications: any[]) => {
|
|
||||||
if (item.id === id) {
|
|
||||||
// Update the notification
|
|
||||||
notifications[index] = assign(
|
|
||||||
{},
|
|
||||||
notifications[index],
|
|
||||||
notification
|
|
||||||
);
|
|
||||||
|
|
||||||
// Store the updated notification
|
|
||||||
updatedNotification = notifications[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Return the response
|
|
||||||
return [200, updatedNotification];
|
|
||||||
});
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Notifications - DELETE
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
this._angorMockApiService
|
|
||||||
.onDelete('api/common/notifications')
|
|
||||||
.reply(({ request }) => {
|
|
||||||
// Get the id
|
|
||||||
const id = request.params.get('id');
|
|
||||||
|
|
||||||
// Prepare the deleted notification
|
|
||||||
let deletedNotification = null;
|
|
||||||
|
|
||||||
// Find the notification
|
|
||||||
const index = this._notifications.findIndex(
|
|
||||||
(item: any) => item.id === id
|
|
||||||
);
|
|
||||||
|
|
||||||
// Store the deleted notification
|
|
||||||
deletedNotification = cloneDeep(this._notifications[index]);
|
|
||||||
|
|
||||||
// Delete the notification
|
|
||||||
this._notifications.splice(index, 1);
|
|
||||||
|
|
||||||
// Return the response
|
|
||||||
return [200, deletedNotification];
|
|
||||||
});
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Mark all as read - GET
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
this._angorMockApiService
|
|
||||||
.onGet('api/common/notifications/mark-all-as-read')
|
|
||||||
.reply(() => {
|
|
||||||
// Go through all notifications
|
|
||||||
this._notifications.forEach(
|
|
||||||
(item: any, index: number, notifications: any[]) => {
|
|
||||||
// Mark it as read
|
|
||||||
notifications[index].read = true;
|
|
||||||
notifications[index].seen = true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Return the response
|
|
||||||
return [200, true];
|
|
||||||
});
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
// @ Toggle read status - POST
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
this._angorMockApiService
|
|
||||||
.onPost('api/common/notifications/toggle-read-status')
|
|
||||||
.reply(({ request }) => {
|
|
||||||
// Get the notification
|
|
||||||
const notification = cloneDeep(request.body.notification);
|
|
||||||
|
|
||||||
// Prepare the updated notification
|
|
||||||
let updatedNotification = null;
|
|
||||||
|
|
||||||
// Find the notification and update it
|
|
||||||
this._notifications.forEach(
|
|
||||||
(item: any, index: number, notifications: any[]) => {
|
|
||||||
if (item.id === notification.id) {
|
|
||||||
// Update the notification
|
|
||||||
notifications[index].read = notification.read;
|
|
||||||
|
|
||||||
// Store the updated notification
|
|
||||||
updatedNotification = notifications[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Return the response
|
|
||||||
return [200, updatedNotification];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
import { DateTime } from 'luxon';
|
|
||||||
|
|
||||||
/* Retrieve the current date and time */
|
|
||||||
const currentMoment = DateTime.now();
|
|
||||||
|
|
||||||
export const notifications = [
|
|
||||||
{
|
|
||||||
id: '493190c9-5b61-4912-afe5-78c21f1044d7',
|
|
||||||
icon: 'heroicons_mini:star',
|
|
||||||
title: 'Daily Challenges',
|
|
||||||
description: 'Your submission has been approved',
|
|
||||||
time: currentMoment.minus({ minute: 25 }).toISO(), // 25 minutes ago
|
|
||||||
read: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '6e3e97e5-effc-4fb7-b730-52a151f0b641',
|
|
||||||
image: 'images/avatars/avatar-placeholder.png',
|
|
||||||
description:
|
|
||||||
'<strong>Leo Gill</strong> has added you to the <em>Top Secret Project</em> group and assigned you as the <em>Project Manager</em>',
|
|
||||||
time: currentMoment.minus({ minute: 50 }).toISO(), // 50 minutes ago
|
|
||||||
read: true,
|
|
||||||
link: '/dashboards/project',
|
|
||||||
useRouter: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'b91ccb58-b06c-413b-b389-87010e03a120',
|
|
||||||
icon: 'heroicons_mini:envelope',
|
|
||||||
title: 'Mailbox',
|
|
||||||
description: 'You have 15 unread emails across 3 mailboxes',
|
|
||||||
time: currentMoment.minus({ hour: 3 }).toISO(), // 3 hours ago
|
|
||||||
read: false,
|
|
||||||
link: '/dashboards/project',
|
|
||||||
useRouter: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '541416c9-84a7-408a-8d74-27a43c38d797',
|
|
||||||
icon: 'heroicons_mini:arrow-path',
|
|
||||||
title: 'Cron Jobs',
|
|
||||||
description: 'Your <em>Docker container</em> is ready for publishing',
|
|
||||||
time: currentMoment.minus({ hour: 5 }).toISO(), // 5 hours ago
|
|
||||||
read: false,
|
|
||||||
link: '/dashboards/project',
|
|
||||||
useRouter: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'ef7b95a7-8e8b-4616-9619-130d9533add9',
|
|
||||||
image: 'images/avatars/avatar-placeholder.png',
|
|
||||||
description:
|
|
||||||
'<strong>Roger Murray</strong> has accepted your friend request',
|
|
||||||
time: currentMoment.minus({ hour: 7 }).toISO(), // 7 hours ago
|
|
||||||
read: true,
|
|
||||||
link: '/dashboards/project',
|
|
||||||
useRouter: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'eb8aa470-635e-461d-88e1-23d9ea2a5665',
|
|
||||||
image: 'images/avatars/avatar-placeholder.png',
|
|
||||||
description: '<strong>Sophie Stone</strong> sent you a direct message',
|
|
||||||
time: currentMoment.minus({ hour: 9 }).toISO(), // 9 hours ago
|
|
||||||
read: true,
|
|
||||||
link: '/dashboards/project',
|
|
||||||
useRouter: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'b85c2338-cc98-4140-bbf8-c226ce4e395e',
|
|
||||||
icon: 'heroicons_mini:envelope',
|
|
||||||
title: 'Mailbox',
|
|
||||||
description: 'You have 3 new unread emails',
|
|
||||||
time: currentMoment.minus({ day: 1 }).toISO(), // 1 day ago
|
|
||||||
read: true,
|
|
||||||
link: '/dashboards/project',
|
|
||||||
useRouter: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '8f8e1bf9-4661-4939-9e43-390957b60f42',
|
|
||||||
icon: 'heroicons_mini:star',
|
|
||||||
title: 'Daily Challenges',
|
|
||||||
description:
|
|
||||||
'Your submission has been accepted, and you can now sign up for the final assignment, which will be available in 2 days',
|
|
||||||
time: currentMoment.minus({ day: 3 }).toISO(), // 3 days ago
|
|
||||||
read: true,
|
|
||||||
link: '/dashboards/project',
|
|
||||||
useRouter: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '30af917b-7a6a-45d1-822f-9e7ad7f8bf69',
|
|
||||||
icon: 'heroicons_mini:arrow-path',
|
|
||||||
title: 'Cron Jobs',
|
|
||||||
description: 'Your Vagrant container is ready for download',
|
|
||||||
time: currentMoment.minus({ day: 4 }).toISO(), // 4 days ago
|
|
||||||
read: true,
|
|
||||||
link: '/dashboards/project',
|
|
||||||
useRouter: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { ChatMockApi } from 'app/mock-api/apps/chat/api';
|
|
||||||
import { NavigationMockApi } from 'app/mock-api/common/navigation/api';
|
|
||||||
import { NotificationsMockApi } from 'app/mock-api/common/notifications/api';
|
|
||||||
|
|
||||||
|
|
||||||
export const mockApiServices = [
|
|
||||||
ChatMockApi,
|
|
||||||
NavigationMockApi,
|
|
||||||
NotificationsMockApi,
|
|
||||||
|
|
||||||
];
|
|
||||||
@@ -57,7 +57,12 @@ export class NotificationService {
|
|||||||
return this.notificationCount.asObservable();
|
return this.notificationCount.asObservable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async subscribeToNotifications(pubkey: string): Promise<void> {
|
private loadFilterPreferences(): number[] {
|
||||||
|
const storedPreferences = localStorage.getItem('notificationSettings');
|
||||||
|
return storedPreferences ? JSON.parse(storedPreferences) : [1, 3, 4, 9735]; // Default to all kinds if not set
|
||||||
|
}
|
||||||
|
|
||||||
|
public async subscribeToNotifications(pubkey: string): Promise<void> {
|
||||||
await this.relayService.ensureConnectedRelays();
|
await this.relayService.ensureConnectedRelays();
|
||||||
const pool = this.relayService.getPool();
|
const pool = this.relayService.getPool();
|
||||||
const connectedRelays = this.relayService.getConnectedRelays();
|
const connectedRelays = this.relayService.getConnectedRelays();
|
||||||
@@ -66,9 +71,14 @@ export class NotificationService {
|
|||||||
throw new Error('No connected relays');
|
throw new Error('No connected relays');
|
||||||
}
|
}
|
||||||
const lastNotificationTimestamp = this.loadTimestampFromLocalStorage();
|
const lastNotificationTimestamp = this.loadTimestampFromLocalStorage();
|
||||||
|
const filterPreferences = this.loadFilterPreferences();
|
||||||
|
|
||||||
|
if (filterPreferences.length === 0) {
|
||||||
|
filterPreferences.push(1, 3, 4, 9735);
|
||||||
|
}
|
||||||
|
|
||||||
const filter: Filter = {
|
const filter: Filter = {
|
||||||
kinds: [1, 3, 4, 9735],
|
kinds: filterPreferences,
|
||||||
'#p': [pubkey],
|
'#p': [pubkey],
|
||||||
limit: 50,
|
limit: 50,
|
||||||
since: lastNotificationTimestamp || undefined
|
since: lastNotificationTimestamp || undefined
|
||||||
|
|||||||
Reference in New Issue
Block a user