Move space shortcut from roomlist to accountdata
authorAjay Bura <ajbura@gmail.com>
Sun, 27 Feb 2022 11:32:03 +0000 (17:02 +0530)
committerAjay Bura <ajbura@gmail.com>
Sun, 27 Feb 2022 11:32:03 +0000 (17:02 +0530)
Signed-off-by: Ajay Bura <ajbura@gmail.com>
src/app/hooks/useSpaceShortcut.js
src/app/molecules/space-options/SpaceOptions.jsx
src/app/organisms/navigation/SideBar.jsx
src/app/organisms/space-settings/SpaceSettings.jsx
src/client/action/accountData.js [new file with mode: 0644]
src/client/action/room.js
src/client/initMatrix.js
src/client/state/AccountData.js [new file with mode: 0644]
src/client/state/RoomList.js
src/client/state/cons.js

index 8dca2ba1e20eadfaf5f3dfcb1641e9b4f0356ebe..a1710c603f95115166eeb2ea2a80fadb132cb642 100644 (file)
@@ -5,16 +5,19 @@ import initMatrix from '../../client/initMatrix';
 import cons from '../../client/state/cons';
 
 export function useSpaceShortcut() {
-  const { roomList } = initMatrix;
-  const [spaceShortcut, setSpaceShortcut] = useState([...roomList.spaceShortcut]);
+  const { accountData } = initMatrix;
+  const [spaceShortcut, setSpaceShortcut] = useState([...accountData.spaceShortcut]);
 
   useEffect(() => {
     const onSpaceShortcutUpdated = () => {
-      setSpaceShortcut([...roomList.spaceShortcut]);
+      setSpaceShortcut([...accountData.spaceShortcut]);
     };
-    roomList.on(cons.events.roomList.SPACE_SHORTCUT_UPDATED, onSpaceShortcutUpdated);
+    accountData.on(cons.events.accountData.SPACE_SHORTCUT_UPDATED, onSpaceShortcutUpdated);
     return () => {
-      roomList.removeListener(cons.events.roomList.SPACE_SHORTCUT_UPDATED, onSpaceShortcutUpdated);
+      accountData.removeListener(
+        cons.events.accountData.SPACE_SHORTCUT_UPDATED,
+        onSpaceShortcutUpdated,
+      );
     };
   }, []);
 
index cb69e180114c1ac29fea7b8f14c7caa0690fb8b0..223ff57e3d7a4be6760943380a9510af82845700 100644 (file)
@@ -5,10 +5,13 @@ import { twemojify } from '../../../util/twemojify';
 
 import initMatrix from '../../../client/initMatrix';
 import { openSpaceSettings, openSpaceManage, openInviteUser } from '../../../client/action/navigation';
-import { leave, createSpaceShortcut, deleteSpaceShortcut } from '../../../client/action/room';
+import { leave } from '../../../client/action/room';
+import { createSpaceShortcut, deleteSpaceShortcut } from '../../../client/action/accountData';
 
 import { MenuHeader, MenuItem } from '../../atoms/context-menu/ContextMenu';
 
+import CategoryIC from '../../../../public/res/ic/outlined/category.svg';
+import CategoryFilledIC from '../../../../public/res/ic/filled/category.svg';
 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';
@@ -20,7 +23,7 @@ function SpaceOptions({ roomId, afterOptionSelect }) {
   const mx = initMatrix.matrixClient;
   const room = mx.getRoom(roomId);
   const canInvite = room?.canInvite(mx.getUserId());
-  const isPinned = initMatrix.roomList.spaceShortcut.has(roomId);
+  const isPinned = initMatrix.accountData.spaceShortcut.has(roomId);
 
   const handleInviteClick = () => {
     openInviteUser(roomId);
@@ -31,7 +34,10 @@ function SpaceOptions({ roomId, afterOptionSelect }) {
     else createSpaceShortcut(roomId);
     afterOptionSelect();
   };
-
+  const handleCategorizeClick = () => {
+    alert('categorize');
+    afterOptionSelect();
+  };
   const handleSettingsClick = () => {
     openSpaceSettings(roomId);
     afterOptionSelect();
@@ -51,6 +57,12 @@ function SpaceOptions({ roomId, afterOptionSelect }) {
   return (
     <div style={{ maxWidth: 'calc(var(--navigation-drawer-width) - var(--sp-normal))' }}>
       <MenuHeader>{twemojify(`Options for ${initMatrix.matrixClient.getRoom(roomId)?.name}`)}</MenuHeader>
+      <MenuItem
+        onClick={handleCategorizeClick}
+        iconSrc={CategoryIC}
+      >
+        Categorize subspaces
+      </MenuItem>
       <MenuItem
         onClick={handlePinClick}
         iconSrc={isPinned ? PinFilledIC : PinIC}
index c99929fd267f8e1e7acd9c9d588219ebb0569730..fe4645d273ab48d8df28cbb118a91b72e78eec30 100644 (file)
@@ -79,7 +79,7 @@ function useTotalInvites() {
 }
 
 function SideBar() {
-  const { roomList, notifications } = initMatrix;
+  const { roomList, accountData, notifications } = initMatrix;
   const mx = initMatrix.matrixClient;
 
   const [selectedTab] = useSelectedTab();
@@ -112,7 +112,7 @@ function SideBar() {
     let noti = null;
 
     orphans.forEach((roomId) => {
-      if (roomList.spaceShortcut.has(roomId)) return;
+      if (accountData.spaceShortcut.has(roomId)) return;
       if (!notifications.hasNoti(roomId)) return;
       if (noti === null) noti = { total: 0, highlight: 0 };
       const childNoti = notifications.getNoti(roomId);
index 697bbc19a5c0e3720f355721f4302856a7403268..76f68a6b7cffa17a14cf1ef557f5046c5a28adf7 100644 (file)
@@ -7,7 +7,8 @@ import { twemojify } from '../../../util/twemojify';
 import initMatrix from '../../../client/initMatrix';
 import cons from '../../../client/state/cons';
 import navigation from '../../../client/state/navigation';
-import { leave, createSpaceShortcut, deleteSpaceShortcut } from '../../../client/action/room';
+import { leave } from '../../../client/action/room';
+import { createSpaceShortcut, deleteSpaceShortcut } from '../../../client/action/accountData';
 
 import Text from '../../atoms/text/Text';
 import IconButton from '../../atoms/button/IconButton';
@@ -51,7 +52,7 @@ const tabItems = [{
 }];
 
 function GeneralSettings({ roomId }) {
-  const isPinned = initMatrix.roomList.spaceShortcut.has(roomId);
+  const isPinned = initMatrix.accountData.spaceShortcut.has(roomId);
   const [, forceUpdate] = useForceUpdate();
 
   return (
diff --git a/src/client/action/accountData.js b/src/client/action/accountData.js
new file mode 100644 (file)
index 0000000..00ddf23
--- /dev/null
@@ -0,0 +1,16 @@
+import appDispatcher from '../dispatcher';
+import cons from '../state/cons';
+
+export function createSpaceShortcut(roomId) {
+  appDispatcher.dispatch({
+    type: cons.actions.accountData.CREATE_SPACE_SHORTCUT,
+    roomId,
+  });
+}
+
+export function deleteSpaceShortcut(roomId) {
+  appDispatcher.dispatch({
+    type: cons.actions.accountData.DELETE_SPACE_SHORTCUT,
+    roomId,
+  });
+}
index 10927511f9aff4d477a8e4b3bfe16b4289b5e022..5bc9bf170f8c3e703753b2b93b8b2eb4774e0a16 100644 (file)
@@ -298,24 +298,9 @@ async function setPowerLevel(roomId, userId, powerLevel) {
   return result;
 }
 
-function createSpaceShortcut(roomId) {
-  appDispatcher.dispatch({
-    type: cons.actions.room.CREATE_SPACE_SHORTCUT,
-    roomId,
-  });
-}
-
-function deleteSpaceShortcut(roomId) {
-  appDispatcher.dispatch({
-    type: cons.actions.room.DELETE_SPACE_SHORTCUT,
-    roomId,
-  });
-}
-
 export {
   join, leave,
   createDM, createRoom,
   invite, kick, ban, unban,
   setPowerLevel,
-  createSpaceShortcut, deleteSpaceShortcut,
 };
index ce5bf648372503af45b7455c54d11c502b8e3882..bcf5c2840ef7dbbc331234334db7a20b160aa63c 100644 (file)
@@ -4,6 +4,7 @@ import * as sdk from 'matrix-js-sdk';
 
 import { secret } from './state/auth';
 import RoomList from './state/RoomList';
+import AccountData from './state/AccountData';
 import RoomsInput from './state/RoomsInput';
 import Notifications from './state/Notifications';
 import { initHotkeys } from './event/hotkeys';
@@ -62,6 +63,7 @@ class InitMatrix extends EventEmitter {
         global.initMatrix = this;
         if (prevState === null) {
           this.roomList = new RoomList(this.matrixClient);
+          this.accountData = new AccountData(this.roomList);
           this.roomsInput = new RoomsInput(this.matrixClient);
           this.notifications = new Notifications(this.roomList);
           initHotkeys();
diff --git a/src/client/state/AccountData.js b/src/client/state/AccountData.js
new file mode 100644 (file)
index 0000000..f75d861
--- /dev/null
@@ -0,0 +1,79 @@
+import EventEmitter from 'events';
+import appDispatcher from '../dispatcher';
+import cons from './cons';
+
+class AccountData extends EventEmitter {
+  constructor(roomList) {
+    super();
+
+    this.matrixClient = roomList.matrixClient;
+    this.roomList = roomList;
+    this.spaces = roomList.spaces;
+
+    this.spaceShortcut = new Set();
+    this._populateSpaceShortcut();
+    this._listenEvents();
+
+    appDispatcher.register(this.roomActions.bind(this));
+  }
+
+  _populateSpaceShortcut() {
+    this.spaceShortcut.clear();
+    const spacesContent = this.matrixClient.getAccountData(cons.IN_CINNY_SPACES)?.getContent();
+
+    if (!spacesContent) return;
+    if (spacesContent?.shortcut === undefined) return;
+
+    spacesContent.shortcut.forEach((shortcut) => {
+      if (this.spaces.has(shortcut)) this.spaceShortcut.add(shortcut);
+    });
+    if (spacesContent.shortcut.length !== this.spaceShortcut.size) {
+      // update shortcut list from account data if shortcut space doesn't exist.
+      // TODO: we can wait for sync to complete or else we may end up removing valid space id
+      this._updateSpaceShortcutData([...this.spaceShortcut]);
+    }
+  }
+
+  _updateSpaceShortcutData(shortcutList) {
+    const spaceContent = this.matrixClient.getAccountData(cons.IN_CINNY_SPACES)?.getContent() || {};
+    spaceContent.shortcut = shortcutList;
+    this.matrixClient.setAccountData(cons.IN_CINNY_SPACES, spaceContent);
+  }
+
+  roomActions(action) {
+    const actions = {
+      [cons.actions.accountData.CREATE_SPACE_SHORTCUT]: () => {
+        if (this.spaceShortcut.has(action.roomId)) return;
+        this.spaceShortcut.add(action.roomId);
+        this._updateSpaceShortcutData([...this.spaceShortcut]);
+        this.emit(cons.events.accountData.SPACE_SHORTCUT_UPDATED, action.roomId);
+      },
+      [cons.actions.accountData.DELETE_SPACE_SHORTCUT]: () => {
+        if (!this.spaceShortcut.has(action.roomId)) return;
+        this.spaceShortcut.delete(action.roomId);
+        this._updateSpaceShortcutData([...this.spaceShortcut]);
+        this.emit(cons.events.accountData.SPACE_SHORTCUT_UPDATED, action.roomId);
+      },
+    };
+    actions[action.type]?.();
+  }
+
+  _listenEvents() {
+    this.matrixClient.on('accountData', (event) => {
+      if (event.getType() !== cons.IN_CINNY_SPACES) return;
+      this._populateSpaceShortcut();
+      this.emit(cons.events.accountData.SPACE_SHORTCUT_UPDATED);
+    });
+
+    this.roomList.on(cons.events.roomList.ROOM_LEAVED, (roomId) => {
+      if (this.spaceShortcut.has(roomId)) {
+        // if deleted space has shortcut remove it.
+        this.spaceShortcut.delete(roomId);
+        this._updateSpaceShortcutData([...this.spaceShortcut]);
+        this.emit(cons.events.accountData.SPACE_SHORTCUT_UPDATED, roomId);
+      }
+    });
+  }
+}
+
+export default AccountData;
index 27401e1a898157213655d18f7bf4f81cc8289bb2..263c454fac4418825b112bfcfcb32b13599ad407 100644 (file)
@@ -16,8 +16,6 @@ class RoomList extends EventEmitter {
     // No matter if you have joined those children rooms or not.
     this.roomIdToParents = new Map();
 
-    this.spaceShortcut = new Set();
-
     this.inviteDirects = new Set();
     this.inviteSpaces = new Set();
     this.inviteRooms = new Set();
@@ -29,18 +27,11 @@ class RoomList extends EventEmitter {
     this.processingRooms = new Map();
 
     this._populateRooms();
-    this._populateSpaceShortcut();
     this._listenEvents();
 
     appDispatcher.register(this.roomActions.bind(this));
   }
 
-  _updateSpaceShortcutData(shortcutList) {
-    const spaceContent = this.matrixClient.getAccountData(cons['in.cinny.spaces'])?.getContent() || {};
-    spaceContent.shortcut = shortcutList;
-    this.matrixClient.setAccountData(cons['in.cinny.spaces'], spaceContent);
-  }
-
   isOrphan(roomId) {
     return !this.roomIdToParents.has(roomId);
   }
@@ -103,12 +94,6 @@ class RoomList extends EventEmitter {
     spaceChildren?.forEach((childRoomId) => {
       this.removeFromRoomIdToParents(childRoomId, roomId);
     });
-
-    if (this.spaceShortcut.has(roomId)) {
-      // if delete space has shortcut remove it.
-      this.spaceShortcut.delete(roomId);
-      this._updateSpaceShortcutData([...this.spaceShortcut]);
-    }
   }
 
   roomActions(action) {
@@ -151,18 +136,6 @@ class RoomList extends EventEmitter {
           });
         }
       },
-      [cons.actions.room.CREATE_SPACE_SHORTCUT]: () => {
-        if (this.spaceShortcut.has(action.roomId)) return;
-        this.spaceShortcut.add(action.roomId);
-        this._updateSpaceShortcutData([...this.spaceShortcut]);
-        this.emit(cons.events.roomList.SPACE_SHORTCUT_UPDATED, action.roomId);
-      },
-      [cons.actions.room.DELETE_SPACE_SHORTCUT]: () => {
-        if (!this.spaceShortcut.has(action.roomId)) return;
-        this.spaceShortcut.delete(action.roomId);
-        this._updateSpaceShortcutData([...this.spaceShortcut]);
-        this.emit(cons.events.roomList.SPACE_SHORTCUT_UPDATED, action.roomId);
-      },
     };
     actions[action.type]?.();
   }
@@ -182,21 +155,6 @@ class RoomList extends EventEmitter {
     return mDirectsId;
   }
 
-  _populateSpaceShortcut() {
-    this.spaceShortcut.clear();
-    const spacesContent = this.matrixClient.getAccountData(cons['in.cinny.spaces'])?.getContent();
-
-    if (spacesContent && Array.isArray(spacesContent?.shortcut)) {
-      spacesContent.shortcut.forEach((shortcut) => {
-        if (this.spaces.has(shortcut)) this.spaceShortcut.add(shortcut);
-      });
-      if (spacesContent.shortcut.length !== this.spaceShortcut.size) {
-        // update shortcut list from account data if shortcut space doesn't exist.
-        this._updateSpaceShortcutData([...this.spaceShortcut]);
-      }
-    }
-  }
-
   _populateRooms() {
     this.directs.clear();
     this.roomIdToParents.clear();
@@ -238,12 +196,6 @@ class RoomList extends EventEmitter {
   _listenEvents() {
     // Update roomList when m.direct changes
     this.matrixClient.on('accountData', (event) => {
-      if (event.getType() === cons['in.cinny.spaces']) {
-        this._populateSpaceShortcut();
-        this.emit(cons.events.roomList.SPACE_SHORTCUT_UPDATED);
-        return;
-      }
-
       if (event.getType() !== 'm.direct') return;
 
       const latestMDirects = this.getMDirects();
index e9413cbb2bfc5ef95d41136f928d78162092eb0b..d277ea1f9e0ecf6511e020b381e1640c579584c4 100644 (file)
@@ -7,7 +7,7 @@ const cons = {
     BASE_URL: 'cinny_hs_base_url',
   },
   DEVICE_DISPLAY_NAME: 'Cinny Web',
-  'in.cinny.spaces': 'in.cinny.spaces',
+  IN_CINNY_SPACES: 'in.cinny.spaces',
   tabs: {
     HOME: 'home',
     DIRECTS: 'dm',
@@ -51,6 +51,8 @@ const cons = {
       JOIN: 'JOIN',
       LEAVE: 'LEAVE',
       CREATE: 'CREATE',
+    },
+    accountData: {
       CREATE_SPACE_SHORTCUT: 'CREATE_SPACE_SHORTCUT',
       DELETE_SPACE_SHORTCUT: 'DELETE_SPACE_SHORTCUT',
     },
@@ -91,9 +93,11 @@ const cons = {
       ROOM_JOINED: 'ROOM_JOINED',
       ROOM_LEAVED: 'ROOM_LEAVED',
       ROOM_CREATED: 'ROOM_CREATED',
-      SPACE_SHORTCUT_UPDATED: 'SPACE_SHORTCUT_UPDATED',
       ROOM_PROFILE_UPDATED: 'ROOM_PROFILE_UPDATED',
     },
+    accountData: {
+      SPACE_SHORTCUT_UPDATED: 'SPACE_SHORTCUT_UPDATED',
+    },
     notifications: {
       NOTI_CHANGED: 'NOTI_CHANGED',
       FULL_READ: 'FULL_READ',