2020-08-17 21:07:16 +01:00
import React from 'react'
2020-08-17 21:59:29 +01:00
import PropTypes from 'prop-types'
2020-08-17 21:39:25 +01:00
import { connect } from 'react-redux'
2020-09-10 23:12:43 +01:00
import { NavLink } from 'react-router-dom'
2020-08-06 05:54:23 +01:00
import { defineMessages , injectIntl } from 'react-intl'
2020-02-28 15:20:47 +00:00
import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
2020-08-06 05:54:23 +01:00
import moment from 'moment-mini'
2020-02-28 15:20:47 +00:00
import { shortNumberFormat } from '../../utils/numbers'
2020-09-10 23:12:43 +01:00
import slugify from '../../utils/slugify'
2020-02-28 15:20:47 +00:00
import PanelLayout from './panel_layout'
2020-02-29 15:42:47 +00:00
import Button from '../button'
import Divider from '../divider'
2020-08-06 05:54:23 +01:00
import Heading from '../heading'
2020-02-29 15:42:47 +00:00
import Icon from '../icon'
import Text from '../text'
2020-08-06 05:54:23 +01:00
import DotTextSeperator from '../dot_text_seperator'
import ProfileInfoPanelPlaceholder from '../placeholder/profile_info_panel_placeholder'
2020-02-28 15:20:47 +00:00
class GroupInfoPanel extends ImmutablePureComponent {
2020-09-15 01:53:33 +01:00
state = {
descriptionOpen : false
}
handleToggleDescriptionOpen = ( ) => {
this . setState ( { descriptionOpen : ! this . state . descriptionOpen } )
}
2020-02-28 15:20:47 +00:00
render ( ) {
2020-08-06 05:54:23 +01:00
const {
intl ,
group ,
noPanel ,
relationships ,
} = this . props
2020-09-15 01:53:33 +01:00
const { descriptionOpen } = this . state
2020-05-09 03:17:19 +01:00
2020-08-06 05:54:23 +01:00
if ( ! group && ! noPanel ) {
return (
2020-09-15 06:16:20 +01:00
< PanelLayout title = { intl . formatMessage ( messages . title ) } >
2020-08-06 05:54:23 +01:00
< ProfileInfoPanelPlaceholder / >
2020-09-15 06:16:20 +01:00
< / P a n e l L a y o u t >
2020-08-06 05:54:23 +01:00
)
}
2020-09-11 23:27:00 +01:00
const isAdminOrMod = relationships ? ( relationships . get ( 'admin' ) || relationships . get ( 'moderator' ) ) : false
2020-08-06 05:54:23 +01:00
const groupId = ! ! group ? group . get ( 'id' ) : ''
const slug = ! ! group ? ! ! group . get ( 'slug' ) ? ` g/ ${ group . get ( 'slug' ) } ` : undefined : undefined
const isPrivate = ! ! group ? group . get ( 'is_private' ) : false
const isVisible = ! ! group ? group . get ( 'is_visible' ) : false
const tags = ! ! group ? group . get ( 'tags' ) : [ ]
2020-09-10 23:12:43 +01:00
const groupCategory = ! ! group ? group . getIn ( [ 'group_category' , 'text' ] , null ) : null
2020-09-15 01:53:33 +01:00
2020-09-15 17:03:37 +01:00
const collapsable = ! ! group ? ` ${ group . get ( 'description' ) } ` . length > 500 && noPanel : false
2020-09-15 01:53:33 +01:00
let des = ''
if ( ! ! group ) des = collapsable && ! descriptionOpen ? ` ${ group . get ( 'description_html' ) } ` . substring ( 0 , 500 ) : group . get ( 'description_html' )
const descriptionHTML = ! ! group ? { _ _html : des } : { }
2020-08-06 05:54:23 +01:00
if ( noPanel ) {
return (
2020-08-18 21:49:11 +01:00
< div className = { [ _s . d ] . join ( ' ' ) } >
2020-08-06 05:54:23 +01:00
{
! ! group &&
2020-08-17 21:07:16 +01:00
< React . Fragment >
2020-08-06 05:54:23 +01:00
< Heading isCentered >
{ group . get ( 'title' ) }
< / H e a d i n g >
{
! ! slug &&
< Text className = { _s . mt5 } size = 'small' color = 'secondary' align = 'center' >
{ slug }
< / T e x t >
}
< Text className = { [ _s . mt10 , _s . py2 ] . join ( ' ' ) } color = 'secondary' size = 'small' align = 'center' >
2020-09-02 00:14:11 +01:00
< div className = { _s . dangerousContent } dangerouslySetInnerHTML = { descriptionHTML } / >
2020-09-15 01:53:33 +01:00
{
collapsable &&
< Button
isText
underlineOnHover
color = 'primary'
backgroundColor = 'none'
className = { [ _s . py2 , _s . mlAuto , _s . mrAuto ] . join ( ' ' ) }
onClick = { this . handleToggleDescriptionOpen }
>
< Text size = 'medium' color = 'inherit' weight = 'bold' >
{ intl . formatMessage ( descriptionOpen ? messages . readLess : messages . readMore ) }
< / T e x t >
< / B u t t o n >
}
2020-08-06 05:54:23 +01:00
< / T e x t >
2020-08-18 21:49:11 +01:00
< div className = { [ _s . d , _s . mt10 , _s . flexRow , _s . jcCenter , _s . aiCenter ] . join ( ' ' ) } >
2020-08-06 05:54:23 +01:00
< Text color = 'secondary' size = 'small' align = 'center' >
< Icon
id = { isPrivate ? 'lock-filled' : 'globe' }
size = '10px'
2020-08-18 21:43:06 +01:00
className = { _s . cSecondary }
2020-08-06 05:54:23 +01:00
/ >
< span className = { _s . ml5 } >
{ intl . formatMessage ( isPrivate ? messages . privateGroup : messages . publicGroup ) }
< / s p a n >
< / T e x t >
< DotTextSeperator / >
< Text className = { _s . ml5 } color = 'secondary' size = 'small' align = 'center' >
{ shortNumberFormat ( group . get ( 'member_count' ) ) }
& nbsp ;
{ intl . formatMessage ( messages . members ) }
< / T e x t >
< / d i v >
2020-08-17 21:07:16 +01:00
< / R e a c t . F r a g m e n t >
2020-08-06 05:54:23 +01:00
}
< / d i v >
)
}
2020-02-28 15:20:47 +00:00
return (
2020-08-06 05:54:23 +01:00
< PanelLayout title = { intl . formatMessage ( messages . title ) } >
2020-02-29 15:42:47 +00:00
{
! ! group &&
2020-08-17 21:07:16 +01:00
< React . Fragment >
2020-02-29 15:42:47 +00:00
2020-08-06 05:54:23 +01:00
< Text className = { _s . mb5 } >
2020-09-02 00:14:11 +01:00
< div className = { _s . dangerousContent } dangerouslySetInnerHTML = { descriptionHTML } / >
2020-08-06 05:54:23 +01:00
< / T e x t >
2020-02-29 15:42:47 +00:00
2020-04-23 07:13:29 +01:00
< Divider isSmall / >
2020-02-29 15:42:47 +00:00
2020-08-06 05:54:23 +01:00
< GroupInfoPanelRow
title = { intl . formatMessage ( isPrivate ? messages . privateGroup : messages . publicGroup ) }
icon = { isPrivate ? 'lock-filled' : 'globe' }
>
< Button
isNarrow
backgroundColor = 'secondary'
color = 'secondary'
className = { [ _s . px5 , _s . py2 ] . join ( ' ' ) }
2020-09-10 23:18:13 +01:00
tooltip = { isPrivate ? 'Only members can see group posts' : 'Anyone on or off Gab can view group posts' }
2020-08-06 05:54:23 +01:00
>
< Text size = 'small' color = 'inherit' className = { _s . px5 } > ? < / T e x t >
< / B u t t o n >
< / G r o u p I n f o P a n e l R o w >
2020-02-29 15:42:47 +00:00
2020-08-06 05:54:23 +01:00
< Divider isSmall / >
2020-02-29 15:42:47 +00:00
2020-08-06 05:54:23 +01:00
< GroupInfoPanelRow
title = { intl . formatMessage ( isVisible ? messages . visibleGroup : messages . invisibleGroup ) }
2020-08-17 17:40:17 +01:00
icon = { isVisible ? 'visible' : 'hidden' }
2020-08-06 05:54:23 +01:00
>
< Button
isNarrow
backgroundColor = 'secondary'
2020-04-28 06:33:58 +01:00
color = 'secondary'
2020-08-06 05:54:23 +01:00
className = { [ _s . px5 , _s . py2 ] . join ( ' ' ) }
2020-09-10 23:18:13 +01:00
tooltip = { isVisible ? 'Anyone can find this group in search and other places on gab' : 'The group admin made this group invisible in search and other places on Gab' }
2020-04-28 06:33:58 +01:00
>
2020-08-06 05:54:23 +01:00
< Text size = 'small' color = 'inherit' className = { _s . px5 } > ? < / T e x t >
< / B u t t o n >
< / G r o u p I n f o P a n e l R o w >
2020-09-11 23:27:00 +01:00
2020-08-06 05:54:23 +01:00
< Divider isSmall / >
< GroupInfoPanelRow title = { intl . formatMessage ( messages . members ) } icon = 'group' >
< Button
isText
2020-09-11 23:27:00 +01:00
color = { isAdminOrMod ? 'brand' : 'primary' }
2020-08-06 05:54:23 +01:00
backgroundColor = 'none'
className = { _s . mlAuto }
2020-09-11 23:27:00 +01:00
to = { isAdminOrMod ? ` /groups/ ${ groupId } /members ` : undefined }
2020-08-06 05:54:23 +01:00
>
2020-09-11 23:27:00 +01:00
< Text color = 'inherit' weight = { isAdminOrMod ? 'medium' : 'normal' } size = 'normal' className = { isAdminOrMod ? _s . underline _onHover : undefined } >
2020-08-06 05:54:23 +01:00
{ shortNumberFormat ( group . get ( 'member_count' ) ) }
& nbsp ;
{ intl . formatMessage ( messages . members ) }
< / T e x t >
< / B u t t o n >
< / G r o u p I n f o P a n e l R o w >
2020-04-28 06:33:58 +01:00
2020-09-10 23:12:43 +01:00
{
! ! groupCategory &&
< React . Fragment >
< Divider isSmall / >
2020-04-28 06:33:58 +01:00
2020-09-10 23:12:43 +01:00
< GroupInfoPanelRow title = { intl . formatMessage ( messages . category ) } icon = 'apps' >
< Button
isText
color = 'brand'
backgroundColor = 'none'
className = { _s . mlAuto }
to = { ` /groups/browse/categories/ ${ slugify ( groupCategory ) } ` }
>
< Text color = 'inherit' weight = 'medium' size = 'normal' className = { _s . underline _onHover } >
{ groupCategory }
< / T e x t >
< / B u t t o n >
< / G r o u p I n f o P a n e l R o w >
< / R e a c t . F r a g m e n t >
}
2020-08-06 05:54:23 +01:00
< Divider isSmall / >
< GroupInfoPanelRow title = { intl . formatMessage ( messages . created ) } icon = 'calendar' >
< Text >
{ moment ( group . get ( 'created_at' ) ) . format ( 'LL' ) }
< / T e x t >
< / G r o u p I n f o P a n e l R o w >
{
! ! tags &&
2020-08-17 21:07:16 +01:00
< React . Fragment >
2020-08-06 05:54:23 +01:00
< Divider isSmall / >
< GroupInfoPanelRow title = { intl . formatMessage ( messages . tags ) } icon = 'shop' >
2020-08-18 21:49:11 +01:00
< div className = { [ _s . d , _s . flexRow , _s . jcEnd , _s . flexWrap , _s . pl5 ] . join ( ' ' ) } >
2020-08-06 05:54:23 +01:00
{
tags . map ( ( tag ) => (
< div className = { [ _s . mr5 , _s . mb5 ] . join ( ' ' ) } >
2020-09-11 23:27:00 +01:00
< NavLink
to = { ` /groups/browse/tags/ ${ slugify ( tag ) } ` }
className = { _s . noUnderline }
>
< Text size = 'small' className = { [ _s . bgSecondary , _s . radiusSmall , _s . px10 , _s . py2 , _s . lineHeight15 ] . join ( ' ' ) } >
{ tag }
< / T e x t >
< / N a v L i n k >
2020-08-06 05:54:23 +01:00
< / d i v >
) )
}
< / d i v >
< / G r o u p I n f o P a n e l R o w >
2020-08-17 21:07:16 +01:00
< / R e a c t . F r a g m e n t >
2020-08-06 05:54:23 +01:00
}
2020-08-17 21:07:16 +01:00
< / R e a c t . F r a g m e n t >
2020-02-29 15:42:47 +00:00
}
2020-08-06 05:54:23 +01:00
< / P a n e l L a y o u t >
2020-02-28 15:20:47 +00:00
)
}
2020-08-06 05:54:23 +01:00
}
2020-08-17 21:07:16 +01:00
class GroupInfoPanelRow extends React . PureComponent {
2020-08-06 05:54:23 +01:00
render ( ) {
const { icon , title } = this . props
return (
2020-08-18 21:49:11 +01:00
< div className = { [ _s . d , _s . flexRow , _s . py2 ] . join ( ' ' ) } >
< div className = { [ _s . d , _s . flexRow , _s . jcCenter ] . join ( ' ' ) } >
2020-08-06 05:54:23 +01:00
< Icon id = { icon } size = '16px' / >
< Text weight = 'bold' size = 'medium' className = { _s . ml10 } >
{ title }
< / T e x t >
< / d i v >
< div className = { _s . mlAuto } >
{ this . props . children }
< / d i v >
< / d i v >
)
}
2020-08-19 01:22:15 +01:00
}
GroupInfoPanelRow . propTypes = {
icon : PropTypes . string ,
title : PropTypes . string . isRequired ,
}
const messages = defineMessages ( {
title : { id : 'about' , defaultMessage : 'About' } ,
members : { id : 'members' , defaultMessage : 'Members' } ,
created : { id : 'created' , defaultMessage : 'Created' } ,
category : { id : 'category' , defaultMessage : 'Category' } ,
tags : { id : 'tags' , defaultMessage : 'Tags' } ,
privateGroup : { id : 'group.private' , defaultMessage : 'Private' } ,
publicGroup : { id : 'group.public' , defaultMessage : 'Public' } ,
visibleGroup : { id : 'group.visible' , defaultMessage : 'Visible' } ,
invisibleGroup : { id : 'group.invisible' , defaultMessage : 'Invisible' } ,
2020-09-15 01:53:33 +01:00
readMore : { id : 'status.read_more' , defaultMessage : 'Read more' } ,
readLess : { id : 'status.read_less' , defaultMessage : 'Read less' } ,
2020-08-19 01:22:15 +01:00
} )
const mapStateToProps = ( state , { group } ) => {
const groupId = group ? group . get ( 'id' ) : - 1
const relationships = group === - 1 ? null : state . getIn ( [ 'group_relationships' , groupId ] )
return { relationships }
}
GroupInfoPanel . propTypes = {
group : ImmutablePropTypes . map . isRequired ,
intl : PropTypes . object . isRequired ,
noPanel : PropTypes . bool ,
relationships : ImmutablePropTypes . map ,
}
export default injectIntl ( connect ( mapStateToProps ) ( GroupInfoPanel ) )