fix: turn on notification defaults and prompt on first DM visit

This commit is contained in:
2026-05-26 11:32:32 +05:30
parent 6dbe9c0ebb
commit 36b09eb8d5
4 changed files with 116 additions and 4 deletions
@@ -0,0 +1,56 @@
<script lang="ts">
import Bell from "@assets/icons/bell.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalTitle from "@lib/components/ModalTitle.svelte"
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import {enableNotifications} from "@app/util/notifications"
import {pushToast} from "@app/util/toast"
const dismiss = () => history.back()
const enable = async () => {
loading = true
try {
if (await enableNotifications()) {
pushToast({message: "Notifications enabled!"})
dismiss()
} else {
pushToast({
theme: "error",
message: "Failed to request notification permissions.",
})
}
} finally {
loading = false
}
}
let loading = $state(false)
</script>
<Modal>
<ModalBody>
<ModalHeader>
<div class="flex justify-center">
<Icon icon={Bell} size={6} />
</div>
<ModalTitle>Enable notifications</ModalTitle>
<ModalSubtitle>
Get notified when you receive new direct messages, even when Flotilla is in the background.
</ModalSubtitle>
</ModalHeader>
</ModalBody>
<ModalFooter>
<Button class="btn btn-ghost" onclick={dismiss} disabled={loading}>Not now</Button>
<Button class="btn btn-primary" onclick={enable} disabled={loading}>
<Spinner {loading}>Enable</Spinner>
</Button>
</ModalFooter>
</Modal>
+3 -3
View File
@@ -417,9 +417,9 @@ export const device = withGetter(writable(randomId()))
export const notificationSettings = withGetter(
writable({
push: false,
sound: false,
badge: false,
push: true,
sound: true,
badge: true,
spaces: true,
mentions: true,
messages: true,
+45 -1
View File
@@ -1,4 +1,5 @@
import {derived, get, writable} from "svelte/store"
import {Capacitor} from "@capacitor/core"
import {Badge} from "@capawesome/capacitor-badge"
import {synced, throttled, withGetter} from "@welshman/store"
import {pubkey, tracker, repository, relaysByUrl} from "@welshman/app"
@@ -10,6 +11,7 @@ import {makeSpacePath, makeRoomPath, makeSpaceChatPath, makeChatPath} from "@app
import {
CONTENT_KINDS,
notificationSettings,
pushState,
chatsById,
userGroupList,
getSpaceUrlsFromGroupList,
@@ -18,7 +20,49 @@ import {
} from "@app/core/state"
import {kv} from "@app/core/storage"
import {page} from "$app/stores"
export {Push} from "@app/util/push"
import {Push} from "@app/util/push"
export {Push}
export const areNotificationsEnabled = () => {
const {push, messages} = notificationSettings.get()
if (!push || !messages) {
return false
}
if (Capacitor.isNativePlatform()) {
return Boolean(pushState.get().token)
}
return Notification?.permission === "granted"
}
export const enableNotifications = async () => {
const permission = await Push.request()
if (!permission.startsWith("granted")) {
return false
}
const current = notificationSettings.get()
notificationSettings.set({
...current,
push: true,
badge: true,
sound: Capacitor.isNativePlatform() ? current.sound : true,
messages: true,
})
return true
}
export const dmNotificationsPrompted = synced({
key: "dmNotificationsPrompted",
defaultValue: false,
storage: kv,
})
// Checked state
+12
View File
@@ -1,13 +1,25 @@
<script lang="ts">
import {onMount} from "svelte"
import {get} from "svelte/store"
import {page} from "$app/stores"
import type {MakeNonOptional} from "@welshman/lib"
import {append, uniq} from "@welshman/lib"
import {pubkey} from "@welshman/app"
import Chat from "@app/components/Chat.svelte"
import EnableNotificationsPrompt from "@app/components/EnableNotificationsPrompt.svelte"
import {splitChatId} from "@app/core/state"
import {areNotificationsEnabled, dmNotificationsPrompted} from "@app/util/notifications"
import {pushModal} from "@app/util/modal"
const {chat} = $page.params as MakeNonOptional<typeof $page.params>
const pubkeys = uniq(append($pubkey!, splitChatId(chat)))
onMount(() => {
if (!areNotificationsEnabled() && !get(dmNotificationsPrompted)) {
dmNotificationsPrompted.set(true)
pushModal(EnableNotificationsPrompt)
}
})
</script>
<Chat {pubkeys} />