Browse Source
- Created NotificationSettingsService class for settings and permission logic - Separates business logic from UI presentation in NotificationSection - Maintains component lifecycle boundary while improving testability - Service handles settings hydration, persistence, and permission management - Component now focuses purely on UI with computed properties for template access - Added src/composables/useNotificationSettings.ts - Updated src/components/NotificationSection.vue to use service - Resolved TypeScript type issues with PlatformServiceMixin integrationpull/150/head
3 changed files with 305 additions and 120 deletions
@ -0,0 +1,233 @@ |
|||
/** |
|||
* useNotificationSettings.ts - Notification settings and permissions service |
|||
* |
|||
* This service handles all notification-related business logic including: |
|||
* - Settings hydration and persistence |
|||
* - Registration status checking |
|||
* - Notification permission management |
|||
* - Settings state management |
|||
* |
|||
* Separates business logic from UI components while maintaining |
|||
* the lifecycle boundary and settings access patterns. |
|||
* |
|||
* @author Matthew Raymer |
|||
* @service NotificationSettingsService |
|||
*/ |
|||
|
|||
import { createNotifyHelpers } from "@/utils/notify"; |
|||
import { ACCOUNT_VIEW_CONSTANTS } from "@/constants/accountView"; |
|||
import { DAILY_CHECK_TITLE, DIRECT_PUSH_TITLE } from "@/libs/util"; |
|||
import type { ComponentPublicInstance } from "vue"; |
|||
|
|||
/** |
|||
* Interface for notification settings state |
|||
*/ |
|||
export interface NotificationSettingsState { |
|||
isRegistered: boolean; |
|||
notifyingNewActivity: boolean; |
|||
notifyingNewActivityTime: string; |
|||
notifyingReminder: boolean; |
|||
notifyingReminderMessage: string; |
|||
notifyingReminderTime: string; |
|||
} |
|||
|
|||
/** |
|||
* Interface for notification settings actions |
|||
*/ |
|||
export interface NotificationSettingsActions { |
|||
hydrateFromSettings: () => Promise<void>; |
|||
updateNewActivityNotification: ( |
|||
enabled: boolean, |
|||
timeText?: string, |
|||
) => Promise<void>; |
|||
updateReminderNotification: ( |
|||
enabled: boolean, |
|||
timeText?: string, |
|||
message?: string, |
|||
) => Promise<void>; |
|||
showNewActivityNotificationInfo: (router: any) => Promise<void>; |
|||
showReminderNotificationInfo: (router: any) => Promise<void>; |
|||
showNewActivityNotificationChoice: ( |
|||
pushNotificationPermissionRef: any, |
|||
) => Promise<void>; |
|||
showReminderNotificationChoice: ( |
|||
pushNotificationPermissionRef: any, |
|||
) => Promise<void>; |
|||
} |
|||
|
|||
/** |
|||
* Service class for managing notification settings and permissions |
|||
* |
|||
* @param platformService - PlatformServiceMixin instance for settings access |
|||
* @param notify - Notification helper functions |
|||
*/ |
|||
export class NotificationSettingsService |
|||
implements NotificationSettingsState, NotificationSettingsActions |
|||
{ |
|||
// State properties
|
|||
public isRegistered: boolean = false; |
|||
public notifyingNewActivity: boolean = false; |
|||
public notifyingNewActivityTime: string = ""; |
|||
public notifyingReminder: boolean = false; |
|||
public notifyingReminderMessage: string = ""; |
|||
public notifyingReminderTime: string = ""; |
|||
|
|||
constructor( |
|||
private platformService: ComponentPublicInstance & { |
|||
$accountSettings: () => Promise<any>; |
|||
$saveSettings: (changes: any) => Promise<boolean>; |
|||
}, |
|||
private notify: ReturnType<typeof createNotifyHelpers>, |
|||
) {} |
|||
|
|||
/** |
|||
* Load notification settings from database and hydrate internal state |
|||
* Uses the existing settings mechanism for consistency |
|||
*/ |
|||
public async hydrateFromSettings(): Promise<void> { |
|||
try { |
|||
const settings = await this.platformService.$accountSettings(); |
|||
|
|||
// Hydrate registration status
|
|||
this.isRegistered = !!settings?.isRegistered; |
|||
|
|||
// Hydrate boolean flags from time presence
|
|||
this.notifyingNewActivity = !!settings.notifyingNewActivityTime; |
|||
this.notifyingNewActivityTime = settings.notifyingNewActivityTime || ""; |
|||
this.notifyingReminder = !!settings.notifyingReminderTime; |
|||
this.notifyingReminderMessage = settings.notifyingReminderMessage || ""; |
|||
this.notifyingReminderTime = settings.notifyingReminderTime || ""; |
|||
} catch (error) { |
|||
console.error("Failed to hydrate notification settings:", error); |
|||
// Keep default values on error
|
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Update new activity notification settings |
|||
*/ |
|||
public async updateNewActivityNotification( |
|||
enabled: boolean, |
|||
timeText: string = "", |
|||
): Promise<void> { |
|||
await this.platformService.$saveSettings({ |
|||
notifyingNewActivityTime: timeText, |
|||
}); |
|||
this.notifyingNewActivity = enabled; |
|||
this.notifyingNewActivityTime = timeText; |
|||
} |
|||
|
|||
/** |
|||
* Update reminder notification settings |
|||
*/ |
|||
public async updateReminderNotification( |
|||
enabled: boolean, |
|||
timeText: string = "", |
|||
message: string = "", |
|||
): Promise<void> { |
|||
await this.platformService.$saveSettings({ |
|||
notifyingReminderMessage: message, |
|||
notifyingReminderTime: timeText, |
|||
}); |
|||
this.notifyingReminder = enabled; |
|||
this.notifyingReminderMessage = message; |
|||
this.notifyingReminderTime = timeText; |
|||
} |
|||
|
|||
/** |
|||
* Show new activity notification info dialog |
|||
*/ |
|||
public async showNewActivityNotificationInfo(router: any): Promise<void> { |
|||
this.notify.confirm( |
|||
ACCOUNT_VIEW_CONSTANTS.NOTIFICATIONS.NEW_ACTIVITY_INFO, |
|||
async () => { |
|||
await router.push({ |
|||
name: "help-notification-types", |
|||
}); |
|||
}, |
|||
); |
|||
} |
|||
|
|||
/** |
|||
* Show reminder notification info dialog |
|||
*/ |
|||
public async showReminderNotificationInfo(router: any): Promise<void> { |
|||
this.notify.confirm( |
|||
ACCOUNT_VIEW_CONSTANTS.NOTIFICATIONS.REMINDER_INFO, |
|||
async () => { |
|||
await router.push({ |
|||
name: "help-notification-types", |
|||
}); |
|||
}, |
|||
); |
|||
} |
|||
|
|||
/** |
|||
* Handle new activity notification choice (enable/disable) |
|||
*/ |
|||
public async showNewActivityNotificationChoice( |
|||
pushNotificationPermissionRef: any, |
|||
): Promise<void> { |
|||
if (!this.notifyingNewActivity) { |
|||
// Enable notification
|
|||
pushNotificationPermissionRef.open( |
|||
DAILY_CHECK_TITLE, |
|||
async (success: boolean, timeText: string) => { |
|||
if (success) { |
|||
await this.updateNewActivityNotification(true, timeText); |
|||
} |
|||
}, |
|||
); |
|||
} else { |
|||
// Disable notification
|
|||
this.notify.notificationOff(DAILY_CHECK_TITLE, async (success) => { |
|||
if (success) { |
|||
await this.updateNewActivityNotification(false); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Handle reminder notification choice (enable/disable) |
|||
*/ |
|||
public async showReminderNotificationChoice( |
|||
pushNotificationPermissionRef: any, |
|||
): Promise<void> { |
|||
if (!this.notifyingReminder) { |
|||
// Enable notification
|
|||
pushNotificationPermissionRef.open( |
|||
DIRECT_PUSH_TITLE, |
|||
async (success: boolean, timeText: string, message?: string) => { |
|||
if (success) { |
|||
await this.updateReminderNotification(true, timeText, message); |
|||
} |
|||
}, |
|||
); |
|||
} else { |
|||
// Disable notification
|
|||
this.notify.notificationOff(DIRECT_PUSH_TITLE, async (success) => { |
|||
if (success) { |
|||
await this.updateReminderNotification(false); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Factory function to create a NotificationSettingsService instance |
|||
* |
|||
* @param platformService - PlatformServiceMixin instance |
|||
* @param notify - Notification helper functions |
|||
* @returns NotificationSettingsService instance |
|||
*/ |
|||
export function createNotificationSettingsService( |
|||
platformService: ComponentPublicInstance & { |
|||
$accountSettings: () => Promise<any>; |
|||
$saveSettings: (changes: any) => Promise<boolean>; |
|||
}, |
|||
notify: ReturnType<typeof createNotifyHelpers>, |
|||
): NotificationSettingsService { |
|||
return new NotificationSettingsService(platformService, notify); |
|||
} |
Loading…
Reference in new issue