diff --git a/src/app/mail/index.ts b/src/app/mail/index.ts index be7199f7..0f8b6a99 100644 --- a/src/app/mail/index.ts +++ b/src/app/mail/index.ts @@ -1,4 +1,4 @@ -import {hash, maybe} from "@welshman/lib" +import {hash, maybe, throttle} from "@welshman/lib" import type {Filter} from "@welshman/util" import {Address, DELETE, makeEvent, makeHttpAuth, makeHttpAuthHeader} from "@welshman/util" import {Relays, User} from "@welshman/app" @@ -6,6 +6,7 @@ import {buildUrl} from "@lib/util" import {app, thunks} from "@app/core" import {device} from "@app/device" import {EMAIL_NOTIFICATION_SERVER, PUSH_BRIDGE} from "@app/env" +import {userSettingsValues} from "@app/settings" import {emailNotificationState, syncRelaySubscriptions} from "@app/push/adapters/common" export class MailNotifications { @@ -119,6 +120,32 @@ export class MailNotifications { await this.unregister() } + sync() { + return userSettingsValues.subscribe( + throttle(500, async ({email, emailAddress, emailFrequency}) => { + const current = emailNotificationState.get() + + if (email && emailAddress) { + if ( + !current.callback || + current.email !== emailAddress || + current.frequency !== emailFrequency + ) { + try { + await this.register(emailAddress, emailFrequency) + } catch { + return + } + } + + await this.enable() + } else { + await this.disable() + } + }), + ) + } + _getSubscriptionIdentifier = (relay: string, key: string) => String(hash(relay + key + device.get() + "email")) diff --git a/src/app/settings.ts b/src/app/settings.ts index fa342dca..0d7c8b91 100644 --- a/src/app/settings.ts +++ b/src/app/settings.ts @@ -31,6 +31,9 @@ export type SettingsValues = { font_size: number alerts: SpaceNotificationSettings[] zap_amounts: number[] + email: boolean + emailAddress: string + emailFrequency: string } export const defaultSettings: SettingsValues = { @@ -43,6 +46,9 @@ export const defaultSettings: SettingsValues = { font_size: 1.1, alerts: [], zap_amounts: [21, 210, 2100, 21000], + email: false, + emailAddress: "", + emailFrequency: "daily", } export class Settings extends DerivedPlugin { @@ -97,9 +103,6 @@ export const notificationSettings = withGetter( spaces: true, mentions: true, messages: true, - email: false, - emailFrequency: "daily", - emailAddress: "", }), ) diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 417e0b8c..6055ab41 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -43,6 +43,7 @@ latestActivityByPath, } from "@app/notifications" import {Push} from "@app/push" + import {Mail} from "@app/mail" import {onPushNotificationAction, pushState} from "@app/push/adapters/common" import {syncKeyboard} from "@app/keyboard" import {syncCallAudioResume} from "@app/call" @@ -212,6 +213,9 @@ // Initialize background notifications unsubscribers.push(Push.sync()) + // Sync email notification prefs across devices and register this device + unsubscribers.push(Mail.sync()) + // Logging in swaps in a fresh app — its policies rebind themselves, we just have to sync // application data against the new identity's relays. Wait for the new app's storage to // load the way startup does, so sync reconciles against cached events. diff --git a/src/routes/settings/alerts/+page.svelte b/src/routes/settings/alerts/+page.svelte index 57432257..dc2e27e9 100644 --- a/src/routes/settings/alerts/+page.svelte +++ b/src/routes/settings/alerts/+page.svelte @@ -15,7 +15,7 @@ import {clearBadges} from "@app/notifications" import {Push} from "@app/push" import {Mail} from "@app/mail" - import {notificationSettings} from "@app/settings" + import {notificationSettings, publishSettings, userSettingsValues} from "@app/settings" import {emailNotificationState} from "@app/push/adapters/common" const clearError = () => { @@ -24,8 +24,24 @@ } } + const buildSettings = () => { + const local = notificationSettings.get() + + return { + push: local.push, + sound: local.sound, + badge: local.badge, + spaces: local.spaces, + mentions: local.mentions, + messages: local.messages, + email: $userSettingsValues.email, + emailAddress: $userSettingsValues.emailAddress, + emailFrequency: $userSettingsValues.emailFrequency, + } + } + const reset = () => { - settings = {...notificationSettings.get()} + settings = buildSettings() clearError() } @@ -73,7 +89,21 @@ await Mail.disable() } - notificationSettings.set(settings) + // Sync email prefs across devices via AppData + await publishSettings({ + email: settings.email, + emailAddress: settings.emailAddress, + emailFrequency: settings.emailFrequency, + }) + + notificationSettings.set({ + push: settings.push, + sound: settings.sound, + badge: settings.badge, + spaces: settings.spaces, + mentions: settings.mentions, + messages: settings.messages, + }) pushToast({message: "Your settings have been saved!"}) } finally { @@ -82,7 +112,7 @@ }) let loading = $state(false) - let settings = $state({...notificationSettings.get()}) + let settings = $state(buildSettings())