Merge remote-tracking branch 'origin/main' into hailey/embed-pack
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import React, {useCallback} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {FeedDescriptor} from '#/state/queries/post-feed'
|
||||
import {isNative} from 'platform/detection'
|
||||
import {Feed} from 'view/com/posts/Feed'
|
||||
import {EmptyState} from 'view/com/util/EmptyState'
|
||||
import {ListRef} from 'view/com/util/List'
|
||||
import {SectionRef} from '#/screens/Profile/Sections/types'
|
||||
|
||||
interface ProfilesListProps {
|
||||
listUri: string
|
||||
headerHeight: number
|
||||
scrollElRef: ListRef
|
||||
}
|
||||
|
||||
export const PostsList = React.forwardRef<SectionRef, ProfilesListProps>(
|
||||
function PostsListImpl({listUri, headerHeight, scrollElRef}, ref) {
|
||||
const feed: FeedDescriptor = `list|${listUri}|as_following`
|
||||
const {_} = useLingui()
|
||||
|
||||
const onScrollToTop = useCallback(() => {
|
||||
scrollElRef.current?.scrollToOffset({
|
||||
animated: isNative,
|
||||
offset: -headerHeight,
|
||||
})
|
||||
}, [scrollElRef, headerHeight])
|
||||
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
scrollToTop: onScrollToTop,
|
||||
}))
|
||||
|
||||
const renderPostsEmpty = useCallback(() => {
|
||||
return <EmptyState icon="hashtag" message={_(msg`This feed is empty.`)} />
|
||||
}, [_])
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Feed
|
||||
feed={feed}
|
||||
pollInterval={60e3}
|
||||
scrollElRef={scrollElRef}
|
||||
renderEmptyState={renderPostsEmpty}
|
||||
headerOffset={headerHeight}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -232,11 +232,13 @@ function Empty() {
|
||||
t.atoms.text_contrast_medium,
|
||||
{color: 'white'},
|
||||
]}>
|
||||
You haven't created a starter pack yet!
|
||||
<Trans>You haven't created a starter pack yet!</Trans>
|
||||
</Text>
|
||||
<Text style={[a.text_md, {color: 'white'}]}>
|
||||
Starter packs let you easily share your favorite feeds and people with
|
||||
your friends.
|
||||
<Trans>
|
||||
Starter packs let you easily share your favorite feeds and people
|
||||
with your friends.
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
<View style={[a.flex_row, a.gap_md, {marginLeft: 'auto'}]}>
|
||||
|
||||
+360
-256
File diff suppressed because it is too large
Load Diff
+360
-256
File diff suppressed because it is too large
Load Diff
+359
-255
File diff suppressed because it is too large
Load Diff
+360
-256
File diff suppressed because it is too large
Load Diff
+360
-256
File diff suppressed because it is too large
Load Diff
+300
-256
File diff suppressed because it is too large
Load Diff
+360
-256
File diff suppressed because it is too large
Load Diff
+359
-259
File diff suppressed because it is too large
Load Diff
+360
-256
File diff suppressed because it is too large
Load Diff
+360
-256
File diff suppressed because it is too large
Load Diff
+289
-248
File diff suppressed because it is too large
Load Diff
+351
-257
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+360
-256
File diff suppressed because it is too large
Load Diff
+360
-256
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {Linking, View} from 'react-native'
|
||||
import {useSafeAreaFrame} from 'react-native-safe-area-context'
|
||||
import {ComAtprotoLabelDefs} from '@atproto/api'
|
||||
import {LABELS} from '@atproto/api'
|
||||
@@ -10,6 +10,7 @@ import {useFocusEffect} from '@react-navigation/native'
|
||||
import {getLabelingServiceTitle} from '#/lib/moderation'
|
||||
import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
|
||||
import {logger} from '#/logger'
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {
|
||||
useMyLabelersQuery,
|
||||
usePreferencesQuery,
|
||||
@@ -202,6 +203,8 @@ export function ModerationScreenInner({
|
||||
[setAdultContentPref],
|
||||
)
|
||||
|
||||
const disabledOnIOS = isIOS && !adultContentEnabled
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
contentContainerStyle={[
|
||||
@@ -324,12 +327,14 @@ export function ModerationScreenInner({
|
||||
a.flex_row,
|
||||
a.align_center,
|
||||
a.justify_between,
|
||||
disabledOnIOS && {opacity: 0.5},
|
||||
]}>
|
||||
<Text style={[a.font_semibold, t.atoms.text_contrast_high]}>
|
||||
<Trans>Enable adult content</Trans>
|
||||
</Text>
|
||||
<Toggle.Item
|
||||
label={_(msg`Toggle to enable or disable adult content`)}
|
||||
disabled={disabledOnIOS}
|
||||
name="adultContent"
|
||||
value={adultContentEnabled}
|
||||
onChange={onToggleAdultContentEnabled}>
|
||||
@@ -345,6 +350,25 @@ export function ModerationScreenInner({
|
||||
</View>
|
||||
</Toggle.Item>
|
||||
</View>
|
||||
{disabledOnIOS && (
|
||||
<View style={[a.pb_lg, a.px_lg]}>
|
||||
<Text>
|
||||
<Trans>
|
||||
Adult content can only be enabled via the Web at{' '}
|
||||
<InlineLinkText
|
||||
to=""
|
||||
onPress={evt => {
|
||||
evt.preventDefault()
|
||||
Linking.openURL('https://bsky.app/')
|
||||
return false
|
||||
}}>
|
||||
bsky.app
|
||||
</InlineLinkText>
|
||||
.
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
<Divider />
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import React from 'react'
|
||||
import {View, ViewStyle, TextStyle} from 'react-native'
|
||||
import {TextStyle, View, ViewStyle} from 'react-native'
|
||||
|
||||
import {useTheme, atoms as a, native} from '#/alf'
|
||||
import {capitalize} from '#/lib/strings/capitalize'
|
||||
import {useInterestsDisplayNames} from '#/screens/Onboarding/state'
|
||||
import {atoms as a, native, useTheme} from '#/alf'
|
||||
import * as Toggle from '#/components/forms/Toggle'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {capitalize} from '#/lib/strings/capitalize'
|
||||
|
||||
import {Context} from '#/screens/Onboarding/state'
|
||||
|
||||
export function InterestButton({interest}: {interest: string}) {
|
||||
const t = useTheme()
|
||||
const {interestsDisplayNames} = React.useContext(Context)
|
||||
const interestsDisplayNames = useInterestsDisplayNames()
|
||||
const ctx = Toggle.useItemContext()
|
||||
|
||||
const styles = React.useMemo(() => {
|
||||
|
||||
@@ -15,7 +15,11 @@ import {
|
||||
OnboardingControls,
|
||||
TitleText,
|
||||
} from '#/screens/Onboarding/Layout'
|
||||
import {ApiResponseMap, Context} from '#/screens/Onboarding/state'
|
||||
import {
|
||||
ApiResponseMap,
|
||||
Context,
|
||||
useInterestsDisplayNames,
|
||||
} from '#/screens/Onboarding/state'
|
||||
import {InterestButton} from '#/screens/Onboarding/StepInterests/InterestButton'
|
||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
@@ -33,8 +37,9 @@ export function StepInterests() {
|
||||
const t = useTheme()
|
||||
const {gtMobile} = useBreakpoints()
|
||||
const {track} = useAnalytics()
|
||||
const interestsDisplayNames = useInterestsDisplayNames()
|
||||
|
||||
const {state, dispatch, interestsDisplayNames} = React.useContext(Context)
|
||||
const {state, dispatch} = React.useContext(Context)
|
||||
const [saving, setSaving] = React.useState(false)
|
||||
const [interests, setInterests] = React.useState<string[]>(
|
||||
state.interestsStepResults.selectedInterests.map(i => i),
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import React from 'react'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {logger} from '#/logger'
|
||||
import {AvatarColor, Emoji} from '#/screens/Onboarding/StepProfile/types'
|
||||
@@ -68,31 +70,36 @@ export type ApiResponseMap = {
|
||||
}
|
||||
}
|
||||
|
||||
export const INTEREST_TO_DISPLAY_NAME_DEFAULTS: {
|
||||
[key: string]: string
|
||||
} = {
|
||||
news: 'News',
|
||||
journalism: 'Journalism',
|
||||
nature: 'Nature',
|
||||
art: 'Art',
|
||||
comics: 'Comics',
|
||||
writers: 'Writers',
|
||||
culture: 'Culture',
|
||||
sports: 'Sports',
|
||||
pets: 'Pets',
|
||||
animals: 'Animals',
|
||||
books: 'Books',
|
||||
education: 'Education',
|
||||
climate: 'Climate',
|
||||
science: 'Science',
|
||||
politics: 'Politics',
|
||||
fitness: 'Fitness',
|
||||
tech: 'Tech',
|
||||
dev: 'Software Dev',
|
||||
comedy: 'Comedy',
|
||||
gaming: 'Video Games',
|
||||
food: 'Food',
|
||||
cooking: 'Cooking',
|
||||
export function useInterestsDisplayNames() {
|
||||
const {_} = useLingui()
|
||||
|
||||
return React.useMemo<Record<string, string>>(() => {
|
||||
return {
|
||||
// Keep this alphabetized
|
||||
animals: _(msg`Animals`),
|
||||
art: _(msg`Art`),
|
||||
books: _(msg`Books`),
|
||||
comedy: _(msg`Comedy`),
|
||||
comics: _(msg`Comics`),
|
||||
culture: _(msg`Culture`),
|
||||
dev: _(msg`Software Dev`),
|
||||
education: _(msg`Education`),
|
||||
food: _(msg`Food`),
|
||||
gaming: _(msg`Video Games`),
|
||||
journalism: _(msg`Journalism`),
|
||||
movies: _(msg`Movies`),
|
||||
nature: _(msg`Nature`),
|
||||
news: _(msg`News`),
|
||||
pets: _(msg`Pets`),
|
||||
photography: _(msg`Photography`),
|
||||
politics: _(msg`Politics`),
|
||||
science: _(msg`Science`),
|
||||
sports: _(msg`Sports`),
|
||||
tech: _(msg`Tech`),
|
||||
tv: _(msg`TV`),
|
||||
writers: _(msg`Writers`),
|
||||
}
|
||||
}, [_])
|
||||
}
|
||||
|
||||
export const initialState: OnboardingState = {
|
||||
@@ -120,11 +127,9 @@ export const initialState: OnboardingState = {
|
||||
export const Context = React.createContext<{
|
||||
state: OnboardingState
|
||||
dispatch: React.Dispatch<OnboardingAction>
|
||||
interestsDisplayNames: {[key: string]: string}
|
||||
}>({
|
||||
state: {...initialState},
|
||||
dispatch: () => {},
|
||||
interestsDisplayNames: INTEREST_TO_DISPLAY_NAME_DEFAULTS,
|
||||
})
|
||||
|
||||
export function reducer(
|
||||
|
||||
@@ -55,6 +55,7 @@ import * as Prompt from '#/components/Prompt'
|
||||
import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog'
|
||||
import {RichText} from '#/components/RichText'
|
||||
import {FeedsList} from '#/components/StarterPack/Main/FeedsList'
|
||||
import {PostsList} from '#/components/StarterPack/Main/PostsList'
|
||||
import {ProfilesList} from '#/components/StarterPack/Main/ProfilesList'
|
||||
import {QrCodeDialog} from '#/components/StarterPack/QrCodeDialog'
|
||||
import {ShareDialog} from '#/components/StarterPack/ShareDialog'
|
||||
@@ -132,9 +133,14 @@ function StarterPackScreenInner({
|
||||
>
|
||||
moderationOpts: ModerationOpts
|
||||
}) {
|
||||
const showPeopleTab = Boolean(starterPack.list)
|
||||
const showFeedsTab = Boolean(starterPack.feeds?.length)
|
||||
const showPostsTab = Boolean(starterPack.list)
|
||||
|
||||
const tabs = [
|
||||
...(starterPack.list ? ['People'] : []),
|
||||
...(starterPack.feeds?.length ? ['Feeds'] : []),
|
||||
...(showPeopleTab ? ['People'] : []),
|
||||
...(showFeedsTab ? ['Feeds'] : []),
|
||||
...(showPostsTab ? ['Posts'] : []),
|
||||
]
|
||||
|
||||
const qrCodeDialogControl = useDialogControl()
|
||||
@@ -180,10 +186,9 @@ function StarterPackScreenInner({
|
||||
onOpenShareDialog={onOpenShareDialog}
|
||||
/>
|
||||
)}>
|
||||
{starterPack.list != null
|
||||
{showPeopleTab
|
||||
? ({headerHeight, scrollElRef}) => (
|
||||
<ProfilesList
|
||||
key={0}
|
||||
// Validated above
|
||||
listUri={starterPack!.list!.uri}
|
||||
headerHeight={headerHeight}
|
||||
@@ -194,10 +199,9 @@ function StarterPackScreenInner({
|
||||
/>
|
||||
)
|
||||
: null}
|
||||
{starterPack.feeds != null
|
||||
{showFeedsTab
|
||||
? ({headerHeight, scrollElRef}) => (
|
||||
<FeedsList
|
||||
key={1}
|
||||
// @ts-expect-error ?
|
||||
feeds={starterPack?.feeds}
|
||||
headerHeight={headerHeight}
|
||||
@@ -206,6 +210,18 @@ function StarterPackScreenInner({
|
||||
/>
|
||||
)
|
||||
: null}
|
||||
{showPostsTab
|
||||
? ({headerHeight, scrollElRef}) => (
|
||||
<PostsList
|
||||
// Validated above
|
||||
listUri={starterPack!.list!.uri}
|
||||
headerHeight={headerHeight}
|
||||
// @ts-expect-error
|
||||
scrollElRef={scrollElRef}
|
||||
moderationOpts={moderationOpts}
|
||||
/>
|
||||
)
|
||||
: null}
|
||||
</PagerWithHeader>
|
||||
</View>
|
||||
|
||||
|
||||
@@ -393,7 +393,6 @@ function Footer({
|
||||
state.currentStep === 'Profiles'
|
||||
? [profile, ...state.profiles]
|
||||
: state.feeds
|
||||
const initialNamesIndex = state.currentStep === 'Profiles' ? 1 : 0
|
||||
|
||||
const isEditEnabled =
|
||||
(state.currentStep === 'Profiles' && items.length > 1) ||
|
||||
@@ -445,65 +444,99 @@ function Footer({
|
||||
))}
|
||||
</View>
|
||||
|
||||
{items.length === 0 ? (
|
||||
<View style={[a.gap_sm]}>
|
||||
<Text style={[a.font_bold, a.text_center, textStyles]}>
|
||||
<Trans>Add some feeds to your starter pack!</Trans>
|
||||
</Text>
|
||||
{
|
||||
state.currentStep === 'Profiles' ? (
|
||||
<Text style={[a.text_center, textStyles]}>
|
||||
<Trans>Search for feeds that you want to suggest to others.</Trans>
|
||||
{
|
||||
items.length < 2 ? (
|
||||
<Trans>
|
||||
It's just you right now! Add more people to your starter pack
|
||||
by searching above.
|
||||
</Trans>
|
||||
) : items.length === 2 ? (
|
||||
<Trans>
|
||||
<Text style={[a.font_bold, textStyles]}>You</Text> and
|
||||
<Text> </Text>
|
||||
<Text style={[a.font_bold, textStyles]}>
|
||||
{getName(items[1] /* [0] is self, skip it */)}{' '}
|
||||
</Text>
|
||||
are included in your starter pack
|
||||
</Trans>
|
||||
) : items.length > 2 ? (
|
||||
<Trans context="profiles">
|
||||
<Text style={[a.font_bold, textStyles]}>
|
||||
{getName(items[1] /* [0] is self, skip it */)},{' '}
|
||||
</Text>
|
||||
<Text style={[a.font_bold, textStyles]}>
|
||||
{getName(items[2])},{' '}
|
||||
</Text>
|
||||
and{' '}
|
||||
<Plural
|
||||
value={items.length - 2}
|
||||
one="# other"
|
||||
other="# others"
|
||||
/>{' '}
|
||||
are included in your starter pack
|
||||
</Trans>
|
||||
) : null /* Should not happen. */
|
||||
}
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
<Text style={[a.text_center, textStyles]}>
|
||||
{state.currentStep === 'Profiles' && items.length === 1 ? (
|
||||
<Trans>
|
||||
It's just you right now! Add more people to your starter pack by
|
||||
searching above.
|
||||
</Trans>
|
||||
) : items.length === 1 ? (
|
||||
<Trans>
|
||||
<Text style={[a.font_bold, textStyles]}>
|
||||
{getName(items[initialNamesIndex])}
|
||||
</Text>{' '}
|
||||
is included in your starter pack
|
||||
</Trans>
|
||||
) : items.length === 2 ? (
|
||||
<Trans>
|
||||
<Text style={[a.font_bold, textStyles]}>You</Text> and
|
||||
<Text> </Text>
|
||||
<Text style={[a.font_bold, textStyles]}>
|
||||
{getName(items[initialNamesIndex])}{' '}
|
||||
) : state.currentStep === 'Feeds' ? (
|
||||
items.length === 0 ? (
|
||||
<View style={[a.gap_sm]}>
|
||||
<Text style={[a.font_bold, a.text_center, textStyles]}>
|
||||
<Trans>Add some feeds to your starter pack!</Trans>
|
||||
</Text>
|
||||
are included in your starter pack
|
||||
</Trans>
|
||||
) : state.currentStep === 'Profiles' ? (
|
||||
<Trans context="profiles">
|
||||
<Text style={[a.font_bold, textStyles]}>
|
||||
{getName(items[initialNamesIndex])},{' '}
|
||||
<Text style={[a.text_center, textStyles]}>
|
||||
<Trans>
|
||||
Search for feeds that you want to suggest to others.
|
||||
</Trans>
|
||||
</Text>
|
||||
<Text style={[a.font_bold, textStyles]}>
|
||||
{getName(items[initialNamesIndex + 1])},{' '}
|
||||
</Text>
|
||||
and{' '}
|
||||
<Plural value={items.length - 2} one="# other" other="# others" />{' '}
|
||||
are included in your starter pack
|
||||
</Trans>
|
||||
</View>
|
||||
) : (
|
||||
<Trans context="feeds">
|
||||
<Text style={[a.font_bold, textStyles]}>
|
||||
{getName(items[initialNamesIndex])},{' '}
|
||||
</Text>
|
||||
<Text style={[a.font_bold, textStyles]}>
|
||||
{getName(items[initialNamesIndex + 1])},{' '}
|
||||
</Text>
|
||||
and{' '}
|
||||
<Plural value={items.length - 2} one="# other" other="# others" />{' '}
|
||||
are included in your starter pack
|
||||
</Trans>
|
||||
)}
|
||||
</Text>
|
||||
)}
|
||||
<Text style={[a.text_center, textStyles]}>
|
||||
{
|
||||
items.length === 1 ? (
|
||||
<Trans>
|
||||
<Text style={[a.font_bold, textStyles]}>
|
||||
{getName(items[0])}
|
||||
</Text>{' '}
|
||||
is included in your starter pack
|
||||
</Trans>
|
||||
) : items.length === 2 ? (
|
||||
<Trans>
|
||||
<Text style={[a.font_bold, textStyles]}>
|
||||
{getName(items[0])}
|
||||
</Text>{' '}
|
||||
and
|
||||
<Text> </Text>
|
||||
<Text style={[a.font_bold, textStyles]}>
|
||||
{getName(items[1])}{' '}
|
||||
</Text>
|
||||
are included in your starter pack
|
||||
</Trans>
|
||||
) : items.length > 2 ? (
|
||||
<Trans context="feeds">
|
||||
<Text style={[a.font_bold, textStyles]}>
|
||||
{getName(items[0])},{' '}
|
||||
</Text>
|
||||
<Text style={[a.font_bold, textStyles]}>
|
||||
{getName(items[1])},{' '}
|
||||
</Text>
|
||||
and{' '}
|
||||
<Plural
|
||||
value={items.length - 2}
|
||||
one="# other"
|
||||
other="# others"
|
||||
/>{' '}
|
||||
are included in your starter pack
|
||||
</Trans>
|
||||
) : null /* Should not happen. */
|
||||
}
|
||||
</Text>
|
||||
)
|
||||
) : null /* Should not happen. */
|
||||
}
|
||||
|
||||
<View
|
||||
style={[
|
||||
|
||||
@@ -19,7 +19,34 @@ export function useFeedTuners(feedDesc: FeedDescriptor) {
|
||||
]
|
||||
}
|
||||
if (feedDesc.startsWith('list')) {
|
||||
return [FeedTuner.dedupReposts]
|
||||
const feedTuners = []
|
||||
|
||||
if (feedDesc.endsWith('|as_following')) {
|
||||
// Same as Following tuners below, copypaste for now.
|
||||
if (preferences?.feedViewPrefs.hideReposts) {
|
||||
feedTuners.push(FeedTuner.removeReposts)
|
||||
} else {
|
||||
feedTuners.push(FeedTuner.dedupReposts)
|
||||
}
|
||||
if (preferences?.feedViewPrefs.hideReplies) {
|
||||
feedTuners.push(FeedTuner.removeReplies)
|
||||
} else {
|
||||
feedTuners.push(
|
||||
FeedTuner.thresholdRepliesOnly({
|
||||
userDid: currentAccount?.did || '',
|
||||
minLikes: preferences?.feedViewPrefs.hideRepliesByLikeCount || 0,
|
||||
followedOnly:
|
||||
!!preferences?.feedViewPrefs.hideRepliesByUnfollowed,
|
||||
}),
|
||||
)
|
||||
}
|
||||
if (preferences?.feedViewPrefs.hideQuotePosts) {
|
||||
feedTuners.push(FeedTuner.removeQuotePosts)
|
||||
}
|
||||
} else {
|
||||
feedTuners.push(FeedTuner.dedupReposts)
|
||||
}
|
||||
return feedTuners
|
||||
}
|
||||
if (feedDesc === 'following') {
|
||||
const feedTuners = []
|
||||
@@ -29,7 +56,6 @@ export function useFeedTuners(feedDesc: FeedDescriptor) {
|
||||
} else {
|
||||
feedTuners.push(FeedTuner.dedupReposts)
|
||||
}
|
||||
|
||||
if (preferences?.feedViewPrefs.hideReplies) {
|
||||
feedTuners.push(FeedTuner.removeReplies)
|
||||
} else {
|
||||
@@ -41,7 +67,6 @@ export function useFeedTuners(feedDesc: FeedDescriptor) {
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
if (preferences?.feedViewPrefs.hideQuotePosts) {
|
||||
feedTuners.push(FeedTuner.removeQuotePosts)
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ type AuthorFilter =
|
||||
| 'posts_with_media'
|
||||
type FeedUri = string
|
||||
type ListUri = string
|
||||
type ListFilter = 'as_following' // Applies current Following settings. Currently client-side.
|
||||
|
||||
export type FeedDescriptor =
|
||||
| 'following'
|
||||
@@ -56,6 +57,7 @@ export type FeedDescriptor =
|
||||
| `feedgen|${FeedUri}`
|
||||
| `likes|${ActorDid}`
|
||||
| `list|${ListUri}`
|
||||
| `list|${ListUri}|${ListFilter}`
|
||||
export interface FeedParams {
|
||||
disableTuner?: boolean
|
||||
mergeFeedEnabled?: boolean
|
||||
|
||||
Reference in New Issue
Block a user