diff options
Diffstat (limited to 'src/state')
-rw-r--r-- | src/state/models/content/post-thread-item.ts | 8 | ||||
-rw-r--r-- | src/state/models/content/post-thread.ts | 12 | ||||
-rw-r--r-- | src/state/models/feeds/notifications.ts | 4 | ||||
-rw-r--r-- | src/state/models/feeds/post.ts | 18 | ||||
-rw-r--r-- | src/state/models/muted-threads.ts | 29 | ||||
-rw-r--r-- | src/state/models/root-store.ts | 6 | ||||
-rw-r--r-- | src/state/muted-threads.tsx | 59 |
7 files changed, 61 insertions, 75 deletions
diff --git a/src/state/models/content/post-thread-item.ts b/src/state/models/content/post-thread-item.ts index 942f3acc8..855b038c4 100644 --- a/src/state/models/content/post-thread-item.ts +++ b/src/state/models/content/post-thread-item.ts @@ -63,10 +63,6 @@ export class PostThreadItemModel { return this.post.uri } - get isThreadMuted() { - return this.data.isThreadMuted - } - get moderation(): PostModeration { return this.data.moderation } @@ -129,10 +125,6 @@ export class PostThreadItemModel { this.data.toggleRepost() } - async toggleThreadMute() { - this.data.toggleThreadMute() - } - async delete() { this.data.delete() } diff --git a/src/state/models/content/post-thread.ts b/src/state/models/content/post-thread.ts index fd194056a..65e74f7ce 100644 --- a/src/state/models/content/post-thread.ts +++ b/src/state/models/content/post-thread.ts @@ -74,10 +74,6 @@ export class PostThreadModel { return this.resolvedUri } - get isThreadMuted() { - return this.rootStore.mutedThreads.uris.has(this.rootUri) - } - get isCachedPostAReply() { if (AppBskyFeedPost.isRecord(this.thread?.post.record)) { return !!this.thread?.post.record.reply @@ -140,14 +136,6 @@ export class PostThreadModel { this.refresh() } - async toggleThreadMute() { - if (this.isThreadMuted) { - this.rootStore.mutedThreads.uris.delete(this.rootUri) - } else { - this.rootStore.mutedThreads.uris.add(this.rootUri) - } - } - // state transitions // = diff --git a/src/state/models/feeds/notifications.ts b/src/state/models/feeds/notifications.ts index 607e3038b..272d52881 100644 --- a/src/state/models/feeds/notifications.ts +++ b/src/state/models/feeds/notifications.ts @@ -18,6 +18,7 @@ import {RootStoreModel} from '../root-store' import {PostThreadModel} from '../content/post-thread' import {cleanError} from 'lib/strings/errors' import {logger} from '#/logger' +import {isThreadMuted} from '#/state/muted-threads' const GROUPABLE_REASONS = ['like', 'repost', 'follow'] const PAGE_SIZE = 30 @@ -550,8 +551,7 @@ export class NotificationsFeedModel { .filter(item => { const hideByLabel = item.shouldFilter let mutedThread = !!( - item.reasonSubjectRootUri && - this.rootStore.mutedThreads.uris.has(item.reasonSubjectRootUri) + item.reasonSubjectRootUri && isThreadMuted(item.reasonSubjectRootUri) ) return !hideByLabel && !mutedThread }) diff --git a/src/state/models/feeds/post.ts b/src/state/models/feeds/post.ts index d064edc21..4fa1213b5 100644 --- a/src/state/models/feeds/post.ts +++ b/src/state/models/feeds/post.ts @@ -75,10 +75,6 @@ export class PostsFeedItemModel { return this.post.uri } - get isThreadMuted() { - return this.rootStore.mutedThreads.uris.has(this.rootUri) - } - get moderation(): PostModeration { return moderatePost(this.post, this.rootStore.preferences.moderationOpts) } @@ -172,20 +168,6 @@ export class PostsFeedItemModel { } } - async toggleThreadMute() { - try { - if (this.isThreadMuted) { - this.rootStore.mutedThreads.uris.delete(this.rootUri) - track('Post:ThreadUnmute') - } else { - this.rootStore.mutedThreads.uris.add(this.rootUri) - track('Post:ThreadMute') - } - } catch (error) { - logger.error('Failed to toggle thread mute', {error}) - } - } - async delete() { try { await this.rootStore.agent.deletePost(this.post.uri) diff --git a/src/state/models/muted-threads.ts b/src/state/models/muted-threads.ts deleted file mode 100644 index e6f202745..000000000 --- a/src/state/models/muted-threads.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * This is a temporary client-side system for storing muted threads - * When the system lands on prod we should switch to that - */ - -import {makeAutoObservable} from 'mobx' -import {isObj, hasProp, isStrArray} from 'lib/type-guards' - -export class MutedThreads { - uris: Set<string> = new Set() - - constructor() { - makeAutoObservable( - this, - {serialize: false, hydrate: false}, - {autoBind: true}, - ) - } - - serialize() { - return {uris: Array.from(this.uris)} - } - - hydrate(v: unknown) { - if (isObj(v) && hasProp(v, 'uris') && isStrArray(v.uris)) { - this.uris = new Set(v.uris) - } - } -} diff --git a/src/state/models/root-store.ts b/src/state/models/root-store.ts index f04a9922d..fadd279fc 100644 --- a/src/state/models/root-store.ts +++ b/src/state/models/root-store.ts @@ -19,7 +19,6 @@ import {InvitedUsers} from './invited-users' import {PreferencesModel} from './ui/preferences' import {resetToTab} from '../../Navigation' import {ImageSizesCache} from './cache/image-sizes' -import {MutedThreads} from './muted-threads' import {reset as resetNavigation} from '../../Navigation' import {logger} from '#/logger' @@ -49,7 +48,6 @@ export class RootStoreModel { posts = new PostsCache(this) linkMetas = new LinkMetasCache(this) imageSizes = new ImageSizesCache() - mutedThreads = new MutedThreads() constructor(agent: BskyAgent) { this.agent = agent @@ -71,7 +69,6 @@ export class RootStoreModel { me: this.me.serialize(), preferences: this.preferences.serialize(), invitedUsers: this.invitedUsers.serialize(), - mutedThreads: this.mutedThreads.serialize(), } } @@ -95,9 +92,6 @@ export class RootStoreModel { if (hasProp(v, 'invitedUsers')) { this.invitedUsers.hydrate(v.invitedUsers) } - if (hasProp(v, 'mutedThreads')) { - this.mutedThreads.hydrate(v.mutedThreads) - } } } diff --git a/src/state/muted-threads.tsx b/src/state/muted-threads.tsx new file mode 100644 index 000000000..2b3a7de6a --- /dev/null +++ b/src/state/muted-threads.tsx @@ -0,0 +1,59 @@ +import React from 'react' +import * as persisted from '#/state/persisted' + +type StateContext = persisted.Schema['mutedThreads'] +type ToggleContext = (uri: string) => boolean + +const stateContext = React.createContext<StateContext>( + persisted.defaults.mutedThreads, +) +const toggleContext = React.createContext<ToggleContext>((_: string) => false) + +export function Provider({children}: React.PropsWithChildren<{}>) { + const [state, setState] = React.useState(persisted.get('mutedThreads')) + + const toggleThreadMute = React.useCallback( + (uri: string) => { + let muted = false + setState((arr: string[]) => { + if (arr.includes(uri)) { + arr = arr.filter(v => v !== uri) + muted = false + } else { + arr = arr.concat([uri]) + muted = true + } + persisted.write('mutedThreads', arr) + return arr + }) + return muted + }, + [setState], + ) + + React.useEffect(() => { + return persisted.onUpdate(() => { + setState(persisted.get('mutedThreads')) + }) + }, [setState]) + + return ( + <stateContext.Provider value={state}> + <toggleContext.Provider value={toggleThreadMute}> + {children} + </toggleContext.Provider> + </stateContext.Provider> + ) +} + +export function useMutedThreads() { + return React.useContext(stateContext) +} + +export function useToggleThreadMute() { + return React.useContext(toggleContext) +} + +export function isThreadMuted(uri: string) { + return persisted.get('mutedThreads').includes(uri) +} |