diff --git a/src/app/molecules/room-members/RoomMembers.jsx b/src/app/molecules/room-members/RoomMembers.jsx
index ac004f46..f931f9dd 100644
--- a/src/app/molecules/room-members/RoomMembers.jsx
+++ b/src/app/molecules/room-members/RoomMembers.jsx
@@ -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);
};
diff --git a/src/app/organisms/navigation/Directs.jsx b/src/app/organisms/navigation/Directs.jsx
index 61313479..c2a9798b 100644
--- a/src/app/organisms/navigation/Directs.jsx
+++ b/src/app/organisms/navigation/Directs.jsx
@@ -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) => {
diff --git a/src/app/organisms/navigation/Home.jsx b/src/app/organisms/navigation/Home.jsx
index 35e43a97..5e26a48b 100644
--- a/src/app/organisms/navigation/Home.jsx
+++ b/src/app/organisms/navigation/Home.jsx
@@ -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 && (
-
+
)}
{ roomIds.length !== 0 && (
-
+
)}
{ directIds.length !== 0 && (
-
+
)}
- { isCategorized && [...categories].map(([catId, childIds]) => (
-
- ))}
+ { 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 (
+
+ );
+ })}
>
);
}
diff --git a/src/app/organisms/navigation/common.js b/src/app/organisms/navigation/common.js
deleted file mode 100644
index 3c37e548..00000000
--- a/src/app/organisms/navigation/common.js
+++ /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 };
diff --git a/src/app/organisms/room/PeopleDrawer.jsx b/src/app/organisms/room/PeopleDrawer.jsx
index f00ff890..8f983247 100644
--- a/src/app/organisms/room/PeopleDrawer.jsx
+++ b/src/app/organisms/room/PeopleDrawer.jsx
@@ -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),
),
);
};
diff --git a/src/app/organisms/shortcut-spaces/ShortcutSpaces.jsx b/src/app/organisms/shortcut-spaces/ShortcutSpaces.jsx
index c379b6b9..62ec76a3 100644
--- a/src/app/organisms/shortcut-spaces/ShortcutSpaces.jsx
+++ b/src/app/organisms/shortcut-spaces/ShortcutSpaces.jsx
@@ -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
index 00000000..72ba3c43
--- /dev/null
+++ b/src/util/sort.js
@@ -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;
+}