@@ -2,6 +2,8 @@ import styles from "./styles.module.scss";
22import { classNames , cn , conditionalClass } from "@/common/classNames" ;
33import {
44 formatTimestamp ,
5+ fullDate ,
6+ fullDateTime ,
57 millisecondsToHhMmSs ,
68 timeElapsed ,
79 timeSince ,
@@ -279,6 +281,18 @@ const MessageItem = (props: MessageItemProps) => {
279281
280282 const { createPortal } = useCustomPortal ( ) ;
281283
284+ const isNewDay = createMemo ( ( ) => {
285+ if ( ! props . beforeMessage ) return true ;
286+ const beforeCreatedAt = new Date ( props . beforeMessage . createdAt ) ;
287+ const createdAt = new Date ( props . message . createdAt ) ;
288+
289+ const nextDay = new Date ( beforeCreatedAt ) ;
290+ nextDay . setDate ( nextDay . getDate ( ) + 1 ) ;
291+ nextDay . setHours ( 0 , 0 , 0 , 0 ) ;
292+
293+ return createdAt >= nextDay ;
294+ } ) ;
295+
282296 const currentTime = props . message ?. createdAt ;
283297 const beforeMessageTime = ( ) => props . beforeMessage ?. createdAt ! ;
284298
@@ -397,110 +411,117 @@ const MessageItem = (props: MessageItemProps) => {
397411 } ;
398412
399413 return (
400- < div
401- class = { classNames (
402- styles . messageItem ,
403- conditionalClass ( isCompact ( ) , styles . compact ) ,
404- conditionalClass ( isMentioned ( ) , styles . mentioned ) ,
405- conditionalClass ( isSomeoneMentioned ( ) , styles . someoneMentioned ) ,
406- props . class ,
407- "messageItem"
408- ) }
409- onContextMenu = { props . contextMenu }
410- onMouseEnter = { ( ) => setHovered ( true ) }
411- onMouseLeave = { ( ) => setHovered ( false ) }
412- id = { `message-${ props . message . id } ` }
413- >
414- < Show when = { ! props . hideFloating } >
415- < FloatOptions
416- textAreaEl = { props . textAreaEl }
417- reactionPickerClick = { props . reactionPickerClick }
418- showContextMenu = { props . contextMenu }
419- isCompact = { isCompact ( ) }
420- message = { props . message }
421- />
414+ < >
415+ < Show when = { isNewDay ( ) } >
416+ < div class = { styles . newDayMarker } >
417+ { fullDate ( props . message . createdAt , "long" , "long" ) }
418+ </ div >
422419 </ Show >
423- < Switch
424- fallback = {
425- < Show when = { blockedMessage ( ) } >
426- < div
427- onClick = { ( ) => setBlockedMessage ( false ) }
428- class = { classNames (
429- styles . blockedMessage ,
430- conditionalClass ( isCompact ( ) , styles . compact )
431- ) }
432- >
433- You have blocked this user. Click to show.
434- </ div >
435- </ Show >
436- }
420+ < div
421+ class = { classNames (
422+ styles . messageItem ,
423+ conditionalClass ( isCompact ( ) , styles . compact ) ,
424+ conditionalClass ( isMentioned ( ) , styles . mentioned ) ,
425+ conditionalClass ( isSomeoneMentioned ( ) , styles . someoneMentioned ) ,
426+ props . class ,
427+ "messageItem"
428+ ) }
429+ onContextMenu = { props . contextMenu }
430+ onMouseEnter = { ( ) => setHovered ( true ) }
431+ onMouseLeave = { ( ) => setHovered ( false ) }
432+ id = { `message-${ props . message . id } ` }
437433 >
438- < Match when = { isSystemMessage ( ) } >
439- < SystemMessage message = { props . message } />
440- </ Match >
441- < Match when = { ! isSystemMessage ( ) && ! blockedMessage ( ) } >
442- < div class = { styles . messageInner } >
443- < MessageReplies message = { props . message } />
444- < div class = { styles . messageInnerInner } >
445- < Show when = { ! isCompact ( ) } >
446- < A
447- onClick = { showProfileFlyout }
448- onContextMenu = { props . userContextMenu }
449- href = { RouterEndpoints . PROFILE ( props . message . createdBy . id ) }
450- class = { classNames ( styles . avatar , "trigger-profile-flyout" ) }
451- >
452- < Avatar
453- animate = { hovered ( ) }
454- user = { props . message . createdBy }
455- size = { 40 }
456- resize = { 96 }
457- />
458- </ A >
459- </ Show >
460- < div class = { styles . messageInnerInnerInner } >
434+ < Show when = { ! props . hideFloating } >
435+ < FloatOptions
436+ textAreaEl = { props . textAreaEl }
437+ reactionPickerClick = { props . reactionPickerClick }
438+ showContextMenu = { props . contextMenu }
439+ isCompact = { isCompact ( ) }
440+ message = { props . message }
441+ />
442+ </ Show >
443+ < Switch
444+ fallback = {
445+ < Show when = { blockedMessage ( ) } >
446+ < div
447+ onClick = { ( ) => setBlockedMessage ( false ) }
448+ class = { classNames (
449+ styles . blockedMessage ,
450+ conditionalClass ( isCompact ( ) , styles . compact )
451+ ) }
452+ >
453+ You have blocked this user. Click to show.
454+ </ div >
455+ </ Show >
456+ }
457+ >
458+ < Match when = { isSystemMessage ( ) } >
459+ < SystemMessage message = { props . message } />
460+ </ Match >
461+ < Match when = { ! isSystemMessage ( ) && ! blockedMessage ( ) } >
462+ < div class = { styles . messageInner } >
463+ < MessageReplies message = { props . message } />
464+ < div class = { styles . messageInnerInner } >
461465 < Show when = { ! isCompact ( ) } >
462- < Details
463- hovered = { hovered ( ) }
464- message = { props . message }
465- isServerCreator = { isServerCreator ( ) }
466- isSystemMessage = { isSystemMessage ( ) }
467- serverMember = { serverMember ( ) }
468- showProfileFlyout = { showProfileFlyout }
469- userContextMenu = { props . userContextMenu }
470- />
466+ < A
467+ onClick = { showProfileFlyout }
468+ onContextMenu = { props . userContextMenu }
469+ href = { RouterEndpoints . PROFILE ( props . message . createdBy . id ) }
470+ class = { classNames ( styles . avatar , "trigger-profile-flyout" ) }
471+ >
472+ < Avatar
473+ animate = { hovered ( ) }
474+ user = { props . message . createdBy }
475+ size = { 40 }
476+ resize = { 96 }
477+ />
478+ </ A >
471479 </ Show >
472- < Content message = { props . message } hovered = { hovered ( ) } />
473- < Show when = { translatedContent ( ) } >
474- < div class = { styles . translationArea } >
475- < span class = { styles . title } >
476- Translation{ " " }
477- < span class = { styles . translationSource } >
478- ({ translatedContent ( ) ?. src } )
480+ < div class = { styles . messageInnerInnerInner } >
481+ < Show when = { ! isCompact ( ) } >
482+ < Details
483+ hovered = { hovered ( ) }
484+ message = { props . message }
485+ isServerCreator = { isServerCreator ( ) }
486+ isSystemMessage = { isSystemMessage ( ) }
487+ serverMember = { serverMember ( ) }
488+ showProfileFlyout = { showProfileFlyout }
489+ userContextMenu = { props . userContextMenu }
490+ />
491+ </ Show >
492+ < Content message = { props . message } hovered = { hovered ( ) } />
493+ < Show when = { translatedContent ( ) } >
494+ < div class = { styles . translationArea } >
495+ < span class = { styles . title } >
496+ Translation{ " " }
497+ < span class = { styles . translationSource } >
498+ ({ translatedContent ( ) ?. src } )
499+ </ span >
479500 </ span >
480- </ span >
481- < Markup
482- text = { translatedContent ( ) ?. translationString ! }
483- replaceCommandBotId
501+ < Markup
502+ text = { translatedContent ( ) ?. translationString ! }
503+ replaceCommandBotId
504+ />
505+ </ div >
506+ </ Show >
507+ < Show when = { props . message . uploadingAttachment } >
508+ < UploadAttachment message = { props . message } />
509+ </ Show >
510+ < Show when = { props . message . reactions ?. length } >
511+ < Reactions
512+ textAreaEl = { props . textAreaEl }
513+ reactionPickerClick = { props . reactionPickerClick }
514+ hovered = { hovered ( ) }
515+ message = { props . message }
484516 />
485- </ div >
486- </ Show >
487- < Show when = { props . message . uploadingAttachment } >
488- < UploadAttachment message = { props . message } />
489- </ Show >
490- < Show when = { props . message . reactions ?. length } >
491- < Reactions
492- textAreaEl = { props . textAreaEl }
493- reactionPickerClick = { props . reactionPickerClick }
494- hovered = { hovered ( ) }
495- message = { props . message }
496- />
497- </ Show >
517+ </ Show >
518+ </ div >
498519 </ div >
499520 </ div >
500- </ div >
501- </ Match >
502- </ Switch >
503- </ div >
521+ </ Match >
522+ </ Switch >
523+ </ div >
524+ </ >
504525 ) ;
505526} ;
506527
0 commit comments