Add ability to explore and join space rooms
authorajbura <ajbura@gmail.com>
Wed, 16 Feb 2022 14:55:36 +0000 (20:25 +0530)
committerajbura <ajbura@gmail.com>
Wed, 16 Feb 2022 14:55:36 +0000 (20:25 +0530)
Signed-off-by: ajbura <ajbura@gmail.com>
src/app/molecules/space-options/SpaceOptions.jsx
src/app/organisms/pw/Windows.jsx
src/app/organisms/space-manage/SpaceManage.jsx [new file with mode: 0644]
src/app/organisms/space-manage/SpaceManage.scss [new file with mode: 0644]
src/app/organisms/space-settings/SpaceSettings.jsx
src/client/action/navigation.js
src/client/state/cons.js
src/client/state/navigation.js

index a1f0c6bb5437f73691111ae48db1200703ca5bae..cb69e180114c1ac29fea7b8f14c7caa0690fb8b0 100644 (file)
@@ -4,13 +4,14 @@ import PropTypes from 'prop-types';
 import { twemojify } from '../../../util/twemojify';
 
 import initMatrix from '../../../client/initMatrix';
-import { openSpaceSettings, openInviteUser } from '../../../client/action/navigation';
+import { openSpaceSettings, openSpaceManage, openInviteUser } from '../../../client/action/navigation';
 import { leave, createSpaceShortcut, deleteSpaceShortcut } from '../../../client/action/room';
 
 import { MenuHeader, MenuItem } from '../../atoms/context-menu/ContextMenu';
 
 import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg';
 import SettingsIC from '../../../../public/res/ic/outlined/settings.svg';
+import HashSearchIC from '../../../../public/res/ic/outlined/hash-search.svg';
 import LeaveArrowIC from '../../../../public/res/ic/outlined/leave-arrow.svg';
 import PinIC from '../../../../public/res/ic/outlined/pin.svg';
 import PinFilledIC from '../../../../public/res/ic/filled/pin.svg';
@@ -35,6 +36,10 @@ function SpaceOptions({ roomId, afterOptionSelect }) {
     openSpaceSettings(roomId);
     afterOptionSelect();
   };
