Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
gab-social
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
gab
social
gab-social
Commits
fafd1ef6
Commit
fafd1ef6
authored
Sep 14, 2020
by
mgabdev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added pages and routes for Groups by tag and category
• Added: - pages and routes for Groups by tag and category
parent
cb30e0dc
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
355 additions
and
5 deletions
+355
-5
app/controllers/api/v1/groups_controller.rb
app/controllers/api/v1/groups_controller.rb
+21
-1
app/javascript/gabsocial/actions/groups.js
app/javascript/gabsocial/actions/groups.js
+74
-0
app/javascript/gabsocial/features/group_category.js
app/javascript/gabsocial/features/group_category.js
+103
-0
app/javascript/gabsocial/features/group_tag.js
app/javascript/gabsocial/features/group_tag.js
+103
-0
app/javascript/gabsocial/features/groups_collection.js
app/javascript/gabsocial/features/groups_collection.js
+3
-3
app/javascript/gabsocial/features/ui/ui.js
app/javascript/gabsocial/features/ui/ui.js
+4
-0
app/javascript/gabsocial/features/ui/util/async_components.js
...javascript/gabsocial/features/ui/util/async_components.js
+2
-1
app/javascript/gabsocial/reducers/group_lists.js
app/javascript/gabsocial/reducers/group_lists.js
+35
-0
app/javascript/gabsocial/utils/unslugify.js
app/javascript/gabsocial/utils/unslugify.js
+7
-0
config/routes.rb
config/routes.rb
+3
-0
No files found.
app/controllers/api/v1/groups_controller.rb
View file @
fafd1ef6
...
...
@@ -7,7 +7,7 @@ class Api::V1::GroupsController < Api::BaseController
before_action
->
{
doorkeeper_authorize!
:write
,
:'write:groups'
},
except:
[
:index
,
:show
]
before_action
:require_user!
,
except:
[
:index
,
:show
]
before_action
:set_group
,
except:
[
:index
,
:create
]
before_action
:set_group
,
except:
[
:index
,
:create
,
:by_category
,
:by_tag
]
def
index
case
current_tab
...
...
@@ -34,6 +34,26 @@ class Api::V1::GroupsController < Api::BaseController
render
json:
@groups
,
each_serializer:
REST
::
GroupSerializer
end
def
by_category
if
!
current_user
render
json:
{
error:
'This method requires an authenticated user'
},
status:
422
end
@groups
=
[]
render
json:
@groups
,
each_serializer:
REST
::
GroupSerializer
end
def
by_tag
if
!
current_user
render
json:
{
error:
'This method requires an authenticated user'
},
status:
422
end
@groups
=
[]
render
json:
@groups
,
each_serializer:
REST
::
GroupSerializer
end
def
current_tab
tab
=
'featured'
tab
=
params
[
:tab
]
if
[
'featured'
,
'member'
,
'admin'
,
'new'
].
include?
params
[
:tab
]
...
...
app/javascript/gabsocial/actions/groups.js
View file @
fafd1ef6
...
...
@@ -90,6 +90,14 @@ export const GROUP_UNPIN_STATUS_REQUEST = 'GROUP_UNPIN_STATUS_REQUEST'
export
const
GROUP_UNPIN_STATUS_SUCCESS
=
'
GROUP_UNPIN_STATUS_SUCCESS
'
export
const
GROUP_UNPIN_STATUS_FAIL
=
'
GROUP_UNPIN_STATUS_FAIL
'
export
const
GROUPS_BY_CATEGORY_FETCH_REQUEST
=
'
GROUPS_BY_CATEGORY_FETCH_REQUEST
'
export
const
GROUPS_BY_CATEGORY_FETCH_SUCCESS
=
'
GROUPS_BY_CATEGORY_FETCH_SUCCESS
'
export
const
GROUPS_BY_CATEGORY_FETCH_FAIL
=
'
GROUPS_BY_CATEGORY_FETCH_FAIL
'
export
const
GROUPS_BY_TAG_FETCH_REQUEST
=
'
GROUPS_BY_TAG_FETCH_REQUEST
'
export
const
GROUPS_BY_TAG_FETCH_SUCCESS
=
'
GROUPS_BY_TAG_FETCH_SUCCESS
'
export
const
GROUPS_BY_TAG_FETCH_FAIL
=
'
GROUPS_BY_TAG_FETCH_FAIL
'
export
const
GROUP_TIMELINE_SORT
=
'
GROUP_TIMELINE_SORT
'
export
const
GROUP_TIMELINE_TOP_SORT
=
'
GROUP_TIMELINE_TOP_SORT
'
...
...
@@ -210,6 +218,72 @@ export const fetchGroupsFail = (error, tab) => ({
tab
,
});
export
const
fetchGroupsByCategory
=
(
category
)
=>
(
dispatch
,
getState
)
=>
{
// Don't refetch or fetch when loading
const
isLoading
=
getState
().
getIn
([
'
group_lists
'
,
'
by_category
'
,
category
,
'
isLoading
'
],
false
)
if
(
isLoading
)
return
dispatch
(
fetchGroupsByCategoryRequest
(
category
))
api
(
getState
).
get
(
`/api/v1/groups/_/category/
${
category
}
`
)
.
then
(({
data
})
=>
{
dispatch
(
fetchGroupsByCategorySuccess
(
data
,
category
))
dispatch
(
fetchGroupRelationships
(
data
.
map
(
item
=>
item
.
id
)))
})
.
catch
((
err
)
=>
dispatch
(
fetchGroupsByCategoryFail
(
err
,
category
)))
}
export
const
fetchGroupsByCategoryRequest
=
(
category
)
=>
({
type
:
GROUPS_BY_CATEGORY_FETCH_REQUEST
,
category
,
})
export
const
fetchGroupsByCategorySuccess
=
(
groups
,
category
)
=>
({
type
:
GROUPS_BY_CATEGORY_FETCH_SUCCESS
,
groups
,
category
,
})
export
const
fetchGroupsByCategoryFail
=
(
error
,
category
)
=>
({
type
:
GROUPS_BY_CATEGORY_FETCH_FAIL
,
error
,
category
,
})
export
const
fetchGroupsByTag
=
(
tag
)
=>
(
dispatch
,
getState
)
=>
{
// Don't refetch or fetch when loading
const
isLoading
=
getState
().
getIn
([
'
group_lists
'
,
'
by_tag
'
,
tag
,
'
isLoading
'
],
false
)
if
(
isLoading
)
return
dispatch
(
fetchGroupsByTagRequest
(
tag
))
api
(
getState
).
get
(
`/api/v1/groups/_/tag/
${
tag
}
`
)
.
then
(({
data
})
=>
{
dispatch
(
fetchGroupsByTagSuccess
(
data
,
tag
))
dispatch
(
fetchGroupRelationships
(
data
.
map
(
item
=>
item
.
id
)))
})
.
catch
((
err
)
=>
dispatch
(
fetchGroupsByTagFail
(
err
,
tag
)))
}
export
const
fetchGroupsByTagRequest
=
(
tag
)
=>
({
type
:
GROUPS_BY_TAG_FETCH_REQUEST
,
tag
,
})
export
const
fetchGroupsByTagSuccess
=
(
groups
,
tag
)
=>
({
type
:
GROUPS_BY_TAG_FETCH_SUCCESS
,
groups
,
tag
,
})
export
const
fetchGroupsByTagFail
=
(
error
,
tag
)
=>
({
type
:
GROUPS_BY_TAG_FETCH_FAIL
,
error
,
tag
,
})
export
function
joinGroup
(
id
)
{
return
(
dispatch
,
getState
)
=>
{
if
(
!
me
)
return
;
...
...
app/javascript/gabsocial/features/group_category.js
0 → 100644
View file @
fafd1ef6
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
)
\ No newline at end of file
app/javascript/gabsocial/features/group_tag.js
0 → 100644
View file @
fafd1ef6
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
)
\ No newline at end of file
app/javascript/gabsocial/features/groups_collection.js
View file @
fafd1ef6
...
...
@@ -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
...
...
app/javascript/gabsocial/features/ui/ui.js
View file @
fafd1ef6
...
...
@@ -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
}
/
>
...
...
app/javascript/gabsocial/features/ui/util/async_components.js
View file @
fafd1ef6
...
...
@@ -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
'
)
}
...
...
app/javascript/gabsocial/reducers/group_lists.js
View file @
fafd1ef6
...
...
@@ -10,12 +10,19 @@ import {
GROUP_CHECK_PASSWORD_REQUEST
,
GROUP_CHECK_PASSWORD_SUCCESS
,
GROUP_CHECK_PASSWORD_FAIL
,
GROUPS_BY_CATEGORY_FETCH_REQUEST
,
GROUPS_BY_CATEGORY_FETCH_SUCCESS
,
GROUPS_BY_CATEGORY_FETCH_FAIL
,
GROUPS_BY_TAG_FETCH_REQUEST
,
GROUPS_BY_TAG_FETCH_SUCCESS
,
GROUPS_BY_TAG_FETCH_FAIL
,
}
from
'
../actions/groups
'
import
{
GROUP_TIMELINE_SORTING_TYPE_TOP
,
GROUP_TIMELINE_SORTING_TYPE_NEWEST
,
GROUP_TIMELINE_SORTING_TYPE_TOP_OPTION_TODAY
,
}
from
'
../constants
'
import
slugify
from
'
../utils/slugify
'
const
tabs
=
[
'
new
'
,
'
featured
'
,
'
member
'
,
'
admin
'
]
...
...
@@ -43,6 +50,8 @@ const initialState = ImmutableMap({
isLoading
:
false
,
items
:
ImmutableList
(),
}),
by_category
:
ImmutableMap
(),
by_tag
:
ImmutableMap
(),
})
export
default
function
groupLists
(
state
=
initialState
,
action
)
{
...
...
@@ -111,7 +120,33 @@ export default function groupLists(state = initialState, action) {
mutable
.
setIn
([
'
passwordCheck
'
,
'
isLoading
'
],
false
)
})
case
GROUPS_BY_CATEGORY_FETCH_REQUEST
:
return
state
.
setIn
([
'
by_category
'
,
slugify
(
action
.
category
),
'
isLoading
'
],
true
)
case
GROUPS_BY_CATEGORY_FETCH_SUCCESS
:
return
state
.
setIn
([
'
by_category
'
,
slugify
(
action
.
category
)],
ImmutableMap
({
items
:
ImmutableList
(
action
.
groups
.
map
(
item
=>
item
.
id
)),
isLoading
:
false
,
}))
case
GROUPS_BY_CATEGORY_FETCH_FAIL
:
return
state
.
setIn
([
'
by_category
'
,
slugify
(
action
.
category
)],
ImmutableMap
({
items
:
ImmutableList
(),
isLoading
:
false
,
}))
case
GROUPS_BY_TAG_FETCH_REQUEST
:
return
state
.
setIn
([
'
by_tag
'
,
slugify
(
action
.
tag
),
'
isLoading
'
],
true
)
case
GROUPS_BY_TAG_FETCH_SUCCESS
:
return
state
.
setIn
([
'
by_tag
'
,
slugify
(
action
.
tag
)],
ImmutableMap
({
items
:
ImmutableList
(
action
.
groups
.
map
(
item
=>
item
.
id
)),
isLoading
:
false
,
}))
case
GROUPS_BY_TAG_FETCH_FAIL
:
return
state
.
setIn
([
'
by_tag
'
,
slugify
(
action
.
tag
)],
ImmutableMap
({
items
:
ImmutableList
(),
isLoading
:
false
,
}))
default
:
return
state
}
}
app/javascript/gabsocial/utils/unslugify.js
0 → 100644
View file @
fafd1ef6
// https://github.com/danny-wood/unslugify/blob/master/index.js
export
default
function
unslugify
(
text
)
{
const
result
=
`
${
text
}
`
.
replace
(
/
\-
/g
,
"
"
);
return
result
.
replace
(
/
\w\S
*/g
,
function
(
txt
)
{
return
txt
.
charAt
(
0
).
toUpperCase
()
+
txt
.
substr
(
1
).
toLowerCase
();
});
}
config/routes.rb
View file @
fafd1ef6
...
...
@@ -437,6 +437,9 @@ Rails.application.routes.draw do
post
'/statuses/:status_id/approve'
,
to:
'groups#approve_status'
end
get
'/category/:category'
,
to:
'groups#by_category'
get
'/tag/:tag'
,
to:
'groups#by_tag'
resources
:relationships
,
only: :index
,
controller:
'groups/relationships'
resource
:accounts
,
only:
[
:show
,
:create
,
:update
,
:destroy
],
controller:
'groups/accounts'
resource
:removed_accounts
,
only:
[
:show
,
:create
,
:destroy
],
controller:
'groups/removed_accounts'
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment