about summary refs log tree commit diff
path: root/src/view/screens/Notifications.tsx
blob: 970882f1222038d5f13b0a187b341d648f3f7aa1 (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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import React from 'react'
import {FlatList, View} from 'react-native'
import {useFocusEffect} from '@react-navigation/native'
import {useQueryClient} from '@tanstack/react-query'
import {
  NativeStackScreenProps,
  NotificationsTabNavigatorParams,
} from 'lib/routes/types'
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
import {ViewHeader} from '../com/util/ViewHeader'
import {Feed} from '../com/notifications/Feed'
import {TextLink} from 'view/com/util/Link'
import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
import {useOnMainScroll} from 'lib/hooks/useOnMainScroll'
import {usePalette} from 'lib/hooks/usePalette'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {s, colors} from 'lib/styles'
import {useAnalytics} from 'lib/analytics/analytics'
import {logger} from '#/logger'
import {useSetMinimalShellMode} from '#/state/shell'
import {useUnreadNotifications} from '#/state/queries/notifications/unread'
import {RQKEY as NOTIFS_RQKEY} from '#/state/queries/notifications/feed'
import {listenSoftReset, emitSoftReset} from '#/state/events'

type Props = NativeStackScreenProps<
  NotificationsTabNavigatorParams,
  'Notifications'
>
export const NotificationsScreen = withAuthRequired(
  function NotificationsScreenImpl({}: Props) {
    const setMinimalShellMode = useSetMinimalShellMode()
    const [onMainScroll, isScrolledDown, resetMainScroll] = useOnMainScroll()
    const scrollElRef = React.useRef<FlatList>(null)
    const {screen} = useAnalytics()
    const pal = usePalette('default')
    const {isDesktop} = useWebMediaQueries()
    const unreadNotifs = useUnreadNotifications()
    const queryClient = useQueryClient()
    const hasNew = !!unreadNotifs

    // event handlers
    // =
    const scrollToTop = React.useCallback(() => {
      scrollElRef.current?.scrollToOffset({offset: 0})
      resetMainScroll()
    }, [scrollElRef, resetMainScroll])

    const onPressLoadLatest = React.useCallback(() => {
      scrollToTop()
      queryClient.invalidateQueries({queryKey: NOTIFS_RQKEY()})
    }, [scrollToTop, queryClient])

    // on-visible setup
    // =
    useFocusEffect(
      React.useCallback(() => {
        setMinimalShellMode(false)
        logger.debug('NotificationsScreen: Updating feed')
        screen('Notifications')
        return listenSoftReset(onPressLoadLatest)
      }, [screen, onPressLoadLatest, setMinimalShellMode]),
    )

    const ListHeaderComponent = React.useCallback(() => {
      if (isDesktop) {
        return (
          <View
            style={[
              pal.view,
              {
                flexDirection: 'row',
                alignItems: 'center',
                justifyContent: 'space-between',
                paddingHorizontal: 18,
                paddingVertical: 12,
              },
            ]}>
            <TextLink
              type="title-lg"
              href="/notifications"
              style={[pal.text, {fontWeight: 'bold'}]}
              text={
                <>
                  Notifications{' '}
                  {hasNew && (
                    <View
                      style={{
                        top: -8,
                        backgroundColor: colors.blue3,
                        width: 8,
                        height: 8,
                        borderRadius: 4,
                      }}
                    />
                  )}
                </>
              }
              onPress={emitSoftReset}
            />
          </View>
        )
      }
      return <></>
    }, [isDesktop, pal, hasNew])

    return (
      <View testID="notificationsScreen" style={s.hContentRegion}>
        <ViewHeader title="Notifications" canGoBack={false} />
        <Feed
          onScroll={onMainScroll}
          scrollElRef={scrollElRef}
          ListHeaderComponent={ListHeaderComponent}
        />
        {(isScrolledDown || hasNew) && (
          <LoadLatestBtn
            onPress={onPressLoadLatest}
            label="Load new notifications"
            showIndicator={hasNew}
          />
        )}
      </View>
    )
  },
)