From ac9b9e84489c0fc50614a4a097387e77dfffcfa7 Mon Sep 17 00:00:00 2001 From: mgabdev <> Date: Wed, 2 Sep 2020 18:06:38 -0500 Subject: [PATCH] Added new role for moderator to Groups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Added: - new role for moderator to Groups --- .../components/group_collection_item.js | 18 +++++++++++-- .../popover/group_member_options_popover.js | 25 +++++++++++++------ .../popover/status_options_popover.js | 2 +- .../gabsocial/features/group_members.js | 17 ++++++++----- app/models/concerns/group_interactions.rb | 4 +++ app/models/group_account.rb | 5 +++- .../group_relationships_presenter.rb | 3 ++- .../rest/group_relationship_serializer.rb | 6 ++++- 8 files changed, 61 insertions(+), 19 deletions(-) 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