Sort direct messages by activity (#393)
authorAjay Bura <32841439+ajbura@users.noreply.github.com>
Thu, 17 Mar 2022 11:25:16 +0000 (16:55 +0530)
committerGitHub <noreply@github.com>
Thu, 17 Mar 2022 11:25:16 +0000 (16:55 +0530)
* Add sort util

Signed-off-by: Ajay Bura <ajbura@gmail.com>
* Use sort util for members

Signed-off-by: Ajay Bura <ajbura@gmail.com>
* Sort dms by activity

Signed-off-by: Ajay Bura <ajbura@gmail.com>
* Sort dms activily

Signed-off-by: Ajay Bura <ajbura@gmail.com>
* Chanege roomIdByLastActive func name

Signed-off-by: Ajay Bura <ajbura@gmail.com>
src/app/molecules/room-members/RoomMembers.jsx
src/app/organisms/navigation/Directs.jsx
src/app/organisms/navigation/Home.jsx
src/app/organisms/navigation/common.js [deleted file]
src/app/organisms/room/PeopleDrawer.jsx
src/app/organisms/shortcut-spaces/ShortcutSpaces.jsx
src/util/sort.js [new file with mode: 0644]

index ac004f469d8ce32621c5c03c8ddd9302ea9592c5..f931f9ddecc0de74d4f9de7c83e67f9a107763c9 100644 (file)
@@ -9,6 +9,7 @@ import colorMXID from '../../../util/colorMXID';
 import { openProfileViewer } from '../../../client/action/navigation';
 import { getUsernameOfRoomMember, getPowerLabel } from '../../../util/matrixUtil';
 import AsyncSearch from '../../../util/AsyncSearch';
+import { memberByAtoZ, memberByPowerLevel } from '../../../util/sort';
 
 import Text from '../../atoms/text/Text';
 import Button from '../../atoms/button/Button';
@@ -19,26 +20,6 @@ import PeopleSelector from '../people-selector/PeopleSelector';
 
 const PER_PAGE_MEMBER = 50;
 
-function AtoZ(m1, m2) {
-  const aName = m1.name;
-  const bName = m2.name;
-
-  if (aName.toLowerCase() < bName.toLowerCase()) {
-    return -1;
-  }
-  if (aName.toLowerCase() > bName.toLowerCase()) {
-    return 1;
-  }
-  return 0;
-}
-function sortByPowerLevel(m1, m2) {
-  const pl1 = m1.powerLevel;
-  const pl2 = m2.powerLevel;
-
-  if (pl1 > pl2) return -1;
-  if (pl1 < pl2) return 1;
-  return 0;
-}
 function normalizeMembers(members) {
   const mx = initMatrix.matrixClient;
   return members.map((member) => ({
@@ -65,7 +46,7 @@ function useMemberOfMembership(roomId, membership) {
       if (event && event?.getRoomId() !== roomId) return;
       const memberOfMembership = normalizeMembers(
         room.getMembersWithMembership(membership)
-          .sort(AtoZ).sort(sortByPowerLevel),
+          .sort(memberByAtoZ).sort(memberByPowerLevel),
       );
       setMembers(memberOfMembership);
     };
index 613134794587a36bef51897d79a631af133c5a3d..c2a9798b58ef99943904abe31b0c0c245b035347 100644 (file)
@@ -1,18 +1,38 @@
-import React, { useEffect } from 'react';
+import React, { useState, useEffect } from 'react';
 
 import initMatrix from '../../../client/initMatrix';
 import cons from '../../../client/state/cons';
 import navigation from '../../../client/state/navigation';
 import Postie from '../../../util/Postie';
+import { roomIdByActivity } from '../../../util/sort';
 
 import RoomsCategory from './RoomsCategory';
 
-import { AtoZ } from './common';
-
 const drawerPostie = new Postie();
 function Directs() {
+  const mx = initMatrix.matrixClient;
   const { roomList, notifications } = initMatrix;
-  const directIds = [...roomList.directs].sort(AtoZ);
+  const [directIds, setDirectIds] = useState([]);
+
+  useEffect(() => setDirectIds([...roomList.directs].sort(roomIdByActivity)), []);
+
+  useEffect(() => {
+    const handleTimeline = (event, room, toStartOfTimeline, removed, data) => {
+      if (!roomList.directs.has(room.roomId)) return;
+      if (!data.liveEvent) return;
+      if (directIds[0] === room.roomId) return;
+      const newDirectIds = [room.roomId];
+      directIds.forEach((id) => {
+        if (id === room.roomId) return;
+        newDirectIds.push(id);
+      });
+      setDirectIds(newDirectIds);
+    };
+    mx.on('Room.timeline', handleTimeline);
+    return () => {
+      mx.removeListener('Room.timeline', handleTimeline);
+    };
+  }, [directIds]);
 
   useEffect(() => {
     const selectorChanged = (selectedRoomId, prevSelectedRoomId) => {
index 35e43a97755b82126b6266b6d5718c8865f949dd..5e26a48ba62ba279eb4eda6be22483e62381ba50 100644 (file)
@@ -5,11 +5,11 @@ import initMatrix from '../../../client/initMatrix';
 import cons from '../../../client/state/cons';
 import navigation from '../../../client/state/navigation';
 import Postie from '../../../util/Postie';
+import { roomIdByActivity, roomIdByAtoZ } from '../../../util/sort';
 
 import RoomsCategory from './RoomsCategory';
 
 import { useCategorizedSpaces } from '../../hooks/useCategorizedSpaces';
-import { AtoZ, RoomToDM } from './common';
 
 const drawerPostie = new Postie();
 function Home({ spaceId }) {
@@ -34,10 +34,6 @@ function Home({ spaceId }) {
     roomIds = roomList.getOrphanRooms();
   }
 
-  spaceIds.sort(AtoZ);
-  roomIds.sort(AtoZ);
-  directIds.sort(AtoZ);
-
   if (isCategorized) {
     categories = roomList.getCategorizedSpaces(spaceIds);
     categories.delete(spaceId);
@@ -73,26 +69,36 @@ function Home({ spaceId }) {
   return (
     <>
       { !isCategorized && spaceIds.length !== 0 && (
-        <RoomsCategory name="Spaces" roomIds={spaceIds} drawerPostie={drawerPostie} />
+        <RoomsCategory name="Spaces" roomIds={spaceIds.sort(roomIdByAtoZ)} drawerPostie={drawerPostie} />
       )}
 
       { roomIds.length !== 0 && (
-        <RoomsCategory name="Rooms" roomIds={roomIds} drawerPostie={drawerPostie} />
+        <RoomsCategory name="Rooms" roomIds={roomIds.sort(roomIdByAtoZ)} drawerPostie={drawerPostie} />
       )}
 
       { directIds.length !== 0 && (
-        <RoomsCategory name="People" roomIds={directIds} drawerPostie={drawerPostie} />
+        <RoomsCategory name="People" roomIds={directIds.sort(roomIdByActivity)} drawerPostie={drawerPostie} />
       )}
 
-      { isCategorized && [...categories].map(([catId, childIds]) => (
-        <RoomsCategory
-          key={catId}
-          spaceId={catId}
-          name={mx.getRoom(catId).name}
-          roomIds={[...childIds].sort(AtoZ).sort(RoomToDM)}
-          drawerPostie={drawerPostie}
-        />
-      ))}
+      { isCategorized && [...categories].map(([catId, childIds]) => {
+        const rms = [];
+        const dms = [];
+        childIds.forEach((id) => {
+          if (directs.has(id)) dms.push(id);
+          else rms.push(id);
+        });
+        rms.sort(roomIdByAtoZ);
+        dms.sort(roomIdByActivity);
+        return (
+          <RoomsCategory
+            key={catId}
+            spaceId={catId}
+            name={mx.getRoom(catId).name}
+            roomIds={rms.concat(dms)}
+            drawerPostie={drawerPostie}
+          />
+        );
+      })}
     </>
   );
 }
diff --git a/src/app/organisms/navigation/common.js b/src/app/organisms/navigation/common.js
deleted file mode 100644 (file)
index 3c37e54..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-import initMatrix from '../../../client/initMatrix';
-
-function AtoZ(aId, bId) {
-  let aName = initMatrix.matrixClient.getRoom(aId).name;
-  let bName = initMatrix.matrixClient.getRoom(bId).name;
-
-  // remove "#" from the room name
-  // To ignore it in sorting
-  aName = aName.replaceAll('#', '');
-  bName = bName.replaceAll('#', '');
-
-  if (aName.toLowerCase() < bName.toLowerCase()) {
-    return -1;
-  }
-  if (aName.toLowerCase() > bName.toLowerCase()) {
-    return 1;
-  }
-  return 0;
-}
-
-const RoomToDM = (aId, bId) => {
-  const { directs } = initMatrix.roomList;
-  const aIsDm = directs.has(aId);
-  const bIsDm = directs.has(bId);
-  if (aIsDm && !bIsDm) return 1;
-  if (!aIsDm && bIsDm) return -1;
-  return 0;
-};
-
-export { AtoZ, RoomToDM };
index f00ff890543cb187c62001e24f6ba5f0eb62ae3e..8f983247ac93ed18a6f6c026a7f7dbeda7101c3c 100644 (file)
@@ -9,6 +9,7 @@ import { getPowerLabel, getUsernameOfRoomMember } from '../../../util/matrixUtil
 import colorMXID from '../../../util/colorMXID';
 import { openInviteUser, openProfileViewer } from '../../../client/action/navigation';
 import AsyncSearch from '../../../util/AsyncSearch';
+import { memberByAtoZ, memberByPowerLevel } from '../../../util/sort';
 
 import Text from '../../atoms/text/Text';
 import Header, { TitleWrapper } from '../../atoms/header/Header';
@@ -24,26 +25,6 @@ import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg';
 import SearchIC from '../../../../public/res/ic/outlined/search.svg';
 import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
 
-function AtoZ(m1, m2) {
-  const aName = m1.name;
-  const bName = m2.name;
-
-  if (aName.toLowerCase() < bName.toLowerCase()) {
-    return -1;
-  }
-  if (aName.toLowerCase() > bName.toLowerCase()) {
-    return 1;
-  }
-  return 0;
-}
-function sortByPowerLevel(m1, m2) {
-  const pl1 = m1.powerLevel;
-  const pl2 = m2.powerLevel;
-
-  if (pl1 > pl2) return -1;
-  if (pl1 < pl2) return 1;
-  return 0;
-}
 function simplyfiMembers(members) {
   const mx = initMatrix.matrixClient;
   return members.map((member) => ({
@@ -111,7 +92,7 @@ function PeopleDrawer({ roomId }) {
       setMemberList(
         simplyfiMembers(
           getMembersWithMembership(membership)
-            .sort(AtoZ).sort(sortByPowerLevel),
+            .sort(memberByAtoZ).sort(memberByPowerLevel),
         ),
       );
     };
index c379b6b9f623d6906b12fd6d31a056bd93849139..62ec76a3133fa15820419fc13e9e9ee122d19814 100644 (file)
@@ -6,6 +6,7 @@ import cons from '../../../client/state/cons';
 import navigation from '../../../client/state/navigation';
 import { createSpaceShortcut, deleteSpaceShortcut } from '../../../client/action/accountData';
 import { joinRuleToIconSrc } from '../../../util/matrixUtil';
+import { roomIdByAtoZ } from '../../../util/sort';
 
 import Text from '../../atoms/text/Text';
 import Button from '../../atoms/button/Button';
@@ -20,7 +21,6 @@ import PinFilledIC from '../../../../public/res/ic/filled/pin.svg';
 import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
 
 import { useSpaceShortcut } from '../../hooks/useSpaceShortcut';
-import { AtoZ } from '../navigation/common';
 
 function ShortcutSpacesContent() {
   const mx = initMatrix.matrixClient;
@@ -29,7 +29,7 @@ function ShortcutSpacesContent() {
   const [spaceShortcut] = useSpaceShortcut();
   const spaceWithoutShortcut = [...spaces].filter(
     (spaceId) => !spaceShortcut.includes(spaceId),
-  ).sort(AtoZ);
+  ).sort(roomIdByAtoZ);
 
   const [process, setProcess] = useState(null);
   const [selected, setSelected] = useState([]);
diff --git a/src/util/sort.js b/src/util/sort.js
new file mode 100644 (file)
index 0000000..72ba3c4
--- /dev/null
@@ -0,0 +1,47 @@
+import initMatrix from '../client/initMatrix';
+
+export function roomIdByActivity(id1, id2) {
+  const room1 = initMatrix.matrixClient.getRoom(id1);
+  const room2 = initMatrix.matrixClient.getRoom(id2);
+
+  return room2.getLastActiveTimestamp() - room1.getLastActiveTimestamp();
+}
+
+export function roomIdByAtoZ(aId, bId) {
+  let aName = initMatrix.matrixClient.getRoom(aId).name;
+  let bName = initMatrix.matrixClient.getRoom(bId).name;
+
+  // remove "#" from the room name
+  // To ignore it in sorting
+  aName = aName.replaceAll('#', '');
+  bName = bName.replaceAll('#', '');
+
+  if (aName.toLowerCase() < bName.toLowerCase()) {
+    return -1;
+  }
+  if (aName.toLowerCase() > bName.toLowerCase()) {
+    return 1;
+  }
+  return 0;
+}
+
+export function memberByAtoZ(m1, m2) {
+  const aName = m1.name;
+  const bName = m2.name;
+
+  if (aName.toLowerCase() < bName.toLowerCase()) {
+    return -1;
+  }
+  if (aName.toLowerCase() > bName.toLowerCase()) {
+    return 1;
+  }
+  return 0;
+}
+export function memberByPowerLevel(m1, m2) {
+  const pl1 = m1.powerLevel;
+  const pl2 = m2.powerLevel;
+
+  if (pl1 > pl2) return -1;
+  if (pl1 < pl2) return 1;
+  return 0;
+}