Skip to content

Commit

Permalink
Move muted threads to new persistence + context
Browse files Browse the repository at this point in the history
  • Loading branch information
pfrazee committed Nov 8, 2023
1 parent 4afed4b commit 4b07398
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 94 deletions.
5 changes: 4 additions & 1 deletion src/App.native.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import * as Toast from 'view/com/util/Toast'
import {queryClient} from 'lib/react-query'
import {TestCtrls} from 'view/com/testing/TestCtrls'
import {Provider as ShellStateProvider} from 'state/shell'
import {Provider as MutedThreadsProvider} from 'state/muted-threads'

SplashScreen.preventAutoHideAsync()

Expand Down Expand Up @@ -78,7 +79,9 @@ function App() {

return (
<ShellStateProvider>
<InnerApp />
<MutedThreadsProvider>
<InnerApp />
</MutedThreadsProvider>
</ShellStateProvider>
)
}
Expand Down
5 changes: 4 additions & 1 deletion src/App.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {ToastContainer} from 'view/com/util/Toast.web'
import {ThemeProvider} from 'lib/ThemeContext'
import {queryClient} from 'lib/react-query'
import {Provider as ShellStateProvider} from 'state/shell'
import {Provider as MutedThreadsProvider} from 'state/muted-threads'

const InnerApp = observer(function AppImpl() {
const colorMode = useColorMode()
Expand Down Expand Up @@ -68,7 +69,9 @@ function App() {

return (
<ShellStateProvider>
<InnerApp />
<MutedThreadsProvider>
<InnerApp />
</MutedThreadsProvider>
</ShellStateProvider>
)
}
Expand Down
8 changes: 0 additions & 8 deletions src/state/models/content/post-thread-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ export class PostThreadItemModel {
return this.post.uri
}

get isThreadMuted() {
return this.data.isThreadMuted
}

get moderation(): PostModeration {
return this.data.moderation
}
Expand Down Expand Up @@ -129,10 +125,6 @@ export class PostThreadItemModel {
this.data.toggleRepost()
}

async toggleThreadMute() {
this.data.toggleThreadMute()
}

async delete() {
this.data.delete()
}
Expand Down
12 changes: 0 additions & 12 deletions src/state/models/content/post-thread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
// =

Expand Down
4 changes: 2 additions & 2 deletions src/state/models/feeds/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
})
Expand Down
18 changes: 0 additions & 18 deletions src/state/models/feeds/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
Expand Down
29 changes: 0 additions & 29 deletions src/state/models/muted-threads.ts

This file was deleted.

6 changes: 0 additions & 6 deletions src/state/models/root-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -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
Expand All @@ -71,7 +69,6 @@ export class RootStoreModel {
me: this.me.serialize(),
preferences: this.preferences.serialize(),
invitedUsers: this.invitedUsers.serialize(),
mutedThreads: this.mutedThreads.serialize(),
}
}

Expand All @@ -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)
}
}
}

Expand Down
59 changes: 59 additions & 0 deletions src/state/muted-threads.tsx
Original file line number Diff line number Diff line change
@@ -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)
}
17 changes: 10 additions & 7 deletions src/view/com/post-thread/PostThreadItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {makeProfileLink} from 'lib/routes/links'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {MAX_POST_LINES} from 'lib/constants'
import {logger} from '#/logger'
import {useMutedThreads, useToggleThreadMute} from '#/state/muted-threads'

