Make the tab title unread count match the notification dots (#402)
Co-authored-by: Coracle-Bot <npub1klq6260@nostr.local>
This commit is contained in:
parent
a4cec9caf2
commit
1d4be33326
2 changed files with 40 additions and 20 deletions
|
|
@ -29,6 +29,7 @@ import {Relays, RoomLists} from "@welshman/app"
|
||||||
import {deriveEventsByIdByUrl} from "@app/repository"
|
import {deriveEventsByIdByUrl} from "@app/repository"
|
||||||
import {app, fromApp} from "@app/core"
|
import {app, fromApp} from "@app/core"
|
||||||
import {makeRoomPath, makeSpaceChatPath, makeChatPath, makeContentPath} from "@app/routes"
|
import {makeRoomPath, makeSpaceChatPath, makeChatPath, makeContentPath} from "@app/routes"
|
||||||
|
import {decodeRelay} from "@app/relays"
|
||||||
import {CONTENT_KINDS, makeCommentFilter} from "@app/content"
|
import {CONTENT_KINDS, makeCommentFilter} from "@app/content"
|
||||||
import {getIsMuted, notificationSettings, userSettingsValues} from "@app/settings"
|
import {getIsMuted, notificationSettings, userSettingsValues} from "@app/settings"
|
||||||
import {chatsById} from "@app/chats"
|
import {chatsById} from "@app/chats"
|
||||||
|
|
@ -60,25 +61,41 @@ const getPaths = (path: string) =>
|
||||||
.map((_, i, segments) => segments.slice(0, i + 1).join("/"))
|
.map((_, i, segments) => segments.slice(0, i + 1).join("/"))
|
||||||
.slice(1)
|
.slice(1)
|
||||||
|
|
||||||
|
const getCheckedPaths = (pathname: string, relay?: string) => {
|
||||||
|
const paths = getPaths(pathname)
|
||||||
|
|
||||||
|
if (relay) {
|
||||||
|
const url = decodeRelay(relay)
|
||||||
|
|
||||||
|
if (CONTENT_KINDS.some(kind => makeContentPath(url, kind) === pathname)) {
|
||||||
|
paths.push(pathname + "*")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths
|
||||||
|
}
|
||||||
|
|
||||||
export const syncChecked = () => {
|
export const syncChecked = () => {
|
||||||
let prev = ""
|
let prev: string[] = []
|
||||||
|
|
||||||
return page.subscribe($page => {
|
return page.subscribe($page => {
|
||||||
// Set checked when we leave a given page
|
// Set checked when we leave a given page
|
||||||
checked.update($checked => {
|
checked.update($checked => {
|
||||||
for (const path of getPaths(prev)) {
|
for (const path of prev) {
|
||||||
$checked[path] = now()
|
$checked[path] = now()
|
||||||
}
|
}
|
||||||
|
|
||||||
return $checked
|
return $checked
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const paths = getCheckedPaths($page.url.pathname, $page.params.relay)
|
||||||
|
|
||||||
// Set checked when we visit a given page - but delay it a tad
|
// Set checked when we visit a given page - but delay it a tad
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const defer = get(deferredRoomPath)
|
const defer = get(deferredRoomPath)
|
||||||
|
|
||||||
checked.update($checked => {
|
checked.update($checked => {
|
||||||
for (const path of getPaths($page.url.pathname)) {
|
for (const path of paths) {
|
||||||
if (defer && path === defer) continue
|
if (defer && path === defer) continue
|
||||||
$checked[path] = now()
|
$checked[path] = now()
|
||||||
}
|
}
|
||||||
|
|
@ -87,7 +104,7 @@ export const syncChecked = () => {
|
||||||
})
|
})
|
||||||
}, 300)
|
}, 300)
|
||||||
|
|
||||||
prev = $page.url.pathname
|
prev = paths
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -330,16 +347,26 @@ export const notifications = derived(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const countActivity = (activity: Map<string, TrustedEvent>, paths: Set<string>) =>
|
||||||
|
[...activity.keys()].filter(path => paths.has(path)).length
|
||||||
|
|
||||||
|
export const notificationCount = derived(
|
||||||
|
[latestActivityByPath, notifications],
|
||||||
|
([$latestActivityByPath, $notifications]) => countActivity($latestActivityByPath, $notifications),
|
||||||
|
)
|
||||||
|
|
||||||
|
export const backgroundNotificationCount = derived(
|
||||||
|
[latestActivityByPath, allNotifications],
|
||||||
|
([$latestActivityByPath, $allNotifications]) =>
|
||||||
|
countActivity($latestActivityByPath, $allNotifications),
|
||||||
|
)
|
||||||
|
|
||||||
// Badges
|
// Badges
|
||||||
|
|
||||||
export const syncBadges = () =>
|
export const syncBadges = () =>
|
||||||
derived([latestActivityByPath, notifications, notificationSettings], identity).subscribe(
|
derived([notificationCount, notificationSettings], identity).subscribe(
|
||||||
async ([$latestActivityByPath, $notifications, $notificationSettings]) => {
|
async ([count, $notificationSettings]) => {
|
||||||
if ($notificationSettings.badge) {
|
if ($notificationSettings.badge) {
|
||||||
const count = [...$latestActivityByPath.keys()].filter(path =>
|
|
||||||
$notifications.has(path),
|
|
||||||
).length
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Badge.set({count})
|
await Badge.set({count})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,7 @@
|
||||||
import {activeTheme, flTheme, theme} from "@app/theme"
|
import {activeTheme, flTheme, theme} from "@app/theme"
|
||||||
import {toast, pushToast} from "@app/toast"
|
import {toast, pushToast} from "@app/toast"
|
||||||
import * as notifications from "@app/notifications"
|
import * as notifications from "@app/notifications"
|
||||||
import {
|
import {notificationCount, backgroundNotificationCount} from "@app/notifications"
|
||||||
notifications as notificationPaths,
|
|
||||||
allNotifications,
|
|
||||||
latestActivityByPath,
|
|
||||||
} from "@app/notifications"
|
|
||||||
import {Push} from "@app/push"
|
import {Push} from "@app/push"
|
||||||
import {onPushNotificationAction, pushState} from "@app/push/adapters/common"
|
import {onPushNotificationAction, pushState} from "@app/push/adapters/common"
|
||||||
import {syncKeyboard} from "@app/keyboard"
|
import {syncKeyboard} from "@app/keyboard"
|
||||||
|
|
@ -290,12 +286,9 @@
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
const {user} = core.app.get()
|
const {user} = core.app.get()
|
||||||
const title = getPageTitle({page: $page, pubkey: user?.pubkey})
|
const title = getPageTitle({page: $page, pubkey: user?.pubkey})
|
||||||
// While the tab isn't actively focused the user isn't actually looking at the
|
const count = $documentActive ? $notificationCount : $backgroundNotificationCount
|
||||||
// active page, so count notifications for it too rather than treating it as read.
|
|
||||||
const paths = $documentActive ? $notificationPaths : $allNotifications
|
|
||||||
const unreadCount = [...$latestActivityByPath.keys()].filter(path => paths.has(path)).length
|
|
||||||
|
|
||||||
document.title = unreadCount > 0 ? `(${unreadCount}) ${title}` : title
|
document.title = count > 0 ? `(${count}) ${title}` : title
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue