fix(threads): viewing a room no longer reads threads you don't follow (#314)
CI / Build & Quality Checks (pull_request) Successful in 1m49s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 7s
CI / Playwright smoke (e2e) (pull_request) Successful in 13m31s
CI / Build & Quality Checks (pull_request) Successful in 1m49s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 7s
CI / Playwright smoke (e2e) (pull_request) Successful in 13m31s
A passive read (just looking at the room) sent a threaded receipt for every unread thread you don't follow, so the Threads panel's Unread filter and Mark all read only ever worked for followed threads. Decision (2026-10-19): leave them unread until opened, but stop counting unfollowed threads toward the room's unread dot (getUnreadInfo subtracts them like muted threads; a mention makes a thread followed, so highlights are never hidden). isThreadFollowed moves to utils/room. Adds a Playwright regression. Fixes #314 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
04605f2680
commit
fee3fbb7fc
@@ -18,6 +18,7 @@ import {
|
||||
NotificationCountType,
|
||||
RelationType,
|
||||
Room,
|
||||
Thread,
|
||||
RoomMember,
|
||||
TimelineEvents,
|
||||
IRoomTimelineData,
|
||||
@@ -418,6 +419,20 @@ export const roomHaveUnread = (mx: MatrixClient, room: Room) => {
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* [Gitea #217] Threads the user is following: they started it, replied in it,
|
||||
* or were mentioned in it. `hasCurrentUserParticipated` comes from the server's
|
||||
* thread bundle and lags a reply we just sent, so our own loaded events count too.
|
||||
*/
|
||||
export function isThreadFollowed(room: Room, thread: Thread, userId: string | null): boolean {
|
||||
if (thread.hasCurrentUserParticipated) return true;
|
||||
if (userId && thread.rootEvent?.getSender() === userId) return true;
|
||||
if (userId && thread.timeline?.some((e) => e.getSender() === userId)) return true;
|
||||
return (
|
||||
(room.getThreadUnreadNotificationCount(thread.id, NotificationCountType.Highlight) ?? 0) > 0
|
||||
);
|
||||
}
|
||||
|
||||
export const getUnreadInfo = (
|
||||
room: Room,
|
||||
mutedThreads?: Set<string>,
|
||||
@@ -439,6 +454,18 @@ export const getUnreadInfo = (
|
||||
if (highlight < 0) highlight = 0;
|
||||
}
|
||||
|
||||
// [Gitea #314] Threads you don't follow stay unread in the Threads panel
|
||||
// (viewing the room no longer reads them) but don't light the room's dot.
|
||||
// A mention makes a thread followed, so highlights are never subtracted.
|
||||
if (mx) {
|
||||
room.getThreads().forEach((thread) => {
|
||||
if (mutedThreads?.has(thread.id)) return;
|
||||
if (isThreadFollowed(room, thread, mx.getUserId())) return;
|
||||
total -= room.getThreadUnreadNotificationCount(thread.id, NotificationCountType.Total) ?? 0;
|
||||
});
|
||||
if (total < 0) total = 0;
|
||||
}
|
||||
|
||||
const resolvedTotal = highlight > total ? highlight : total;
|
||||
|
||||
// Suppress a spurious Total when the room isn't really unread. Two safe cases,
|
||||
|
||||
Reference in New Issue
Block a user