Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More prefs cleanup #1882

Merged
merged 5 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 0 additions & 51 deletions src/lib/hooks/useDesktopRightNavItems.ts

This file was deleted.

29 changes: 0 additions & 29 deletions src/lib/hooks/useHomeTabs.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/state/models/content/feed-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class FeedSourceModel {
}

get isPinned() {
return this.rootStore.preferences.isPinnedFeed(this.uri)
return false
}

get isLiked() {
Expand Down
18 changes: 2 additions & 16 deletions src/state/models/ui/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
BskyFeedViewPreference,
BskyThreadViewPreference,
} from '@atproto/api'
import AwaitLock from 'await-lock'
import {isObj, hasProp} from 'lib/type-guards'
import {RootStoreModel} from '../root-store'
import {ModerationOpts} from '@atproto/api'
Expand Down Expand Up @@ -33,30 +32,17 @@ export class LabelPreferencesModel {
}

export class PreferencesModel {
adultContentEnabled = false
contentLabels = new LabelPreferencesModel()
savedFeeds: string[] = []
pinnedFeeds: string[] = []
birthDate: Date | undefined = undefined
homeFeed: FeedViewPreference = {
hideReplies: false,
hideRepliesByUnfollowed: false,
hideRepliesByLikeCount: 0,
hideReposts: false,
hideQuotePosts: false,
lab_mergeFeedEnabled: false, // experimental
}
thread: ThreadViewPreference = {
sort: 'oldest',
prioritizeFollowedUsers: true,
lab_treeViewEnabled: false, // experimental
}

// used to linearize async modifications to state
lock = new AwaitLock()

constructor(public rootStore: RootStoreModel) {
makeAutoObservable(this, {lock: false}, {autoBind: true})
makeAutoObservable(this, {}, {autoBind: true})
}

serialize() {
Expand Down Expand Up @@ -106,7 +92,7 @@ export class PreferencesModel {
get moderationOpts(): ModerationOpts {
return {
userDid: this.rootStore.session.currentSession?.did || '',
adultContentEnabled: this.adultContentEnabled,
adultContentEnabled: false,
labels: {
// TEMP translate old settings until this UI can be migrated -prf
porn: tempfixLabelPref(this.contentLabels.nsfw),
Expand Down
132 changes: 121 additions & 11 deletions src/state/queries/feed.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React from 'react'
import {
useQuery,
useInfiniteQuery,
InfiniteData,
QueryKey,
useMutation,
useQueryClient,
} from '@tanstack/react-query'
import {
AtUri,
Expand All @@ -13,16 +15,22 @@ import {
AppBskyUnspeccedGetPopularFeedGenerators,
} from '@atproto/api'

import {router} from '#/routes'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
import {useSession} from '#/state/session'
import {usePreferencesQuery} from '#/state/queries/preferences'

type FeedSourceInfo =
export type FeedSourceInfo =
| {
type: 'feed'
uri: string
route: {
href: string
name: string
params: Record<string, string>
}
cid: string
href: string
avatar: string | undefined
displayName: string
description: RichText
Expand All @@ -34,16 +42,20 @@ type FeedSourceInfo =
| {
type: 'list'
uri: string
route: {
href: string
name: string
params: Record<string, string>
}
cid: string
href: string
avatar: string | undefined
displayName: string
description: RichText
creatorDid: string
creatorHandle: string
}

export const useFeedSourceInfoQueryKey = ({uri}: {uri: string}) => [
export const feedSourceInfoQueryKey = ({uri}: {uri: string}) => [
'getFeedSourceInfo',
uri,
]
Expand All @@ -53,19 +65,24 @@ const feedSourceNSIDs = {
list: 'app.bsky.graph.list',
}

function hydrateFeedGenerator(
export function hydrateFeedGenerator(
view: AppBskyFeedDefs.GeneratorView,
): FeedSourceInfo {
const urip = new AtUri(view.uri)
const collection =
urip.collection === 'app.bsky.feed.generator' ? 'feed' : 'lists'
const href = `/profile/${urip.hostname}/${collection}/${urip.rkey}`
const route = router.matchPath(href)

return {
type: 'feed',
uri: view.uri,
cid: view.cid,
href,
route: {
href,
name: route[0],
params: route[1],
},
avatar: view.avatar,
displayName: view.displayName
? sanitizeDisplayName(view.displayName)
Expand All @@ -81,17 +98,22 @@ function hydrateFeedGenerator(
}
}

function hydrateList(view: AppBskyGraphDefs.ListView): FeedSourceInfo {
export function hydrateList(view: AppBskyGraphDefs.ListView): FeedSourceInfo {
const urip = new AtUri(view.uri)
const collection =
urip.collection === 'app.bsky.feed.generator' ? 'feed' : 'lists'
const href = `/profile/${urip.hostname}/${collection}/${urip.rkey}`
const route = router.matchPath(href)

return {
type: 'list',
uri: view.uri,
route: {
href,
name: route[0],
params: route[1],
},
cid: view.cid,
href,
avatar: view.avatar,
description: new RichText({
text: view.description || '',
Expand All @@ -105,13 +127,17 @@ function hydrateList(view: AppBskyGraphDefs.ListView): FeedSourceInfo {
}
}

export function getFeedTypeFromUri(uri: string) {
const {pathname} = new AtUri(uri)
return pathname.includes(feedSourceNSIDs.feed) ? 'feed' : 'list'
}

export function useFeedSourceInfoQuery({uri}: {uri: string}) {
const {agent} = useSession()
const {pathname} = new AtUri(uri)
const type = pathname.includes(feedSourceNSIDs.feed) ? 'feed' : 'list'
const type = getFeedTypeFromUri(uri)

return useQuery({
queryKey: useFeedSourceInfoQueryKey({uri}),
queryKey: feedSourceInfoQueryKey({uri}),
queryFn: async () => {
let view: FeedSourceInfo

Expand Down Expand Up @@ -170,3 +196,87 @@ export function useSearchPopularFeedsMutation() {
},
})
}

const FOLLOWING_FEED_STUB: FeedSourceInfo = {
type: 'feed',
displayName: 'Following',
uri: '',
route: {
href: '/',
name: 'Home',
params: {},
},
cid: '',
avatar: '',
description: new RichText({text: ''}),
creatorDid: '',
creatorHandle: '',
likeCount: 0,
likeUri: '',
}

export function usePinnedFeedsInfos(): FeedSourceInfo[] {
const {agent} = useSession()
const queryClient = useQueryClient()
const [tabs, setTabs] = React.useState<FeedSourceInfo[]>([
FOLLOWING_FEED_STUB,
])
const {data: preferences} = usePreferencesQuery()
const pinnedFeedsKey = JSON.stringify(preferences?.feeds?.pinned)

React.useEffect(() => {
if (!preferences?.feeds?.pinned) return
const uris = preferences.feeds.pinned

async function fetchFeedInfo() {
const reqs = []

for (const uri of uris) {
const cached = queryClient.getQueryData<FeedSourceInfo>(
feedSourceInfoQueryKey({uri}),
)

if (cached) {
reqs.push(cached)
} else {
reqs.push(
queryClient.fetchQuery({
queryKey: feedSourceInfoQueryKey({uri}),
queryFn: async () => {
const type = getFeedTypeFromUri(uri)

if (type === 'feed') {
const res = await agent.app.bsky.feed.getFeedGenerator({
feed: uri,
})
return hydrateFeedGenerator(res.data.view)
} else {
const res = await agent.app.bsky.graph.getList({
list: uri,
limit: 1,
})
return hydrateList(res.data.list)
}
},
}),
)
}
}

const views = await Promise.all(reqs)

setTabs([FOLLOWING_FEED_STUB].concat(views))
}

fetchFeedInfo()
}, [
agent,
queryClient,
setTabs,
preferences?.feeds?.pinned,
// ensure we react to re-ordering
pinnedFeedsKey,
])

return tabs
}
5 changes: 4 additions & 1 deletion src/state/queries/preferences/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
BskyPreferences,
LabelPreference,
BskyThreadViewPreference,
BskyFeedViewPreference,
} from '@atproto/api'

export type ConfigurableLabelGroup =
Expand Down Expand Up @@ -29,7 +30,9 @@ export type UsePreferencesQueryResponse = Omit<
* we clean up the data in `usePreferencesQuery`.
*/
contentLabels: Record<ConfigurableLabelGroup, LabelPreference>
feedViewPrefs: BskyPreferences['feedViewPrefs']['home']
feedViewPrefs: BskyFeedViewPreference & {
lab_mergeFeedEnabled: boolean
}
/**
* User thread-view prefs, including newer fields that may not be typed yet.
*/
Expand Down
Loading
Loading