diff options
Diffstat (limited to 'src/state/queries')
-rw-r--r-- | src/state/queries/notifications/feed.ts | 37 | ||||
-rw-r--r-- | src/state/queries/notifications/settings.ts | 67 | ||||
-rw-r--r-- | src/state/queries/notifications/types.ts | 1 | ||||
-rw-r--r-- | src/state/queries/notifications/util.ts | 8 |
4 files changed, 97 insertions, 16 deletions
diff --git a/src/state/queries/notifications/feed.ts b/src/state/queries/notifications/feed.ts index 17ee90929..3cafcb716 100644 --- a/src/state/queries/notifications/feed.ts +++ b/src/state/queries/notifications/feed.ts @@ -46,11 +46,14 @@ const PAGE_SIZE = 30 type RQPageParam = string | undefined const RQKEY_ROOT = 'notification-feed' -export function RQKEY() { - return [RQKEY_ROOT] +export function RQKEY(priority?: false) { + return [RQKEY_ROOT, priority] } -export function useNotificationFeedQuery(opts?: {enabled?: boolean}) { +export function useNotificationFeedQuery(opts?: { + enabled?: boolean + overridePriorityNotifications?: boolean +}) { const agent = useAgent() const queryClient = useQueryClient() const moderationOpts = useModerationOpts() @@ -59,6 +62,10 @@ export function useNotificationFeedQuery(opts?: {enabled?: boolean}) { const lastPageCountRef = useRef(0) const gate = useGate() + // false: force showing all notifications + // undefined: let the server decide + const priority = opts?.overridePriorityNotifications ? false : undefined + const query = useInfiniteQuery< FeedPage, Error, @@ -67,7 +74,7 @@ export function useNotificationFeedQuery(opts?: {enabled?: boolean}) { RQPageParam >({ staleTime: STALE.INFINITY, - queryKey: RQKEY(), + queryKey: RQKEY(priority), async queryFn({pageParam}: {pageParam: RQPageParam}) { let page if (!pageParam) { @@ -75,17 +82,17 @@ export function useNotificationFeedQuery(opts?: {enabled?: boolean}) { page = unreads.getCachedUnreadPage() } if (!page) { - page = ( - await fetchPage({ - agent, - limit: PAGE_SIZE, - cursor: pageParam, - queryClient, - moderationOpts, - fetchAdditionalData: true, - shouldUngroupFollowBacks: () => gate('ungroup_follow_backs'), - }) - ).page + const {page: fetchedPage} = await fetchPage({ + agent, + limit: PAGE_SIZE, + cursor: pageParam, + queryClient, + moderationOpts, + fetchAdditionalData: true, + shouldUngroupFollowBacks: () => gate('ungroup_follow_backs'), + priority, + }) + page = fetchedPage } // if the first page has an unread, mark all read diff --git a/src/state/queries/notifications/settings.ts b/src/state/queries/notifications/settings.ts new file mode 100644 index 000000000..78ecbd9f7 --- /dev/null +++ b/src/state/queries/notifications/settings.ts @@ -0,0 +1,67 @@ +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useMutation, useQueryClient} from '@tanstack/react-query' + +import {until} from '#/lib/async/until' +import {logger} from '#/logger' +import {RQKEY as RQKEY_NOTIFS} from '#/state/queries/notifications/feed' +import {useAgent} from '#/state/session' +import * as Toast from '#/view/com/util/Toast' + +export function useNotificationsSettingsMutation() { + const {_} = useLingui() + const agent = useAgent() + const queryClient = useQueryClient() + + return useMutation({ + mutationFn: async (keys: string[]) => { + const enabled = keys[0] === 'enabled' + + await agent.api.app.bsky.notification.putPreferences({ + priority: enabled, + }) + + await until( + 5, // 5 tries + 1e3, // 1s delay between tries + res => res.data.priority === enabled, + () => agent.api.app.bsky.notification.listNotifications({limit: 1}), + ) + + eagerlySetCachedPriority(queryClient, enabled) + }, + onError: err => { + logger.error('Failed to save notification preferences', { + safeMessage: err, + }) + Toast.show( + _(msg`Failed to save notification preferences, please try again`), + 'xmark', + ) + }, + onSuccess: () => { + Toast.show(_(msg`Preference saved`)) + }, + onSettled: () => { + queryClient.invalidateQueries({queryKey: RQKEY_NOTIFS()}) + }, + }) +} + +function eagerlySetCachedPriority( + queryClient: ReturnType<typeof useQueryClient>, + enabled: boolean, +) { + queryClient.setQueryData(RQKEY_NOTIFS(), (old: any) => { + if (!old) return old + return { + ...old, + pages: old.pages.map((page: any) => { + return { + ...page, + priority: enabled, + } + }), + } + }) +} diff --git a/src/state/queries/notifications/types.ts b/src/state/queries/notifications/types.ts index d40a07b12..c96374eb8 100644 --- a/src/state/queries/notifications/types.ts +++ b/src/state/queries/notifications/types.ts @@ -22,6 +22,7 @@ export interface FeedPage { cursor: string | undefined seenAt: Date items: FeedNotification[] + priority: boolean } export interface CachedFeedPage { diff --git a/src/state/queries/notifications/util.ts b/src/state/queries/notifications/util.ts index 2f2c242d8..7651e414a 100644 --- a/src/state/queries/notifications/util.ts +++ b/src/state/queries/notifications/util.ts @@ -39,10 +39,15 @@ export async function fetchPage({ moderationOpts: ModerationOpts | undefined fetchAdditionalData: boolean shouldUngroupFollowBacks?: () => boolean -}): Promise<{page: FeedPage; indexedAt: string | undefined}> { + priority?: boolean +}): Promise<{ + page: FeedPage + indexedAt: string | undefined +}> { const res = await agent.listNotifications({ limit, cursor, + // priority, }) const indexedAt = res.data.notifications[0]?.indexedAt @@ -88,6 +93,7 @@ export async function fetchPage({ cursor: res.data.cursor, seenAt, items: notifsGrouped, + priority: res.data.priority ?? false, }, indexedAt, } |