import React from 'react' import {View} from 'react-native' import {useFocusEffect, useIsFocused} from '@react-navigation/native' import {useQueryClient} from '@tanstack/react-query' import { NativeStackScreenProps, NotificationsTabNavigatorParams, } from 'lib/routes/types' import {ViewHeader} from '../com/util/ViewHeader' import {Feed} from '../com/notifications/Feed' import {TextLink} from 'view/com/util/Link' import {ListMethods} from 'view/com/util/List' import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn' import {MainScrollProvider} from '../com/util/MainScrollProvider' 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 {Trans, msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import { useUnreadNotifications, useUnreadNotificationsApi, } from '#/state/queries/notifications/unread' import {RQKEY as NOTIFS_RQKEY} from '#/state/queries/notifications/feed' import {listenSoftReset, emitSoftReset} from '#/state/events' import {truncateAndInvalidate} from '#/state/queries/util' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import {isNative} from '#/platform/detection' import {FAB} from '../com/util/fab/FAB' import {ComposeIcon2} from 'lib/icons' import {useComposerControls} from '#/state/shell/composer' type Props = NativeStackScreenProps< NotificationsTabNavigatorParams, 'Notifications' > export function NotificationsScreen({}: Props) { const {_} = useLingui() const setMinimalShellMode = useSetMinimalShellMode() const [isScrolledDown, setIsScrolledDown] = React.useState(false) const scrollElRef = React.useRef(null) const {screen} = useAnalytics() const pal = usePalette('default') const {isDesktop} = useWebMediaQueries() const queryClient = useQueryClient() const unreadNotifs = useUnreadNotifications() const unreadApi = useUnreadNotificationsApi() const hasNew = !!unreadNotifs const isScreenFocused = useIsFocused() const {openComposer} = useComposerControls() // event handlers // = const scrollToTop = React.useCallback(() => { scrollElRef.current?.scrollToOffset({animated: isNative, offset: 0}) setMinimalShellMode(false) }, [scrollElRef, setMinimalShellMode]) const onPressLoadLatest = React.useCallback(() => { scrollToTop() if (hasNew) { // render what we have now truncateAndInvalidate(queryClient, NOTIFS_RQKEY()) } else { // check with the server unreadApi.checkUnread({invalidate: true}) } }, [scrollToTop, queryClient, unreadApi, hasNew]) const onFocusCheckLatest = useNonReactiveCallback(() => { // on focus, check for latest, but only invalidate if the user // isnt scrolled down to avoid moving content underneath them let currentIsScrolledDown if (isNative) { currentIsScrolledDown = isScrolledDown } else { // On the web, this isn't always updated in time so // we're just going to look it up synchronously. currentIsScrolledDown = window.scrollY > 200 } unreadApi.checkUnread({invalidate: !currentIsScrolledDown}) }) // on-visible setup // = useFocusEffect( React.useCallback(() => { setMinimalShellMode(false) logger.debug('NotificationsScreen: Focus') screen('Notifications') onFocusCheckLatest() }, [screen, setMinimalShellMode, onFocusCheckLatest]), ) React.useEffect(() => { if (!isScreenFocused) { return } return listenSoftReset(onPressLoadLatest) }, [onPressLoadLatest, isScreenFocused]) const ListHeaderComponent = React.useCallback(() => { if (isDesktop) { return ( Notifications{' '} {hasNew && ( )} } onPress={emitSoftReset} /> ) } return <> }, [isDesktop, pal, hasNew]) return ( {(isScrolledDown || hasNew) && ( )} openComposer({})} icon={} accessibilityRole="button" accessibilityLabel={_(msg`New post`)} accessibilityHint="" /> ) }