fix: call media-connect state, blocklist banner staleness, group rename, avatar URL

- stores/calls.ts, CallRoot.tsx: distinguish signaling-connected from
  actual media-joined (mediaJoined flag), so a call whose mic never
  attaches no longer shows a live timer/"网络良好"; propagate a
  disconnected reason on post-accept media failure so both sides agree
  on the outcome instead of one side seeing a normal "已结束".
- DetailColumn.tsx: invalidate conversation-context alongside blocks on
  block/unblock, so the composer's blocked-notice banner updates
  immediately instead of only after a window-focus refetch.
- GroupDetailColumn.tsx: add an owner-only group rename control
  (updateGroup was already implemented but never wired to any UI).
- Avatar.tsx: stop re-wrapping an already-absolute avatar_file_id (seen
  on default-avatar placeholders) into a malformed
  /v0/file/s/https://... request.
This commit is contained in:
Your Name
2026-09-18 15:01:08 +08:00
parent 0c5b329179
commit 7fff1a7b3a
5 changed files with 133 additions and 22 deletions
+10 -4
View File
@@ -20,12 +20,18 @@ interface AvatarProps {
* through every profile-update API in this app but never actually RENDERED anywhere -- every avatar
* call site across the whole codebase drew only the letter-tile fallback, so uploading a custom
* avatar produced zero visible change anywhere, including on the very page the upload happened.
* `avatar_file_id` is a bare file id (e.g. "abc123"), not a ref path -- reconstruct the
* `/v0/file/s/{id}` shape `useAuthedBlobUrl` (same authenticated-fetch-to-blob-URL mechanism already
* used for chat attachments) expects.
* `avatar_file_id` is USUALLY a bare file id (e.g. "abc123"), needing the `/v0/file/s/{id}` shape
* `useAuthedBlobUrl` (same authenticated-fetch-to-blob-URL mechanism already used for chat
* attachments) reconstructed -- but live-confirmed (2026-09-18, real console error): default-avatar
* placeholders come back as an ALREADY-COMPLETE OSS URL in this same field (e.g.
* "https://im-oss-t1.oss-cn-shenzhen.aliyuncs.com/im-assets/default-avatars/male/2.png"), which this
* used to unconditionally re-wrap into "/v0/file/s/https://...", a malformed request that 404s.
* `useAuthedBlobUrl`/`fileDownloadUrl` already accept either shape (see hooks.ts's own comment) --
* only needed to stop force-prefixing a value that's already a full URL.
*/
export function Avatar({ id, name, avatarFileId, className = '', fallbackBgClass }: AvatarProps) {
const remote = useAuthedBlobUrl(avatarFileId ? `/v0/file/s/${avatarFileId}` : undefined);
const isAbsoluteUrl = !!avatarFileId && /^https?:\/\//.test(avatarFileId);
const remote = useAuthedBlobUrl(avatarFileId ? (isAbsoluteUrl ? avatarFileId : `/v0/file/s/${avatarFileId}`) : undefined);
if (remote.url) {
return <img src={remote.url} alt="" className={`object-cover ${className}`} />;
}