From ffdd9595c72ac3c532ac1251540dd9f6dd886935 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Tue, 30 Jun 2026 13:49:28 +0100
Subject: [PATCH] Cut some import cycles (#34038)
* Fix SettingsController -> SettingsStore import cycles
* Fix AnalyticsToast<->AnalyticsLearnMoreDialog import cycle
* Fix emojipicker import cycle
* Fix MessageComposerButtons import cycle
* Fix ReadReceiptGroup<>ReadReceiptMarker import cycle
* Fix RoomSettingsDialog import cycles
* Fix SlashCommands import cycles
* Fix Pill import cycles
* Fill TODO comment
---
apps/web/src/TextForEvent.tsx | 2 +-
.../dialogs/AnalyticsLearnMoreDialog.tsx | 5 ++++-
.../views/dialogs/RoomSettingsDialog-tab.ts | 21 ++++++++++++++++++
.../views/dialogs/RoomSettingsDialog.tsx | 13 +----------
.../src/components/views/elements/Pill.tsx | 10 +--------
.../src/components/views/elements/PillType.ts | 16 ++++++++++++++
.../components/views/elements/ReplyChain.tsx | 3 ++-
.../components/views/emojipicker/Category.tsx | 2 +-
.../views/emojipicker/EmojiPicker.tsx | 5 +----
.../components/views/emojipicker/config.ts | 12 ++++++++++
.../views/location/LocationButton.tsx | 3 +--
.../views/rooms/CollapsibleButton.tsx | 6 +++--
.../components/views/rooms/EmojiButton.tsx | 3 +--
.../views/rooms/MessageComposerButtons.tsx | 7 ++----
.../components/views/rooms/NewRoomIntro.tsx | 2 +-
.../views/rooms/ReadReceiptGroup.tsx | 3 +--
.../views/rooms/ReadReceiptMarker.tsx | 3 ++-
.../views/rooms/RoomHeader/RoomHeader.tsx | 2 +-
.../components/views/rooms/RoomKnocksBar.tsx | 2 +-
.../components/views/settings/BridgeTile.tsx | 3 ++-
.../views/settings/JoinRuleSettings.tsx | 2 +-
apps/web/src/hooks/usePermalink.ts | 2 +-
apps/web/src/hooks/usePermalinkEvent.ts | 2 +-
apps/web/src/hooks/usePermalinkMember.ts | 2 +-
apps/web/src/hooks/usePermalinkTargetRoom.ts | 2 +-
apps/web/src/renderer/pill.tsx | 3 ++-
apps/web/src/settings/Settings.tsx | 2 +-
apps/web/src/settings/SettingsStore.ts | 2 ++
.../BlockInvitesConfigController.ts | 13 ++++-------
.../FallbackIceServerController.ts | 3 +--
.../controllers/IncompatibleController.ts | 5 ++---
.../controllers/RequiresSettingsController.ts | 3 +--
.../ServerSupportUnstableFeatureController.ts | 5 ++---
.../settings/controllers/SettingController.ts | 11 ++++++++++
.../controllers/SlidingSyncController.ts | 3 +--
.../controllers/SystemFontController.ts | 7 +++---
.../controllers/UIFeatureController.ts | 3 +--
apps/web/src/slash-commands/SlashCommands.tsx | 22 +------------------
apps/web/src/slash-commands/status.ts | 5 +++--
apps/web/src/slash-commands/utils.ts | 20 +++++++++++++++++
apps/web/src/toasts/AnalyticsToast.tsx | 4 ----
.../components/views/elements/Pill-test.tsx | 3 ++-
.../views/rooms/RoomKnocksBar-test.tsx | 2 +-
...t-at-first-space-test.ts => utils.test.ts} | 2 +-
44 files changed, 140 insertions(+), 111 deletions(-)
create mode 100644 apps/web/src/components/views/dialogs/RoomSettingsDialog-tab.ts
create mode 100644 apps/web/src/components/views/elements/PillType.ts
create mode 100644 apps/web/src/components/views/emojipicker/config.ts
rename apps/web/test/unit-tests/slash-commands/{split-at-first-space-test.ts => utils.test.ts} (93%)
diff --git a/apps/web/src/TextForEvent.tsx b/apps/web/src/TextForEvent.tsx
index 32dfb213b1..77d476e0b0 100644
--- a/apps/web/src/TextForEvent.tsx
+++ b/apps/web/src/TextForEvent.tsx
@@ -33,7 +33,7 @@ import { ALL_RULE_TYPES, ROOM_RULE_TYPES, SERVER_RULE_TYPES, USER_RULE_TYPES } f
import { WIDGET_LAYOUT_EVENT_TYPE } from "./stores/widgets/WidgetLayoutStore";
import { RightPanelPhases } from "./stores/right-panel/RightPanelStorePhases";
import defaultDispatcher from "./dispatcher/dispatcher";
-import { RoomSettingsTab } from "./components/views/dialogs/RoomSettingsDialog";
+import { RoomSettingsTab } from "./components/views/dialogs/RoomSettingsDialog-tab";
import AccessibleButton from "./components/views/elements/AccessibleButton";
import RightPanelStore from "./stores/right-panel/RightPanelStore";
import { highlightEvent, isLocationEvent } from "./utils/EventUtils";
diff --git a/apps/web/src/components/views/dialogs/AnalyticsLearnMoreDialog.tsx b/apps/web/src/components/views/dialogs/AnalyticsLearnMoreDialog.tsx
index f5481c09ce..0e9ada6f2f 100644
--- a/apps/web/src/components/views/dialogs/AnalyticsLearnMoreDialog.tsx
+++ b/apps/web/src/components/views/dialogs/AnalyticsLearnMoreDialog.tsx
@@ -14,9 +14,12 @@ import { _t } from "../../../languageHandler";
import DialogButtons from "../elements/DialogButtons";
import Modal, { type ComponentProps, type IHandle } from "../../../Modal";
import SdkConfig from "../../../SdkConfig";
-import { getPolicyUrl } from "../../../toasts/AnalyticsToast";
import ExternalLink from "../elements/ExternalLink";
+function getPolicyUrl(): string | undefined {
+ return SdkConfig.get("privacy_policy_url");
+}
+
export enum ButtonClicked {
Primary,
Cancel,
diff --git a/apps/web/src/components/views/dialogs/RoomSettingsDialog-tab.ts b/apps/web/src/components/views/dialogs/RoomSettingsDialog-tab.ts
new file mode 100644
index 0000000000..a32b56bfba
--- /dev/null
+++ b/apps/web/src/components/views/dialogs/RoomSettingsDialog-tab.ts
@@ -0,0 +1,21 @@
+/*
+Copyright 2024 New Vector Ltd.
+Copyright 2023 The Matrix.org Foundation C.I.C.
+Copyright 2019 New Vector Ltd
+Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
+
+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.
+*/
+
+export const enum RoomSettingsTab {
+ General = "ROOM_GENERAL_TAB",
+ People = "ROOM_PEOPLE_TAB",
+ Voip = "ROOM_VOIP_TAB",
+ Security = "ROOM_SECURITY_TAB",
+ Roles = "ROOM_ROLES_TAB",
+ Notifications = "ROOM_NOTIFICATIONS_TAB",
+ Bridges = "ROOM_BRIDGES_TAB",
+ Advanced = "ROOM_ADVANCED_TAB",
+ PollHistory = "ROOM_POLL_HISTORY_TAB",
+}
diff --git a/apps/web/src/components/views/dialogs/RoomSettingsDialog.tsx b/apps/web/src/components/views/dialogs/RoomSettingsDialog.tsx
index 4488c6bf93..80a559883c 100644
--- a/apps/web/src/components/views/dialogs/RoomSettingsDialog.tsx
+++ b/apps/web/src/components/views/dialogs/RoomSettingsDialog.tsx
@@ -43,18 +43,7 @@ import { PollHistoryTab } from "../settings/tabs/room/PollHistoryTab";
import ErrorBoundary from "../elements/ErrorBoundary";
import { PeopleRoomSettingsTab } from "../settings/tabs/room/PeopleRoomSettingsTab";
import { SDKContext, type SdkContextClass } from "../../../contexts/SDKContext";
-
-export const enum RoomSettingsTab {
- General = "ROOM_GENERAL_TAB",
- People = "ROOM_PEOPLE_TAB",
- Voip = "ROOM_VOIP_TAB",
- Security = "ROOM_SECURITY_TAB",
- Roles = "ROOM_ROLES_TAB",
- Notifications = "ROOM_NOTIFICATIONS_TAB",
- Bridges = "ROOM_BRIDGES_TAB",
- Advanced = "ROOM_ADVANCED_TAB",
- PollHistory = "ROOM_POLL_HISTORY_TAB",
-}
+import { RoomSettingsTab } from "./RoomSettingsDialog-tab.ts";
interface IProps {
roomId: string;
diff --git a/apps/web/src/components/views/elements/Pill.tsx b/apps/web/src/components/views/elements/Pill.tsx
index 32e78fc32e..0365dd3ddd 100644
--- a/apps/web/src/components/views/elements/Pill.tsx
+++ b/apps/web/src/components/views/elements/Pill.tsx
@@ -17,15 +17,7 @@ import { usePermalink } from "../../../hooks/usePermalink";
import RoomAvatar from "../avatars/RoomAvatar";
import MemberAvatar from "../avatars/MemberAvatar";
import { _t } from "../../../languageHandler";
-
-export enum PillType {
- UserMention = "TYPE_USER_MENTION",
- RoomMention = "TYPE_ROOM_MENTION",
- AtRoomMention = "TYPE_AT_ROOM_MENTION", // '@room' mention
- EventInSameRoom = "TYPE_EVENT_IN_SAME_ROOM",
- EventInOtherRoom = "TYPE_EVENT_IN_OTHER_ROOM",
- Keyword = "TYPE_KEYWORD", // Used to highlight keywords that triggered a notification rule
-}
+import { PillType } from "./PillType";
const linkIcon = ;
diff --git a/apps/web/src/components/views/elements/PillType.ts b/apps/web/src/components/views/elements/PillType.ts
new file mode 100644
index 0000000000..8450364ef8
--- /dev/null
+++ b/apps/web/src/components/views/elements/PillType.ts
@@ -0,0 +1,16 @@
+/*
+Copyright 2024 New Vector Ltd.
+Copyright 2017-2019 , 2021 The Matrix.org Foundation C.I.C.
+
+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.
+*/
+
+export enum PillType {
+ UserMention = "TYPE_USER_MENTION",
+ RoomMention = "TYPE_ROOM_MENTION",
+ AtRoomMention = "TYPE_AT_ROOM_MENTION", // '@room' mention
+ EventInSameRoom = "TYPE_EVENT_IN_SAME_ROOM",
+ EventInOtherRoom = "TYPE_EVENT_IN_OTHER_ROOM",
+ Keyword = "TYPE_KEYWORD", // Used to highlight keywords that triggered a notification rule
+}
diff --git a/apps/web/src/components/views/elements/ReplyChain.tsx b/apps/web/src/components/views/elements/ReplyChain.tsx
index f6642303b7..ead388832c 100644
--- a/apps/web/src/components/views/elements/ReplyChain.tsx
+++ b/apps/web/src/components/views/elements/ReplyChain.tsx
@@ -19,7 +19,8 @@ import { getUserNameColorClass } from "../../../utils/FormattingUtils";
import { Action } from "../../../dispatcher/actions";
import Spinner from "./Spinner";
import ReplyTile from "../rooms/ReplyTile";
-import { Pill, PillType } from "./Pill";
+import { Pill } from "./Pill";
+import { PillType } from "./PillType";
import AccessibleButton from "./AccessibleButton";
import { getParentEventId, shouldDisplayReply } from "../../../utils/Reply";
import RoomContext from "../../../contexts/RoomContext";
diff --git a/apps/web/src/components/views/emojipicker/Category.tsx b/apps/web/src/components/views/emojipicker/Category.tsx
index 17f33d9346..db61015f56 100644
--- a/apps/web/src/components/views/emojipicker/Category.tsx
+++ b/apps/web/src/components/views/emojipicker/Category.tsx
@@ -10,7 +10,7 @@ Please see LICENSE files in the repository root for full details.
import React, { type JSX, type RefObject } from "react";
import { type DATA_BY_CATEGORY, type Emoji as IEmoji } from "@matrix-org/emojibase-bindings";
-import { CATEGORY_HEADER_HEIGHT, EMOJI_HEIGHT, EMOJIS_PER_ROW } from "./EmojiPicker";
+import { CATEGORY_HEADER_HEIGHT, EMOJI_HEIGHT, EMOJIS_PER_ROW } from "./config";
import LazyRenderList from "../elements/LazyRenderList";
import Emoji from "./Emoji";
import { type ButtonEvent } from "../elements/AccessibleButton";
diff --git a/apps/web/src/components/views/emojipicker/EmojiPicker.tsx b/apps/web/src/components/views/emojipicker/EmojiPicker.tsx
index 47047ef77f..6b81f84b44 100644
--- a/apps/web/src/components/views/emojipicker/EmojiPicker.tsx
+++ b/apps/web/src/components/views/emojipicker/EmojiPicker.tsx
@@ -28,10 +28,7 @@ import {
} from "../../../accessibility/RovingTabIndex";
import { Key } from "../../../Keyboard";
import { type ButtonEvent } from "../elements/AccessibleButton";
-
-export const CATEGORY_HEADER_HEIGHT = 20;
-export const EMOJI_HEIGHT = 35;
-export const EMOJIS_PER_ROW = 8;
+import { CATEGORY_HEADER_HEIGHT, EMOJI_HEIGHT, EMOJIS_PER_ROW } from "./config";
const ZERO_WIDTH_JOINER = "\u200D";
diff --git a/apps/web/src/components/views/emojipicker/config.ts b/apps/web/src/components/views/emojipicker/config.ts
new file mode 100644
index 0000000000..2b0e8c8858
--- /dev/null
+++ b/apps/web/src/components/views/emojipicker/config.ts
@@ -0,0 +1,12 @@
+/*
+Copyright 2024 New Vector Ltd.
+Copyright 2020 The Matrix.org Foundation C.I.C.
+Copyright 2019 Tulir Asokan
+
+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.
+*/
+
+export const CATEGORY_HEADER_HEIGHT = 20;
+export const EMOJI_HEIGHT = 35;
+export const EMOJIS_PER_ROW = 8;
diff --git a/apps/web/src/components/views/location/LocationButton.tsx b/apps/web/src/components/views/location/LocationButton.tsx
index 79385a35b8..0f02689b7d 100644
--- a/apps/web/src/components/views/location/LocationButton.tsx
+++ b/apps/web/src/components/views/location/LocationButton.tsx
@@ -12,9 +12,8 @@ import { type RoomMember, type IEventRelation } from "matrix-js-sdk/src/matrix";
import { LocationPinIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
import { _t } from "../../../languageHandler";
-import { CollapsibleButton } from "../rooms/CollapsibleButton";
+import { CollapsibleButton, OverflowMenuContext } from "../rooms/CollapsibleButton";
import { aboveLeftOf, useContextMenu, type MenuProps } from "../../structures/ContextMenu";
-import { OverflowMenuContext } from "../rooms/MessageComposerButtons";
import LocationShareMenu from "./LocationShareMenu";
export interface IProps {
diff --git a/apps/web/src/components/views/rooms/CollapsibleButton.tsx b/apps/web/src/components/views/rooms/CollapsibleButton.tsx
index 158a4e426b..080b199c8b 100644
--- a/apps/web/src/components/views/rooms/CollapsibleButton.tsx
+++ b/apps/web/src/components/views/rooms/CollapsibleButton.tsx
@@ -6,12 +6,14 @@ 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 React, { type RefObject, useContext } from "react";
+import React, { type RefObject, useContext, createContext } from "react";
import AccessibleButton, { type ButtonProps } from "../elements/AccessibleButton";
-import { OverflowMenuContext } from "./MessageComposerButtons";
import { IconizedContextMenuOption } from "../context_menus/IconizedContextMenu";
+type OverflowMenuCloser = () => void;
+export const OverflowMenuContext = createContext(null);
+
interface Props extends Omit, "element"> {
inputRef?: RefObject;
title: string;
diff --git a/apps/web/src/components/views/rooms/EmojiButton.tsx b/apps/web/src/components/views/rooms/EmojiButton.tsx
index bc973d7b57..d5db6a3fd2 100644
--- a/apps/web/src/components/views/rooms/EmojiButton.tsx
+++ b/apps/web/src/components/views/rooms/EmojiButton.tsx
@@ -13,8 +13,7 @@ import { ReactionIcon } from "@vector-im/compound-design-tokens/assets/web/icons
import { _t } from "../../../languageHandler";
import ContextMenu, { aboveLeftOf, type MenuProps, useContextMenu } from "../../structures/ContextMenu";
import EmojiPicker from "../emojipicker/EmojiPicker";
-import { CollapsibleButton } from "./CollapsibleButton";
-import { OverflowMenuContext } from "./MessageComposerButtons";
+import { CollapsibleButton, OverflowMenuContext } from "./CollapsibleButton";
interface IEmojiButtonProps {
addEmoji: (unicode: string) => boolean;
diff --git a/apps/web/src/components/views/rooms/MessageComposerButtons.tsx b/apps/web/src/components/views/rooms/MessageComposerButtons.tsx
index 6f4f5d1c44..919e33d039 100644
--- a/apps/web/src/components/views/rooms/MessageComposerButtons.tsx
+++ b/apps/web/src/components/views/rooms/MessageComposerButtons.tsx
@@ -15,7 +15,7 @@ import {
THREAD_RELATION_TYPE,
M_POLL_START,
} from "matrix-js-sdk/src/matrix";
-import React, { type JSX, createContext, type ReactElement, type ReactNode, useContext } from "react";
+import React, { type JSX, type ReactElement, type ReactNode, useContext } from "react";
import {
MicOnIcon,
OverflowHorizontalIcon,
@@ -26,7 +26,7 @@ import {
import { UploadButton, useViewModel } from "@element-hq/web-shared-components";
import { _t } from "../../../languageHandler";
-import { CollapsibleButton } from "./CollapsibleButton";
+import { CollapsibleButton, OverflowMenuContext } from "./CollapsibleButton";
import { type MenuProps } from "../../structures/ContextMenu";
import ErrorDialog from "../dialogs/ErrorDialog";
import { LocationButton } from "../location";
@@ -62,9 +62,6 @@ interface IProps {
onComposerModeClick: () => void;
}
-type OverflowMenuCloser = () => void;
-export const OverflowMenuContext = createContext(null);
-
const MessageComposerButtons: React.FC = (props: IProps) => {
const matrixClient = useContext(MatrixClientContext);
const roomUploadVM = useRoomUploadViewModel();
diff --git a/apps/web/src/components/views/rooms/NewRoomIntro.tsx b/apps/web/src/components/views/rooms/NewRoomIntro.tsx
index 1dec30785d..c4f4a169fa 100644
--- a/apps/web/src/components/views/rooms/NewRoomIntro.tsx
+++ b/apps/web/src/components/views/rooms/NewRoomIntro.tsx
@@ -23,7 +23,7 @@ import { type ViewUserPayload } from "../../../dispatcher/payloads/ViewUserPaylo
import { Action } from "../../../dispatcher/actions";
import SpaceStore from "../../../stores/spaces/SpaceStore";
import { showSpaceInvite } from "../../../utils/space";
-import { RoomSettingsTab } from "../dialogs/RoomSettingsDialog";
+import { RoomSettingsTab } from "../dialogs/RoomSettingsDialog-tab";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
import { UIComponent } from "../../../settings/UIFeature";
diff --git a/apps/web/src/components/views/rooms/ReadReceiptGroup.tsx b/apps/web/src/components/views/rooms/ReadReceiptGroup.tsx
index e2f039e4d1..0f3eee10b4 100644
--- a/apps/web/src/components/views/rooms/ReadReceiptGroup.tsx
+++ b/apps/web/src/components/views/rooms/ReadReceiptGroup.tsx
@@ -11,7 +11,7 @@ import { type User } from "matrix-js-sdk/src/matrix";
import { Tooltip } from "@vector-im/compound-web";
import { AutoHideScrollbar } from "@element-hq/web-shared-components";
-import ReadReceiptMarker, { type IReadReceiptPosition } from "./ReadReceiptMarker";
+import ReadReceiptMarker, { type IReadReceiptPosition, READ_AVATAR_SIZE } from "./ReadReceiptMarker";
import { type IReadReceiptProps } from "./EventTile";
import AccessibleButton from "../elements/AccessibleButton";
import MemberAvatar from "../avatars/MemberAvatar";
@@ -29,7 +29,6 @@ const MAX_READ_AVATARS_PLUS_N = 3;
const MAX_READ_AVATARS = MAX_READ_AVATARS_PLUS_N + 1;
const READ_AVATAR_OFFSET = 10;
-export const READ_AVATAR_SIZE = 16;
interface Props {
readReceipts: IReadReceiptProps[];
diff --git a/apps/web/src/components/views/rooms/ReadReceiptMarker.tsx b/apps/web/src/components/views/rooms/ReadReceiptMarker.tsx
index 91983427f5..3bcd301bff 100644
--- a/apps/web/src/components/views/rooms/ReadReceiptMarker.tsx
+++ b/apps/web/src/components/views/rooms/ReadReceiptMarker.tsx
@@ -14,7 +14,8 @@ import { logger } from "matrix-js-sdk/src/logger";
import NodeAnimator from "../../../NodeAnimator";
import { toPx } from "../../../utils/units";
import MemberAvatar from "../avatars/MemberAvatar";
-import { READ_AVATAR_SIZE } from "./ReadReceiptGroup";
+
+export const READ_AVATAR_SIZE = 16;
// The top & right from the bounding client rect of each read receipt
export interface IReadReceiptPosition {
diff --git a/apps/web/src/components/views/rooms/RoomHeader/RoomHeader.tsx b/apps/web/src/components/views/rooms/RoomHeader/RoomHeader.tsx
index 4226b40f25..dbdb0f619a 100644
--- a/apps/web/src/components/views/rooms/RoomHeader/RoomHeader.tsx
+++ b/apps/web/src/components/views/rooms/RoomHeader/RoomHeader.tsx
@@ -51,7 +51,7 @@ import WithPresenceIndicator, { useDmMember } from "../../avatars/WithPresenceIn
import { type IOOBData } from "../../../../stores/ThreepidInviteStore.ts";
import { MainSplitContentType } from "../../../../contexts/RoomContext.ts";
import defaultDispatcher from "../../../../dispatcher/dispatcher.ts";
-import { RoomSettingsTab } from "../../dialogs/RoomSettingsDialog.tsx";
+import { RoomSettingsTab } from "../../dialogs/RoomSettingsDialog-tab";
import { useScopedRoomContext } from "../../../../contexts/ScopedRoomContext.tsx";
import { ToggleableIcon } from "./toggle/ToggleableIcon.tsx";
import { CurrentRightPanelPhaseContextProvider } from "../../../../contexts/CurrentRightPanelPhaseContext.tsx";
diff --git a/apps/web/src/components/views/rooms/RoomKnocksBar.tsx b/apps/web/src/components/views/rooms/RoomKnocksBar.tsx
index 9b762f0b96..bada3f33a3 100644
--- a/apps/web/src/components/views/rooms/RoomKnocksBar.tsx
+++ b/apps/web/src/components/views/rooms/RoomKnocksBar.tsx
@@ -17,7 +17,7 @@ import { _t } from "../../../languageHandler";
import Modal from "../../../Modal";
import MemberAvatar from "../avatars/MemberAvatar";
import ErrorDialog from "../dialogs/ErrorDialog";
-import { RoomSettingsTab } from "../dialogs/RoomSettingsDialog";
+import { RoomSettingsTab } from "../dialogs/RoomSettingsDialog-tab";
import AccessibleButton from "../elements/AccessibleButton";
import Heading from "../typography/Heading";
import { formatList } from "../../../utils/FormattingUtils";
diff --git a/apps/web/src/components/views/settings/BridgeTile.tsx b/apps/web/src/components/views/settings/BridgeTile.tsx
index 5cec9314d7..870ed18884 100644
--- a/apps/web/src/components/views/settings/BridgeTile.tsx
+++ b/apps/web/src/components/views/settings/BridgeTile.tsx
@@ -11,7 +11,8 @@ import { type MatrixEvent, type Room } from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger";
import { _t } from "../../../languageHandler";
-import { Pill, PillType } from "../elements/Pill";
+import { Pill } from "../elements/Pill";
+import { PillType } from "../elements/PillType";
import { makeUserPermalink } from "../../../utils/permalinks/Permalinks";
import BaseAvatar from "../avatars/BaseAvatar";
import SettingsStore from "../../../settings/SettingsStore";
diff --git a/apps/web/src/components/views/settings/JoinRuleSettings.tsx b/apps/web/src/components/views/settings/JoinRuleSettings.tsx
index 1fd43657be..86ef7af7a6 100644
--- a/apps/web/src/components/views/settings/JoinRuleSettings.tsx
+++ b/apps/web/src/components/views/settings/JoinRuleSettings.tsx
@@ -22,7 +22,7 @@ import { type RoomUpgradeProgress, upgradeRoom } from "../../../utils/RoomUpgrad
import { arrayHasDiff } from "../../../utils/arrays";
import { useLocalEcho } from "../../../hooks/useLocalEcho";
import dis from "../../../dispatcher/dispatcher";
-import { RoomSettingsTab } from "../dialogs/RoomSettingsDialog";
+import { RoomSettingsTab } from "../dialogs/RoomSettingsDialog-tab";
import { Action } from "../../../dispatcher/actions";
import { type ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import { doesRoomVersionSupport, PreferredRoomVersions } from "../../../utils/PreferredRoomVersions";
diff --git a/apps/web/src/hooks/usePermalink.ts b/apps/web/src/hooks/usePermalink.ts
index 146c44cdfe..00e22b423a 100644
--- a/apps/web/src/hooks/usePermalink.ts
+++ b/apps/web/src/hooks/usePermalink.ts
@@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details.
import { type MatrixEvent, type Room, type RoomMember } from "matrix-js-sdk/src/matrix";
import { type ButtonEvent } from "../components/views/elements/AccessibleButton";
-import { PillType } from "../components/views/elements/Pill";
+import { PillType } from "../components/views/elements/PillType";
import { parsePermalink } from "../utils/permalinks/Permalinks";
import dis from "../dispatcher/dispatcher";
import { Action } from "../dispatcher/actions";
diff --git a/apps/web/src/hooks/usePermalinkEvent.ts b/apps/web/src/hooks/usePermalinkEvent.ts
index bb95f3b5c0..85adc20dc9 100644
--- a/apps/web/src/hooks/usePermalinkEvent.ts
+++ b/apps/web/src/hooks/usePermalinkEvent.ts
@@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details.
import { MatrixEvent, type Room } from "matrix-js-sdk/src/matrix";
import { useEffect, useState } from "react";
-import { PillType } from "../components/views/elements/Pill";
+import { PillType } from "../components/views/elements/PillType";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { type PermalinkParts } from "../utils/permalinks/PermalinkConstructor";
diff --git a/apps/web/src/hooks/usePermalinkMember.ts b/apps/web/src/hooks/usePermalinkMember.ts
index b5e751d28f..3e1bd945cf 100644
--- a/apps/web/src/hooks/usePermalinkMember.ts
+++ b/apps/web/src/hooks/usePermalinkMember.ts
@@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details.
import { type IMatrixProfile, type MatrixEvent, type Room, RoomMember } from "matrix-js-sdk/src/matrix";
import { useContext, useEffect, useState } from "react";
-import { PillType } from "../components/views/elements/Pill";
+import { PillType } from "../components/views/elements/PillType";
import { SDKContext, type SdkContextClass } from "../contexts/SDKContext";
import { type PermalinkParts } from "../utils/permalinks/PermalinkConstructor";
diff --git a/apps/web/src/hooks/usePermalinkTargetRoom.ts b/apps/web/src/hooks/usePermalinkTargetRoom.ts
index 9de18cc4f8..3df1fa4cb5 100644
--- a/apps/web/src/hooks/usePermalinkTargetRoom.ts
+++ b/apps/web/src/hooks/usePermalinkTargetRoom.ts
@@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details.
import { type Room } from "matrix-js-sdk/src/matrix";
import { useEffect, useState } from "react";
-import { PillType } from "../components/views/elements/Pill";
+import { PillType } from "../components/views/elements/PillType";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { type PermalinkParts } from "../utils/permalinks/PermalinkConstructor";
diff --git a/apps/web/src/renderer/pill.tsx b/apps/web/src/renderer/pill.tsx
index 9157c1181a..5946fab1d6 100644
--- a/apps/web/src/renderer/pill.tsx
+++ b/apps/web/src/renderer/pill.tsx
@@ -13,7 +13,8 @@ import { textContent } from "domutils";
import reactStringReplace from "react-string-replace";
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor";
-import { Pill, PillType } from "../components/views/elements/Pill";
+import { Pill } from "../components/views/elements/Pill";
+import { PillType } from "../components/views/elements/PillType";
import { parsePermalink } from "../utils/permalinks/Permalinks";
import { type PermalinkParts } from "../utils/permalinks/PermalinkConstructor";
import { hasParentMatching, type RendererMap, type ParentNode } from "./utils.tsx";
diff --git a/apps/web/src/settings/Settings.tsx b/apps/web/src/settings/Settings.tsx
index dad9373c27..2f0670b90f 100644
--- a/apps/web/src/settings/Settings.tsx
+++ b/apps/web/src/settings/Settings.tsx
@@ -457,7 +457,7 @@ export const SETTINGS: Settings = {
shouldExportToRageshake: false,
},
"blockInvites": {
- controller: new BlockInvitesConfigController("blockInvites"),
+ controller: new BlockInvitesConfigController("blockInvites", defaultWatchManager),
supportedLevels: [SettingLevel.ACCOUNT],
default: false,
},
diff --git a/apps/web/src/settings/SettingsStore.ts b/apps/web/src/settings/SettingsStore.ts
index 006343be68..ad8627ab05 100644
--- a/apps/web/src/settings/SettingsStore.ts
+++ b/apps/web/src/settings/SettingsStore.ts
@@ -40,6 +40,7 @@ import PlatformSettingsHandler from "./handlers/PlatformSettingsHandler";
import ReloadOnChangeController from "./controllers/ReloadOnChangeController";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { MediaPreviewValue } from "../@types/media_preview";
+import SettingController from "./controllers/SettingController.ts";
// Convert the settings to easier to manage objects for the handlers
const defaultSettings: Record = {};
@@ -887,5 +888,6 @@ export default class SettingsStore {
}
}
+SettingController.settingsStore = SettingsStore;
// For debugging purposes
window.mxSettingsStore = SettingsStore;
diff --git a/apps/web/src/settings/controllers/BlockInvitesConfigController.ts b/apps/web/src/settings/controllers/BlockInvitesConfigController.ts
index a945dbb384..7890df7647 100644
--- a/apps/web/src/settings/controllers/BlockInvitesConfigController.ts
+++ b/apps/web/src/settings/controllers/BlockInvitesConfigController.ts
@@ -10,21 +10,16 @@ import { EventType } from "matrix-js-sdk/src/matrix";
import { type SettingLevel } from "../SettingLevel.ts";
import { _td } from "../../languageHandler.tsx";
import ServerSupportUnstableFeatureController from "./ServerSupportUnstableFeatureController.ts";
-import { defaultWatchManager, type SettingKey } from "../Settings.tsx";
+import { type SettingKey } from "../Settings.tsx";
+import type { WatchManager } from "../WatchManager.ts";
/**
* Handles invite filtering rules provided by MSC4380.
* This handler does not make use of the roomId parameter.
*/
export default class BlockInvitesConfigController extends ServerSupportUnstableFeatureController {
- public constructor(settingName: SettingKey) {
- super(
- settingName,
- defaultWatchManager,
- [["org.matrix.msc4380.stable"]],
- "v1.18",
- _td("settings|not_supported"),
- );
+ public constructor(settingName: SettingKey, watchers: WatchManager) {
+ super(settingName, watchers, [["org.matrix.msc4380.stable"]], "v1.18", _td("settings|not_supported"));
}
public getValueOverride(_level: SettingLevel): boolean {
diff --git a/apps/web/src/settings/controllers/FallbackIceServerController.ts b/apps/web/src/settings/controllers/FallbackIceServerController.ts
index fa87a00bd3..858bab6ce8 100644
--- a/apps/web/src/settings/controllers/FallbackIceServerController.ts
+++ b/apps/web/src/settings/controllers/FallbackIceServerController.ts
@@ -8,7 +8,6 @@ Please see LICENSE files in the repository root for full details.
import { ClientEvent, type IClientWellKnown, type MatrixClient } from "matrix-js-sdk/src/matrix";
import { type SettingLevel } from "../SettingLevel";
-import SettingsStore from "../SettingsStore.ts";
import MatrixClientBackedController from "./MatrixClientBackedController.ts";
/**
@@ -47,6 +46,6 @@ export default class FallbackIceServerController extends MatrixClientBackedContr
}
public onChange(_level: SettingLevel, _roomId: string | null, _newValue: any): void {
- this.client?.setFallbackICEServerAllowed(!!SettingsStore.getValue("fallbackICEServerAllowed"));
+ this.client?.setFallbackICEServerAllowed(!!this.settingsStore.getValue("fallbackICEServerAllowed"));
}
}
diff --git a/apps/web/src/settings/controllers/IncompatibleController.ts b/apps/web/src/settings/controllers/IncompatibleController.ts
index 7351139d97..35edeeadb4 100644
--- a/apps/web/src/settings/controllers/IncompatibleController.ts
+++ b/apps/web/src/settings/controllers/IncompatibleController.ts
@@ -8,7 +8,6 @@ Please see LICENSE files in the repository root for full details.
import SettingController from "./SettingController";
import { type SettingLevel } from "../SettingLevel";
-import SettingsStore from "../SettingsStore";
import { type BooleanSettingKey } from "../Settings.tsx";
import PlatformPeg from "../../PlatformPeg.ts";
@@ -49,9 +48,9 @@ export default class IncompatibleController extends SettingController {
public get incompatibleSetting(): boolean {
if (typeof this.incompatibleValue === "function") {
- return this.incompatibleValue(SettingsStore.getValue(this.settingName));
+ return this.incompatibleValue(this.settingsStore.getValue(this.settingName));
}
- return SettingsStore.getValue(this.settingName) === this.incompatibleValue;
+ return this.settingsStore.getValue(this.settingName) === this.incompatibleValue;
}
public onChange(): void {
diff --git a/apps/web/src/settings/controllers/RequiresSettingsController.ts b/apps/web/src/settings/controllers/RequiresSettingsController.ts
index 3729ce7fbb..cfe6802721 100644
--- a/apps/web/src/settings/controllers/RequiresSettingsController.ts
+++ b/apps/web/src/settings/controllers/RequiresSettingsController.ts
@@ -8,7 +8,6 @@ Please see LICENSE files in the repository root for full details.
import { logger as rootLogger } from "matrix-js-sdk/src/logger";
import type { Capabilities } from "matrix-js-sdk/src/matrix";
-import SettingsStore from "../SettingsStore";
import type { BooleanSettingKey } from "../Settings.tsx";
import MatrixClientBackedController from "./MatrixClientBackedController.ts";
@@ -60,7 +59,7 @@ export default class RequiresSettingsController extends MatrixClientBackedContro
}
public get settingDisabled(): boolean | string {
- if (this.settingNames.some((s) => !SettingsStore.getValue(s))) {
+ if (this.settingNames.some((s) => !this.settingsStore.getValue(s))) {
return true;
}
return this.isBlockedByCapabilites;
diff --git a/apps/web/src/settings/controllers/ServerSupportUnstableFeatureController.ts b/apps/web/src/settings/controllers/ServerSupportUnstableFeatureController.ts
index c5c3fc3911..078891e72d 100644
--- a/apps/web/src/settings/controllers/ServerSupportUnstableFeatureController.ts
+++ b/apps/web/src/settings/controllers/ServerSupportUnstableFeatureController.ts
@@ -10,7 +10,6 @@ Please see LICENSE files in the repository root for full details.
import { type SettingLevel } from "../SettingLevel";
import MatrixClientBackedController from "./MatrixClientBackedController";
import { type WatchManager } from "../WatchManager";
-import SettingsStore from "../SettingsStore";
import { type SettingKey } from "../Settings.tsx";
import { _t } from "../../languageHandler.tsx";
import PlatformPeg from "../../PlatformPeg.ts";
@@ -63,9 +62,9 @@ export default class ServerSupportUnstableFeatureController extends MatrixClient
public set disabled(newDisabledValue: boolean) {
if (!newDisabledValue === this.enabled) return;
this.enabled = !newDisabledValue;
- const level = SettingsStore.firstSupportedLevel(this.settingName);
+ const level = this.settingsStore.firstSupportedLevel(this.settingName);
if (!level) return;
- const settingValue = SettingsStore.getValue(this.settingName, null);
+ const settingValue = this.settingsStore.getValue(this.settingName, null);
this.watchers.notifyUpdate(this.settingName, null, level, settingValue);
}
diff --git a/apps/web/src/settings/controllers/SettingController.ts b/apps/web/src/settings/controllers/SettingController.ts
index 4f8d804adb..a1e2ff561b 100644
--- a/apps/web/src/settings/controllers/SettingController.ts
+++ b/apps/web/src/settings/controllers/SettingController.ts
@@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details.
*/
import { type SettingLevel } from "../SettingLevel";
+import type SettingsStore from "../SettingsStore";
/**
* Represents a controller for individual settings to alter the reading behaviour
@@ -18,6 +19,8 @@ import { type SettingLevel } from "../SettingLevel";
* intended to handle environmental factors for specific settings.
*/
export default abstract class SettingController {
+ public static settingsStore: typeof SettingsStore;
+
/**
* Gets the overridden value for the setting, if any. This must return null if the
* value is not to be overridden, otherwise it must return the new value.
@@ -66,4 +69,12 @@ export default abstract class SettingController {
public get settingDisabled(): boolean | string {
return false;
}
+
+ /**
+ * Accessor to the SettingsStore injected at runtime.
+ * Preferred to direct imports in order to avoid import cycles.
+ */
+ protected get settingsStore(): typeof SettingsStore {
+ return SettingController.settingsStore;
+ }
}
diff --git a/apps/web/src/settings/controllers/SlidingSyncController.ts b/apps/web/src/settings/controllers/SlidingSyncController.ts
index 44de3ba8ee..dfa3732f25 100644
--- a/apps/web/src/settings/controllers/SlidingSyncController.ts
+++ b/apps/web/src/settings/controllers/SlidingSyncController.ts
@@ -9,7 +9,6 @@ Please see LICENSE files in the repository root for full details.
import SettingController from "./SettingController";
import PlatformPeg from "../../PlatformPeg";
-import SettingsStore from "../SettingsStore";
import { _t } from "../../languageHandler";
import { SlidingSyncManager } from "../../SlidingSyncManager";
@@ -20,7 +19,7 @@ export default class SlidingSyncController extends SettingController {
public get settingDisabled(): boolean | string {
// Cannot be disabled once enabled, user has been warned and must log out and back in.
- if (SettingsStore.getValue("feature_simplified_sliding_sync")) {
+ if (this.settingsStore.getValue("feature_simplified_sliding_sync")) {
return _t("labs|sliding_sync_disabled_notice");
}
if (!SlidingSyncManager.serverSupportsSlidingSync) {
diff --git a/apps/web/src/settings/controllers/SystemFontController.ts b/apps/web/src/settings/controllers/SystemFontController.ts
index 11d9a2cbd6..499e84bb06 100644
--- a/apps/web/src/settings/controllers/SystemFontController.ts
+++ b/apps/web/src/settings/controllers/SystemFontController.ts
@@ -7,7 +7,6 @@ Please see LICENSE files in the repository root for full details.
*/
import SettingController from "./SettingController";
-import SettingsStore from "../SettingsStore";
import dis from "../../dispatcher/dispatcher";
import { type UpdateSystemFontPayload } from "../../dispatcher/payloads/UpdateSystemFontPayload";
import { Action } from "../../dispatcher/actions";
@@ -21,9 +20,9 @@ export default class SystemFontController extends SettingController {
// Dispatch font size change so that everything open responds to the change.
dis.dispatch({
action: Action.UpdateSystemFont,
- useBundledEmojiFont: SettingsStore.getValue("useBundledEmojiFont"),
- useSystemFont: SettingsStore.getValue("useSystemFont"),
- font: SettingsStore.getValue("systemFont"),
+ useBundledEmojiFont: this.settingsStore.getValue("useBundledEmojiFont"),
+ useSystemFont: this.settingsStore.getValue("useSystemFont"),
+ font: this.settingsStore.getValue("systemFont"),
});
}
}
diff --git a/apps/web/src/settings/controllers/UIFeatureController.ts b/apps/web/src/settings/controllers/UIFeatureController.ts
index 59ab516487..94cd669f22 100644
--- a/apps/web/src/settings/controllers/UIFeatureController.ts
+++ b/apps/web/src/settings/controllers/UIFeatureController.ts
@@ -8,7 +8,6 @@ Please see LICENSE files in the repository root for full details.
import SettingController from "./SettingController";
import { type SettingLevel } from "../SettingLevel";
-import SettingsStore from "../SettingsStore";
import { type SettingKey } from "../Settings.tsx";
/**
@@ -40,6 +39,6 @@ export default class UIFeatureController extends SettingController {
}
public get settingDisabled(): boolean {
- return !SettingsStore.getValue(this.uiFeatureName);
+ return !this.settingsStore.getValue(this.uiFeatureName);
}
}
diff --git a/apps/web/src/slash-commands/SlashCommands.tsx b/apps/web/src/slash-commands/SlashCommands.tsx
index d34949a4bc..b91d2f4d32 100644
--- a/apps/web/src/slash-commands/SlashCommands.tsx
+++ b/apps/web/src/slash-commands/SlashCommands.tsx
@@ -55,7 +55,7 @@ import { type ViewRoomPayload } from "../dispatcher/payloads/ViewRoomPayload";
import { htmlSerializeFromMdIfNeeded } from "../editor/serialize";
import { leaveRoomBehaviour } from "../utils/leave-behaviour";
import { MatrixClientPeg } from "../MatrixClientPeg";
-import { isCurrentLocalRoom, reject, singleMxcUpload, success, successSync } from "./utils";
+import { isCurrentLocalRoom, reject, singleMxcUpload, success, successSync, splitAtFirstSpace } from "./utils";
import { deop, op } from "./op";
import { CommandCategories } from "./interface";
import { Command } from "./command";
@@ -892,26 +892,6 @@ interface ICmd {
args?: string;
}
-/**
- * Split the supplied string into one or two strings separated by the first
- * region of white space we can find.
- */
-export function splitAtFirstSpace(args: string): [string, string?] {
- const trimmedArgs = args.trim();
- const i = trimmedArgs.search(/\s+/);
- if (i === -1) {
- return [trimmedArgs];
- } else {
- const first = trimmedArgs.slice(0, i);
- const second = trimmedArgs.slice(i + 1).trimStart();
- if (second === "") {
- return [first];
- } else {
- return [first, second];
- }
- }
-}
-
/**
* Process the given text for /commands and returns a parsed command that can be used for running the operation.
* @param {string} roomId The room ID where the command was issued.
diff --git a/apps/web/src/slash-commands/status.ts b/apps/web/src/slash-commands/status.ts
index e19c73ec9d..6eb74a6777 100644
--- a/apps/web/src/slash-commands/status.ts
+++ b/apps/web/src/slash-commands/status.ts
@@ -7,9 +7,10 @@ Please see LICENSE files in the repository root for full details.
import { _td } from "@element-hq/web-shared-components";
-import { Command, CommandCategories, splitAtFirstSpace } from "./SlashCommands";
+import { Command } from "./command";
+import { CommandCategories } from "./interface";
import SettingsStore from "../settings/SettingsStore";
-import { reject, success } from "./utils";
+import { reject, success, splitAtFirstSpace } from "./utils";
import { UserFriendlyError } from "../languageHandler";
import { TimelineRenderingType } from "../contexts/RoomContext";
import { setUserStatus, userStatusTextWithinMaxLength } from "../utils/userStatus";
diff --git a/apps/web/src/slash-commands/utils.ts b/apps/web/src/slash-commands/utils.ts
index a96a324d5d..1ec60aecf6 100644
--- a/apps/web/src/slash-commands/utils.ts
+++ b/apps/web/src/slash-commands/utils.ts
@@ -76,3 +76,23 @@ export const isCurrentLocalRoom = (cli: MatrixClient | null): boolean => {
if (!room) return false;
return isLocalRoom(room);
};
+
+/**
+ * Split the supplied string into one or two strings separated by the first
+ * region of white space we can find.
+ */
+export function splitAtFirstSpace(args: string): [string, string?] {
+ const trimmedArgs = args.trim();
+ const i = trimmedArgs.search(/\s+/);
+ if (i === -1) {
+ return [trimmedArgs];
+ } else {
+ const first = trimmedArgs.slice(0, i);
+ const second = trimmedArgs.slice(i + 1).trimStart();
+ if (second === "") {
+ return [first];
+ } else {
+ return [first, second];
+ }
+ }
+}
diff --git a/apps/web/src/toasts/AnalyticsToast.tsx b/apps/web/src/toasts/AnalyticsToast.tsx
index 351ccdf4b2..40d4643e93 100644
--- a/apps/web/src/toasts/AnalyticsToast.tsx
+++ b/apps/web/src/toasts/AnalyticsToast.tsx
@@ -68,10 +68,6 @@ const onLearnMorePreviouslyOptedIn = (): void => {
const TOAST_KEY = "analytics";
-export function getPolicyUrl(): string | undefined {
- return SdkConfig.get("privacy_policy_url");
-}
-
export const showToast = (): void => {
const legacyAnalyticsOptIn = SettingsStore.getValue("analyticsOptIn", null, true);
diff --git a/apps/web/test/unit-tests/components/views/elements/Pill-test.tsx b/apps/web/test/unit-tests/components/views/elements/Pill-test.tsx
index f3a49d6734..2119021654 100644
--- a/apps/web/test/unit-tests/components/views/elements/Pill-test.tsx
+++ b/apps/web/test/unit-tests/components/views/elements/Pill-test.tsx
@@ -13,7 +13,8 @@ import { mocked, type Mocked } from "jest-mock";
import { type MatrixClient, type MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
import dis from "../../../../../src/dispatcher/dispatcher";
-import { Pill, type PillProps, PillType } from "../../../../../src/components/views/elements/Pill";
+import { Pill, type PillProps } from "../../../../../src/components/views/elements/Pill";
+import { PillType } from "../../../../../src/components/views/elements/PillType";
import {
filterConsole,
flushPromises,
diff --git a/apps/web/test/unit-tests/components/views/rooms/RoomKnocksBar-test.tsx b/apps/web/test/unit-tests/components/views/rooms/RoomKnocksBar-test.tsx
index fa818850dd..e1865eb080 100644
--- a/apps/web/test/unit-tests/components/views/rooms/RoomKnocksBar-test.tsx
+++ b/apps/web/test/unit-tests/components/views/rooms/RoomKnocksBar-test.tsx
@@ -21,7 +21,7 @@ import { KnownMembership } from "matrix-js-sdk/src/types";
import React from "react";
import ErrorDialog from "../../../../../src/components/views/dialogs/ErrorDialog";
-import { RoomSettingsTab } from "../../../../../src/components/views/dialogs/RoomSettingsDialog";
+import { RoomSettingsTab } from "../../../../../src/components/views/dialogs/RoomSettingsDialog-tab";
import { RoomKnocksBar } from "../../../../../src/components/views/rooms/RoomKnocksBar";
import MatrixClientContext from "../../../../../src/contexts/MatrixClientContext";
import dis from "../../../../../src/dispatcher/dispatcher";
diff --git a/apps/web/test/unit-tests/slash-commands/split-at-first-space-test.ts b/apps/web/test/unit-tests/slash-commands/utils.test.ts
similarity index 93%
rename from apps/web/test/unit-tests/slash-commands/split-at-first-space-test.ts
rename to apps/web/test/unit-tests/slash-commands/utils.test.ts
index 2bbbb87b3b..2ca3016425 100644
--- a/apps/web/test/unit-tests/slash-commands/split-at-first-space-test.ts
+++ b/apps/web/test/unit-tests/slash-commands/utils.test.ts
@@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details.
*/
-import { splitAtFirstSpace } from "../../../src/slash-commands/SlashCommands";
+import { splitAtFirstSpace } from "../../../src/slash-commands/utils";
describe("splitAtFirstSpace", () => {
it("should be able to split arguments at the first whitespace", () => {