diff --git a/app/javascript/gabsocial/components/group_collection_item.js b/app/javascript/gabsocial/components/group_collection_item.js
index 8377a8ed..87cdfd34 100644
--- a/app/javascript/gabsocial/components/group_collection_item.js
+++ b/app/javascript/gabsocial/components/group_collection_item.js
@@ -24,6 +24,7 @@ class GroupCollectionItem extends ImmutablePureComponent {
const isMember = relationships.get('member')
const isAdmin = relationships.get('admin')
+ const isModerator = relationships.get('moderator')
const coverSrc = group.get('cover_image_url') || ''
const coverMissing = coverSrc.indexOf(PLACEHOLDER_MISSING_HEADER_SRC) > -1 || !coverSrc
@@ -34,6 +35,7 @@ class GroupCollectionItem extends ImmutablePureComponent {
{group.get('title')}
{isMember && intl.formatMessage(messages.member)}
{isAdmin && intl.formatMessage(messages.admin)}
+ {isModerator && intl.formatMessage(messages.moderator)}
)
}
@@ -69,12 +71,12 @@ class GroupCollectionItem extends ImmutablePureComponent {
}
{
- (!coverSrc || coverMissing) && (isMember || isAdmin) &&
+ (!coverSrc || coverMissing) && (isMember || isAdmin || isModerator) &&
}
{
- (isMember || isAdmin) &&
+ (isMember || isAdmin || isModerator) &&
{
isMember &&
@@ -98,6 +100,17 @@ class GroupCollectionItem extends ImmutablePureComponent {
{intl.formatMessage(messages.admin)}
}
+ {
+ isModerator &&
+
+ {intl.formatMessage(messages.moderator)}
+
+ }
}
@@ -127,6 +140,7 @@ const messages = defineMessages({
viewGroup: { id: 'view_group', defaultMessage: 'View Group' },
member: { id: 'member', defaultMessage: 'Member' },
admin: { id: 'admin', defaultMessage: 'Admin' },
+ moderator: { id: 'moderator', defaultMessage: 'Moderator' },
})
const mapStateToProps = (state, { id }) => ({
diff --git a/app/javascript/gabsocial/components/popover/group_member_options_popover.js b/app/javascript/gabsocial/components/popover/group_member_options_popover.js
index c02f7cbf..2c62e172 100644
--- a/app/javascript/gabsocial/components/popover/group_member_options_popover.js
+++ b/app/javascript/gabsocial/components/popover/group_member_options_popover.js
@@ -15,8 +15,8 @@ class GroupMemberOptionsPopover extends React.PureComponent {
this.props.onCreateRemovedAccount(this.props.groupId, this.props.accountId)
}
- handleOnMakeAdmin = () => {
- this.props.onUpdateRole(this.props.groupId, this.props.accountId, 'admin')
+ handleOnUpdateRole = (role) => {
+ this.props.onUpdateRole(this.props.groupId, this.props.accountId, role)
}
handleOnClosePopover = () => {
@@ -24,7 +24,7 @@ class GroupMemberOptionsPopover extends React.PureComponent {
}
render() {
- const { isXS } = this.props
+ const { isModerator, isXS } = this.props
const listItems = [
{
@@ -33,13 +33,23 @@ class GroupMemberOptionsPopover extends React.PureComponent {
title: 'Remove from group',
onClick: this.handleOnRemoveFromGroup,
},
- {
+ ]
+
+ if (!isModerator) {
+ listItems.push({
+ hideArrow: true,
+ icon: 'group',
+ title: 'Make group moderator',
+ onClick: () => this.handleOnUpdateRole('moderator'),
+ })
+
+ listItems.push({
hideArrow: true,
icon: 'group',
title: 'Make group admin',
- onClick: this.handleOnMakeAdmin,
- },
- ]
+ onClick: () => this.handleOnUpdateRole('admin'),
+ })
+ }
return (
{
- this.props.onOpenGroupMemberOptions(e.currentTarget, accountId, this.props.groupId)
+ const { relationships, groupId } = this.props
+
+ const isMod = relationships ? relationships.get('moderator') : true
+ this.props.onOpenGroupMemberOptions(e.currentTarget, accountId, groupId, isMod)
}
handleLoadMore = debounce(() => {
@@ -51,9 +54,9 @@ class GroupMembers extends ImmutablePureComponent {
if (!group || !relationships) return
- const isAdmin = relationships ? relationships.get('admin') : false
+ const isAdminOrMod = relationships ? (relationships.get('admin') || relationships.get('moderator')) : false
- if (!isAdmin) return
+ if (!isAdminOrMod) return
return (
@@ -86,13 +89,14 @@ class GroupMembers extends ImmutablePureComponent {
>
{
accountIds && accountIds.map((id) => (
+ // : todo : add badges for isAdmin, isModerator
{
- return !isAdmin ? false : this.handleOpenGroupMemberOptions(event, id)
+ return !isAdminOrMod ? false : this.handleOpenGroupMemberOptions(event, id)
}}
/>
))
@@ -125,11 +129,12 @@ const mapDispatchToProps = (dispatch) => ({
onExpandMembers(groupId) {
dispatch(expandMembers(groupId))
},
- onOpenGroupMemberOptions(targetRef, accountId, groupId) {
+ onOpenGroupMemberOptions(targetRef, accountId, groupId, isModerator) {
dispatch(openPopover('GROUP_MEMBER_OPTIONS', {
targetRef,
accountId,
groupId,
+ isModerator,
position: 'top',
}))
},
diff --git a/app/models/concerns/group_interactions.rb b/app/models/concerns/group_interactions.rb
index a0833165..6b856599 100644
--- a/app/models/concerns/group_interactions.rb
+++ b/app/models/concerns/group_interactions.rb
@@ -13,6 +13,10 @@ module GroupInteractions
follow_mapping(GroupAccount.where(group_id: target_group_ids, account_id: account_id, role: :admin), :group_id)
end
+ def moderator_map(target_group_ids, account_id)
+ follow_mapping(GroupAccount.where(group_id: target_group_ids, account_id: account_id, role: :moderator), :group_id)
+ end
+
private
def follow_mapping(query, field)
diff --git a/app/models/group_account.rb b/app/models/group_account.rb
index 0f059eee..901f5810 100644
--- a/app/models/group_account.rb
+++ b/app/models/group_account.rb
@@ -13,7 +13,10 @@
class GroupAccount < ApplicationRecord
self.ignored_columns = ["unread_count"]
- enum role: { admin: "admin" }
+ enum role: {
+ admin: "admin",
+ moderator: "moderator"
+ }
belongs_to :group
belongs_to :account
diff --git a/app/presenters/group_relationships_presenter.rb b/app/presenters/group_relationships_presenter.rb
index 55466cf6..a8c9a8a7 100644
--- a/app/presenters/group_relationships_presenter.rb
+++ b/app/presenters/group_relationships_presenter.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class GroupRelationshipsPresenter
- attr_reader :member, :admin
+ attr_reader :member, :admin, :moderator
def initialize(group_ids, current_account_id, **options)
@group_ids = group_ids.map { |a| a.is_a?(Group) ? a.id : a }
@@ -9,6 +9,7 @@ class GroupRelationshipsPresenter
@member = Group.member_map(@group_ids, @current_account_id)
@admin = Group.admin_map(@group_ids, @current_account_id)
+ @moderator = Group.moderator_map(@group_ids, @current_account_id)
end
end
\ No newline at end of file
diff --git a/app/serializers/rest/group_relationship_serializer.rb b/app/serializers/rest/group_relationship_serializer.rb
index ce875681..233de329 100644
--- a/app/serializers/rest/group_relationship_serializer.rb
+++ b/app/serializers/rest/group_relationship_serializer.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class REST::GroupRelationshipSerializer < ActiveModel::Serializer
- attributes :id, :member, :admin
+ attributes :id, :member, :admin, :moderator
def id
object.id.to_s
@@ -15,4 +15,8 @@ class REST::GroupRelationshipSerializer < ActiveModel::Serializer
instance_options[:relationships].admin[object.id] ? true : false
end
+ def moderator
+ instance_options[:relationships].moderator[object.id] ? true : false
+ end
+
end