diff options
Diffstat (limited to 'src/state/queries')
-rw-r--r-- | src/state/queries/notifications/feed.ts | 3 | ||||
-rw-r--r-- | src/state/queries/notifications/unread.tsx | 5 | ||||
-rw-r--r-- | src/state/queries/notifications/util.ts | 50 | ||||
-rw-r--r-- | src/state/queries/post.ts | 70 |
4 files changed, 71 insertions, 57 deletions
diff --git a/src/state/queries/notifications/feed.ts b/src/state/queries/notifications/feed.ts index d9f019af3..0607f07a1 100644 --- a/src/state/queries/notifications/feed.ts +++ b/src/state/queries/notifications/feed.ts @@ -26,7 +26,6 @@ import { useQueryClient, } from '@tanstack/react-query' -import {useMutedThreads} from '#/state/muted-threads' import {useAgent} from '#/state/session' import {useModerationOpts} from '../../preferences/moderation-opts' import {STALE} from '..' @@ -54,7 +53,6 @@ export function useNotificationFeedQuery(opts?: {enabled?: boolean}) { const agent = useAgent() const queryClient = useQueryClient() const moderationOpts = useModerationOpts() - const threadMutes = useMutedThreads() const unreads = useUnreadNotificationsApi() const enabled = opts?.enabled !== false const lastPageCountRef = useRef(0) @@ -82,7 +80,6 @@ export function useNotificationFeedQuery(opts?: {enabled?: boolean}) { cursor: pageParam, queryClient, moderationOpts, - threadMutes, fetchAdditionalData: true, }) ).page diff --git a/src/state/queries/notifications/unread.tsx b/src/state/queries/notifications/unread.tsx index ffb8d03bc..7bb325ea9 100644 --- a/src/state/queries/notifications/unread.tsx +++ b/src/state/queries/notifications/unread.tsx @@ -9,7 +9,6 @@ import EventEmitter from 'eventemitter3' import BroadcastChannel from '#/lib/broadcast' import {logger} from '#/logger' -import {useMutedThreads} from '#/state/muted-threads' import {useAgent, useSession} from '#/state/session' import {resetBadgeCount} from 'lib/notifications/notifications' import {useModerationOpts} from '../../preferences/moderation-opts' @@ -48,7 +47,6 @@ export function Provider({children}: React.PropsWithChildren<{}>) { const agent = useAgent() const queryClient = useQueryClient() const moderationOpts = useModerationOpts() - const threadMutes = useMutedThreads() const [numUnread, setNumUnread] = React.useState('') @@ -147,7 +145,6 @@ export function Provider({children}: React.PropsWithChildren<{}>) { limit: 40, queryClient, moderationOpts, - threadMutes, // only fetch subjects when the page is going to be used // in the notifications query, otherwise skip it @@ -192,7 +189,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } }, } - }, [setNumUnread, queryClient, moderationOpts, threadMutes, agent]) + }, [setNumUnread, queryClient, moderationOpts, agent]) checkUnreadRef.current = api.checkUnread return ( diff --git a/src/state/queries/notifications/util.ts b/src/state/queries/notifications/util.ts index 466249353..8ed1c0390 100644 --- a/src/state/queries/notifications/util.ts +++ b/src/state/queries/notifications/util.ts @@ -1,5 +1,4 @@ import { - AppBskyEmbedRecord, AppBskyFeedDefs, AppBskyFeedLike, AppBskyFeedPost, @@ -28,7 +27,6 @@ export async function fetchPage({ limit, queryClient, moderationOpts, - threadMutes, fetchAdditionalData, }: { agent: BskyAgent @@ -36,7 +34,6 @@ export async function fetchPage({ limit: number queryClient: QueryClient moderationOpts: ModerationOpts | undefined - threadMutes: string[] fetchAdditionalData: boolean }): Promise<{page: FeedPage; indexedAt: string | undefined}> { const res = await agent.listNotifications({ @@ -67,11 +64,6 @@ export async function fetchPage({ } } - // apply thread muting - notifsGrouped = notifsGrouped.filter( - notif => !isThreadMuted(notif, threadMutes), - ) - let seenAt = res.data.seenAt ? new Date(res.data.seenAt) : new Date() if (Number.isNaN(seenAt.getTime())) { seenAt = new Date() @@ -207,45 +199,3 @@ function getSubjectUri( return notif.reasonSubject } } - -export function isThreadMuted(notif: FeedNotification, threadMutes: string[]) { - // If there's a subject we want to use that. This will always work on the notifications tab - if (notif.subject) { - const record = notif.subject.record as AppBskyFeedPost.Record - // Check for a quote record - if ( - (record.reply && threadMutes.includes(record.reply.root.uri)) || - (notif.subject.uri && threadMutes.includes(notif.subject.uri)) - ) { - return true - } else if ( - AppBskyEmbedRecord.isMain(record.embed) && - threadMutes.includes(record.embed.record.uri) - ) { - return true - } - } else { - // Otherwise we just do the best that we can - const record = notif.notification.record - if (AppBskyFeedPost.isRecord(record)) { - if (record.reply && threadMutes.includes(record.reply.root.uri)) { - // We can always filter replies - return true - } else if ( - AppBskyEmbedRecord.isMain(record.embed) && - threadMutes.includes(record.embed.record.uri) - ) { - // We can also filter quotes if the quoted post is the root - return true - } - } else if ( - AppBskyFeedRepost.isRecord(record) && - threadMutes.includes(record.subject.uri) - ) { - // Finally we can filter reposts, again if the post is the root - return true - } - } - - return false -} diff --git a/src/state/queries/post.ts b/src/state/queries/post.ts index 794f48eb1..8e77bf6b9 100644 --- a/src/state/queries/post.ts +++ b/src/state/queries/post.ts @@ -8,6 +8,7 @@ import {logEvent, LogEvents, toClout} from '#/lib/statsig/statsig' import {updatePostShadow} from '#/state/cache/post-shadow' import {Shadow} from '#/state/cache/types' import {useAgent, useSession} from '#/state/session' +import {useIsThreadMuted, useSetThreadMute} from '../cache/thread-mutes' import {findProfileQueryData} from './profile' const RQKEY_ROOT = 'post' @@ -291,3 +292,72 @@ export function usePostDeleteMutation() { }, }) } + +export function useThreadMuteMutationQueue( + post: Shadow<AppBskyFeedDefs.PostView>, + rootUri: string, +) { + const threadMuteMutation = useThreadMuteMutation() + const threadUnmuteMutation = useThreadUnmuteMutation() + const isThreadMuted = useIsThreadMuted(rootUri, post.viewer?.threadMuted) + const setThreadMute = useSetThreadMute() + + const queueToggle = useToggleMutationQueue<boolean>({ + initialState: isThreadMuted, + runMutation: async (_prev, shouldLike) => { + if (shouldLike) { + await threadMuteMutation.mutateAsync({ + uri: rootUri, + }) + return true + } else { + await threadUnmuteMutation.mutateAsync({ + uri: rootUri, + }) + return false + } + }, + onSuccess(finalIsMuted) { + // finalize + setThreadMute(rootUri, finalIsMuted) + }, + }) + + const queueMuteThread = useCallback(() => { + // optimistically update + setThreadMute(rootUri, true) + return queueToggle(true) + }, [setThreadMute, rootUri, queueToggle]) + + const queueUnmuteThread = useCallback(() => { + // optimistically update + setThreadMute(rootUri, false) + return queueToggle(false) + }, [rootUri, setThreadMute, queueToggle]) + + return [isThreadMuted, queueMuteThread, queueUnmuteThread] as const +} + +function useThreadMuteMutation() { + const agent = useAgent() + return useMutation< + {}, + Error, + {uri: string} // the root post's uri + >({ + mutationFn: ({uri}) => { + logEvent('post:mute', {}) + return agent.api.app.bsky.graph.muteThread({root: uri}) + }, + }) +} + +function useThreadUnmuteMutation() { + const agent = useAgent() + return useMutation<{}, Error, {uri: string}>({ + mutationFn: ({uri}) => { + logEvent('post:unmute', {}) + return agent.api.app.bsky.graph.unmuteThread({root: uri}) + }, + }) +} |