@@ -22,13 +22,14 @@ import {
22
22
import { VisibleMDLG } from "@cocalc/frontend/components" ;
23
23
import useVirtuosoScrollHook from "@cocalc/frontend/components/virtuoso-scroll-hook" ;
24
24
import { HashtagBar } from "@cocalc/frontend/editors/task-editor/hashtag-bar" ;
25
+ import { webapp_client } from "@cocalc/frontend/webapp-client" ;
25
26
import {
26
27
cmp ,
28
+ hoursToTimeIntervalHuman ,
27
29
parse_hashtags ,
28
30
search_match ,
29
31
search_split ,
30
32
} from "@cocalc/util/misc" ;
31
- import { webapp_client } from "../webapp-client" ;
32
33
import { ChatActions , getRootMessage } from "./actions" ;
33
34
import Composing from "./composing" ;
34
35
import Message from "./message" ;
@@ -78,7 +79,7 @@ export function ChatLog(props: Readonly<Props>) {
78
79
actions . setState ( { scrollToBottom : undefined } ) ;
79
80
} , [ scrollToBottom ] ) ;
80
81
81
- const today = useRedux ( [ "today " ] , project_id , path ) ;
82
+ const filterRecentH = useRedux ( [ "filterRecentH " ] , project_id , path ) ;
82
83
const user_map = useTypedRedux ( "users" , "user_map" ) ;
83
84
const account_id = useTypedRedux ( "account" , "account_id" ) ;
84
85
const { dates : sortedDates , numFolded } = useMemo < {
@@ -89,10 +90,10 @@ export function ChatLog(props: Readonly<Props>) {
89
90
messages ,
90
91
search ,
91
92
account_id ,
92
- today ,
93
+ filterRecentH ,
93
94
) ;
94
95
return { dates, numFolded } ;
95
- } , [ messages , search , project_id , path , today ] ) ;
96
+ } , [ messages , search , project_id , path , filterRecentH ] ) ;
96
97
97
98
const visibleHashtags = useMemo ( ( ) => {
98
99
let X = immutableSet < string > ( [ ] ) ;
@@ -115,13 +116,15 @@ export function ChatLog(props: Readonly<Props>) {
115
116
scrollToBottomRef . current = ( force ?: boolean ) => {
116
117
if ( manualScrollRef . current && ! force ) return ;
117
118
manualScrollRef . current = false ;
118
- virtuosoRef . current ?. scrollToIndex ( { index : 99999999999999999999 } ) ;
119
+ virtuosoRef . current ?. scrollToIndex ( { index : Number . MAX_SAFE_INTEGER } ) ;
119
120
// sometimes scrolling to bottom is requested before last entry added,
120
121
// so we do it again in the next render loop. This seems needed mainly
121
122
// for side chat when there is little vertical space.
122
123
setTimeout (
123
124
( ) =>
124
- virtuosoRef . current ?. scrollToIndex ( { index : 99999999999999999999 } ) ,
125
+ virtuosoRef . current ?. scrollToIndex ( {
126
+ index : Number . MAX_SAFE_INTEGER ,
127
+ } ) ,
125
128
0 ,
126
129
) ;
127
130
} ;
@@ -151,7 +154,7 @@ export function ChatLog(props: Readonly<Props>) {
151
154
< NotShowing
152
155
num = { messages . size - numFolded - sortedDates . length }
153
156
search = { search }
154
- today = { today }
157
+ filterRecentH = { filterRecentH }
155
158
/>
156
159
) }
157
160
< Virtuoso
@@ -167,7 +170,10 @@ export function ChatLog(props: Readonly<Props>) {
167
170
}
168
171
169
172
const is_thread = isThread ( messages , message ) ;
170
- const is_folded = isFolded ( messages , message , account_id ) ;
173
+ // if we search for a message, we treat all threads as unfolded
174
+ const force_unfold = ! ! search ;
175
+ const is_folded =
176
+ ! force_unfold && isFolded ( messages , message , account_id ) ;
171
177
const is_thread_body = message . get ( "reply_to" ) != null ;
172
178
173
179
return (
@@ -185,6 +191,7 @@ export function ChatLog(props: Readonly<Props>) {
185
191
actions = { actions }
186
192
is_thread = { is_thread }
187
193
is_folded = { is_folded }
194
+ force_unfold = { force_unfold }
188
195
is_thread_body = { is_thread_body }
189
196
is_prev_sender = { isPrevMessageSender (
190
197
index ,
@@ -304,7 +311,7 @@ export function getSortedDates(
304
311
messages : ChatMessages ,
305
312
search ?: string ,
306
313
account_id ?: string ,
307
- today ?: boolean ,
314
+ filterRecentH ?: number ,
308
315
) : { dates : string [ ] ; numFolded : number } {
309
316
let numFolded = 0 ;
310
317
let m = messages ;
@@ -315,8 +322,9 @@ export function getSortedDates(
315
322
m = m . filter ( ( message ) => searchMatches ( message , searchTerms ) ) ;
316
323
}
317
324
318
- if ( today ) {
319
- const cutoff = webapp_client . server_time ( ) . getTime ( ) - 1000 * 24 * 60 * 60 ;
325
+ if ( typeof filterRecentH === "number" && filterRecentH > 0 ) {
326
+ const now = webapp_client . server_time ( ) . getTime ( ) ;
327
+ const cutoff = now - filterRecentH * 1000 * 60 * 60 ;
320
328
m = m . filter ( ( msg ) => {
321
329
const date = msg . get ( "date" ) . getTime ( ) ;
322
330
return date >= cutoff ;
@@ -327,13 +335,16 @@ export function getSortedDates(
327
335
for ( const [ date , message ] of m ) {
328
336
if ( message == null ) continue ;
329
337
330
- const is_thread = isThread ( messages , message ) ;
331
- const is_folded = isFolded ( messages , message , account_id ) ;
332
- const is_thread_body = message . get ( "reply_to" ) != null ;
333
- const folded = is_thread && is_folded && is_thread_body ;
334
- if ( folded ) {
335
- numFolded ++ ;
336
- continue ;
338
+ // If we search for a message, we treat all threads as unfolded
339
+ if ( ! search ) {
340
+ const is_thread = isThread ( messages , message ) ;
341
+ const is_folded = isFolded ( messages , message , account_id ) ;
342
+ const is_thread_body = message . get ( "reply_to" ) != null ;
343
+ const folded = is_thread && is_folded && is_thread_body ;
344
+ if ( folded ) {
345
+ numFolded ++ ;
346
+ continue ;
347
+ }
337
348
}
338
349
339
350
const reply_to = message . get ( "reply_to" ) ;
@@ -384,8 +395,18 @@ export function getUserName(userMap, accountId: string): string {
384
395
return account . get ( "first_name" , "" ) + " " + account . get ( "last_name" , "" ) ;
385
396
}
386
397
387
- function NotShowing ( { num, search, today } ) {
398
+ interface NotShowingProps {
399
+ num : number ;
400
+ search : string ;
401
+ filterRecentH : number ;
402
+ }
403
+
404
+ function NotShowing ( { num, search, filterRecentH } : NotShowingProps ) {
388
405
if ( num <= 0 ) return null ;
406
+
407
+ const timespan =
408
+ filterRecentH > 0 ? hoursToTimeIntervalHuman ( filterRecentH ) : null ;
409
+
389
410
return (
390
411
< Alert
391
412
style = { { margin : "0" } }
@@ -399,8 +420,10 @@ function NotShowing({ num, search, today }) {
399
420
{ search . trim ( )
400
421
? ` that do not match search for '${ search . trim ( ) } '`
401
422
: "" }
402
- { today
403
- ? ` ${ search . trim ( ) ? "and" : "that" } were not sent today`
423
+ { timespan
424
+ ? ` ${
425
+ search . trim ( ) ? "and" : "that"
426
+ } were not sent in the past ${ timespan } `
404
427
: "" }
405
428
.
406
429
</ b >
0 commit comments