New room list: new visual for invitation (#29773)
* feat: rework invitation styling in room list item * test: update notification decoration test * test: add test for vm * test(e2e): update to new invitation styling
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.8 KiB |
@@ -20,10 +20,6 @@
|
|||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--cpd-color-bg-action-secondary-hovered);
|
background-color: var(--cpd-color-bg-action-secondary-hovered);
|
||||||
|
|
||||||
.mx_RoomListItemView_content {
|
|
||||||
padding-right: var(--cpd-space-1-5x);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomListItemView_container {
|
.mx_RoomListItemView_container {
|
||||||
|
|||||||
@@ -66,12 +66,18 @@ export function useRoomListItemViewModel(room: Room): RoomListItemViewState {
|
|||||||
const roomTags = useEventEmitterState(room, RoomEvent.Tags, () => room.tags);
|
const roomTags = useEventEmitterState(room, RoomEvent.Tags, () => room.tags);
|
||||||
const isArchived = Boolean(roomTags[DefaultTagID.Archived]);
|
const isArchived = Boolean(roomTags[DefaultTagID.Archived]);
|
||||||
|
|
||||||
const showHoverMenu =
|
|
||||||
hasAccessToOptionsMenu(room) || hasAccessToNotificationMenu(room, matrixClient.isGuest(), isArchived);
|
|
||||||
const notificationState = useMemo(() => RoomNotificationStateStore.instance.getRoomState(room), [room]);
|
const notificationState = useMemo(() => RoomNotificationStateStore.instance.getRoomState(room), [room]);
|
||||||
|
const invited = notificationState.invited;
|
||||||
const a11yLabel = getA11yLabel(room, notificationState);
|
const a11yLabel = getA11yLabel(room, notificationState);
|
||||||
const isBold = notificationState.hasAnyNotificationOrActivity;
|
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
|
// Video room
|
||||||
const isVideoRoom = room.isElementVideoRoom() || room.isCallRoom();
|
const isVideoRoom = room.isElementVideoRoom() || room.isCallRoom();
|
||||||
// EC video call or video room
|
// EC video call or video room
|
||||||
|
|||||||
@@ -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 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 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 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 { UnreadCounter, Unread } from "@vector-im/compound-web";
|
||||||
|
|
||||||
import { Flex } from "../../utils/Flex";
|
import { Flex } from "../../utils/Flex";
|
||||||
@@ -56,7 +57,7 @@ export function NotificationDecoration({
|
|||||||
>
|
>
|
||||||
{isUnsetMessage && <ErrorIcon width="20px" height="20px" fill="var(--cpd-color-icon-critical-primary)" />}
|
{isUnsetMessage && <ErrorIcon width="20px" height="20px" fill="var(--cpd-color-icon-critical-primary)" />}
|
||||||
{hasVideoCall && <VideoCallIcon width="20px" height="20px" fill="var(--cpd-color-icon-accent-primary)" />}
|
{hasVideoCall && <VideoCallIcon width="20px" height="20px" fill="var(--cpd-color-icon-accent-primary)" />}
|
||||||
{invited && <UnreadCounter count={1} />}
|
{invited && <EmailIcon width="20px" height="20px" fill="var(--cpd-color-icon-accent-primary)" />}
|
||||||
{isMention && <MentionIcon width="20px" height="20px" fill="var(--cpd-color-icon-accent-primary)" />}
|
{isMention && <MentionIcon width="20px" height="20px" fill="var(--cpd-color-icon-accent-primary)" />}
|
||||||
{(isMention || isNotification) && <UnreadCounter count={count || null} />}
|
{(isMention || isNotification) && <UnreadCounter count={count || null} />}
|
||||||
{isActivityNotification && <Unread />}
|
{isActivityNotification && <Unread />}
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ describe("RoomListItemViewModel", () => {
|
|||||||
room = mkStubRoom("roomId", "roomName", matrixClient);
|
room = mkStubRoom("roomId", "roomName", matrixClient);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
it("should dispatch view room action on openRoom", async () => {
|
it("should dispatch view room action on openRoom", async () => {
|
||||||
const { result: vm } = renderHook(
|
const { result: vm } = renderHook(
|
||||||
() => useRoomListItemViewModel(room),
|
() => useRoomListItemViewModel(room),
|
||||||
@@ -68,6 +72,20 @@ describe("RoomListItemViewModel", () => {
|
|||||||
expect(vm.current.showHoverMenu).toBe(true);
|
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", () => {
|
describe("a11yLabel", () => {
|
||||||
let notificationState: RoomNotificationState;
|
let notificationState: RoomNotificationState;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -108,7 +126,10 @@ describe("RoomListItemViewModel", () => {
|
|||||||
},
|
},
|
||||||
])("should return the $label label", ({ mock, expected }) => {
|
])("should return the $label label", ({ mock, expected }) => {
|
||||||
mock?.();
|
mock?.();
|
||||||
const { result: vm } = renderHook(() => useRoomListItemViewModel(room));
|
const { result: vm } = renderHook(
|
||||||
|
() => useRoomListItemViewModel(room),
|
||||||
|
withClientContextRenderOptions(room.client),
|
||||||
|
);
|
||||||
expect(vm.current.a11yLabel).toBe(expected);
|
expect(vm.current.a11yLabel).toBe(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -23,11 +23,17 @@ exports[`<NotificationDecoration /> should render the invitation decoration 1`]
|
|||||||
data-testid="notification-decoration"
|
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;"
|
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;"
|
||||||
>
|
>
|
||||||
<span
|
<svg
|
||||||
class="_unread-counter_9mg0k_8"
|
fill="var(--cpd-color-icon-accent-primary)"
|
||||||
|
height="20px"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="20px"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
>
|
>
|
||||||
1
|
<path
|
||||||
</span>
|
d="M4 4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2m0 5.111a1 1 0 0 0 .514.874l7 3.89a1 1 0 0 0 .972 0l7-3.89a1 1 0 1 0-.972-1.748L12 11.856 5.486 8.237A1 1 0 0 0 4 9.111"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</DocumentFragment>
|
</DocumentFragment>
|
||||||
`;
|
`;
|
||||||
|
|||||||
Reference in New Issue
Block a user