From 72b7b79cafb048e4705e29f96f501d35cd893def Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 8 Sep 2026 05:27:41 +0800 Subject: [PATCH] fix(web): code review round 3 -- UI bugs and remaining design fidelity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - FileAttachment never surfaced a failed authenticated download -- the card looked identically clickable whether it worked or not, and clicking while broken silently no-op'd. Added an error state/retry (useAuthedBlobUrl gained a retry() escape hatch for this). ImageAttachment/AudioAttachment already handled this; only the file card didn't. - --shadow-btn was one token serving two different specs: round 2's fix (0 6px 16px, from the 50px auth CTAs) actually regressed the 36px messaging send button (ConversationView/VoiceRecorder), which needs 0 4px 12px per 02-messages.dc.html. Split into --shadow-btn / --shadow-btn-sm. - loadOlder's scroll-restore guard compared topicId by value, which false-positives on an A->B->A round trip within one request's lifetime (same string, but the DOM was torn down and rebuilt by the intervening open/close). Switched to a generation counter, same pattern as topics.ts's leave-race fix. - errorToast wasn't included in ConversationView/DetailColumn's topicId-reset effects -- a failed action's toast could keep showing over a conversation/contact switched to afterward. Also switched those effects (and MessagesLayout's) from useEffect to useLayoutEffect -- since none of these components remount on topicId change, a post-paint effect could let one frame render with the previous topicId's stale UI still showing. - VoiceRecorder never listened for MediaRecorder's own onerror -- a mid-recording failure left the "录音中" timer ticking forever with no indication the recording had already died. - VerificationCodeButton's phone-change countdown reset (round 2) only cleared the button's own state; RegisterPage/ResetPasswordPage's challengeId was still tied to whatever phone the code was actually issued for, with nothing cross-checking it against a since-edited phone number. - Agreement's checkbox used bare accent-color on a native input, which only tints the checked fill and leaves size/radius/border to the browser/OS; replaced with the spec's exact 16x16 border-radius:4px box + check glyph. - Added a catch-all route (App.tsx), TenantFeedbackPage image-picker validation feedback + corrected remove-button style, and a handful of smaller token/spacing corrections against screens/*.dc.html (NavRail font-weight, LoginPage/TenantEntryPage logo size+shadow+color, ChatListColumn row padding/icon size, --shadow-modal alpha). Co-Authored-By: Claude Sonnet 5 --- web/src/App.tsx | 4 ++ web/src/app/NavRail.tsx | 2 +- web/src/features/auth/LoginPage.tsx | 10 +++-- web/src/features/auth/RegisterPage.tsx | 10 ++++- web/src/features/auth/ResetPasswordPage.tsx | 10 ++++- web/src/features/auth/TenantEntryPage.tsx | 9 ++++- web/src/features/auth/TenantFeedbackPage.tsx | 13 +++--- .../features/auth/components/Agreement.tsx | 21 +++++++--- .../features/messages/AttachmentPreview.tsx | 17 ++++++-- web/src/features/messages/ChatListColumn.tsx | 6 +-- .../features/messages/ConversationView.tsx | 40 ++++++++++++------- web/src/features/messages/DetailColumn.tsx | 12 ++++-- web/src/features/messages/MessagesLayout.tsx | 4 +- web/src/features/messages/VoiceRecorder.tsx | 12 +++++- web/src/index.css | 6 ++- web/src/lib/hooks.ts | 7 ++-- 16 files changed, 130 insertions(+), 53 deletions(-) diff --git a/web/src/App.tsx b/web/src/App.tsx index b5480df3..d0a07f24 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -48,6 +48,10 @@ const router = createBrowserRouter([ }, ], }, + // A stale bookmark/link to a route renamed during this redesign should land somewhere the app + // itself resolves (tenant/login/messages, per RequireAuth's own gating), not React Router's + // generic unstyled default error boundary. + { path: '*', element: }, ]); export default function App() { diff --git a/web/src/app/NavRail.tsx b/web/src/app/NavRail.tsx index 3760659b..4e01e616 100644 --- a/web/src/app/NavRail.tsx +++ b/web/src/app/NavRail.tsx @@ -46,7 +46,7 @@ function NavRailButton({ item }: { item: NavRailItem }) { export function NavRail({ selfInitial = '我', unreadMessages = 0 }: { selfInitial?: string; unreadMessages?: number }) { return (