Skip to content

Commit

Permalink
add "send Push to user" feature
Browse files Browse the repository at this point in the history
  • Loading branch information
AnSch1510 committed Jul 3, 2024
1 parent 2c4a761 commit 63336c4
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,14 @@ <h1 class="m-0">{{ translations.nav_settings() }}</h1>
<div class="relative -my-4 p-0">
<p-button
class="items-center"
[label]="translations.settings_notifications_testNotification_buttonText()"
[label]="translations.shared_send()"
icon="i-[mdi--send]"
size="small"
[severity]="'primary'"
(onClick)="sendTestNotification()"
/>
<app-saved-fading-message [showTrigger]="settingsSaveStates.testSend | async">{{
translations.settings_notifications_testNotification_successText()
translations.shared_sent()
}}</app-saved-fading-message>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,12 @@ export class UserSettingsComponent {

protected async sendTestNotification() {
this.sendPush.set(false);
const response = await this._notificationService.sendNotification({ body: {} });
const response = await this._notificationService.sendNotification({
body: {
title: this.translations.users_notificationDialog_titleDefault(),
body: this.translations.users_notificationDialog_bodyDefault(),
},
});
if (response.ok) {
this.sendPush.set(true);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<p-dialog
[header]="translations.users_notificationDialog_dialogTitle()"
[visible]="visible()"
(visibleChange)="visible.set($event)"
[modal]="true"
[draggable]="false"
[resizable]="false"
styleClass="min-w-[80vw]"
>
<div class="flex flex-col gap-4" [formGroup]="form">
<div>
{{ translations.users_notificationDialog_sendTo() | interpolate: user() }}
</div>

<span class="p-float-label">
<input
pInputText
[id]="id('title')"
type="text"
formControlName="title"
autocomplete="off"
pAutoFocus
[autofocus]="true"
[placeholder]="translations.users_notificationDialog_titleDefault()"
/>
<label [htmlFor]="id('title')">{{ translations.users_notificationDialog_title() }}</label>
</span>

<span class="p-float-label">
<textarea
pInputTextarea
[id]="id('body')"
formControlName="body"
autocomplete="off"
[placeholder]="translations.users_notificationDialog_bodyDefault()"
></textarea>
<label [htmlFor]="id('body')">{{ translations.users_notificationDialog_body() }}</label>
</span>
</div>
<ng-template pTemplate="footer">
<p-button
[disabled]="isLoading()"
[text]="true"
label="{{ translations.shared_cancel() }}"
(onClick)="close()"
/>
<p-button
[disabled]="isLoading()"
label="{{ translations.shared_send() }}"
(onClick)="submit()"
/>
</ng-template>
</p-dialog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import { AutoFocusModule } from 'primeng/autofocus';
import { ButtonModule } from 'primeng/button';
import { DialogModule } from 'primeng/dialog';
import { InputTextModule } from 'primeng/inputtext';
import { InputTextareaModule } from 'primeng/inputtextarea';

import { NotificationsService } from '../../../api/services';
import { InterpolatePipe } from '../../../directives/interpolate.pipe';
import { User } from '../../../models/parsed-models';
import { TranslateService } from '../../../services/translate.service';

@Component({
selector: 'app-user-push-dialog',
standalone: true,
imports: [
AutoFocusModule,
ButtonModule,
CommonModule,
DialogModule,
InputTextModule,
InputTextareaModule,
InterpolatePipe,
ReactiveFormsModule,
],
templateUrl: './user-push-dialog.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class UserPushDialogComponent {
protected readonly translations = inject(TranslateService).translations;
private readonly _randomId = Math.random().toString(36).substring(2, 9);

private readonly _formBuilder = inject(FormBuilder);
private readonly _notificationsService = inject(NotificationsService);

protected readonly visible = signal(false);
protected readonly isLoading = signal(false);
protected readonly user = signal<User | undefined>(undefined);
protected readonly form = this._formBuilder.group({
title: this._formBuilder.control(''),
body: this._formBuilder.control(''),
});

public open(user: User): void {
this.user.set(user);
this.visible.set(true);
}

public close(): void {
this.visible.set(false);
}

protected async submit() {
if (!this.form.valid) {
this.form.markAllAsTouched();
return;
}

const user = this.user();
if (!user) return;

this.isLoading.set(true);
try {
await this._notificationsService.sendNotification({
body: {
userId: user.id,
title: this.form.value.title || this.translations.users_notificationDialog_titleDefault(),
body: this.form.value.body || this.translations.users_notificationDialog_bodyDefault(),
},
});
this.close();
} finally {
this.isLoading.set(false);
}
}

protected id(purpose: string) {
return `${purpose}-${this._randomId}`;
}
}
9 changes: 8 additions & 1 deletion src/client/src/app/components/users/users.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@
>
<app-user-item [user]="user" class="min-w-0 grow" />
@if (user.hasPushSubscription) {
<span class="i-[mdi--bell] mr-2"></span>
<p-button
icon="i-[mdi--bell]"
[rounded]="true"
[text]="true"
size="small"
(onClick)="pushDialog.open(user)"
/>
}
<p-button
icon="i-[mdi--pencil-outline]"
Expand Down Expand Up @@ -79,3 +85,4 @@
}

<app-user-dialog #dialog />
<app-user-push-dialog #pushDialog />
2 changes: 2 additions & 0 deletions src/client/src/app/components/users/users.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ProgressSpinnerModule } from 'primeng/progressspinner';

import { UserDialogComponent } from './user-dialog/user-dialog.component';
import { UserItemComponent } from './user-item/user-item.component';
import { UserPushDialogComponent } from './user-push-dialog/user-push-dialog.component';
import { isActionBusy, hasActionFailed } from '../../+state/action-state';
import {
keepUsersLoaded,
Expand Down Expand Up @@ -37,6 +38,7 @@ function userMatchesFilter(map: User | undefined, lowerCaseFilter: string): map
InputTextModule,
MessagesModule,
UserDialogComponent,
UserPushDialogComponent,
UserItemComponent,
ProgressSpinnerModule,
],
Expand Down
16 changes: 12 additions & 4 deletions src/client/src/app/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@
"enabledOnAllDevices": "Auf allen Geräten aktiviert",
"eanbled": "Auf diesem Gerät aktiviert",
"testNotification": {
"text": "Testbenachrichtigung",
"buttonText": "Senden",
"successText": "Gesendet"
"text": "Testbenachrichtigung"
},
"errors": {
"notSupported": "Benachrichtigungen werden von diesem Browser nicht unterstützt. Gegenebenfalls muss die Webseite auf dem Home-Bildschirm installiert werden.",
Expand Down Expand Up @@ -199,6 +197,14 @@
},
"error": {
"load": "Fehler beim Laden der Benutzer."
},
"notificationDialog": {
"dialogTitle": "Spieler Benachrichtigen",
"sendTo": "senden an \"{{alias}}\"",
"title": "Titel",
"titleDefault": "Testbenachrichtigung",
"body": "Inhalt",
"bodyDefault": "Benachrichtigungen funktionieren!!! Wohoo ⛳"
}
},
"playerEvents": {
Expand Down Expand Up @@ -252,7 +258,9 @@
"commit": "Freigeben",
"minute": "Minute",
"minutes": "Minuten",
"none": "Keine"
"none": "Keine",
"send": "Senden",
"sent": "Gesendet"
},
"validation": {
"required": "Darf nicht leer sein.",
Expand Down
16 changes: 12 additions & 4 deletions src/client/src/app/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@
"enabledOnAllDevices": "Enabled on all devices",
"eanbled": "Enabled on this device",
"testNotification": {
"text": "Test notification",
"buttonText": "Send",
"successText": "Sent"
"text": "Test notification"
},
"errors": {
"notSupported": "Notifications are not supported by this browser. Probably this website needs to be installed onto the homescreen.",
Expand Down Expand Up @@ -199,6 +197,14 @@
},
"error": {
"load": "Failed to load users."
},
"notificationDialog": {
"dialogTitle": "Notify player",
"sendTo": "senden an \"{{alias}}\"",
"title": "title",
"titleDefault": "test notification",
"body": "body",
"bodyDefault": "Notifications are working!!! Wohoo ⛳"
}
},
"playerEvents": {
Expand Down Expand Up @@ -252,7 +258,9 @@
"commit": "Commit",
"minute": "Minute",
"minutes": "Minutes",
"none": "None"
"none": "None",
"send": "send",
"sent": "sent"
},
"validation": {
"required": "Cannot be blank.",
Expand Down
10 changes: 9 additions & 1 deletion src/client/src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,21 @@
@apply px-3;
}

input::placeholder,
textarea::placeholder {
opacity: 1;
}

input:focus,
input.p-filled,
textarea:focus,
textarea.p-filled,
.p-inputwrapper-focus,
.p-inputwrapper-filled {
.p-inputwrapper-filled,
input[placeholder],
textarea[placeholder] {
~ label {
font-size: 0.75rem;
top: 2px;
padding: 0 4px;
left: 8px;
Expand Down

0 comments on commit 63336c4

Please sign in to comment.