diff --git a/web/src/features/groups/GroupDetailColumn.tsx b/web/src/features/groups/GroupDetailColumn.tsx
index 92c7bbe9..7d2749b7 100644
--- a/web/src/features/groups/GroupDetailColumn.tsx
+++ b/web/src/features/groups/GroupDetailColumn.tsx
@@ -12,7 +12,6 @@ import { GroupAnnouncementModal } from '@/features/groups/GroupAnnouncementModal
import { GroupFilesModal } from '@/features/groups/GroupFilesModal';
import { GroupMembersModal } from '@/features/groups/GroupMembersModal';
import {
- canRemoveMember,
disbandGroup,
getGroup,
getMyGroupProfile,
@@ -20,7 +19,6 @@ import {
getGroupSettings,
getGroupSummary,
leaveGroup,
- removeGroupMember,
updateGroup,
updateGroupMemberSettings,
updateMyGroupNickname,
@@ -73,27 +71,6 @@ function RoleCorner({ role }: { role: GroupMember['role'] }) {
return null;
}
-/** Corner "-" badge for a removable member's avatar in the compact grid -- the "outside the avatar,
- * like the +邀请 tile" treatment (explicit user correction: a text "移出" link inside a member ROW is
- * the full-list modal's job, not this grid's). Opposite corner from RoleCorner (top-right, not
- * top-left) because both can legitimately apply to the same avatar at once -- an owner removing an
- * admin still needs the "管" tag AND this badge on one avatar. */
-function RemoveBadge({ pending, onRemove }: { pending: boolean; onRemove: () => void }) {
- return (
-
- );
-}
/**
* README §4.4's 群聊设置 detail rail (group-owner/admin/member view). Sibling of DetailColumn.tsx
@@ -207,19 +184,6 @@ export function GroupDetailColumn({ topicId, peerName, onClose, onOpenHistory }:
onError: (err) => showError(err, '群名保存失败'),
});
- // Drives the corner "-" badge on the compact member grid below -- same removeGroupMember call and
- // same invalidation keys as GroupMembersModal's own remove button (canRemoveMember is now shared
- // from lib/api/groups.ts so the two surfaces can't drift on who's eligible to remove whom).
- const removeMutation = useMutation({
- mutationFn: (userId: string) => removeGroupMember(topicId, userId),
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['group-members', topicId] });
- queryClient.invalidateQueries({ queryKey: ['group-members-preview', topicId] });
- queryClient.invalidateQueries({ queryKey: ['group', topicId] });
- },
- onError: (err) => showError(err, '移出失败,请重试'),
- });
-
// Both mutations call forgetTopic() the instant their own REST call succeeds, rather than waiting
// on the async native/`group.dissolved` gone-signal that normally follows a group actually going
// away -- real, user-reported bugs fixed by this: (1) the chat list kept showing a broken stale
@@ -409,17 +373,6 @@ export function GroupDetailColumn({ topicId, peerName, onClose, onOpenHistory }:
className="h-11 w-11 rounded-lg text-sm md:h-10 md:w-10"
/>
- {canRemoveMember(myUserId, myRole || 'member', m) ? (
- {
- const label = m.display_name || m.user_id;
- if (await requestConfirm({ message: `确定将"${label}"移出群聊吗?`, danger: true })) {
- removeMutation.mutate(m.user_id);
- }
- }}
- />
- ) : null}
{m.display_name || m.user_id}
))}
@@ -437,6 +390,20 @@ export function GroupDetailColumn({ topicId, peerName, onClose, onOpenHistory }:
邀请
) : null}
+ {isAdmin ? (
+ // Sibling tile to "+邀请" right above -- same dashed-square treatment, mirrored icon.
+ // A single standalone entry point into the plain member list (not a per-avatar corner
+ // badge, and not a direct remove action) -- the actual "移出" control already lives on
+ // each removable row inside that list. Explicit user correction after a first attempt
+ // put a "-" badge on every removable avatar's own corner: that read as "many separate
+ // remove buttons" when the intent was one "+"-shaped entry point, mirroring "+邀请".
+
+ ) : null}