2022-04-10 01:20:12 -07:00
import { List as ImmutableList } from 'immutable' ;
2022-05-30 09:18:31 -07:00
import React , { useEffect , useState } from 'react' ;
2022-04-10 01:20:12 -07:00
import { FormattedMessage , defineMessages , useIntl } from 'react-intl' ;
import { fetchFavourites , fetchReactions } from 'soapbox/actions/interactions' ;
2022-11-15 08:00:49 -08:00
import ScrollableList from 'soapbox/components/scrollable-list' ;
2022-06-09 12:47:21 -07:00
import { Emoji , Modal , Spinner , Tabs } from 'soapbox/components/ui' ;
2022-04-10 01:20:12 -07:00
import AccountContainer from 'soapbox/containers/account_container' ;
2022-05-28 09:02:04 -07:00
import { useAppDispatch , useAppSelector } from 'soapbox/hooks' ;
2022-06-21 15:29:17 -07:00
import { ReactionRecord } from 'soapbox/reducers/user_lists' ;
2022-04-10 01:20:12 -07:00
2022-06-09 12:47:21 -07:00
import type { Item } from 'soapbox/components/ui/tabs/tabs' ;
2022-04-10 01:20:12 -07:00
const messages = defineMessages ( {
close : { id : 'lightbox.close' , defaultMessage : 'Close' } ,
all : { id : 'reactions.all' , defaultMessage : 'All' } ,
} ) ;
interface IReactionsModal {
onClose : ( string : string ) = > void ,
statusId : string ,
reaction? : string ,
}
2022-05-28 09:02:04 -07:00
const ReactionsModal : React.FC < IReactionsModal > = ( { onClose , statusId , reaction : initialReaction } ) = > {
const dispatch = useAppDispatch ( ) ;
2022-04-10 01:20:12 -07:00
const intl = useIntl ( ) ;
2022-05-28 09:02:04 -07:00
const [ reaction , setReaction ] = useState ( initialReaction ) ;
2022-06-21 15:29:17 -07:00
const reactions = useAppSelector < ImmutableList < ReturnType < typeof ReactionRecord > > | undefined > ( ( state ) = > {
const favourites = state . user_lists . favourited_by . get ( statusId ) ? . items ;
const reactions = state . user_lists . reactions . get ( statusId ) ? . items ;
return favourites && reactions && ImmutableList ( favourites ? . size ? [ ReactionRecord ( { accounts : favourites , count : favourites.size , name : '👍' } ) ] : [ ] ) . concat ( reactions || [ ] ) ;
2022-04-10 01:20:12 -07:00
} ) ;
const fetchData = ( ) = > {
dispatch ( fetchFavourites ( statusId ) ) ;
dispatch ( fetchReactions ( statusId ) ) ;
} ;
const onClickClose = ( ) = > {
onClose ( 'REACTIONS' ) ;
} ;
const renderFilterBar = ( ) = > {
2022-06-09 12:47:21 -07:00
const items : Array < Item > = [
2022-04-10 01:20:12 -07:00
{
text : intl.formatMessage ( messages . all ) ,
action : ( ) = > setReaction ( '' ) ,
name : 'all' ,
} ,
] ;
2022-06-21 15:29:17 -07:00
reactions ! . forEach ( reaction = > items . push (
2022-04-10 01:20:12 -07:00
{
2022-06-09 12:47:21 -07:00
text : < div className = 'flex items-center gap-1' >
< Emoji className = 'w-4 h-4' emoji = { reaction . name } / >
{ reaction . count }
< / div > ,
2022-04-10 01:20:12 -07:00
action : ( ) = > setReaction ( reaction . name ) ,
name : reaction.name ,
} ,
) ) ;
2022-06-09 12:47:21 -07:00
return < Tabs items = { items } activeItem = { reaction || 'all' } / > ;
2022-04-10 01:20:12 -07:00
} ;
useEffect ( ( ) = > {
fetchData ( ) ;
} , [ ] ) ;
const accounts = reactions && ( reaction
? reactions . find ( ( { name } ) = > name === reaction ) ? . accounts . map ( account = > ( { id : account , reaction : reaction } ) )
2022-06-21 15:29:17 -07:00
: reactions . map ( ( { accounts , name } ) = > accounts . map ( account = > ( { id : account , reaction : name } ) ) ) . flatten ( ) ) as ImmutableList < { id : string , reaction : string } > ;
2022-04-10 01:20:12 -07:00
let body ;
if ( ! accounts ) {
body = < Spinner / > ;
} else {
const emptyMessage = < FormattedMessage id = 'status.reactions.empty' defaultMessage = 'No one has reacted to this post yet. When someone does, they will show up here.' / > ;
body = ( < >
2022-06-09 12:47:21 -07:00
{ reactions . size > 0 && renderFilterBar ( ) }
2022-04-10 01:20:12 -07:00
< ScrollableList
scrollKey = 'reactions'
emptyMessage = { emptyMessage }
2022-06-09 12:47:21 -07:00
className = 'mt-4'
2022-04-22 10:24:09 -07:00
itemClassName = 'pb-3'
2022-04-10 01:20:12 -07:00
>
{ accounts . map ( ( account ) = >
2022-06-09 12:47:21 -07:00
< AccountContainer key = { ` ${ account . id } - ${ account . reaction } ` } id = { account . id } emoji = { account . reaction } / > ,
2022-04-10 01:20:12 -07:00
) }
< / ScrollableList >
< / > ) ;
}
return (
< Modal
title = { < FormattedMessage id = 'column.reactions' defaultMessage = 'Reactions' / > }
onClose = { onClickClose }
>
{ body }
< / Modal >
) ;
} ;
export default ReactionsModal ;