mirror of
https://github.com/Cleanuparr/Cleanuparr.git
synced 2026-05-14 17:54:15 -04:00
Add Discord notification provider (#417)
This commit is contained in:
@@ -152,6 +152,11 @@ export class DocumentationService {
|
||||
'telegram.topicId': 'topic-id',
|
||||
'telegram.sendSilently': 'send-silently'
|
||||
},
|
||||
'notifications/discord': {
|
||||
'discord.webhookUrl': 'webhook-url',
|
||||
'discord.username': 'username',
|
||||
'discord.avatarUrl': 'avatar-url'
|
||||
},
|
||||
};
|
||||
|
||||
constructor(private applicationPathService: ApplicationPathService) {}
|
||||
|
||||
@@ -230,6 +230,40 @@ export interface TestTelegramProviderRequest {
|
||||
sendSilently: boolean;
|
||||
}
|
||||
|
||||
export interface CreateDiscordProviderRequest {
|
||||
name: string;
|
||||
isEnabled: boolean;
|
||||
onFailedImportStrike: boolean;
|
||||
onStalledStrike: boolean;
|
||||
onSlowStrike: boolean;
|
||||
onQueueItemDeleted: boolean;
|
||||
onDownloadCleaned: boolean;
|
||||
onCategoryChanged: boolean;
|
||||
webhookUrl: string;
|
||||
username: string;
|
||||
avatarUrl: string;
|
||||
}
|
||||
|
||||
export interface UpdateDiscordProviderRequest {
|
||||
name: string;
|
||||
isEnabled: boolean;
|
||||
onFailedImportStrike: boolean;
|
||||
onStalledStrike: boolean;
|
||||
onSlowStrike: boolean;
|
||||
onQueueItemDeleted: boolean;
|
||||
onDownloadCleaned: boolean;
|
||||
onCategoryChanged: boolean;
|
||||
webhookUrl: string;
|
||||
username: string;
|
||||
avatarUrl: string;
|
||||
}
|
||||
|
||||
export interface TestDiscordProviderRequest {
|
||||
webhookUrl: string;
|
||||
username: string;
|
||||
avatarUrl: string;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
@@ -287,6 +321,13 @@ export class NotificationProviderService {
|
||||
return this.http.post<NotificationProviderDto>(`${this.baseUrl}/telegram`, provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Discord provider
|
||||
*/
|
||||
createDiscordProvider(provider: CreateDiscordProviderRequest): Observable<NotificationProviderDto> {
|
||||
return this.http.post<NotificationProviderDto>(`${this.baseUrl}/discord`, provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing Notifiarr provider
|
||||
*/
|
||||
@@ -322,6 +363,13 @@ export class NotificationProviderService {
|
||||
return this.http.put<NotificationProviderDto>(`${this.baseUrl}/telegram/${id}`, provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing Discord provider
|
||||
*/
|
||||
updateDiscordProvider(id: string, provider: UpdateDiscordProviderRequest): Observable<NotificationProviderDto> {
|
||||
return this.http.put<NotificationProviderDto>(`${this.baseUrl}/discord/${id}`, provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a notification provider
|
||||
*/
|
||||
@@ -364,6 +412,13 @@ export class NotificationProviderService {
|
||||
return this.http.post<TestNotificationResult>(`${this.baseUrl}/telegram/test`, testRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a Discord provider (without ID - for testing configuration before saving)
|
||||
*/
|
||||
testDiscordProvider(testRequest: TestDiscordProviderRequest): Observable<TestNotificationResult> {
|
||||
return this.http.post<TestNotificationResult>(`${this.baseUrl}/discord/test`, testRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic create method that delegates to provider-specific methods
|
||||
*/
|
||||
@@ -379,6 +434,8 @@ export class NotificationProviderService {
|
||||
return this.createPushoverProvider(provider as CreatePushoverProviderRequest);
|
||||
case NotificationProviderType.Telegram:
|
||||
return this.createTelegramProvider(provider as CreateTelegramProviderRequest);
|
||||
case NotificationProviderType.Discord:
|
||||
return this.createDiscordProvider(provider as CreateDiscordProviderRequest);
|
||||
default:
|
||||
throw new Error(`Unsupported provider type: ${type}`);
|
||||
}
|
||||
@@ -399,6 +456,8 @@ export class NotificationProviderService {
|
||||
return this.updatePushoverProvider(id, provider as UpdatePushoverProviderRequest);
|
||||
case NotificationProviderType.Telegram:
|
||||
return this.updateTelegramProvider(id, provider as UpdateTelegramProviderRequest);
|
||||
case NotificationProviderType.Discord:
|
||||
return this.updateDiscordProvider(id, provider as UpdateDiscordProviderRequest);
|
||||
default:
|
||||
throw new Error(`Unsupported provider type: ${type}`);
|
||||
}
|
||||
@@ -419,6 +478,8 @@ export class NotificationProviderService {
|
||||
return this.testPushoverProvider(testRequest as TestPushoverProviderRequest);
|
||||
case NotificationProviderType.Telegram:
|
||||
return this.testTelegramProvider(testRequest as TestTelegramProviderRequest);
|
||||
case NotificationProviderType.Discord:
|
||||
return this.testDiscordProvider(testRequest as TestDiscordProviderRequest);
|
||||
default:
|
||||
throw new Error(`Unsupported provider type: ${type}`);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<app-notification-provider-base
|
||||
[visible]="visible"
|
||||
modalTitle="Configure Discord Provider"
|
||||
[saving]="saving"
|
||||
[testing]="testing"
|
||||
[editingProvider]="editingProvider"
|
||||
(save)="onSave($event)"
|
||||
(cancel)="onCancel()"
|
||||
(test)="onTest($event)">
|
||||
|
||||
<!-- Provider-specific configuration goes here -->
|
||||
<div slot="provider-config">
|
||||
<!-- Webhook URL Field -->
|
||||
<div class="field">
|
||||
<label for="webhook-url">
|
||||
<i class="pi pi-question-circle field-info-icon"
|
||||
title="Click for documentation"
|
||||
(click)="openFieldDocs('discord.webhookUrl')"></i>
|
||||
Webhook URL *
|
||||
</label>
|
||||
<input
|
||||
id="webhook-url"
|
||||
type="password"
|
||||
pInputText
|
||||
[formControl]="webhookUrlControl"
|
||||
placeholder="https://discord.com/api/webhooks/..."
|
||||
class="w-full" />
|
||||
<small *ngIf="hasFieldError(webhookUrlControl, 'required')" class="form-error-text">Webhook URL is required</small>
|
||||
<small *ngIf="hasFieldError(webhookUrlControl, 'pattern')" class="form-error-text">Must be a valid Discord webhook URL</small>
|
||||
<small class="form-helper-text">Your Discord webhook URL. Create one in your Discord server's channel settings under Integrations.</small>
|
||||
</div>
|
||||
|
||||
<!-- Username Field (Optional) -->
|
||||
<div class="field">
|
||||
<label for="username">
|
||||
<i class="pi pi-question-circle field-info-icon"
|
||||
title="Click for documentation"
|
||||
(click)="openFieldDocs('discord.username')"></i>
|
||||
Username (Optional)
|
||||
</label>
|
||||
<input
|
||||
id="username"
|
||||
type="text"
|
||||
pInputText
|
||||
[formControl]="usernameControl"
|
||||
placeholder="Cleanuparr"
|
||||
class="w-full" />
|
||||
<small *ngIf="hasFieldError(usernameControl, 'maxlength')" class="form-error-text">Username cannot exceed 80 characters</small>
|
||||
<small class="form-helper-text">Override the default webhook username. Leave empty to use the webhook's default name.</small>
|
||||
</div>
|
||||
|
||||
<!-- Avatar URL Field (Optional) -->
|
||||
<div class="field">
|
||||
<label for="avatar-url">
|
||||
<i class="pi pi-question-circle field-info-icon"
|
||||
title="Click for documentation"
|
||||
(click)="openFieldDocs('discord.avatarUrl')"></i>
|
||||
Avatar URL (Optional)
|
||||
</label>
|
||||
<input
|
||||
id="avatar-url"
|
||||
type="text"
|
||||
pInputText
|
||||
[formControl]="avatarUrlControl"
|
||||
placeholder="https://example.com/avatar.png"
|
||||
class="w-full" />
|
||||
<small *ngIf="hasFieldError(avatarUrlControl, 'pattern')" class="form-error-text">Must be a valid URL</small>
|
||||
<small class="form-helper-text">Override the default webhook avatar. Leave empty to use the webhook's default avatar.</small>
|
||||
</div>
|
||||
</div>
|
||||
</app-notification-provider-base>
|
||||
@@ -0,0 +1 @@
|
||||
@use '../../../styles/settings-shared.scss';
|
||||
@@ -0,0 +1,117 @@
|
||||
import { Component, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges, inject } from '@angular/core';
|
||||
import { FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { InputTextModule } from 'primeng/inputtext';
|
||||
import { DiscordFormData, BaseProviderFormData } from '../../models/provider-modal.model';
|
||||
import { DocumentationService } from '../../../../core/services/documentation.service';
|
||||
import { NotificationProviderDto } from '../../../../shared/models/notification-provider.model';
|
||||
import { NotificationProviderBaseComponent } from '../base/notification-provider-base.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-discord-provider',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
ReactiveFormsModule,
|
||||
InputTextModule,
|
||||
NotificationProviderBaseComponent
|
||||
],
|
||||
templateUrl: './discord-provider.component.html',
|
||||
styleUrls: ['./discord-provider.component.scss']
|
||||
})
|
||||
export class DiscordProviderComponent implements OnInit, OnChanges {
|
||||
@Input() visible = false;
|
||||
@Input() editingProvider: NotificationProviderDto | null = null;
|
||||
@Input() saving = false;
|
||||
@Input() testing = false;
|
||||
|
||||
@Output() save = new EventEmitter<DiscordFormData>();
|
||||
@Output() cancel = new EventEmitter<void>();
|
||||
@Output() test = new EventEmitter<DiscordFormData>();
|
||||
|
||||
// Provider-specific form controls
|
||||
webhookUrlControl = new FormControl('', [Validators.required, Validators.pattern(/^https:\/\/(discord\.com|discordapp\.com)\/api\/webhooks\/.+/)]);
|
||||
usernameControl = new FormControl('', [Validators.maxLength(80)]);
|
||||
avatarUrlControl = new FormControl('', [Validators.pattern(/^(https?:\/\/.+)?$/)]);
|
||||
|
||||
private documentationService = inject(DocumentationService);
|
||||
|
||||
/** Exposed for template to open documentation for discord fields */
|
||||
openFieldDocs(fieldName: string): void {
|
||||
this.documentationService.openFieldDocumentation('notifications/discord', fieldName);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
// Initialize component but don't populate yet - wait for ngOnChanges
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
// Populate provider-specific fields when editingProvider input changes
|
||||
if (changes['editingProvider']) {
|
||||
if (this.editingProvider) {
|
||||
this.populateProviderFields();
|
||||
} else {
|
||||
// Reset fields when editingProvider is cleared
|
||||
this.resetProviderFields();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private populateProviderFields(): void {
|
||||
if (this.editingProvider) {
|
||||
const config = this.editingProvider.configuration as any;
|
||||
|
||||
this.webhookUrlControl.setValue(config?.webhookUrl || '');
|
||||
this.usernameControl.setValue(config?.username || '');
|
||||
this.avatarUrlControl.setValue(config?.avatarUrl || '');
|
||||
}
|
||||
}
|
||||
|
||||
private resetProviderFields(): void {
|
||||
this.webhookUrlControl.setValue('');
|
||||
this.usernameControl.setValue('');
|
||||
this.avatarUrlControl.setValue('https://github.com/Cleanuparr/Cleanuparr/blob/main/Logo/48.png?raw=true');
|
||||
}
|
||||
|
||||
protected hasFieldError(control: FormControl, errorType: string): boolean {
|
||||
return !!(control && control.errors?.[errorType] && (control.dirty || control.touched));
|
||||
}
|
||||
|
||||
onSave(baseData: BaseProviderFormData): void {
|
||||
if (this.webhookUrlControl.valid && this.usernameControl.valid && this.avatarUrlControl.valid) {
|
||||
const discordData: DiscordFormData = {
|
||||
...baseData,
|
||||
webhookUrl: this.webhookUrlControl.value || '',
|
||||
username: this.usernameControl.value || '',
|
||||
avatarUrl: this.avatarUrlControl.value || ''
|
||||
};
|
||||
this.save.emit(discordData);
|
||||
} else {
|
||||
// Mark provider-specific fields as touched to show validation errors
|
||||
this.webhookUrlControl.markAsTouched();
|
||||
this.usernameControl.markAsTouched();
|
||||
this.avatarUrlControl.markAsTouched();
|
||||
}
|
||||
}
|
||||
|
||||
onCancel(): void {
|
||||
this.cancel.emit();
|
||||
}
|
||||
|
||||
onTest(baseData: BaseProviderFormData): void {
|
||||
if (this.webhookUrlControl.valid && this.usernameControl.valid && this.avatarUrlControl.valid) {
|
||||
const discordData: DiscordFormData = {
|
||||
...baseData,
|
||||
webhookUrl: this.webhookUrlControl.value || '',
|
||||
username: this.usernameControl.value || '',
|
||||
avatarUrl: this.avatarUrlControl.value || ''
|
||||
};
|
||||
this.test.emit(discordData);
|
||||
} else {
|
||||
// Mark provider-specific fields as touched to show validation errors
|
||||
this.webhookUrlControl.markAsTouched();
|
||||
this.usernameControl.markAsTouched();
|
||||
this.avatarUrlControl.markAsTouched();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,8 +57,15 @@ export class ProviderTypeSelectionComponent {
|
||||
iconUrl: 'icons/ext/telegram-light.svg',
|
||||
iconUrlHover: 'icons/ext/telegram.svg',
|
||||
description: 'https://core.telegram.org/bots'
|
||||
}
|
||||
];
|
||||
},
|
||||
{
|
||||
type: NotificationProviderType.Discord,
|
||||
name: 'Discord',
|
||||
iconUrl: 'icons/ext/discord-light.svg',
|
||||
iconUrlHover: 'icons/ext/discord.svg',
|
||||
description: 'https://discord.com'
|
||||
},
|
||||
].sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
selectProvider(type: NotificationProviderType) {
|
||||
this.providerSelected.emit(type);
|
||||
|
||||
@@ -72,6 +72,12 @@ export interface TelegramFormData extends BaseProviderFormData {
|
||||
sendSilently: boolean;
|
||||
}
|
||||
|
||||
export interface DiscordFormData extends BaseProviderFormData {
|
||||
webhookUrl: string;
|
||||
username: string;
|
||||
avatarUrl: string;
|
||||
}
|
||||
|
||||
// Events for modal communication
|
||||
export interface ProviderModalEvents {
|
||||
save: (data: any) => void;
|
||||
|
||||
@@ -135,7 +135,6 @@
|
||||
<h3>Provider Type Not Yet Supported</h3>
|
||||
<p class="text-color-secondary">
|
||||
This provider type is not yet supported by the new modal system.
|
||||
<br>Please select Notifiarr or Apprise for now.
|
||||
</p>
|
||||
<button
|
||||
pButton
|
||||
@@ -209,6 +208,17 @@
|
||||
(test)="onTelegramTest($event)"
|
||||
></app-telegram-provider>
|
||||
|
||||
<!-- Discord Provider Modal -->
|
||||
<app-discord-provider
|
||||
[visible]="showDiscordModal"
|
||||
[editingProvider]="editingProvider"
|
||||
[saving]="saving()"
|
||||
[testing]="testing()"
|
||||
(save)="onDiscordSave($event)"
|
||||
(cancel)="onProviderCancel()"
|
||||
(test)="onDiscordTest($event)"
|
||||
></app-discord-provider>
|
||||
|
||||
<!-- Confirmation Dialog -->
|
||||
<p-confirmDialog></p-confirmDialog>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
} from "../../shared/models/notification-provider.model";
|
||||
import { NotificationProviderType } from "../../shared/models/enums";
|
||||
import { DocumentationService } from "../../core/services/documentation.service";
|
||||
import { NotifiarrFormData, AppriseFormData, NtfyFormData, PushoverFormData, TelegramFormData } from "./models/provider-modal.model";
|
||||
import { NotifiarrFormData, AppriseFormData, NtfyFormData, PushoverFormData, TelegramFormData, DiscordFormData } from "./models/provider-modal.model";
|
||||
import { LoadingErrorStateComponent } from "../../shared/components/loading-error-state/loading-error-state.component";
|
||||
|
||||
// New modal components
|
||||
@@ -18,6 +18,7 @@ import { AppriseProviderComponent } from "./modals/apprise-provider/apprise-prov
|
||||
import { NtfyProviderComponent } from "./modals/ntfy-provider/ntfy-provider.component";
|
||||
import { PushoverProviderComponent } from "./modals/pushover-provider/pushover-provider.component";
|
||||
import { TelegramProviderComponent } from "./modals/telegram-provider/telegram-provider.component";
|
||||
import { DiscordProviderComponent } from "./modals/discord-provider/discord-provider.component";
|
||||
|
||||
// PrimeNG Components
|
||||
import { CardModule } from "primeng/card";
|
||||
@@ -55,6 +56,7 @@ import { NotificationService } from "../../core/services/notification.service";
|
||||
NtfyProviderComponent,
|
||||
PushoverProviderComponent,
|
||||
TelegramProviderComponent,
|
||||
DiscordProviderComponent,
|
||||
],
|
||||
providers: [NotificationProviderConfigStore, ConfirmationService, MessageService],
|
||||
templateUrl: "./notification-settings.component.html",
|
||||
@@ -66,12 +68,13 @@ export class NotificationSettingsComponent implements OnDestroy, CanComponentDea
|
||||
|
||||
// Modal state
|
||||
showProviderModal = false; // Legacy modal for unsupported types
|
||||
showTypeSelectionModal = false; // New: Provider type selection modal
|
||||
showNotifiarrModal = false; // New: Notifiarr provider modal
|
||||
showAppriseModal = false; // New: Apprise provider modal
|
||||
showNtfyModal = false; // New: Ntfy provider modal
|
||||
showPushoverModal = false; // New: Pushover provider modal
|
||||
showTelegramModal = false; // New: Telegram provider modal
|
||||
showTypeSelectionModal = false;
|
||||
showNotifiarrModal = false;
|
||||
showAppriseModal = false;
|
||||
showNtfyModal = false;
|
||||
showPushoverModal = false;
|
||||
showTelegramModal = false;
|
||||
showDiscordModal = false;
|
||||
modalMode: 'add' | 'edit' = 'add';
|
||||
editingProvider: NotificationProviderDto | null = null;
|
||||
|
||||
@@ -186,6 +189,9 @@ export class NotificationSettingsComponent implements OnDestroy, CanComponentDea
|
||||
case NotificationProviderType.Telegram:
|
||||
this.showTelegramModal = true;
|
||||
break;
|
||||
case NotificationProviderType.Discord:
|
||||
this.showDiscordModal = true;
|
||||
break;
|
||||
default:
|
||||
// For unsupported types, show the legacy modal with info message
|
||||
this.showProviderModal = true;
|
||||
@@ -242,6 +248,9 @@ export class NotificationSettingsComponent implements OnDestroy, CanComponentDea
|
||||
case NotificationProviderType.Telegram:
|
||||
this.showTelegramModal = true;
|
||||
break;
|
||||
case NotificationProviderType.Discord:
|
||||
this.showDiscordModal = true;
|
||||
break;
|
||||
default:
|
||||
// For unsupported types, show the legacy modal with info message
|
||||
this.showProviderModal = true;
|
||||
@@ -327,6 +336,14 @@ export class NotificationSettingsComponent implements OnDestroy, CanComponentDea
|
||||
sendSilently: telegramConfig.sendSilently || false,
|
||||
};
|
||||
break;
|
||||
case NotificationProviderType.Discord:
|
||||
const discordConfig = provider.configuration as any;
|
||||
testRequest = {
|
||||
webhookUrl: discordConfig.webhookUrl,
|
||||
username: discordConfig.username || "",
|
||||
avatarUrl: discordConfig.avatarUrl || "",
|
||||
};
|
||||
break;
|
||||
default:
|
||||
this.notificationService.showError("Testing not supported for this provider type");
|
||||
return;
|
||||
@@ -369,6 +386,8 @@ export class NotificationSettingsComponent implements OnDestroy, CanComponentDea
|
||||
return "Pushover";
|
||||
case NotificationProviderType.Telegram:
|
||||
return "Telegram";
|
||||
case NotificationProviderType.Discord:
|
||||
return "Discord";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
@@ -537,6 +556,33 @@ export class NotificationSettingsComponent implements OnDestroy, CanComponentDea
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Discord provider save
|
||||
*/
|
||||
onDiscordSave(data: DiscordFormData): void {
|
||||
if (this.modalMode === "edit" && this.editingProvider) {
|
||||
this.updateDiscordProvider(data);
|
||||
} else {
|
||||
this.createDiscordProvider(data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Discord provider test
|
||||
*/
|
||||
onDiscordTest(data: DiscordFormData): void {
|
||||
const testRequest = {
|
||||
webhookUrl: data.webhookUrl,
|
||||
username: data.username,
|
||||
avatarUrl: data.avatarUrl,
|
||||
};
|
||||
|
||||
this.notificationProviderStore.testProvider({
|
||||
testRequest,
|
||||
type: NotificationProviderType.Discord,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle provider modal cancel
|
||||
*/
|
||||
@@ -554,6 +600,7 @@ export class NotificationSettingsComponent implements OnDestroy, CanComponentDea
|
||||
this.showNtfyModal = false;
|
||||
this.showPushoverModal = false;
|
||||
this.showTelegramModal = false;
|
||||
this.showDiscordModal = false;
|
||||
this.showProviderModal = false;
|
||||
this.editingProvider = null;
|
||||
this.notificationProviderStore.clearTestResult();
|
||||
@@ -848,6 +895,59 @@ export class NotificationSettingsComponent implements OnDestroy, CanComponentDea
|
||||
this.monitorProviderOperation("updated");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new Discord provider
|
||||
*/
|
||||
private createDiscordProvider(data: DiscordFormData): void {
|
||||
const createDto = {
|
||||
name: data.name,
|
||||
isEnabled: data.enabled,
|
||||
onFailedImportStrike: data.onFailedImportStrike,
|
||||
onStalledStrike: data.onStalledStrike,
|
||||
onSlowStrike: data.onSlowStrike,
|
||||
onQueueItemDeleted: data.onQueueItemDeleted,
|
||||
onDownloadCleaned: data.onDownloadCleaned,
|
||||
onCategoryChanged: data.onCategoryChanged,
|
||||
webhookUrl: data.webhookUrl,
|
||||
username: data.username,
|
||||
avatarUrl: data.avatarUrl,
|
||||
};
|
||||
|
||||
this.notificationProviderStore.createProvider({
|
||||
provider: createDto,
|
||||
type: NotificationProviderType.Discord,
|
||||
});
|
||||
this.monitorProviderOperation("created");
|
||||
}
|
||||
|
||||
/**
|
||||
* Update existing Discord provider
|
||||
*/
|
||||
private updateDiscordProvider(data: DiscordFormData): void {
|
||||
if (!this.editingProvider) return;
|
||||
|
||||
const updateDto = {
|
||||
name: data.name,
|
||||
isEnabled: data.enabled,
|
||||
onFailedImportStrike: data.onFailedImportStrike,
|
||||
onStalledStrike: data.onStalledStrike,
|
||||
onSlowStrike: data.onSlowStrike,
|
||||
onQueueItemDeleted: data.onQueueItemDeleted,
|
||||
onDownloadCleaned: data.onDownloadCleaned,
|
||||
onCategoryChanged: data.onCategoryChanged,
|
||||
webhookUrl: data.webhookUrl,
|
||||
username: data.username,
|
||||
avatarUrl: data.avatarUrl,
|
||||
};
|
||||
|
||||
this.notificationProviderStore.updateProvider({
|
||||
id: this.editingProvider.id,
|
||||
provider: updateDto,
|
||||
type: NotificationProviderType.Discord,
|
||||
});
|
||||
this.monitorProviderOperation("updated");
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitor provider operation completion and close modals
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,7 @@ export enum NotificationProviderType {
|
||||
Ntfy = "Ntfy",
|
||||
Pushover = "Pushover",
|
||||
Telegram = "Telegram",
|
||||
Discord = "Discord",
|
||||
}
|
||||
|
||||
export enum AppriseMode {
|
||||
|
||||
Reference in New Issue
Block a user