From cc9ea45c618c4893c1494829e8d7da6722fd8755 Mon Sep 17 00:00:00 2001 From: gosangam Date: Sun, 30 Aug 2026 10:54:56 +0530 Subject: [PATCH] feat: sticker preview --- components/chat/sticker-grid.tsx | 85 ++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 26 deletions(-) diff --git a/components/chat/sticker-grid.tsx b/components/chat/sticker-grid.tsx index 83dc30f0..000f33e2 100644 --- a/components/chat/sticker-grid.tsx +++ b/components/chat/sticker-grid.tsx @@ -1,7 +1,13 @@ "use client"; /** - * Stickers on a message: a 2-column grid, rendered without a chat bubble. + * Stickers on a message, rendered without a chat bubble. + * + * Laid out as rows of at most two, NOT a fixed 2-column grid: a grid reserves + * the second cell whether or not anything fills it, so a single sticker sat + * beside a gap the width of another sticker. Rows size themselves — a lone + * sticker takes the row and is drawn larger, a pair shares it and both shrink. + * An odd count therefore ends on one big sticker rather than a hole. * * Unlike the media grid, this never collapses into "+N more" — every sticker * sent is drawn. They are small and deliberately playful, and hiding some @@ -16,6 +22,10 @@ import { useState } from "react"; import Image from "next/image"; import { toast } from "sonner"; import { chat, type Attachment } from "@/lib/chat"; +import { cn } from "@/lib/utils"; + +/** At most two per row, as WhatsApp and Telegram do. */ +const STICKERS_PER_ROW = 2; export function StickerGrid({ conversationId, @@ -47,32 +57,55 @@ export function StickerGrid({ } }; + // Chunk into rows of at most two. Doing this in JS rather than CSS is what + // lets a row know how many it holds, which is what sets the size. + const rows: Attachment[][] = []; + for (let i = 0; i < stickers.length; i += STICKERS_PER_ROW) { + rows.push(stickers.slice(i, i + STICKERS_PER_ROW)); + } + return ( -
- {stickers.map((a) => ( - + // w-fit so the block hugs its rows: any fixed width would reintroduce the + // empty space this layout exists to remove. +
+ {rows.map((row, i) => ( +
+ {row.map((a) => { + const alone = row.length === 1; + return ( + + ); + })} +
))}
);