diff options
author | Eric Bailey <git@esb.lol> | 2024-10-04 15:33:17 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-04 13:33:17 -0700 |
commit | 1cedd4a3c4980dd2120c287497b6bd3098fdf751 (patch) | |
tree | 3fe375647cb05b7fdc80adc9bc6b9ab9636c4c0c /src | |
parent | d17da8474b6aa3985e3a74bc3459b483d23109cd (diff) | |
download | voidsky-1cedd4a3c4980dd2120c287497b6bd3098fdf751.tar.zst |
Post alignment (#5580)
Co-authored-by: Hailey <me@haileyok.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/view/com/post-thread/PostThreadComposePrompt.tsx | 2 | ||||
-rw-r--r-- | src/view/com/post-thread/PostThreadFollowBtn.tsx | 87 | ||||
-rw-r--r-- | src/view/com/post-thread/PostThreadItem.tsx | 345 |
3 files changed, 170 insertions, 264 deletions
diff --git a/src/view/com/post-thread/PostThreadComposePrompt.tsx b/src/view/com/post-thread/PostThreadComposePrompt.tsx index 5ad4c256d..c5582922a 100644 --- a/src/view/com/post-thread/PostThreadComposePrompt.tsx +++ b/src/view/com/post-thread/PostThreadComposePrompt.tsx @@ -48,7 +48,7 @@ export function PostThreadComposePrompt({ accessibilityHint={_(msg`Opens composer`)} style={[ gtMobile ? a.py_xs : {paddingTop: 8, paddingBottom: 11}, - gtMobile ? {paddingLeft: 6, paddingRight: 6} : a.px_sm, + a.px_sm, a.border_t, t.atoms.border_contrast_low, t.atoms.bg, diff --git a/src/view/com/post-thread/PostThreadFollowBtn.tsx b/src/view/com/post-thread/PostThreadFollowBtn.tsx index b75731f6f..1808e91a3 100644 --- a/src/view/com/post-thread/PostThreadFollowBtn.tsx +++ b/src/view/com/post-thread/PostThreadFollowBtn.tsx @@ -1,14 +1,9 @@ import React from 'react' -import {StyleSheet, TouchableOpacity, View} from 'react-native' import {AppBskyActorDefs} from '@atproto/api' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' -import {usePalette} from '#/lib/hooks/usePalette' -import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' -import {s} from '#/lib/styles' import {logger} from '#/logger' import {Shadow, useProfileShadow} from '#/state/cache/profile-shadow' import { @@ -16,8 +11,11 @@ import { useProfileQuery, } from '#/state/queries/profile' import {useRequireAuth} from '#/state/session' -import {Text} from '#/view/com/util/text/Text' import * as Toast from '#/view/com/util/Toast' +import {atoms as a, useBreakpoints} from '#/alf' +import {Button, ButtonIcon, ButtonText} from '#/components/Button' +import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' +import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' export function PostThreadFollowBtn({did}: {did: string}) { const {data: profile, isLoading} = useProfileQuery({did}) @@ -36,9 +34,7 @@ function PostThreadFollowBtnLoaded({ }) { const navigation = useNavigation() const {_} = useLingui() - const pal = usePalette('default') - const palInverted = usePalette('inverted') - const {isTabletOrDesktop} = useWebMediaQueries() + const {gtMobile} = useBreakpoints() const profile: Shadow<AppBskyActorDefs.ProfileViewBasic> = useProfileShadow(profileUnshadowed) const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( @@ -113,51 +109,32 @@ function PostThreadFollowBtnLoaded({ if (!showFollowBtn) return null return ( - <View style={{width: isTabletOrDesktop ? 130 : 120}}> - <View style={styles.btnOuter}> - <TouchableOpacity - testID="followBtn" - onPress={onPress} - style={[styles.btn, !isFollowing ? palInverted.view : pal.viewLight]} - accessibilityRole="button" - accessibilityLabel={_(msg`Follow ${profile.handle}`)} - accessibilityHint={_( - msg`Shows posts from ${profile.handle} in your feed`, - )}> - {isTabletOrDesktop && ( - <FontAwesomeIcon - icon={!isFollowing ? 'plus' : 'check'} - style={[!isFollowing ? palInverted.text : pal.text, s.mr5]} - /> - )} - <Text - type="button" - style={[!isFollowing ? palInverted.text : pal.text, s.bold]} - numberOfLines={1}> - {!isFollowing ? ( - isFollowedBy ? ( - <Trans>Follow Back</Trans> - ) : ( - <Trans>Follow</Trans> - ) - ) : ( - <Trans>Following</Trans> - )} - </Text> - </TouchableOpacity> - </View> - </View> + <Button + testID="followBtn" + label={_(msg`Follow ${profile.handle}`)} + onPress={onPress} + size="small" + variant="solid" + color="secondary_inverted" + style={[a.rounded_full]}> + {gtMobile && ( + <ButtonIcon + icon={isFollowing ? Check : Plus} + position="left" + size="sm" + /> + )} + <ButtonText> + {!isFollowing ? ( + isFollowedBy ? ( + <Trans>Follow Back</Trans> + ) : ( + <Trans>Follow</Trans> + ) + ) : ( + <Trans>Following</Trans> + )} + </ButtonText> + </Button> ) } - -const styles = StyleSheet.create({ - btnOuter: { - marginLeft: 'auto', - }, - btn: { - flexDirection: 'row', - borderRadius: 50, - paddingVertical: 8, - paddingHorizontal: 14, - }, -}) diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index ead9df116..4701f225c 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -14,14 +14,12 @@ import {useLingui} from '@lingui/react' import {MAX_POST_LINES} from '#/lib/constants' import {usePalette} from '#/lib/hooks/usePalette' -import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {makeProfileLink} from '#/lib/routes/links' import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeHandle} from '#/lib/strings/handles' import {countLines} from '#/lib/strings/helpers' import {niceDate} from '#/lib/strings/time' import {s} from '#/lib/styles' -import {isWeb} from '#/platform/detection' import {POST_TOMBSTONE, Shadow, usePostShadow} from '#/state/cache/post-shadow' import {useLanguagePrefs} from '#/state/preferences' import {useOpenLink} from '#/state/preferences/in-app-browser' @@ -30,9 +28,10 @@ import {useSession} from '#/state/session' import {useComposerControls} from '#/state/shell/composer' import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies' import {PostThreadFollowBtn} from '#/view/com/post-thread/PostThreadFollowBtn' -import {atoms as a} from '#/alf' +import {atoms as a, useTheme} from '#/alf' import {AppModerationCause} from '#/components/Pills' import {RichText} from '#/components/RichText' +import {Text as NewText} from '#/components/Typography' import {ContentHider} from '../../../components/moderation/ContentHider' import {LabelsOnMyPost} from '../../../components/moderation/LabelsOnMe' import {PostAlerts} from '../../../components/moderation/PostAlerts' @@ -180,6 +179,7 @@ let PostThreadItemLoaded = ({ hideTopBorder?: boolean threadgateRecord?: AppBskyFeedThreadgate.Record }): React.ReactNode => { + const t = useTheme() const pal = usePalette('default') const {_, i18n} = useLingui() const langPrefs = useLanguagePrefs() @@ -268,8 +268,14 @@ let PostThreadItemLoaded = ({ return ( <> {rootUri !== post.uri && ( - <View style={{paddingLeft: 16, flexDirection: 'row', height: 16}}> - <View style={{width: 38}}> + <View + style={[ + a.pl_lg, + a.flex_row, + a.pb_xs, + {height: a.pt_lg.paddingTop}, + ]}> + <View style={{width: 42}}> <View style={[ styles.replyLine, @@ -286,88 +292,74 @@ let PostThreadItemLoaded = ({ <View testID={`postThreadItem-by-${post.author.handle}`} style={[ - styles.outer, - styles.outerHighlighted, - pal.border, - pal.view, - rootUri === post.uri && styles.outerHighlightedRoot, - hideTopBorder && styles.noTopBorder, - ]} - accessible={false}> - <View style={[styles.layout]}> - <View style={[styles.layoutAvi, {paddingBottom: 8}]}> - <PreviewableUserAvatar - size={42} - profile={post.author} - moderation={moderation.ui('avatar')} - type={post.author.associated?.labeler ? 'labeler' : 'user'} - /> - </View> - <View style={styles.layoutContent}> - <View - style={[styles.meta, styles.metaExpandedLine1, {zIndex: 1}]}> - <Link style={s.flex1} href={authorHref} title={authorTitle}> - <Text - emoji - type="xl-bold" - style={[pal.text, a.self_start]} - numberOfLines={1} - lineHeight={1.2}> - {sanitizeDisplayName( - post.author.displayName || - sanitizeHandle(post.author.handle), - moderation.ui('displayName'), - )} - </Text> - </Link> - </View> - <View style={styles.meta}> - <Link style={s.flex1} href={authorHref} title={authorTitle}> - <Text - emoji - type="md" - style={[pal.textLight]} - numberOfLines={1}> - {sanitizeHandle(post.author.handle, '@')} - </Text> - </Link> - </View> + a.px_lg, + t.atoms.border_contrast_low, + // root post styles + rootUri === post.uri && [a.pt_lg], + ]}> + <View style={[a.flex_row, a.gap_md, a.pb_md]}> + <PreviewableUserAvatar + size={42} + profile={post.author} + moderation={moderation.ui('avatar')} + type={post.author.associated?.labeler ? 'labeler' : 'user'} + /> + <View style={[a.flex_1]}> + <Link style={s.flex1} href={authorHref} title={authorTitle}> + <NewText + emoji + style={[a.text_lg, a.font_bold, a.leading_snug, a.self_start]} + numberOfLines={1}> + {sanitizeDisplayName( + post.author.displayName || + sanitizeHandle(post.author.handle), + moderation.ui('displayName'), + )} + </NewText> + </Link> + <Link style={s.flex1} href={authorHref} title={authorTitle}> + <NewText + emoji + style={[ + a.text_md, + a.leading_snug, + t.atoms.text_contrast_medium, + ]} + numberOfLines={1}> + {sanitizeHandle(post.author.handle, '@')} + </NewText> + </Link> </View> {currentAccount?.did !== post.author.did && ( - <PostThreadFollowBtn did={post.author.did} /> + <View> + <PostThreadFollowBtn did={post.author.did} /> + </View> )} </View> - <View style={[s.pl10, s.pr10, s.pb10]}> - <LabelsOnMyPost post={post} /> + <View style={[a.pb_sm]}> + <LabelsOnMyPost post={post} style={[a.pb_sm]} /> <ContentHider modui={moderation.ui('contentView')} ignoreMute - style={styles.contentHider} - childContainerStyle={styles.contentHiderChild}> + childContainerStyle={[a.pt_sm]}> <PostAlerts modui={moderation.ui('contentView')} size="lg" includeMute - style={[a.pt_2xs, a.pb_sm]} + style={[a.pb_sm]} additionalCauses={additionalPostAlerts} /> {richText?.text ? ( - <View - style={[ - styles.postTextContainer, - styles.postTextLargeContainer, - ]}> - <RichText - enableTags - selectable - value={richText} - style={[a.flex_1, a.text_xl]} - authorHandle={post.author.handle} - /> - </View> + <RichText + enableTags + selectable + value={richText} + style={[a.flex_1, a.text_xl]} + authorHandle={post.author.handle} + /> ) : undefined} {post.embed && ( - <View style={[a.pb_sm]}> + <View style={[a.py_xs]}> <PostEmbeds embed={post.embed} moderation={moderation} @@ -386,68 +378,73 @@ let PostThreadItemLoaded = ({ post.likeCount !== 0 || post.quoteCount !== 0 ? ( // Show this section unless we're *sure* it has no engagement. - <View style={[styles.expandedInfo, pal.border]}> + <View + style={[ + a.flex_row, + a.align_center, + a.gap_lg, + a.border_t, + a.border_b, + a.mt_md, + a.py_md, + t.atoms.border_contrast_low, + ]}> {post.repostCount != null && post.repostCount !== 0 ? ( - <Link - style={styles.expandedInfoItem} - href={repostsHref} - title={repostsTitle}> - <Text + <Link href={repostsHref} title={repostsTitle}> + <NewText testID="repostCount-expanded" - type="lg" - style={pal.textLight}> - <Text type="xl-bold" style={pal.text}> + style={[a.text_md, t.atoms.text_contrast_medium]}> + <NewText style={[a.text_md, a.font_bold, t.atoms.text]}> {formatCount(i18n, post.repostCount)} - </Text>{' '} + </NewText>{' '} <Plural value={post.repostCount} one="repost" other="reposts" /> - </Text> + </NewText> </Link> ) : null} {post.quoteCount != null && post.quoteCount !== 0 && !post.viewer?.embeddingDisabled ? ( - <Link - style={styles.expandedInfoItem} - href={quotesHref} - title={quotesTitle}> - <Text + <Link href={quotesHref} title={quotesTitle}> + <NewText testID="quoteCount-expanded" - type="lg" - style={pal.textLight}> - <Text type="xl-bold" style={pal.text}> + style={[a.text_md, t.atoms.text_contrast_medium]}> + <NewText style={[a.text_md, a.font_bold, t.atoms.text]}> {formatCount(i18n, post.quoteCount)} - </Text>{' '} + </NewText>{' '} <Plural value={post.quoteCount} one="quote" other="quotes" /> - </Text> + </NewText> </Link> ) : null} {post.likeCount != null && post.likeCount !== 0 ? ( - <Link - style={styles.expandedInfoItem} - href={likesHref} - title={likesTitle}> - <Text + <Link href={likesHref} title={likesTitle}> + <NewText testID="likeCount-expanded" - type="lg" - style={pal.textLight}> - <Text type="xl-bold" style={pal.text}> + style={[a.text_md, t.atoms.text_contrast_medium]}> + <NewText style={[a.text_md, a.font_bold, t.atoms.text]}> {formatCount(i18n, post.likeCount)} - </Text>{' '} + </NewText>{' '} <Plural value={post.likeCount} one="like" other="likes" /> - </Text> + </NewText> </Link> ) : null} </View> ) : null} - <View style={[s.pl10, s.pr10]}> + <View + style={[ + a.pt_sm, + a.pb_2xs, + { + marginLeft: -5, + }, + ]}> <PostCtrls big post={post} @@ -481,9 +478,8 @@ let PostThreadItemLoaded = ({ testID={`postThreadItem-by-${post.author.handle}`} href={postHref} disabled={overrideBlur} - style={[pal.view]} modui={moderation.ui('contentList')} - iconSize={isThreadedChild ? 26 : 38} + iconSize={isThreadedChild ? 24 : 42} iconStyles={ isThreadedChild ? {marginRight: 4} : {marginLeft: 2, marginRight: 2} } @@ -496,7 +492,7 @@ let PostThreadItemLoaded = ({ paddingLeft: 8, height: isThreadedChildAdjacentTop ? 8 : 16, }}> - <View style={{width: 38}}> + <View style={{width: 42}}> {!isThreadedChild && showParentReplyLine && ( <View style={[ @@ -514,7 +510,9 @@ let PostThreadItemLoaded = ({ <View style={[ - styles.layout, + a.flex_row, + a.px_sm, + a.gap_md, { paddingBottom: showChildReplyLine && !isThreadedChild @@ -526,9 +524,9 @@ let PostThreadItemLoaded = ({ ]}> {/* If we are in threaded mode, the avatar is rendered in PostMeta */} {!isThreadedChild && ( - <View style={styles.layoutAvi}> + <View> <PreviewableUserAvatar - size={38} + size={42} profile={post.author} moderation={moderation.ui('avatar')} type={post.author.associated?.labeler ? 'labeler' : 'user'} @@ -549,12 +547,7 @@ let PostThreadItemLoaded = ({ </View> )} - <View - style={ - isThreadedChild - ? styles.layoutContentThreaded - : styles.layoutContent - }> + <View style={[a.flex_1]}> <PostMeta author={post.author} moderation={moderation} @@ -563,20 +556,16 @@ let PostThreadItemLoaded = ({ showAvatar={isThreadedChild} avatarModeration={moderation.ui('avatar')} avatarSize={24} - style={ - isThreadedChild && { - paddingBottom: isWeb ? 5 : 4, - } - } + style={[a.pb_xs]} /> - <LabelsOnMyPost post={post} /> + <LabelsOnMyPost post={post} style={[a.pb_xs]} /> <PostAlerts modui={moderation.ui('contentList')} - style={[a.pt_2xs, a.pb_2xs]} + style={[a.pb_2xs]} additionalCauses={additionalPostAlerts} /> {richText?.text ? ( - <View style={styles.postTextContainer}> + <View style={[a.pb_2xs, a.pr_sm]}> <RichText enableTags value={richText} @@ -659,29 +648,31 @@ function PostOuterWrapper({ hasPrecedingItem: boolean hideTopBorder?: boolean }>) { - const {isMobile} = useWebMediaQueries() - const pal = usePalette('default') + const t = useTheme() if (treeView && depth > 0) { return ( <View style={[ - pal.border, + a.flex_row, + a.px_sm, + t.atoms.border_contrast_low, styles.cursor, { flexDirection: 'row', - paddingHorizontal: isMobile ? 10 : 6, - borderTopWidth: depth === 1 ? StyleSheet.hairlineWidth : 0, + borderTopWidth: depth === 1 ? a.border_t.borderTopWidth : 0, }, ]}> {Array.from(Array(depth - 1)).map((_, n: number) => ( <View key={`${post.uri}-padding-${n}`} - style={{ - borderLeftWidth: 2, - borderLeftColor: pal.colors.border, - marginLeft: isMobile ? 6 : 12, - paddingLeft: isMobile ? 6 : 8, - }} + style={[ + a.ml_sm, + t.atoms.border_contrast_low, + { + borderLeftWidth: 2, + paddingLeft: a.pl_sm.paddingLeft - 2, // minus border + }, + ]} /> ))} <View style={{flex: 1}}>{children}</View> @@ -691,8 +682,9 @@ function PostOuterWrapper({ return ( <View style={[ - styles.outer, - pal.border, + a.border_t, + a.px_sm, + t.atoms.border_contrast_low, showParentReplyLine && hasPrecedingItem && styles.noTopBorder, hideTopBorder && styles.noTopBorder, styles.cursor, @@ -713,6 +705,7 @@ function ExpandedPostDetails({ needsTranslation: boolean translatorUrl: string }) { + const t = useTheme() const pal = usePalette('default') const {_, i18n} = useLingui() const openLink = useOpenLink() @@ -723,31 +716,25 @@ function ExpandedPostDetails({ }, [openLink, translatorUrl]) return ( - <View - style={[ - a.flex_row, - a.align_center, - a.flex_wrap, - a.gap_xs, - s.mt2, - s.mb10, - ]}> - <Text style={[a.text_sm, pal.textLight]}> + <View style={[a.flex_row, a.align_center, a.flex_wrap, a.gap_sm, a.pt_md]}> + <NewText style={[a.text_sm, t.atoms.text_contrast_medium]}> {niceDate(i18n, post.indexedAt)} - </Text> + </NewText> {isRootPost && ( <WhoCanReply post={post} isThreadAuthor={isThreadAuthor} /> )} {needsTranslation && ( <> - <Text style={[a.text_sm, pal.textLight]}>·</Text> + <NewText style={[a.text_sm, t.atoms.text_contrast_medium]}> + · + </NewText> - <Text + <NewText style={[a.text_sm, pal.link]} title={_(msg`Translate`)} onPress={onTranslatePress}> <Trans>Translate</Trans> - </Text> + </NewText> </> )} </View> @@ -773,31 +760,9 @@ const styles = StyleSheet.create({ borderTopWidth: StyleSheet.hairlineWidth, paddingLeft: 8, }, - outerHighlighted: { - borderTopWidth: 0, - paddingTop: 4, - paddingLeft: 8, - paddingRight: 8, - }, - outerHighlightedRoot: { - borderTopWidth: StyleSheet.hairlineWidth, - paddingTop: 16, - }, noTopBorder: { borderTopWidth: 0, }, - layout: { - flexDirection: 'row', - paddingHorizontal: 8, - }, - layoutAvi: {}, - layoutContent: { - flex: 1, - marginLeft: 10, - }, - layoutContentThreaded: { - flex: 1, - }, meta: { flexDirection: 'row', paddingVertical: 2, @@ -805,42 +770,6 @@ const styles = StyleSheet.create({ metaExpandedLine1: { paddingVertical: 0, }, - alert: { - marginBottom: 6, - }, - postTextContainer: { - flexDirection: 'row', - alignItems: 'center', - flexWrap: 'wrap', - paddingBottom: 4, - paddingRight: 10, - overflow: 'hidden', - }, - postTextLargeContainer: { - paddingHorizontal: 0, - paddingRight: 0, - paddingBottom: 10, - }, - translateLink: { - marginBottom: 6, - }, - contentHider: { - marginBottom: 6, - }, - contentHiderChild: { - marginTop: 6, - }, - expandedInfo: { - flexDirection: 'row', - padding: 10, - borderTopWidth: StyleSheet.hairlineWidth, - borderBottomWidth: StyleSheet.hairlineWidth, - marginTop: 5, - marginBottom: 10, - }, - expandedInfoItem: { - marginRight: 10, - }, loadMore: { flexDirection: 'row', alignItems: 'center', |