Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Post alignment (#5580)

Co-authored-by: Hailey <me@haileyok.com>

authored by

Eric Bailey
Hailey
and committed by
GitHub
1cedd4a3 d17da847

+170 -264
+1 -1
src/view/com/post-thread/PostThreadComposePrompt.tsx
··· 48 48 accessibilityHint={_(msg`Opens composer`)} 49 49 style={[ 50 50 gtMobile ? a.py_xs : {paddingTop: 8, paddingBottom: 11}, 51 - gtMobile ? {paddingLeft: 6, paddingRight: 6} : a.px_sm, 51 + a.px_sm, 52 52 a.border_t, 53 53 t.atoms.border_contrast_low, 54 54 t.atoms.bg,
+32 -55
src/view/com/post-thread/PostThreadFollowBtn.tsx
··· 1 1 import React from 'react' 2 - import {StyleSheet, TouchableOpacity, View} from 'react-native' 3 2 import {AppBskyActorDefs} from '@atproto/api' 4 - import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 5 3 import {msg, Trans} from '@lingui/macro' 6 4 import {useLingui} from '@lingui/react' 7 5 import {useNavigation} from '@react-navigation/native' 8 6 9 - import {usePalette} from '#/lib/hooks/usePalette' 10 - import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' 11 - import {s} from '#/lib/styles' 12 7 import {logger} from '#/logger' 13 8 import {Shadow, useProfileShadow} from '#/state/cache/profile-shadow' 14 9 import { ··· 16 11 useProfileQuery, 17 12 } from '#/state/queries/profile' 18 13 import {useRequireAuth} from '#/state/session' 19 - import {Text} from '#/view/com/util/text/Text' 20 14 import * as Toast from '#/view/com/util/Toast' 15 + import {atoms as a, useBreakpoints} from '#/alf' 16 + import {Button, ButtonIcon, ButtonText} from '#/components/Button' 17 + import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' 18 + import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' 21 19 22 20 export function PostThreadFollowBtn({did}: {did: string}) { 23 21 const {data: profile, isLoading} = useProfileQuery({did}) ··· 36 34 }) { 37 35 const navigation = useNavigation() 38 36 const {_} = useLingui() 39 - const pal = usePalette('default') 40 - const palInverted = usePalette('inverted') 41 - const {isTabletOrDesktop} = useWebMediaQueries() 37 + const {gtMobile} = useBreakpoints() 42 38 const profile: Shadow<AppBskyActorDefs.ProfileViewBasic> = 43 39 useProfileShadow(profileUnshadowed) 44 40 const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( ··· 113 109 if (!showFollowBtn) return null 114 110 115 111 return ( 116 - <View style={{width: isTabletOrDesktop ? 130 : 120}}> 117 - <View style={styles.btnOuter}> 118 - <TouchableOpacity 119 - testID="followBtn" 120 - onPress={onPress} 121 - style={[styles.btn, !isFollowing ? palInverted.view : pal.viewLight]} 122 - accessibilityRole="button" 123 - accessibilityLabel={_(msg`Follow ${profile.handle}`)} 124 - accessibilityHint={_( 125 - msg`Shows posts from ${profile.handle} in your feed`, 126 - )}> 127 - {isTabletOrDesktop && ( 128 - <FontAwesomeIcon 129 - icon={!isFollowing ? 'plus' : 'check'} 130 - style={[!isFollowing ? palInverted.text : pal.text, s.mr5]} 131 - /> 132 - )} 133 - <Text 134 - type="button" 135 - style={[!isFollowing ? palInverted.text : pal.text, s.bold]} 136 - numberOfLines={1}> 137 - {!isFollowing ? ( 138 - isFollowedBy ? ( 139 - <Trans>Follow Back</Trans> 140 - ) : ( 141 - <Trans>Follow</Trans> 142 - ) 143 - ) : ( 144 - <Trans>Following</Trans> 145 - )} 146 - </Text> 147 - </TouchableOpacity> 148 - </View> 149 - </View> 112 + <Button 113 + testID="followBtn" 114 + label={_(msg`Follow ${profile.handle}`)} 115 + onPress={onPress} 116 + size="small" 117 + variant="solid" 118 + color="secondary_inverted" 119 + style={[a.rounded_full]}> 120 + {gtMobile && ( 121 + <ButtonIcon 122 + icon={isFollowing ? Check : Plus} 123 + position="left" 124 + size="sm" 125 + /> 126 + )} 127 + <ButtonText> 128 + {!isFollowing ? ( 129 + isFollowedBy ? ( 130 + <Trans>Follow Back</Trans> 131 + ) : ( 132 + <Trans>Follow</Trans> 133 + ) 134 + ) : ( 135 + <Trans>Following</Trans> 136 + )} 137 + </ButtonText> 138 + </Button> 150 139 ) 151 140 } 152 - 153 - const styles = StyleSheet.create({ 154 - btnOuter: { 155 - marginLeft: 'auto', 156 - }, 157 - btn: { 158 - flexDirection: 'row', 159 - borderRadius: 50, 160 - paddingVertical: 8, 161 - paddingHorizontal: 14, 162 - }, 163 - })
+137 -208
src/view/com/post-thread/PostThreadItem.tsx
··· 14 14 15 15 import {MAX_POST_LINES} from '#/lib/constants' 16 16 import {usePalette} from '#/lib/hooks/usePalette' 17 - import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' 18 17 import {makeProfileLink} from '#/lib/routes/links' 19 18 import {sanitizeDisplayName} from '#/lib/strings/display-names' 20 19 import {sanitizeHandle} from '#/lib/strings/handles' 21 20 import {countLines} from '#/lib/strings/helpers' 22 21 import {niceDate} from '#/lib/strings/time' 23 22 import {s} from '#/lib/styles' 24 - import {isWeb} from '#/platform/detection' 25 23 import {POST_TOMBSTONE, Shadow, usePostShadow} from '#/state/cache/post-shadow' 26 24 import {useLanguagePrefs} from '#/state/preferences' 27 25 import {useOpenLink} from '#/state/preferences/in-app-browser' ··· 30 28 import {useComposerControls} from '#/state/shell/composer' 31 29 import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies' 32 30 import {PostThreadFollowBtn} from '#/view/com/post-thread/PostThreadFollowBtn' 33 - import {atoms as a} from '#/alf' 31 + import {atoms as a, useTheme} from '#/alf' 34 32 import {AppModerationCause} from '#/components/Pills' 35 33 import {RichText} from '#/components/RichText' 34 + import {Text as NewText} from '#/components/Typography' 36 35 import {ContentHider} from '../../../components/moderation/ContentHider' 37 36 import {LabelsOnMyPost} from '../../../components/moderation/LabelsOnMe' 38 37 import {PostAlerts} from '../../../components/moderation/PostAlerts' ··· 180 179 hideTopBorder?: boolean 181 180 threadgateRecord?: AppBskyFeedThreadgate.Record 182 181 }): React.ReactNode => { 182 + const t = useTheme() 183 183 const pal = usePalette('default') 184 184 const {_, i18n} = useLingui() 185 185 const langPrefs = useLanguagePrefs() ··· 268 268 return ( 269 269 <> 270 270 {rootUri !== post.uri && ( 271 - <View style={{paddingLeft: 16, flexDirection: 'row', height: 16}}> 272 - <View style={{width: 38}}> 271 + <View 272 + style={[ 273 + a.pl_lg, 274 + a.flex_row, 275 + a.pb_xs, 276 + {height: a.pt_lg.paddingTop}, 277 + ]}> 278 + <View style={{width: 42}}> 273 279 <View 274 280 style={[ 275 281 styles.replyLine, ··· 286 292 <View 287 293 testID={`postThreadItem-by-${post.author.handle}`} 288 294 style={[ 289 - styles.outer, 290 - styles.outerHighlighted, 291 - pal.border, 292 - pal.view, 293 - rootUri === post.uri && styles.outerHighlightedRoot, 294 - hideTopBorder && styles.noTopBorder, 295 - ]} 296 - accessible={false}> 297 - <View style={[styles.layout]}> 298 - <View style={[styles.layoutAvi, {paddingBottom: 8}]}> 299 - <PreviewableUserAvatar 300 - size={42} 301 - profile={post.author} 302 - moderation={moderation.ui('avatar')} 303 - type={post.author.associated?.labeler ? 'labeler' : 'user'} 304 - /> 295 + a.px_lg, 296 + t.atoms.border_contrast_low, 297 + // root post styles 298 + rootUri === post.uri && [a.pt_lg], 299 + ]}> 300 + <View style={[a.flex_row, a.gap_md, a.pb_md]}> 301 + <PreviewableUserAvatar 302 + size={42} 303 + profile={post.author} 304 + moderation={moderation.ui('avatar')} 305 + type={post.author.associated?.labeler ? 'labeler' : 'user'} 306 + /> 307 + <View style={[a.flex_1]}> 308 + <Link style={s.flex1} href={authorHref} title={authorTitle}> 309 + <NewText 310 + emoji 311 + style={[a.text_lg, a.font_bold, a.leading_snug, a.self_start]} 312 + numberOfLines={1}> 313 + {sanitizeDisplayName( 314 + post.author.displayName || 315 + sanitizeHandle(post.author.handle), 316 + moderation.ui('displayName'), 317 + )} 318 + </NewText> 319 + </Link> 320 + <Link style={s.flex1} href={authorHref} title={authorTitle}> 321 + <NewText 322 + emoji 323 + style={[ 324 + a.text_md, 325 + a.leading_snug, 326 + t.atoms.text_contrast_medium, 327 + ]} 328 + numberOfLines={1}> 329 + {sanitizeHandle(post.author.handle, '@')} 330 + </NewText> 331 + </Link> 305 332 </View> 306 - <View style={styles.layoutContent}> 307 - <View 308 - style={[styles.meta, styles.metaExpandedLine1, {zIndex: 1}]}> 309 - <Link style={s.flex1} href={authorHref} title={authorTitle}> 310 - <Text 311 - emoji 312 - type="xl-bold" 313 - style={[pal.text, a.self_start]} 314 - numberOfLines={1} 315 - lineHeight={1.2}> 316 - {sanitizeDisplayName( 317 - post.author.displayName || 318 - sanitizeHandle(post.author.handle), 319 - moderation.ui('displayName'), 320 - )} 321 - </Text> 322 - </Link> 333 + {currentAccount?.did !== post.author.did && ( 334 + <View> 335 + <PostThreadFollowBtn did={post.author.did} /> 323 336 </View> 324 - <View style={styles.meta}> 325 - <Link style={s.flex1} href={authorHref} title={authorTitle}> 326 - <Text 327 - emoji 328 - type="md" 329 - style={[pal.textLight]} 330 - numberOfLines={1}> 331 - {sanitizeHandle(post.author.handle, '@')} 332 - </Text> 333 - </Link> 334 - </View> 335 - </View> 336 - {currentAccount?.did !== post.author.did && ( 337 - <PostThreadFollowBtn did={post.author.did} /> 338 337 )} 339 338 </View> 340 - <View style={[s.pl10, s.pr10, s.pb10]}> 341 - <LabelsOnMyPost post={post} /> 339 + <View style={[a.pb_sm]}> 340 + <LabelsOnMyPost post={post} style={[a.pb_sm]} /> 342 341 <ContentHider 343 342 modui={moderation.ui('contentView')} 344 343 ignoreMute 345 - style={styles.contentHider} 346 - childContainerStyle={styles.contentHiderChild}> 344 + childContainerStyle={[a.pt_sm]}> 347 345 <PostAlerts 348 346 modui={moderation.ui('contentView')} 349 347 size="lg" 350 348 includeMute 351 - style={[a.pt_2xs, a.pb_sm]} 349 + style={[a.pb_sm]} 352 350 additionalCauses={additionalPostAlerts} 353 351 /> 354 352 {richText?.text ? ( 355 - <View 356 - style={[ 357 - styles.postTextContainer, 358 - styles.postTextLargeContainer, 359 - ]}> 360 - <RichText 361 - enableTags 362 - selectable 363 - value={richText} 364 - style={[a.flex_1, a.text_xl]} 365 - authorHandle={post.author.handle} 366 - /> 367 - </View> 353 + <RichText 354 + enableTags 355 + selectable 356 + value={richText} 357 + style={[a.flex_1, a.text_xl]} 358 + authorHandle={post.author.handle} 359 + /> 368 360 ) : undefined} 369 361 {post.embed && ( 370 - <View style={[a.pb_sm]}> 362 + <View style={[a.py_xs]}> 371 363 <PostEmbeds 372 364 embed={post.embed} 373 365 moderation={moderation} ··· 386 378 post.likeCount !== 0 || 387 379 post.quoteCount !== 0 ? ( 388 380 // Show this section unless we're *sure* it has no engagement. 389 - <View style={[styles.expandedInfo, pal.border]}> 381 + <View 382 + style={[ 383 + a.flex_row, 384 + a.align_center, 385 + a.gap_lg, 386 + a.border_t, 387 + a.border_b, 388 + a.mt_md, 389 + a.py_md, 390 + t.atoms.border_contrast_low, 391 + ]}> 390 392 {post.repostCount != null && post.repostCount !== 0 ? ( 391 - <Link 392 - style={styles.expandedInfoItem} 393 - href={repostsHref} 394 - title={repostsTitle}> 395 - <Text 393 + <Link href={repostsHref} title={repostsTitle}> 394 + <NewText 396 395 testID="repostCount-expanded" 397 - type="lg" 398 - style={pal.textLight}> 399 - <Text type="xl-bold" style={pal.text}> 396 + style={[a.text_md, t.atoms.text_contrast_medium]}> 397 + <NewText style={[a.text_md, a.font_bold, t.atoms.text]}> 400 398 {formatCount(i18n, post.repostCount)} 401 - </Text>{' '} 399 + </NewText>{' '} 402 400 <Plural 403 401 value={post.repostCount} 404 402 one="repost" 405 403 other="reposts" 406 404 /> 407 - </Text> 405 + </NewText> 408 406 </Link> 409 407 ) : null} 410 408 {post.quoteCount != null && 411 409 post.quoteCount !== 0 && 412 410 !post.viewer?.embeddingDisabled ? ( 413 - <Link 414 - style={styles.expandedInfoItem} 415 - href={quotesHref} 416 - title={quotesTitle}> 417 - <Text 411 + <Link href={quotesHref} title={quotesTitle}> 412 + <NewText 418 413 testID="quoteCount-expanded" 419 - type="lg" 420 - style={pal.textLight}> 421 - <Text type="xl-bold" style={pal.text}> 414 + style={[a.text_md, t.atoms.text_contrast_medium]}> 415 + <NewText style={[a.text_md, a.font_bold, t.atoms.text]}> 422 416 {formatCount(i18n, post.quoteCount)} 423 - </Text>{' '} 417 + </NewText>{' '} 424 418 <Plural 425 419 value={post.quoteCount} 426 420 one="quote" 427 421 other="quotes" 428 422 /> 429 - </Text> 423 + </NewText> 430 424 </Link> 431 425 ) : null} 432 426 {post.likeCount != null && post.likeCount !== 0 ? ( 433 - <Link 434 - style={styles.expandedInfoItem} 435 - href={likesHref} 436 - title={likesTitle}> 437 - <Text 427 + <Link href={likesHref} title={likesTitle}> 428 + <NewText 438 429 testID="likeCount-expanded" 439 - type="lg" 440 - style={pal.textLight}> 441 - <Text type="xl-bold" style={pal.text}> 430 + style={[a.text_md, t.atoms.text_contrast_medium]}> 431 + <NewText style={[a.text_md, a.font_bold, t.atoms.text]}> 442 432 {formatCount(i18n, post.likeCount)} 443 - </Text>{' '} 433 + </NewText>{' '} 444 434 <Plural value={post.likeCount} one="like" other="likes" /> 445 - </Text> 435 + </NewText> 446 436 </Link> 447 437 ) : null} 448 438 </View> 449 439 ) : null} 450 - <View style={[s.pl10, s.pr10]}> 440 + <View 441 + style={[ 442 + a.pt_sm, 443 + a.pb_2xs, 444 + { 445 + marginLeft: -5, 446 + }, 447 + ]}> 451 448 <PostCtrls 452 449 big 453 450 post={post} ··· 481 478 testID={`postThreadItem-by-${post.author.handle}`} 482 479 href={postHref} 483 480 disabled={overrideBlur} 484 - style={[pal.view]} 485 481 modui={moderation.ui('contentList')} 486 - iconSize={isThreadedChild ? 26 : 38} 482 + iconSize={isThreadedChild ? 24 : 42} 487 483 iconStyles={ 488 484 isThreadedChild ? {marginRight: 4} : {marginLeft: 2, marginRight: 2} 489 485 } ··· 496 492 paddingLeft: 8, 497 493 height: isThreadedChildAdjacentTop ? 8 : 16, 498 494 }}> 499 - <View style={{width: 38}}> 495 + <View style={{width: 42}}> 500 496 {!isThreadedChild && showParentReplyLine && ( 501 497 <View 502 498 style={[ ··· 514 510 515 511 <View 516 512 style={[ 517 - styles.layout, 513 + a.flex_row, 514 + a.px_sm, 515 + a.gap_md, 518 516 { 519 517 paddingBottom: 520 518 showChildReplyLine && !isThreadedChild ··· 526 524 ]}> 527 525 {/* If we are in threaded mode, the avatar is rendered in PostMeta */} 528 526 {!isThreadedChild && ( 529 - <View style={styles.layoutAvi}> 527 + <View> 530 528 <PreviewableUserAvatar 531 - size={38} 529 + size={42} 532 530 profile={post.author} 533 531 moderation={moderation.ui('avatar')} 534 532 type={post.author.associated?.labeler ? 'labeler' : 'user'} ··· 549 547 </View> 550 548 )} 551 549 552 - <View 553 - style={ 554 - isThreadedChild 555 - ? styles.layoutContentThreaded 556 - : styles.layoutContent 557 - }> 550 + <View style={[a.flex_1]}> 558 551 <PostMeta 559 552 author={post.author} 560 553 moderation={moderation} ··· 563 556 showAvatar={isThreadedChild} 564 557 avatarModeration={moderation.ui('avatar')} 565 558 avatarSize={24} 566 - style={ 567 - isThreadedChild && { 568 - paddingBottom: isWeb ? 5 : 4, 569 - } 570 - } 559 + style={[a.pb_xs]} 571 560 /> 572 - <LabelsOnMyPost post={post} /> 561 + <LabelsOnMyPost post={post} style={[a.pb_xs]} /> 573 562 <PostAlerts 574 563 modui={moderation.ui('contentList')} 575 - style={[a.pt_2xs, a.pb_2xs]} 564 + style={[a.pb_2xs]} 576 565 additionalCauses={additionalPostAlerts} 577 566 /> 578 567 {richText?.text ? ( 579 - <View style={styles.postTextContainer}> 568 + <View style={[a.pb_2xs, a.pr_sm]}> 580 569 <RichText 581 570 enableTags 582 571 value={richText} ··· 659 648 hasPrecedingItem: boolean 660 649 hideTopBorder?: boolean 661 650 }>) { 662 - const {isMobile} = useWebMediaQueries() 663 - const pal = usePalette('default') 651 + const t = useTheme() 664 652 if (treeView && depth > 0) { 665 653 return ( 666 654 <View 667 655 style={[ 668 - pal.border, 656 + a.flex_row, 657 + a.px_sm, 658 + t.atoms.border_contrast_low, 669 659 styles.cursor, 670 660 { 671 661 flexDirection: 'row', 672 - paddingHorizontal: isMobile ? 10 : 6, 673 - borderTopWidth: depth === 1 ? StyleSheet.hairlineWidth : 0, 662 + borderTopWidth: depth === 1 ? a.border_t.borderTopWidth : 0, 674 663 }, 675 664 ]}> 676 665 {Array.from(Array(depth - 1)).map((_, n: number) => ( 677 666 <View 678 667 key={`${post.uri}-padding-${n}`} 679 - style={{ 680 - borderLeftWidth: 2, 681 - borderLeftColor: pal.colors.border, 682 - marginLeft: isMobile ? 6 : 12, 683 - paddingLeft: isMobile ? 6 : 8, 684 - }} 668 + style={[ 669 + a.ml_sm, 670 + t.atoms.border_contrast_low, 671 + { 672 + borderLeftWidth: 2, 673 + paddingLeft: a.pl_sm.paddingLeft - 2, // minus border 674 + }, 675 + ]} 685 676 /> 686 677 ))} 687 678 <View style={{flex: 1}}>{children}</View> ··· 691 682 return ( 692 683 <View 693 684 style={[ 694 - styles.outer, 695 - pal.border, 685 + a.border_t, 686 + a.px_sm, 687 + t.atoms.border_contrast_low, 696 688 showParentReplyLine && hasPrecedingItem && styles.noTopBorder, 697 689 hideTopBorder && styles.noTopBorder, 698 690 styles.cursor, ··· 713 705 needsTranslation: boolean 714 706 translatorUrl: string 715 707 }) { 708 + const t = useTheme() 716 709 const pal = usePalette('default') 717 710 const {_, i18n} = useLingui() 718 711 const openLink = useOpenLink() ··· 723 716 }, [openLink, translatorUrl]) 724 717 725 718 return ( 726 - <View 727 - style={[ 728 - a.flex_row, 729 - a.align_center, 730 - a.flex_wrap, 731 - a.gap_xs, 732 - s.mt2, 733 - s.mb10, 734 - ]}> 735 - <Text style={[a.text_sm, pal.textLight]}> 719 + <View style={[a.flex_row, a.align_center, a.flex_wrap, a.gap_sm, a.pt_md]}> 720 + <NewText style={[a.text_sm, t.atoms.text_contrast_medium]}> 736 721 {niceDate(i18n, post.indexedAt)} 737 - </Text> 722 + </NewText> 738 723 {isRootPost && ( 739 724 <WhoCanReply post={post} isThreadAuthor={isThreadAuthor} /> 740 725 )} 741 726 {needsTranslation && ( 742 727 <> 743 - <Text style={[a.text_sm, pal.textLight]}>&middot;</Text> 728 + <NewText style={[a.text_sm, t.atoms.text_contrast_medium]}> 729 + &middot; 730 + </NewText> 744 731 745 - <Text 732 + <NewText 746 733 style={[a.text_sm, pal.link]} 747 734 title={_(msg`Translate`)} 748 735 onPress={onTranslatePress}> 749 736 <Trans>Translate</Trans> 750 - </Text> 737 + </NewText> 751 738 </> 752 739 )} 753 740 </View> ··· 773 760 borderTopWidth: StyleSheet.hairlineWidth, 774 761 paddingLeft: 8, 775 762 }, 776 - outerHighlighted: { 777 - borderTopWidth: 0, 778 - paddingTop: 4, 779 - paddingLeft: 8, 780 - paddingRight: 8, 781 - }, 782 - outerHighlightedRoot: { 783 - borderTopWidth: StyleSheet.hairlineWidth, 784 - paddingTop: 16, 785 - }, 786 763 noTopBorder: { 787 764 borderTopWidth: 0, 788 765 }, 789 - layout: { 790 - flexDirection: 'row', 791 - paddingHorizontal: 8, 792 - }, 793 - layoutAvi: {}, 794 - layoutContent: { 795 - flex: 1, 796 - marginLeft: 10, 797 - }, 798 - layoutContentThreaded: { 799 - flex: 1, 800 - }, 801 766 meta: { 802 767 flexDirection: 'row', 803 768 paddingVertical: 2, 804 769 }, 805 770 metaExpandedLine1: { 806 771 paddingVertical: 0, 807 - }, 808 - alert: { 809 - marginBottom: 6, 810 - }, 811 - postTextContainer: { 812 - flexDirection: 'row', 813 - alignItems: 'center', 814 - flexWrap: 'wrap', 815 - paddingBottom: 4, 816 - paddingRight: 10, 817 - overflow: 'hidden', 818 - }, 819 - postTextLargeContainer: { 820 - paddingHorizontal: 0, 821 - paddingRight: 0, 822 - paddingBottom: 10, 823 - }, 824 - translateLink: { 825 - marginBottom: 6, 826 - }, 827 - contentHider: { 828 - marginBottom: 6, 829 - }, 830 - contentHiderChild: { 831 - marginTop: 6, 832 - }, 833 - expandedInfo: { 834 - flexDirection: 'row', 835 - padding: 10, 836 - borderTopWidth: StyleSheet.hairlineWidth, 837 - borderBottomWidth: StyleSheet.hairlineWidth, 838 - marginTop: 5, 839 - marginBottom: 10, 840 - }, 841 - expandedInfoItem: { 842 - marginRight: 10, 843 772 }, 844 773 loadMore: { 845 774 flexDirection: 'row',