Commit Graph

6 Commits

Author SHA1 Message Date
vsecoder
7bfd8c7dea fix(feed): side padding on action row + stable FAB right-anchor
- Post action row (chat / ❤ / eye / share) had only a small paddingRight
  and no left padding. First icon sat flush under the avatar and share
  iron against the card edge. Replaced with paddingHorizontal: 12 so
  both sides get equal breathing room; each of the four cells still
  flex:1 so the icons distribute evenly.
- FAB kept appearing at the LEFT edge instead of the right on user's
  device despite position:absolute + right:12. Pressable's dynamic-
  function style can drop absolute-positioning fields between renders
  on some RN versions. Wrapping the Pressable in a plain absolute-
  positioned View fixes this: positioning lives on the View (never
  re-evaluated mid-render), the Pressable inside only declares size
  and visuals. pointerEvents="box-none" on the wrapper keeps taps
  outside the button passing through to the feed list below.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 20:31:03 +03:00
vsecoder
f688f45739 fix(feed): breathing room around divider + FAB back to right/bottom corner
- PostSeparator was a bare 1px line flush against both neighbouring
  cards, so the seam looked like card contact instead of a real
  break. Wrapped it in a 12px vertical padding — now there's 12px
  blank above the line, 1px line, 12px blank below. Trimmed the
  card's own paddingVertical back down since the separator now owns
  the inter-post breathing room.
- FAB was lifted to bottom: max(insets.bottom, 8) + 70 in the previous
  commit which put it far too high (a leftover from the original
  experiment with the absoluteFill wrapper). User wants 12px above
  the NavBar and 12px from the right edge. The Feed screen's
  container ends at the NavBar top (enforced by (app)/_layout.tsx's
  outer <View flex:1> + NavBar sibling), so a simple `right: 12,
  bottom: 12` on position:absolute lands the button exactly there on
  every device. Removed the now-unnecessary absoluteFill wrapper too.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 20:28:52 +03:00
vsecoder
a248c540d5 fix(feed): visible post divider + reliable FAB positioning
- Post divider was on each PostCard's outer Pressable as borderBottom
  (#222), which was barely visible on OLED black and disappeared
  entirely in pressed state (the pressed bg ate the line). Moved the
  seam to a dedicated PostSeparator component (1px, #2a2a2a) wired as
  FlatList's ItemSeparatorComponent on both /feed (timeline / for-you
  / trending) and /feed/tag/[tag]. Also bumped inter-card vertical
  padding (14-16 top / 16-20 bottom) so cards have real breathing room
  even before the divider.
- FAB position was flaky: with <Stack> at the (app) level the overlay
  could end up positioned against the Stack's card view instead of the
  tab container, which made the button drift around and stick against
  unexpected edges. Wrapped it in an absoluteFill container with
  pointerEvents="box-none" — the wrapper owns positioning against the
  tab screen, the button inside just declares right: 14 / bottom: N.
  Bumped bottom offset to `max(insets.bottom, 8) + 70` so the FAB
  always clears the 5-icon NavBar with ~14px visual gap on every
  device. Shadow switched from blue-cast to standard dark for better
  depth perception on dark backgrounds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 20:23:52 +03:00
vsecoder
51bc0a1850 fix(feed): card spacing, action-row distribution, tab strip, detail inset
- PostCard rows got cramped paddings and a near-invisible divider.
  Increased paddingTop 12→16, paddingBottom 12→18, paddingHorizontal
  14→16; divider colour #141414→#222222 so the seam between posts is
  legible on OLED blacks.
- Action row (chat / ❤ / view / share) used a fixed gap:32 + spacer.
  Reworked to four flex:1 cells with justifyContent: space-between,
  so the first three icons distribute evenly across the row and share
  pins to the right edge. Matches Twitter's layout where each action
  occupies a quarter of the row regardless of label width.
- Feed tab strip (Подписки / Для вас / В тренде) used flex:1 +
  gap:10 which bunched the three labels together visually. Switched
  to justifyContent: space-between + paddingHorizontal:20 so each
  tab hugs its label and the three labels spread to the edges with
  full horizontal breathing room.
- Post detail screen (/feed/[id]) and hashtag feed (/feed/tag/[tag])
  were missing the safe-area top inset — their headers butted right
  against the status bar / notch. Added useSafeAreaInsets().top as
  paddingTop on the outer View, matching the rest of the app.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 20:20:18 +03:00
vsecoder
93040a0684 fix(client): DM-only info, seed on API error, proper cross-group back stack
Three related UX fixes on the client.

1. Participants count on profile

   DMs always have exactly two participants (you and the contact) so a
   "Участников: 1" row was confusing — either it's obviously the other
   person or it's wrong depending on how you count. Removed for direct
   conversations; the row still appears for group chats (and shows an
   em-dash until v2.1.0 gives groups a real member list).

2. Dev feed seed now activates on network / 404 errors

   The seed was only surfaced when the real API returned an EMPTY
   array. If the node was down (Network request failed) or the endpoint
   replied 404, the catch block quietly set posts to [] and the list
   stayed blank — defeating the point of the seed. Now both the empty-
   response path AND the network-error path fall back to getDevSeedFeed(),
   so scrolling / like-toggling works even without a running node.

   Also made the __DEV__ lookup more defensive: use `globalThis.__DEV__`
   at runtime instead of the typed global. Some bundler configurations
   have the TS type but not the runtime binding, or vice-versa — the
   runtime lookup always agrees with Metro.

3. Back from profile → previous screen instead of tab root

   Root cause: AnimatedSlot rendered <Slot>, which is stack-less. When
   /chats/xyz pushed /profile/abc (cross-group), the chats group
   unmounted. Hitting Back then re-entered chats at its root (/chats
   list) rather than /chats/xyz.

   Replaced <Slot> with <Stack> in AnimatedSlot. Tab switching still
   stays flat because NavBar uses router.replace (which maps to
   navigation.replace on the Stack — no history accumulation).
   Cross-group pushes (post author tap from feed, avatar tap from chat
   header, compose modal) now live in the outer Stack's history, so
   Back pops correctly to the caller.

   The nested Stacks (chats/_layout.tsx, feed/_layout.tsx,
   profile/_layout.tsx) still handle intra-group navigation as before.
   The PanResponder-based swipe-right-to-back was removed since the
   native Stack now provides iOS edge-swipe natively; Android uses the
   system back button.

   animation: 'none' keeps the visual swap instant — matches the prior
   Slot look so nothing flashes slide-animations that weren't there
   before. Sub-group layouts can opt into slide_from_right themselves
   (profile/_layout.tsx and feed/_layout.tsx already do).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 20:16:38 +03:00
vsecoder
98a0a4b8ba fix(nav): move feed.tsx → feed/index.tsx to unblock duplicate-route error
expo-router error: "A navigator cannot contain multiple 'Screen'
components with the same name (found duplicate screen named 'feed')".

Cause: having both app/(app)/feed.tsx (a file-route) and
app/(app)/feed/ (a folder with _layout.tsx) at the same level makes
expo-router try to register two routes called "feed".

Fix: the folder's _layout.tsx wraps the tab + its sub-routes in a
single Stack, so the tab screen becomes feed/index.tsx — the initial
screen of that Stack. Back navigation from /feed/[id] and
/feed/tag/[tag] now correctly pops to the Feed tab root.

No other route references changed (paths like /(app)/feed,
/(app)/feed/<id>, /(app)/feed/tag/<tag> still resolve identically).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 20:10:33 +03:00