diff --git a/playwright/snapshots/left-panel/room-list-panel/room-list.spec.ts/room-list-item-invited-linux.png b/playwright/snapshots/left-panel/room-list-panel/room-list.spec.ts/room-list-item-invited-linux.png
index aa35ea7118..4d9fd3ccd2 100644
Binary files a/playwright/snapshots/left-panel/room-list-panel/room-list.spec.ts/room-list-item-invited-linux.png and b/playwright/snapshots/left-panel/room-list-panel/room-list.spec.ts/room-list-item-invited-linux.png differ
diff --git a/res/css/views/rooms/RoomListPanel/_RoomListItemView.pcss b/res/css/views/rooms/RoomListPanel/_RoomListItemView.pcss
index 41ee00fff5..ee228ec262 100644
--- a/res/css/views/rooms/RoomListPanel/_RoomListItemView.pcss
+++ b/res/css/views/rooms/RoomListPanel/_RoomListItemView.pcss
@@ -20,10 +20,6 @@
&:hover {
background-color: var(--cpd-color-bg-action-secondary-hovered);
-
- .mx_RoomListItemView_content {
- padding-right: var(--cpd-space-1-5x);
- }
}
.mx_RoomListItemView_container {
diff --git a/src/components/viewmodels/roomlist/RoomListItemViewModel.tsx b/src/components/viewmodels/roomlist/RoomListItemViewModel.tsx
index ad6a271e57..d20c834c70 100644
--- a/src/components/viewmodels/roomlist/RoomListItemViewModel.tsx
+++ b/src/components/viewmodels/roomlist/RoomListItemViewModel.tsx
@@ -66,12 +66,18 @@ export function useRoomListItemViewModel(room: Room): RoomListItemViewState {
const roomTags = useEventEmitterState(room, RoomEvent.Tags, () => room.tags);
const isArchived = Boolean(roomTags[DefaultTagID.Archived]);
- const showHoverMenu =
- hasAccessToOptionsMenu(room) || hasAccessToNotificationMenu(room, matrixClient.isGuest(), isArchived);
const notificationState = useMemo(() => RoomNotificationStateStore.instance.getRoomState(room), [room]);
+ const invited = notificationState.invited;
const a11yLabel = getA11yLabel(room, notificationState);
const isBold = notificationState.hasAnyNotificationOrActivity;
+ // We don't want to show the hover menu if
+ // - there is an invitation for this room
+ // - the user doesn't have access to both notification and more options menus
+ const showHoverMenu =
+ !invited &&
+ (hasAccessToOptionsMenu(room) || hasAccessToNotificationMenu(room, matrixClient.isGuest(), isArchived));
+
// Video room
const isVideoRoom = room.isElementVideoRoom() || room.isCallRoom();
// EC video call or video room
diff --git a/src/components/views/rooms/NotificationDecoration.tsx b/src/components/views/rooms/NotificationDecoration.tsx
index cfb82c461c..9cc1bee738 100644
--- a/src/components/views/rooms/NotificationDecoration.tsx
+++ b/src/components/views/rooms/NotificationDecoration.tsx
@@ -10,6 +10,7 @@ import MentionIcon from "@vector-im/compound-design-tokens/assets/web/icons/ment
import ErrorIcon from "@vector-im/compound-design-tokens/assets/web/icons/error-solid";
import NotificationOffIcon from "@vector-im/compound-design-tokens/assets/web/icons/notifications-off-solid";
import VideoCallIcon from "@vector-im/compound-design-tokens/assets/web/icons/video-call-solid";
+import EmailIcon from "@vector-im/compound-design-tokens/assets/web/icons/email-solid";
import { UnreadCounter, Unread } from "@vector-im/compound-web";
import { Flex } from "../../utils/Flex";
@@ -56,7 +57,7 @@ export function NotificationDecoration({
>
{isUnsetMessage && }
{hasVideoCall && }
- {invited && }
+ {invited && }
{isMention && }
{(isMention || isNotification) && }
{isActivityNotification && }
diff --git a/test/unit-tests/components/viewmodels/roomlist/RoomListItemViewModel-test.tsx b/test/unit-tests/components/viewmodels/roomlist/RoomListItemViewModel-test.tsx
index 867a909f2e..be309b36ed 100644
--- a/test/unit-tests/components/viewmodels/roomlist/RoomListItemViewModel-test.tsx
+++ b/test/unit-tests/components/viewmodels/roomlist/RoomListItemViewModel-test.tsx
@@ -33,6 +33,10 @@ describe("RoomListItemViewModel", () => {
room = mkStubRoom("roomId", "roomName", matrixClient);
});
+ afterEach(() => {
+ jest.resetAllMocks();
+ });
+
it("should dispatch view room action on openRoom", async () => {
const { result: vm } = renderHook(
() => useRoomListItemViewModel(room),
@@ -68,6 +72,20 @@ describe("RoomListItemViewModel", () => {
expect(vm.current.showHoverMenu).toBe(true);
});
+ it("should not show hover menu if user has an invitation notification", async () => {
+ mocked(hasAccessToOptionsMenu).mockReturnValue(true);
+
+ const notificationState = new RoomNotificationState(room, false);
+ jest.spyOn(RoomNotificationStateStore.instance, "getRoomState").mockReturnValue(notificationState);
+ jest.spyOn(notificationState, "invited", "get").mockReturnValue(false);
+
+ const { result: vm } = renderHook(
+ () => useRoomListItemViewModel(room),
+ withClientContextRenderOptions(room.client),
+ );
+ expect(vm.current.showHoverMenu).toBe(true);
+ });
+
describe("a11yLabel", () => {
let notificationState: RoomNotificationState;
beforeEach(() => {
@@ -108,7 +126,10 @@ describe("RoomListItemViewModel", () => {
},
])("should return the $label label", ({ mock, expected }) => {
mock?.();
- const { result: vm } = renderHook(() => useRoomListItemViewModel(room));
+ const { result: vm } = renderHook(
+ () => useRoomListItemViewModel(room),
+ withClientContextRenderOptions(room.client),
+ );
expect(vm.current.a11yLabel).toBe(expected);
});
});
diff --git a/test/unit-tests/components/views/rooms/__snapshots__/NotificationDecoration-test.tsx.snap b/test/unit-tests/components/views/rooms/__snapshots__/NotificationDecoration-test.tsx.snap
index be81664eb8..33ee60102b 100644
--- a/test/unit-tests/components/views/rooms/__snapshots__/NotificationDecoration-test.tsx.snap
+++ b/test/unit-tests/components/views/rooms/__snapshots__/NotificationDecoration-test.tsx.snap
@@ -23,11 +23,17 @@ exports[` should render the invitation decoration 1`]
data-testid="notification-decoration"
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: center; --mx-flex-gap: var(--cpd-space-1-5x); --mx-flex-wrap: nowrap;"
>
-
- 1
-
+
+
`;