Merge pull request #6381 from matrix-org/t3chguy/spacesperf

pull/21833/head
Michael Telatynski 2021-07-15 11:39:42 +01:00 committed by GitHub
commit 76022dc95f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 114 additions and 87 deletions

View File

@ -21,7 +21,7 @@ import { ResizeMethod } from "matrix-js-sdk/src/@types/partials";
import DMRoomMap from './utils/DMRoomMap';
import { mediaFromMxc } from "./customisations/Media";
import SettingsStore from "./settings/SettingsStore";
import SpaceStore from "./stores/SpaceStore";
// Not to be used for BaseAvatar urls as that has similar default avatar fallback already
export function avatarUrlForMember(
@ -153,7 +153,7 @@ export function avatarUrlForRoom(room: Room, width: number, height: number, resi
}
// space rooms cannot be DMs so skip the rest
if (SettingsStore.getValue("feature_spaces") && room.isSpaceRoom()) return null;
if (SpaceStore.spacesEnabled && room.isSpaceRoom()) return null;
let otherMember = null;
const otherUserId = DMRoomMap.shared().getUserIdForRoomId(room.roomId);

View File

@ -27,8 +27,8 @@ import EmojiProvider from './EmojiProvider';
import NotifProvider from './NotifProvider';
import { timeout } from "../utils/promise";
import AutocompleteProvider, { ICommand } from "./AutocompleteProvider";
import SettingsStore from "../settings/SettingsStore";
import SpaceProvider from "./SpaceProvider";
import SpaceStore from "../stores/SpaceStore";
export interface ISelectionRange {
beginning?: boolean; // whether the selection is in the first block of the editor or not
@ -58,8 +58,7 @@ const PROVIDERS = [
DuckDuckGoProvider,
];
// as the spaces feature is device configurable only, and toggling it refreshes the page, we can do this here
if (SettingsStore.getValue("feature_spaces")) {
if (SpaceStore.spacesEnabled) {
PROVIDERS.push(SpaceProvider);
} else {
PROVIDERS.push(CommunityProvider);

View File

@ -28,7 +28,7 @@ import { PillCompletion } from './Components';
import { makeRoomPermalink } from "../utils/permalinks/Permalinks";
import { ICompletion, ISelectionRange } from "./Autocompleter";
import RoomAvatar from '../components/views/avatars/RoomAvatar';
import SettingsStore from "../settings/SettingsStore";
import SpaceStore from "../stores/SpaceStore";
const ROOM_REGEX = /\B#\S*/g;
@ -59,7 +59,8 @@ export default class RoomProvider extends AutocompleteProvider {
const cli = MatrixClientPeg.get();
let rooms = cli.getVisibleRooms();
if (SettingsStore.getValue("feature_spaces")) {
// if spaces are enabled then filter them out here as they get their own autocomplete provider
if (SpaceStore.spacesEnabled) {
rooms = rooms.filter(r => !r.isSpaceRoom());
}

View File

@ -63,6 +63,7 @@ import ToastContainer from './ToastContainer';
import MyGroups from "./MyGroups";
import UserView from "./UserView";
import GroupView from "./GroupView";
import SpaceStore from "../../stores/SpaceStore";
// We need to fetch each pinned message individually (if we don't already have it)
// so each pinned message may trigger a request. Limit the number per room for sanity.
@ -631,7 +632,7 @@ class LoggedInView extends React.Component<IProps, IState> {
>
<ToastContainer />
<div ref={this._resizeContainer} className={bodyClasses}>
{ SettingsStore.getValue("feature_spaces") ? <SpacePanel /> : null }
{ SpaceStore.spacesEnabled ? <SpacePanel /> : null }
<LeftPanel
isMinimized={this.props.collapseLhs || false}
resizeNotifier={this.props.resizeNotifier}

View File

@ -1099,7 +1099,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
private leaveRoomWarnings(roomId: string) {
const roomToLeave = MatrixClientPeg.get().getRoom(roomId);
const isSpace = SettingsStore.getValue("feature_spaces") && roomToLeave?.isSpaceRoom();
const isSpace = SpaceStore.spacesEnabled && roomToLeave?.isSpaceRoom();
// Show a warning if there are additional complications.
const warnings = [];
@ -1137,7 +1137,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
const roomToLeave = MatrixClientPeg.get().getRoom(roomId);
const warnings = this.leaveRoomWarnings(roomId);
const isSpace = SettingsStore.getValue("feature_spaces") && roomToLeave?.isSpaceRoom();
const isSpace = SpaceStore.spacesEnabled && roomToLeave?.isSpaceRoom();
Modal.createTrackedDialog(isSpace ? "Leave space" : "Leave room", '', QuestionDialog, {
title: isSpace ? _t("Leave space") : _t("Leave room"),
description: (
@ -1687,7 +1687,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
const type = screen === "start_sso" ? "sso" : "cas";
PlatformPeg.get().startSingleSignOn(cli, type, this.getFragmentAfterLogin());
} else if (screen === 'groups') {
if (SettingsStore.getValue("feature_spaces")) {
if (SpaceStore.spacesEnabled) {
dis.dispatch({ action: "view_home_page" });
return;
}
@ -1774,7 +1774,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
subAction: params.action,
});
} else if (screen.indexOf('group/') === 0) {
if (SettingsStore.getValue("feature_spaces")) {
if (SpaceStore.spacesEnabled) {
dis.dispatch({ action: "view_home_page" });
return;
}

View File

@ -48,6 +48,7 @@ import NotificationPanel from "./NotificationPanel";
import ResizeNotifier from "../../utils/ResizeNotifier";
import PinnedMessagesCard from "../views/right_panel/PinnedMessagesCard";
import { throttle } from 'lodash';
import SpaceStore from "../../stores/SpaceStore";
interface IProps {
room?: Room; // if showing panels for a given room, this is set
@ -107,7 +108,7 @@ export default class RightPanel extends React.Component<IProps, IState> {
return RightPanelPhases.GroupMemberList;
}
return rps.groupPanelPhase;
} else if (SettingsStore.getValue("feature_spaces") && this.props.room?.isSpaceRoom()
} else if (SpaceStore.spacesEnabled && this.props.room?.isSpaceRoom()
&& !RIGHT_PANEL_SPACE_PHASES.includes(rps.roomPanelPhase)
) {
return RightPanelPhases.SpaceMemberList;

View File

@ -89,6 +89,7 @@ import RoomStatusBar from "./RoomStatusBar";
import MessageComposer from '../views/rooms/MessageComposer';
import JumpToBottomButton from "../views/rooms/JumpToBottomButton";
import TopUnreadMessagesBar from "../views/rooms/TopUnreadMessagesBar";
import SpaceStore from "../../stores/SpaceStore";
const DEBUG = false;
let debuglog = function(msg: string) {};
@ -1748,10 +1749,8 @@ export default class RoomView extends React.Component<IProps, IState> {
}
const myMembership = this.state.room.getMyMembership();
if (myMembership === "invite"
// SpaceRoomView handles invites itself
&& (!SettingsStore.getValue("feature_spaces") || !this.state.room.isSpaceRoom())
) {
// SpaceRoomView handles invites itself
if (myMembership === "invite" && (!SpaceStore.spacesEnabled || !this.state.room.isSpaceRoom())) {
if (this.state.joining || this.state.rejecting) {
return (
<ErrorBoundary>
@ -1882,7 +1881,7 @@ export default class RoomView extends React.Component<IProps, IState> {
room={this.state.room}
/>
);
if (!this.state.canPeek && (!SettingsStore.getValue("feature_spaces") || !this.state.room?.isSpaceRoom())) {
if (!this.state.canPeek && (!SpaceStore.spacesEnabled || !this.state.room?.isSpaceRoom())) {
return (
<div className="mx_RoomView">
{ previewBar }

View File

@ -62,7 +62,6 @@ import IconizedContextMenu, {
import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton";
import { BetaPill } from "../views/beta/BetaCard";
import { UserTab } from "../views/dialogs/UserSettingsDialog";
import SettingsStore from "../../settings/SettingsStore";
import Modal from "../../Modal";
import BetaFeedbackDialog from "../views/dialogs/BetaFeedbackDialog";
import SdkConfig from "../../SdkConfig";
@ -178,7 +177,7 @@ const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) =>
const [busy, setBusy] = useState(false);
const spacesEnabled = SettingsStore.getValue("feature_spaces");
const spacesEnabled = SpaceStore.spacesEnabled;
const cannotJoin = getEffectiveMembership(myMembership) === EffectiveMembership.Leave
&& space.getJoinRule() !== JoinRule.Public;
@ -854,7 +853,7 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
private renderBody() {
switch (this.state.phase) {
case Phase.Landing:
if (this.state.myMembership === "join" && SettingsStore.getValue("feature_spaces")) {
if (this.state.myMembership === "join" && SpaceStore.spacesEnabled) {
return <SpaceLanding space={this.props.space} />;
} else {
return <SpacePreview

View File

@ -90,7 +90,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
};
OwnProfileStore.instance.on(UPDATE_EVENT, this.onProfileUpdate);
if (SettingsStore.getValue("feature_spaces")) {
if (SpaceStore.spacesEnabled) {
SpaceStore.instance.on(UPDATE_SELECTED_SPACE, this.onSelectedSpaceUpdate);
}
@ -115,7 +115,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
if (this.dispatcherRef) defaultDispatcher.unregister(this.dispatcherRef);
OwnProfileStore.instance.off(UPDATE_EVENT, this.onProfileUpdate);
this.tagStoreRef.remove();
if (SettingsStore.getValue("feature_spaces")) {
if (SpaceStore.spacesEnabled) {
SpaceStore.instance.off(UPDATE_SELECTED_SPACE, this.onSelectedSpaceUpdate);
}
MatrixClientPeg.get().removeListener("Room", this.onRoom);

View File

@ -105,7 +105,7 @@ const BetaCard = ({ title: titleOverride, featureId }: IProps) => {
</div>
<img src={image} alt="" />
</div>
{ extraSettings && <div className="mx_BetaCard_relatedSettings">
{ extraSettings && value && <div className="mx_BetaCard_relatedSettings">
{ extraSettings.map(key => (
<SettingsFlag key={key} name={key} level={SettingLevel.DEVICE} />
)) }

View File

@ -43,6 +43,7 @@ import QueryMatcher from "../../../autocomplete/QueryMatcher";
import TruncatedList from "../elements/TruncatedList";
import EntityTile from "../rooms/EntityTile";
import BaseAvatar from "../avatars/BaseAvatar";
import SpaceStore from "../../../stores/SpaceStore";
const AVATAR_SIZE = 30;
@ -180,7 +181,7 @@ const ForwardDialog: React.FC<IProps> = ({ matrixClient: cli, event, permalinkCr
const [query, setQuery] = useState("");
const lcQuery = query.toLowerCase();
const spacesEnabled = useFeatureEnabled("feature_spaces");
const spacesEnabled = SpaceStore.spacesEnabled;
const flairEnabled = useFeatureEnabled(UIFeature.Flair);
const previewLayout = useSettingValue<Layout>("layout");

View File

@ -71,6 +71,7 @@ import QuestionDialog from "./QuestionDialog";
import Spinner from "../elements/Spinner";
import BaseDialog from "./BaseDialog";
import DialPadBackspaceButton from "../elements/DialPadBackspaceButton";
import SpaceStore from "../../../stores/SpaceStore";
// we have a number of types defined from the Matrix spec which can't reasonably be altered here.
/* eslint-disable camelcase */
@ -1407,7 +1408,7 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
</div>;
} else if (this.props.kind === KIND_INVITE) {
const room = MatrixClientPeg.get()?.getRoom(this.props.roomId);
const isSpace = SettingsStore.getValue("feature_spaces") && room?.isSpaceRoom();
const isSpace = SpaceStore.spacesEnabled && room?.isSpaceRoom();
title = isSpace
? _t("Invite to %(spaceName)s", {
spaceName: room.name || _t("Unnamed Space"),

View File

@ -69,6 +69,7 @@ import RoomName from "../elements/RoomName";
import { mediaFromMxc } from "../../../customisations/Media";
import UIStore from "../../../stores/UIStore";
import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInsertPayload";
import SpaceStore from "../../../stores/SpaceStore";
export interface IDevice {
deviceId: string;
@ -728,7 +729,7 @@ const MuteToggleButton: React.FC<IBaseRoomProps> = ({ member, room, powerLevels,
// if muting self, warn as it may be irreversible
if (target === cli.getUserId()) {
try {
if (!(await warnSelfDemote(SettingsStore.getValue("feature_spaces") && room?.isSpaceRoom()))) return;
if (!(await warnSelfDemote(SpaceStore.spacesEnabled && room?.isSpaceRoom()))) return;
} catch (e) {
console.error("Failed to warn about self demotion: ", e);
return;
@ -817,7 +818,7 @@ const RoomAdminToolsContainer: React.FC<IBaseRoomProps> = ({
if (canAffectUser && me.powerLevel >= kickPowerLevel) {
kickButton = <RoomKickButton member={member} startUpdating={startUpdating} stopUpdating={stopUpdating} />;
}
if (me.powerLevel >= redactPowerLevel && (!SettingsStore.getValue("feature_spaces") || !room.isSpaceRoom())) {
if (me.powerLevel >= redactPowerLevel && (!SpaceStore.spacesEnabled || !room.isSpaceRoom())) {
redactButton = (
<RedactMessagesButton member={member} startUpdating={startUpdating} stopUpdating={stopUpdating} />
);
@ -1096,7 +1097,7 @@ const PowerLevelEditor: React.FC<{
} else if (myUserId === target) {
// If we are changing our own PL it can only ever be decreasing, which we cannot reverse.
try {
if (!(await warnSelfDemote(SettingsStore.getValue("feature_spaces") && room?.isSpaceRoom()))) return;
if (!(await warnSelfDemote(SpaceStore.spacesEnabled && room?.isSpaceRoom()))) return;
} catch (e) {
console.error("Failed to warn about self demotion: ", e);
}
@ -1326,10 +1327,10 @@ const BasicUserInfo: React.FC<{
if (!isRoomEncrypted) {
if (!cryptoEnabled) {
text = _t("This client does not support end-to-end encryption.");
} else if (room && (!SettingsStore.getValue("feature_spaces") || !room.isSpaceRoom())) {
} else if (room && (!SpaceStore.spacesEnabled || !room.isSpaceRoom())) {
text = _t("Messages in this room are not end-to-end encrypted.");
}
} else if (!SettingsStore.getValue("feature_spaces") || !room.isSpaceRoom()) {
} else if (!SpaceStore.spacesEnabled || !room.isSpaceRoom()) {
text = _t("Messages in this room are end-to-end encrypted.");
}
@ -1405,7 +1406,7 @@ const BasicUserInfo: React.FC<{
canInvite={roomPermissions.canInvite}
isIgnored={isIgnored}
member={member as RoomMember}
isSpace={SettingsStore.getValue("feature_spaces") && room?.isSpaceRoom()}
isSpace={SpaceStore.spacesEnabled && room?.isSpaceRoom()}
/>
{ adminToolsContainer }
@ -1568,7 +1569,7 @@ const UserInfo: React.FC<IProps> = ({
previousPhase = RightPanelPhases.RoomMemberInfo;
refireParams = { member: member };
} else if (room) {
previousPhase = previousPhase = SettingsStore.getValue("feature_spaces") && room.isSpaceRoom()
previousPhase = previousPhase = SpaceStore.spacesEnabled && room.isSpaceRoom()
? RightPanelPhases.SpaceMemberList
: RightPanelPhases.RoomMemberList;
}
@ -1617,7 +1618,7 @@ const UserInfo: React.FC<IProps> = ({
}
let scopeHeader;
if (SettingsStore.getValue("feature_spaces") && room?.isSpaceRoom()) {
if (SpaceStore.spacesEnabled && room?.isSpaceRoom()) {
scopeHeader = <div className="mx_RightPanel_scopeHeader">
<RoomAvatar room={room} height={32} width={32} />
<RoomName room={room} />

View File

@ -43,6 +43,7 @@ import EntityTile from "./EntityTile";
import MemberTile from "./MemberTile";
import BaseAvatar from '../avatars/BaseAvatar';
import { throttle } from 'lodash';
import SpaceStore from "../../../stores/SpaceStore";
const INITIAL_LOAD_NUM_MEMBERS = 30;
const INITIAL_LOAD_NUM_INVITED = 5;
@ -509,7 +510,7 @@ export default class MemberList extends React.Component<IProps, IState> {
const chat = CommunityPrototypeStore.instance.getSelectedCommunityGeneralChat();
if (chat && chat.roomId === this.props.roomId) {
inviteButtonText = _t("Invite to this community");
} else if (SettingsStore.getValue("feature_spaces") && room.isSpaceRoom()) {
} else if (SpaceStore.spacesEnabled && room.isSpaceRoom()) {
inviteButtonText = _t("Invite to this space");
}
@ -549,7 +550,7 @@ export default class MemberList extends React.Component<IProps, IState> {
let previousPhase = RightPanelPhases.RoomSummary;
// We have no previousPhase for when viewing a MemberList from a Space
let scopeHeader;
if (SettingsStore.getValue("feature_spaces") && room?.isSpaceRoom()) {
if (SpaceStore.spacesEnabled && room?.isSpaceRoom()) {
previousPhase = undefined;
scopeHeader = <div className="mx_RightPanel_scopeHeader">
<RoomAvatar room={room} height={32} width={32} />

View File

@ -417,7 +417,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
}
private renderCommunityInvites(): ReactComponentElement<typeof ExtraTile>[] {
if (SettingsStore.getValue("feature_spaces")) return [];
if (SpaceStore.spacesEnabled) return [];
// TODO: Put community invites in a more sensible place (not in the room list)
// See https://github.com/vector-im/element-web/issues/14456
return MatrixClientPeg.get().getGroups().filter(g => {

View File

@ -25,9 +25,9 @@ import { isValid3pidInvite } from "../../../RoomInvite";
import RoomAvatar from "../avatars/RoomAvatar";
import RoomName from "../elements/RoomName";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import SettingsStore from "../../../settings/SettingsStore";
import ErrorDialog from '../dialogs/ErrorDialog';
import AccessibleButton from '../elements/AccessibleButton';
import SpaceStore from "../../../stores/SpaceStore";
interface IProps {
event: MatrixEvent;
@ -134,7 +134,7 @@ export default class ThirdPartyMemberInfo extends React.Component<IProps, IState
}
let scopeHeader;
if (SettingsStore.getValue("feature_spaces") && this.room.isSpaceRoom()) {
if (SpaceStore.spacesEnabled && this.room.isSpaceRoom()) {
scopeHeader = <div className="mx_RightPanel_scopeHeader">
<RoomAvatar room={this.room} height={32} width={32} />
<RoomName room={this.room} />

View File

@ -42,7 +42,6 @@ import {
import { Key } from "../../../Keyboard";
import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore";
import { NotificationState } from "../../../stores/notifications/NotificationState";
import SettingsStore from "../../../settings/SettingsStore";
interface IButtonProps {
space?: Room;
@ -134,7 +133,7 @@ const InnerSpacePanel = React.memo<IInnerSpacePanelProps>(({ children, isPanelCo
const [invites, spaces, activeSpace] = useSpaces();
const activeSpaces = activeSpace ? [activeSpace] : [];
const homeNotificationState = SettingsStore.getValue("feature_spaces.all_rooms")
const homeNotificationState = SpaceStore.spacesTweakAllRoomsEnabled
? RoomNotificationStateStore.instance.globalState : SpaceStore.instance.getNotificationState(HOME_SPACE);
return <div className="mx_SpaceTreeLevel">
@ -142,7 +141,7 @@ const InnerSpacePanel = React.memo<IInnerSpacePanelProps>(({ children, isPanelCo
className="mx_SpaceButton_home"
onClick={() => SpaceStore.instance.setActiveSpace(null)}
selected={!activeSpace}
tooltip={SettingsStore.getValue("feature_spaces.all_rooms") ? _t("All rooms") : _t("Home")}
tooltip={SpaceStore.spacesTweakAllRoomsEnabled ? _t("All rooms") : _t("Home")}
notificationState={homeNotificationState}
isNarrow={isPanelCollapsed}
/>

View File

@ -22,6 +22,7 @@ import defaultDispatcher from "../dispatcher/dispatcher";
import { arrayHasDiff } from "../utils/arrays";
import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
import { SettingLevel } from "../settings/SettingLevel";
import SpaceStore from "./SpaceStore";
const MAX_ROOMS = 20; // arbitrary
const AUTOJOIN_WAIT_THRESHOLD_MS = 90000; // 90s, the time we wait for an autojoined room to show up
@ -122,7 +123,7 @@ export class BreadcrumbsStore extends AsyncStoreWithClient<IState> {
}
private async appendRoom(room: Room) {
if (SettingsStore.getValue("feature_spaces") && room.isSpaceRoom()) return; // hide space rooms
if (SpaceStore.spacesEnabled && room.isSpaceRoom()) return; // hide space rooms
let updated = false;
const rooms = (this.state.rooms || []).slice(); // cheap clone

View File

@ -59,7 +59,13 @@ export interface ISuggestedRoom extends ISpaceSummaryRoom {
const MAX_SUGGESTED_ROOMS = 20;
const homeSpaceKey = SettingsStore.getValue("feature_spaces.all_rooms") ? "ALL_ROOMS" : "HOME_SPACE";
// All of these settings cause the page to reload and can be costly if read frequently, so read them here only
const spacesEnabled = SettingsStore.getValue("feature_spaces");
const spacesTweakAllRoomsEnabled = SettingsStore.getValue("feature_spaces.all_rooms");
const spacesTweakSpaceMemberDMsEnabled = SettingsStore.getValue("feature_spaces.space_member_dms");
const spacesTweakSpaceDMBadgesEnabled = SettingsStore.getValue("feature_spaces.space_dm_badges");
const homeSpaceKey = spacesTweakAllRoomsEnabled ? "ALL_ROOMS" : "HOME_SPACE";
const getSpaceContextKey = (space?: Room) => `mx_space_context_${space?.roomId || homeSpaceKey}`;
const partitionSpacesAndRooms = (arr: Room[]): [Room[], Room[]] => { // [spaces, rooms]
@ -260,7 +266,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
}
public getSpaceFilteredRoomIds = (space: Room | null): Set<string> => {
if (!space && SettingsStore.getValue("feature_spaces.all_rooms")) {
if (!space && spacesTweakAllRoomsEnabled) {
return new Set(this.matrixClient.getVisibleRooms().map(r => r.roomId));
}
return this.spaceFilteredRooms.get(space?.roomId || HOME_SPACE) || new Set();
@ -357,7 +363,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
};
private showInHomeSpace = (room: Room) => {
if (SettingsStore.getValue("feature_spaces.all_rooms")) return true;
if (spacesTweakAllRoomsEnabled) return true;
if (room.isSpaceRoom()) return false;
return !this.parentMap.get(room.roomId)?.size // put all orphaned rooms in the Home Space
|| DMRoomMap.shared().getUserIdForRoomId(room.roomId) // put all DMs in the Home Space
@ -389,7 +395,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
const oldFilteredRooms = this.spaceFilteredRooms;
this.spaceFilteredRooms = new Map();
if (!SettingsStore.getValue("feature_spaces.all_rooms")) {
if (!spacesTweakAllRoomsEnabled) {
// put all room invites in the Home Space
const invites = visibleRooms.filter(r => !r.isSpaceRoom() && r.getMyMembership() === "invite");
this.spaceFilteredRooms.set(HOME_SPACE, new Set<string>(invites.map(room => room.roomId)));
@ -416,7 +422,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
const roomIds = new Set(childRooms.map(r => r.roomId));
const space = this.matrixClient?.getRoom(spaceId);
if (SettingsStore.getValue("feature_spaces.space_member_dms")) {
if (spacesTweakSpaceMemberDMsEnabled) {
// Add relevant DMs
space?.getMembers().forEach(member => {
if (member.membership !== "join" && member.membership !== "invite") return;
@ -450,7 +456,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
// Update NotificationStates
this.getNotificationState(s)?.setRooms(visibleRooms.filter(room => {
if (roomIds.has(room.roomId)) {
if (s !== HOME_SPACE && SettingsStore.getValue("feature_spaces.space_dm_badges")) return true;
if (s !== HOME_SPACE && spacesTweakSpaceDMBadgesEnabled) return true;
return !DMRoomMap.shared().getUserIdForRoomId(room.roomId)
|| RoomListStore.instance.getTagsForRoom(room).includes(DefaultTagID.Favourite);
@ -549,7 +555,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
// TODO confirm this after implementing parenting behaviour
if (room.isSpaceRoom()) {
this.onSpaceUpdate();
} else if (!SettingsStore.getValue("feature_spaces.all_rooms")) {
} else if (!spacesTweakAllRoomsEnabled) {
this.onRoomUpdate(room);
}
this.emit(room.roomId);
@ -573,7 +579,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
if (order !== lastOrder) {
this.notifyIfOrderChanged();
}
} else if (ev.getType() === EventType.Tag && !SettingsStore.getValue("feature_spaces.all_rooms")) {
} else if (ev.getType() === EventType.Tag && !spacesTweakAllRoomsEnabled) {
// If the room was in favourites and now isn't or the opposite then update its position in the trees
const oldTags = lastEv?.getContent()?.tags || {};
const newTags = ev.getContent()?.tags || {};
@ -613,13 +619,13 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
}
protected async onNotReady() {
if (!SettingsStore.getValue("feature_spaces")) return;
if (!SpaceStore.spacesEnabled) return;
if (this.matrixClient) {
this.matrixClient.removeListener("Room", this.onRoom);
this.matrixClient.removeListener("Room.myMembership", this.onRoom);
this.matrixClient.removeListener("Room.accountData", this.onRoomAccountData);
this.matrixClient.removeListener("RoomState.events", this.onRoomState);
if (!SettingsStore.getValue("feature_spaces.all_rooms")) {
if (!spacesTweakAllRoomsEnabled) {
this.matrixClient.removeListener("accountData", this.onAccountData);
}
}
@ -627,12 +633,12 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
}
protected async onReady() {
if (!SettingsStore.getValue("feature_spaces")) return;
if (!spacesEnabled) return;
this.matrixClient.on("Room", this.onRoom);
this.matrixClient.on("Room.myMembership", this.onRoom);
this.matrixClient.on("Room.accountData", this.onRoomAccountData);
this.matrixClient.on("RoomState.events", this.onRoomState);
if (!SettingsStore.getValue("feature_spaces.all_rooms")) {
if (!spacesTweakAllRoomsEnabled) {
this.matrixClient.on("accountData", this.onAccountData);
}
@ -646,7 +652,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
}
protected async onAction(payload: ActionPayload) {
if (!SettingsStore.getValue("feature_spaces")) return;
if (!spacesEnabled) return;
switch (payload.action) {
case "view_room": {
// Don't auto-switch rooms when reacting to a context-switch
@ -660,7 +666,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
// as it will cause you to end up in the wrong room
this.setActiveSpace(room, false);
} else if (
(!SettingsStore.getValue("feature_spaces.all_rooms") || this.activeSpace) &&
(!spacesTweakAllRoomsEnabled || this.activeSpace) &&
!this.getSpaceFilteredRoomIds(this.activeSpace).has(roomId)
) {
this.switchToRelatedSpace(roomId);
@ -752,6 +758,11 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
}
export default class SpaceStore {
public static spacesEnabled = spacesEnabled;
public static spacesTweakAllRoomsEnabled = spacesTweakAllRoomsEnabled;
public static spacesTweakSpaceMemberDMsEnabled = spacesTweakSpaceMemberDMsEnabled;
public static spacesTweakSpaceDMBadgesEnabled = spacesTweakSpaceDMBadgesEnabled;
private static internalInstance = new SpaceStoreClass();
public static get instance(): SpaceStoreClass {

View File

@ -35,6 +35,7 @@ import { NameFilterCondition } from "./filters/NameFilterCondition";
import { RoomNotificationStateStore } from "../notifications/RoomNotificationStateStore";
import { VisibilityProvider } from "./filters/VisibilityProvider";
import { SpaceWatcher } from "./SpaceWatcher";
import SpaceStore from "../SpaceStore";
interface IState {
tagsEnabled?: boolean;
@ -76,7 +77,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
}
private setupWatchers() {
if (SettingsStore.getValue("feature_spaces")) {
if (SpaceStore.spacesEnabled) {
this.spaceWatcher = new SpaceWatcher(this);
} else {
this.tagWatcher = new TagWatcher(this);
@ -608,9 +609,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
// if spaces are enabled only consider the prefilter conditions when there are no runtime conditions
// for the search all spaces feature
if (this.prefilterConditions.length > 0
&& (!SettingsStore.getValue("feature_spaces") || !this.filterConditions.length)
) {
if (this.prefilterConditions.length > 0 && (!SpaceStore.spacesEnabled || !this.filterConditions.length)) {
rooms = rooms.filter(r => {
for (const filter of this.prefilterConditions) {
if (!filter.isVisible(r)) {
@ -682,7 +681,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
} else {
this.filterConditions.push(filter);
// Runtime filters with spaces disable prefiltering for the search all spaces feature
if (SettingsStore.getValue("feature_spaces")) {
if (SpaceStore.spacesEnabled) {
// this has to be awaited so that `setKnownRooms` is called in time for the `addFilterCondition` below
// this way the runtime filters are only evaluated on one dataset and not both.
await this.recalculatePrefiltering();
@ -715,7 +714,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
this.algorithm.removeFilterCondition(filter);
}
// Runtime filters with spaces disable prefiltering for the search all spaces feature
if (SettingsStore.getValue("feature_spaces")) {
if (SpaceStore.spacesEnabled) {
promise = this.recalculatePrefiltering();
}
}

View File

@ -19,7 +19,6 @@ import { Room } from "matrix-js-sdk/src/models/room";
import { RoomListStoreClass } from "./RoomListStore";
import { SpaceFilterCondition } from "./filters/SpaceFilterCondition";
import SpaceStore, { UPDATE_SELECTED_SPACE } from "../SpaceStore";
import SettingsStore from "../../settings/SettingsStore";
/**
* Watches for changes in spaces to manage the filter on the provided RoomListStore
@ -29,7 +28,7 @@ export class SpaceWatcher {
private activeSpace: Room = SpaceStore.instance.activeSpace;
constructor(private store: RoomListStoreClass) {
if (!SettingsStore.getValue("feature_spaces.all_rooms")) {
if (!SpaceStore.spacesTweakAllRoomsEnabled) {
this.filter = new SpaceFilterCondition();
this.updateFilter();
store.addFilter(this.filter);
@ -41,7 +40,7 @@ export class SpaceWatcher {
this.activeSpace = activeSpace;
if (this.filter) {
if (activeSpace || !SettingsStore.getValue("feature_spaces.all_rooms")) {
if (activeSpace || !SpaceStore.spacesTweakAllRoomsEnabled) {
this.updateFilter();
} else {
this.store.removeFilter(this.filter);

View File

@ -34,6 +34,7 @@ import { OrderingAlgorithm } from "./list-ordering/OrderingAlgorithm";
import { getListAlgorithmInstance } from "./list-ordering";
import SettingsStore from "../../../settings/SettingsStore";
import { VisibilityProvider } from "../filters/VisibilityProvider";
import SpaceStore from "../../SpaceStore";
/**
* Fired when the Algorithm has determined a list has been updated.
@ -199,7 +200,7 @@ export class Algorithm extends EventEmitter {
}
private async doUpdateStickyRoom(val: Room) {
if (SettingsStore.getValue("feature_spaces") && val?.isSpaceRoom() && val.getMyMembership() !== "invite") {
if (SpaceStore.spacesEnabled && val?.isSpaceRoom() && val.getMyMembership() !== "invite") {
// no-op sticky rooms for spaces - they're effectively virtual rooms
val = null;
}

View File

@ -18,7 +18,7 @@ import { Room } from "matrix-js-sdk/src/models/room";
import CallHandler from "../../../CallHandler";
import { RoomListCustomisations } from "../../../customisations/RoomList";
import VoipUserMapper from "../../../VoipUserMapper";
import SettingsStore from "../../../settings/SettingsStore";
import SpaceStore from "../../SpaceStore";
export class VisibilityProvider {
private static internalInstance: VisibilityProvider;
@ -50,7 +50,7 @@ export class VisibilityProvider {
}
// hide space rooms as they'll be shown in the SpacePanel
if (SettingsStore.getValue("feature_spaces") && room.isSpaceRoom()) {
if (SpaceStore.spacesEnabled && room.isSpaceRoom()) {
return false;
}

View File

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import "../skinned-sdk"; // Must be first for skinning to work
import { getLineAndNodePosition } from "../../src/editor/caret";
import EditorModel from "../../src/editor/model";
import { createPartCreator } from "./mock";

View File

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import "../skinned-sdk"; // Must be first for skinning to work
import EditorModel from "../../src/editor/model";
import { createPartCreator, createRenderer } from "./mock";

View File

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import "../skinned-sdk"; // Must be first for skinning to work
import EditorModel from "../../src/editor/model";
import { createPartCreator, createRenderer } from "./mock";
import { toggleInlineFormat } from "../../src/editor/operations";

View File

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import "../skinned-sdk"; // Must be first for skinning to work
import EditorModel from "../../src/editor/model";
import { createPartCreator } from "./mock";

View File

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import "../skinned-sdk"; // Must be first for skinning to work
import EditorModel from "../../src/editor/model";
import { createPartCreator, createRenderer } from "./mock";

View File

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import "../skinned-sdk"; // Must be first for skinning to work
import EditorModel from "../../src/editor/model";
import { htmlSerializeIfNeeded } from "../../src/editor/serialize";
import { createPartCreator } from "./mock";

View File

@ -0,0 +1,23 @@
/*
Copyright 2021 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.
*/
// This needs to be executed before the SpaceStore gets imported but due to ES6 import hoisting we have to do this here.
// SpaceStore reads the SettingsStore which needs the localStorage values set at init time.
localStorage.setItem("mx_labs_feature_feature_spaces", "true");
localStorage.setItem("mx_labs_feature_feature_spaces.all_rooms", "true");
localStorage.setItem("mx_labs_feature_feature_spaces.space_member_dms", "true");
localStorage.setItem("mx_labs_feature_feature_spaces.space_dm_badges", "false");

View File

@ -16,7 +16,9 @@ limitations under the License.
import { EventEmitter } from "events";
import { EventType } from "matrix-js-sdk/src/@types/event";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import "./SpaceStore-setup"; // enable space lab
import "../skinned-sdk"; // Must be first for skinning to work
import SpaceStore, {
UPDATE_INVITED_SPACES,
@ -26,13 +28,10 @@ import SpaceStore, {
import { resetAsyncStoreWithClient, setupAsyncStoreWithClient } from "../utils/test-utils";
import { mkEvent, mkStubRoom, stubClient } from "../test-utils";
import { EnhancedMap } from "../../src/utils/maps";
import SettingsStore from "../../src/settings/SettingsStore";
import DMRoomMap from "../../src/utils/DMRoomMap";
import { MatrixClientPeg } from "../../src/MatrixClientPeg";
import defaultDispatcher from "../../src/dispatcher/dispatcher";
type MatrixEvent = any; // importing from js-sdk upsets things
jest.useFakeTimers();
const mockStateEventImplementation = (events: MatrixEvent[]) => {
@ -79,9 +78,6 @@ const mkSpace = (spaceId: string, children: string[] = []) => {
return space;
};
const getValue = jest.fn();
SettingsStore.getValue = getValue;
const getUserIdForRoomId = jest.fn();
// @ts-ignore
DMRoomMap.sharedInstance = { getUserIdForRoomId };
@ -122,18 +118,6 @@ describe("SpaceStore", () => {
beforeEach(() => {
jest.runAllTimers();
client.getVisibleRooms.mockReturnValue(rooms = []);
getValue.mockImplementation(settingName => {
switch (settingName) {
case "feature_spaces":
return true;
case "feature_spaces.all_rooms":
return true;
case "feature_spaces.space_member_dms":
return true;
case "feature_spaces.space_dm_badges":
return false;
}
});
});
afterEach(async () => {
await resetAsyncStoreWithClient(store);