export const PostThreadItem = observer(function PostThreadItem({
item,
Expand All @@ -51,6 +52,8 @@ export const PostThreadItem = observer(function PostThreadItem({
}) {
const pal = usePalette('default')
const store = useStores()
const mutedThreads = useMutedThreads()
const toggleThreadMute = useToggleThreadMute()
const [deleted, setDeleted] = React.useState(false)
const [limitLines, setLimitLines] = React.useState(
countLines(item.richText?.text) >= MAX_POST_LINES,
Expand Down Expand Up @@ -130,18 +133,18 @@ export const PostThreadItem = observer(function PostThreadItem({
Linking.openURL(translatorUrl)
}, [translatorUrl])

const onToggleThreadMute = React.useCallback(async () => {
const onToggleThreadMute = React.useCallback(() => {
try {
await item.toggleThreadMute()
if (item.isThreadMuted) {
const muted = toggleThreadMute(item.data.rootUri)
if (muted) {
Toast.show('You will no longer receive notifications for this thread')
} else {
Toast.show('You will now receive notifications for this thread')
}
} catch (e) {
logger.error('Failed to toggle thread mute', {error: e})
}
}, [item])
}, [item, toggleThreadMute])

const onDeletePost = React.useCallback(() => {
item.delete().then(
Expand Down Expand Up @@ -284,7 +287,7 @@ export const PostThreadItem = observer(function PostThreadItem({
itemHref={itemHref}
itemTitle={itemTitle}
isAuthor={item.post.author.did === store.me.did}
isThreadMuted={item.isThreadMuted}
isThreadMuted={mutedThreads.includes(item.data.rootUri)}
onCopyPostText={onCopyPostText}
onOpenTranslate={onOpenTranslate}
onToggleThreadMute={onToggleThreadMute}
Expand Down Expand Up @@ -391,7 +394,7 @@ export const PostThreadItem = observer(function PostThreadItem({
isAuthor={item.post.author.did === store.me.did}
isReposted={!!item.post.viewer?.repost}
isLiked={!!item.post.viewer?.like}
isThreadMuted={item.isThreadMuted}
isThreadMuted={mutedThreads.includes(item.data.rootUri)}
onPressReply={onPressReply}
onPressToggleRepost={onPressToggleRepost}
onPressToggleLike={onPressToggleLike}
Expand Down Expand Up @@ -534,7 +537,7 @@ export const PostThreadItem = observer(function PostThreadItem({
likeCount={item.post.likeCount}
isReposted={!!item.post.viewer?.repost}
isLiked={!!item.post.viewer?.like}
isThreadMuted={item.isThreadMuted}
isThreadMuted={mutedThreads.includes(item.data.rootUri)}
onPressReply={onPressReply}
onPressToggleRepost={onPressToggleRepost}
onPressToggleLike={onPressToggleLike}
Expand Down
13 changes: 8 additions & 5 deletions src/view/com/post/Post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {makeProfileLink} from 'lib/routes/links'
import {MAX_POST_LINES} from 'lib/constants'
import {countLines} from 'lib/strings/helpers'
import {logger} from '#/logger'
import {useMutedThreads, useToggleThreadMute} from '#/state/muted-threads'

export const Post = observer(function PostImpl({
view,
Expand Down Expand Up @@ -106,6 +107,8 @@ const PostLoaded = observer(function PostLoadedImpl({
}) {
const pal = usePalette('default')
const store = useStores()
const mutedThreads = useMutedThreads()
const toggleThreadMute = useToggleThreadMute()
const [limitLines, setLimitLines] = React.useState(
countLines(item.richText?.text) >= MAX_POST_LINES,
)
Expand Down Expand Up @@ -161,18 +164,18 @@ const PostLoaded = observer(function PostLoadedImpl({
Linking.openURL(translatorUrl)
}, [translatorUrl])

const onToggleThreadMute = React.useCallback(async () => {
const onToggleThreadMute = React.useCallback(() => {
try {
await item.toggleThreadMute()
if (item.isThreadMuted) {
const muted = toggleThreadMute(item.data.rootUri)
if (muted) {
Toast.show('You will no longer receive notifications for this thread')
} else {
Toast.show('You will now receive notifications for this thread')
}
} catch (e) {
logger.error('Failed to toggle thread mute', {error: e})
}
}, [item])
}, [item, toggleThreadMute])

const onDeletePost = React.useCallback(() => {
item.delete().then(
Expand Down Expand Up @@ -286,7 +289,7 @@ const PostLoaded = observer(function PostLoadedImpl({
likeCount={item.post.likeCount}
isReposted={!!item.post.viewer?.repost}
isLiked={!!item.post.viewer?.like}
isThreadMuted={item.isThreadMuted}
isThreadMuted={mutedThreads.includes(item.data.rootUri)}
onPressReply={onPressReply}
onPressToggleRepost={onPressToggleRepost}
onPressToggleLike={onPressToggleLike}
Expand Down
Loading

0 comments on commit 4b07398

Please sign in to comment.