@@ -63,58 +63,59 @@ export const sortRooms = (rooms: Room[]): Room[] => {
6363 }
6464
6565 const tsCache : { [ roomId : string ] : number } = { } ;
66- const getLastTs = ( r : Room ) => {
67- if ( tsCache [ r . roomId ] ) {
68- return tsCache [ r . roomId ] ;
69- }
7066
71- const ts = ( ( ) => {
72- // Apparently we can have rooms without timelines, at least under testing
73- // environments. Just return MAX_INT when this happens.
74- if ( ! r || ! r . timeline ) {
75- return Number . MAX_SAFE_INTEGER ;
76- }
67+ return rooms . sort ( ( a , b ) => {
68+ const roomALastTs = tsCache [ a . roomId ] ?? getLastTs ( a , myUserId ) ;
69+ const roomBLastTs = tsCache [ b . roomId ] ?? getLastTs ( b , myUserId ) ;
7770
78- // If the room hasn't been joined yet, it probably won't have a timeline to
79- // parse. We'll still fall back to the timeline if this fails, but chances
80- // are we'll at least have our own membership event to go off of.
81- const effectiveMembership = getEffectiveMembership ( r . getMyMembership ( ) ) ;
82- if ( effectiveMembership !== EffectiveMembership . Join ) {
83- const membershipEvent = r . currentState . getStateEvents ( "m.room.member" , myUserId ) ;
84- if ( membershipEvent && ! Array . isArray ( membershipEvent ) ) {
85- return membershipEvent . getTs ( ) ;
86- }
87- }
71+ tsCache [ a . roomId ] = roomALastTs ;
72+ tsCache [ b . roomId ] = roomBLastTs ;
8873
89- for ( let i = r . timeline . length - 1 ; i >= 0 ; -- i ) {
90- const ev = r . timeline [ i ] ;
91- if ( ! ev . getTs ( ) ) continue ; // skip events that don't have timestamps (tests only?)
74+ return roomBLastTs - roomALastTs ;
75+ } ) ;
76+ } ;
9277
93- if (
94- ( ev . getSender ( ) === myUserId && shouldCauseReorder ( ev ) ) ||
95- Unread . eventTriggersUnreadCount ( ev )
96- ) {
97- return ev . getTs ( ) ;
98- }
99- }
78+ const getLastTs = ( r : Room , userId : string ) => {
79+ const ts = ( ( ) => {
80+ // Apparently we can have rooms without timelines, at least under testing
81+ // environments. Just return MAX_INT when this happens.
82+ if ( ! r || ! r . timeline ) {
83+ return Number . MAX_SAFE_INTEGER ;
84+ }
10085
101- // we might only have events that don't trigger the unread indicator,
102- // in which case use the oldest event even if normally it wouldn't count.
103- // This is better than just assuming the last event was forever ago.
104- if ( r . timeline . length && r . timeline [ 0 ] . getTs ( ) ) {
105- return r . timeline [ 0 ] . getTs ( ) ;
106- } else {
107- return Number . MAX_SAFE_INTEGER ;
86+ // If the room hasn't been joined yet, it probably won't have a timeline to
87+ // parse. We'll still fall back to the timeline if this fails, but chances
88+ // are we'll at least have our own membership event to go off of.
89+ const effectiveMembership = getEffectiveMembership ( r . getMyMembership ( ) ) ;
90+ if ( effectiveMembership !== EffectiveMembership . Join ) {
91+ const membershipEvent = r . currentState . getStateEvents ( "m.room.member" , userId ) ;
92+ if ( membershipEvent && ! Array . isArray ( membershipEvent ) ) {
93+ return membershipEvent . getTs ( ) ;
10894 }
109- } ) ( ) ;
95+ }
11096
111- tsCache [ r . roomId ] = ts ;
112- return ts ;
113- } ;
97+ for ( let i = r . timeline . length - 1 ; i >= 0 ; -- i ) {
98+ const ev = r . timeline [ i ] ;
99+ if ( ! ev . getTs ( ) ) continue ; // skip events that don't have timestamps (tests only?)
114100
115- return rooms . sort ( ( a , b ) => {
116- return getLastTs ( b ) - getLastTs ( a ) ;
117- } ) ;
101+ if (
102+ ( ev . getSender ( ) === userId && shouldCauseReorder ( ev ) ) ||
103+ Unread . eventTriggersUnreadCount ( ev )
104+ ) {
105+ return ev . getTs ( ) ;
106+ }
107+ }
108+
109+ // we might only have events that don't trigger the unread indicator,
110+ // in which case use the oldest event even if normally it wouldn't count.
111+ // This is better than just assuming the last event was forever ago.
112+ if ( r . timeline . length && r . timeline [ 0 ] . getTs ( ) ) {
113+ return r . timeline [ 0 ] . getTs ( ) ;
114+ } else {
115+ return Number . MAX_SAFE_INTEGER ;
116+ }
117+ } ) ( ) ;
118+ return ts ;
118119} ;
119120
120121/**
@@ -125,4 +126,8 @@ export class RecentAlgorithm implements IAlgorithm {
125126 public sortRooms ( rooms : Room [ ] , tagId : TagID ) : Room [ ] {
126127 return sortRooms ( rooms ) ;
127128 }
129+
130+ public getLastTs ( room : Room , userId : string ) : number {
131+ return getLastTs ( room , userId ) ;
132+ }
128133}
0 commit comments