diff --git a/web/src/features/messages/ForwardPickerModal.tsx b/web/src/features/messages/ForwardPickerModal.tsx index f27e19fd..55a7d03e 100644 --- a/web/src/features/messages/ForwardPickerModal.tsx +++ b/web/src/features/messages/ForwardPickerModal.tsx @@ -14,6 +14,19 @@ interface ForwardPickerModalProps { onClose: () => void; } +/** A hand-drawn checkmark instead of the Material Icons font glyph this row used to use -- the font + * glyph's hinting isn't tuned for a 14px render inside a 20px circle, so at anything above 1x pixel + * density it comes out visibly soft/asymmetric where a vector path stays crisp at any scale. Not a + * systemic swap (`Icon` is still how the rest of the app draws icons) -- scoped to this one + * selection indicator, which is the one a user actually screenshotted and flagged as rough-looking. */ +function CheckMark({ className = '' }: { className?: string }) { + return ( + + ); +} + /** * README §3.6: multi-select targets + an optional comment, sent in one action. Used by the message * context menu's single-message "转发", the multi-select bulk bar's "转发", and favorites' bulk @@ -30,6 +43,9 @@ export function ForwardPickerModal({ onPick, onClose }: ForwardPickerModalProps) const [query, setQuery] = useState(''); const [selected, setSelected] = useState>(new Set()); const [comment, setComment] = useState(''); + // Both start expanded -- collapsing is for a long list getting in the way of the OTHER section, + // not a default state anyone would want on first open. + const [collapsed, setCollapsed] = useState<{ friends: boolean; groups: boolean }>({ friends: false, groups: false }); useEscapeKey(onClose); const filtered = contacts.filter((c) => !query.trim() || (c.public?.fn || '').includes(query.trim())); @@ -75,6 +91,10 @@ export function ForwardPickerModal({ onPick, onClose }: ForwardPickerModalProps) }); }; + const toggleCollapsed = (section: 'friends' | 'groups') => { + setCollapsed((prev) => ({ ...prev, [section]: !prev[section] })); + }; + const send = () => { if (selected.size === 0) return; onPick([...selected], comment.trim()); @@ -96,14 +116,26 @@ export function ForwardPickerModal({ onPick, onClose }: ForwardPickerModalProps) {c.public?.fn || c.topic} - {isSelected ? : null} + {isSelected ? : null} ); }; + const renderSectionHeader = (label: string, section: 'friends' | 'groups', topics: string[], allSelected: boolean) => ( +
+ + +
+ ); + return (
e.stopPropagation()}> @@ -130,32 +162,14 @@ export function ForwardPickerModal({ onPick, onClose }: ForwardPickerModalProps)
{friends.length ? ( <> -
- 好友 - -
- {friends.map(renderRow)} + {renderSectionHeader('好友', 'friends', friendTopics, allFriendsSelected)} + {collapsed.friends ? null : friends.map(renderRow)} ) : null} {groups.length ? ( <> -
- 群聊 - -
- {groups.map(renderRow)} + {renderSectionHeader('群聊', 'groups', groupTopics, allGroupsSelected)} + {collapsed.groups ? null : groups.map(renderRow)} ) : null} {!friends.length && !groups.length ? (