修复邀请入群交互:点击邀请要直接进入邀请,而不是先看成员列表再点第二次

用户实测反馈的真实bug:GroupDetailColumn里那个专门的"+邀请"图标(虚线边框
方块,只有canInvite为真才显示——这个权限门控本身一直是对的)点击后走的是
setOpenModal('members'),和"查看全部成员"是完全同一个入口——弹出的是成员
列表,标题栏里那个真正的"邀请"按钮还要再点一次才能看到可邀请的联系人列表。

GroupMembersModal新增initialView属性,"invite"直接以邀请视图打开(跳过
成员列表这一步),"查看全部"/"查看全部成员"两处不受影响仍然打开成员列表。

同时补全了邀请结果的反馈——原来邀请成功后只做了查询失效,无论是"立即加入"
还是需要对方/群设置审批的"待确认",界面上都没有任何区别于点击前的视觉反馈,
容易让人怀疑是不是点了没反应从而重复点击。读了im_be的serveIMGroupInvitations
源码(不是协议文档的单一示例)确认真实的单人邀请结果有joined/already_member/
pending/pending_approval/failed五种可能,现在每种都有对应的行内文案,
"failed"不计入"已处理"状态,允许原地重试。

实机验证:全新建群后点"+邀请"直接进入邀请视图(标题"邀请成员",不经过成员
列表);邀请一个全新好友后确认成功加入、群成员数正确从2变3、界面正确显示
结果反馈。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-09-16 22:26:12 +08:00
co-authored by Claude Sonnet 5
parent 3fab8b08b9
commit 66dad284c7
2 changed files with 68 additions and 12 deletions
+15 -4
View File
@@ -81,7 +81,7 @@ export function GroupDetailColumn({ topicId, peerName, onClose, onOpenHistory }:
const [nicknameEditing, setNicknameEditing] = useState(false);
const [nicknameDraft, setNicknameDraft] = useState('');
const [errorToast, setErrorToast] = useState('');
const [openModal, setOpenModal] = useState<'members' | 'announcement' | 'files' | 'admin' | 'qrcode' | null>(null);
const [openModal, setOpenModal] = useState<'members' | 'invite' | 'announcement' | 'files' | 'admin' | 'qrcode' | null>(null);
const showError = (err: unknown, fallback: string) => setErrorToast(err instanceof Error ? err.message : fallback);
// Same long-lived-instance leak this exact pattern already caused twice in DetailColumn.tsx --
@@ -284,7 +284,13 @@ export function GroupDetailColumn({ topicId, peerName, onClose, onOpenHistory }:
</div>
))}
{canInvite ? (
<button type="button" onClick={() => setOpenModal('members')} className="flex flex-col items-center gap-1">
// Goes straight to the invite-candidates view (GroupMembersModal's `initialView=
// "invite"`), not the member list -- this dedicated "+邀请" tile landing on the member
// list and requiring a SECOND click on an in-modal "邀请" button was a real, reported
// UX complaint ("点击邀请那个按钮弹出的并不是直接到邀请,而是显示的成员列表,还要再次
// 点击邀请"). "查看全部"/"查看全部成员" right below/above this still correctly open the
// plain member list -- only THIS tile's whole purpose is inviting.
<button type="button" onClick={() => setOpenModal('invite')} className="flex flex-col items-center gap-1">
<span className="grid h-11 w-11 place-items-center rounded-lg border border-dashed border-[#c5cad2] text-text-tertiary-3 md:h-10 md:w-10">
<Icon name="add" className="text-[18px]" />
</span>
@@ -420,8 +426,13 @@ export function GroupDetailColumn({ topicId, peerName, onClose, onOpenHistory }:
<Toast message={errorToast} variant="error" onDone={() => setErrorToast('')} />
{openModal === 'members' ? (
<GroupMembersModal topicId={topicId} canInvite={canInvite} onClose={() => setOpenModal(null)} />
{openModal === 'members' || openModal === 'invite' ? (
<GroupMembersModal
topicId={topicId}
canInvite={canInvite}
initialView={openModal === 'invite' ? 'invite' : 'members'}
onClose={() => setOpenModal(null)}
/>
) : null}
{openModal === 'announcement' ? (
<GroupAnnouncementModal topicId={topicId} canEdit={isAdmin} onClose={() => setOpenModal(null)} />