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-03-06 15:38:22 +00:00
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
2020-02-29 15:42:47 +00:00
import { defineMessages , injectIntl } from 'react-intl'
2020-03-06 15:38:22 +00:00
import isObject from 'lodash.isobject'
2020-04-28 06:33:58 +01:00
import {
changeGroupTitle ,
2020-09-11 23:27:00 +01:00
changeGroupPassword ,
2020-04-28 06:33:58 +01:00
changeGroupDescription ,
changeGroupCoverImage ,
2020-08-06 05:59:14 +01:00
changeGroupId ,
changeGroupTags ,
changeGroupCategory ,
changeGroupIsPrivate ,
changeGroupIsVisible ,
2020-04-28 06:33:58 +01:00
submit ,
setGroup ,
resetEditor ,
} from '../actions/group_editor'
2020-09-02 19:06:18 +01:00
import {
openModal ,
closeModal ,
} from '../actions/modal'
2020-08-06 05:59:14 +01:00
import { fetchGroup } from '../actions/groups'
import { fetchGroupCategories } from '../actions/group_categories'
2020-09-02 19:06:18 +01:00
import { me } from '../initial_state'
import { MODAL _PRO _UPGRADE } from '../constants'
2020-04-28 06:33:58 +01:00
import ColumnIndicator from '../components/column_indicator'
2020-03-05 15:44:17 +00:00
import Button from '../components/button'
import Divider from '../components/divider'
import Input from '../components/input'
import Text from '../components/text'
2020-04-28 06:33:58 +01:00
import Form from '../components/form'
2020-08-06 05:59:14 +01:00
import Switch from '../components/switch'
import Select from '../components/select'
2020-03-05 15:44:17 +00:00
import Textarea from '../components/textarea'
import FileInput from '../components/file_input'
2019-07-02 08:10:25 +01:00
2020-04-28 06:33:58 +01:00
class GroupCreate extends ImmutablePureComponent {
2019-07-02 08:10:25 +01:00
2019-07-17 19:22:19 +01:00
static contextTypes = {
router : PropTypes . object
}
2020-04-28 06:33:58 +01:00
componentDidMount ( ) {
2020-08-06 05:59:14 +01:00
const { groupId , group } = this . props
this . props . onFetchGroupCategories ( )
if ( ! group ) {
if ( groupId ) {
this . props . onFetchGroup ( groupId )
} else {
this . props . onResetEditor ( )
}
2020-03-06 15:38:22 +00:00
} else {
2020-08-06 05:59:14 +01:00
this . props . onSetGroup ( group )
2020-03-06 15:38:22 +00:00
}
}
componentWillReceiveProps ( nextProps ) {
if ( this . props . group !== nextProps . group && ! ! nextProps . group ) {
2020-04-28 06:33:58 +01:00
this . props . onSetGroup ( nextProps . group )
2020-03-06 15:38:22 +00:00
}
2019-07-17 19:22:19 +01:00
}
2020-04-28 06:33:58 +01:00
handleCoverImageChange = ( e ) => {
2020-07-14 22:37:46 +01:00
try {
this . props . onCoverImageChange ( e . target . files [ 0 ] )
} catch ( error ) {
//
}
2019-07-17 19:22:19 +01:00
}
2020-04-28 06:33:58 +01:00
handleSubmit = ( e ) => {
2020-02-29 15:42:47 +00:00
e . preventDefault ( )
2020-09-02 19:06:18 +01:00
// if not pro and not admin of group show pro upgrade modal
if ( ! this . props . isPro && ! this . props . isAdmin ) {
this . props . onOpenProUpgradeModal ( )
return
}
2020-05-14 21:45:39 +01:00
if ( this . props . onClose ) this . props . onClose ( )
2020-02-29 15:42:47 +00:00
this . props . onSubmit ( this . context . router . history )
2019-07-17 19:22:19 +01:00
}
2020-02-29 15:42:47 +00:00
render ( ) {
2020-03-05 15:44:17 +00:00
const {
2020-03-06 15:38:22 +00:00
group ,
error ,
2020-04-28 06:33:58 +01:00
titleValue ,
descriptionValue ,
2020-09-11 23:27:00 +01:00
passwordValue ,
2020-03-05 15:44:17 +00:00
coverImage ,
2020-04-28 06:33:58 +01:00
intl ,
onTitleChange ,
2020-09-11 23:27:00 +01:00
onChangeGroupPassword ,
2020-04-28 06:33:58 +01:00
onDescriptionChange ,
2020-08-06 05:59:14 +01:00
onChangeGroupId ,
onChangeGroupTags ,
onChangeGroupCategory ,
onChangeGroupIsPrivate ,
onChangeGroupIsVisible ,
2020-04-28 06:33:58 +01:00
isSubmitting ,
onSubmit ,
2020-08-06 05:59:14 +01:00
idValue ,
tags ,
category ,
isPrivate ,
isVisible ,
groupId ,
categories ,
2020-08-08 19:21:18 +01:00
isAdmin ,
2020-09-02 19:06:18 +01:00
isPro ,
2020-03-05 15:44:17 +00:00
} = this . props
2019-07-17 19:22:19 +01:00
2020-08-06 05:59:14 +01:00
if ( ! group && groupId ) {
return < ColumnIndicator type = 'loading' / >
2020-08-11 04:00:35 +01:00
} else if ( ( ! group && error ) || ( groupId && ! isAdmin ) ) {
2020-03-06 15:38:22 +00:00
return < ColumnIndicator type = 'missing' / >
2020-09-02 19:06:18 +01:00
} else if ( ! isPro && ! groupId ) {
return < ColumnIndicator type = 'error' message = { (
< React . Fragment >
< Text > You must be a GabPRO member to create a group . < / T e x t >
< Button
onClick = { this . props . onOpenProUpgradeModal }
className = { [ _s . mt15 , _s . mlAuto , _s . mrAuto ] . join ( ' ' ) }
>
Learn more
< / B u t t o n >
< / R e a c t . F r a g m e n t >
) } / >
2020-03-06 15:38:22 +00:00
}
2020-08-06 05:59:14 +01:00
const memberCount = group ? group . get ( 'member_count' ) : 0
2020-08-08 19:24:09 +01:00
const hasGroupSlug = group ? ! ! group . get ( 'slug' ) : false
2020-09-10 23:12:43 +01:00
let categoriesOptions = [ { 'title' : '' , value : '' } ]
2020-08-06 05:59:14 +01:00
if ( categories ) {
for ( let i = 0 ; i < categories . count ( ) ; i ++ ) {
const c = categories . get ( i )
categoriesOptions . push ( {
title : c . get ( 'text' ) ,
value : c . get ( 'id' ) ,
} )
}
}
2020-09-11 23:27:00 +01:00
const submitDisabled = ( ( ! titleValue || ! category || ! descriptionValue ) && ! groupId ) || isSubmitting
2019-07-17 19:22:19 +01:00
return (
2020-04-28 06:33:58 +01:00
< Form onSubmit = { onSubmit } >
2020-03-05 15:44:17 +00:00
< Input
2020-08-06 05:59:14 +01:00
id = 'group-title'
2020-09-11 23:27:00 +01:00
title = { ` ${ intl . formatMessage ( messages . title ) } * ` }
2020-04-28 06:33:58 +01:00
value = { titleValue }
onChange = { onTitleChange }
disabled = { isSubmitting }
placeholder = { intl . formatMessage ( messages . titlePlaceholder ) }
2020-09-11 23:27:00 +01:00
isRequired
2020-03-05 15:44:17 +00:00
/ >
2020-04-23 07:13:29 +01:00
< Divider isInvisible / >
2020-03-05 15:44:17 +00:00
2020-08-06 05:59:14 +01:00
{
2020-08-08 19:24:09 +01:00
memberCount >= 50 && ! hasGroupSlug &&
2020-08-17 21:07:16 +01:00
< React . Fragment >
2020-08-06 05:59:14 +01:00
< Input
id = 'group-id'
title = { intl . formatMessage ( messages . idTitle ) }
value = { idValue }
onChange = { onChangeGroupId }
disabled = { isSubmitting }
/ >
< Text className = { [ _s . mt5 , _s . pl15 ] } size = 'small' color = 'secondary' >
{
! ! idValue &&
< b > g / { idValue } & nbsp ; – & nbsp ; < / b >
}
{ intl . formatMessage ( messages . idDescription ) }
< / T e x t >
< Divider isInvisible / >
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:59:14 +01:00
}
2020-09-11 23:27:00 +01:00
< Textarea
title = { ` ${ intl . formatMessage ( messages . description ) } * ` }
value = { descriptionValue }
onChange = { onDescriptionChange }
placeholder = { intl . formatMessage ( messages . descriptionPlaceholder ) }
2020-08-06 05:59:14 +01:00
disabled = { isSubmitting }
2020-09-11 23:27:00 +01:00
isRequired
2020-08-06 05:59:14 +01:00
/ >
< Divider isInvisible / >
2020-08-18 21:49:11 +01:00
< div className = { _s . d } >
2020-08-06 05:59:14 +01:00
< Text className = { [ _s . pl15 , _s . mb10 ] . join ( ' ' ) } size = 'small' weight = 'medium' color = 'secondary' >
2020-09-11 23:27:00 +01:00
{ intl . formatMessage ( messages . categoryTitle ) } *
2020-08-06 05:59:14 +01:00
< / T e x t >
< Select
value = { category }
onChange = { onChangeGroupCategory }
options = { categoriesOptions }
/ >
2020-09-11 23:27:00 +01:00
< Text className = { [ _s . mt5 , _s . pl15 ] . join ( ' ' ) } size = 'small' color = 'tertiary' >
2020-08-06 05:59:14 +01:00
{ intl . formatMessage ( messages . categoryDescription ) }
< / T e x t >
< Divider isInvisible / >
< / d i v >
2020-09-11 23:27:00 +01:00
< Input
id = 'group-tags'
title = { intl . formatMessage ( messages . tagsTitle ) }
value = { tags }
onChange = { onChangeGroupTags }
2020-04-28 06:33:58 +01:00
disabled = { isSubmitting }
2020-03-05 15:44:17 +00:00
/ >
2020-09-11 23:27:00 +01:00
< Text className = { [ _s . mt5 , _s . pl15 , _s . mb15 , _s . pb5 ] . join ( ' ' ) } size = 'small' color = 'tertiary' >
{ intl . formatMessage ( messages . tagsDescription ) }
< / T e x t >
2020-03-05 15:44:17 +00:00
2020-09-11 23:27:00 +01:00
< Divider / >
2020-03-05 15:44:17 +00:00
< FileInput
2020-04-28 06:33:58 +01:00
disabled = { isSubmitting }
2020-07-14 22:37:46 +01:00
id = 'group-cover-photo'
2020-03-05 15:44:17 +00:00
title = { intl . formatMessage ( coverImage === null ? messages . coverImage : messages . coverImageChange ) }
onChange = { this . handleCoverImageChange }
2020-06-11 03:16:23 +01:00
file = { group ? group . get ( 'cover_image_url' ) : undefined }
2020-03-05 15:44:17 +00:00
width = '340px'
height = '145px'
2020-07-14 22:37:46 +01:00
isBordered
2020-03-05 15:44:17 +00:00
/ >
2020-09-11 23:27:00 +01:00
< Text className = { [ _s . mt5 , _s . pl15 , _s . mb15 , _s . pb5 ] . join ( ' ' ) } size = 'small' color = 'tertiary' >
2020-08-06 05:59:14 +01:00
{ intl . formatMessage ( messages . coverImageDescription ) }
< / T e x t >
2020-09-11 23:27:00 +01:00
< Divider / >
2020-03-05 15:44:17 +00:00
2020-09-11 23:27:00 +01:00
< Input
id = 'group-password'
title = { intl . formatMessage ( messages . passwordTitle ) }
value = { passwordValue }
onChange = { onChangeGroupPassword }
disabled = { isSubmitting }
2020-08-06 05:59:14 +01:00
/ >
2020-09-11 23:27:00 +01:00
< Text className = { [ _s . mt5 , _s . pl15 , _s . mb15 , _s . pb5 ] . join ( ' ' ) } size = 'small' color = 'tertiary' >
{ intl . formatMessage ( messages . passwordDescription ) }
2020-08-06 05:59:14 +01:00
< / T e x t >
2020-09-11 23:27:00 +01:00
< Divider / >
< div className = { [ _s . d , _s . pl15 ] . join ( ' ' ) } >
< Switch
label = { 'Private' }
id = 'group-isprivate'
checked = { isPrivate }
onChange = { onChangeGroupIsPrivate }
labelProps = { {
size : 'small' ,
weight : 'medium' ,
color : 'secondary' ,
} }
/ >
< Text className = { _s . mt5 } size = 'small' color = 'tertiary' >
{ intl . formatMessage ( messages . isPrivateDescription ) }
< / T e x t >
< Divider isInvisible / >
< Switch
label = { 'Visible' }
id = 'group-isvisible'
checked = { isVisible }
onChange = { onChangeGroupIsVisible }
labelProps = { {
size : 'small' ,
weight : 'medium' ,
color : 'secondary' ,
} }
/ >
< Text className = { _s . mt5 } size = 'small' color = 'tertiary' >
{ intl . formatMessage ( messages . isVisibleDescription ) }
< / T e x t >
< / d i v >
2020-08-06 05:59:14 +01:00
< Divider isInvisible / >
2020-04-28 06:33:58 +01:00
< Button
2020-09-11 23:27:00 +01:00
isDisabled = { submitDisabled }
2020-04-28 06:33:58 +01:00
onClick = { this . handleSubmit }
>
2020-09-11 23:27:00 +01:00
< Text color = 'inherit' align = 'center' weight = 'medium' >
2020-03-06 15:38:22 +00:00
{ intl . formatMessage ( ! ! group ? messages . update : messages . create ) }
2020-03-05 15:44:17 +00:00
< / T e x t >
< / B u t t o n >
2020-04-28 06:33:58 +01:00
< / F o r m >
2020-02-29 15:42:47 +00:00
)
2019-07-17 19:22:19 +01:00
}
2019-07-02 08:10:25 +01:00
}
2020-08-19 01:22:15 +01:00
const messages = defineMessages ( {
title : { id : 'groups.form.title' , defaultMessage : 'Title' } ,
idTitle : { id : 'groups.form.id_title' , defaultMessage : 'Unique id' } ,
idDescription : { id : 'groups.form.id_description' , defaultMessage : 'A unique id that links to this group. (Cannot be changed)' } ,
tagsTitle : { id : 'groups.form.tags_title' , defaultMessage : 'Tags' } ,
2020-09-11 23:27:00 +01:00
tagsDescription : { id : 'groups.form.tags_description' , defaultMessage : '(Optional) Add tags seperated by commas to increase group visibility' } ,
passwordTitle : { id : 'groups.form.password_title' , defaultMessage : 'Password' } ,
passwordDescription : { id : 'groups.form.password_description' , defaultMessage : '(Optional) Add a password to restrict access to this group. This password is NOT encrypted and is only visible to group admins.' } ,
2020-08-19 01:22:15 +01:00
categoryTitle : { id : 'groups.form.category_title' , defaultMessage : 'Category' } ,
categoryDescription : { id : 'groups.form.category_description' , defaultMessage : 'Add a general category for your group' } ,
2020-09-11 23:27:00 +01:00
description : { id : 'groups.form.description' , defaultMessage : 'Description' } ,
coverImage : { id : 'groups.form.coverImage' , defaultMessage : 'Cover image' } ,
coverImageDescription : { id : 'groups.form.coverImage_description' , defaultMessage : '(Optional) Max: 5MB. Accepted image types: .jpg, .png' } ,
coverImageChange : { id : 'groups.form.coverImageChange' , defaultMessage : 'Cover image selected' } ,
2020-08-19 01:22:15 +01:00
create : { id : 'groups.form.create' , defaultMessage : 'Create group' } ,
update : { id : 'groups.form.update' , defaultMessage : 'Update group' } ,
titlePlaceholder : { id : 'groups.form.title_placeholder' , defaultMessage : 'New group title...' } ,
descriptionPlaceholder : { id : 'groups.form.description_placeholder' , defaultMessage : 'This group is about...' } ,
isPrivateDescription : { id : 'groups.form.is_private_description' , defaultMessage : 'Only members can see group posts.' } ,
isVisibleDescription : { id : 'groups.form.is_visible_description' , defaultMessage : 'Anyone can find a visible group in search and other places on Gab.' } ,
} )
const mapStateToProps = ( state , { params } ) => {
const groupId = isObject ( params ) ? params [ 'id' ] : null
const group = state . getIn ( [ 'groups' , groupId ] )
let isAdmin = false
if ( groupId ) {
const relationships = state . getIn ( [ 'group_relationships' , groupId ] )
if ( relationships ) {
isAdmin = relationships . get ( 'admin' )
}
}
return {
group ,
groupId ,
isAdmin ,
error : ( groupId && ! group ) || ( group && ! isAdmin ) ,
titleValue : state . getIn ( [ 'group_editor' , 'title' ] ) ,
2020-09-11 23:27:00 +01:00
passwordValue : state . getIn ( [ 'group_editor' , 'password' ] ) ,
2020-08-19 01:22:15 +01:00
descriptionValue : state . getIn ( [ 'group_editor' , 'description' ] ) ,
coverImage : state . getIn ( [ 'group_editor' , 'coverImage' ] ) ,
isSubmitting : state . getIn ( [ 'group_editor' , 'isSubmitting' ] ) ,
idValue : state . getIn ( [ 'group_editor' , 'id' ] ) ,
tags : state . getIn ( [ 'group_editor' , 'tags' ] ) ,
category : state . getIn ( [ 'group_editor' , 'category' ] ) ,
isPrivate : state . getIn ( [ 'group_editor' , 'isPrivate' ] ) ,
isVisible : state . getIn ( [ 'group_editor' , 'isVisible' ] ) ,
categories : state . getIn ( [ 'group_categories' , 'items' ] ) ,
2020-09-02 19:06:18 +01:00
isPro : state . getIn ( [ 'accounts' , me , 'is_pro' ] ) ,
2020-08-19 01:22:15 +01:00
}
}
const mapDispatchToProps = ( dispatch ) => ( {
onTitleChange ( value ) {
dispatch ( changeGroupTitle ( value ) )
} ,
onDescriptionChange ( value ) {
dispatch ( changeGroupDescription ( value ) )
} ,
2020-09-11 23:27:00 +01:00
onChangeGroupPassword ( value ) {
dispatch ( changeGroupPassword ( value ) )
} ,
2020-08-19 01:22:15 +01:00
onCoverImageChange ( imageData ) {
dispatch ( changeGroupCoverImage ( imageData ) )
} ,
onChangeGroupId ( value ) {
dispatch ( changeGroupId ( value ) )
} ,
onChangeGroupTags ( value ) {
dispatch ( changeGroupTags ( value ) )
} ,
onChangeGroupCategory ( e ) {
dispatch ( changeGroupCategory ( e . target . value ) )
} ,
2020-09-01 20:54:17 +01:00
onChangeGroupIsPrivate ( checked ) {
dispatch ( changeGroupIsPrivate ( checked ) )
2020-08-19 01:22:15 +01:00
} ,
2020-09-01 20:54:17 +01:00
onChangeGroupIsVisible ( checked ) {
dispatch ( changeGroupIsVisible ( checked ) )
2020-08-19 01:22:15 +01:00
} ,
onResetEditor ( ) {
dispatch ( resetEditor ( ) )
} ,
onSetGroup ( group ) {
dispatch ( setGroup ( group ) )
} ,
onSubmit ( routerHistory ) {
dispatch ( submit ( routerHistory ) )
dispatch ( closeModal ( ) )
} ,
onFetchGroup ( groupId ) {
dispatch ( fetchGroup ( groupId ) )
} ,
onFetchGroupCategories ( ) {
dispatch ( fetchGroupCategories ( ) )
2020-09-02 19:06:18 +01:00
} ,
onOpenProUpgradeModal ( ) {
dispatch ( openModal ( MODAL _PRO _UPGRADE ) )
} ,
2020-08-19 01:22:15 +01:00
} )
GroupCreate . propTypes = {
group : ImmutablePropTypes . map ,
titleValue : PropTypes . string . isRequired ,
descriptionValue : PropTypes . string . isRequired ,
coverImage : PropTypes . object ,
intl : PropTypes . object . isRequired ,
onTitleChange : PropTypes . func . isRequired ,
onDescriptionChange : PropTypes . func . isRequired ,
onChangeGroupId : PropTypes . func . isRequired ,
onChangeGroupTags : PropTypes . func . isRequired ,
2020-09-11 23:27:00 +01:00
onChangeGroupPassword : PropTypes . func . isRequired ,
2020-08-19 01:22:15 +01:00
onChangeGroupCategory : PropTypes . func . isRequired ,
onChangeGroupIsPrivate : PropTypes . func . isRequired ,
onChangeGroupIsVisible : PropTypes . func . isRequired ,
onFetchGroup : PropTypes . func . isRequired ,
onFetchGroupCategories : PropTypes . func . isRequired ,
onResetEditor : PropTypes . func . isRequired ,
onSetGroup : PropTypes . func . isRequired ,
onSubmit : PropTypes . func . isRequired ,
2020-09-02 19:06:18 +01:00
onOpenProUpgradeModal : PropTypes . func . isRequired ,
2020-08-19 01:22:15 +01:00
isSubmitting : PropTypes . bool ,
isAdmin : PropTypes . bool ,
onClose : PropTypes . func ,
idValue : PropTypes . string . isRequired ,
tags : PropTypes . string . isRequired ,
category : PropTypes . string . isRequired ,
isPrivate : PropTypes . bool . isRequired ,
isVisible : PropTypes . bool . isRequired ,
categories : ImmutablePropTypes . list . isRequired ,
}
export default injectIntl ( connect ( mapStateToProps , mapDispatchToProps ) ( GroupCreate ) )