Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Mark a thread as unread in the threads list due to activity.
Browse files Browse the repository at this point in the history
  • Loading branch information
clokep committed Dec 12, 2022
1 parent 9de5654 commit d66fa2e
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/Unread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function doesRoomHaveUnreadMessages(room: Room): boolean {
return false;
}

function doesRoomOrThreadHaveUnreadMessages(room: Room | Thread): boolean {
export function doesRoomOrThreadHaveUnreadMessages(room: Room | Thread): boolean {
const myUserId = MatrixClientPeg.get().getUserId();

// as we don't send RRs for our own messages, make sure we special case that
Expand Down
13 changes: 8 additions & 5 deletions src/hooks/useUnreadNotifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ limitations under the License.
*/

import { NotificationCount, NotificationCountType, Room, RoomEvent } from "matrix-js-sdk/src/models/room";
import { Thread } from "matrix-js-sdk/src/models/thread";
import { useCallback, useEffect, useState } from "react";

import { getUnsentMessages } from "../components/structures/RoomStatusBar";
import { getRoomNotifsState, getUnreadNotificationCount, RoomNotifState } from "../RoomNotifs";
import { NotificationColor } from "../stores/notifications/NotificationColor";
import { doesRoomHaveUnreadMessages } from "../Unread";
import { doesRoomOrThreadHaveUnreadMessages } from "../Unread";
import { EffectiveMembership, getEffectiveMembership } from "../utils/membership";
import { useEventEmitter } from "./useEventEmitter";

Expand Down Expand Up @@ -70,12 +71,14 @@ export const useUnreadNotifications = (room: Room, threadId?: string): {
setColor(NotificationColor.Red);
} else if (greyNotifs > 0) {
setColor(NotificationColor.Grey);
} else if (!threadId) {
// TODO: No support for `Bold` on threads at the moment

} else {
// We don't have any notified messages, but we might have unread messages. Let's
// find out.
const hasUnread = doesRoomHaveUnreadMessages(room);
let roomOrThread: Room | Thread = room;
if (threadId) {
roomOrThread = room.getThread(threadId)!;
}
const hasUnread = doesRoomOrThreadHaveUnreadMessages(roomOrThread);
setColor(hasUnread ? NotificationColor.Bold : NotificationColor.None);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ limitations under the License.
import React from "react";
import "jest-mock";
import { screen, act, render } from "@testing-library/react";
import { MatrixClient, PendingEventOrdering } from "matrix-js-sdk/src/client";
import { MsgType } from "matrix-js-sdk/src/matrix";
import { PendingEventOrdering } from "matrix-js-sdk/src/client";
import { NotificationCountType, Room } from "matrix-js-sdk/src/models/room";
import { mocked } from "jest-mock";
import { EventStatus } from "matrix-js-sdk/src/models/event-status";

import {
UnreadNotificationBadge,
} from "../../../../../src/components/views/rooms/NotificationBadge/UnreadNotificationBadge";
import { mkMessage, stubClient } from "../../../../test-utils/test-utils";
import { mkEvent, mkMessage, stubClient } from "../../../../test-utils/test-utils";
import { mkThread } from "../../../../test-utils/threads";
import { MatrixClientPeg } from "../../../../../src/MatrixClientPeg";
import * as RoomNotifs from "../../../../../src/RoomNotifs";

Expand All @@ -36,28 +37,35 @@ jest.mock('../../../../../src/RoomNotifs', () => ({
}));

const ROOM_ID = "!roomId:example.org";
let THREAD_ID;
let THREAD_ID: string;

describe("UnreadNotificationBadge", () => {
let mockClient: MatrixClient;
stubClient();
const client = MatrixClientPeg.get();
let room: Room;

function getComponent(threadId?: string) {
return <UnreadNotificationBadge room={room} threadId={threadId} />;
}

beforeAll(() => {
client.supportsExperimentalThreads = () => true;
});

beforeEach(() => {
jest.clearAllMocks();

stubClient();
mockClient = mocked(MatrixClientPeg.get());

room = new Room(ROOM_ID, mockClient, mockClient.getUserId() ?? "", {
room = new Room(ROOM_ID, client, client.getUserId()!, {
pendingEventOrdering: PendingEventOrdering.Detached,
});
room.setUnreadNotificationCount(NotificationCountType.Total, 1);
room.setUnreadNotificationCount(NotificationCountType.Highlight, 0);

const { rootEvent } = mkThread(
{ room, client, authorId: client.getUserId()!, participantUserIds: [client.getUserId()!] },
);
THREAD_ID = rootEvent.getId()!;

room.setThreadUnreadNotificationCount(THREAD_ID, NotificationCountType.Total, 1);
room.setThreadUnreadNotificationCount(THREAD_ID, NotificationCountType.Highlight, 0);

Expand Down Expand Up @@ -129,4 +137,33 @@ describe("UnreadNotificationBadge", () => {
const { container } = render(getComponent());
expect(container.querySelector(".mx_NotificationBadge")).toBeNull();
});

it.only("activity renders unread notification badge", () => {
act(() => {
room.setThreadUnreadNotificationCount(THREAD_ID, NotificationCountType.Total, 0);
room.setThreadUnreadNotificationCount(THREAD_ID, NotificationCountType.Highlight, 0);

// Add another event on the thread which is not sent by us.
const event = mkEvent({
event: true,
type: "m.room.message",
user: "@alice:server.org",
room: room.roomId,
content: {
"msgtype": MsgType.Text,
"body": 'Hello from Bob',
"m.relates_to": {
event_id: THREAD_ID,
rel_type: "m.thread",
},
},
});
room.addLiveEvents([event]);
});

const { container } = render(getComponent(THREAD_ID));
expect(container.querySelector(".mx_NotificationBadge_dot")).toBeTruthy();
expect(container.querySelector(".mx_NotificationBadge_visible")).toBeTruthy();
expect(container.querySelector(".mx_NotificationBadge_highlighted")).toBeFalsy();
});
});

0 comments on commit d66fa2e

Please sign in to comment.