Improve icon rendering in iconized context menu (#31458)
* Fix composer button visibility in contrast colour mode Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update snapshot Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update test Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Simplify Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update snapshots Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update screenshots Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update screenshots Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update screenshot Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Improve icon rendering in iconized context menu Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Add test Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Delint Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
@ -120,9 +120,6 @@
|
||||
@import "./views/context_menus/_DeviceContextMenu.pcss";
|
||||
@import "./views/context_menus/_IconizedContextMenu.pcss";
|
||||
@import "./views/context_menus/_LegacyCallContextMenu.pcss";
|
||||
@import "./views/context_menus/_MessageContextMenu.pcss";
|
||||
@import "./views/context_menus/_RoomGeneralContextMenu.pcss";
|
||||
@import "./views/context_menus/_RoomNotificationContextMenu.pcss";
|
||||
@import "./views/dialogs/_AddExistingToSpaceDialog.pcss";
|
||||
@import "./views/dialogs/_AnalyticsLearnMoreDialog.pcss";
|
||||
@import "./views/dialogs/_BugReportDialog.pcss";
|
||||
|
||||
@ -428,46 +428,6 @@ Please see LICENSE files in the repository root for full details.
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconHome::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/home-solid.svg");
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconInvite::before {
|
||||
mask-image: url("$(res)/img/element-icons/room/invite.svg");
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconSettings::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/settings-solid.svg");
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconLeave::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/leave.svg");
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconMembers::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/user-profile-solid.svg");
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconPlus::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/plus.svg");
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconExplore::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/search.svg");
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconPreferences::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/preferences.svg");
|
||||
}
|
||||
|
||||
.mx_SpacePanel_noIcon {
|
||||
display: none;
|
||||
|
||||
& + .mx_IconizedContextMenu_label {
|
||||
padding-left: 5px !important; /* override default iconized label style to align with header */
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpacePanel_contextMenu_separatorLabel {
|
||||
color: $tertiary-content;
|
||||
font-size: $font-10px;
|
||||
|
||||
@ -116,48 +116,11 @@ Please see LICENSE files in the repository root for full details.
|
||||
}
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: block;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: block;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background: $icon-button-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconHome::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/home-solid.svg");
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconBell::before {
|
||||
mask-image: url("$(res)/img/element-icons/notifications.svg");
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconLock::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/lock-solid.svg");
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconSettings::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/settings-solid.svg");
|
||||
.mx_IconizedContextMenu_icon svg {
|
||||
color: $icon-button-color;
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconMessage::before {
|
||||
mask-image: url("$(res)/img/element-icons/feedback.svg");
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconSignOut::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/leave.svg");
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconQr::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/qr-code.svg");
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,10 +9,6 @@ Please see LICENSE files in the repository root for full details.
|
||||
.mx_DeviceContextMenu {
|
||||
max-width: 252px;
|
||||
|
||||
.mx_DeviceContextMenu_device_icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_label {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
@ -68,19 +68,6 @@ Please see LICENSE files in the repository root for full details.
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
img,
|
||||
svg,
|
||||
.mx_IconizedContextMenu_icon {
|
||||
/* icons */
|
||||
width: 16px;
|
||||
min-width: 16px;
|
||||
max-width: 16px;
|
||||
|
||||
& + .mx_IconizedContextMenu_label {
|
||||
padding-left: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
span.mx_IconizedContextMenu_label {
|
||||
/* labels */
|
||||
width: 100%;
|
||||
@ -92,27 +79,23 @@ Please see LICENSE files in the repository root for full details.
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: block;
|
||||
flex-shrink: 0;
|
||||
|
||||
& + .mx_IconizedContextMenu_label {
|
||||
padding-left: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_BetaCard_betaPill {
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_icon {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
position: absolute;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background-color: var(--cpd-color-icon-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_optionList_red {
|
||||
.mx_IconizedContextMenu_item {
|
||||
color: $alert !important;
|
||||
@ -121,10 +104,6 @@ Please see LICENSE files in the repository root for full details.
|
||||
svg {
|
||||
color: var(--cpd-color-icon-critical-primary);
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_icon::before {
|
||||
background-color: var(--cpd-color-icon-critical-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_option_red {
|
||||
@ -133,24 +112,16 @@ Please see LICENSE files in the repository root for full details.
|
||||
svg {
|
||||
color: $alert;
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_icon::before {
|
||||
background-color: $alert;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_active {
|
||||
&.mx_IconizedContextMenu_item,
|
||||
.mx_IconizedContextMenu_item {
|
||||
color: $accent !important;
|
||||
}
|
||||
|
||||
svg {
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_icon::before {
|
||||
background-color: $accent;
|
||||
svg {
|
||||
color: $accent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,24 +131,11 @@ Please see LICENSE files in the repository root for full details.
|
||||
}
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_checked,
|
||||
.mx_IconizedContextMenu_unchecked {
|
||||
svg.mx_IconizedContextMenu_checked {
|
||||
margin-left: 16px;
|
||||
margin-right: -5px;
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_developerTools::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/labs.svg");
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_checked::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/check.svg");
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_unchecked::before {
|
||||
content: unset;
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_sublabel {
|
||||
margin-left: 20px;
|
||||
color: $tertiary-content;
|
||||
|
||||
@ -1,113 +0,0 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2021 Michael Weimann <mail@michael-weimann.eu>
|
||||
Copyright 2015, 2016 OpenMarket 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.
|
||||
*/
|
||||
|
||||
.mx_MessageContextMenu {
|
||||
.mx_IconizedContextMenu_icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: block;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: block;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconCollapse::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/chevron-up.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconReport::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/error-solid.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconLink::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/link.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconPermalink::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/share.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconUnhidePreview::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/visibility-on.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconOpenInMapSite::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/pop-out.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconEndPoll::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/check.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconForward::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/forward.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconRedact::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/delete.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconResend::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/restart.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconSource::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/inline-code.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconQuote::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/quote.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconPin::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/pin.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconUnpin::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/unpin.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconCopy::before {
|
||||
height: 16px;
|
||||
mask-image: url($copy-button-url);
|
||||
position: relative;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconEdit::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/edit.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconReply::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/reply.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconReplyInThread::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/threads.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconReact::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/reaction-add.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconViewInRoom::before {
|
||||
mask-image: url("$(res)/img/element-icons/view-in-room.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_jumpToEvent::before {
|
||||
mask-image: url("$(res)/img/element-icons/child-relationship.svg");
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
.mx_RoomGeneralContextMenu_iconStar::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/favourite-solid.svg");
|
||||
}
|
||||
|
||||
.mx_RoomGeneralContextMenu_iconArrowDown::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/arrow-down.svg");
|
||||
}
|
||||
|
||||
.mx_RoomGeneralContextMenu_iconMarkAsRead::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/mark-as-read.svg");
|
||||
}
|
||||
|
||||
.mx_RoomGeneralContextMenu_iconMarkAsUnread::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/mark-as-unread.svg");
|
||||
}
|
||||
|
||||
.mx_RoomGeneralContextMenu_iconSettings::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/settings-solid.svg");
|
||||
}
|
||||
|
||||
.mx_RoomGeneralContextMenu_iconCopyLink::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/link.svg");
|
||||
}
|
||||
|
||||
.mx_RoomGeneralContextMenu_iconInvite::before {
|
||||
mask-image: url("$(res)/img/element-icons/room/invite.svg");
|
||||
}
|
||||
|
||||
.mx_RoomGeneralContextMenu_iconSignOut::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/leave.svg");
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
.mx_RoomNotificationContextMenu_iconBell::before {
|
||||
mask-image: url("$(res)/img/element-icons/notifications.svg");
|
||||
}
|
||||
.mx_RoomNotificationContextMenu_iconBellDot::before {
|
||||
mask-image: url("$(res)/img/element-icons/roomlist/notifications-default.svg");
|
||||
}
|
||||
.mx_RoomNotificationContextMenu_iconBellMentions::before {
|
||||
mask-image: url("$(res)/img/element-icons/roomlist/notifications-dm.svg");
|
||||
}
|
||||
.mx_RoomNotificationContextMenu_iconBellCrossed::before {
|
||||
mask-image: url("$(res)/img/element-icons/roomlist/notifications-off.svg");
|
||||
}
|
||||
@ -340,37 +340,28 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
.mx_SpotlightDialog_option--menu,
|
||||
.mx_SpotlightDialog_option--notifications {
|
||||
width: 20px;
|
||||
min-width: 20px;
|
||||
height: 20px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: var(--cpd-space-0-5x);
|
||||
flex-shrink: 0;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
position: relative;
|
||||
display: none;
|
||||
|
||||
&::before {
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
content: "";
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background: $tertiary-content;
|
||||
svg {
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
display: block;
|
||||
color: $tertiary-content;
|
||||
}
|
||||
|
||||
&:hover::before,
|
||||
&:focus-visible::before {
|
||||
background-color: $secondary-content;
|
||||
&:hover svg,
|
||||
&:focus-visible svg {
|
||||
color: $secondary-content;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpotlightDialog_option--menu::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/overflow-horizontal.svg");
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&[aria-selected="true"] {
|
||||
.mx_SpotlightDialog_option--menu,
|
||||
|
||||
@ -167,14 +167,6 @@ Please see LICENSE files in the repository root for full details.
|
||||
}
|
||||
}
|
||||
|
||||
.mx_ThreadPanel_viewInRoom::before {
|
||||
mask-image: url("$(res)/img/element-icons/view-in-room.svg");
|
||||
}
|
||||
|
||||
.mx_ThreadPanel_copyLinkToThread::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/link.svg");
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_wrapper {
|
||||
.mx_ThreadPanel_Header_FilterOptionItem {
|
||||
display: flex;
|
||||
|
||||
@ -9,25 +9,3 @@ Please see LICENSE files in the repository root for full details.
|
||||
.mx_LegacyRoomList {
|
||||
padding-right: 7px; /* width of the scrollbar, to line things up */
|
||||
}
|
||||
|
||||
.mx_LegacyRoomList_iconPlus::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/plus.svg");
|
||||
}
|
||||
.mx_LegacyRoomList_iconNewRoom::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/plus.svg");
|
||||
}
|
||||
.mx_LegacyRoomList_iconNewVideoRoom::before {
|
||||
mask-image: url("$(res)/img/element-icons/roomlist/hash-video.svg");
|
||||
}
|
||||
.mx_LegacyRoomList_iconAddExistingRoom::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/room.svg");
|
||||
}
|
||||
.mx_LegacyRoomList_iconExplore::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/search.svg");
|
||||
}
|
||||
.mx_LegacyRoomList_iconStartChat::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/user-add-solid.svg");
|
||||
}
|
||||
.mx_LegacyRoomList_iconInvite::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/share.svg");
|
||||
}
|
||||
|
||||
@ -87,22 +87,3 @@ Please see LICENSE files in the repository root for full details.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_LegacyRoomListHeader_iconInvite::before {
|
||||
mask-image: url("$(res)/img/element-icons/room/invite.svg");
|
||||
}
|
||||
.mx_LegacyRoomListHeader_iconStartChat::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/user-add-solid.svg");
|
||||
}
|
||||
.mx_LegacyRoomListHeader_iconNewRoom::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/plus.svg");
|
||||
}
|
||||
.mx_LegacyRoomListHeader_iconNewVideoRoom::before {
|
||||
mask-image: url("$(res)/img/element-icons/roomlist/hash-video.svg");
|
||||
}
|
||||
.mx_LegacyRoomListHeader_iconExplore::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/search.svg");
|
||||
}
|
||||
.mx_LegacyRoomListHeader_iconPlus::before {
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/plus.svg");
|
||||
}
|
||||
|
||||
@ -105,35 +105,23 @@ Please see LICENSE files in the repository root for full details.
|
||||
/* The context menu buttons are hidden by default */
|
||||
.mx_RoomTile_menuButton,
|
||||
.mx_RoomTile_notificationsButton {
|
||||
width: 20px;
|
||||
min-width: 20px; /* yay flex */
|
||||
height: 20px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: var(--cpd-space-0-5x);
|
||||
flex-shrink: 0;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
position: relative;
|
||||
display: none;
|
||||
|
||||
svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: var(--cpd-space-0-5x);
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
display: block;
|
||||
color: var(--cpd-color-icon-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RoomTile_notificationsButton::before {
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
content: "";
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background: var(--cpd-color-icon-primary);
|
||||
}
|
||||
|
||||
/* If the room has an overriden notification setting then we always show the notifications menu button */
|
||||
.mx_RoomTile_notificationsButton.mx_RoomTile_notificationsButton_show {
|
||||
display: block;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.2375 19.5C10.1625 19.7 10.125 19.9 10.125 20.125C10.125 21.1625 10.9625 22 12 22C13.0375 22 13.875 21.1625 13.875 20.125C13.875 19.9 13.825 19.7 13.7625 19.5H10.2375Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.6125 16.0625C18.8625 15.625 18.25 14.8875 18.25 13.75V9.5C18.25 6.05 15.3 3.25 12 3.25C8.7 3.25 5.75 6.05 5.75 9.5V13.75C5.75 14.875 5.125 15.625 4.3875 16.0625C3.8875 16.3625 3.25 16.775 3.25 17.275C3.25 17.85 3.6125 18.2375 4.3625 18.2375H12H19.6375C20.3875 18.2375 20.75 17.8375 20.75 17.275C20.75 16.775 20.125 16.3625 19.6125 16.0625Z" fill="black"/>
|
||||
<path d="M12 4.5C12.6904 4.5 13.25 3.94036 13.25 3.25C13.25 2.55964 12.6904 2 12 2C11.3096 2 10.75 2.55964 10.75 3.25C10.75 3.94036 11.3096 4.5 12 4.5Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.2375 19.5C10.1625 19.7 10.125 19.9 10.125 20.125C10.125 21.1625 10.9625 22 12 22C13.0375 22 13.875 21.1625 13.875 20.125C13.875 19.9 13.825 19.7 13.7625 19.5H10.2375Z" fill="currentColor"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.6125 16.0625C18.8625 15.625 18.25 14.8875 18.25 13.75V9.5C18.25 6.05 15.3 3.25 12 3.25C8.7 3.25 5.75 6.05 5.75 9.5V13.75C5.75 14.875 5.125 15.625 4.3875 16.0625C3.8875 16.3625 3.25 16.775 3.25 17.275C3.25 17.85 3.6125 18.2375 4.3625 18.2375H12H19.6375C20.3875 18.2375 20.75 17.8375 20.75 17.275C20.75 16.775 20.125 16.3625 19.6125 16.0625Z" fill="currentColor"/>
|
||||
<path d="M12 4.5C12.6904 4.5 13.25 3.94036 13.25 3.25C13.25 2.55964 12.6904 2 12 2C11.3096 2 10.75 2.55964 10.75 3.25C10.75 3.94036 11.3096 4.5 12 4.5Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 916 B After Width: | Height: | Size: 937 B |
@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="-0.4 1 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.1001 9C18.7779 9 18.5168 8.73883 18.5168 8.41667V6.08333H16.1834C15.8613 6.08333 15.6001 5.82217 15.6001 5.5C15.6001 5.17783 15.8613 4.91667 16.1834 4.91667H18.5168V2.58333C18.5168 2.26117 18.7779 2 19.1001 2C19.4223 2 19.6834 2.26117 19.6834 2.58333V4.91667H22.0168C22.3389 4.91667 22.6001 5.17783 22.6001 5.5C22.6001 5.82217 22.3389 6.08333 22.0168 6.08333H19.6834V8.41667C19.6834 8.73883 19.4223 9 19.1001 9ZM19.6001 11C20.0669 11 20.5212 10.9467 20.9574 10.8458C21.1161 11.5383 21.2 12.2594 21.2 13C21.2 16.1409 19.6917 18.9294 17.3598 20.6808V20.6807C16.0014 21.7011 14.3635 22.3695 12.5815 22.5505C12.2588 22.5832 11.9314 22.6 11.6 22.6C6.29807 22.6 2 18.302 2 13C2 7.69809 6.29807 3.40002 11.6 3.40002C12.3407 3.40002 13.0618 3.48391 13.7543 3.64268C13.6534 4.07884 13.6001 4.53319 13.6001 5C13.6001 8.31371 16.2864 11 19.6001 11ZM11.5999 20.68C13.6754 20.68 15.5585 19.8567 16.9407 18.5189C16.0859 16.4086 14.0167 14.92 11.5998 14.92C9.18298 14.92 7.11378 16.4086 6.25901 18.5189C7.64115 19.8567 9.52436 20.68 11.5999 20.68ZM11.7426 7.41172C10.3168 7.54168 9.2 8.74043 9.2 10.2C9.2 11.7464 10.4536 13 12 13C13.0308 13 13.9315 12.443 14.4176 11.6135C13.0673 10.6058 12.0929 9.12248 11.7426 7.41172Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.1001 9C18.7779 9 18.5168 8.73883 18.5168 8.41667V6.08333H16.1834C15.8613 6.08333 15.6001 5.82217 15.6001 5.5C15.6001 5.17783 15.8613 4.91667 16.1834 4.91667H18.5168V2.58333C18.5168 2.26117 18.7779 2 19.1001 2C19.4223 2 19.6834 2.26117 19.6834 2.58333V4.91667H22.0168C22.3389 4.91667 22.6001 5.17783 22.6001 5.5C22.6001 5.82217 22.3389 6.08333 22.0168 6.08333H19.6834V8.41667C19.6834 8.73883 19.4223 9 19.1001 9ZM19.6001 11C20.0669 11 20.5212 10.9467 20.9574 10.8458C21.1161 11.5383 21.2 12.2594 21.2 13C21.2 16.1409 19.6917 18.9294 17.3598 20.6808V20.6807C16.0014 21.7011 14.3635 22.3695 12.5815 22.5505C12.2588 22.5832 11.9314 22.6 11.6 22.6C6.29807 22.6 2 18.302 2 13C2 7.69809 6.29807 3.40002 11.6 3.40002C12.3407 3.40002 13.0618 3.48391 13.7543 3.64268C13.6534 4.07884 13.6001 4.53319 13.6001 5C13.6001 8.31371 16.2864 11 19.6001 11ZM11.5999 20.68C13.6754 20.68 15.5585 19.8567 16.9407 18.5189C16.0859 16.4086 14.0167 14.92 11.5998 14.92C9.18298 14.92 7.11378 16.4086 6.25901 18.5189C7.64115 19.8567 9.52436 20.68 11.5999 20.68ZM11.7426 7.41172C10.3168 7.54168 9.2 8.74043 9.2 10.2C9.2 11.7464 10.4536 13 12 13C13.0308 13 13.9315 12.443 14.4176 11.6135C13.0673 10.6058 12.0929 9.12248 11.7426 7.41172Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
@ -1,5 +1,5 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.59 15C7.53 15.16 7.5 15.32 7.5 15.5C7.5 16.33 8.17 17 9 17C9.83 17 10.5 16.33 10.5 15.5C10.5 15.32 10.46 15.16 10.41 15H7.59Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 10.4C14 11.31 14.49 11.9 15.09 12.25C15.5 12.49 16 12.82 16 13.22C16 13.67 15.71 13.99 15.11 13.99H9H2.89C2.29 13.99 2 13.68 2 13.22C2 12.82 2.51 12.49 2.91 12.25C3.5 11.9 4 11.3 4 10.4V7C4 4.24 6.36 2 9 2C11.64 2 14 4.24 14 7V10.4ZM11.2402 6.1226C11.4223 5.9515 11.7099 5.96101 11.8824 6.14162C12.0358 6.31272 12.0358 6.56938 11.9016 6.74048L8.92075 10.685L8.892 10.723C8.62358 11.0462 8.13469 11.0938 7.80875 10.8276C7.7798 10.8132 7.75632 10.7881 7.73417 10.7643C7.72698 10.7566 7.71994 10.749 7.71289 10.7421L6.13071 8.99336C5.93899 8.76522 5.95816 8.42302 6.18823 8.2329C6.37995 8.0618 6.65795 8.0618 6.85926 8.19488L8.21138 9.012L11.2402 6.1226Z" fill="black"/>
|
||||
<path d="M9 3C9.55228 3 10 2.55228 10 2C10 1.44772 9.55228 1 9 1C8.44772 1 8 1.44772 8 2C8 2.55228 8.44772 3 9 3Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.59 15C7.53 15.16 7.5 15.32 7.5 15.5C7.5 16.33 8.17 17 9 17C9.83 17 10.5 16.33 10.5 15.5C10.5 15.32 10.46 15.16 10.41 15H7.59Z" fill="currentColor"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 10.4C14 11.31 14.49 11.9 15.09 12.25C15.5 12.49 16 12.82 16 13.22C16 13.67 15.71 13.99 15.11 13.99H9H2.89C2.29 13.99 2 13.68 2 13.22C2 12.82 2.51 12.49 2.91 12.25C3.5 11.9 4 11.3 4 10.4V7C4 4.24 6.36 2 9 2C11.64 2 14 4.24 14 7V10.4ZM11.2402 6.1226C11.4223 5.9515 11.7099 5.96101 11.8824 6.14162C12.0358 6.31272 12.0358 6.56938 11.9016 6.74048L8.92075 10.685L8.892 10.723C8.62358 11.0462 8.13469 11.0938 7.80875 10.8276C7.7798 10.8132 7.75632 10.7881 7.73417 10.7643C7.72698 10.7566 7.71994 10.749 7.71289 10.7421L6.13071 8.99336C5.93899 8.76522 5.95816 8.42302 6.18823 8.2329C6.37995 8.0618 6.65795 8.0618 6.85926 8.19488L8.21138 9.012L11.2402 6.1226Z" fill="currentColor"/>
|
||||
<path d="M9 3C9.55228 3 10 2.55228 10 2C10 1.44772 9.55228 1 9 1C8.44772 1 8 1.44772 8 2C8 2.55228 8.44772 3 9 3Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@ -1,3 +1,3 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 7C14.6569 7 16 5.65685 16 4C16 2.34315 14.6569 1 13 1C11.3431 1 10 2.34315 10 4C10 5.65685 11.3431 7 13 7ZM8.9677 2C6.34078 2.01817 4 4.25115 4 6.99989V10.3999C4 11.2999 3.5 11.8999 2.91 12.2499C2.51 12.4899 2 12.8199 2 13.2199C2 13.6799 2.29 13.9899 2.89 13.9899H9H15.11C15.71 13.9899 16 13.6699 16 13.2199C16 12.8199 15.5 12.4899 15.09 12.2499C14.49 11.8999 14 11.3099 14 10.3999V8.38838C13.6784 8.46136 13.3437 8.49989 13 8.49989C10.5147 8.49989 8.5 6.48517 8.5 3.99989C8.5 3.28151 8.66833 2.60245 8.9677 2ZM7.59 15C7.53 15.16 7.5 15.32 7.5 15.5C7.5 16.33 8.17 17 9 17C9.83 17 10.5 16.33 10.5 15.5C10.5 15.32 10.46 15.16 10.41 15H7.59Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 7C14.6569 7 16 5.65685 16 4C16 2.34315 14.6569 1 13 1C11.3431 1 10 2.34315 10 4C10 5.65685 11.3431 7 13 7ZM8.9677 2C6.34078 2.01817 4 4.25115 4 6.99989V10.3999C4 11.2999 3.5 11.8999 2.91 12.2499C2.51 12.4899 2 12.8199 2 13.2199C2 13.6799 2.29 13.9899 2.89 13.9899H9H15.11C15.71 13.9899 16 13.6699 16 13.2199C16 12.8199 15.5 12.4899 15.09 12.2499C14.49 11.8999 14 11.3099 14 10.3999V8.38838C13.6784 8.46136 13.3437 8.49989 13 8.49989C10.5147 8.49989 8.5 6.48517 8.5 3.99989C8.5 3.28151 8.66833 2.60245 8.9677 2ZM7.59 15C7.53 15.16 7.5 15.32 7.5 15.5C7.5 16.33 8.17 17 9 17C9.83 17 10.5 16.33 10.5 15.5C10.5 15.32 10.46 15.16 10.41 15H7.59Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 811 B After Width: | Height: | Size: 818 B |
@ -1,7 +1,7 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.59 15C7.53 15.16 7.5 15.32 7.5 15.5C7.5 16.33 8.17 17 9 17C9.83 17 10.5 16.33 10.5 15.5C10.5 15.32 10.46 15.16 10.41 15H7.59Z" fill="black"/>
|
||||
<path d="M9 3C9.55228 3 10 2.55228 10 2C10 1.44772 9.55228 1 9 1C8.44772 1 8 1.44772 8 2C8 2.55228 8.44772 3 9 3Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.08 10.9698C14.03 10.7998 14 10.6098 14 10.4098V7.00977C14 4.24977 11.64 2.00977 8.99998 2.00977C7.93998 2.00977 6.92998 2.37977 6.09998 2.98977L14.08 10.9698Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.38 5.14978C4.14 5.72978 4 6.34978 4 6.99978V10.3998C4 11.2998 3.5 11.8998 2.91 12.2498C2.51 12.4898 2 12.8198 2 13.2198C2 13.6798 2.29 13.9898 2.89 13.9898H9H13.22L4.38 5.14978Z" fill="black"/>
|
||||
<path d="M1 1L17 17" stroke="black" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.59 15C7.53 15.16 7.5 15.32 7.5 15.5C7.5 16.33 8.17 17 9 17C9.83 17 10.5 16.33 10.5 15.5C10.5 15.32 10.46 15.16 10.41 15H7.59Z" fill="currentColor"/>
|
||||
<path d="M9 3C9.55228 3 10 2.55228 10 2C10 1.44772 9.55228 1 9 1C8.44772 1 8 1.44772 8 2C8 2.55228 8.44772 3 9 3Z" fill="currentColor"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.08 10.9698C14.03 10.7998 14 10.6098 14 10.4098V7.00977C14 4.24977 11.64 2.00977 8.99998 2.00977C7.93998 2.00977 6.92998 2.37977 6.09998 2.98977L14.08 10.9698Z" fill="currentColor"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.38 5.14978C4.14 5.72978 4 6.34978 4 6.99978V10.3998C4 11.2998 3.5 11.8998 2.91 12.2498C2.51 12.4898 2 12.8198 2 13.2198C2 13.6798 2.29 13.9898 2.89 13.9898H9H13.22L4.38 5.14978Z" fill="currentColor"/>
|
||||
<path d="M1 1L17 17" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1004 B After Width: | Height: | Size: 1.0 KiB |
@ -10,6 +10,7 @@ import { EventType, RoomType, JoinRule, Preset, type Room, RoomEvent } from "mat
|
||||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import React, { type JSX, useCallback, useContext, useRef, useState } from "react";
|
||||
import { PlusIcon, RoomIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
||||
import createRoom, { type IOpts } from "../../createRoom";
|
||||
@ -66,6 +67,7 @@ import MainSplit from "./MainSplit";
|
||||
import RightPanel from "./RightPanel";
|
||||
import SpaceHierarchy, { showRoom } from "./SpaceHierarchy";
|
||||
import { type RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
|
||||
import { Icon as HashVideoIcon } from "../../../res/img/element-icons/roomlist/hash-video.svg";
|
||||
|
||||
interface IProps {
|
||||
space: Room;
|
||||
@ -117,7 +119,7 @@ const SpaceLandingAddButton: React.FC<{ space: Room }> = ({ space }) => {
|
||||
<>
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|new_room")}
|
||||
iconClassName="mx_LegacyRoomList_iconNewRoom"
|
||||
icon={<PlusIcon />}
|
||||
onClick={async (e): Promise<void> => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -132,7 +134,7 @@ const SpaceLandingAddButton: React.FC<{ space: Room }> = ({ space }) => {
|
||||
{videoRoomsEnabled && (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|new_video_room")}
|
||||
iconClassName="mx_LegacyRoomList_iconNewVideoRoom"
|
||||
icon={<HashVideoIcon />}
|
||||
onClick={async (e): Promise<void> => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -157,7 +159,7 @@ const SpaceLandingAddButton: React.FC<{ space: Room }> = ({ space }) => {
|
||||
)}
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|add_existing_room")}
|
||||
iconClassName="mx_LegacyRoomList_iconAddExistingRoom"
|
||||
icon={<RoomIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -168,7 +170,7 @@ const SpaceLandingAddButton: React.FC<{ space: Room }> = ({ space }) => {
|
||||
{canCreateSpace && (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("room_list|add_space_label")}
|
||||
iconClassName="mx_LegacyRoomList_iconPlus"
|
||||
icon={<PlusIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
@ -8,6 +8,13 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import React, { type JSX, createRef, type ReactNode } from "react";
|
||||
import { type Room } from "matrix-js-sdk/src/matrix";
|
||||
import {
|
||||
HomeSolidIcon,
|
||||
LockSolidIcon,
|
||||
QrCodeIcon,
|
||||
SettingsSolidIcon,
|
||||
LeaveIcon,
|
||||
} from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
||||
import defaultDispatcher from "../../dispatcher/dispatcher";
|
||||
@ -42,7 +49,9 @@ import PosthogTrackers from "../../PosthogTrackers";
|
||||
import { type ViewHomePagePayload } from "../../dispatcher/payloads/ViewHomePagePayload";
|
||||
import { SDKContext } from "../../contexts/SDKContext";
|
||||
import { shouldShowFeedback } from "../../utils/Feedback";
|
||||
import DarkLightModeSvg from "../../../res/img/element-icons/roomlist/dark-light-mode.svg";
|
||||
import { Icon as DarkLightModeSvg } from "../../../res/img/element-icons/roomlist/dark-light-mode.svg";
|
||||
import { Icon as NotificationsIcon } from "../../../res/img/element-icons/notifications.svg";
|
||||
import { Icon as FeedbackIcon } from "../../../res/img/element-icons/feedback.svg";
|
||||
|
||||
interface IProps {
|
||||
isPanelCollapsed: boolean;
|
||||
@ -297,7 +306,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
||||
if (this.hasHomePage) {
|
||||
homeButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_UserMenu_iconHome"
|
||||
icon={<HomeSolidIcon />}
|
||||
label={_t("common|home")}
|
||||
onClick={this.onHomeClick}
|
||||
/>
|
||||
@ -308,7 +317,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
||||
if (shouldShowFeedback()) {
|
||||
feedbackButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_UserMenu_iconMessage"
|
||||
icon={<FeedbackIcon />}
|
||||
label={_t("common|feedback")}
|
||||
onClick={this.onProvideFeedback}
|
||||
/>
|
||||
@ -317,7 +326,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
||||
|
||||
const linkNewDeviceButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_UserMenu_iconQr"
|
||||
icon={<QrCodeIcon />}
|
||||
label={_t("user_menu|link_new_device")}
|
||||
onClick={(e) => this.onSettingsOpen(e, UserTab.SessionManager, { showMsc4108QrCode: true })}
|
||||
/>
|
||||
@ -328,24 +337,24 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
||||
{homeButton}
|
||||
{linkNewDeviceButton}
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_UserMenu_iconBell"
|
||||
icon={<NotificationsIcon />}
|
||||
label={_t("notifications|enable_prompt_toast_title")}
|
||||
onClick={(e) => this.onSettingsOpen(e, UserTab.Notifications)}
|
||||
/>
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_UserMenu_iconLock"
|
||||
icon={<LockSolidIcon />}
|
||||
label={_t("room_settings|security|title")}
|
||||
onClick={(e) => this.onSettingsOpen(e, UserTab.Security)}
|
||||
/>
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_UserMenu_iconSettings"
|
||||
icon={<SettingsSolidIcon />}
|
||||
label={_t("user_menu|settings")}
|
||||
onClick={(e) => this.onSettingsOpen(e)}
|
||||
/>
|
||||
{feedbackButton}
|
||||
<IconizedContextMenuOption
|
||||
className="mx_IconizedContextMenu_option_red"
|
||||
iconClassName="mx_UserMenu_iconSignOut"
|
||||
icon={<LeaveIcon />}
|
||||
label={_t("action|sign_out")}
|
||||
onClick={this.onSignOutClick}
|
||||
/>
|
||||
@ -357,7 +366,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
||||
<IconizedContextMenuOptionList>
|
||||
{homeButton}
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_UserMenu_iconSettings"
|
||||
icon={<SettingsSolidIcon />}
|
||||
label={_t("common|settings")}
|
||||
onClick={(e) => this.onSettingsOpen(e)}
|
||||
/>
|
||||
@ -398,7 +407,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
||||
: _t("user_menu|switch_theme_dark")
|
||||
}
|
||||
>
|
||||
<img src={DarkLightModeSvg} role="presentation" alt="" width={16} />
|
||||
<DarkLightModeSvg width="16px" height="16px" />
|
||||
</RovingAccessibleButton>
|
||||
</div>
|
||||
{topSection}
|
||||
|
||||
@ -7,6 +7,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { LabsIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import Modal from "../../../Modal";
|
||||
import DevtoolsDialog from "../dialogs/DevtoolsDialog";
|
||||
@ -32,7 +33,7 @@ export const DeveloperToolsOption: React.FC<Props> = ({ onFinished, roomId }) =>
|
||||
onFinished();
|
||||
}}
|
||||
label={_t("devtools|title")}
|
||||
iconClassName="mx_IconizedContextMenu_developerTools"
|
||||
icon={<LabsIcon />}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@ -26,14 +26,7 @@ interface IDeviceContextMenuDeviceProps {
|
||||
}
|
||||
|
||||
const DeviceContextMenuDevice: React.FC<IDeviceContextMenuDeviceProps> = ({ label, selected, onClick }) => {
|
||||
return (
|
||||
<IconizedContextMenuRadio
|
||||
iconClassName="mx_DeviceContextMenu_device_icon"
|
||||
label={label}
|
||||
active={selected}
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
return <IconizedContextMenuRadio label={label} active={selected} onClick={onClick} />;
|
||||
};
|
||||
|
||||
interface IDeviceContextMenuSectionProps {
|
||||
|
||||
@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import React, { type JSX, type ReactNode } from "react";
|
||||
import classNames from "classnames";
|
||||
import { CheckIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import ContextMenu, {
|
||||
ChevronFace,
|
||||
@ -33,26 +34,19 @@ interface IOptionListProps {
|
||||
|
||||
interface IOptionProps extends React.ComponentProps<typeof MenuItem> {
|
||||
icon?: ReactNode;
|
||||
iconClassName?: string;
|
||||
isDestructive?: boolean;
|
||||
}
|
||||
|
||||
interface ICheckboxProps extends React.ComponentProps<typeof MenuItemCheckbox> {
|
||||
iconClassName: string;
|
||||
icon?: ReactNode;
|
||||
words?: boolean;
|
||||
}
|
||||
|
||||
interface IRadioProps extends React.ComponentProps<typeof MenuItemRadio> {
|
||||
iconClassName?: string;
|
||||
icon?: ReactNode;
|
||||
}
|
||||
|
||||
export const IconizedContextMenuRadio: React.FC<IRadioProps> = ({
|
||||
label,
|
||||
iconClassName,
|
||||
active,
|
||||
className,
|
||||
...props
|
||||
}) => {
|
||||
export const IconizedContextMenuRadio: React.FC<IRadioProps> = ({ label, icon, active, className, ...props }) => {
|
||||
return (
|
||||
<MenuItemRadio
|
||||
{...props}
|
||||
@ -63,35 +57,28 @@ export const IconizedContextMenuRadio: React.FC<IRadioProps> = ({
|
||||
active={active}
|
||||
label={label}
|
||||
>
|
||||
{iconClassName && <span className={classNames("mx_IconizedContextMenu_icon", iconClassName)} />}
|
||||
{icon}
|
||||
<span className="mx_IconizedContextMenu_label">{label}</span>
|
||||
{active && <span className="mx_IconizedContextMenu_icon mx_IconizedContextMenu_checked" />}
|
||||
{active && <CheckIcon className="mx_IconizedContextMenu_checked" />}
|
||||
</MenuItemRadio>
|
||||
);
|
||||
};
|
||||
|
||||
export const IconizedContextMenuCheckbox: React.FC<ICheckboxProps> = ({
|
||||
label,
|
||||
iconClassName,
|
||||
icon,
|
||||
active,
|
||||
className,
|
||||
words,
|
||||
...props
|
||||
}) => {
|
||||
let marker: JSX.Element;
|
||||
let marker: JSX.Element | undefined;
|
||||
if (words) {
|
||||
marker = (
|
||||
<span className="mx_IconizedContextMenu_activeText">{active ? _t("common|on") : _t("common|off")}</span>
|
||||
);
|
||||
} else {
|
||||
marker = (
|
||||
<span
|
||||
className={classNames("mx_IconizedContextMenu_icon", {
|
||||
mx_IconizedContextMenu_checked: active,
|
||||
mx_IconizedContextMenu_unchecked: !active,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
} else if (active) {
|
||||
marker = <CheckIcon className="mx_IconizedContextMenu_checked" />;
|
||||
}
|
||||
|
||||
return (
|
||||
@ -104,7 +91,7 @@ export const IconizedContextMenuCheckbox: React.FC<ICheckboxProps> = ({
|
||||
active={active}
|
||||
label={label}
|
||||
>
|
||||
<span className={classNames("mx_IconizedContextMenu_icon", iconClassName)} />
|
||||
{icon}
|
||||
<span className="mx_IconizedContextMenu_label">{label}</span>
|
||||
{marker}
|
||||
</MenuItemCheckbox>
|
||||
@ -114,7 +101,6 @@ export const IconizedContextMenuCheckbox: React.FC<ICheckboxProps> = ({
|
||||
export const IconizedContextMenuOption: React.FC<IOptionProps> = ({
|
||||
label,
|
||||
className,
|
||||
iconClassName,
|
||||
icon,
|
||||
children,
|
||||
isDestructive,
|
||||
@ -130,7 +116,6 @@ export const IconizedContextMenuOption: React.FC<IOptionProps> = ({
|
||||
})}
|
||||
label={label}
|
||||
>
|
||||
{iconClassName && <span className={classNames("mx_IconizedContextMenu_icon", iconClassName)} />}
|
||||
{icon}
|
||||
<span className="mx_IconizedContextMenu_label">{label}</span>
|
||||
{children}
|
||||
|
||||
@ -20,6 +20,27 @@ import {
|
||||
Thread,
|
||||
M_POLL_START,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import {
|
||||
CheckIcon,
|
||||
ChevronUpIcon,
|
||||
EditIcon,
|
||||
ErrorSolidIcon,
|
||||
InlineCodeIcon,
|
||||
LinkIcon,
|
||||
PinIcon,
|
||||
QuoteIcon,
|
||||
ReactionAddIcon,
|
||||
ReplyIcon,
|
||||
RestartIcon,
|
||||
ThreadsIcon,
|
||||
UnpinIcon,
|
||||
DeleteIcon,
|
||||
ForwardIcon,
|
||||
PopOutIcon,
|
||||
VisibilityOnIcon,
|
||||
ShareIcon,
|
||||
CopyIcon,
|
||||
} from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
@ -53,6 +74,8 @@ import { type ShowThreadPayload } from "../../../dispatcher/payloads/ShowThreadP
|
||||
import { CardContext } from "../right_panel/context";
|
||||
import PinningUtils from "../../../utils/PinningUtils";
|
||||
import PosthogTrackers from "../../../PosthogTrackers.ts";
|
||||
import { Icon as ViewInRoomIcon } from "../../../../res/img/element-icons/view-in-room.svg";
|
||||
import { Icon as ChildRelationshipIcon } from "../../../../res/img/element-icons/child-relationship.svg";
|
||||
|
||||
interface IReplyInThreadButton {
|
||||
mxEvent: MatrixEvent;
|
||||
@ -86,13 +109,7 @@ const ReplyInThreadButton: React.FC<IReplyInThreadButton> = ({ mxEvent, closeMen
|
||||
closeMenu();
|
||||
};
|
||||
|
||||
return (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconReplyInThread"
|
||||
label={_t("action|reply_in_thread")}
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
return <IconizedContextMenuOption icon={<ThreadsIcon />} label={_t("action|reply_in_thread")} onClick={onClick} />;
|
||||
};
|
||||
|
||||
interface IProps extends MenuProps {
|
||||
@ -413,7 +430,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (!mxEvent.isRedacted() && unsentReactionsCount !== 0) {
|
||||
resendReactionsButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconResend"
|
||||
icon={<RestartIcon />}
|
||||
label={_t("timeline|context_menu|resent_unsent_reactions", { unsentCount: unsentReactionsCount })}
|
||||
onClick={this.onResendReactionsClick}
|
||||
/>
|
||||
@ -424,7 +441,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (isSent && this.state.canRedact) {
|
||||
redactButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconRedact"
|
||||
icon={<DeleteIcon />}
|
||||
label={_t("action|remove")}
|
||||
onClick={this.onRedactClick}
|
||||
/>
|
||||
@ -437,7 +454,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
const mapSiteLink = createMapSiteLinkFromEvent(shareableLocationEvent);
|
||||
openInMapSiteButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconOpenInMapSite"
|
||||
icon={<PopOutIcon />}
|
||||
onClick={null}
|
||||
label={_t("timeline|context_menu|open_in_osm")}
|
||||
element="a"
|
||||
@ -455,7 +472,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (contentActionable && forwardableEvent) {
|
||||
forwardButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconForward"
|
||||
icon={<ForwardIcon />}
|
||||
label={_t("action|forward")}
|
||||
onClick={this.onForwardClick(forwardableEvent)}
|
||||
/>
|
||||
@ -465,7 +482,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
// This is specifically not behind the developerMode flag to give people insight into the Matrix
|
||||
const viewSourceButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconSource"
|
||||
icon={<InlineCodeIcon />}
|
||||
label={_t("timeline|context_menu|view_source")}
|
||||
onClick={this.onViewSourceClick}
|
||||
/>
|
||||
@ -475,7 +492,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (eventTileOps?.isWidgetHidden()) {
|
||||
unhidePreviewButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconUnhidePreview"
|
||||
icon={<VisibilityOnIcon />}
|
||||
label={_t("timeline|context_menu|show_url_preview")}
|
||||
onClick={this.onUnhidePreviewClick}
|
||||
/>
|
||||
@ -486,7 +503,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (permalink) {
|
||||
permalinkButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconPermalink"
|
||||
icon={<ShareIcon />}
|
||||
onClick={this.onShareClick}
|
||||
label={_t("action|share")}
|
||||
element="a"
|
||||
@ -506,7 +523,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (this.canEndPoll(mxEvent)) {
|
||||
endPollButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconEndPoll"
|
||||
icon={<CheckIcon />}
|
||||
label={_t("poll|end_title")}
|
||||
onClick={this.onEndPollClick}
|
||||
/>
|
||||
@ -521,7 +538,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
) {
|
||||
externalURLButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconLink"
|
||||
icon={<LinkIcon />}
|
||||
onClick={this.closeMenu}
|
||||
label={_t("timeline|context_menu|external_url")}
|
||||
element="a"
|
||||
@ -541,7 +558,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (collapseReplyChain) {
|
||||
collapseReplyChainButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconCollapse"
|
||||
icon={<ChevronUpIcon />}
|
||||
label={_t("timeline|context_menu|collapse_reply_thread")}
|
||||
onClick={this.onCollapseReplyChainClick}
|
||||
/>
|
||||
@ -553,7 +570,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (relatedEventId && SettingsStore.getValue("developerMode")) {
|
||||
jumpToRelatedEventButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_jumpToEvent"
|
||||
icon={<ChildRelationshipIcon />}
|
||||
label={_t("timeline|context_menu|view_related_event")}
|
||||
onClick={() => this.onJumpToRelatedEventClick(relatedEventId)}
|
||||
/>
|
||||
@ -564,7 +581,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (mxEvent.getSender() !== me) {
|
||||
reportEventButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconReport"
|
||||
icon={<ErrorSolidIcon />}
|
||||
label={_t("timeline|context_menu|report")}
|
||||
onClick={this.onReportEventClick}
|
||||
/>
|
||||
@ -575,7 +592,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (link) {
|
||||
copyLinkButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconCopy"
|
||||
icon={<CopyIcon />}
|
||||
onClick={this.onCopyLinkClick}
|
||||
label={_t("action|copy_link")}
|
||||
element="a"
|
||||
@ -597,7 +614,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (rightClick && selectedText) {
|
||||
copyButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconCopy"
|
||||
icon={<CopyIcon />}
|
||||
label={_t("action|copy")}
|
||||
triggerOnMouseDown={true} // We use onMouseDown so that the selection isn't cleared when we click
|
||||
onClick={this.onCopyClick}
|
||||
@ -609,7 +626,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (rightClick && selectedText && selectedText.trim().length > 0 && this.isSelectionWithinSingleTextBody()) {
|
||||
quoteButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconQuote"
|
||||
icon={<QuoteIcon />}
|
||||
label={_t("action|quote")}
|
||||
triggerOnMouseDown={true}
|
||||
onClick={this.onQuoteClick}
|
||||
@ -620,11 +637,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
let editButton: JSX.Element | undefined;
|
||||
if (rightClick && canEditContent(cli, mxEvent)) {
|
||||
editButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconEdit"
|
||||
label={_t("action|edit")}
|
||||
onClick={this.onEditClick}
|
||||
/>
|
||||
<IconizedContextMenuOption icon={<EditIcon />} label={_t("action|edit")} onClick={this.onEditClick} />
|
||||
);
|
||||
}
|
||||
|
||||
@ -632,7 +645,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (rightClick && contentActionable && canSendMessages) {
|
||||
replyButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconReply"
|
||||
icon={<ReplyIcon />}
|
||||
label={_t("action|reply")}
|
||||
onClick={this.onReplyClick}
|
||||
/>
|
||||
@ -654,7 +667,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (rightClick && contentActionable && canReact) {
|
||||
reactButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconReact"
|
||||
icon={<ReactionAddIcon />}
|
||||
label={_t("action|react")}
|
||||
onClick={this.onReactClick}
|
||||
inputRef={this.reactButtonRef}
|
||||
@ -667,7 +680,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
const isPinned = PinningUtils.isPinned(MatrixClientPeg.safeGet(), this.props.mxEvent);
|
||||
pinButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName={isPinned ? "mx_MessageContextMenu_iconUnpin" : "mx_MessageContextMenu_iconPin"}
|
||||
icon={isPinned ? <UnpinIcon /> : <PinIcon />}
|
||||
label={isPinned ? _t("action|unpin") : _t("action|pin")}
|
||||
onClick={() => this.onPinClick(isPinned)}
|
||||
/>
|
||||
@ -678,7 +691,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||
if (isThreadRootEvent) {
|
||||
viewInRoomButton = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_MessageContextMenu_iconViewInRoom"
|
||||
icon={<ViewInRoomIcon />}
|
||||
label={_t("timeline|mab|view_in_room")}
|
||||
onClick={this.viewInRoom}
|
||||
/>
|
||||
|
||||
@ -9,6 +9,15 @@ Please see LICENSE files in the repository root for full details.
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { type Room } from "matrix-js-sdk/src/matrix";
|
||||
import React, { type JSX, useContext } from "react";
|
||||
import {
|
||||
FavouriteSolidIcon,
|
||||
LinkIcon,
|
||||
SettingsSolidIcon,
|
||||
ArrowDownIcon,
|
||||
MarkAsReadIcon,
|
||||
MarkAsUnreadIcon,
|
||||
LeaveIcon,
|
||||
} from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
|
||||
import RoomListActions from "../../../actions/RoomListActions";
|
||||
@ -34,6 +43,7 @@ import { shouldShowComponent } from "../../../customisations/helpers/UIComponent
|
||||
import { UIComponent } from "../../../settings/UIFeature";
|
||||
import { DeveloperToolsOption } from "./DeveloperToolsOption";
|
||||
import { useSettingValue } from "../../../hooks/useSettings";
|
||||
import { Icon as InviteIcon } from "../../../../res/img/element-icons/room/invite.svg";
|
||||
|
||||
export interface RoomGeneralContextMenuProps extends IContextMenuProps {
|
||||
room: Room;
|
||||
@ -153,7 +163,7 @@ export const RoomGeneralContextMenu: React.FC<RoomGeneralContextMenuProps> = ({
|
||||
onClick={wrapHandler((ev) => onTagRoom(ev, DefaultTagID.Favourite), onPostFavoriteClick, true)}
|
||||
active={isFavorite}
|
||||
label={isFavorite ? _t("room|context_menu|unfavourite") : _t("room|context_menu|favourite")}
|
||||
iconClassName="mx_RoomGeneralContextMenu_iconStar"
|
||||
icon={<FavouriteSolidIcon />}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -163,7 +173,7 @@ export const RoomGeneralContextMenu: React.FC<RoomGeneralContextMenuProps> = ({
|
||||
onClick={wrapHandler((ev) => onTagRoom(ev, DefaultTagID.LowPriority), onPostLowPriorityClick, true)}
|
||||
active={isLowPriority}
|
||||
label={_t("room|context_menu|low_priority")}
|
||||
iconClassName="mx_RoomGeneralContextMenu_iconArrowDown"
|
||||
icon={<ArrowDownIcon />}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -180,7 +190,7 @@ export const RoomGeneralContextMenu: React.FC<RoomGeneralContextMenuProps> = ({
|
||||
onPostInviteClick,
|
||||
)}
|
||||
label={_t("action|invite")}
|
||||
iconClassName="mx_RoomGeneralContextMenu_iconInvite"
|
||||
icon={<InviteIcon />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -198,7 +208,7 @@ export const RoomGeneralContextMenu: React.FC<RoomGeneralContextMenuProps> = ({
|
||||
onPostCopyLinkClick,
|
||||
)}
|
||||
label={_t("room|context_menu|copy_link")}
|
||||
iconClassName="mx_RoomGeneralContextMenu_iconCopyLink"
|
||||
icon={<LinkIcon />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -214,7 +224,7 @@ export const RoomGeneralContextMenu: React.FC<RoomGeneralContextMenuProps> = ({
|
||||
onPostSettingsClick,
|
||||
)}
|
||||
label={_t("common|settings")}
|
||||
iconClassName="mx_RoomGeneralContextMenu_iconSettings"
|
||||
icon={<SettingsSolidIcon />}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -222,7 +232,7 @@ export const RoomGeneralContextMenu: React.FC<RoomGeneralContextMenuProps> = ({
|
||||
if (roomTags.includes(DefaultTagID.Archived)) {
|
||||
leaveOption = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_RoomGeneralContextMenu_iconSignOut"
|
||||
icon={<LeaveIcon />}
|
||||
label={_t("room|context_menu|forget")}
|
||||
className="mx_IconizedContextMenu_option_red"
|
||||
onClick={wrapHandler(
|
||||
@ -248,7 +258,7 @@ export const RoomGeneralContextMenu: React.FC<RoomGeneralContextMenuProps> = ({
|
||||
)}
|
||||
label={_t("action|leave")}
|
||||
className="mx_IconizedContextMenu_option_red"
|
||||
iconClassName="mx_RoomGeneralContextMenu_iconSignOut"
|
||||
icon={<LeaveIcon />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -263,7 +273,7 @@ export const RoomGeneralContextMenu: React.FC<RoomGeneralContextMenuProps> = ({
|
||||
onFinished?.();
|
||||
}, onPostMarkAsReadClick)}
|
||||
label={_t("room|context_menu|mark_read")}
|
||||
iconClassName="mx_RoomGeneralContextMenu_iconMarkAsRead"
|
||||
icon={<MarkAsReadIcon />}
|
||||
/>
|
||||
);
|
||||
} else if (!roomTags.includes(DefaultTagID.Archived)) {
|
||||
@ -274,7 +284,7 @@ export const RoomGeneralContextMenu: React.FC<RoomGeneralContextMenuProps> = ({
|
||||
onFinished?.();
|
||||
}, onPostMarkAsUnreadClick)}
|
||||
label={_t("room|context_menu|mark_unread")}
|
||||
iconClassName="mx_RoomGeneralContextMenu_iconMarkAsUnread"
|
||||
icon={<MarkAsUnreadIcon />}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
|
||||
@ -20,6 +20,10 @@ import IconizedContextMenu, {
|
||||
IconizedContextMenuRadio,
|
||||
} from "../context_menus/IconizedContextMenu";
|
||||
import { type ButtonEvent } from "../elements/AccessibleButton";
|
||||
import { Icon as NotificationsIcon } from "../../../../res/img/element-icons/notifications.svg";
|
||||
import { Icon as NotificationsDefaultIcon } from "../../../../res/img/element-icons/roomlist/notifications-default.svg";
|
||||
import { Icon as NotificationsDmIcon } from "../../../../res/img/element-icons/roomlist/notifications-dm.svg";
|
||||
import { Icon as NotificationsOffIcon } from "../../../../res/img/element-icons/roomlist/notifications-off.svg";
|
||||
|
||||
interface IProps extends IContextMenuProps {
|
||||
room: Room;
|
||||
@ -46,7 +50,7 @@ export const RoomNotificationContextMenu: React.FC<IProps> = ({ room, onFinished
|
||||
<IconizedContextMenuRadio
|
||||
label={_t("room|context_menu|notifications_default")}
|
||||
active={notificationState === RoomNotifState.AllMessages}
|
||||
iconClassName="mx_RoomNotificationContextMenu_iconBell"
|
||||
icon={<NotificationsIcon />}
|
||||
onClick={wrapHandler(() => setNotificationState(RoomNotifState.AllMessages))}
|
||||
/>
|
||||
);
|
||||
@ -55,7 +59,7 @@ export const RoomNotificationContextMenu: React.FC<IProps> = ({ room, onFinished
|
||||
<IconizedContextMenuRadio
|
||||
label={_t("notifications|all_messages")}
|
||||
active={notificationState === RoomNotifState.AllMessagesLoud}
|
||||
iconClassName="mx_RoomNotificationContextMenu_iconBellDot"
|
||||
icon={<NotificationsDefaultIcon />}
|
||||
onClick={wrapHandler(() => setNotificationState(RoomNotifState.AllMessagesLoud))}
|
||||
/>
|
||||
);
|
||||
@ -64,7 +68,7 @@ export const RoomNotificationContextMenu: React.FC<IProps> = ({ room, onFinished
|
||||
<IconizedContextMenuRadio
|
||||
label={_t("notifications|mentions_keywords")}
|
||||
active={notificationState === RoomNotifState.MentionsOnly}
|
||||
iconClassName="mx_RoomNotificationContextMenu_iconBellMentions"
|
||||
icon={<NotificationsDmIcon />}
|
||||
onClick={wrapHandler(() => setNotificationState(RoomNotifState.MentionsOnly))}
|
||||
/>
|
||||
);
|
||||
@ -73,7 +77,7 @@ export const RoomNotificationContextMenu: React.FC<IProps> = ({ room, onFinished
|
||||
<IconizedContextMenuRadio
|
||||
label={_t("room|context_menu|notifications_mute")}
|
||||
active={notificationState === RoomNotifState.Mute}
|
||||
iconClassName="mx_RoomNotificationContextMenu_iconBellCrossed"
|
||||
icon={<NotificationsOffIcon />}
|
||||
onClick={wrapHandler(() => setNotificationState(RoomNotifState.Mute))}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -8,6 +8,14 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import React, { type JSX, useContext } from "react";
|
||||
import { type Room, EventType, RoomType } from "matrix-js-sdk/src/matrix";
|
||||
import {
|
||||
HomeSolidIcon,
|
||||
PlusIcon,
|
||||
SettingsSolidIcon,
|
||||
LeaveIcon,
|
||||
SearchIcon,
|
||||
PreferencesIcon,
|
||||
} from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { type IProps as IContextMenuProps } from "../../structures/ContextMenu";
|
||||
import IconizedContextMenu, { IconizedContextMenuOption, IconizedContextMenuOptionList } from "./IconizedContextMenu";
|
||||
@ -32,6 +40,7 @@ import { shouldShowComponent } from "../../../customisations/helpers/UIComponent
|
||||
import { UIComponent } from "../../../settings/UIFeature";
|
||||
import PosthogTrackers from "../../../PosthogTrackers";
|
||||
import { type ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
||||
import { Icon as InviteIcon } from "../../../../res/img/element-icons/room/invite.svg";
|
||||
|
||||
interface IProps extends IContextMenuProps {
|
||||
space?: Room;
|
||||
@ -60,7 +69,7 @@ const SpaceContextMenu: React.FC<IProps> = ({ space, hideHeader, onFinished, ...
|
||||
<IconizedContextMenuOption
|
||||
data-testid="invite-option"
|
||||
className="mx_SpacePanel_contextMenu_inviteButton"
|
||||
iconClassName="mx_SpacePanel_iconInvite"
|
||||
icon={<InviteIcon />}
|
||||
label={_t("action|invite")}
|
||||
onClick={onInviteClick}
|
||||
/>
|
||||
@ -81,7 +90,7 @@ const SpaceContextMenu: React.FC<IProps> = ({ space, hideHeader, onFinished, ...
|
||||
settingsOption = (
|
||||
<IconizedContextMenuOption
|
||||
data-testid="settings-option"
|
||||
iconClassName="mx_SpacePanel_iconSettings"
|
||||
icon={<SettingsSolidIcon />}
|
||||
label={_t("common|settings")}
|
||||
onClick={onSettingsClick}
|
||||
/>
|
||||
@ -98,7 +107,7 @@ const SpaceContextMenu: React.FC<IProps> = ({ space, hideHeader, onFinished, ...
|
||||
leaveOption = (
|
||||
<IconizedContextMenuOption
|
||||
data-testid="leave-option"
|
||||
iconClassName="mx_SpacePanel_iconLeave"
|
||||
icon={<LeaveIcon />}
|
||||
className="mx_IconizedContextMenu_option_red"
|
||||
label={_t("space|leave_dialog_action")}
|
||||
onClick={onLeaveClick}
|
||||
@ -123,7 +132,7 @@ const SpaceContextMenu: React.FC<IProps> = ({ space, hideHeader, onFinished, ...
|
||||
|
||||
devtoolsOption = (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_SpacePanel_iconSettings"
|
||||
icon={<SettingsSolidIcon />}
|
||||
label={_t("space|context_menu|devtools_open_timeline")}
|
||||
onClick={onViewTimelineClick}
|
||||
/>
|
||||
@ -170,7 +179,7 @@ const SpaceContextMenu: React.FC<IProps> = ({ space, hideHeader, onFinished, ...
|
||||
{canAddRooms && (
|
||||
<IconizedContextMenuOption
|
||||
data-testid="new-room-option"
|
||||
iconClassName="mx_SpacePanel_iconPlus"
|
||||
icon={<PlusIcon />}
|
||||
label={_t("common|room")}
|
||||
onClick={onNewRoomClick}
|
||||
/>
|
||||
@ -178,7 +187,7 @@ const SpaceContextMenu: React.FC<IProps> = ({ space, hideHeader, onFinished, ...
|
||||
{canAddVideoRooms && (
|
||||
<IconizedContextMenuOption
|
||||
data-testid="new-video-room-option"
|
||||
iconClassName="mx_SpacePanel_iconPlus"
|
||||
icon={<PlusIcon />}
|
||||
label={_t("common|video_room")}
|
||||
onClick={onNewVideoRoomClick}
|
||||
>
|
||||
@ -188,7 +197,7 @@ const SpaceContextMenu: React.FC<IProps> = ({ space, hideHeader, onFinished, ...
|
||||
{canAddSubSpaces && (
|
||||
<IconizedContextMenuOption
|
||||
data-testid="new-subspace-option"
|
||||
iconClassName="mx_SpacePanel_iconPlus"
|
||||
icon={<PlusIcon />}
|
||||
label={_t("common|space")}
|
||||
onClick={onNewSubspaceClick}
|
||||
>
|
||||
@ -234,18 +243,18 @@ const SpaceContextMenu: React.FC<IProps> = ({ space, hideHeader, onFinished, ...
|
||||
{!hideHeader && <div className="mx_SpacePanel_contextMenu_header">{space.name}</div>}
|
||||
<IconizedContextMenuOptionList first>
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_SpacePanel_iconHome"
|
||||
icon={<HomeSolidIcon />}
|
||||
label={_t("space|context_menu|home")}
|
||||
onClick={onHomeClick}
|
||||
/>
|
||||
{inviteOption}
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_SpacePanel_iconExplore"
|
||||
icon={<SearchIcon />}
|
||||
label={canAddRooms ? _t("space|context_menu|manage_and_explore") : _t("space|context_menu|explore")}
|
||||
onClick={onExploreRoomsClick}
|
||||
/>
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_SpacePanel_iconPreferences"
|
||||
icon={<PreferencesIcon />}
|
||||
label={_t("common|preferences")}
|
||||
onClick={onPreferencesClick}
|
||||
/>
|
||||
|
||||
@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
import { type MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { LinkIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { type ButtonEvent } from "../elements/AccessibleButton";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
@ -20,6 +21,7 @@ import IconizedContextMenu, { IconizedContextMenuOption, IconizedContextMenuOpti
|
||||
import { WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import { type ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
||||
import { Icon as ViewInRoomIcon } from "../../../../res/img/element-icons/view-in-room.svg";
|
||||
|
||||
export interface ThreadListContextMenuProps {
|
||||
mxEvent: MatrixEvent;
|
||||
@ -102,7 +104,7 @@ const ThreadListContextMenu: React.FC<ThreadListContextMenuProps> = ({
|
||||
<IconizedContextMenuOption
|
||||
onClick={(e) => viewInRoom(e)}
|
||||
label={_t("timeline|mab|view_in_room")}
|
||||
iconClassName="mx_ThreadPanel_viewInRoom"
|
||||
icon={<ViewInRoomIcon />}
|
||||
/>
|
||||
)}
|
||||
{permalinkCreator && (
|
||||
@ -110,7 +112,7 @@ const ThreadListContextMenu: React.FC<ThreadListContextMenuProps> = ({
|
||||
data-testid="copy-thread-link"
|
||||
onClick={(e) => copyLinkToThread(e)}
|
||||
label={_t("timeline|mab|copy_link_thread")}
|
||||
iconClassName="mx_ThreadPanel_copyLinkToThread"
|
||||
icon={<LinkIcon />}
|
||||
/>
|
||||
)}
|
||||
</IconizedContextMenuOptionList>
|
||||
|
||||
@ -6,9 +6,9 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import classNames from "classnames";
|
||||
import { type Room } from "matrix-js-sdk/src/matrix";
|
||||
import React, { type JSX, Fragment, useState } from "react";
|
||||
import React, { type JSX, Fragment, useState, type ReactNode } from "react";
|
||||
import { OverflowHorizontalIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { ContextMenuTooltipButton } from "../../../../accessibility/context_menu/ContextMenuTooltipButton";
|
||||
import { useNotificationState } from "../../../../hooks/useRoomNotificationState";
|
||||
@ -21,11 +21,25 @@ import { type ButtonEvent } from "../../elements/AccessibleButton";
|
||||
import { contextMenuBelow } from "../../rooms/RoomTile";
|
||||
import { shouldShowComponent } from "../../../../customisations/helpers/UIComponents";
|
||||
import { UIComponent } from "../../../../settings/UIFeature";
|
||||
import { Icon as NotificationsIcon } from "../../../../../res/img/element-icons/notifications.svg";
|
||||
import { Icon as NotificationsDefaultIcon } from "../../../../../res/img/element-icons/roomlist/notifications-default.svg";
|
||||
import { Icon as NotificationsDmIcon } from "../../../../../res/img/element-icons/roomlist/notifications-dm.svg";
|
||||
import { Icon as NotificationsOffIcon } from "../../../../../res/img/element-icons/roomlist/notifications-off.svg";
|
||||
|
||||
interface Props {
|
||||
room: Room;
|
||||
}
|
||||
|
||||
export function getNotificationIcon(state: RoomNotifState): ReactNode {
|
||||
const icons: Record<RoomNotifState, JSX.Element> = {
|
||||
[RoomNotifState.AllMessages]: <NotificationsIcon />,
|
||||
[RoomNotifState.AllMessagesLoud]: <NotificationsDefaultIcon />,
|
||||
[RoomNotifState.MentionsOnly]: <NotificationsDmIcon />,
|
||||
[RoomNotifState.Mute]: <NotificationsOffIcon />,
|
||||
};
|
||||
return icons[state];
|
||||
}
|
||||
|
||||
export function RoomResultContextMenus({ room }: Props): JSX.Element {
|
||||
const [notificationState] = useNotificationState(room);
|
||||
|
||||
@ -64,14 +78,6 @@ export function RoomResultContextMenus({ room }: Props): JSX.Element {
|
||||
);
|
||||
}
|
||||
|
||||
const notificationMenuClasses = classNames("mx_SpotlightDialog_option--notifications", {
|
||||
// Show bell icon for the default case too.
|
||||
mx_RoomNotificationContextMenu_iconBell: notificationState === RoomNotifState.AllMessages,
|
||||
mx_RoomNotificationContextMenu_iconBellDot: notificationState === RoomNotifState.AllMessagesLoud,
|
||||
mx_RoomNotificationContextMenu_iconBellMentions: notificationState === RoomNotifState.MentionsOnly,
|
||||
mx_RoomNotificationContextMenu_iconBellCrossed: notificationState === RoomNotifState.Mute,
|
||||
});
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
{shouldShowComponent(UIComponent.RoomOptionsMenu) && (
|
||||
@ -86,11 +92,13 @@ export function RoomResultContextMenus({ room }: Props): JSX.Element {
|
||||
}}
|
||||
title={room.isSpaceRoom() ? _t("space|context_menu|options") : _t("room|context_menu|title")}
|
||||
isExpanded={generalMenuPosition !== null}
|
||||
/>
|
||||
>
|
||||
<OverflowHorizontalIcon />
|
||||
</ContextMenuTooltipButton>
|
||||
)}
|
||||
{!room.isSpaceRoom() && (
|
||||
<ContextMenuTooltipButton
|
||||
className={notificationMenuClasses}
|
||||
className="mx_SpotlightDialog_option--notifications"
|
||||
onClick={(ev: ButtonEvent) => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
@ -100,7 +108,9 @@ export function RoomResultContextMenus({ room }: Props): JSX.Element {
|
||||
}}
|
||||
title={_t("room_list|notification_options")}
|
||||
isExpanded={notificationMenuPosition !== null}
|
||||
/>
|
||||
>
|
||||
{getNotificationIcon(notificationState!)}
|
||||
</ContextMenuTooltipButton>
|
||||
)}
|
||||
{generalMenu}
|
||||
{notificationMenu}
|
||||
|
||||
@ -8,6 +8,13 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import { EventType, type Room, RoomType } from "matrix-js-sdk/src/matrix";
|
||||
import React, { type JSX, type ComponentType, createRef, type ReactComponentElement, type SyntheticEvent } from "react";
|
||||
import {
|
||||
PlusIcon,
|
||||
UserAddSolidIcon,
|
||||
RoomIcon,
|
||||
SearchIcon,
|
||||
ShareIcon,
|
||||
} from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { type IState as IRovingTabIndexState, RovingTabIndexProvider } from "../../../accessibility/RovingTabIndex.tsx";
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext.tsx";
|
||||
@ -67,6 +74,7 @@ import { getKeyBindingsManager } from "../../../KeyBindingsManager.ts";
|
||||
import AccessibleButton from "../elements/AccessibleButton.tsx";
|
||||
import { Landmark, LandmarkNavigation } from "../../../accessibility/LandmarkNavigation.ts";
|
||||
import LegacyCallHandler, { LegacyCallHandlerEvent } from "../../../LegacyCallHandler.tsx";
|
||||
import { Icon as HashVideoIcon } from "../../../../res/img/element-icons/roomlist/hash-video.svg";
|
||||
|
||||
interface IProps {
|
||||
onKeyDown: (ev: React.KeyboardEvent, state: IRovingTabIndexState) => void;
|
||||
@ -142,7 +150,7 @@ const DmAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex, dispatcher = default
|
||||
{showCreateRooms && (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|start_new_chat")}
|
||||
iconClassName="mx_LegacyRoomList_iconStartChat"
|
||||
icon={<UserAddSolidIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -158,7 +166,7 @@ const DmAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex, dispatcher = default
|
||||
{showInviteUsers && (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|invite_to_space")}
|
||||
iconClassName="mx_LegacyRoomList_iconInvite"
|
||||
icon={<ShareIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -230,7 +238,7 @@ const UntaggedAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex }) => {
|
||||
<IconizedContextMenuOptionList first>
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|explore_rooms")}
|
||||
iconClassName="mx_LegacyRoomList_iconExplore"
|
||||
icon={<SearchIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -247,7 +255,7 @@ const UntaggedAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex }) => {
|
||||
<>
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|new_room")}
|
||||
iconClassName="mx_LegacyRoomList_iconNewRoom"
|
||||
icon={<PlusIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -261,7 +269,7 @@ const UntaggedAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex }) => {
|
||||
{videoRoomsEnabled && (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|new_video_room")}
|
||||
iconClassName="mx_LegacyRoomList_iconNewVideoRoom"
|
||||
icon={<HashVideoIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -279,7 +287,7 @@ const UntaggedAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex }) => {
|
||||
)}
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|add_existing_room")}
|
||||
iconClassName="mx_LegacyRoomList_iconAddExistingRoom"
|
||||
icon={<RoomIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -300,7 +308,7 @@ const UntaggedAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex }) => {
|
||||
<>
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|new_room")}
|
||||
iconClassName="mx_LegacyRoomList_iconNewRoom"
|
||||
icon={<PlusIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -312,7 +320,7 @@ const UntaggedAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex }) => {
|
||||
{videoRoomsEnabled && (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|new_video_room")}
|
||||
iconClassName="mx_LegacyRoomList_iconNewVideoRoom"
|
||||
icon={<HashVideoIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -333,7 +341,7 @@ const UntaggedAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex }) => {
|
||||
{showExploreRooms ? (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|explore_public_rooms")}
|
||||
iconClassName="mx_LegacyRoomList_iconExplore"
|
||||
icon={<SearchIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
import { ClientEvent, EventType, type Room, RoomEvent, RoomType } from "matrix-js-sdk/src/matrix";
|
||||
import React, { type JSX, useContext, useEffect, useState } from "react";
|
||||
import { Tooltip } from "@vector-im/compound-web";
|
||||
import { PlusIcon, UserAddSolidIcon, SearchIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
|
||||
@ -51,6 +52,8 @@ import IconizedContextMenu, {
|
||||
import SpaceContextMenu from "../context_menus/SpaceContextMenu";
|
||||
import InlineSpinner from "../elements/InlineSpinner";
|
||||
import { HomeButtonContextMenu } from "../spaces/SpacePanel";
|
||||
import { Icon as InviteIcon } from "../../../../res/img/element-icons/room/invite.svg";
|
||||
import { Icon as HashVideoIcon } from "../../../../res/img/element-icons/roomlist/hash-video.svg";
|
||||
|
||||
const contextMenuBelow = (elementRect: DOMRect): MenuProps => {
|
||||
// align the context menu's icons with the icon which opened the context menu
|
||||
@ -178,7 +181,7 @@ const LegacyRoomListHeader: React.FC<IProps> = ({ onVisibilityChange }) => {
|
||||
inviteOption = (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|invite")}
|
||||
iconClassName="mx_LegacyRoomListHeader_iconInvite"
|
||||
icon={<InviteIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -194,7 +197,7 @@ const LegacyRoomListHeader: React.FC<IProps> = ({ onVisibilityChange }) => {
|
||||
newRoomOptions = (
|
||||
<>
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_LegacyRoomListHeader_iconNewRoom"
|
||||
icon={<PlusIcon />}
|
||||
label={_t("action|new_room")}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
@ -206,7 +209,7 @@ const LegacyRoomListHeader: React.FC<IProps> = ({ onVisibilityChange }) => {
|
||||
/>
|
||||
{videoRoomsEnabled && (
|
||||
<IconizedContextMenuOption
|
||||
iconClassName="mx_LegacyRoomListHeader_iconNewVideoRoom"
|
||||
icon={<HashVideoIcon />}
|
||||
label={_t("action|new_video_room")}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
@ -236,7 +239,7 @@ const LegacyRoomListHeader: React.FC<IProps> = ({ onVisibilityChange }) => {
|
||||
{newRoomOptions}
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|explore_rooms")}
|
||||
iconClassName="mx_LegacyRoomListHeader_iconExplore"
|
||||
icon={<SearchIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -251,7 +254,7 @@ const LegacyRoomListHeader: React.FC<IProps> = ({ onVisibilityChange }) => {
|
||||
/>
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|add_existing_room")}
|
||||
iconClassName="mx_LegacyRoomListHeader_iconPlus"
|
||||
icon={<PlusIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -264,7 +267,7 @@ const LegacyRoomListHeader: React.FC<IProps> = ({ onVisibilityChange }) => {
|
||||
{canCreateSpaces && (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("room_list|add_space_label")}
|
||||
iconClassName="mx_LegacyRoomListHeader_iconPlus"
|
||||
icon={<PlusIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -289,7 +292,7 @@ const LegacyRoomListHeader: React.FC<IProps> = ({ onVisibilityChange }) => {
|
||||
<>
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|start_new_chat")}
|
||||
iconClassName="mx_LegacyRoomListHeader_iconStartChat"
|
||||
icon={<UserAddSolidIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -300,7 +303,7 @@ const LegacyRoomListHeader: React.FC<IProps> = ({ onVisibilityChange }) => {
|
||||
/>
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|new_room")}
|
||||
iconClassName="mx_LegacyRoomListHeader_iconNewRoom"
|
||||
icon={<PlusIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -312,7 +315,7 @@ const LegacyRoomListHeader: React.FC<IProps> = ({ onVisibilityChange }) => {
|
||||
{videoRoomsEnabled && (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("action|new_video_room")}
|
||||
iconClassName="mx_LegacyRoomListHeader_iconNewVideoRoom"
|
||||
icon={<HashVideoIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -333,7 +336,7 @@ const LegacyRoomListHeader: React.FC<IProps> = ({ onVisibilityChange }) => {
|
||||
joinRoomOpt = (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("room_list|join_public_room_label")}
|
||||
iconClassName="mx_LegacyRoomListHeader_iconExplore"
|
||||
icon={<SearchIcon />}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
@ -45,6 +45,7 @@ import { shouldShowComponent } from "../../../customisations/helpers/UIComponent
|
||||
import { UIComponent } from "../../../settings/UIFeature";
|
||||
import { isKnockDenied } from "../../../utils/membership";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { getNotificationIcon } from "../dialogs/spotlight/RoomResultContextMenus.tsx";
|
||||
|
||||
interface Props {
|
||||
room: Room;
|
||||
@ -293,12 +294,6 @@ class RoomTile extends React.PureComponent<Props, State> {
|
||||
const state = this.roomProps.notificationVolume;
|
||||
|
||||
const classes = classNames("mx_RoomTile_notificationsButton", {
|
||||
// Show bell icon for the default case too.
|
||||
mx_RoomNotificationContextMenu_iconBell: state === RoomNotifState.AllMessages,
|
||||
mx_RoomNotificationContextMenu_iconBellDot: state === RoomNotifState.AllMessagesLoud,
|
||||
mx_RoomNotificationContextMenu_iconBellMentions: state === RoomNotifState.MentionsOnly,
|
||||
mx_RoomNotificationContextMenu_iconBellCrossed: state === RoomNotifState.Mute,
|
||||
|
||||
// Only show the icon by default if the room is overridden to muted.
|
||||
// TODO: [FTUE Notifications] Probably need to detect global mute state
|
||||
mx_RoomTile_notificationsButton_show: state === RoomNotifState.Mute,
|
||||
@ -312,7 +307,9 @@ class RoomTile extends React.PureComponent<Props, State> {
|
||||
title={_t("room_list|notification_options")}
|
||||
isExpanded={!!this.state.notificationsMenuPosition}
|
||||
tabIndex={isActive ? 0 : -1}
|
||||
/>
|
||||
>
|
||||
{getNotificationIcon(state!)}
|
||||
</ContextMenuTooltipButton>
|
||||
{this.state.notificationsMenuPosition && (
|
||||
<RoomNotificationContextMenu
|
||||
{...contextMenuBelow(this.state.notificationsMenuPosition)}
|
||||
|
||||
@ -99,7 +99,6 @@ export const HomeButtonContextMenu: React.FC<ComponentProps<typeof SpaceContextM
|
||||
{!hideHeader && <div className="mx_SpacePanel_contextMenu_header">{_t("common|home")}</div>}
|
||||
<IconizedContextMenuOptionList first>
|
||||
<IconizedContextMenuCheckbox
|
||||
iconClassName="mx_SpacePanel_noIcon"
|
||||
label={_t("settings|sidebar|metaspaces_home_all_rooms")}
|
||||
active={allRoomsInHome}
|
||||
onClick={() => {
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright 2025 Element Creations 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 { render } from "jest-matrix-react";
|
||||
import React from "react";
|
||||
|
||||
import { clearAllModals } from "../../../../test-utils";
|
||||
import DeviceContextMenu from "../../../../../src/components/views/context_menus/DeviceContextMenu.tsx";
|
||||
import MediaDeviceHandler from "../../../../../src/MediaDeviceHandler.ts";
|
||||
|
||||
describe("DeviceContextMenu", () => {
|
||||
afterEach(async () => {
|
||||
await clearAllModals();
|
||||
});
|
||||
|
||||
it("renders a menu with the selected device checked", async () => {
|
||||
jest.spyOn(MediaDeviceHandler, "getDevices").mockResolvedValue({
|
||||
videoinput: [
|
||||
{ deviceId: "A", label: "Camera 1" } as MediaDeviceInfo,
|
||||
{ deviceId: "B", label: "Camera 2" } as MediaDeviceInfo,
|
||||
{ deviceId: "C", label: "Camera 3" } as MediaDeviceInfo,
|
||||
],
|
||||
audioinput: [],
|
||||
audiooutput: [],
|
||||
});
|
||||
jest.spyOn(MediaDeviceHandler, "getDevice").mockReturnValue("B");
|
||||
|
||||
const { container, findByLabelText } = render(
|
||||
<DeviceContextMenu deviceKinds={["videoinput"]} onFinished={jest.fn()} mountAsChild />,
|
||||
);
|
||||
|
||||
await expect(findByLabelText("Camera 2")).resolves.toBeChecked();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,85 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`DeviceContextMenu renders a menu with the selected device checked 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_ContextualMenu_wrapper"
|
||||
>
|
||||
<div
|
||||
class="mx_ContextualMenu_background"
|
||||
/>
|
||||
<div
|
||||
class="mx_ContextualMenu"
|
||||
role="menu"
|
||||
>
|
||||
<ul
|
||||
class="mx_IconizedContextMenu mx_DeviceContextMenu mx_IconizedContextMenu_compact"
|
||||
role="none"
|
||||
>
|
||||
<div
|
||||
class="mx_IconizedContextMenu_optionList mx_IconizedContextMenu_optionList_notFirst"
|
||||
>
|
||||
<div>
|
||||
<span
|
||||
class="mx_IconizedContextMenu_optionList_label"
|
||||
>
|
||||
Cameras
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
aria-checked="false"
|
||||
aria-label="Camera 1"
|
||||
class="mx_AccessibleButton mx_IconizedContextMenu_item"
|
||||
role="menuitemradio"
|
||||
tabindex="0"
|
||||
>
|
||||
<span
|
||||
class="mx_IconizedContextMenu_label"
|
||||
>
|
||||
Camera 1
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
aria-checked="true"
|
||||
aria-label="Camera 2"
|
||||
class="mx_AccessibleButton mx_IconizedContextMenu_item mx_IconizedContextMenu_active"
|
||||
role="menuitemradio"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="mx_IconizedContextMenu_label"
|
||||
>
|
||||
Camera 2
|
||||
</span>
|
||||
<svg
|
||||
class="mx_IconizedContextMenu_checked"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M9.55 17.575q-.2 0-.375-.062a.9.9 0 0 1-.325-.213L4.55 13q-.274-.274-.262-.713.012-.437.287-.712a.95.95 0 0 1 .7-.275q.425 0 .7.275L9.55 15.15l8.475-8.475q.274-.275.713-.275.437 0 .712.275.275.274.275.713 0 .437-.275.712l-9.2 9.2q-.15.15-.325.212a1.1 1.1 0 0 1-.375.063"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
aria-checked="false"
|
||||
aria-label="Camera 3"
|
||||
class="mx_AccessibleButton mx_IconizedContextMenu_item"
|
||||
role="menuitemradio"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="mx_IconizedContextMenu_label"
|
||||
>
|
||||
Camera 3
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@ -32,9 +32,20 @@ exports[`RoomGeneralContextMenu renders an empty context menu for archived rooms
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="mx_IconizedContextMenu_icon mx_RoomGeneralContextMenu_iconSignOut"
|
||||
/>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M14 13q.424 0 .713-.287A.97.97 0 0 0 15 12a.97.97 0 0 0-.287-.713A.97.97 0 0 0 14 11a.97.97 0 0 0-.713.287A.97.97 0 0 0 13 12q0 .424.287.713.288.287.713.287"
|
||||
/>
|
||||
<path
|
||||
d="M10.385 21.788A1 1 0 0 1 10 21V3a1.003 1.003 0 0 1 1.242-.97l8 2A1 1 0 0 1 20 5v14a1 1 0 0 1-.758.97l-8 2a1 1 0 0 1-.857-.182M18 5.781l-6-1.5v15.438l6-1.5zM9 6H7v12h2v2H7a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2z"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
class="mx_IconizedContextMenu_label"
|
||||
>
|
||||
@ -80,9 +91,20 @@ exports[`RoomGeneralContextMenu renders the default context menu 1`] = `
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="mx_IconizedContextMenu_icon mx_RoomGeneralContextMenu_iconSignOut"
|
||||
/>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M14 13q.424 0 .713-.287A.97.97 0 0 0 15 12a.97.97 0 0 0-.287-.713A.97.97 0 0 0 14 11a.97.97 0 0 0-.713.287A.97.97 0 0 0 13 12q0 .424.287.713.288.287.713.287"
|
||||
/>
|
||||
<path
|
||||
d="M10.385 21.788A1 1 0 0 1 10 21V3a1.003 1.003 0 0 1 1.242-.97l8 2A1 1 0 0 1 20 5v14a1 1 0 0 1-.758.97l-8 2a1 1 0 0 1-.857-.182M18 5.781l-6-1.5v15.438l6-1.5zM9 6H7v12h2v2H7a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2z"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
class="mx_IconizedContextMenu_label"
|
||||
>
|
||||
|
||||
@ -34,9 +34,17 @@ exports[`<SpaceContextMenu /> renders menu correctly 1`] = `
|
||||
[33mrole[39m=[32m"menuitem"[39m
|
||||
[33mtabindex[39m=[32m"0"[39m
|
||||
[36m>[39m
|
||||
[36m<span[39m
|
||||
[33mclass[39m=[32m"mx_IconizedContextMenu_icon mx_SpacePanel_iconHome"[39m
|
||||
[36m/>[39m
|
||||
[36m<svg[39m
|
||||
[33mfill[39m=[32m"currentColor"[39m
|
||||
[33mheight[39m=[32m"1em"[39m
|
||||
[33mviewBox[39m=[32m"0 0 24 24"[39m
|
||||
[33mwidth[39m=[32m"1em"[39m
|
||||
[33mxmlns[39m=[32m"http://www.w3.org/2000/svg"[39m
|
||||
[36m>[39m
|
||||
[36m<path[39m
|
||||
[33md[39m=[32m"m12.971 3.54 7 3.889A2 2 0 0 1 21 9.177V19a2 2 0 0 1-2 2h-4v-9H9v9H5a2 2 0 0 1-2-2V9.177a2 2 0 0 1 1.029-1.748l7-3.89a2 2 0 0 1 1.942 0"[39m
|
||||
[36m/>[39m
|
||||
[36m</svg>[39m
|
||||
[36m<span[39m
|
||||
[33mclass[39m=[32m"mx_IconizedContextMenu_label"[39m
|
||||
[36m>[39m
|
||||
@ -49,9 +57,17 @@ exports[`<SpaceContextMenu /> renders menu correctly 1`] = `
|
||||
[33mrole[39m=[32m"menuitem"[39m
|
||||
[33mtabindex[39m=[32m"-1"[39m
|
||||
[36m>[39m
|
||||
[36m<span[39m
|
||||
[33mclass[39m=[32m"mx_IconizedContextMenu_icon mx_SpacePanel_iconExplore"[39m
|
||||
[36m/>[39m
|
||||
[36m<svg[39m
|
||||
[33mfill[39m=[32m"currentColor"[39m
|
||||
[33mheight[39m=[32m"1em"[39m
|
||||
[33mviewBox[39m=[32m"0 0 24 24"[39m
|
||||
[33mwidth[39m=[32m"1em"[39m
|
||||
[33mxmlns[39m=[32m"http://www.w3.org/2000/svg"[39m
|
||||
[36m>[39m
|
||||
[36m<path[39m
|
||||
[33md[39m=[32m"M15.05 16.463a7.5 7.5 0 1 1 1.414-1.414l3.243 3.244a1 1 0 0 1-1.414 1.414zM16 10.5a5.5 5.5 0 1 0-11 0 5.5 5.5 0 0 0 11 0"[39m
|
||||
[36m/>[39m
|
||||
[36m</svg>[39m
|
||||
[36m<span[39m
|
||||
[33mclass[39m=[32m"mx_IconizedContextMenu_label"[39m
|
||||
[36m>[39m
|
||||
@ -64,9 +80,19 @@ exports[`<SpaceContextMenu /> renders menu correctly 1`] = `
|
||||
[33mrole[39m=[32m"menuitem"[39m
|
||||
[33mtabindex[39m=[32m"-1"[39m
|
||||
[36m>[39m
|
||||
[36m<span[39m
|
||||
[33mclass[39m=[32m"mx_IconizedContextMenu_icon mx_SpacePanel_iconPreferences"[39m
|
||||
[36m/>[39m
|
||||
[36m<svg[39m
|
||||
[33mfill[39m=[32m"currentColor"[39m
|
||||
[33mheight[39m=[32m"1em"[39m
|
||||
[33mviewBox[39m=[32m"0 0 24 24"[39m
|
||||
[33mwidth[39m=[32m"1em"[39m
|
||||
[33mxmlns[39m=[32m"http://www.w3.org/2000/svg"[39m
|
||||
[36m>[39m
|
||||
[36m<path[39m
|
||||
[33mclip-rule[39m=[32m"evenodd"[39m
|
||||
[33md[39m=[32m"M6.5 2h11a4.5 4.5 0 1 1 0 9h-11a4.5 4.5 0 0 1 0-9m0 2h7.258A4.5 4.5 0 0 0 13 6.5c0 .925.28 1.785.758 2.5H6.5a2.5 2.5 0 0 1 0-5M15 6.5a2.5 2.5 0 1 1 5 0 2.5 2.5 0 0 1-5 0m-13 11A4.5 4.5 0 0 1 6.5 13h11a4.5 4.5 0 1 1 0 9h-11q-.233 0-.46-.023A4.5 4.5 0 0 1 2 17.5m8.242-2.5H17.5a2.5 2.5 0 0 1 0 5h-7.258A4.5 4.5 0 0 0 11 17.5c0-.925-.28-1.785-.758-2.5M6.5 15a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5"[39m
|
||||
[33mfill-rule[39m=[32m"evenodd"[39m
|
||||
[36m/>[39m
|
||||
[36m</svg>[39m
|
||||
[36m<span[39m
|
||||
[33mclass[39m=[32m"mx_IconizedContextMenu_label"[39m
|
||||
[36m>[39m
|
||||
@ -80,9 +106,20 @@ exports[`<SpaceContextMenu /> renders menu correctly 1`] = `
|
||||
[33mrole[39m=[32m"menuitem"[39m
|
||||
[33mtabindex[39m=[32m"-1"[39m
|
||||
[36m>[39m
|
||||
[36m<span[39m
|
||||
[33mclass[39m=[32m"mx_IconizedContextMenu_icon mx_SpacePanel_iconLeave"[39m
|
||||
[36m/>[39m
|
||||
[36m<svg[39m
|
||||
[33mfill[39m=[32m"currentColor"[39m
|
||||
[33mheight[39m=[32m"1em"[39m
|
||||
[33mviewBox[39m=[32m"0 0 24 24"[39m
|
||||
[33mwidth[39m=[32m"1em"[39m
|
||||
[33mxmlns[39m=[32m"http://www.w3.org/2000/svg"[39m
|
||||
[36m>[39m
|
||||
[36m<path[39m
|
||||
[33md[39m=[32m"M14 13q.424 0 .713-.287A.97.97 0 0 0 15 12a.97.97 0 0 0-.287-.713A.97.97 0 0 0 14 11a.97.97 0 0 0-.713.287A.97.97 0 0 0 13 12q0 .424.287.713.288.287.713.287"[39m
|
||||
[36m/>[39m
|
||||
[36m<path[39m
|
||||
[33md[39m=[32m"M10.385 21.788A1 1 0 0 1 10 21V3a1.003 1.003 0 0 1 1.242-.97l8 2A1 1 0 0 1 20 5v14a1 1 0 0 1-.758.97l-8 2a1 1 0 0 1-.857-.182M18 5.781l-6-1.5v15.438l6-1.5zM9 6H7v12h2v2H7a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2z"[39m
|
||||
[36m/>[39m
|
||||
[36m</svg>[39m
|
||||
[36m<span[39m
|
||||
[33mclass[39m=[32m"mx_IconizedContextMenu_label"[39m
|
||||
[36m>[39m
|
||||
|
||||