@@ -2,6 +2,7 @@ import React from 'react';
22import { useTranslationContext } from '../../context' ;
33import { useStateStore } from '../../store' ;
44import type { Reminder , ReminderState } from 'stream-chat' ;
5+ import { IconBellNotification , IconBookmark } from '../Icons' ;
56
67export type ReminderNotificationProps = {
78 reminder ?: Reminder ;
@@ -11,40 +12,92 @@ const reminderStateSelector = (state: ReminderState) => ({
1112 timeLeftMs : state . timeLeftMs ,
1213} ) ;
1314
14- export const ReminderNotification = ( { reminder } : ReminderNotificationProps ) => {
15+ function SavedForLaterContent ( ) {
16+ const { t } = useTranslationContext ( ) ;
17+ return (
18+ < p className = 'str-chat__message-saved-for-later' >
19+ < IconBookmark />
20+ < span > { t ( 'Saved for later' ) } </ span >
21+ </ p >
22+ ) ;
23+ }
24+
25+ const THRESHOLD_RELATIVE_MINUTES = 59 ;
26+
27+ function RemindMeContent ( { reminder } : { reminder : Reminder } ) {
1528 const { t } = useTranslationContext ( ) ;
1629 const { timeLeftMs } = useStateStore ( reminder ?. state , reminderStateSelector ) ?? { } ;
1730
1831 const stopRefreshBoundaryMs = reminder ?. timer . stopRefreshBoundaryMs ;
1932 const stopRefreshTimeStamp =
2033 reminder ?. remindAt && stopRefreshBoundaryMs
21- ? reminder ? .remindAt . getTime ( ) + stopRefreshBoundaryMs
34+ ? reminder . remindAt . getTime ( ) + stopRefreshBoundaryMs
2235 : undefined ;
2336
2437 const isBehindRefreshBoundary =
2538 ! ! stopRefreshTimeStamp && new Date ( ) . getTime ( ) > stopRefreshTimeStamp ;
2639
40+ if ( timeLeftMs === null || ! reminder . remindAt ) return null ;
41+
42+ const nowMs = Date . now ( ) ;
43+ const remindAtMs = reminder . remindAt . getTime ( ) ;
44+ const diffMs = remindAtMs - nowMs ;
45+ const diffMinutes = Math . abs ( diffMs ) / ( 60 * 1000 ) ;
46+ const useAbsoluteFormat = diffMinutes > THRESHOLD_RELATIVE_MINUTES ;
47+
48+ const renderTime = ( ) => {
49+ if ( isBehindRefreshBoundary ) {
50+ // Past: reminder time has passed
51+ if ( useAbsoluteFormat ) {
52+ // > 59 min ago: calendar + time (same as DateSeparator + HH:mm)
53+ // e.g. "Due since Today at 15:00", "Due since Yesterday at 09:30"
54+ return t ( 'Due since {{ dueSince }}' , {
55+ dueSince : t ( 'timestamp/ReminderNotification' , {
56+ timestamp : reminder . remindAt ,
57+ } ) ,
58+ } ) ;
59+ }
60+ // Within 59 min ago: relative
61+ // e.g. "Due since 5 minutes ago", "Due since a minute ago"
62+ return t ( 'Due since {{ dueSince }}' , {
63+ dueSince : t ( 'duration/Message reminder' , {
64+ milliseconds : diffMs ,
65+ } ) ,
66+ } ) ;
67+ }
68+ // Future: reminder not yet due
69+ if ( useAbsoluteFormat ) {
70+ // > 59 min from now: calendar + time (no "Due" prefix)
71+ // e.g. "Today at 15:00", "Tomorrow at 09:30"
72+ return t ( 'timestamp/ReminderNotification' , {
73+ timestamp : reminder . remindAt ,
74+ } ) ;
75+ }
76+ // Within 59 min from now: relative
77+ // e.g. "Due in 30 minutes", "Due in a minute"
78+ return t ( 'Due {{ timeLeft }}' , {
79+ timeLeft : t ( 'duration/Message reminder' , {
80+ milliseconds : timeLeftMs ,
81+ } ) ,
82+ } ) ;
83+ } ;
84+
2785 return (
2886 < p className = 'str-chat__message-reminder' >
29- < span > { t ( 'Saved for later' ) } </ span >
30- { reminder ?. remindAt && timeLeftMs !== null && (
31- < >
32- < span > | </ span >
33- < span >
34- { isBehindRefreshBoundary
35- ? t ( 'Due since {{ dueSince }}' , {
36- dueSince : t ( 'timestamp/ReminderNotification' , {
37- timestamp : reminder . remindAt ,
38- } ) ,
39- } )
40- : t ( 'Due {{ timeLeft }}' , {
41- timeLeft : t ( 'duration/Message reminder' , {
42- milliseconds : timeLeftMs ,
43- } ) ,
44- } ) }
45- </ span >
46- </ >
47- ) }
87+ < IconBellNotification />
88+ < span > { t ( 'Reminder set' ) } </ span >
89+ < span > · </ span >
90+ < span className = 'str-chat__message-reminder__time-left' > { renderTime ( ) } </ span >
4891 </ p >
4992 ) ;
93+ }
94+
95+ export const ReminderNotification = ( { reminder } : ReminderNotificationProps ) => {
96+ if ( ! reminder ) return null ;
97+
98+ if ( ! reminder . remindAt ) {
99+ return < SavedForLaterContent /> ;
100+ }
101+
102+ return < RemindMeContent reminder = { reminder } /> ;
50103} ;
0 commit comments