Files
ThreadNet-Web/src/components/viewmodels/roomlist/RoomListItemViewModel.tsx
T
Florian DurosandGitHub bbd798ef36 New room list: add notification decoration (#29552)
* chore: update @compound-web

* feat(notification decoration): add NotificationDecoration component

* feat(room list item): get notification state in view model

* feat(room list item): use notification decoration in RoomListItemView

* test(notification decoration): add tests

* test(room list item view model): add a11yLabel tests

* test(room list item): update tests

* test(e2e): add decoration tests
2025-03-26 13:32:02 +00:00

94 lines
2.9 KiB
TypeScript

/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
import { useCallback, useMemo } from "react";
import { type Room } from "matrix-js-sdk/src/matrix";
import dispatcher from "../../../dispatcher/dispatcher";
import type { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import { Action } from "../../../dispatcher/actions";
import { hasAccessToOptionsMenu } from "./utils";
import { _t } from "../../../languageHandler";
import { type RoomNotificationState } from "../../../stores/notifications/RoomNotificationState";
import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore";
export interface RoomListItemViewState {
/**
* Whether the hover menu should be shown.
*/
showHoverMenu: boolean;
/**
* Open the room having given roomId.
*/
openRoom: () => void;
/**
* The a11y label for the room list item.
*/
a11yLabel: string;
/**
* The notification state of the room.
*/
notificationState: RoomNotificationState;
}
/**
* View model for the room list item
* @see {@link RoomListItemViewState} for more information about what this view model returns.
*/
export function useRoomListItemViewModel(room: Room): RoomListItemViewState {
// incoming: Check notification menu rights
const showHoverMenu = hasAccessToOptionsMenu(room);
const notificationState = useMemo(() => RoomNotificationStateStore.instance.getRoomState(room), [room]);
const a11yLabel = getA11yLabel(room, notificationState);
// Actions
const openRoom = useCallback((): void => {
dispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: room.roomId,
metricsTrigger: "RoomList",
});
}, [room]);
return {
notificationState,
showHoverMenu,
openRoom,
a11yLabel,
};
}
/**
* Get the a11y label for the room list item
* @param room
* @param notificationState
*/
function getA11yLabel(room: Room, notificationState: RoomNotificationState): string {
if (notificationState.isUnsetMessage) {
return _t("a11y|room_messsage_not_sent", {
roomName: room.name,
});
} else if (notificationState.invited) {
return _t("a11y|room_n_unread_invite", {
roomName: room.name,
});
} else if (notificationState.isMention) {
return _t("a11y|room_n_unread_messages_mentions", {
roomName: room.name,
count: notificationState.count,
});
} else if (notificationState.hasUnreadCount) {
return _t("a11y|room_n_unread_messages", {
roomName: room.name,
count: notificationState.count,
});
} else {
return _t("room_list|room|open_room", { roomName: room.name });
}
}