diff --git a/README.md b/README.md index 49c4b016ff..64bcbcea5e 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Get the app itself: ## Development Resources -This is a [React Native](https://reactnative.dev/) application, written in the TypeScript programming language. It builds on the `atproto` TypeScript packages (like [`@atproto/api`](https://www.npmjs.com/package/@atproto/api)), code for which is also on open source, but in [a different git repository](https://github.com/bluesky-social/atproto). +This is a [React Native](https://reactnative.dev/) application, written in the TypeScript programming language. It builds on the `atproto` TypeScript packages (like [`@atproto/api`](https://www.npmjs.com/package/@atproto/api)), code for which is also open source, but in [a different git repository](https://github.com/bluesky-social/atproto). There is a small amount of Go language source code (in `./bskyweb/`), for a web service that returns the React Native Web application. @@ -42,10 +42,10 @@ The Bluesky Social application encompasses a set of schemas and APIs built in th - Open an issue and give some time for discussion before submitting a PR. - Stay away from PRs like... - Changing "Post" to "Skeet." - - Refactoring the codebase, eg to replace mobx with redux or something. + - Refactoring the codebase, e.g., to replace MobX with Redux or something. - Adding entirely new features without prior discussion. -Remember, we serve a wide community of users. Our day to day involves us constantly asking "which top priority is our top priority." If you submit well-written PRs that solve problems concisely, that's an awesome contribution. Otherwise, as much as we'd love to accept your ideas and contributions, we really don't have the bandwidth. That's what forking is for! +Remember, we serve a wide community of users. Our day-to-day involves us constantly asking "which top priority is our top priority." If you submit well-written PRs that solve problems concisely, that's an awesome contribution. Otherwise, as much as we'd love to accept your ideas and contributions, we really don't have the bandwidth. That's what forking is for! ## Forking guidelines @@ -63,7 +63,7 @@ If you discover any security issues, please send an email to security@bsky.app. ## Are you a developer interested in building on atproto? -Bluesky is an open social network built on the AT Protocol, a flexible technology that will never lock developers out of the ecosystems that they help build. With atproto, third-party can be as seamless as first-party through custom feeds, federated services, clients, and more. +Bluesky is an open social network built on the AT Protocol, a flexible technology that will never lock developers out of the ecosystems that they help build. With atproto, third-party integration can be as seamless as first-party through custom feeds, federated services, clients, and more. ## License (MIT) diff --git a/src/components/KnownFollowers.tsx b/src/components/KnownFollowers.tsx index 7b861dc660..4017a7b0be 100644 --- a/src/components/KnownFollowers.tsx +++ b/src/components/KnownFollowers.tsx @@ -12,6 +12,7 @@ import {Link, LinkProps} from '#/components/Link' import {Text} from '#/components/Typography' const AVI_SIZE = 30 +const AVI_SIZE_SMALL = 20 const AVI_BORDER = 1 /** @@ -30,10 +31,12 @@ export function KnownFollowers({ profile, moderationOpts, onLinkPress, + minimal, }: { profile: AppBskyActorDefs.ProfileViewDetailed moderationOpts: ModerationOpts onLinkPress?: LinkProps['onPress'] + minimal?: boolean }) { const cache = React.useRef>( new Map(), @@ -59,6 +62,7 @@ export function KnownFollowers({ cachedKnownFollowers={cachedKnownFollowers} moderationOpts={moderationOpts} onLinkPress={onLinkPress} + minimal={minimal} /> ) } @@ -71,11 +75,13 @@ function KnownFollowersInner({ moderationOpts, cachedKnownFollowers, onLinkPress, + minimal, }: { profile: AppBskyActorDefs.ProfileViewDetailed moderationOpts: ModerationOpts cachedKnownFollowers: AppBskyActorDefs.KnownFollowers onLinkPress?: LinkProps['onPress'] + minimal?: boolean }) { const t = useTheme() const {_} = useLingui() @@ -110,6 +116,8 @@ function KnownFollowersInner({ */ if (slice.length === 0) return null + const SIZE = minimal ? AVI_SIZE_SMALL : AVI_SIZE + return ( @@ -129,8 +137,8 @@ function KnownFollowersInner({ diff --git a/src/components/ProfileCard.tsx b/src/components/ProfileCard.tsx index 79f1108cb3..8bc9376e0c 100644 --- a/src/components/ProfileCard.tsx +++ b/src/components/ProfileCard.tsx @@ -166,7 +166,9 @@ export function NameAndHandle({ return ( - + {name} - + {sanitizeDisplayName( profile.displayName || sanitizeHandle(profile.handle), moderation.ui('displayName'), diff --git a/src/components/StarterPack/Wizard/WizardListCard.tsx b/src/components/StarterPack/Wizard/WizardListCard.tsx index aa1b2cf9bd..55cf0f02b3 100644 --- a/src/components/StarterPack/Wizard/WizardListCard.tsx +++ b/src/components/StarterPack/Wizard/WizardListCard.tsx @@ -78,7 +78,13 @@ function WizardListCard({ /> {displayName} diff --git a/src/components/dms/MessagesListHeader.tsx b/src/components/dms/MessagesListHeader.tsx index 8bf673d300..7b9f1a3a02 100644 --- a/src/components/dms/MessagesListHeader.tsx +++ b/src/components/dms/MessagesListHeader.tsx @@ -168,7 +168,12 @@ function HeaderReady({ {displayName} diff --git a/src/components/dms/dialogs/SearchablePeopleList.tsx b/src/components/dms/dialogs/SearchablePeopleList.tsx index d92ea68350..a13dfe509f 100644 --- a/src/components/dms/dialogs/SearchablePeopleList.tsx +++ b/src/components/dms/dialogs/SearchablePeopleList.tsx @@ -395,7 +395,7 @@ function ProfileCard({ /> {displayName} diff --git a/src/lib/statsig/gates.ts b/src/lib/statsig/gates.ts index 378b273494..1c86d01da4 100644 --- a/src/lib/statsig/gates.ts +++ b/src/lib/statsig/gates.ts @@ -1,6 +1,7 @@ export type Gate = // Keep this alphabetic please. | 'debug_show_feedcontext' + | 'explore_page_profile_card_social_proof' | 'native_pwi_disabled' | 'new_user_guided_tour' | 'new_user_progress_guide' diff --git a/src/lib/strings/constants.ts b/src/lib/strings/constants.ts new file mode 100644 index 0000000000..4bce3ac626 --- /dev/null +++ b/src/lib/strings/constants.ts @@ -0,0 +1 @@ +export const NON_BREAKING_SPACE = '\u00A0' diff --git a/src/screens/Messages/Conversation/MessagesList.tsx b/src/screens/Messages/Conversation/MessagesList.tsx index f72515ac62..11b951e99d 100644 --- a/src/screens/Messages/Conversation/MessagesList.tsx +++ b/src/screens/Messages/Conversation/MessagesList.tsx @@ -386,10 +386,10 @@ export function MessagesList({ data={convoState.items} renderItem={renderItem} keyExtractor={keyExtractor} - containWeb={true} + disableFullWindowScroll={true} // Prevents wrong position in Firefox when sending a message // as well as scroll getting stuck on Chome when scrolling upwards. - disableContentVisibility={true} + disableContainStyle={true} disableVirtualization={true} style={animatedListStyle} // The extra two items account for the header and the footer components diff --git a/src/screens/Profile/Header/DisplayName.tsx b/src/screens/Profile/Header/DisplayName.tsx index c63658a44a..955e3d72c8 100644 --- a/src/screens/Profile/Header/DisplayName.tsx +++ b/src/screens/Profile/Header/DisplayName.tsx @@ -20,7 +20,7 @@ export function ProfileHeaderDisplayName({ + style={[t.atoms.text, a.text_4xl, a.self_start, {fontWeight: '500'}]}> {sanitizeDisplayName( profile.displayName || sanitizeHandle(profile.handle), moderation.ui('displayName'), diff --git a/src/screens/StarterPack/Wizard/StepFeeds.tsx b/src/screens/StarterPack/Wizard/StepFeeds.tsx index 878d17ce01..de8d856aba 100644 --- a/src/screens/StarterPack/Wizard/StepFeeds.tsx +++ b/src/screens/StarterPack/Wizard/StepFeeds.tsx @@ -101,7 +101,7 @@ export function StepFeeds({moderationOpts}: {moderationOpts: ModerationOpts}) { onEndReachedThreshold={2} renderScrollComponent={props => } keyboardShouldPersistTaps="handled" - containWeb={true} + disableFullWindowScroll={true} sideBorders={false} style={{flex: 1}} ListEmptyComponent={ diff --git a/src/screens/StarterPack/Wizard/StepProfiles.tsx b/src/screens/StarterPack/Wizard/StepProfiles.tsx index f77a46e7ab..c14de847f6 100644 --- a/src/screens/StarterPack/Wizard/StepProfiles.tsx +++ b/src/screens/StarterPack/Wizard/StepProfiles.tsx @@ -80,7 +80,7 @@ export function StepProfiles({ keyExtractor={keyExtractor} renderScrollComponent={props => } keyboardShouldPersistTaps="handled" - containWeb={true} + disableFullWindowScroll={true} sideBorders={false} style={[a.flex_1]} onEndReached={ diff --git a/src/state/session/agent.ts b/src/state/session/agent.ts index 4bcb4c11ca..d31b5588b4 100644 --- a/src/state/session/agent.ts +++ b/src/state/session/agent.ts @@ -12,6 +12,7 @@ import {tryFetchGates} from '#/lib/statsig/statsig' import {getAge} from '#/lib/strings/time' import {logger} from '#/logger' import {snoozeEmailConfirmationPrompt} from '#/state/shell/reminders' +import {addSessionEventLog} from './logging' import { configureModerationForAccount, configureModerationForGuest, @@ -194,6 +195,7 @@ async function prepareAgent( const account = agentToSessionAccountOrThrow(agent) agent.setPersistSessionHandler(event => { onSessionChange(agent, account.did, event) + addSessionEventLog(account.did, event) }) return {agent, account} } diff --git a/src/state/session/logging.ts b/src/state/session/logging.ts index ea4d9cf1dd..549deddfd1 100644 --- a/src/state/session/logging.ts +++ b/src/state/session/logging.ts @@ -1,4 +1,4 @@ -import {AtpSessionData} from '@atproto/api' +import {AtpSessionData, AtpSessionEvent} from '@atproto/api' import {sha256} from 'js-sha256' import {Statsig} from 'statsig-react-native-expo' @@ -70,6 +70,18 @@ export function wrapSessionReducerForLogging(reducer: Reducer): Reducer { let nextMessageIndex = 0 const MAX_SLICE_LENGTH = 1000 +// Not gated. +export function addSessionEventLog(did: string, event: AtpSessionEvent) { + try { + if (!Statsig.initializeCalled() || !Statsig.getStableID()) { + return + } + Statsig.logEvent('session:event', null, {did, event}) + } catch (e) { + console.error(e) + } +} + export function addSessionDebugLog(log: Log) { console.log(new Date(), log) try { diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx index 1932efbd5c..d31962ff35 100644 --- a/src/view/com/notifications/FeedItem.tsx +++ b/src/view/com/notifications/FeedItem.tsx @@ -58,6 +58,7 @@ import {useNavigation} from '@react-navigation/native' import {parseTenorGif} from '#/lib/strings/embed-player' import {logger} from '#/logger' import {NavigationProp} from 'lib/routes/types' +import {forceLTR} from 'lib/strings/bidi' import {DM_SERVICE_HEADERS} from 'state/queries/messages/const' import {useAgent} from 'state/session' import {Button, ButtonText} from '#/components/Button' @@ -274,13 +275,15 @@ let FeedItem = ({ showDmButton={item.type === 'starterpack-joined' || isFollowBack} /> - + diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 0f5350e790..4e6ed27bed 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -281,7 +281,7 @@ let PostThreadItemLoaded = ({ {sanitizeDisplayName( diff --git a/src/view/com/profile/ProfileCard.tsx b/src/view/com/profile/ProfileCard.tsx index 7332d452ad..9458fbaf8e 100644 --- a/src/view/com/profile/ProfileCard.tsx +++ b/src/view/com/profile/ProfileCard.tsx @@ -5,7 +5,6 @@ import { moderateProfile, ModerationDecision, } from '@atproto/api' -import {Trans} from '@lingui/macro' import {useQueryClient} from '@tanstack/react-query' import {useProfileShadow} from '#/state/cache/profile-shadow' @@ -19,12 +18,16 @@ import {sanitizeDisplayName} from 'lib/strings/display-names' import {sanitizeHandle} from 'lib/strings/handles' import {s} from 'lib/styles' import {precacheProfile} from 'state/queries/profile' +import {atoms as a} from '#/alf' +import { + KnownFollowers, + shouldShowKnownFollowers, +} from '#/components/KnownFollowers' import {Link} from '../util/Link' import {Text} from '../util/text/Text' import {PreviewableUserAvatar} from '../util/UserAvatar' import {FollowButton} from './FollowButton' import hairlineWidth = StyleSheet.hairlineWidth -import {atoms as a} from '#/alf' import * as Pills from '#/components/Pills' export function ProfileCard({ @@ -33,22 +36,22 @@ export function ProfileCard({ noModFilter, noBg, noBorder, - followers, renderButton, onPress, style, + showKnownFollowers, }: { testID?: string profile: AppBskyActorDefs.ProfileViewBasic noModFilter?: boolean noBg?: boolean noBorder?: boolean - followers?: AppBskyActorDefs.ProfileView[] | undefined renderButton?: ( profile: Shadow, ) => React.ReactNode onPress?: () => void style?: StyleProp + showKnownFollowers?: boolean }) { const queryClient = useQueryClient() const pal = usePalette('default') @@ -70,6 +73,11 @@ export function ProfileCard({ return null } + const knownFollowersVisible = + showKnownFollowers && + shouldShowKnownFollowers(profile.viewer?.knownFollowers) && + moderationOpts + return ( {sanitizeDisplayName( @@ -118,14 +126,30 @@ export function ProfileCard({ {renderButton(profile)} ) : undefined} - {profile.description ? ( + {profile.description || knownFollowersVisible ? ( - - {profile.description as string} - + {profile.description ? ( + + {profile.description as string} + + ) : null} + {knownFollowersVisible ? ( + + + + ) : null} ) : null} - ) } @@ -155,73 +179,20 @@ export function ProfileCardPills({ ) } -function FollowersList({ - followers, -}: { - followers?: AppBskyActorDefs.ProfileView[] | undefined -}) { - const pal = usePalette('default') - const moderationOpts = useModerationOpts() - - const followersWithMods = React.useMemo(() => { - if (!followers || !moderationOpts) { - return [] - } - - return followers - .map(f => ({ - f, - mod: moderateProfile(f, moderationOpts), - })) - .filter(({mod}) => !mod.ui('profileList').filter) - }, [followers, moderationOpts]) - - if (!followersWithMods?.length) { - return null - } - - return ( - - - - Followed by{' '} - {followersWithMods.map(({f}) => f.displayName || f.handle).join(', ')} - - - {followersWithMods.slice(0, 3).map(({f, mod}) => ( - - - - - - ))} - - ) -} - export function ProfileCardWithFollowBtn({ profile, noBg, noBorder, - followers, onPress, logContext = 'ProfileCard', + showKnownFollowers, }: { - profile: AppBskyActorDefs.ProfileViewBasic + profile: AppBskyActorDefs.ProfileView noBg?: boolean noBorder?: boolean - followers?: AppBskyActorDefs.ProfileView[] | undefined onPress?: () => void logContext?: 'ProfileCard' | 'StarterPackProfilesList' + showKnownFollowers?: boolean }) { const {currentAccount} = useSession() const isMe = profile.did === currentAccount?.did @@ -231,7 +202,6 @@ export function ProfileCardWithFollowBtn({ profile={profile} noBg={noBg} noBorder={noBorder} - followers={followers} renderButton={ isMe ? undefined @@ -240,6 +210,7 @@ export function ProfileCardWithFollowBtn({ ) } onPress={onPress} + showKnownFollowers={!isMe && showKnownFollowers} /> ) } diff --git a/src/view/com/util/List.tsx b/src/view/com/util/List.tsx index ed43ed5f0d..e1a10e4741 100644 --- a/src/view/com/util/List.tsx +++ b/src/view/com/util/List.tsx @@ -24,11 +24,12 @@ export type ListProps = Omit< refreshing?: boolean onRefresh?: () => void onItemSeen?: (item: ItemT) => void - containWeb?: boolean desktopFixedHeight?: number | boolean + // Web only prop to contain the scroll to the container rather than the window + disableFullWindowScroll?: boolean sideBorders?: boolean // Web only prop to disable a perf optimization (which would otherwise be on). - disableContentVisibility?: boolean + disableContainStyle?: boolean } export type ListRef = React.MutableRefObject diff --git a/src/view/com/util/List.web.tsx b/src/view/com/util/List.web.tsx index ecc714910d..8a96511187 100644 --- a/src/view/com/util/List.web.tsx +++ b/src/view/com/util/List.web.tsx @@ -23,9 +23,11 @@ export type ListProps = Omit< onRefresh?: () => void onItemSeen?: (item: ItemT) => void desktopFixedHeight?: number | boolean - containWeb?: boolean + // Web only prop to contain the scroll to the container rather than the window + disableFullWindowScroll?: boolean sideBorders?: boolean - disableContentVisibility?: boolean + // Web only prop to disable a perf optimization (which would otherwise be on). + disableContainStyle?: boolean } export type ListRef = React.MutableRefObject // TODO: Better types. @@ -39,7 +41,7 @@ function ListImpl( ListHeaderComponent, ListFooterComponent, ListEmptyComponent, - containWeb, + disableFullWindowScroll, contentContainerStyle, data, desktopFixedHeight, @@ -58,7 +60,7 @@ function ListImpl( extraData, style, sideBorders = true, - disableContentVisibility, + disableContainStyle, ...props }: ListProps, ref: React.Ref, @@ -112,7 +114,7 @@ function ListImpl( } const getScrollableNode = React.useCallback(() => { - if (containWeb) { + if (disableFullWindowScroll) { const element = nativeRef.current as HTMLDivElement | null if (!element) return @@ -182,7 +184,7 @@ function ListImpl( }, } } - }, [containWeb]) + }, [disableFullWindowScroll]) const nativeRef = React.useRef(null) React.useImperativeHandle( @@ -267,7 +269,12 @@ function ListImpl( return () => { element?.removeEventListener('scroll', handleScroll) } - }, [isInsideVisibleTree, handleScroll, containWeb, getScrollableNode]) + }, [ + isInsideVisibleTree, + handleScroll, + disableFullWindowScroll, + getScrollableNode, + ]) // --- onScrolledDownChange --- const isScrolledDown = useRef(false) @@ -308,7 +315,7 @@ function ListImpl( {...props} style={[ style, - containWeb && { + disableFullWindowScroll && { flex: 1, // @ts-expect-error web only 'overflow-y': 'scroll', @@ -332,13 +339,13 @@ function ListImpl( pal.border, ]}> {onStartReached && !isEmpty && ( @@ -356,13 +363,13 @@ function ListImpl( renderItem={renderItem} extraData={extraData} onItemSeen={onItemSeen} - disableContentVisibility={disableContentVisibility} + disableContainStyle={disableContainStyle} /> ) })} {onEndReached && !isEmpty && ( ({ renderItem, extraData: _unused, onItemSeen, - disableContentVisibility, + disableContainStyle, }: { item: ItemT index: number @@ -416,7 +423,7 @@ let Row = function RowImpl({ | ((data: {index: number; item: any; separators: any}) => React.ReactNode) extraData: any onItemSeen: ((item: any) => void) | undefined - disableContentVisibility?: boolean + disableContainStyle?: boolean }): React.ReactNode { const rowRef = React.useRef(null) const intersectionTimeout = React.useRef(undefined) @@ -465,14 +472,10 @@ let Row = function RowImpl({ return null } - const shouldDisableContentVisibility = disableContentVisibility || isSafari + const shouldDisableContainStyle = disableContainStyle || isSafari return ( {renderItem({item, index, separators: null as any})} @@ -544,9 +547,9 @@ const styles = StyleSheet.create({ marginLeft: 'auto', marginRight: 'auto', }, - contentVisibilityAuto: { + contain: { // @ts-ignore web only - contentVisibility: 'auto', + contain: 'layout paint', }, minHeightViewport: { // @ts-ignore web only diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx index aec787e4e5..95168e8b3c 100644 --- a/src/view/com/util/PostMeta.tsx +++ b/src/view/com/util/PostMeta.tsx @@ -6,6 +6,8 @@ import {useQueryClient} from '@tanstack/react-query' import {precacheProfile} from '#/state/queries/profile' import {usePalette} from 'lib/hooks/usePalette' import {makeProfileLink} from 'lib/routes/links' +import {forceLTR} from 'lib/strings/bidi' +import {NON_BREAKING_SPACE} from 'lib/strings/constants' import {sanitizeDisplayName} from 'lib/strings/display-names' import {sanitizeHandle} from 'lib/strings/handles' import {niceDate} from 'lib/strings/time' @@ -32,8 +34,6 @@ interface PostMetaOpts { style?: StyleProp } -const NON_BREAKING_SPACE = '\u00A0' - let PostMeta = (opts: PostMetaOpts): React.ReactNode => { const pal = usePalette('default') const displayName = opts.author.displayName || opts.author.handle @@ -70,14 +70,12 @@ let PostMeta = (opts: PostMetaOpts): React.ReactNode => { style={[pal.text]} lineHeight={1.2} disableMismatchWarning - text={ - <> - {sanitizeDisplayName( - displayName, - opts.moderation?.ui('displayName'), - )} - - } + text={forceLTR( + sanitizeDisplayName( + displayName, + opts.moderation?.ui('displayName'), + ), + )} href={profileLink} onBeforePress={onBeforePressAuthor} /> diff --git a/src/view/com/util/post-embeds/index.tsx b/src/view/com/util/post-embeds/index.tsx index 942ad57b81..3fd55f5c21 100644 --- a/src/view/com/util/post-embeds/index.tsx +++ b/src/view/com/util/post-embeds/index.tsx @@ -131,7 +131,7 @@ export function PostEmbeds({ const {alt, thumb, aspectRatio} = images[0] return ( - + - + - + ) } @@ -183,7 +187,7 @@ export function PostEmbeds({ } const styles = StyleSheet.create({ - imagesContainer: { + container: { marginTop: 8, }, altContainer: { diff --git a/src/view/screens/Search/Explore.tsx b/src/view/screens/Search/Explore.tsx index 85e8ffa4ec..05fd85effe 100644 --- a/src/view/screens/Search/Explore.tsx +++ b/src/view/screens/Search/Explore.tsx @@ -10,6 +10,7 @@ import { import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {useGate} from '#/lib/statsig/statsig' import {logger} from '#/logger' import {isWeb} from '#/platform/detection' import {useModerationOpts} from '#/state/preferences/moderation-opts' @@ -241,7 +242,7 @@ type ExploreScreenItems = | { type: 'profile' key: string - profile: AppBskyActorDefs.ProfileViewBasic + profile: AppBskyActorDefs.ProfileView } | { type: 'feed' @@ -291,6 +292,7 @@ export function Explore() { error: feedsError, fetchNextPage: fetchNextFeedsPage, } = useGetPopularFeedsQuery({limit: 10}) + const gate = useGate() const isLoadingMoreProfiles = isFetchingNextProfilesPage && !isLoadingProfiles const onLoadMoreProfiles = React.useCallback(async () => { @@ -492,7 +494,14 @@ export function Explore() { case 'profile': { return ( - + ) } @@ -555,7 +564,7 @@ export function Explore() { } } }, - [t, moderationOpts], + [t, moderationOpts, gate], ) return ( diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx index 1d8199b009..f59bfb1834 100644 --- a/src/view/screens/Settings/index.tsx +++ b/src/view/screens/Settings/index.tsx @@ -68,6 +68,7 @@ import {navigate, resetToTab} from '#/Navigation' import {Email2FAToggle} from './Email2FAToggle' import {ExportCarDialog} from './ExportCarDialog' import hairlineWidth = StyleSheet.hairlineWidth +import {atoms as a} from '#/alf' function SettingsAccountCard({ account, @@ -104,7 +105,7 @@ function SettingsAccountCard({ /> - + {profile?.displayName || account.handle} diff --git a/src/view/screens/Storybook/ListContained.tsx b/src/view/screens/Storybook/ListContained.tsx index b3ea091f40..20ec686570 100644 --- a/src/view/screens/Storybook/ListContained.tsx +++ b/src/view/screens/Storybook/ListContained.tsx @@ -47,7 +47,7 @@ export function ListContained() { ) }} keyExtractor={item => item.id.toString()} - containWeb={true} + disableFullWindowScroll={true} style={{flex: 1}} onStartReached={() => { console.log('Start Reached') diff --git a/src/view/shell/desktop/Search.tsx b/src/view/shell/desktop/Search.tsx index 3829a6c0b2..d8aa518996 100644 --- a/src/view/shell/desktop/Search.tsx +++ b/src/view/shell/desktop/Search.tsx @@ -30,6 +30,7 @@ import {precacheProfile} from 'state/queries/profile' import {Link} from '#/view/com/util/Link' import {UserAvatar} from '#/view/com/util/UserAvatar' import {Text} from 'view/com/util/text/Text' +import {atoms as a} from '#/alf' let SearchLinkCard = ({ label, @@ -127,7 +128,7 @@ let SearchProfileCard = ({ {sanitizeDisplayName(