React Activity Feed
Edit page
Introduction
Top Level Components
ActivityFlat feedNotificationNotification dropdownNotification feedPropertiesBasic usageCustomized Notification UISingle postStatus update form
UI Components
Layout Components
Streami18n
Composition Components
Readme

NotificationFeed

This component should be a child of <StreamApp/> component.

Properties

Group
string | number | boolean | ReactElement<PropsWithElementAttributes<{ activityGroup: NotificationActivityEnriched<UT, AT, CT, RT, CRT>; onClickNotification?: ((activityGroup: NotificationActivityEnriched<UT, AT, CT, RT, CRT>) => void) | undefined; onClickUser?: OnClickUserHandler<...> | undefined; onMarkAsRead?: ((g...
< UT extends DefaultUT = DefaultUT, AT extends DefaultAT = DefaultAT, CT extends UR = UR, RT extends UR = UR, CRT extends UR = UR >({ activityGroup, onMarkAsRead, onClickUser, onClickNotification, className, style, }: NotificationProps<UT, AT, CT, RT, CRT>) => { const { t, tDateTimeParser } = useTranslationContext(); const { activities } = activityGroup; const [latestActivity, ...restOfActivities] = activities; if (typeof latestActivity.object === 'string') return null; const lastObject = latestActivity.object as EnrichedActivity; const lastActor = userOrDefault(latestActivity.actor); const headerText = getHeaderText(t, activities.length, latestActivity.verb, lastActor.data.name, lastObject.verb); const handleUserClick = useOnClickUser<UT>(onClickUser); const handleNotificationClick = onClickNotification ? (e: SyntheticEvent) => { e.stopPropagation(); onClickNotification(activityGroup); } : undefined; return ( <div onClick={handleNotificationClick} className={className ?? `raf-notification ${activityGroup.is_read ? 'raf-notification--read' : ''}`} style={style} > <Avatar onClick={handleUserClick?.(lastActor as EnrichedUser<UT>)} image={lastActor.data.profileImage} circle size={30} /> <div className="raf-notification__content"> <div className="raf-notification__header"> <strong>{headerText}</strong> {!activityGroup.is_read && onMarkAsRead && ( <Dropdown> <div> <Link onClick={(e) => { e.stopPropagation(); onMarkAsRead(activityGroup); }} > Mark&nbsp;as&nbsp;read </Link> </div> </Dropdown> )} </div> <div> <small>{humanizeTimestamp(latestActivity.time, tDateTimeParser)}</small> </div> {latestActivity.verb !== 'follow' && ( <AttachedActivity activity={latestActivity.object as EnrichedActivity<UT, AT, CT, RT, CRT>} /> )} </div> <div className="raf-notification__extra"> {activities.length > 1 && latestActivity.verb === 'follow' && ( <AvatarGroup onClickUser={onClickUser} avatarSize={30} users={getUsers<UT, AT, CT, RT, CRT>(restOfActivities) as Array<EnrichedUser<UT>>} /> )} </div> </div> ); }
LoadingIndicator
string | number | boolean | ReactElement<LoadingIndicatorProps, string | ((props: any) => ReactElement<any, any> | null) | (new (props: any) => Component<any, any, any>)> | ComponentClass<...> | FunctionComponent<...> | null | undefined
Notifier
string | number | boolean | ReactElement<PropsWithElementAttributes<{ adds?: any; deletes?: string[] | undefined; labelFunction?: LabelFunction | undefined; labelPlural?: string | undefined; labelSingle?: string | undefined; onClick?: ((event: MouseEvent<...>) => void) | undefined; }, HTMLButtonElement>, string | .....
({ adds = [], deletes = [], labelPlural, labelSingle, onClick, labelFunction, className, style, }: NewActivitiesNotificationProps) => { const { t } = useTranslationContext(); const attributes: Attributes = { addCount: adds.length, deleteCount: deletes.length, count: adds.length + deletes.length, labelPlural, labelSingle, }; const defaultLabelFunction: LabelFunction = labelFunction ?? (({ addCount, labelPlural, labelSingle }) => { if (!addCount) return null; if (addCount > 1) return labelPlural ? generateText(addCount, labelPlural) : t('You have {{ notificationCount }} new notifications', { notificationCount: addCount, }); return labelSingle ? generateText(1, labelSingle) : t('You have 1 new notification'); }); const label = defaultLabelFunction(attributes); if (!label) return null; return ( <button className={classNames('raf-new-activities-notification', className)} type="button" onClick={onClick} style={style} > <Link>{label}</Link> </button> ); }
Paginator
string | number | boolean | ReactElement<LoadMorePaginatorProps, string | ((props: any) => ReactElement<any, any> | null) | (new (props: any) => Component<any, any, any>)> | ComponentClass<...> | FunctionComponent<...> | null | undefined
({ LoadMoreButton = DefaultLoadMoreButton, children, reverse, hasNextPage, refreshing, loadNextPage, }: LoadMorePaginatorProps) => ( <> {!reverse && children} {hasNextPage && smartRender<LoadMoreButtonProps>(LoadMoreButton, { refreshing, onClick: loadNextPage })} {reverse && children} </> )
Placeholder
string | number | boolean | ReactElement<PropsWithElementAttributes<{ text?: string | undefined; }, HTMLDivElement>, string | ((props: any) => ReactElement<any, any> | null) | (new (props: any) => Component<...>)> | ComponentClass<...> | FunctionComponent<...> | null | undefined
({ text, className, style }: FeedPlaceholderProps) => { const { t } = useTranslationContext(); return ( <div className={classNames('raf-feed-placeholder', className)} style={style}> <p>{text || t('No data to display...')}</p> </div> ); }
options
GetFeedOptions | undefined
feedGroup
string | undefined
notification
userId
string | undefined
analyticsLocation
string | undefined
doActivityDeleteRequest
DeleteRequestFn | undefined
doChildReactionAddRequest
((kind: string, reaction: Reaction<RT>, data?: CRT | undefined, options?: ReactionAddChildOptions | undefined) => Promise<ReactionAPIResponse<CRT>>) | undefined
doChildReactionDeleteRequest
DeleteRequestFn | undefined
doFeedRequest
((client: StreamClient<UT, AT, CT, RT, CRT, PT>, feedGroup: string, userId?: string | undefined, options?: GetFeedOptions | undefined) => Promise<FeedAPIResponse<UT, AT, CT, RT, CRT>>) | undefined
doReactionAddRequest
((kind: string, activity: Activity<AT>, data?: RT | undefined, options?: ReactionAddOptions | undefined) => Promise<ReactionAPIResponse<RT>>) | undefined
doReactionDeleteRequest
DeleteRequestFn | undefined
doReactionsFilterRequest
((options: ReactionFilterConditions) => Promise<ReactionFilterAPIResponse<RT, CRT, AT, UT>>) | undefined
notify
boolean | undefined

Basic usage

Customized Notification UI