Update RoomSummaryCard navigation links (#11812)
* Update RoomSummaryCard navigation links * Fix tests * remove unneeded test * "@vector-im/compound-web": "0.8.0" * Fix: search button no transition on hover * Fix: disabled invite option is not reflected in UI * test canInviteTo * update snapshots for CW 0.8.1 * unit test inviteToRoom * unit test tagRoom * add member link to roomsummarycard when using legacy room header * use onChange instead of onClick for ToggleMenuItem favourite room * update selectors in cypress tests * always show people menu item * add hover style to close button * add padding around room name * prettier --------- Co-authored-by: Kerry Archibald <kerrya@element.io>
This commit is contained in:
parent
b8ff3c169b
commit
f96583e74a
25 changed files with 857 additions and 245 deletions
|
@ -116,7 +116,7 @@ const verify = function (this: CryptoTestContext) {
|
|||
const bobsVerificationRequestPromise = waitForVerificationRequest(this.bob);
|
||||
|
||||
openRoomInfo().within(() => {
|
||||
cy.findByRole("button", { name: /People \d/ }).click(); // \d is the number of the room members
|
||||
cy.findByRole("menuitem", { name: "People" }).click();
|
||||
cy.findByText("Bob").click();
|
||||
cy.findByRole("button", { name: "Verify" }).click();
|
||||
cy.findByRole("button", { name: "Start Verification" }).click();
|
||||
|
|
|
@ -47,16 +47,8 @@ describe("Invite dialog", function () {
|
|||
// Open the room info panel
|
||||
cy.findByRole("button", { name: "Room info" }).click();
|
||||
|
||||
cy.get(".mx_RightPanel").within(() => {
|
||||
// Click "People" button on the panel
|
||||
// Regex pattern due to the string of "mx_BaseCard_Button_sublabel"
|
||||
cy.findByRole("button", { name: /People/ }).click();
|
||||
});
|
||||
|
||||
cy.get(".mx_BaseCard").within(() => {
|
||||
// Click "Invite to this room" button
|
||||
// Regex pattern due to "mx_MemberList_invite span::before"
|
||||
cy.findByRole("button", { name: /Invite to this room/ }).click();
|
||||
cy.findByRole("menuitem", { name: "Invite" }).click();
|
||||
});
|
||||
|
||||
cy.get(".mx_InviteDialog_other").within(() => {
|
||||
|
|
|
@ -121,7 +121,7 @@ describe("Lazy Loading", () => {
|
|||
});
|
||||
|
||||
cy.get(".mx_RoomSummaryCard").within(() => {
|
||||
cy.findByRole("button", { name: /People \d/ }).click(); // \d represents the number of the room members
|
||||
cy.findByRole("menuitem", { name: "People" }).click(); // \d represents the number of the room members
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ describe("Poll history", () => {
|
|||
function openPollHistory(): void {
|
||||
cy.findByRole("button", { name: "Room info" }).click();
|
||||
cy.get(".mx_RoomSummaryCard").within(() => {
|
||||
cy.findByRole("button", { name: "Poll history" }).click();
|
||||
cy.findByRole("menuitem", { name: "Poll history" }).click();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ describe("FilePanel", () => {
|
|||
|
||||
// Open the file panel
|
||||
viewRoomSummaryByName(ROOM_NAME);
|
||||
cy.get(".mx_RoomSummaryCard_icon_files").click();
|
||||
cy.findByRole("menuitem", { name: "Files" }).click();
|
||||
cy.get(".mx_FilePanel").should("have.length", 1);
|
||||
});
|
||||
|
||||
|
|
|
@ -103,21 +103,21 @@ describe("RightPanel", () => {
|
|||
it("should handle viewing export chat", () => {
|
||||
viewRoomSummaryByName(ROOM_NAME);
|
||||
|
||||
cy.findByRole("button", { name: "Export chat" }).click();
|
||||
cy.findByRole("menuitem", { name: "Export Chat" }).click();
|
||||
cy.get(".mx_ExportDialog").should("have.length", 1);
|
||||
});
|
||||
|
||||
it("should handle viewing share room", () => {
|
||||
viewRoomSummaryByName(ROOM_NAME);
|
||||
|
||||
cy.findByRole("button", { name: "Share room" }).click();
|
||||
cy.findByRole("menuitem", { name: "Copy link" }).click();
|
||||
cy.get(".mx_ShareDialog").should("have.length", 1);
|
||||
});
|
||||
|
||||
it("should handle viewing room settings", () => {
|
||||
viewRoomSummaryByName(ROOM_NAME);
|
||||
|
||||
cy.findByRole("button", { name: "Room settings" }).click();
|
||||
cy.findByRole("menuitem", { name: "Settings" }).click();
|
||||
cy.get(".mx_RoomSettingsDialog").should("have.length", 1);
|
||||
cy.get(".mx_Dialog_title").within(() => {
|
||||
cy.findByText("Room Settings - " + ROOM_NAME).should("exist");
|
||||
|
@ -127,7 +127,7 @@ describe("RightPanel", () => {
|
|||
it("should handle viewing files", () => {
|
||||
viewRoomSummaryByName(ROOM_NAME);
|
||||
|
||||
cy.findByRole("button", { name: "Files" }).click();
|
||||
cy.findByRole("menuitem", { name: "Files" }).click();
|
||||
cy.get(".mx_FilePanel").should("have.length", 1);
|
||||
cy.get(".mx_FilePanel_empty").should("have.length", 1);
|
||||
|
||||
|
@ -138,8 +138,7 @@ describe("RightPanel", () => {
|
|||
it("should handle viewing room member", () => {
|
||||
viewRoomSummaryByName(ROOM_NAME);
|
||||
|
||||
// \d represents the number of the room members inside mx_BaseCard_Button_sublabel
|
||||
cy.findByRole("button", { name: /People \d/ }).click();
|
||||
cy.findByRole("menuitem", { name: "People" }).click();
|
||||
cy.get(".mx_MemberList").should("have.length", 1);
|
||||
|
||||
getMemberTileByName(NAME).click();
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
"@sentry/tracing": "^7.0.0",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@vector-im/compound-design-tokens": "^0.0.7",
|
||||
"@vector-im/compound-web": "0.6.3",
|
||||
"@vector-im/compound-web": "0.8.1",
|
||||
"@zxcvbn-ts/core": "^3.0.4",
|
||||
"@zxcvbn-ts/language-common": "^3.0.4",
|
||||
"@zxcvbn-ts/language-en": "^3.0.2",
|
||||
|
|
|
@ -158,11 +158,18 @@ limitations under the License.
|
|||
.mx_BaseCard_close {
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
// @TODO(kerrya) background colours here are not semantic
|
||||
// these buttons to be replaced with IconButton after secondary variant is added
|
||||
// https://github.com/vector-im/compound/issues/279
|
||||
background-color: var(--cpd-color-bg-subtle-secondary);
|
||||
width: var(--BaseCard_header-button-size);
|
||||
height: var(--BaseCard_header-button-size);
|
||||
border-radius: 50%;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--cpd-color-bg-subtle-primary);
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
.mx_RoomSummaryCard {
|
||||
.mx_RoomSummaryCard_container {
|
||||
text-align: center;
|
||||
margin-top: $spacing-20;
|
||||
margin: $spacing-20 var(--cpd-space-4x) 0;
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_roomName,
|
||||
|
@ -29,10 +29,6 @@ limitations under the License.
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_roomName {
|
||||
margin: $spacing-12 0 $spacing-4;
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_alias {
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
@ -203,42 +199,6 @@ limitations under the License.
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_icon_people::before {
|
||||
mask-image: url("$(res)/img/element-icons/room/members.svg");
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_icon_files::before {
|
||||
mask-image: url("$(res)/img/element-icons/room/files.svg");
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_icon_pins::before {
|
||||
mask-image: url("$(res)/img/element-icons/room/pin-upright.svg");
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_icon_threads::before {
|
||||
mask-image: url("$(res)/img/element-icons/message/thread.svg");
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_icon_share::before {
|
||||
mask-image: url("$(res)/img/element-icons/room/share.svg");
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_icon_settings::before {
|
||||
mask-image: url("$(res)/img/element-icons/settings.svg");
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_icon_export::before {
|
||||
mask-image: url("$(res)/img/element-icons/export.svg");
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_icon_poll::before {
|
||||
mask-image: url("$(res)/img/element-icons/room/composer/poll.svg");
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_icon_search::before {
|
||||
mask-image: url("$(res)/img/element-icons/room/search-inset.svg");
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_searchBtn {
|
||||
background: var(--cpd-color-bg-canvas-default);
|
||||
color: var(--cpd-color-icon-primary);
|
||||
|
@ -248,9 +208,12 @@ limitations under the License.
|
|||
height: 36px;
|
||||
padding: var(--cpd-space-2x);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
background: var(--cpd-color-bg-subtle-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_roomName {
|
||||
margin: $spacing-12 0 $spacing-4;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ limitations under the License.
|
|||
|
||||
import React, { useContext } from "react";
|
||||
import { Room } from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import { IProps as IContextMenuProps } from "../../structures/ContextMenu";
|
||||
import IconizedContextMenu, {
|
||||
|
@ -30,7 +29,6 @@ import { ButtonEvent } from "../elements/AccessibleButton";
|
|||
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
|
||||
import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
import RoomListActions from "../../../actions/RoomListActions";
|
||||
import { EchoChamber } from "../../../stores/local-echo/EchoChamber";
|
||||
import { RoomNotifState } from "../../../RoomNotifs";
|
||||
import Modal from "../../../Modal";
|
||||
|
@ -52,6 +50,7 @@ import { SdkContextClass } from "../../../contexts/SDKContext";
|
|||
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
|
||||
import { UIComponent } from "../../../settings/UIFeature";
|
||||
import { DeveloperToolsOption } from "./DeveloperToolsOption";
|
||||
import { tagRoom } from "../../../utils/room/tagRoom";
|
||||
|
||||
interface IProps extends IContextMenuProps {
|
||||
room: Room;
|
||||
|
@ -333,15 +332,7 @@ const RoomContextMenu: React.FC<IProps> = ({ room, onFinished, ...props }) => {
|
|||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
if (tagId === DefaultTagID.Favourite || tagId === DefaultTagID.LowPriority) {
|
||||
const inverseTag = tagId === DefaultTagID.Favourite ? DefaultTagID.LowPriority : DefaultTagID.Favourite;
|
||||
const isApplied = RoomListStore.instance.getTagsForRoom(room).includes(tagId);
|
||||
const removeTag = isApplied ? tagId : inverseTag;
|
||||
const addTag = isApplied ? null : tagId;
|
||||
dis.dispatch(RoomListActions.tagRoom(cli, room, removeTag, addTag, 0));
|
||||
} else {
|
||||
logger.warn(`Unexpected tag ${tagId} applied to ${room.roomId}`);
|
||||
}
|
||||
tagRoom(room, tagId);
|
||||
|
||||
const action = getKeyBindingsManager().getAccessibilityAction(ev as React.KeyboardEvent);
|
||||
switch (action) {
|
||||
|
|
|
@ -16,25 +16,35 @@ limitations under the License.
|
|||
|
||||
import React, { useCallback, useContext, useEffect, useMemo, useState } from "react";
|
||||
import classNames from "classnames";
|
||||
import { EventType, JoinRule, Room } from "matrix-js-sdk/src/matrix";
|
||||
import { Badge, Heading, Text, Tooltip } from "@vector-im/compound-web";
|
||||
import { MenuItem, Tooltip, Separator, ToggleMenuItem, Text, Badge, Heading } from "@vector-im/compound-web";
|
||||
import { Icon as SearchIcon } from "@vector-im/compound-design-tokens/icons/search.svg";
|
||||
import { Icon as FavouriteIcon } from "@vector-im/compound-design-tokens/icons/favourite-off.svg";
|
||||
import { Icon as UserAddIcon } from "@vector-im/compound-design-tokens/icons/user-add.svg";
|
||||
import { Icon as UserProfileSolidIcon } from "@vector-im/compound-design-tokens/icons/user-profile-solid.svg";
|
||||
import { Icon as LinkIcon } from "@vector-im/compound-design-tokens/icons/link.svg";
|
||||
import { Icon as SettingsIcon } from "@vector-im/compound-design-tokens/icons/settings.svg";
|
||||
import { Icon as ExportArchiveIcon } from "@vector-im/compound-design-tokens/icons/export-archive.svg";
|
||||
import { Icon as LeaveIcon } from "@vector-im/compound-design-tokens/icons/leave.svg";
|
||||
import { Icon as FilesIcon } from "@vector-im/compound-design-tokens/icons/files.svg";
|
||||
import { Icon as PollsIcon } from "@vector-im/compound-design-tokens/icons/polls.svg";
|
||||
import { Icon as PinIcon } from "@vector-im/compound-design-tokens/icons/pin-off.svg";
|
||||
import { Icon as LockIcon } from "@vector-im/compound-design-tokens/icons/lock.svg";
|
||||
import { Icon as LockOffIcon } from "@vector-im/compound-design-tokens/icons/lock-off.svg";
|
||||
import { Icon as PublicIcon } from "@vector-im/compound-design-tokens/icons/public.svg";
|
||||
import { Icon as ErrorIcon } from "@vector-im/compound-design-tokens/icons/error.svg";
|
||||
import { EventType, JoinRule, Room } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import { useIsEncrypted } from "../../../hooks/useIsEncrypted";
|
||||
import BaseCard, { Group } from "./BaseCard";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import RoomAvatar from "../avatars/RoomAvatar";
|
||||
import AccessibleButton, { ButtonEvent, IAccessibleButtonProps } from "../elements/AccessibleButton";
|
||||
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
|
||||
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||
import { RightPanelPhases } from "../../../stores/right-panel/RightPanelStorePhases";
|
||||
import Modal from "../../../Modal";
|
||||
import ShareDialog from "../dialogs/ShareDialog";
|
||||
import { useEventEmitter } from "../../../hooks/useEventEmitter";
|
||||
import { useEventEmitter, useEventEmitterState } from "../../../hooks/useEventEmitter";
|
||||
import WidgetUtils from "../../../utils/WidgetUtils";
|
||||
import { IntegrationManagers } from "../../../integrations/IntegrationManagers";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
|
@ -47,7 +57,6 @@ import RoomContext from "../../../contexts/RoomContext";
|
|||
import { UIComponent, UIFeature } from "../../../settings/UIFeature";
|
||||
import { ChevronFace, ContextMenuTooltipButton, useContextMenu } from "../../structures/ContextMenu";
|
||||
import { WidgetContextMenu } from "../context_menus/WidgetContextMenu";
|
||||
import { useRoomMemberCount } from "../../../hooks/useRoomMembers";
|
||||
import { useFeatureEnabled } from "../../../hooks/useSettings";
|
||||
import { usePinnedEvents } from "./PinnedMessagesCard";
|
||||
import { Container, MAX_PINNED, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore";
|
||||
|
@ -59,6 +68,11 @@ import PosthogTrackers from "../../../PosthogTrackers";
|
|||
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
|
||||
import { PollHistoryDialog } from "../dialogs/PollHistoryDialog";
|
||||
import { Flex } from "../../utils/Flex";
|
||||
import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore";
|
||||
import { DefaultTagID } from "../../../stores/room-list/models";
|
||||
import { tagRoom } from "../../../utils/room/tagRoom";
|
||||
import { canInviteTo } from "../../../utils/room/canInviteTo";
|
||||
import { inviteToRoom } from "../../../utils/room/inviteToRoom";
|
||||
import { useAccountData } from "../../../hooks/useAccountData";
|
||||
import { useRoomState } from "../../../hooks/useRoomState";
|
||||
|
||||
|
@ -73,23 +87,6 @@ interface IAppsSectionProps {
|
|||
room: Room;
|
||||
}
|
||||
|
||||
interface IButtonProps extends IAccessibleButtonProps {
|
||||
className: string;
|
||||
onClick(ev: ButtonEvent): void;
|
||||
}
|
||||
|
||||
const Button: React.FC<IButtonProps> = ({ children, className, onClick, ...props }) => {
|
||||
return (
|
||||
<AccessibleButton
|
||||
{...props}
|
||||
className={classNames("mx_BaseCard_Button mx_RoomSummaryCard_Button", className)}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
</AccessibleButton>
|
||||
);
|
||||
};
|
||||
|
||||
export const useWidgets = (room: Room): IApp[] => {
|
||||
const [apps, setApps] = useState<IApp[]>(() => WidgetStore.instance.getApps(room.roomId));
|
||||
|
||||
|
@ -263,11 +260,6 @@ const AppsSection: React.FC<IAppsSectionProps> = ({ room }) => {
|
|||
);
|
||||
};
|
||||
|
||||
const onRoomMembersClick = (ev: ButtonEvent): void => {
|
||||
RightPanelStore.instance.pushCard({ phase: RightPanelPhases.RoomMemberList }, true);
|
||||
PosthogTrackers.trackInteraction("WebRightPanelRoomInfoPeopleButton", ev);
|
||||
};
|
||||
|
||||
const onRoomFilesClick = (): void => {
|
||||
RightPanelStore.instance.pushCard({ phase: RightPanelPhases.FilePanel }, true);
|
||||
};
|
||||
|
@ -304,6 +296,18 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, permalinkCreator, onClose, on
|
|||
});
|
||||
};
|
||||
|
||||
const onLeaveRoomClick = (): void => {
|
||||
defaultDispatcher.dispatch({
|
||||
action: "leave_room",
|
||||
room_id: room.roomId,
|
||||
});
|
||||
};
|
||||
|
||||
const onRoomMembersClick = (ev: ButtonEvent): void => {
|
||||
RightPanelStore.instance.pushCard({ phase: RightPanelPhases.RoomMemberList }, true);
|
||||
PosthogTrackers.trackInteraction("WebRightPanelRoomInfoPeopleButton", ev);
|
||||
};
|
||||
|
||||
const isRoomEncrypted = useIsEncrypted(cli, room);
|
||||
const roomContext = useContext(RoomContext);
|
||||
const e2eStatus = roomContext.e2eStatus;
|
||||
|
@ -383,10 +387,14 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, permalinkCreator, onClose, on
|
|||
</header>
|
||||
);
|
||||
|
||||
const memberCount = useRoomMemberCount(room);
|
||||
const pinningEnabled = useFeatureEnabled("feature_pinning");
|
||||
const pinCount = usePinnedEvents(pinningEnabled ? room : undefined)?.length;
|
||||
|
||||
const roomTags = useEventEmitterState(RoomListStore.instance, LISTS_UPDATE_EVENT, () =>
|
||||
RoomListStore.instance.getTagsForRoom(room),
|
||||
);
|
||||
const isFavorite = roomTags.includes(DefaultTagID.Favourite);
|
||||
|
||||
return (
|
||||
<BaseCard header={null} className="mx_RoomSummaryCard" onClose={onClose}>
|
||||
<Flex
|
||||
|
@ -417,43 +425,58 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, permalinkCreator, onClose, on
|
|||
</Flex>
|
||||
|
||||
{header}
|
||||
<Group title={_t("common|about")} className="mx_RoomSummaryCard_aboutGroup">
|
||||
<Button className="mx_RoomSummaryCard_icon_people" onClick={onRoomMembersClick}>
|
||||
{_t("common|people")}
|
||||
<span className="mx_BaseCard_Button_sublabel">{memberCount}</span>
|
||||
</Button>
|
||||
|
||||
<Separator />
|
||||
|
||||
<ToggleMenuItem
|
||||
Icon={FavouriteIcon}
|
||||
label={_t("room|context_menu|favourite")}
|
||||
checked={isFavorite}
|
||||
onChange={() => tagRoom(room, DefaultTagID.Favourite)}
|
||||
/>
|
||||
<MenuItem
|
||||
Icon={UserAddIcon}
|
||||
label={_t("action|invite")}
|
||||
disabled={!canInviteTo(room)}
|
||||
onClick={() => inviteToRoom(room)}
|
||||
/>
|
||||
<MenuItem Icon={LinkIcon} label={_t("action|copy_link")} onClick={onShareRoomClick} />
|
||||
<MenuItem Icon={SettingsIcon} label={_t("common|settings")} onClick={onRoomSettingsClick} />
|
||||
|
||||
<Separator />
|
||||
<MenuItem
|
||||
// this icon matches the legacy implementation
|
||||
// and is a short term solution until legacy room header is removed
|
||||
Icon={UserProfileSolidIcon}
|
||||
label={_t("common|people")}
|
||||
onClick={onRoomMembersClick}
|
||||
/>
|
||||
{!isVideoRoom && (
|
||||
<Button className="mx_RoomSummaryCard_icon_files" onClick={onRoomFilesClick}>
|
||||
{_t("right_panel|files_button")}
|
||||
</Button>
|
||||
)}
|
||||
{!isVideoRoom && (
|
||||
<Button className="mx_RoomSummaryCard_icon_poll" onClick={onRoomPollHistoryClick}>
|
||||
{_t("right_panel|polls_button")}
|
||||
</Button>
|
||||
)}
|
||||
{pinningEnabled && !isVideoRoom && (
|
||||
<Button className="mx_RoomSummaryCard_icon_pins" onClick={onRoomPinsClick}>
|
||||
{_t("right_panel|pinned_messages_button")}
|
||||
{pinCount > 0 && <span className="mx_BaseCard_Button_sublabel">{pinCount}</span>}
|
||||
</Button>
|
||||
)}
|
||||
{!isVideoRoom && (
|
||||
<Button className="mx_RoomSummaryCard_icon_export" onClick={onRoomExportClick}>
|
||||
{_t("right_panel|export_chat_button")}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
data-testid="shareRoomButton"
|
||||
className="mx_RoomSummaryCard_icon_share"
|
||||
onClick={onShareRoomClick}
|
||||
<>
|
||||
<MenuItem Icon={FilesIcon} label={_t("right_panel|files_button")} onClick={onRoomFilesClick} />
|
||||
<MenuItem
|
||||
Icon={PollsIcon}
|
||||
label={_t("right_panel|polls_button")}
|
||||
onClick={onRoomPollHistoryClick}
|
||||
/>
|
||||
{pinningEnabled && (
|
||||
<MenuItem
|
||||
Icon={PinIcon}
|
||||
label={_t("right_panel|pinned_messages_button")}
|
||||
onClick={onRoomPinsClick}
|
||||
>
|
||||
{_t("right_panel|share_button")}
|
||||
</Button>
|
||||
<Button className="mx_RoomSummaryCard_icon_settings" onClick={onRoomSettingsClick}>
|
||||
{_t("right_panel|settings_button")}
|
||||
</Button>
|
||||
</Group>
|
||||
<Text as="span" size="sm">
|
||||
{pinCount}
|
||||
</Text>
|
||||
</MenuItem>
|
||||
)}
|
||||
<MenuItem Icon={ExportArchiveIcon} label={_t("export_chat|title")} onClick={onRoomExportClick} />
|
||||
</>
|
||||
)}
|
||||
|
||||
<Separator />
|
||||
|
||||
<MenuItem Icon={LeaveIcon} kind="critical" label={_t("action|leave_room")} onClick={onLeaveRoomClick} />
|
||||
|
||||
{SettingsStore.getValue(UIFeature.Widgets) &&
|
||||
!isVideoRoom &&
|
||||
|
|
|
@ -418,7 +418,6 @@
|
|||
"spaceinvaders_message": "sends space invaders"
|
||||
},
|
||||
"common": {
|
||||
"about": "About",
|
||||
"access_token": "Access Token",
|
||||
"accessibility": "Accessibility",
|
||||
"advanced": "Advanced",
|
||||
|
@ -1854,8 +1853,6 @@
|
|||
"room_summary_card": {
|
||||
"title": "Room info"
|
||||
},
|
||||
"settings_button": "Room settings",
|
||||
"share_button": "Share room",
|
||||
"thread_list": {
|
||||
"context_menu_label": "Thread options"
|
||||
},
|
||||
|
|
33
src/utils/room/canInviteTo.ts
Normal file
33
src/utils/room/canInviteTo.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { JoinRule, Room } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { shouldShowComponent } from "../../customisations/helpers/UIComponents";
|
||||
import { UIComponent } from "../../settings/UIFeature";
|
||||
|
||||
/**
|
||||
* Can a user invite new members to the room
|
||||
* @param room
|
||||
* @returns whether the user can invite new members to the room
|
||||
*/
|
||||
export function canInviteTo(room: Room): boolean {
|
||||
const client = room.client;
|
||||
const canInvite =
|
||||
!!room.canInvite(client.getSafeUserId()) || !!(room.isSpaceRoom() && room.getJoinRule() === JoinRule.Public);
|
||||
|
||||
return canInvite && room.getMyMembership() === "join" && shouldShowComponent(UIComponent.InviteUsers);
|
||||
}
|
36
src/utils/room/inviteToRoom.ts
Normal file
36
src/utils/room/inviteToRoom.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { Room } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import dis from "../../dispatcher/dispatcher";
|
||||
|
||||
/**
|
||||
* Invite to a room and prompts guests to registers
|
||||
* @param room
|
||||
*/
|
||||
export function inviteToRoom(room: Room): void {
|
||||
if (room.client.isGuest()) {
|
||||
dis.dispatch({ action: "require_registration" });
|
||||
return;
|
||||
}
|
||||
|
||||
// open the room inviter
|
||||
dis.dispatch({
|
||||
action: "view_invite",
|
||||
roomId: room.roomId,
|
||||
});
|
||||
}
|
40
src/utils/room/tagRoom.ts
Normal file
40
src/utils/room/tagRoom.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { Room } from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import RoomListStore from "../../stores/room-list/RoomListStore";
|
||||
import { DefaultTagID, TagID } from "../../stores/room-list/models";
|
||||
import RoomListActions from "../../actions/RoomListActions";
|
||||
import dis from "../../dispatcher/dispatcher";
|
||||
|
||||
/**
|
||||
* Toggle tag for a given room
|
||||
* @param room The room to tag
|
||||
* @param tagId The tag to invert
|
||||
*/
|
||||
export function tagRoom(room: Room, tagId: TagID): void {
|
||||
if (tagId === DefaultTagID.Favourite || tagId === DefaultTagID.LowPriority) {
|
||||
const inverseTag = tagId === DefaultTagID.Favourite ? DefaultTagID.LowPriority : DefaultTagID.Favourite;
|
||||
const isApplied = RoomListStore.instance.getTagsForRoom(room).includes(tagId);
|
||||
const removeTag = isApplied ? tagId : inverseTag;
|
||||
const addTag = isApplied ? null : tagId;
|
||||
dis.dispatch(RoomListActions.tagRoom(room.client, room, removeTag, addTag, 0));
|
||||
} else {
|
||||
logger.warn(`Unexpected tag ${tagId} applied to ${room.roomId}`);
|
||||
}
|
||||
}
|
|
@ -16,7 +16,6 @@ limitations under the License.
|
|||
|
||||
import React from "react";
|
||||
import { render, screen, waitFor } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { jest } from "@jest/globals";
|
||||
import { mocked, MockedObject } from "jest-mock";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
|
@ -85,47 +84,6 @@ describe("RightPanel", () => {
|
|||
|
||||
const waitForRpsUpdate = () => new Promise<void>((resolve) => RightPanelStore.instance.once(UPDATE_EVENT, resolve));
|
||||
|
||||
it("navigates from room summary to member list", async () => {
|
||||
const r1 = mkRoom(cli, "r1");
|
||||
cli.getRoom.mockImplementation((roomId) => (roomId === "r1" ? r1 : null));
|
||||
|
||||
// Set up right panel state
|
||||
const realGetValue = SettingsStore.getValue;
|
||||
jest.spyOn(SettingsStore, "getValue").mockImplementation((name, roomId) => {
|
||||
if (name !== "RightPanel.phases") return realGetValue(name, roomId);
|
||||
if (roomId === "r1") {
|
||||
return {
|
||||
history: [{ phase: RightPanelPhases.RoomSummary }],
|
||||
isOpen: true,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
await spinUpStores();
|
||||
const viewedRoom = waitForRpsUpdate();
|
||||
dis.dispatch({
|
||||
action: Action.ViewRoom,
|
||||
room_id: "r1",
|
||||
});
|
||||
await viewedRoom;
|
||||
|
||||
const { container } = render(
|
||||
<RightPanel
|
||||
room={r1}
|
||||
resizeNotifier={resizeNotifier}
|
||||
permalinkCreator={new RoomPermalinkCreator(r1, r1.roomId)}
|
||||
/>,
|
||||
);
|
||||
expect(container.getElementsByClassName("mx_RoomSummaryCard")).toHaveLength(1);
|
||||
|
||||
const switchedPhases = waitForRpsUpdate();
|
||||
userEvent.click(screen.getByText(/people/i));
|
||||
await switchedPhases;
|
||||
|
||||
expect(container.getElementsByClassName("mx_MemberList")).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("renders info from only one room during room changes", async () => {
|
||||
const r1 = mkRoom(cli, "r1");
|
||||
const r2 = mkRoom(cli, "r2");
|
||||
|
|
|
@ -33,6 +33,7 @@ import { flushPromises, getMockClientWithEventEmitter, mockClientMethodsUser } f
|
|||
import { PollHistoryDialog } from "../../../../src/components/views/dialogs/PollHistoryDialog";
|
||||
import { RoomPermalinkCreator } from "../../../../src/utils/permalinks/Permalinks";
|
||||
import { _t } from "../../../../src/languageHandler";
|
||||
import SettingsStore from "../../../../src/settings/SettingsStore";
|
||||
|
||||
describe("<RoomSummaryCard />", () => {
|
||||
const userId = "@alice:domain.org";
|
||||
|
@ -108,17 +109,6 @@ describe("<RoomSummaryCard />", () => {
|
|||
expect(onSearchClick).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("opens room members list on button click", () => {
|
||||
const { getByText } = getComponent();
|
||||
|
||||
fireEvent.click(getByText("People"));
|
||||
|
||||
expect(RightPanelStore.instance.pushCard).toHaveBeenCalledWith(
|
||||
{ phase: RightPanelPhases.RoomMemberList },
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it("opens room file panel on button click", () => {
|
||||
const { getByText } = getComponent();
|
||||
|
||||
|
@ -130,7 +120,7 @@ describe("<RoomSummaryCard />", () => {
|
|||
it("opens room export dialog on button click", () => {
|
||||
const { getByText } = getComponent();
|
||||
|
||||
fireEvent.click(getByText("Export chat"));
|
||||
fireEvent.click(getByText(_t("export_chat|title")));
|
||||
|
||||
expect(Modal.createDialog).toHaveBeenCalledWith(ExportDialog, { room });
|
||||
});
|
||||
|
@ -138,7 +128,7 @@ describe("<RoomSummaryCard />", () => {
|
|||
it("opens share room dialog on button click", () => {
|
||||
const { getByText } = getComponent();
|
||||
|
||||
fireEvent.click(getByText("Share room"));
|
||||
fireEvent.click(getByText(_t("action|copy_link")));
|
||||
|
||||
expect(Modal.createDialog).toHaveBeenCalledWith(ShareDialog, { target: room });
|
||||
});
|
||||
|
@ -146,11 +136,23 @@ describe("<RoomSummaryCard />", () => {
|
|||
it("opens room settings on button click", () => {
|
||||
const { getByText } = getComponent();
|
||||
|
||||
fireEvent.click(getByText("Room settings"));
|
||||
fireEvent.click(getByText(_t("common|settings")));
|
||||
|
||||
expect(defaultDispatcher.dispatch).toHaveBeenCalledWith({ action: "open_room_settings" });
|
||||
});
|
||||
|
||||
it("renders room members options when new room UI is not enabled", () => {
|
||||
jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
|
||||
const { getByText } = getComponent();
|
||||
|
||||
fireEvent.click(getByText(_t("common|people")));
|
||||
|
||||
expect(RightPanelStore.instance.pushCard).toHaveBeenCalledWith(
|
||||
{ phase: RightPanelPhases.RoomMemberList },
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
describe("pinning", () => {
|
||||
it("renders pins options when pinning feature is enabled", () => {
|
||||
mocked(settingsHooks.useFeatureEnabled).mockImplementation((feature) => feature === "feature_pinning");
|
||||
|
|
|
@ -46,13 +46,13 @@ exports[`<RoomSummaryCard /> renders the room summary 1`] = `
|
|||
!
|
||||
</span>
|
||||
<h1
|
||||
class="_font-heading-md-semibold_1jx6b_121 mx_RoomSummaryCard_roomName text-primary"
|
||||
class="_typography_yh5dq_162 _font-heading-md-semibold_yh5dq_121 mx_RoomSummaryCard_roomName text-primary"
|
||||
title="!room:domain.org"
|
||||
>
|
||||
!room:domain.org
|
||||
</h1>
|
||||
<div
|
||||
class="_font-body-sm-semibold_1jx6b_45 mx_RoomSummaryCard_alias text-secondary"
|
||||
class="_typography_yh5dq_162 _font-body-sm-semibold_yh5dq_45 mx_RoomSummaryCard_alias text-secondary"
|
||||
title=""
|
||||
/>
|
||||
<section
|
||||
|
@ -60,7 +60,7 @@ exports[`<RoomSummaryCard /> renders the room summary 1`] = `
|
|||
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: start; --mx-flex-justify: center; --mx-flex-gap: var(--cpd-space-2x);"
|
||||
>
|
||||
<span
|
||||
class="_font-body-sm-medium_1jx6b_50 _badge_qipht_17"
|
||||
class="_typography_yh5dq_162 _font-body-sm-medium_yh5dq_50 _badge_qipht_17"
|
||||
data-kind="default"
|
||||
>
|
||||
<div
|
||||
|
@ -71,60 +71,299 @@ exports[`<RoomSummaryCard /> renders the room summary 1`] = `
|
|||
</section>
|
||||
</header>
|
||||
<div
|
||||
class="mx_BaseCard_Group mx_RoomSummaryCard_aboutGroup"
|
||||
class="_separator_1uqhh_17"
|
||||
data-orientation="horizontal"
|
||||
role="separator"
|
||||
/>
|
||||
<label
|
||||
class="_item_zxa40_17 _interactive_zxa40_36"
|
||||
data-kind="primary"
|
||||
for=":r1:"
|
||||
role="menuitemcheckbox"
|
||||
>
|
||||
<h2>
|
||||
About
|
||||
</h2>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_BaseCard_Button mx_RoomSummaryCard_Button mx_RoomSummaryCard_icon_people"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
aria-hidden="true"
|
||||
class="_icon_zxa40_49"
|
||||
height="24"
|
||||
width="24"
|
||||
/>
|
||||
<span
|
||||
class="_typography_yh5dq_162 _font-body-md-medium_yh5dq_69 _label_zxa40_58"
|
||||
>
|
||||
Favourite
|
||||
</span>
|
||||
<div
|
||||
class="_container_ik1u1_18"
|
||||
>
|
||||
<input
|
||||
class="_input_ik1u1_32"
|
||||
id=":r1:"
|
||||
type="checkbox"
|
||||
/>
|
||||
<div
|
||||
class="_ui_ik1u1_42"
|
||||
/>
|
||||
</div>
|
||||
</label>
|
||||
<button
|
||||
class="_item_zxa40_17 _interactive_zxa40_36 _disabled_zxa40_125"
|
||||
data-kind="primary"
|
||||
disabled=""
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="_icon_zxa40_49"
|
||||
height="24"
|
||||
width="24"
|
||||
/>
|
||||
<span
|
||||
class="_typography_yh5dq_162 _font-body-md-medium_yh5dq_69 _label_zxa40_58"
|
||||
>
|
||||
Invite
|
||||
</span>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="_nav-hint_zxa40_65"
|
||||
fill="none"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M8.70005 17.3C8.51672 17.1167 8.42505 16.8834 8.42505 16.6C8.42505 16.3167 8.51672 16.0834 8.70005 15.9L12.6 12L8.70005 8.10005C8.51672 7.91672 8.42505 7.68338 8.42505 7.40005C8.42505 7.11672 8.51672 6.88338 8.70005 6.70005C8.88338 6.51672 9.11672 6.42505 9.40005 6.42505C9.68338 6.42505 9.91672 6.51672 10.1 6.70005L14.7 11.3C14.8 11.4 14.8709 11.5084 14.9125 11.625C14.9542 11.7417 14.975 11.8667 14.975 12C14.975 12.1334 14.9542 12.2584 14.9125 12.375C14.8709 12.4917 14.8 12.6 14.7 12.7L10.1 17.3C9.91672 17.4834 9.68338 17.575 9.40005 17.575C9.11672 17.575 8.88338 17.4834 8.70005 17.3Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
class="_item_zxa40_17 _interactive_zxa40_36"
|
||||
data-kind="primary"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="_icon_zxa40_49"
|
||||
height="24"
|
||||
width="24"
|
||||
/>
|
||||
<span
|
||||
class="_typography_yh5dq_162 _font-body-md-medium_yh5dq_69 _label_zxa40_58"
|
||||
>
|
||||
Copy link
|
||||
</span>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="_nav-hint_zxa40_65"
|
||||
fill="none"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M8.70005 17.3C8.51672 17.1167 8.42505 16.8834 8.42505 16.6C8.42505 16.3167 8.51672 16.0834 8.70005 15.9L12.6 12L8.70005 8.10005C8.51672 7.91672 8.42505 7.68338 8.42505 7.40005C8.42505 7.11672 8.51672 6.88338 8.70005 6.70005C8.88338 6.51672 9.11672 6.42505 9.40005 6.42505C9.68338 6.42505 9.91672 6.51672 10.1 6.70005L14.7 11.3C14.8 11.4 14.8709 11.5084 14.9125 11.625C14.9542 11.7417 14.975 11.8667 14.975 12C14.975 12.1334 14.9542 12.2584 14.9125 12.375C14.8709 12.4917 14.8 12.6 14.7 12.7L10.1 17.3C9.91672 17.4834 9.68338 17.575 9.40005 17.575C9.11672 17.575 8.88338 17.4834 8.70005 17.3Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
class="_item_zxa40_17 _interactive_zxa40_36"
|
||||
data-kind="primary"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="_icon_zxa40_49"
|
||||
height="24"
|
||||
width="24"
|
||||
/>
|
||||
<span
|
||||
class="_typography_yh5dq_162 _font-body-md-medium_yh5dq_69 _label_zxa40_58"
|
||||
>
|
||||
Settings
|
||||
</span>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="_nav-hint_zxa40_65"
|
||||
fill="none"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M8.70005 17.3C8.51672 17.1167 8.42505 16.8834 8.42505 16.6C8.42505 16.3167 8.51672 16.0834 8.70005 15.9L12.6 12L8.70005 8.10005C8.51672 7.91672 8.42505 7.68338 8.42505 7.40005C8.42505 7.11672 8.51672 6.88338 8.70005 6.70005C8.88338 6.51672 9.11672 6.42505 9.40005 6.42505C9.68338 6.42505 9.91672 6.51672 10.1 6.70005L14.7 11.3C14.8 11.4 14.8709 11.5084 14.9125 11.625C14.9542 11.7417 14.975 11.8667 14.975 12C14.975 12.1334 14.9542 12.2584 14.9125 12.375C14.8709 12.4917 14.8 12.6 14.7 12.7L10.1 17.3C9.91672 17.4834 9.68338 17.575 9.40005 17.575C9.11672 17.575 8.88338 17.4834 8.70005 17.3Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<div
|
||||
class="_separator_1uqhh_17"
|
||||
data-orientation="horizontal"
|
||||
role="separator"
|
||||
/>
|
||||
<button
|
||||
class="_item_zxa40_17 _interactive_zxa40_36"
|
||||
data-kind="primary"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="_icon_zxa40_49"
|
||||
height="24"
|
||||
width="24"
|
||||
/>
|
||||
<span
|
||||
class="_typography_yh5dq_162 _font-body-md-medium_yh5dq_69 _label_zxa40_58"
|
||||
>
|
||||
People
|
||||
<span
|
||||
class="mx_BaseCard_Button_sublabel"
|
||||
>
|
||||
0
|
||||
</span>
|
||||
</div>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="_nav-hint_zxa40_65"
|
||||
fill="none"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M8.70005 17.3C8.51672 17.1167 8.42505 16.8834 8.42505 16.6C8.42505 16.3167 8.51672 16.0834 8.70005 15.9L12.6 12L8.70005 8.10005C8.51672 7.91672 8.42505 7.68338 8.42505 7.40005C8.42505 7.11672 8.51672 6.88338 8.70005 6.70005C8.88338 6.51672 9.11672 6.42505 9.40005 6.42505C9.68338 6.42505 9.91672 6.51672 10.1 6.70005L14.7 11.3C14.8 11.4 14.8709 11.5084 14.9125 11.625C14.9542 11.7417 14.975 11.8667 14.975 12C14.975 12.1334 14.9542 12.2584 14.9125 12.375C14.8709 12.4917 14.8 12.6 14.7 12.7L10.1 17.3C9.91672 17.4834 9.68338 17.575 9.40005 17.575C9.11672 17.575 8.88338 17.4834 8.70005 17.3Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
class="_item_zxa40_17 _interactive_zxa40_36"
|
||||
data-kind="primary"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_BaseCard_Button mx_RoomSummaryCard_Button mx_RoomSummaryCard_icon_files"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
aria-hidden="true"
|
||||
class="_icon_zxa40_49"
|
||||
height="24"
|
||||
width="24"
|
||||
/>
|
||||
<span
|
||||
class="_typography_yh5dq_162 _font-body-md-medium_yh5dq_69 _label_zxa40_58"
|
||||
>
|
||||
Files
|
||||
</div>
|
||||
</span>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="_nav-hint_zxa40_65"
|
||||
fill="none"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M8.70005 17.3C8.51672 17.1167 8.42505 16.8834 8.42505 16.6C8.42505 16.3167 8.51672 16.0834 8.70005 15.9L12.6 12L8.70005 8.10005C8.51672 7.91672 8.42505 7.68338 8.42505 7.40005C8.42505 7.11672 8.51672 6.88338 8.70005 6.70005C8.88338 6.51672 9.11672 6.42505 9.40005 6.42505C9.68338 6.42505 9.91672 6.51672 10.1 6.70005L14.7 11.3C14.8 11.4 14.8709 11.5084 14.9125 11.625C14.9542 11.7417 14.975 11.8667 14.975 12C14.975 12.1334 14.9542 12.2584 14.9125 12.375C14.8709 12.4917 14.8 12.6 14.7 12.7L10.1 17.3C9.91672 17.4834 9.68338 17.575 9.40005 17.575C9.11672 17.575 8.88338 17.4834 8.70005 17.3Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
class="_item_zxa40_17 _interactive_zxa40_36"
|
||||
data-kind="primary"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_BaseCard_Button mx_RoomSummaryCard_Button mx_RoomSummaryCard_icon_poll"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
aria-hidden="true"
|
||||
class="_icon_zxa40_49"
|
||||
height="24"
|
||||
width="24"
|
||||
/>
|
||||
<span
|
||||
class="_typography_yh5dq_162 _font-body-md-medium_yh5dq_69 _label_zxa40_58"
|
||||
>
|
||||
Poll history
|
||||
</div>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_BaseCard_Button mx_RoomSummaryCard_Button mx_RoomSummaryCard_icon_export"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
</span>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="_nav-hint_zxa40_65"
|
||||
fill="none"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
Export chat
|
||||
</div>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_BaseCard_Button mx_RoomSummaryCard_Button mx_RoomSummaryCard_icon_share"
|
||||
data-testid="shareRoomButton"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
<path
|
||||
d="M8.70005 17.3C8.51672 17.1167 8.42505 16.8834 8.42505 16.6C8.42505 16.3167 8.51672 16.0834 8.70005 15.9L12.6 12L8.70005 8.10005C8.51672 7.91672 8.42505 7.68338 8.42505 7.40005C8.42505 7.11672 8.51672 6.88338 8.70005 6.70005C8.88338 6.51672 9.11672 6.42505 9.40005 6.42505C9.68338 6.42505 9.91672 6.51672 10.1 6.70005L14.7 11.3C14.8 11.4 14.8709 11.5084 14.9125 11.625C14.9542 11.7417 14.975 11.8667 14.975 12C14.975 12.1334 14.9542 12.2584 14.9125 12.375C14.8709 12.4917 14.8 12.6 14.7 12.7L10.1 17.3C9.91672 17.4834 9.68338 17.575 9.40005 17.575C9.11672 17.575 8.88338 17.4834 8.70005 17.3Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
class="_item_zxa40_17 _interactive_zxa40_36"
|
||||
data-kind="primary"
|
||||
role="menuitem"
|
||||
>
|
||||
Share room
|
||||
</div>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_BaseCard_Button mx_RoomSummaryCard_Button mx_RoomSummaryCard_icon_settings"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
aria-hidden="true"
|
||||
class="_icon_zxa40_49"
|
||||
height="24"
|
||||
width="24"
|
||||
/>
|
||||
<span
|
||||
class="_typography_yh5dq_162 _font-body-md-medium_yh5dq_69 _label_zxa40_58"
|
||||
>
|
||||
Room settings
|
||||
</div>
|
||||
</div>
|
||||
Export Chat
|
||||
</span>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="_nav-hint_zxa40_65"
|
||||
fill="none"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M8.70005 17.3C8.51672 17.1167 8.42505 16.8834 8.42505 16.6C8.42505 16.3167 8.51672 16.0834 8.70005 15.9L12.6 12L8.70005 8.10005C8.51672 7.91672 8.42505 7.68338 8.42505 7.40005C8.42505 7.11672 8.51672 6.88338 8.70005 6.70005C8.88338 6.51672 9.11672 6.42505 9.40005 6.42505C9.68338 6.42505 9.91672 6.51672 10.1 6.70005L14.7 11.3C14.8 11.4 14.8709 11.5084 14.9125 11.625C14.9542 11.7417 14.975 11.8667 14.975 12C14.975 12.1334 14.9542 12.2584 14.9125 12.375C14.8709 12.4917 14.8 12.6 14.7 12.7L10.1 17.3C9.91672 17.4834 9.68338 17.575 9.40005 17.575C9.11672 17.575 8.88338 17.4834 8.70005 17.3Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<div
|
||||
class="_separator_1uqhh_17"
|
||||
data-orientation="horizontal"
|
||||
role="separator"
|
||||
/>
|
||||
<button
|
||||
class="_item_zxa40_17 _interactive_zxa40_36"
|
||||
data-kind="critical"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="_icon_zxa40_49"
|
||||
height="24"
|
||||
width="24"
|
||||
/>
|
||||
<span
|
||||
class="_typography_yh5dq_162 _font-body-md-medium_yh5dq_69 _label_zxa40_58"
|
||||
>
|
||||
Leave room
|
||||
</span>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="_nav-hint_zxa40_65"
|
||||
fill="none"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M8.70005 17.3C8.51672 17.1167 8.42505 16.8834 8.42505 16.6C8.42505 16.3167 8.51672 16.0834 8.70005 15.9L12.6 12L8.70005 8.10005C8.51672 7.91672 8.42505 7.68338 8.42505 7.40005C8.42505 7.11672 8.51672 6.88338 8.70005 6.70005C8.88338 6.51672 9.11672 6.42505 9.40005 6.42505C9.68338 6.42505 9.91672 6.51672 10.1 6.70005L14.7 11.3C14.8 11.4 14.8709 11.5084 14.9125 11.625C14.9542 11.7417 14.975 11.8667 14.975 12C14.975 12.1334 14.9542 12.2584 14.9125 12.375C14.8709 12.4917 14.8 12.6 14.7 12.7L10.1 17.3C9.91672 17.4834 9.68338 17.575 9.40005 17.575C9.11672 17.575 8.88338 17.4834 8.70005 17.3Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<div
|
||||
class="mx_BaseCard_Group mx_RoomSummaryCard_appsGroup"
|
||||
>
|
||||
|
|
|
@ -40,6 +40,7 @@ import {
|
|||
resetAsyncStoreWithClient,
|
||||
mockPlatformPeg,
|
||||
mkEvent,
|
||||
filterConsole,
|
||||
} from "../../../test-utils";
|
||||
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||
import DMRoomMap from "../../../../src/utils/DMRoomMap";
|
||||
|
@ -74,6 +75,10 @@ describe("LegacyRoomHeader", () => {
|
|||
let bob: RoomMember;
|
||||
let carol: RoomMember;
|
||||
|
||||
filterConsole(
|
||||
"Age for event was not available, using `now - origin_server_ts` as a fallback. If the device clock is not correct issues might occur.",
|
||||
);
|
||||
|
||||
beforeEach(async () => {
|
||||
// some of our tests rely on the jest canvas mock, and `afterEach` will have reset the mock, so we need to
|
||||
// restore it.
|
||||
|
|
|
@ -48,7 +48,10 @@ import { Container, WidgetLayoutStore } from "../../../../src/stores/widgets/Wid
|
|||
jest.mock("../../../../src/utils/ShieldUtils");
|
||||
|
||||
describe("RoomHeader", () => {
|
||||
filterConsole("[getType] Room !1:example.org does not have an m.room.create event");
|
||||
filterConsole(
|
||||
"[getType] Room !1:example.org does not have an m.room.create event",
|
||||
"Age for event was not available, using `now - origin_server_ts` as a fallback. If the device clock is not correct issues might occur.",
|
||||
);
|
||||
|
||||
let room: Room;
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ exports[`RoomHeader does not show the face pile for DMs 1`] = `
|
|||
>
|
||||
<div
|
||||
aria-level="1"
|
||||
class="_font-body-lg-semibold_1jx6b_83 mx_RoomHeader_heading"
|
||||
class="_typography_yh5dq_162 _font-body-lg-semibold_yh5dq_83 mx_RoomHeader_heading"
|
||||
dir="auto"
|
||||
role="heading"
|
||||
>
|
||||
|
|
105
test/utils/room/canInviteTo-test.ts
Normal file
105
test/utils/room/canInviteTo-test.ts
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { mocked } from "jest-mock";
|
||||
import { JoinRule, Room } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { shouldShowComponent } from "../../../src/customisations/helpers/UIComponents";
|
||||
import { UIComponent } from "../../../src/settings/UIFeature";
|
||||
import { canInviteTo } from "../../../src/utils/room/canInviteTo";
|
||||
import { getMockClientWithEventEmitter, mockClientMethodsUser } from "../../test-utils";
|
||||
|
||||
jest.mock("../../../src/customisations/helpers/UIComponents", () => ({
|
||||
shouldShowComponent: jest.fn(),
|
||||
}));
|
||||
|
||||
describe("canInviteTo()", () => {
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
const userId = "@alice:server.org";
|
||||
const roomId = "!room:server.org";
|
||||
|
||||
const makeRoom = (): Room => {
|
||||
const client = getMockClientWithEventEmitter({
|
||||
...mockClientMethodsUser(userId),
|
||||
});
|
||||
const room = new Room(roomId, client, userId);
|
||||
jest.spyOn(room, "getMyMembership").mockReturnValue("join");
|
||||
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Public);
|
||||
jest.spyOn(room, "canInvite").mockReturnValue(true);
|
||||
return room;
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
mocked(shouldShowComponent).mockReturnValue(true);
|
||||
});
|
||||
|
||||
describe("when user has permissions to issue an invite for this room", () => {
|
||||
// aka when Room.canInvite is true
|
||||
|
||||
it("should return false when current user membership is not joined", () => {
|
||||
const room = makeRoom();
|
||||
jest.spyOn(room, "getMyMembership").mockReturnValue("invite");
|
||||
|
||||
expect(canInviteTo(room)).toEqual(false);
|
||||
});
|
||||
|
||||
it("should return false when UIComponent.InviteUsers customisation hides invite", () => {
|
||||
const room = makeRoom();
|
||||
mocked(shouldShowComponent).mockReturnValue(false);
|
||||
|
||||
expect(canInviteTo(room)).toEqual(false);
|
||||
expect(shouldShowComponent).toHaveBeenCalledWith(UIComponent.InviteUsers);
|
||||
});
|
||||
|
||||
it("should return true when user can invite and is a room member", () => {
|
||||
const room = makeRoom();
|
||||
|
||||
expect(canInviteTo(room)).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when user does not have permissions to issue an invite for this room", () => {
|
||||
// aka when Room.canInvite is false
|
||||
|
||||
it("should return false when room is a private space", () => {
|
||||
const room = makeRoom();
|
||||
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Invite);
|
||||
jest.spyOn(room, "isSpaceRoom").mockReturnValue(true);
|
||||
jest.spyOn(room, "canInvite").mockReturnValue(false);
|
||||
|
||||
expect(canInviteTo(room)).toEqual(false);
|
||||
});
|
||||
|
||||
it("should return false when room is just a room", () => {
|
||||
const room = makeRoom();
|
||||
jest.spyOn(room, "canInvite").mockReturnValue(false);
|
||||
|
||||
expect(canInviteTo(room)).toEqual(false);
|
||||
});
|
||||
|
||||
it("should return true when room is a public space", () => {
|
||||
const room = makeRoom();
|
||||
// default join rule is public
|
||||
jest.spyOn(room, "isSpaceRoom").mockReturnValue(true);
|
||||
jest.spyOn(room, "canInvite").mockReturnValue(false);
|
||||
|
||||
expect(canInviteTo(room)).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
65
test/utils/room/inviteToRoom-test.ts
Normal file
65
test/utils/room/inviteToRoom-test.ts
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { Room } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import defaultDispatcher from "../../../src/dispatcher/dispatcher";
|
||||
import { inviteToRoom } from "../../../src/utils/room/inviteToRoom";
|
||||
import { getMockClientWithEventEmitter } from "../../test-utils";
|
||||
|
||||
describe("inviteToRoom()", () => {
|
||||
const userId = "@alice:server.org";
|
||||
const roomId = "!room:server.org";
|
||||
|
||||
const makeRoom = (): Room => {
|
||||
const client = getMockClientWithEventEmitter({
|
||||
isGuest: jest.fn(),
|
||||
});
|
||||
const room = new Room(roomId, client, userId);
|
||||
return room;
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
// stub
|
||||
jest.spyOn(defaultDispatcher, "dispatch").mockImplementation(() => {});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("requires registration when a guest tries to invite to a room", () => {
|
||||
const room = makeRoom();
|
||||
|
||||
jest.spyOn(room.client, "isGuest").mockReturnValue(true);
|
||||
|
||||
inviteToRoom(room);
|
||||
|
||||
expect(defaultDispatcher.dispatch).toHaveBeenCalledTimes(1);
|
||||
expect(defaultDispatcher.dispatch).toHaveBeenCalledWith({ action: "require_registration" });
|
||||
});
|
||||
|
||||
it("opens the room inviter", () => {
|
||||
const room = makeRoom();
|
||||
|
||||
jest.spyOn(room.client, "isGuest").mockReturnValue(false);
|
||||
|
||||
inviteToRoom(room);
|
||||
|
||||
expect(defaultDispatcher.dispatch).toHaveBeenCalledTimes(1);
|
||||
expect(defaultDispatcher.dispatch).toHaveBeenCalledWith({ action: "view_invite", roomId });
|
||||
});
|
||||
});
|
154
test/utils/room/tagRoom-test.ts
Normal file
154
test/utils/room/tagRoom-test.ts
Normal file
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { Room } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import RoomListActions from "../../../src/actions/RoomListActions";
|
||||
import defaultDispatcher from "../../../src/dispatcher/dispatcher";
|
||||
import { DefaultTagID, TagID } from "../../../src/stores/room-list/models";
|
||||
import RoomListStore from "../../../src/stores/room-list/RoomListStore";
|
||||
import { tagRoom } from "../../../src/utils/room/tagRoom";
|
||||
import { getMockClientWithEventEmitter } from "../../test-utils";
|
||||
|
||||
describe("tagRoom()", () => {
|
||||
const userId = "@alice:server.org";
|
||||
const roomId = "!room:server.org";
|
||||
|
||||
const makeRoom = (tags: TagID[] = []): Room => {
|
||||
const client = getMockClientWithEventEmitter({
|
||||
isGuest: jest.fn(),
|
||||
});
|
||||
const room = new Room(roomId, client, userId);
|
||||
|
||||
jest.spyOn(RoomListStore.instance, "getTagsForRoom").mockReturnValue(tags);
|
||||
|
||||
return room;
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
// stub
|
||||
jest.spyOn(defaultDispatcher, "dispatch").mockImplementation(() => {});
|
||||
jest.spyOn(RoomListActions, "tagRoom").mockReturnValue({ action: "mocked_tag_room_action", fn: () => {} });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("does nothing when room tag is not allowed", () => {
|
||||
const room = makeRoom();
|
||||
|
||||
tagRoom(room, DefaultTagID.ServerNotice);
|
||||
|
||||
expect(defaultDispatcher.dispatch).not.toHaveBeenCalled();
|
||||
expect(RoomListActions.tagRoom).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe("when a room has no tags", () => {
|
||||
it("should tag a room as favourite", () => {
|
||||
const room = makeRoom();
|
||||
|
||||
tagRoom(room, DefaultTagID.Favourite);
|
||||
|
||||
expect(defaultDispatcher.dispatch).toHaveBeenCalled();
|
||||
expect(RoomListActions.tagRoom).toHaveBeenCalledWith(
|
||||
room.client,
|
||||
room,
|
||||
DefaultTagID.LowPriority, // remove
|
||||
DefaultTagID.Favourite, // add
|
||||
0,
|
||||
);
|
||||
});
|
||||
|
||||
it("should tag a room low priority", () => {
|
||||
const room = makeRoom();
|
||||
|
||||
tagRoom(room, DefaultTagID.LowPriority);
|
||||
|
||||
expect(defaultDispatcher.dispatch).toHaveBeenCalled();
|
||||
expect(RoomListActions.tagRoom).toHaveBeenCalledWith(
|
||||
room.client,
|
||||
room,
|
||||
DefaultTagID.Favourite, // remove
|
||||
DefaultTagID.LowPriority, // add
|
||||
0,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when a room is tagged as favourite", () => {
|
||||
it("should unfavourite a room", () => {
|
||||
const room = makeRoom([DefaultTagID.Favourite]);
|
||||
|
||||
tagRoom(room, DefaultTagID.Favourite);
|
||||
|
||||
expect(defaultDispatcher.dispatch).toHaveBeenCalled();
|
||||
expect(RoomListActions.tagRoom).toHaveBeenCalledWith(
|
||||
room.client,
|
||||
room,
|
||||
DefaultTagID.Favourite, // remove
|
||||
null, // add
|
||||
0,
|
||||
);
|
||||
});
|
||||
|
||||
it("should tag a room low priority", () => {
|
||||
const room = makeRoom([DefaultTagID.Favourite]);
|
||||
|
||||
tagRoom(room, DefaultTagID.LowPriority);
|
||||
|
||||
expect(defaultDispatcher.dispatch).toHaveBeenCalled();
|
||||
expect(RoomListActions.tagRoom).toHaveBeenCalledWith(
|
||||
room.client,
|
||||
room,
|
||||
DefaultTagID.Favourite, // remove
|
||||
DefaultTagID.LowPriority, // add
|
||||
0,
|
||||
);
|
||||
});
|
||||
});
|
||||
describe("when a room is tagged as low priority", () => {
|
||||
it("should favourite a room", () => {
|
||||
const room = makeRoom([DefaultTagID.LowPriority]);
|
||||
|
||||
tagRoom(room, DefaultTagID.Favourite);
|
||||
|
||||
expect(defaultDispatcher.dispatch).toHaveBeenCalled();
|
||||
expect(RoomListActions.tagRoom).toHaveBeenCalledWith(
|
||||
room.client,
|
||||
room,
|
||||
DefaultTagID.LowPriority, // remove
|
||||
DefaultTagID.Favourite, // add
|
||||
0,
|
||||
);
|
||||
});
|
||||
|
||||
it("should untag a room low priority", () => {
|
||||
const room = makeRoom([DefaultTagID.LowPriority]);
|
||||
|
||||
tagRoom(room, DefaultTagID.LowPriority);
|
||||
|
||||
expect(defaultDispatcher.dispatch).toHaveBeenCalled();
|
||||
expect(RoomListActions.tagRoom).toHaveBeenCalledWith(
|
||||
room.client,
|
||||
room,
|
||||
DefaultTagID.LowPriority, // remove
|
||||
null, // add
|
||||
0,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -3048,10 +3048,10 @@
|
|||
dependencies:
|
||||
svg2vectordrawable "^2.9.1"
|
||||
|
||||
"@vector-im/compound-web@0.6.3":
|
||||
version "0.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@vector-im/compound-web/-/compound-web-0.6.3.tgz#e5d025a3e5de1d94e721b0f6a5127dfa90968a2b"
|
||||
integrity sha512-Jw63AWRltUC/AH4f+0rxdeWgf/qin7fc9E3ZqtdI10tGAOz9YdHadeGg4aGTKjUgv8/J0GvF8VnEfVq9kRAbag==
|
||||
"@vector-im/compound-web@0.8.1":
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@vector-im/compound-web/-/compound-web-0.8.1.tgz#5ad709d78471b61af3adb41a3254a57a47cf5bb1"
|
||||
integrity sha512-+va9oW0mVe1MdXcP/k2+6YUARNq5N4aDbOu4mVTCOrBz8k+Apzydr+EO1dCjPkwLgkbibu1dutLimW9FxYEH3Q==
|
||||
dependencies:
|
||||
"@radix-ui/react-form" "^0.0.3"
|
||||
"@radix-ui/react-separator" "^1.0.3"
|
||||
|
|
Loading…
Reference in a new issue