@@ -4,6 +4,7 @@ import { Animated, Image, StyleSheet, Text, TouchableOpacity, View } from 'react
44import type { NotificationCardProps } from '../types' ;
55import { CommonUtils , useSiren } from '../utils' ;
66import { eventTypes , events } from '../utils/constants' ;
7+ import { useSirenContext } from './sirenProvider' ;
78import CloseIcon from './closeIcon' ;
89import TimerIcon from './timerIcon' ;
910
@@ -47,28 +48,39 @@ const Card = (props: NotificationCardProps): ReactElement => {
4748 disableAutoMarkAsRead,
4849 hideDelete = false ,
4950 onAvatarClick,
50- deleteIcon = null
51+ deleteIcon = null ,
52+ hideMediaThumbnail = false ,
53+ onMediaThumbnailClick
5154 } = cardProps ;
5255 const { markAsReadById } = useSiren ( ) ;
56+ const { id : providerId } = useSirenContext ( ) ;
5357
5458 const opacity = useRef ( new Animated . Value ( 1 ) ) . current ;
5559
5660 const emptyState = ( ) => {
5761 return darkMode ? require ( '../assets/emptyDark.png' ) : require ( '../assets/emptyLight.png' ) ;
5862 } ;
5963
64+ const failedState = ( ) => {
65+ return darkMode
66+ ? require ( '../assets/failedImageDark.png' )
67+ : require ( '../assets/failedImageLight.png' ) ;
68+ } ;
69+
70+ const avatarUrl = notification ?. message ?. avatar ?. imageUrl || '' ;
71+ const thumbnailUrl = notification ?. message ?. thumbnailUrl || '' ;
72+
6073 const [ imageSource , setImageSource ] = useState (
61- notification ?. message ?. avatar ?. imageUrl ?. length > 0
62- ? { uri : notification . message ?. avatar ?. imageUrl }
63- : emptyState ( )
74+ avatarUrl ?. length > 0 ? { uri : avatarUrl } : emptyState ( )
75+ ) ;
76+
77+ const [ mediaSource , setMediaSource ] = useState (
78+ thumbnailUrl ?. length > 0 ? { uri : thumbnailUrl } : emptyState ( )
6479 ) ;
6580
6681 useEffect ( ( ) => {
67- setImageSource (
68- notification ?. message ?. avatar ?. imageUrl ?. length > 0
69- ? { uri : notification . message ?. avatar ?. imageUrl }
70- : emptyState ( )
71- ) ;
82+ setImageSource ( avatarUrl ?. length > 0 ? { uri : avatarUrl } : emptyState ( ) ) ;
83+ setMediaSource ( thumbnailUrl ?. length > 0 ? { uri : thumbnailUrl } : failedState ( ) ) ;
7284 } , [ notification , darkMode ] ) ;
7385
7486 const cardClick = ( ) : void => {
@@ -80,10 +92,18 @@ const Card = (props: NotificationCardProps): ReactElement => {
8092 setImageSource ( emptyState ( ) ) ;
8193 } ;
8294
95+ const onErrorMedia = ( ) : void => {
96+ setMediaSource ( failedState ( ) ) ;
97+ } ;
98+
8399 const avatarClick = ( ) => {
84100 if ( onAvatarClick ) onAvatarClick ( notification ) ;
85101 } ;
86102
103+ const mediaClick = ( ) => {
104+ if ( onMediaThumbnailClick ) onMediaThumbnailClick ( notification ) ;
105+ } ;
106+
87107 const renderAvatar = useMemo ( ( ) : JSX . Element => {
88108 return (
89109 < View style = { style . cardIconContainer } >
@@ -104,6 +124,18 @@ const Card = (props: NotificationCardProps): ReactElement => {
104124 ) ;
105125 } , [ styles , darkMode , imageSource , onAvatarClick ] ) ;
106126
127+ const renderMediaThumbnail = useMemo ( ( ) : JSX . Element => {
128+ return (
129+ < TouchableOpacity
130+ style = { [ style . mediaContainer , styles . mediaContainer ] }
131+ disabled = { Boolean ( ! onMediaThumbnailClick ) }
132+ onPress = { mediaClick }
133+ >
134+ < Image source = { mediaSource } resizeMode = 'cover' style = { style . icon } onError = { onErrorMedia } />
135+ </ TouchableOpacity >
136+ ) ;
137+ } , [ darkMode , mediaSource , onMediaThumbnailClick ] ) ;
138+
107139 const onDeleteItem = async ( ) : Promise < void > => {
108140 const isSuccess = await onDelete ( notification . id , false ) ;
109141
@@ -115,7 +147,7 @@ const Card = (props: NotificationCardProps): ReactElement => {
115147 } ) . start ( ( ) => {
116148 const payload = { id : notification . id , action : eventTypes . DELETE_ITEM } ;
117149
118- PubSub . publish ( events . NOTIFICATION_LIST_EVENT , JSON . stringify ( payload ) ) ;
150+ PubSub . publish ( ` ${ events . NOTIFICATION_LIST_EVENT } ${ providerId } ` , JSON . stringify ( payload ) ) ;
119151 } ) ;
120152 } ;
121153
@@ -141,19 +173,28 @@ const Card = (props: NotificationCardProps): ReactElement => {
141173 < Text numberOfLines = { 2 } style = { [ styles . cardTitle , style . cardTitle ] } >
142174 { notification . message ?. header }
143175 </ Text >
144- { ! hideDelete &&
145- ( deleteIcon || (
146- < CloseIcon onDelete = { onDeleteItem } notification = { notification } styles = { styles } />
147- ) ) }
176+ { ! hideDelete && (
177+ < CloseIcon
178+ onDelete = { onDeleteItem }
179+ customIcon = { deleteIcon }
180+ notification = { notification }
181+ styles = { styles }
182+ />
183+ ) }
148184 </ View >
149185 { Boolean ( notification . message ?. subHeader ) && (
150186 < Text numberOfLines = { 2 } style = { [ style . cardSubTitle , styles . cardSubTitle ] } >
151187 { notification . message ?. subHeader }
152188 </ Text >
153189 ) }
154- < Text numberOfLines = { 2 } style = { [ style . cardDescription , styles . cardDescription ] } >
155- { notification . message ?. body }
156- </ Text >
190+ { Boolean ( notification . message ?. body ) && (
191+ < Text numberOfLines = { 2 } style = { [ style . cardDescription , styles . cardDescription ] } >
192+ { notification . message ?. body }
193+ </ Text >
194+ ) }
195+ { ! hideMediaThumbnail &&
196+ Boolean ( notification . message ?. thumbnailUrl ) &&
197+ renderMediaThumbnail }
157198 < View style = { style . dateContainer } >
158199 < TimerIcon styles = { styles } />
159200 < Text style = { [ style . dateStyle , styles . dateStyle ] } >
@@ -228,6 +269,14 @@ const style = StyleSheet.create({
228269 } ,
229270 transparent : {
230271 backgroundColor : 'transparent'
272+ } ,
273+ mediaContainer : {
274+ width : '100%' ,
275+ height : 130 ,
276+ borderRadius : 6 ,
277+ marginBottom : 10 ,
278+ overflow : 'hidden' ,
279+ backgroundColor : '#D3D3D3'
231280 }
232281} ) ;
233282
0 commit comments