about summary refs log tree commit diff
path: root/src/state/queries/notifications/settings.ts
blob: bfc449d17bca7a6b5f22836a9a569e4d2ad089d8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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 {invalidateCachedUnreadPage} from '#/state/queries/notifications/unread'
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: () => {
      invalidateCachedUnreadPage()
      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,
        }
      }),
    }
  })
}