// 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 (
);
}
// 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 (
);
}
// 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')}