From 598ac7e66daab77a17b9153e3eede64e70595283 Mon Sep 17 00:00:00 2001 From: Arnas Donauskas Date: Fri, 22 May 2026 10:06:34 +0300 Subject: [PATCH] feat(inbox): WhatsApp-style doodle background in the chat area MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a subtle, repeating SVG pattern behind the message thread and the "select a conversation" empty state — same visual language WhatsApp uses in their own chat UI, themed for a CRM (message bubble, phone, mail, calendar, lightbulb, briefcase, trophy, dollar sign, percent, etc). Asset: public/inbox-doodle.svg, 6 KB, 240×240 tile that repeats seamlessly. Icon shapes are taken verbatim from lucide-react (already a dependency, every other icon in the UI uses it) so the doodle reads as part of the same visual system, not a separate clip-art import. Stroke is slate-500 at 22% opacity over bg-slate-950 — visible but not competing with message text. Wiring: a single DOODLE_BG_CLASSES constant in message-thread.tsx applied to both the empty-state and active-thread containers, so they can't drift. The header keeps bg-slate-900 (solid) and the composer keeps its own background, so the doodle only shows in the actual message scroll area — exactly like WhatsApp. No JS, no perf hit beyond a one-off 6 KB asset fetch that's then browser-cached forever (it's served from /public with Next's default caching). Co-Authored-By: Claude Opus 4.7 (1M context) --- public/inbox-doodle.svg | 139 ++++++++++++++++++++++++ src/components/inbox/message-thread.tsx | 23 +++- 2 files changed, 158 insertions(+), 4 deletions(-) create mode 100644 public/inbox-doodle.svg diff --git a/public/inbox-doodle.svg b/public/inbox-doodle.svg new file mode 100644 index 0000000..977f4f6 --- /dev/null +++ b/public/inbox-doodle.svg @@ -0,0 +1,139 @@ + + + diff --git a/src/components/inbox/message-thread.tsx b/src/components/inbox/message-thread.tsx index fce4b03..12235b5 100644 --- a/src/components/inbox/message-thread.tsx +++ b/src/components/inbox/message-thread.tsx @@ -110,6 +110,18 @@ const STATUS_OPTIONS: { label: string; value: ConversationStatus; color: string { label: "Closed", value: "closed", color: "text-slate-400" }, ]; +/** + * WhatsApp-style doodle background applied to the chat area (both the + * active thread and the empty state). The SVG tile lives at + * `/public/inbox-doodle.svg`; the slate-950 colour sits underneath so + * the doodles read as a subtle pattern rather than a stark grid. + * + * Defined once at module scope so the two render paths can't drift — + * if we ever switch the asset, both spots update together. + */ +const DOODLE_BG_CLASSES = + "bg-slate-950 bg-[url('/inbox-doodle.svg')] bg-repeat"; + export function MessageThread({ conversation, contact, @@ -629,10 +641,12 @@ export function MessageThread({ [conversation, onAssignChange], ); - // Empty state + // Empty state — same WhatsApp-style doodle background as the active + // thread below, so swapping between empty/selected doesn't change the + // pattern under the user's eye. if (!conversation || !contact) { return ( -
+
@@ -658,8 +672,9 @@ export function MessageThread({ : "Assign"; return ( -
- {/* Header */} +
+ {/* Header — solid bg-slate-900 sits on top of the doodle so the + name/avatar/dropdowns stay legible. */}
{/* Back-to-list button — mobile only. Hidden on lg+ where the