From 237e957d1699fb4da756e9acc98c527f282e90b0 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Fri, 7 Jul 2023 12:00:17 -0500 Subject: [PATCH] Fixes and improvements to the Profile Preview modal (#992) * Fix: use more reliable navigation method * Fix: show lightbox over the active modal * Fix: close the profile preview on navigation * Factor out UserPreviewLink and add preview behavior to notifications * Fix postmeta overflow on web * Fix lint --- src/state/models/ui/shell.ts | 18 +++++++++++ src/view/com/notifications/FeedItem.tsx | 37 +++++++++++---------- src/view/com/post/Post.tsx | 18 +++++------ src/view/com/profile/ProfileHeader.tsx | 11 ++++--- src/view/com/util/PostMeta.tsx | 4 +-- src/view/com/util/UserAvatar.tsx | 27 +++------------- src/view/com/util/UserPreviewLink.tsx | 43 +++++++++++++++++++++++++ src/view/shell/index.tsx | 2 +- 8 files changed, 101 insertions(+), 59 deletions(-) create mode 100644 src/view/com/util/UserPreviewLink.tsx diff --git a/src/state/models/ui/shell.ts b/src/state/models/ui/shell.ts index c6e7289d..a0e0cd7b 100644 --- a/src/state/models/ui/shell.ts +++ b/src/state/models/ui/shell.ts @@ -279,6 +279,24 @@ export class ShellUiModel { return false } + /** + * used to clear out any modals, eg for a navigation + */ + closeAllActiveElements() { + if (this.isLightboxActive) { + this.closeLightbox() + } + while (this.isModalActive) { + this.closeModal() + } + if (this.isComposerActive) { + this.closeComposer() + } + if (this.isDrawerOpen) { + this.closeDrawer() + } + } + openDrawer() { this.isDrawerOpen = true } diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx index 6c03d7f9..d5acf230 100644 --- a/src/view/com/notifications/FeedItem.tsx +++ b/src/view/com/notifications/FeedItem.tsx @@ -22,7 +22,8 @@ import {sanitizeDisplayName} from 'lib/strings/display-names' import {pluralize} from 'lib/strings/helpers' import {HeartIconSolid} from 'lib/icons' import {Text} from '../util/text/Text' -import {UserAvatar} from '../util/UserAvatar' +import {UserAvatar, PreviewableUserAvatar} from '../util/UserAvatar' +import {UserPreviewLink} from '../util/UserPreviewLink' import {ImageHorzList} from '../util/images/ImageHorzList' import {Post} from '../post/Post' import {Link, TextLink} from '../util/Link' @@ -42,6 +43,7 @@ const EXPANDED_AUTHOR_EL_HEIGHT = 35 interface Author { href: string + did: string handle: string displayName?: string avatar?: string @@ -91,6 +93,7 @@ export const FeedItem = observer(function ({ return [ { href: `/profile/${item.author.handle}`, + did: item.author.did, handle: item.author.handle, displayName: item.author.displayName, avatar: item.author.avatar, @@ -102,6 +105,7 @@ export const FeedItem = observer(function ({ ...(item.additional?.map(({author}) => { return { href: `/profile/${author.handle}`, + did: author.did, handle: author.handle, displayName: author.displayName, avatar: author.avatar, @@ -282,17 +286,13 @@ function CondensedAuthorsList({ if (authors.length === 1) { return ( - - - + ) } @@ -356,12 +356,11 @@ function ExpandedAuthorsList({ visible ? s.mb10 : undefined, ]}> {authors.map(author => ( - + - + ))} ) diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx index 34154e7e..bdc84b62 100644 --- a/src/view/com/post/Post.tsx +++ b/src/view/com/post/Post.tsx @@ -25,7 +25,7 @@ import {ImageHider} from '../util/moderation/ImageHider' import {Text} from '../util/text/Text' import {RichText} from '../util/text/RichText' import * as Toast from '../util/Toast' -import {UserAvatar} from '../util/UserAvatar' +import {PreviewableUserAvatar} from '../util/UserAvatar' import {useStores} from 'state/index' import {s, colors} from 'lib/styles' import {usePalette} from 'lib/hooks/usePalette' @@ -127,8 +127,6 @@ const PostLoaded = observer( const itemUrip = new AtUri(item.post.uri) const itemHref = `/profile/${item.post.author.handle}/post/${itemUrip.rkey}` const itemTitle = `Post by ${item.post.author.handle}` - const authorHref = `/profile/${item.post.author.handle}` - const authorTitle = item.post.author.handle let replyAuthorDid = '' if (record.reply) { const urip = new AtUri(record.reply.parent?.uri || record.reply.root.uri) @@ -214,13 +212,13 @@ const PostLoaded = observer( {showReplyLine && } - - - + { track('ProfileHeader:FollowersButtonClicked') - navigation.push('ProfileFollowers', {name: view.handle}) - }, [track, navigation, view]) + navigate('ProfileFollowers', {name: view.handle}) + store.shell.closeAllActiveElements() // for when used in the profile preview modal + }, [track, view, store.shell]) const onPressFollows = React.useCallback(() => { track('ProfileHeader:FollowsButtonClicked') - navigation.push('ProfileFollows', {name: view.handle}) - }, [track, navigation, view]) + navigate('ProfileFollows', {name: view.handle}) + store.shell.closeAllActiveElements() // for when used in the profile preview modal + }, [track, view, store.shell]) const onPressShare = React.useCallback(() => { track('ProfileHeader:ShareButtonClicked') diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx index 396b0278..7f8abebd 100644 --- a/src/view/com/util/PostMeta.tsx +++ b/src/view/com/util/PostMeta.tsx @@ -7,7 +7,7 @@ import {usePalette} from 'lib/hooks/usePalette' import {UserAvatar} from './UserAvatar' import {observer} from 'mobx-react-lite' import {sanitizeDisplayName} from 'lib/strings/display-names' -import {isAndroid, isIOS} from 'platform/detection' +import {isAndroid} from 'platform/detection' interface PostMetaOpts { authorAvatar?: string @@ -88,6 +88,6 @@ const styles = StyleSheet.create({ }, maxWidth: { flex: isAndroid ? 1 : undefined, - maxWidth: isIOS ? '80%' : undefined, + maxWidth: !isAndroid ? '80%' : undefined, }, }) diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx index 135615a3..eb6405f1 100644 --- a/src/view/com/util/UserAvatar.tsx +++ b/src/view/com/util/UserAvatar.tsx @@ -1,5 +1,5 @@ import React, {useMemo} from 'react' -import {Pressable, StyleSheet, View} from 'react-native' +import {StyleSheet, View} from 'react-native' import Svg, {Circle, Rect, Path} from 'react-native-svg' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {IconProp} from '@fortawesome/fontawesome-svg-core' @@ -12,12 +12,11 @@ import { import {useStores} from 'state/index' import {colors} from 'lib/styles' import {DropdownButton} from './forms/DropdownButton' -import {Link} from './Link' import {usePalette} from 'lib/hooks/usePalette' import {isWeb, isAndroid} from 'platform/detection' import {Image as RNImage} from 'react-native-image-crop-picker' import {AvatarModeration} from 'lib/labeling/types' -import {isDesktopWeb} from 'platform/detection' +import {UserPreviewLink} from './UserPreviewLink' type Type = 'user' | 'algo' | 'list' @@ -257,28 +256,10 @@ export function UserAvatar({ } export function PreviewableUserAvatar(props: PreviewableUserAvatarProps) { - const store = useStores() - - if (isDesktopWeb) { - return ( - - - - ) - } return ( - - store.shell.openModal({ - name: 'profile-preview', - did: props.did, - }) - } - accessibilityRole="button" - accessibilityLabel={props.handle} - accessibilityHint=""> + - + ) } diff --git a/src/view/com/util/UserPreviewLink.tsx b/src/view/com/util/UserPreviewLink.tsx new file mode 100644 index 00000000..ae49301f --- /dev/null +++ b/src/view/com/util/UserPreviewLink.tsx @@ -0,0 +1,43 @@ +import React from 'react' +import {Pressable, StyleProp, ViewStyle} from 'react-native' +import {useStores} from 'state/index' +import {Link} from './Link' +import {isDesktopWeb} from 'platform/detection' + +interface UserPreviewLinkProps { + did: string + handle: string + style?: StyleProp +} +export function UserPreviewLink( + props: React.PropsWithChildren, +) { + const store = useStores() + + if (isDesktopWeb) { + return ( + + {props.children} + + ) + } + return ( + + store.shell.openModal({ + name: 'profile-preview', + did: props.did, + }) + } + accessibilityRole="button" + accessibilityLabel={props.handle} + accessibilityHint="" + style={props.style}> + {props.children} + + ) +} diff --git a/src/view/shell/index.tsx b/src/view/shell/index.tsx index 08a93868..7ab371d5 100644 --- a/src/view/shell/index.tsx +++ b/src/view/shell/index.tsx @@ -61,7 +61,6 @@ const ShellInner = observer(() => { - store.shell.closeComposer()} @@ -71,6 +70,7 @@ const ShellInner = observer(() => { quote={store.shell.composerOpts?.quote} /> + ) })