Negotiation Inbox: Mobile Layout & Auto-Scroll — What's New in v0.1.113
Negotiation Inbox: Mobile Layout & Auto-Scroll
Released in v0.1.113
Overview
Version 0.1.113 ships two quality-of-life improvements to the negotiation inbox: a proper responsive layout for mobile and tablet users, and automatic scrolling to the latest message when opening or receiving messages in a thread.
Responsive Two-Screen Pattern on Mobile
The Problem
The inbox was built around a fixed lg:grid-cols-[340px_1fr] two-column layout. This works well on wide desktop screens, but below the 1024px breakpoint the columns would collapse vertically — leaving users with a cramped, stacked experience and no way to navigate back to the thread list once they'd tapped into a conversation.
The Fix
On screens smaller than the lg breakpoint (i.e. phones and most tablets), the inbox now follows a two-screen pattern:
- Screen 1 — Thread List: The full screen is used to display the list of negotiation threads. No message viewer is visible.
- Screen 2 — Message View: Tapping a thread slides into a full-screen message view for that conversation. A back button at the top returns the user to the thread list.
The transition between screens uses the existing onClose callback already present on the ThreadViewer component — no new APIs were introduced.
The previously hard-coded min-h-[600px] on the thread viewer has also been removed, so the layout adapts correctly to any screen height.
Desktop behaviour is unchanged — the side-by-side two-column layout remains in place at ≥ lg.
Auto-Scroll to Latest Message
Previously, opening a thread with a long message history required manual scrolling to reach the most recent message. New messages arriving via background polling also didn't trigger any scroll.
With v0.1.113, the message list now automatically scrolls to the bottom whenever:
- A thread is first opened.
- A new message arrives (detected via a change in the messages array length).
This is implemented using a useEffect hook that calls:
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })
The scroll is smooth and non-jarring. No user interaction is required.
Polling Spinner Behaviour
The inbox polls for new messages every 5 seconds. Previously, the RefreshCw icon would animate a spinning state on every background poll — a subtle but persistent visual distraction.
The spinner is now only shown on explicit user-triggered refreshes. The "Updated X seconds ago" timestamp is still displayed so users can always confirm when data was last fetched.
Summary of Changes
| Area | Before | After |
|---|---|---|
| Mobile layout | Collapsed vertical stack, no back navigation | Two-screen pattern with back button |
| Thread viewer height | Fixed min-h-[600px] | Adapts to screen size |
| Scroll position on open | Top of message list | Bottom (latest message) |
| Scroll on new message | No scroll | Auto-scrolls to latest |
| Polling spinner | Spins every 5 s | Only on manual refresh |
Affected File
src/app/dashboard/negotiation/negotiation-inbox.tsx