// screens/thread.jsx — Conversation Thread (the hero screen) // Instagram-style DM layout: header → messages → AI suggestion strip → compose. // All user-visible copy goes through window.tr() so the language picker // on the landing page swaps content live. Falls back to EN literals when // i18n isn't loaded (e.g. when this file is used inside the design canvas). const _tr = (k, fb) => (window.tr ? window.tr(k, fb) : fb); const _useLang = () => (window.useLang ? window.useLang() : 'en'); function ThreadHeader({ theme, name, handle, presence }) { const t = useT(theme); return (
{name}
{presence && } @{handle} · {presence ? _tr('thread.activeNow', 'Active now') : _tr('thread.activeAgo', 'Active 2h ago')}
); } // Day divider — "TODAY 2:14 PM" function DayDivider({ theme, label }) { const t = useT(theme); return (
{label}
); } // Tiny "delivered/seen" status under the last outbound bubble in a group. function ReadReceipt({ theme, label }) { const t = useT(theme); return (
{label}
); } // AI-suggestion strip. Three suggestions; tapping one drops it into the // compose field. Built as a horizontally-scrollable row at the device width. function SuggestStrip({ theme, suggestions, onPick }) { const t = useT(theme); return (
{_tr('thread.suggested', 'Suggested replies')}
{suggestions.map((s, i) => ( ))}
); } // Compose bar: sparkle (left), text field, send (right). The field shows // either the placeholder or a draft (e.g. dropped-in suggestion). function ComposeBar({ theme, draft, focused }) { const t = useT(theme); const hasText = !!(draft && draft.length); return (
{hasText ? draft : _tr('thread.composePlaceholder', 'Message…')}
); } // Default thread content. opts: // draft — text in compose field (simulates a tapped suggestion). When // draft === true, we pull the localized "draftFilled" string // so callers don't have to know which language we're in. // suggestionsHidden — hide the AI strip (when the user is mid-edit) function ConversationThread({ theme = 'light', draft = '', focused = false, suggestionsHidden = false }) { _useLang(); // subscribe to language changes → re-render const t = useT(theme); const suggestions = [ _tr('thread.suggest.1', 'Ships free to Floripa — usually 2–3 business days ✨'), _tr('thread.suggest.2', 'Yes! We replace it within 30 days, no questions.'), _tr('thread.suggest.3', "I'll DM you a 10% code for being patient 🧡"), ]; // Allow callers to pass `draft={true}` and let the component pick the // localized "filled draft" sample. Anything else is used as-is. const draftText = draft === true ? _tr('thread.draftFilled', suggestions[0]) : draft; return (
{_tr('thread.bubble.q1')} {_tr('thread.bubble.q2')}
{_tr('thread.bubble.a1')} {_tr('thread.bubble.a2')}
{_tr('thread.bubble.q3')} {_tr('thread.bubble.q4')}
{/* AI-context strip — a soft, in-line hint that AI is paying attention. Lives between the last inbound message and the compose, so suggestions feel earned, not invasive. */}
{_tr('thread.aiHint', 'Recadly noticed a question about shipping & returns')}
{!suggestionsHidden && ( )}
); } window.ConversationThread = ConversationThread;