Conversation
✅ Deploy Preview for echo-ieeecs-vit ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
🟡 Changes recommended
Several introduced behaviors are currently incorrect (notably useChatScroll’s in-flight lock can deadlock across conversation switches, and the new toast API drops title despite being used by callers).
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR bundles multiple user-facing reliability and UX fixes across messaging, auth flows, and UI notifications, including a new centralized toast system, basic client-side message moderation, and several chat/query consistency improvements.
Changes:
- Introduces a new toast system (
toastService+ToastProvider) and replaces ad-hocalert/local toast state with centralized notifications and normalized error messaging. - Adds message moderation utilities (blacklist token matching + error-code detection) and integrates moderation checks into message send flows.
- Improves chat/query correctness: scoped reaction caching cleanup, debounced realtime cache flushing on unmount, safer API URL building, and scroll pagination concurrency control.
File summaries
| File | Description |
|---|---|
| src/lib/security/safeUrl.ts | Tightens allowed URL protocols for links/media. |
| src/lib/query/RealtimeCacheSync.tsx | Flushes pending query invalidations/removals during effect cleanup. |
| src/lib/query/reactionStore.ts | Adds helper to remove reaction entries for message IDs. |
| src/lib/query/reactionStore.test.ts | Adds tests for reaction removal helper. |
| src/lib/moderation/index.ts | Exposes moderation utilities and a toast notification helper. |
| src/lib/moderation/checkMessage.ts | Adds whole-token blacklist matching and moderation error detection. |
| src/lib/moderation/checkMessage.test.ts | Adds tests for token-based moderation and error detection. |
| src/lib/moderation/blacklist.ts | Adds moderation error code and blocked-word list. |
| src/lib/dm/messageUtils.ts | Adds helper to remove DM messages by ID set from paginated data. |
| src/lib/channels/mentions.ts | Centralizes role mention regex and updates role mention parsing. |
| src/lib/channels/mentions.test.ts | Adds tests for spaced and adjacent role mentions. |
| src/lib/auth/tokenStore.ts | Uses centralized API URL builder for refresh endpoint. |
| src/lib/apiUrl.ts | Adds API base URL builder that strips/normalizes slashes. |
| src/hooks/useTokenRefresh.ts | Adds toast warning on session expiry before redirect. |
| src/hooks/useMessageReactions.ts | Scopes reaction fetch tracking and clears reactions on scope change. |
| src/hooks/useChatScroll.ts | Refactors older-page loading into a reusable async helper with locking. |
| src/hooks/useChannelPermissions.ts | Changes default canSend permission to false. |
| src/hooks/useChannelMessages.ts | Exposes loadError status to consumers. |
| src/hooks/useChannelMembers.ts | Uses centralized API URL builder for member fetch. |
| src/contexts/ToastContext.tsx | Re-exports toast provider/service/types from new toast module. |
| src/components/VoiceVideoControls.tsx | Replaces alert() with toast error notification. |
| src/components/toast/types.ts | Adds shared toast types/options/items for new system. |
| src/components/toast/toastService.ts | Implements global toast store with subscribe/update/dismiss APIs. |
| src/components/toast/toastService.test.ts | Adds tests for toast service behavior (types, dedupe, lifecycle, etc.). |
| src/components/toast/ToastProvider.tsx | Adds provider bridging React context to the toast service store. |
| src/components/toast/ToastContainer.tsx | Adds toast list container layout and dismissal wiring. |
| src/components/toast/Toast.tsx | Adds new toast UI with progress bar, variants, and accessibility attributes. |
| src/components/toast/errorNormalizer.ts | Adds centralized safe error-to-message normalization. |
| src/components/toast/errorNormalizer.test.ts | Adds tests ensuring errors map to safe messages without leaking backend details. |
| src/components/Toast.tsx | Removes legacy toast component implementation. |
| src/components/SelfAssignRoles.tsx | Uses error normalizer for user-facing errors. |
| src/components/RouteChangeLoader.tsx | Simplifies cleanup to ensure timers are cleared on unmount. |
| src/components/profile/UserProfileCard.tsx | Uses error normalizer for friend action failures. |
| src/components/MessageInputWithMentions.tsx | Uses shared role mention regex, adds moderation check, debounces mention search cleanup. |
| src/components/MessageContentWithMentions.tsx | Uses shared role mention regex for consistent parsing/highlighting. |
| src/components/JoinServerModal.tsx | Adds success toast on join. |
| src/components/ErrorBoundary.tsx | Adds client-side error boundary with reset support and fallback UI. |
| src/components/ChatWindow.tsx | Replaces local toast state/alerts with global toasts; adds moderation handling; uses API URL builder. |
| src/components/ChatPage.tsx | Replaces per-page toast state with global toasts; adds moderation handling for DMs and load-error toasts. |
| src/app/page.tsx | Adds sign-in in-flight guard and uses toast + auth error normalization. |
| src/app/layout.tsx | Wraps app in ErrorBoundary at the root layout. |
| src/app/globals.css | Adds toast-out and progress bar keyframes/styles. |
| src/app/(auth)/reset-password/page.tsx | Adds success toast and uses error normalizer. |
| src/app/(auth)/oauth-callback/page.tsx | Uses toast loading/update lifecycle and auth error normalization; ensures timers cleanup. |
| src/app/(auth)/forgot-password/page.tsx | Adds basic email validation, better input attrs, and normalized errors. |
| src/app/(auth)/change-password/page.tsx | Updates commented import reference to new toast system. |
| src/app/(auth)/auth/callback/page.tsx | Removes unused useSearchParams dependency from effect. |
| src/app/(app)/servers/page.tsx | Replaces local toast state/alerts with global toasts and normalized errors. |
| src/app/(app)/server-settings/components/ServerSettings/Role.tsx | Adds success toasts and normalized errors for role/category operations. |
| src/app/(app)/server-settings/components/ServerSettings/Overview.tsx | Uses error normalizer for save failures. |
| src/app/(app)/server-settings/components/ServerSettings/Members.tsx | Adds success toasts and normalized errors for member/role operations. |
| src/app/(app)/server-settings/components/ServerSettings/Leave.tsx | Adds success toast and normalized error on leave failure. |
| src/app/(app)/server-settings/components/ServerSettings/InvitePeople.tsx | Uses error normalizer for invite creation failures. |
| src/app/(app)/server-settings/components/ServerSettings/DangerZone.tsx | Uses error normalizer for delete/transfer failures. |
| src/app/(app)/server-settings/components/ServerSettings/BannedUsers.tsx | Uses error normalizer for banned user load/unban failures. |
| src/app/(app)/server-settings/components/ServerSettings/AddChannel.tsx | Uses error normalizer for channel creation failures. |
| src/app/(app)/profile/page.tsx | Replaces local toast state with toast loading/update lifecycle for logout. |
| src/app/(app)/profile-settings/page.tsx | Uses toast loading/update lifecycle for logout. |
| src/app/(app)/layout.tsx | Wraps main app content in ErrorBoundary keyed by pathname. |
| src/app/(app)/invite/[code]/page.tsx | Uses toast + auth error normalization on OAuth initiation failure. |
| src/app/(app)/friends/page.tsx | Replaces inline error strings with toasts and normalized errors; adds success toasts. |
| src/app/(app)/delete-account/page.tsx | Switches to shared axios client + toasts + normalized errors; adds in-flight state. |
| src/api/message.api.ts | Avoids logging cancellations while still rethrowing. |
Review details
Suppressed comments (2)
src/components/toast/toastService.ts:54
- Even after adding a
titleparameter, the createdToastItemcurrently omitstitle, so it will still be lost before it reachesToastrendering.
src/components/toast/toastService.ts:105 - The shorthand helpers (
toast.error(...), etc.) acceptToastOptionsbut currently only forwardduration. That dropstitlefor callers likenotifyModerationBlocked().
- Files reviewed: 63/63 changed files
- Comments generated: 4
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| export function showToast( | ||
| message: string, | ||
| type: ToastType = "info", | ||
| duration?: number | ||
| ): string { |
| try { | ||
| return await opts.onLoadOlder(); | ||
| } finally { | ||
| if (keyRef.current === requestedKey) { | ||
| olderInFlightRef.current = false; | ||
| } | ||
| } |
| export const normalizeRoleName = (name: string): string => | ||
| name.trim().toLowerCase().replace(/\s+/g, " "); | ||
|
|
||
| export const ROLE_MENTION_REGEX = /@&([a-zA-Z_][a-zA-Z0-9_\s]*)\b/g; |
| it("uses sensible default durations and keeps loading sticky", () => { | ||
| toast.success("ok"); | ||
| toast.loading("busy"); | ||
| const [success, loading] = getToasts(); | ||
| expect(success.duration).toBe(3000); | ||
| expect(success.duration).toBe(3000); | ||
| expect(loading.duration).toBe(0); | ||
| }); |
No description provided.