Skip to content

Fix chat images and unread#645

Merged
feruzm merged 2 commits intodevelopfrom
chatt
Feb 6, 2026
Merged

Fix chat images and unread#645
feruzm merged 2 commits intodevelopfrom
chatt

Conversation

@feruzm
Copy link
Copy Markdown
Member

@feruzm feruzm commented Feb 6, 2026

Summary by CodeRabbit

  • New Features

    • Images in chat messages now support interactive zoom with a dark overlay and margin; zoom is initialized after image load for better performance.
  • Bug Fixes

    • Direct message channels for deactivated users are excluded from channel lists and unread/mention/thread totals, preserving counts for active or unknown users.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 6, 2026

📝 Walkthrough

Walkthrough

Filters deactivated direct-message channels by checking delete_at on Mattermost users in two API routes, and adds a new client-side ChatImage component that lazy-initializes medium-zoom for images and replaces inline img usage in the chat view.

Changes

Cohort / File(s) Summary
Mattermost DM filtering
apps/web/src/app/api/mattermost/channels/route.ts, apps/web/src/app/api/mattermost/channels/unreads/route.ts
Added optional delete_at?: number to MattermostUser. Both routes now fetch DM partner user records, build exclusion sets for channels whose other user is deactivated (delete_at > 0), and filter out those DM channels before computing counts and returning results.
Chat image rendering
apps/web/src/features/chat/components/chat-image.tsx, apps/web/src/features/chat/mattermost-channel-view.tsx
New exported ChatImage component (lazy medium-zoom with dark background and 24px margin). Replaced inline img renderings in mattermost-channel-view with ChatImage.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • DM warning #630: Touches the Mattermost unreads channel processing route; likely related to DM filtering logic.

Poem

🐰 I nibble through channels, checking who's gone,
Quiet the deactivated, tidy the lawn,
Images hop bigger with a gentle zoom,
Chats feel cozier, bright as the moon,
Hooray for small fixes — a rabbit's soft song.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title partially relates to the changeset. It mentions 'chat images' and 'unread', which correspond to changes in chat image rendering and unread channel filtering, but omits the significant Mattermost user deactivation logic that is a core part of the changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chatt

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@apps/web/src/features/chat/components/chat-image.tsx`:
- Around line 12-41: Reset isLoaded (and clear any existing zoom) when the src
prop changes so the effect that creates mediumZoom runs for the new image; add a
useEffect that watches src and calls setIsLoaded(false) and detaches/clears
zoomRef.current (the zoomRef used in ChatImage) so the old zoom overlay is
removed before the new image loads, keeping the existing onLoad/useEffect logic
intact.
🧹 Nitpick comments (4)
apps/web/src/app/api/mattermost/channels/route.ts (2)

183-211: DM deactivation filter logic is correct; the type assertion on Line 207 is noisy.

The filter correctly excludes channels where the other user has delete_at > 0. However, the cast on Line 207 is verbose because TypeScript can't narrow the union produced by .map(). A cleaner approach is to store directUser in the mapped object for all branches (or chain the filter inside the D-type branch).

♻️ Simplify by always including `directUser` in the mapped result
     const channelsWithDirectUsers = filteredChannels
       .map((channel) => {
-        if (channel.type !== "D") return channel;
+        if (channel.type !== "D") return { ...channel, directUser: null as MattermostUser | null };
 
         const parts = channel.name?.split("__") ?? [];
         const otherUserId =
@@ ... @@
       })
       // Filter out DM channels where the other user has been deactivated
       .filter((channel) => {
         if (channel.type !== "D") return true;
-        const directUser = (channel as typeof channel & { directUser: MattermostUser | null }).directUser;
+        const directUser = channel.directUser;
         // Keep channel if directUser doesn't exist (can't determine) or if they're not deactivated
         if (!directUser) return true;
         return !directUser.delete_at || directUser.delete_at === 0;
       });

32-32: Multiple MattermostUser interfaces across the codebase — consider consolidating.

There are at least four separate MattermostUser interface definitions: apps/web/src/server/mattermost.ts (Lines 14-18), apps/web/src/features/chat/mattermost-api.ts (Lines 546-553), this file, and the unreads route. The delete_at field is now added here and in the unreads route but not in the shared definitions. If any shared code starts consuming delete_at, it won't be typed.

This is low-priority but worth tracking to avoid drift.

apps/web/src/app/api/mattermost/channels/unreads/route.ts (2)

139-186: Extra /users/ids fetch on every unread poll may add latency.

This route is likely polled frequently (for badge counts, etc.). The new POST /users/ids call on every request adds a round-trip to the Mattermost server. For users with many DM channels, this could noticeably increase response time.

Consider caching the deactivated-user set (e.g., short TTL in-memory or via a shared utility) so the fetch doesn't happen on every poll. This is not blocking for the current fix but worth considering if you observe latency increases.


139-186: DM channel name-parsing logic is duplicated across channels/route.ts and this file.

The channel.name?.split("__")parts.find(id => id !== currentUser.id) || parts[0] pattern appears in both routes (and multiple times within each). Extracting a small helper (e.g., getOtherDmUserId(channelName, currentUserId)) would reduce duplication and the risk of them diverging.

Comment thread apps/web/src/features/chat/components/chat-image.tsx
@feruzm feruzm merged commit 3124b71 into develop Feb 6, 2026
1 check passed
@feruzm feruzm deleted the chatt branch February 6, 2026 07:38
@coderabbitai coderabbitai Bot mentioned this pull request Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant