Adds removeGroupMember (DELETE /groups/{topic}/members/{user_id}) --
confirmed live the backend now has this route (server/im_http.go's
serveIMGroupMember + canRemoveIMGroupMember), which an earlier pass
recorded as a genuine protocol gap; it isn't anymore. Wired into
GroupMembersModal with a per-row "移出" button gated by the same rule
the backend enforces (owner or admin removes a plain member, only the
owner removes an admin, nobody removes the owner or themselves), with
a confirm dialog before the real DELETE call. Verified live end-to-end
against a real owned group: member count 4 -> 3, list updates
correctly (the side panel's own separate "群成员 N" summary count
still trailed behind after this -- confirmed via a direct GET that the
server's own group payload hadn't recalculated member_count yet, a
backend read-consistency lag unrelated to this fix, not chased
further).
Also fixes the reported "已处理的群邀请消息,即使群解散了,接受邀请
按钮还是一直可以点" bug: the button's visibility used to be derived
purely from the notification's static action payload every render, so
neither a successful accept nor a definitively-failed one (expired,
already handled, group gone) ever stopped it from looking freshly
clickable again. Tracks per-invitation resolved state (accepted/
failed) once either outcome happens and swaps the button for a static
resolved label. Doesn't survive a page reload for invitations resolved
in an earlier visit (the notification record itself carries no
resolved flag to read back) -- a real, acknowledged limit, not
silently hidden.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Backend added read_count/member_count/read_summary to the announcement
payload in today's deploy (previously confirmed absent). Wire it up:
- groups.ts: add the three fields to the GroupAnnouncement type.
- GroupAnnouncementModal.tsx: render "已读N/M" per README §4.8, and
call readGroupAnnouncement() on open -- that endpoint existed in
groups.ts already but was never called from anywhere, so opening an
announcement never told the server this member had read it.
Rounds out the full rewrite with the remaining feature domains: group
management (admin panel, mute, files, announcements, QR-based invite/join),
contacts (friend profile, add-friend, blocklist, new-friends), favorites
(real media rendering across text/image/video/voice/file/link), settings
(profile/security/privacy/general/about), calls (Agora-backed audio/video
signaling + call history), and system messages/file assistant.
Also folds in a large batch of live-verified fixes surfaced by repeated
fresh code-review passes and hands-on E2E testing against the real
backend, including: WS reconnect not resubscribing any topic after a
disconnect, missing x-im-client-mid on every send path (protocol
compliance for retry dedup), group mute/member-settings/self-profile
endpoint corrections, relationship-state type fixes across search/QR/
friend-profile, tenant-switch logout gap, password-policy now read from
the real per-tenant config instead of guessed, NavRail highlight/
aria-current desync, several call-state-machine races, and responsive
layout fixes across all four breakpoints (mobile/tablet/laptop/desktop)
including a full mobile rebuild of favorites, call UI, and the settings
home/sub-list split.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>