add note to mentions tab that it's nonfunctional

This commit is contained in:
Samuel Newman
2025-06-19 14:43:06 +03:00
parent 728addccb7
commit 6bd916514b
3 changed files with 51 additions and 17 deletions
+4 -1
View File
@@ -14,7 +14,9 @@ import * as Toast from '#/view/com/util/Toast'
const RQKEY_ROOT = 'notification-settings' const RQKEY_ROOT = 'notification-settings'
const RQKEY = [RQKEY_ROOT] const RQKEY = [RQKEY_ROOT]
export function useNotificationSettingsQuery() { export function useNotificationSettingsQuery({
enabled,
}: {enabled?: boolean} = {}) {
const agent = useAgent() const agent = useAgent()
return useQuery({ return useQuery({
@@ -23,6 +25,7 @@ export function useNotificationSettingsQuery() {
const response = await agent.app.bsky.notification.getPreferences() const response = await agent.app.bsky.notification.getPreferences()
return response.data.preferences return response.data.preferences
}, },
enabled,
}) })
} }
export function useNotificationSettingsUpdateMutation() { export function useNotificationSettingsUpdateMutation() {
@@ -16,7 +16,7 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useNotificationFeedQuery} from '#/state/queries/notifications/feed' import {useNotificationFeedQuery} from '#/state/queries/notifications/feed'
import {EmptyState} from '#/view/com/util/EmptyState' import {EmptyState} from '#/view/com/util/EmptyState'
import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
import {List, type ListRef} from '#/view/com/util/List' import {List, type ListProps, type ListRef} from '#/view/com/util/List'
import {NotificationFeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' import {NotificationFeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
import {LoadMoreRetryBtn} from '#/view/com/util/LoadMoreRetryBtn' import {LoadMoreRetryBtn} from '#/view/com/util/LoadMoreRetryBtn'
import {NotificationFeedItem} from './NotificationFeedItem' import {NotificationFeedItem} from './NotificationFeedItem'
@@ -39,7 +39,7 @@ export function NotificationFeed({
scrollElRef?: ListRef scrollElRef?: ListRef
onPressTryAgain?: () => void onPressTryAgain?: () => void
onScrolledDownChange: (isScrolledDown: boolean) => void onScrolledDownChange: (isScrolledDown: boolean) => void
ListHeaderComponent?: () => JSX.Element ListHeaderComponent?: ListProps['ListHeaderComponent']
refreshNotifications: () => Promise<void> refreshNotifications: () => Promise<void>
}) { }) {
const initialNumToRender = useInitialNumToRender() const initialNumToRender = useInitialNumToRender()
+45 -14
View File
@@ -1,4 +1,4 @@
import React from 'react' import {useCallback, useEffect, useMemo, useRef, useState} from 'react'
import {View} from 'react-native' import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
@@ -17,6 +17,7 @@ import {logger} from '#/logger'
import {isNative} from '#/platform/detection' import {isNative} from '#/platform/detection'
import {emitSoftReset, listenSoftReset} from '#/state/events' import {emitSoftReset, listenSoftReset} from '#/state/events'
import {RQKEY as NOTIFS_RQKEY} from '#/state/queries/notifications/feed' import {RQKEY as NOTIFS_RQKEY} from '#/state/queries/notifications/feed'
import {useNotificationSettingsQuery} from '#/state/queries/notifications/settings'
import { import {
useUnreadNotifications, useUnreadNotifications,
useUnreadNotificationsApi, useUnreadNotificationsApi,
@@ -30,8 +31,9 @@ import {FAB} from '#/view/com/util/fab/FAB'
import {type ListMethods} from '#/view/com/util/List' import {type ListMethods} from '#/view/com/util/List'
import {LoadLatestBtn} from '#/view/com/util/load-latest/LoadLatestBtn' import {LoadLatestBtn} from '#/view/com/util/load-latest/LoadLatestBtn'
import {MainScrollProvider} from '#/view/com/util/MainScrollProvider' import {MainScrollProvider} from '#/view/com/util/MainScrollProvider'
import {atoms as a} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {web} from '#/alf' import {web} from '#/alf'
import {Admonition} from '#/components/Admonition'
import {ButtonIcon} from '#/components/Button' import {ButtonIcon} from '#/components/Button'
import {SettingsGear2_Stroke2_Corner0_Rounded as SettingsIcon} from '#/components/icons/SettingsGear2' import {SettingsGear2_Stroke2_Corner0_Rounded as SettingsIcon} from '#/components/icons/SettingsGear2'
import * as Layout from '#/components/Layout' import * as Layout from '#/components/Layout'
@@ -53,13 +55,13 @@ export function NotificationsScreen({}: Props) {
const unreadNotifs = useUnreadNotifications() const unreadNotifs = useUnreadNotifications()
const hasNew = !!unreadNotifs const hasNew = !!unreadNotifs
const {checkUnread: checkUnreadAll} = useUnreadNotificationsApi() const {checkUnread: checkUnreadAll} = useUnreadNotificationsApi()
const [isLoadingAll, setIsLoadingAll] = React.useState(false) const [isLoadingAll, setIsLoadingAll] = useState(false)
const [isLoadingMentions, setIsLoadingMentions] = React.useState(false) const [isLoadingMentions, setIsLoadingMentions] = useState(false)
const initialActiveTab = lastActiveTab const initialActiveTab = lastActiveTab
const [activeTab, setActiveTab] = React.useState(initialActiveTab) const [activeTab, setActiveTab] = useState(initialActiveTab)
const isLoading = activeTab === 0 ? isLoadingAll : isLoadingMentions const isLoading = activeTab === 0 ? isLoadingAll : isLoadingMentions
const onPageSelected = React.useCallback( const onPageSelected = useCallback(
(index: number) => { (index: number) => {
setActiveTab(index) setActiveTab(index)
lastActiveTab = index lastActiveTab = index
@@ -68,7 +70,7 @@ export function NotificationsScreen({}: Props) {
) )
const queryClient = useQueryClient() const queryClient = useQueryClient()
const checkUnreadMentions = React.useCallback( const checkUnreadMentions = useCallback(
async ({invalidate}: {invalidate: boolean}) => { async ({invalidate}: {invalidate: boolean}) => {
if (invalidate) { if (invalidate) {
return truncateAndInvalidate(queryClient, NOTIFS_RQKEY('mentions')) return truncateAndInvalidate(queryClient, NOTIFS_RQKEY('mentions'))
@@ -80,7 +82,7 @@ export function NotificationsScreen({}: Props) {
[queryClient], [queryClient],
) )
const sections = React.useMemo(() => { const sections = useMemo(() => {
return [ return [
{ {
title: _(msg`All`), title: _(msg`All`),
@@ -186,20 +188,20 @@ function NotificationsTab({
}) { }) {
const {_} = useLingui() const {_} = useLingui()
const setMinimalShellMode = useSetMinimalShellMode() const setMinimalShellMode = useSetMinimalShellMode()
const [isScrolledDown, setIsScrolledDown] = React.useState(false) const [isScrolledDown, setIsScrolledDown] = useState(false)
const scrollElRef = React.useRef<ListMethods>(null) const scrollElRef = useRef<ListMethods>(null)
const queryClient = useQueryClient() const queryClient = useQueryClient()
const isScreenFocused = useIsFocused() const isScreenFocused = useIsFocused()
const isFocusedAndActive = isScreenFocused && isActive const isFocusedAndActive = isScreenFocused && isActive
// event handlers // event handlers
// = // =
const scrollToTop = React.useCallback(() => { const scrollToTop = useCallback(() => {
scrollElRef.current?.scrollToOffset({animated: isNative, offset: 0}) scrollElRef.current?.scrollToOffset({animated: isNative, offset: 0})
setMinimalShellMode(false) setMinimalShellMode(false)
}, [scrollElRef, setMinimalShellMode]) }, [scrollElRef, setMinimalShellMode])
const onPressLoadLatest = React.useCallback(() => { const onPressLoadLatest = useCallback(() => {
scrollToTop() scrollToTop()
if (hasNew) { if (hasNew) {
// render what we have now // render what we have now
@@ -238,7 +240,7 @@ function NotificationsTab({
// on-visible setup // on-visible setup
// = // =
useFocusEffect( useFocusEffect(
React.useCallback(() => { useCallback(() => {
if (isFocusedAndActive) { if (isFocusedAndActive) {
setMinimalShellMode(false) setMinimalShellMode(false)
logger.debug('NotificationsScreen: Focus') logger.debug('NotificationsScreen: Focus')
@@ -246,7 +248,8 @@ function NotificationsTab({
} }
}, [setMinimalShellMode, onFocusCheckLatest, isFocusedAndActive]), }, [setMinimalShellMode, onFocusCheckLatest, isFocusedAndActive]),
) )
React.useEffect(() => {
useEffect(() => {
if (!isFocusedAndActive) { if (!isFocusedAndActive) {
return return
} }
@@ -262,6 +265,11 @@ function NotificationsTab({
refreshNotifications={() => checkUnread({invalidate: true})} refreshNotifications={() => checkUnread({invalidate: true})}
onScrolledDownChange={setIsScrolledDown} onScrolledDownChange={setIsScrolledDown}
scrollElRef={scrollElRef} scrollElRef={scrollElRef}
ListHeaderComponent={
filter === 'mentions' ? (
<DisabledNotificationsWarning active={isFocusedAndActive} />
) : null
}
/> />
</MainScrollProvider> </MainScrollProvider>
{(isScrolledDown || hasNew) && ( {(isScrolledDown || hasNew) && (
@@ -274,3 +282,26 @@ function NotificationsTab({
</> </>
) )
} }
function DisabledNotificationsWarning({active}: {active: boolean}) {
const t = useTheme()
const [hasBeenActive, setHasBeenActive] = useState(false)
const {data} = useNotificationSettingsQuery({enabled: hasBeenActive})
if (active && !hasBeenActive) {
setHasBeenActive(true)
}
if (!data) return null
return (
<View style={[a.py_md, a.px_lg, a.border_b, t.atoms.border_contrast_low]}>
<Admonition type="warning">
<Trans>
You have completely disabled reply, quote, and mention notifications,
so this tab will no longer update.
</Trans>
</Admonition>
</View>
)
}