From a818544df0453a8a935c1fa033eaa35ea07000bc Mon Sep 17 00:00:00 2001 From: qer Date: Fri, 24 Jul 2026 13:51:29 +0800 Subject: [PATCH] feat(sidebar): session emoji icon with searchable picker (#97) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(sidebar): session emoji icon with searchable picker A session's icon is the leading emoji cluster of its title (web-core splitSessionEmoji/applySessionEmoji) — no icon field, every client renders the title as-is, and writing reuses the existing rename path. SessionRow grows a kebab-menu 'Set Emoji…' entry (the touch/keyboard path) plus a quiet hover wash on the title's emoji; both open SessionEmojiPicker, a Menu-shelled panel with a bare search row (zh/en keyword dataset, ~400 grouped entries), a Recently-used row (localStorage, cap 8), and remove/random MenuItems. Inline rename edits only the title text and re-applies the icon on commit. DesignSystemView documents the pattern (§07 session row + no-emoji-icon's user-content scope); the two apps' copies of the row/picker stay in sync. * fix(sidebar): emoji picker review fixes - Unchanged text in the inline rename now skips the PATCH entirely, so stored titles that don't use the normalized "emoji + space" shape (e.g. "🔥bug") are kept byte-for-byte instead of being rewritten. - The picker's outside-click handler ignores the trigger element, so clicking the title emoji / kebab again toggles the picker closed instead of close-then-reopen. - Enter during IME composition no longer picks the first search result (useImeComposition guard on the search input). - Picker paddings/gaps moved onto --space-* tokens. * fix(sidebar): emoji picker review fixes, round 2 - The picker's Escape listener now runs in the capture phase and consumes the key, so dismissing the picker can't reach the conversation pane's bubble-phase handler and interrupt / undo the active turn. - The title emoji trigger is a real