Added pages and routes for Groups by tag and category
• Added: - pages and routes for Groups by tag and category
This commit is contained in:
103
app/javascript/gabsocial/features/group_category.js
Normal file
103
app/javascript/gabsocial/features/group_category.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { connect } from 'react-redux'
|
||||
import { FormattedMessage } from 'react-intl'
|
||||
import slugify from '../utils/slugify'
|
||||
import unslugify from '../utils/unslugify'
|
||||
import { fetchGroupsByCategory } from '../actions/groups'
|
||||
import Block from '../components/block'
|
||||
import ColumnIndicator from '../components/column_indicator'
|
||||
import Heading from '../components/heading'
|
||||
import GroupListItem from '../components/group_list_item'
|
||||
|
||||
class GroupCategory extends ImmutablePureComponent {
|
||||
|
||||
state = {
|
||||
category: this.props.params.sluggedCategory,
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.params.sluggedCategory !== prevProps.params.sluggedCategory) {
|
||||
this.handleLoad(this.props.params.sluggedCategory)
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.handleLoad(this.props.params.sluggedCategory)
|
||||
}
|
||||
|
||||
handleLoad = (sluggedCategory) => {
|
||||
const category = unslugify(sluggedCategory)
|
||||
this.setState({ category })
|
||||
this.props.onFetchGroupsByCategory(category)
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
isFetched,
|
||||
isLoading,
|
||||
groupIds,
|
||||
} = this.props
|
||||
const { category } = this.state
|
||||
|
||||
let errorMessage
|
||||
if (!groupIds || (isFetched && groupIds.size === 0)) {
|
||||
errorMessage = <ColumnIndicator type='error' message={<FormattedMessage id='groups.empty' defaultMessage='There are no groups to display' />} />
|
||||
} else if (isLoading && groupIds.size === 0) {
|
||||
errorMessage = <ColumnIndicator type='loading' />
|
||||
}
|
||||
|
||||
return (
|
||||
<Block>
|
||||
<div className={[_s.d, _s.flexRow, _s.px15, _s.pt10].join(' ')}>
|
||||
<div className={[_s.d, _s.aiStart, _s.overflowHidden].join(' ')}>
|
||||
<Heading size='h2'>
|
||||
Groups by category: {category}
|
||||
</Heading>
|
||||
</div>
|
||||
</div>
|
||||
<div className={[_s.d, _s.py10, _s.w100PC].join(' ')}>
|
||||
{
|
||||
!errorMessage &&
|
||||
groupIds.map((groupId, i) => (
|
||||
<GroupListItem
|
||||
isAddable
|
||||
key={`group-collection-item-${i}`}
|
||||
id={groupId}
|
||||
isLast={groupIds.count() - 1 === i}
|
||||
/>
|
||||
))
|
||||
}
|
||||
{ !!errorMessage && errorMessage}
|
||||
</div>
|
||||
</Block>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, { params: { sluggedCategory } }) => {
|
||||
const cleanSluggedCategory = slugify(sluggedCategory)
|
||||
|
||||
return {
|
||||
groupIds: state.getIn(['group_lists', 'by_category', cleanSluggedCategory, 'items']),
|
||||
isFetched: state.getIn(['group_lists', 'by_category', cleanSluggedCategory, 'isFetched']),
|
||||
isLoading: state.getIn(['group_lists', 'by_category', cleanSluggedCategory, 'isLoading']),
|
||||
}
|
||||
}
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
onFetchGroupsByCategory: (category) => dispatch(fetchGroupsByCategory(category)),
|
||||
})
|
||||
|
||||
GroupCategory.propTypes = {
|
||||
groupIds: ImmutablePropTypes.list,
|
||||
isFetched: PropTypes.bool.isRequired,
|
||||
isLoading: PropTypes.bool.isRequired,
|
||||
onFetchGroupsByCategory: PropTypes.func.isRequired,
|
||||
sluggedCategory: PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(GroupCategory)
|
||||
103
app/javascript/gabsocial/features/group_tag.js
Normal file
103
app/javascript/gabsocial/features/group_tag.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { connect } from 'react-redux'
|
||||
import { FormattedMessage } from 'react-intl'
|
||||
import slugify from '../utils/slugify'
|
||||
import unslugify from '../utils/unslugify'
|
||||
import { fetchGroupsByTag } from '../actions/groups'
|
||||
import Block from '../components/block'
|
||||
import ColumnIndicator from '../components/column_indicator'
|
||||
import Heading from '../components/heading'
|
||||
import GroupListItem from '../components/group_list_item'
|
||||
|
||||
class GroupTag extends ImmutablePureComponent {
|
||||
|
||||
state = {
|
||||
tag: this.props.params.sluggedTag,
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.params.sluggedTag !== prevProps.params.sluggedTag) {
|
||||
this.handleLoad(this.props.params.sluggedTag)
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.handleLoad(this.props.params.sluggedTag)
|
||||
}
|
||||
|
||||
handleLoad = (sluggedTag) => {
|
||||
const tag = unslugify(sluggedTag)
|
||||
this.setState({ tag })
|
||||
this.props.onFetchGroupsByTag(tag)
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
isFetched,
|
||||
isLoading,
|
||||
groupIds,
|
||||
} = this.props
|
||||
const { tag } = this.state
|
||||
|
||||
let errorMessage
|
||||
if (!groupIds || (isFetched && groupIds.size === 0)) {
|
||||
errorMessage = <ColumnIndicator type='error' message={<FormattedMessage id='groups.empty' defaultMessage='There are no groups to display' />} />
|
||||
} else if (isLoading && groupIds.size === 0) {
|
||||
errorMessage = <ColumnIndicator type='loading' />
|
||||
}
|
||||
|
||||
return (
|
||||
<Block>
|
||||
<div className={[_s.d, _s.flexRow, _s.px15, _s.pt10].join(' ')}>
|
||||
<div className={[_s.d, _s.overflowHidden].join(' ')}>
|
||||
<Heading size='h2'>
|
||||
Groups by tag: {tag}
|
||||
</Heading>
|
||||
</div>
|
||||
</div>
|
||||
<div className={[_s.d, _s.py10, _s.w100PC].join(' ')}>
|
||||
{
|
||||
!errorMessage &&
|
||||
groupIds.map((groupId, i) => (
|
||||
<GroupListItem
|
||||
isAddable
|
||||
key={`group-collection-item-${i}`}
|
||||
id={groupId}
|
||||
isLast={groupIds.count() - 1 === i}
|
||||
/>
|
||||
))
|
||||
}
|
||||
{ !!errorMessage && errorMessage}
|
||||
</div>
|
||||
</Block>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, { params: { sluggedTag } }) => {
|
||||
const cleanSluggedTag = slugify(sluggedTag)
|
||||
|
||||
return {
|
||||
groupIds: state.getIn(['group_lists', 'by_tag', cleanSluggedTag, 'items']),
|
||||
isFetched: state.getIn(['group_lists', 'by_tag', cleanSluggedTag, 'isFetched']),
|
||||
isLoading: state.getIn(['group_lists', 'by_tag', cleanSluggedTag, 'isLoading']),
|
||||
}
|
||||
}
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
onFetchGroupsByTag: (tag) => dispatch(fetchGroupsByTag(tag)),
|
||||
})
|
||||
|
||||
GroupTag.propTypes = {
|
||||
groupIds: ImmutablePropTypes.list,
|
||||
isFetched: PropTypes.bool.isRequired,
|
||||
isLoading: PropTypes.bool.isRequired,
|
||||
onFetchGroupsByTag: PropTypes.func.isRequired,
|
||||
sluggedTag: PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(GroupTag)
|
||||
@@ -42,10 +42,10 @@ class GroupsCollection extends ImmutablePureComponent {
|
||||
isFetched,
|
||||
} = this.props
|
||||
|
||||
if (isLoading && groupIds.size === 0) {
|
||||
return <ColumnIndicator type='loading' />
|
||||
} else if (isFetched && groupIds.size === 0) {
|
||||
if (!groupIds || (isFetched && groupIds.size === 0)) {
|
||||
return <ColumnIndicator type='error' message={intl.formatMessage(messages.empty)} />
|
||||
} else if (isLoading && groupIds.size === 0) {
|
||||
return <ColumnIndicator type='loading' />
|
||||
}
|
||||
|
||||
const isAddable = ['featured', 'new'].indexOf(activeTab) > -1
|
||||
|
||||
@@ -70,6 +70,8 @@ import {
|
||||
GroupRemovedAccounts,
|
||||
GroupTimeline,
|
||||
GroupsCategories,
|
||||
GroupCategory,
|
||||
GroupTag,
|
||||
HashtagTimeline,
|
||||
HomeTimeline,
|
||||
Investors,
|
||||
@@ -197,6 +199,8 @@ class SwitchingArea extends React.PureComponent {
|
||||
<WrappedRoute path='/groups/browse/member' exact page={GroupsPage} component={GroupsCollection} content={children} componentParams={{ activeTab: 'member' }} />
|
||||
<WrappedRoute path='/groups/browse/admin' exact page={GroupsPage} component={GroupsCollection} content={children} componentParams={{ activeTab: 'admin' }} />
|
||||
<WrappedRoute path='/groups/browse/categories' exact page={GroupsPage} component={GroupsCategories} content={children} componentParams={{ activeTab: 'categories' }} />
|
||||
<WrappedRoute path='/groups/browse/categories/:sluggedCategory' exact page={GroupsPage} component={GroupCategory} content={children} componentParams={{ activeTab: 'categories' }} />
|
||||
<WrappedRoute path='/groups/browse/tags/:sluggedTag' exact page={GroupsPage} component={GroupTag} content={children} />
|
||||
|
||||
<WrappedRoute path='/groups/create' page={ModalPage} component={GroupCreate} content={children} componentParams={{ title: 'Create Group', page: 'create-group' }} />
|
||||
<WrappedRoute path='/groups/:id/members' page={GroupPage} component={GroupMembers} content={children} />
|
||||
|
||||
@@ -47,8 +47,9 @@ export function GroupRemovedAccounts() { return import(/* webpackChunkName: "fea
|
||||
export function GroupTimeline() { return import(/* webpackChunkName: "features/group_timeline" */'../../group_timeline') }
|
||||
export function GroupTimelineSortOptionsPopover() { return import(/* webpackChunkName: "components/group_timeline_sort_options_popover" */'../../../components/popover/group_timeline_sort_options_popover') }
|
||||
export function GroupTimelineSortTopOptionsPopover() { return import(/* webpackChunkName: "components/group_timeline_sort_top_options_popover" */'../../../components/popover/group_timeline_sort_top_options_popover') }
|
||||
// export function GroupCategory() { return import(/* webpackChunkName: "features/group_category" */'../../group_category') }
|
||||
export function GroupsCategories() { return import(/* webpackChunkName: "features/groups_categories" */'../../groups_categories') }
|
||||
export function GroupCategory() { return import(/* webpackChunkName: "features/group_category" */'../../group_category') }
|
||||
export function GroupTag() { return import(/* webpackChunkName: "features/group_tag" */'../../group_tag') }
|
||||
export function HashtagTimeline() { return import(/* webpackChunkName: "features/hashtag_timeline" */'../../hashtag_timeline') }
|
||||
export function HashtagTimelineSettingsModal() { return import(/* webpackChunkName: "components/hashtag_timeline_settings_modal" */'../../../components/modal/hashtag_timeline_settings_modal') }
|
||||
export function HomeTimeline() { return import(/* webpackChunkName: "features/home_timeline" */'../../home_timeline') }
|
||||
|
||||
Reference in New Issue
Block a user