From 50aacced0b35edf9bf23e106227b13719120ba99 Mon Sep 17 00:00:00 2001 From: vsecoder Date: Sat, 18 Apr 2026 21:18:29 +0300 Subject: [PATCH] fix(feed): header on one line, avatar padding explicit, icon/label aligned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three related layout polish issues. 1. Avatar + name + time splitting to two lines Fixed by collapsing the "·" separator + time into a single Text component (was three sibling Texts). RN occasionally lays out three-Text-sibling rows oddly when the name is long because each Text measures independently. With the separator glued to the time, there's one indivisible chip for "· 2h" that flexShrink:0 keeps on the row; the name takes the rest and truncates with "…" if needed. Also wrapped the name + time in a flex:1 Pressable (author tap target) so the row width is authoritative. 2. Avatar flush against the left edge The outer Pressable's style-function paddingLeft was being applied but the visual offset felt wrong because avatar has no explicit width. Added width:44 to the avatar's own Pressable wrapper so the flex-row layout reserves exactly the expected space and the 16-px paddingLeft on the outer Pressable is visible around the avatar's left edge. 3. Like / view count text visually below icon's centre RN Text includes extra top padding (Android) and baseline-anchors (iOS) that push the number glyph a pixel or two below the icon centre in a flex-row with alignItems:'center'. Added explicit lineHeight:16 (matching icon size) + includeFontPadding:false + textAlignVertical:'center' on both the heart button's Text and the shared ActionButton Text → numbers now sit on the same optical baseline as their icons on both platforms. Co-Authored-By: Claude Opus 4.7 (1M context) --- client-app/components/feed/PostCard.tsx | 112 ++++++++++++++---------- 1 file changed, 65 insertions(+), 47 deletions(-) diff --git a/client-app/components/feed/PostCard.tsx b/client-app/components/feed/PostCard.tsx index 9c654c6..0b6d41d 100644 --- a/client-app/components/feed/PostCard.tsx +++ b/client-app/components/feed/PostCard.tsx @@ -185,65 +185,65 @@ function PostCardInner({ post, likedByMe, onStatsChanged, onDeleted, compact }: onLongPress={onLongPress} style={({ pressed }) => ({ flexDirection: 'row', - paddingHorizontal: 16, + paddingLeft: 16, + paddingRight: 16, paddingVertical: compact ? 10 : 12, backgroundColor: pressed ? '#080808' : 'transparent', })} > - {/* Avatar column */} - + {/* Avatar — own tap target (opens author profile). Explicit width + on the wrapper (width:44) so the flex-row sibling below computes + its remaining space correctly. */} + - {/* Content column. overflow:'hidden' stops a long unbreakable - token (URL, hashtag) from visually escaping the card — it'll - be ellipsized or clipped instead. */} + {/* Content column. overflow:'hidden' prevents unbreakable tokens + from drawing past the right edge of the card. */} - {/* Header: [name] · [time] … [menu] - All three on a single row with no wrap. The name shrinks if - too long (flexShrink:1 + numberOfLines:1), time never shrinks - — so long handles get truncated with ellipsis while "2h" - stays readable. - - Whole header is inside a single Pressable so a tap anywhere - on the header opens the author's profile — matches Twitter's - behaviour where the name-row is a big hit target. */} - - " tail + (flexShrink:0 — never truncates). Keeping the "·" inside the + time Text means they stay glued even if the inline layout + decides to break weirdly. */} + + - {displayName} - - - · - - - {formatRelativeTime(post.created_at)} - - + + {displayName} + + + · {formatRelativeTime(post.created_at)} + + {mine && ( - + )} - + {/* Body text with hashtag highlighting. flexShrink:1 + explicit width:'100%' + paddingRight:4 keep @@ -336,6 +336,9 @@ function PostCardInner({ post, likedByMe, onStatsChanged, onDeleted, compact }: color: localLiked ? '#e0245e' : '#6a6a6a', fontSize: 12, fontWeight: localLiked ? '600' : '400', + lineHeight: 16, + includeFontPadding: false, + textAlignVertical: 'center', }} > {formatCount(localLikeCount)} @@ -406,7 +409,22 @@ function ActionButton({ icon, label, onPress }: { > {label && ( - {label} + + {label} + )} );