Move muted threads to new persistence + context (#1838)
This commit is contained in:
parent
4afed4be28
commit
74f8390f1d
12 changed files with 95 additions and 94 deletions
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
// =
|
||||
|
||||
|
|
|
@ -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
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
59
src/state/muted-threads.tsx
Normal file
59
src/state/muted-threads.tsx
Normal file
|
@ -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)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue