Skip to content

feat(threads): implement thread side panel with full functionality#123

Open
Just-Insane wants to merge 11 commits intoSableClient:devfrom
Just-Insane:feat/threads
Open

feat(threads): implement thread side panel with full functionality#123
Just-Insane wants to merge 11 commits intoSableClient:devfrom
Just-Insane:feat/threads

Conversation

@Just-Insane
Copy link
Contributor

@Just-Insane Just-Insane commented Mar 10, 2026

Summary

Implements Matrix thread support with side panels, browser, and notification integration.

Features

  • Thread Drawer: Side panel for viewing and replying within threads
    • Full message rendering with replies, reactions, edits, and deletions
    • Emoji picker and sticker support
    • Automatic read receipt management
  • Thread Browser: Panel listing all room threads with search functionality
  • Thread Chips: Visual indicators on messages that start threads
    • Shows reply count
    • Click to open thread
  • Unread Badge: Discord-style notification badge on thread icon showing unread count
  • Cross-device Sync: Threads created on other devices automatically appear in list
    • Initializes Thread objects from room history on mount
    • Auto-creates Thread objects when receiving new thread events
  • Notification Integration: Clicking inbox notifications for thread replies opens the thread

Implementation Details

  • Uses matrix-js-sdk Thread API (room.createThread(), room.getThreads())
  • Filters thread replies from main timeline
  • Scans timeline on mount to initialize Thread objects for existing threads
  • Auto-creates Thread objects when receiving ThreadEvent.New
  • Auto-opens drawer when navigating to thread events from notifications
  • Tracks unread status using thread.getEventReadUpTo() and thread.hasCurrentUserParticipated

Related

Future enhancement tracked in #124 to leverage SDK's thread-specific notification APIs (getThreadUnreadNotificationCount(), hasThreadUnreadNotification()).

@Just-Insane
Copy link
Contributor Author

Also Fixes #124 - Use the SDK's notification options, will properly respect user's notification settings.

@Just-Insane Just-Insane marked this pull request as ready for review March 10, 2026 05:58
@Just-Insane Just-Insane requested a review from a team March 10, 2026 05:58
@Just-Insane Just-Insane marked this pull request as draft March 10, 2026 12:11
Evie Gauthier added 7 commits March 10, 2026 11:08
- Add device capability detection using same logic as sliding sync
- Implement background pagination on room open with adaptive limits:
  - High-end (4g+/desktop/high-memory): 500 messages, 1s delay
  - Medium (3g or <=4GB RAM): 250 messages, 2s delay
  - Low-end (save-data/2g or mobile): 100 messages, 3s delay
- Detection based on: connection type, device memory, save-data preference
- Improves message history availability without blocking initial room load
- Consistent with sliding sync's adaptive behavior
- Export AdaptiveSignals type and readAdaptiveSignals() from device-capabilities.ts
- Update slidingSync.ts to import shared logic instead of duplicating it
- Single source of truth for device capability detection across the app
- Reduces code duplication and ensures consistent behavior
- Add ThreadDrawer component with message rendering and input
- Add ThreadBrowser panel for viewing all threads in a room
- Add thread chips on messages showing reply count and participants
- Enable message actions in threads (edit, react, reply, delete)
- Add emoji and sticker rendering support in threads
- Filter thread replies from main timeline to avoid duplicates
- Auto-create Thread objects when starting threads or syncing from other devices
- Add unread thread badge to header icon (Discord-style)
- Auto-open thread drawer when navigating to thread events from notifications
- Reorder room header icons: search, pinned, threads, widgets, members, more
- Add automatic read receipts when viewing threads

Fixes thread browser showing empty list and inbox notifications not opening threads.
- Move readAdaptiveSignals import to top with other imports
- Fixes unconventional import placement from previous refactor
…nation

Add actual scroll position check (150px threshold) to ResizeObserver forceScroll
to prevent it from forcing scroll to bottom when back paginating. During back
pagination, messages load at the top causing content resize, but if atBottomRef
hasn't updated yet from the scroll, it would incorrectly scroll to bottom.

Now checks both: atBottomRef.current AND distance from bottom < 150px before
forcing scroll, ensuring back pagination doesn't get interrupted.
Remove ThreadMockupPage and related route - no longer needed as threads
are fully implemented.
Evie Gauthier added 4 commits March 10, 2026 14:27
The thread mockup feature was removed in previous commits but the
button and navigation code remained in WelcomePage.tsx, causing
build failures. This removes:
- Thread mockup button from welcome page
- Unused useNavigate import and hook call
@Just-Insane Just-Insane marked this pull request as ready for review March 10, 2026 19:16
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