+  const handleManageRoom = () => {
+    openSpaceManage(roomId);
+    afterOptionSelect();
+  };
 
   const handleLeaveClick = () => {
     if (confirm('Are you really want to leave this space?')) {
@@ -59,6 +64,7 @@ function SpaceOptions({ roomId, afterOptionSelect }) {
       >
         Invite
       </MenuItem>
+      <MenuItem onClick={handleManageRoom} iconSrc={HashSearchIC}>Manage rooms</MenuItem>
       <MenuItem onClick={handleSettingsClick} iconSrc={SettingsIC}>Settings</MenuItem>
       <MenuItem
         variant="danger"
index 692f2e14270089a4d7ef43100f3e30923ebe63bc..b1669a14977c789e878f0868a1fc96b870e9b0a6 100644 (file)
@@ -9,6 +9,7 @@ import CreateRoom from '../create-room/CreateRoom';
 import InviteUser from '../invite-user/InviteUser';
 import Settings from '../settings/Settings';
 import SpaceSettings from '../space-settings/SpaceSettings';
+import SpaceManage from '../space-manage/SpaceManage';
 
 function Windows() {
   const [isInviteList, changeInviteList] = useState(false);
@@ -85,6 +86,7 @@ function Windows() {
         onRequestClose={() => changeSettings(false)}
       />
       <SpaceSettings />
+      <SpaceManage />
     </>
   );
 }
diff --git a/src/app/organisms/space-manage/SpaceManage.jsx b/src/app/organisms/space-manage/SpaceManage.jsx
new file mode 100644 (file)
index 0000000..fd275b3
--- /dev/null
@@ -0,0 +1,352 @@
+/* eslint-disable react/prop-types */
+import React, { useState, useEffect } from 'react';
+import PropTypes from 'prop-types';
+import './SpaceManage.scss';
+
+import { twemojify } from '../../../util/twemojify';
+
+import initMatrix from '../../../client/initMatrix';
+import cons from '../../../client/state/cons';
+import navigation from '../../../client/state/navigation';
+import colorMXID from '../../../util/colorMXID';
+import { selectRoom, selectTab } from '../../../client/action/navigation';
+import RoomsHierarchy from '../../../client/state/RoomsHierarchy';
+import { joinRuleToIconSrc } from '../../../util/matrixUtil';
+import { join } from '../../../client/action/room';
+
+import Text from '../../atoms/text/Text';
+import RawIcon from '../../atoms/system-icons/RawIcon';
+import Button from '../../atoms/button/Button';
+import IconButton from '../../atoms/button/IconButton';
+import Checkbox from '../../atoms/button/Checkbox';
+import Avatar from '../../atoms/avatar/Avatar';
+import Spinner from '../../atoms/spinner/Spinner';
+import ScrollView from '../../atoms/scroll/ScrollView';
+import PopupWindow from '../../molecules/popup-window/PopupWindow';
+
+import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
+import ChevronRightIC from '../../../../public/res/ic/outlined/chevron-right.svg';
+import InfoIC from '../../../../public/res/ic/outlined/info.svg';
+
+import { useForceUpdate } from '../../hooks/useForceUpdate';
+import { useStore } from '../../hooks/useStore';
+
+function SpaceManageBreadcrumb({ path, onSelect }) {
+  return (
+    <div className="space-manage-breadcrumb__wrapper">
+      <ScrollView horizontal vertical={false} invisible>
+        <div className="space-manage-breadcrumb">
+          {
+            path.map((item, index) => (
+              <React.Fragment key={item.roomId}>
+                {index > 0 && <RawIcon size="extra-small" src={ChevronRightIC} />}
+                <Button onClick={() => onSelect(item.roomId, item.name)}>
+                  <Text variant="b2">{twemojify(item.name)}</Text>
+                </Button>
+              </React.Fragment>
+            ))
+          }
+        </div>
+      </ScrollView>
+    </div>
+  );
+}
+SpaceManageBreadcrumb.propTypes = {
+  path: PropTypes.arrayOf(PropTypes.exact({
+    roomId: PropTypes.string,
+    name: PropTypes.string,
+  })).isRequired,
+  onSelect: PropTypes.func.isRequired,
+};
+
+function SpaceManageItem({
+  parentId, roomInfo, onSpaceClick, requestClose,
+  isSelected, onSelect, roomHierarchy,
+}) {
+  const [isExpand, setIsExpand] = useState(false);
+  const [isJoining, setIsJoining] = useState(false);
+
+  const { directs } = initMatrix.roomList;
+  const mx = initMatrix.matrixClient;
+  const parentRoom = mx.getRoom(parentId);
+  const canManage = parentRoom?.currentState.maySendStateEvent('m.space.child', mx.getUserId()) || false;
+
+  const isSpace = roomInfo.room_type === 'm.space';
+  const roomId = roomInfo.room_id;
+  const room = mx.getRoom(roomId);
+  const isJoined = !!(room?.getMyMembership() === 'join' || null);
+  const name = room?.name || roomInfo.name || roomInfo.canonical_alias || roomId;
+  let imageSrc = mx.mxcUrlToHttp(roomInfo.avatar_url, 24, 24, 'crop') || null;
+  if (!imageSrc && room) {
+    imageSrc = room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null;
+    if (imageSrc === null) imageSrc = room.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null;
+  }
+
+  const handleOpen = () => {
+    if (isSpace) selectTab(roomId);
+    else selectRoom(roomId);
+    requestClose();
+  };
+  const handleJoin = () => {
+    const viaSet = roomHierarchy.viaMap.get(roomId);
+    const via = viaSet ? [...viaSet] : undefined;
+    join(roomId, false, via);
+    setIsJoining(true);
+  };
+
+  const roomAvatarJSX = (
+    <Avatar
+      text={name}
+      bgColor={colorMXID(roomId)}
+      imageSrc={directs.has(roomId) ? imageSrc : null}
+      iconColor="var(--ic-surface-low)"
+      iconSrc={joinRuleToIconSrc(roomInfo.join_rule, isSpace)}
+      size="extra-small"
+    />
+  );
+  const roomNameJSX = (
+    <Text>
+      {twemojify(name)}
+      <Text variant="b3" span>{` • ${roomInfo.num_joined_members} members`}</Text>
+    </Text>
+  );
+
+  const expandBtnJsx = (
+    <IconButton
+      variant={isExpand ? 'primary' : 'surface'}
+      size="extra-small"
+      src={InfoIC}
+      tooltip="Topic"
+      tooltipPlacement="top"
+      onClick={() => setIsExpand(!isExpand)}
+    />
+  );
+
+  return (
+    <div
+      className={`space-manage-item${isSpace ? '--space' : ''}`}
+    >
+      <div>
+        {canManage && <Checkbox isActive={isSelected} onToggle={() => onSelect(roomId)} variant="positive" />}
+        <button
+          className="space-manage-item__btn"
+          onClick={isSpace ? () => onSpaceClick(roomId, name) : null}
+          type="button"
+        >
+          {roomAvatarJSX}
+          {roomNameJSX}
+        </button>
+        {roomInfo.topic && expandBtnJsx}
+        {
+          isJoined
+            ? <Button onClick={handleOpen}>Open</Button>
+            : <Button variant="primary" onClick={handleJoin} disabled={isJoining}>{isJoining ? 'Joining...' : 'Join'}</Button>
+        }
+      </div>
+      {isExpand && roomInfo.topic && <Text variant="b2">{twemojify(roomInfo.topic, undefined, true)}</Text>}
+    </div>
+  );
+}
+SpaceManageItem.propTypes = {
+  parentId: PropTypes.string.isRequired,
+  roomHierarchy: PropTypes.shape({}).isRequired,
+  roomInfo: PropTypes.shape({}).isRequired,
+  onSpaceClick: PropTypes.func.isRequired,
+  requestClose: PropTypes.func.isRequired,
+  isSelected: PropTypes.bool.isRequired,
+  onSelect: PropTypes.func.isRequired,
+};
+
+function SpaceManageFooter({ roomId, selected }) {
+  return (
+    <div className="space-manage__footer">
+      <Text weight="medium">{`${selected.length} item selected`}</Text>
+      <Button variant="danger">Remove</Button>
+      <Button variant="primary">Mark as suggested</Button>
+    </div>
+  );
+}
+SpaceManageFooter.propTypes = {
+  roomId: PropTypes.string.isRequired,
+  selected: PropTypes.arrayOf(PropTypes.string).isRequired,
+};
+
+function useSpacePath(roomId) {
+  const mx = initMatrix.matrixClient;
+  const room = mx.getRoom(roomId);
+  const [spacePath, setSpacePath] = useState([{ roomId, name: room.name }]);
+
+  const addPathItem = (rId, name) => {
+    const newPath = [...spacePath];
+    const itemIndex = newPath.findIndex((item) => item.roomId === rId);
+    if (itemIndex < 0) {
+      newPath.push({ roomId: rId, name });
+      setSpacePath(newPath);
+      return;
+    }
+    newPath.splice(itemIndex + 1);
+    setSpacePath(newPath);
+  };
+
+  return [spacePath, addPathItem];
+}
+
+function useUpdateOnJoin(roomId) {
+  const [, forceUpdate] = useForceUpdate();
+  const { roomList } = initMatrix;
+
+  useEffect(() => {
+    const handleRoomList = () => forceUpdate();
+
+    roomList.on(cons.events.roomList.ROOM_JOINED, handleRoomList);
+    roomList.on(cons.events.roomList.ROOM_LEAVED, handleRoomList);
+    return () => {
+      roomList.removeListener(cons.events.roomList.ROOM_JOINED, handleRoomList);
+      roomList.removeListener(cons.events.roomList.ROOM_LEAVED, handleRoomList);
+    };
+  }, [roomId]);
+}
+
+function SpaceManageContent({ roomId, requestClose }) {
+  const mx = initMatrix.matrixClient;
+  useUpdateOnJoin(roomId);
+  const [roomsHierarchy] = useState(new RoomsHierarchy(mx, 30));
+  const [spacePath, addPathItem] = useSpacePath(roomId);
+  const [isLoading, setIsLoading] = useState(true);
+  const [selected, setSelected] = useState([]);
+  const mountStore = useStore();
+
+  const currentPath = spacePath[spacePath.length - 1];
+  const currentHierarchy = roomsHierarchy.getHierarchy(currentPath.roomId);
+
+  useEffect(() => {
+    mountStore.setItem(true);
+    return () => {
+      mountStore.setItem(false);
+    };
+  }, [roomId]);
+
+  useEffect(() => {
+    setSelected([]);
+  }, [spacePath]);
+
+  const handleSelected = (selectedRoomId) => {
+    const newSelected = [...selected];
+    const selectedIndex = newSelected.indexOf(selectedRoomId);
+
+    if (selectedIndex > -1) {
+      newSelected.splice(selectedIndex, 1);
+      setSelected(newSelected);
+      return;
+    }
+    newSelected.push(selectedRoomId);
+    setSelected(newSelected);
+  };
+
+  const loadRoomHierarchy = async () => {
+    if (!roomsHierarchy.canLoadMore(currentPath.roomId)) return;
+    setIsLoading(true);
+    try {
+      await roomsHierarchy.load(currentPath.roomId);
+      if (!mountStore.getItem()) return;
+      setIsLoading(false);
+    } catch {
+      if (!mountStore.getItem()) return;
+      setIsLoading(false);
+    }
+  };
+
+  if (!currentHierarchy) loadRoomHierarchy();
+  return (
+    <div className="space-manage__content">
+      {spacePath.length > 1 && (
+        <SpaceManageBreadcrumb path={spacePath} onSelect={addPathItem} />
+      )}
+      <Text variant="b3" weight="bold">Rooms and spaces</Text>
+      <div className="space-manage__content-items">
+        {!isLoading && currentHierarchy?.rooms?.length === 1 && (
+          <Text>
+            Either the space contains private rooms or you need to join space to view it's rooms.
+          </Text>
+        )}
+        {currentHierarchy && (currentHierarchy.rooms?.map((roomInfo) => (
+          roomInfo.room_id === currentPath.roomId
+            ? null
+            : (
+              <SpaceManageItem
+                key={roomInfo.room_id}
+                isSelected={selected.includes(roomInfo.room_id)}
+                roomHierarchy={currentHierarchy}
+                parentId={currentPath.roomId}
+                roomInfo={roomInfo}
+                onSpaceClick={addPathItem}
+                requestClose={requestClose}
+                onSelect={handleSelected}
+              />
+            )
+        )))}
+        {!currentHierarchy && <Text>loading...</Text>}
+      </div>
+      {currentHierarchy?.canLoadMore && !isLoading && (
+        <Button onClick={loadRoomHierarchy}>Load more</Button>
+      )}
+      {isLoading && (
+        <div className="space-manage__content-loading">
+          <Spinner size="small" />
+          <Text>Loading rooms</Text>
+        </div>
+      )}
+      {selected.length > 0 && <SpaceManageFooter roomId={roomId} selected={selected} />}
+    </div>
+  );
+}
+SpaceManageContent.propTypes = {
+  roomId: PropTypes.string.isRequired,
+  requestClose: PropTypes.func.isRequired,
+};
+
+function useWindowToggle() {
+  const [roomId, setRoomId] = useState(null);
+
+  useEffect(() => {
+    const openSpaceManage = (rId) => {
+      setRoomId(rId);
+    };
+    navigation.on(cons.events.navigation.SPACE_MANAGE_OPENED, openSpaceManage);
+    return () => {
+      navigation.removeListener(cons.events.navigation.SPACE_MANAGE_OPENED, openSpaceManage);
+    };
+  }, []);
+
+  const requestClose = () => setRoomId(null);
+
+  return [roomId, requestClose];
+}
+function SpaceManage() {
+  const mx = initMatrix.matrixClient;
+  const [roomId, requestClose] = useWindowToggle();
+  const room = mx.getRoom(roomId);
+
+  return (
+    <PopupWindow
+      isOpen={roomId !== null}
+      className="space-manage"
+      title={(
+        <Text variant="s1" weight="medium" primary>
+          {roomId && twemojify(room.name)}
+          <span style={{ color: 'var(--tc-surface-low)' }}> — manage rooms</span>
+        </Text>
+      )}
+      contentOptions={<IconButton src={CrossIC} onClick={requestClose} tooltip="Close" />}
+      onRequestClose={requestClose}
+    >
+      {
+        roomId
+          ? <SpaceManageContent roomId={roomId} requestClose={requestClose} />
+          : <div />
+      }
+    </PopupWindow>
+  );
+}
+
+export default SpaceManage;
diff --git a/src/app/organisms/space-manage/SpaceManage.scss b/src/app/organisms/space-manage/SpaceManage.scss
new file mode 100644 (file)
index 0000000..6592d48
--- /dev/null
@@ -0,0 +1,159 @@
+@use '../../partials/text';
+@use '../../partials/dir';
+@use '../../partials/flex';
+
+.space-manage {
+  & .pw__content-wrapper {
+    position: relative;
+  }
+  & .pw__content-container {
+    padding-top: 0;
+    padding-bottom: 73px;
+  }
+}
+
+.space-manage__content {
+  margin-bottom: var(--sp-extra-loose);
+  
+  & > .text {
+    margin-top: var(--sp-extra-tight);
+    padding: var(--sp-extra-tight) var(--sp-normal);
+    text-transform: uppercase;
+  }
+
+  &-items {
+    @include dir.side(padding, var(--sp-extra-tight), 0);
+    & > .text:first-child {
+      padding: var(--sp-extra-tight);
+    }
+  }
+  
+  & > button {
+    margin: var(--sp-normal);
+  }
+
+  &-loading {
+    padding: var(--sp-loose);
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    & .text {
+      margin: 0 var(--sp-normal);
+    }
+  }
+}
+.space-manage-breadcrumb {
+  display: flex;
+  align-items: center;
+  height: 100%;
+  margin: 0 var(--sp-extra-tight);
+
+  &__wrapper {
+    height: var(--header-height);
+    position: sticky;
+    top: 0;
+    z-index: 99;
+    background-color: var(--bg-surface);
+  }
+  & > * {
+    flex-shrink: 0;
+  }
+
+  & > .btn-surface {
+    min-width: 0;
+    padding: var(--sp-extra-tight) 10px;
+    white-space: nowrap;
+    box-shadow: none;
+    & p {
+      @extend .cp-txt__ellipsis;
+      max-width: 200px;
+    }
+    &:last-child {
+      box-shadow: var(--bs-surface-border) !important;
+      background-color: var(--bg-surface);
+    }
+  }
+
+}
+
+.space-manage-item {
+  margin: var(--sp-ultra-tight) 0;
+  padding: 0 var(--sp-extra-tight);
+  border-radius: var(--bo-radius);
+
+  & > div {
+    min-height: 40px;
+    display: flex;
+    align-items: center;
+  }
+
+  &--space {
+    @extend .space-manage-item;
+    & .space-manage-item__btn {
+      cursor: pointer;
+    }
+  }
+
+  &:hover {
+    background-color: var(--bg-surface-hover);
+  }
+
+  & .checkbox {
+    @include dir.side(margin, 0, var(--sp-tight));
+  }
+  
+  
+  &__btn {
+    @extend .cp-fx__item-one;
+    display: flex;
+
+    & .avatar__border--active {
+      box-shadow: none;
+    }
+    & .text {
+      @extend .cp-txt__ellipsis;
+      min-width: 0;
+      margin: 0 var(--sp-extra-tight);
+    }
+  }
+
+  & .ic-btn {
+    padding: 7px;
+    @include dir.side(margin, 0, var(--sp-extra-tight));
+    opacity: 0.7;
+  }
+
+  & .btn-surface,
+  & .btn-primary {
+    padding: var(--sp-ultra-tight) var(--sp-extra-tight);
+    min-width: 60px;
+  }
+
+  & > .text {
+    padding: 32px;
+    padding-top: 0;
+    padding-bottom: var(--sp-normal);
+    white-space: pre-wrap;
+  }
+}
+
+.space-manage__footer {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  padding: var(--sp-normal);
+  background-color: var(--bg-surface);
+  border-top: 1px solid var(--bg-surface-border);
+  display: flex;
+  align-items: center;
+
+  & > .text {
+    @extend .cp-fx__item-one;
+    padding: 0 var(--sp-tight);
+  }
+
+  & > button {
+    @include dir.side(margin, var(--sp-normal), 0);
+  }
+}
\ No newline at end of file
index c3f7e29d9fc758f75ba0671ab816076d1df56e5e..697bbc19a5c0e3720f355721f4302856a7403268 100644 (file)
@@ -100,8 +100,8 @@ function useWindowToggle(setSelectedTab) {
   const [window, setWindow] = useState(null);
 
   useEffect(() => {
-    const openSpaceSettings = (spaceId, tab) => {
-      setWindow({ spaceId, tabText });
+    const openSpaceSettings = (roomId, tab) => {
+      setWindow({ roomId, tabText });
       const tabItem = tabItems.find((item) => item.text === tab);
       if (tabItem) setSelectedTab(tabItem);
     };
@@ -120,7 +120,7 @@ function SpaceSettings() {
   const [selectedTab, setSelectedTab] = useState(tabItems[0]);
   const [window, requestClose] = useWindowToggle(setSelectedTab);
   const isOpen = window !== null;
-  const roomId = window?.spaceId;
+  const roomId = window?.roomId;
 
   const mx = initMatrix.matrixClient;
   const room = mx.getRoom(roomId);
index 23420b8393bd5027270e192964bc5195ccb7a88a..6f82a42b26dff0ab1e834a9ea0d616bda81ba382 100644 (file)
@@ -23,14 +23,21 @@ export function selectRoom(roomId, eventId) {
   });
 }
 
-export function openSpaceSettings(spaceId, tabText) {
+export function openSpaceSettings(roomId, tabText) {
   appDispatcher.dispatch({
     type: cons.actions.navigation.OPEN_SPACE_SETTINGS,
-    spaceId,
+    roomId,
     tabText,
   });
 }
 
+export function openSpaceManage(roomId) {
+  appDispatcher.dispatch({
+    type: cons.actions.navigation.OPEN_SPACE_MANAGE,
+    roomId,
+  });
+}
+
 export function toggleRoomSettings(tabText) {
   appDispatcher.dispatch({
     type: cons.actions.navigation.TOGGLE_ROOM_SETTINGS,
index 97dcf9efcc5907188e6167cd014e273ef13d6b3e..2ac4cbdde8237a8e352776edc1e3bdcdfda329c4 100644 (file)
@@ -31,6 +31,7 @@ const cons = {
       SELECT_SPACE: 'SELECT_SPACE',
       SELECT_ROOM: 'SELECT_ROOM',
       OPEN_SPACE_SETTINGS: 'OPEN_SPACE_SETTINGS',
+      OPEN_SPACE_MANAGE: 'OPEN_SPACE_MANAGE',
       TOGGLE_ROOM_SETTINGS: 'TOGGLE_ROOM_SETTINGS',
       OPEN_INVITE_LIST: 'OPEN_INVITE_LIST',
       OPEN_PUBLIC_ROOMS: 'OPEN_PUBLIC_ROOMS',
@@ -69,6 +70,7 @@ const cons = {
       SPACE_SELECTED: 'SPACE_SELECTED',
       ROOM_SELECTED: 'ROOM_SELECTED',
       SPACE_SETTINGS_OPENED: 'SPACE_SETTINGS_OPENED',
+      SPACE_MANAGE_OPENED: 'SPACE_MANAGE_OPENED',
       ROOM_SETTINGS_TOGGLED: 'ROOM_SETTINGS_TOGGLED',
       INVITE_LIST_OPENED: 'INVITE_LIST_OPENED',
       PUBLIC_ROOMS_OPENED: 'PUBLIC_ROOMS_OPENED',
index ff1d065b4bb39aeba4a7deeefc55e806d92ed0d1..a7044f596ba49e5f19d1e529d55ea844d5357755 100644 (file)
@@ -90,7 +90,10 @@ class Navigation extends EventEmitter {
         );
       },
       [cons.actions.navigation.OPEN_SPACE_SETTINGS]: () => {
-        this.emit(cons.events.navigation.SPACE_SETTINGS_OPENED, action.spaceId, action.tabText);
+        this.emit(cons.events.navigation.SPACE_SETTINGS_OPENED, action.roomId, action.tabText);
+      },
+      [cons.actions.navigation.OPEN_SPACE_MANAGE]: () => {
+        this.emit(cons.events.navigation.SPACE_MANAGE_OPENED, action.roomId);
       },
       [cons.actions.navigation.TOGGLE_ROOM_SETTINGS]: () => {
         this.isRoomSettings = !this.isRoomSettings;