Added new role for moderator to Groups
• Added: - new role for moderator to Groups
This commit is contained in:
parent
cc224d7659
commit
ac9b9e8448
|
@ -24,6 +24,7 @@ class GroupCollectionItem extends ImmutablePureComponent {
|
||||||
|
|
||||||
const isMember = relationships.get('member')
|
const isMember = relationships.get('member')
|
||||||
const isAdmin = relationships.get('admin')
|
const isAdmin = relationships.get('admin')
|
||||||
|
const isModerator = relationships.get('moderator')
|
||||||
const coverSrc = group.get('cover_image_url') || ''
|
const coverSrc = group.get('cover_image_url') || ''
|
||||||
const coverMissing = coverSrc.indexOf(PLACEHOLDER_MISSING_HEADER_SRC) > -1 || !coverSrc
|
const coverMissing = coverSrc.indexOf(PLACEHOLDER_MISSING_HEADER_SRC) > -1 || !coverSrc
|
||||||
|
|
||||||
|
@ -34,6 +35,7 @@ class GroupCollectionItem extends ImmutablePureComponent {
|
||||||
{group.get('title')}
|
{group.get('title')}
|
||||||
{isMember && intl.formatMessage(messages.member)}
|
{isMember && intl.formatMessage(messages.member)}
|
||||||
{isAdmin && intl.formatMessage(messages.admin)}
|
{isAdmin && intl.formatMessage(messages.admin)}
|
||||||
|
{isModerator && intl.formatMessage(messages.moderator)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -69,12 +71,12 @@ class GroupCollectionItem extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
(!coverSrc || coverMissing) && (isMember || isAdmin) &&
|
(!coverSrc || coverMissing) && (isMember || isAdmin || isModerator) &&
|
||||||
<div className={[_s.d, _s.h40PX, _s.bgSubtle, _s.borderColorSecondary, _s.borderBottom1PX].join(' ')} />
|
<div className={[_s.d, _s.h40PX, _s.bgSubtle, _s.borderColorSecondary, _s.borderBottom1PX].join(' ')} />
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
(isMember || isAdmin) &&
|
(isMember || isAdmin || isModerator) &&
|
||||||
<div className={[_s.d, _s.flexRow, _s.posAbs, _s.top0, _s.right0, _s.pt10, _s.mr10].join(' ')}>
|
<div className={[_s.d, _s.flexRow, _s.posAbs, _s.top0, _s.right0, _s.pt10, _s.mr10].join(' ')}>
|
||||||
{
|
{
|
||||||
isMember &&
|
isMember &&
|
||||||
|
@ -98,6 +100,17 @@ class GroupCollectionItem extends ImmutablePureComponent {
|
||||||
{intl.formatMessage(messages.admin)}
|
{intl.formatMessage(messages.admin)}
|
||||||
</Text>
|
</Text>
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
isModerator &&
|
||||||
|
<Text
|
||||||
|
isBadge
|
||||||
|
className={[_s.bgBlack, _s.ml5].join(' ')}
|
||||||
|
size='extraSmall'
|
||||||
|
color='white'
|
||||||
|
>
|
||||||
|
{intl.formatMessage(messages.moderator)}
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +140,7 @@ const messages = defineMessages({
|
||||||
viewGroup: { id: 'view_group', defaultMessage: 'View Group' },
|
viewGroup: { id: 'view_group', defaultMessage: 'View Group' },
|
||||||
member: { id: 'member', defaultMessage: 'Member' },
|
member: { id: 'member', defaultMessage: 'Member' },
|
||||||
admin: { id: 'admin', defaultMessage: 'Admin' },
|
admin: { id: 'admin', defaultMessage: 'Admin' },
|
||||||
|
moderator: { id: 'moderator', defaultMessage: 'Moderator' },
|
||||||
})
|
})
|
||||||
|
|
||||||
const mapStateToProps = (state, { id }) => ({
|
const mapStateToProps = (state, { id }) => ({
|
||||||
|
|
|
@ -15,8 +15,8 @@ class GroupMemberOptionsPopover extends React.PureComponent {
|
||||||
this.props.onCreateRemovedAccount(this.props.groupId, this.props.accountId)
|
this.props.onCreateRemovedAccount(this.props.groupId, this.props.accountId)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleOnMakeAdmin = () => {
|
handleOnUpdateRole = (role) => {
|
||||||
this.props.onUpdateRole(this.props.groupId, this.props.accountId, 'admin')
|
this.props.onUpdateRole(this.props.groupId, this.props.accountId, role)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleOnClosePopover = () => {
|
handleOnClosePopover = () => {
|
||||||
|
@ -24,7 +24,7 @@ class GroupMemberOptionsPopover extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isXS } = this.props
|
const { isModerator, isXS } = this.props
|
||||||
|
|
||||||
const listItems = [
|
const listItems = [
|
||||||
{
|
{
|
||||||
|
@ -33,13 +33,23 @@ class GroupMemberOptionsPopover extends React.PureComponent {
|
||||||
title: 'Remove from group',
|
title: 'Remove from group',
|
||||||
onClick: this.handleOnRemoveFromGroup,
|
onClick: this.handleOnRemoveFromGroup,
|
||||||
},
|
},
|
||||||
{
|
]
|
||||||
|
|
||||||
|
if (!isModerator) {
|
||||||
|
listItems.push({
|
||||||
|
hideArrow: true,
|
||||||
|
icon: 'group',
|
||||||
|
title: 'Make group moderator',
|
||||||
|
onClick: () => this.handleOnUpdateRole('moderator'),
|
||||||
|
})
|
||||||
|
|
||||||
|
listItems.push({
|
||||||
hideArrow: true,
|
hideArrow: true,
|
||||||
icon: 'group',
|
icon: 'group',
|
||||||
title: 'Make group admin',
|
title: 'Make group admin',
|
||||||
onClick: this.handleOnMakeAdmin,
|
onClick: () => this.handleOnUpdateRole('admin'),
|
||||||
},
|
})
|
||||||
]
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PopoverLayout
|
<PopoverLayout
|
||||||
|
@ -77,6 +87,7 @@ GroupMemberOptionsPopover.defaultProps = {
|
||||||
onClosePopover: PropTypes.func.isRequired,
|
onClosePopover: PropTypes.func.isRequired,
|
||||||
onCreateRemovedAccount: PropTypes.func.isRequired,
|
onCreateRemovedAccount: PropTypes.func.isRequired,
|
||||||
onUpdateRole: PropTypes.func.isRequired,
|
onUpdateRole: PropTypes.func.isRequired,
|
||||||
|
isModerator: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps)(GroupMemberOptionsPopover)
|
export default connect(null, mapDispatchToProps)(GroupMemberOptionsPopover)
|
|
@ -149,7 +149,7 @@ class StatusOptionsPopover extends ImmutablePureComponent {
|
||||||
const mutingConversation = status.get('muted')
|
const mutingConversation = status.get('muted')
|
||||||
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'))
|
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'))
|
||||||
const isReply = !!status.get('in_reply_to_id')
|
const isReply = !!status.get('in_reply_to_id')
|
||||||
const withGroupAdmin = !!groupRelationships ? groupRelationships.get('admin') : false
|
const withGroupAdmin = !!groupRelationships ? (groupRelationships.get('admin') || groupRelationships.get('moderator')) : false
|
||||||
const mailToHref = !status ? undefined : `mailto:?subject=Gab&body=${status.get('url')}`
|
const mailToHref = !status ? undefined : `mailto:?subject=Gab&body=${status.get('url')}`
|
||||||
|
|
||||||
let menu = []
|
let menu = []
|
||||||
|
|
|
@ -34,7 +34,10 @@ class GroupMembers extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleOpenGroupMemberOptions = (e, accountId) => {
|
handleOpenGroupMemberOptions = (e, accountId) => {
|
||||||
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(() => {
|
handleLoadMore = debounce(() => {
|
||||||
|
@ -51,9 +54,9 @@ class GroupMembers extends ImmutablePureComponent {
|
||||||
|
|
||||||
if (!group || !relationships) return <ColumnIndicator type='loading' />
|
if (!group || !relationships) return <ColumnIndicator type='loading' />
|
||||||
|
|
||||||
const isAdmin = relationships ? relationships.get('admin') : false
|
const isAdminOrMod = relationships ? (relationships.get('admin') || relationships.get('moderator')) : false
|
||||||
|
|
||||||
if (!isAdmin) return <ColumnIndicator type='missing' />
|
if (!isAdminOrMod) return <ColumnIndicator type='missing' />
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Block>
|
<Block>
|
||||||
|
@ -86,13 +89,14 @@ class GroupMembers extends ImmutablePureComponent {
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
accountIds && accountIds.map((id) => (
|
accountIds && accountIds.map((id) => (
|
||||||
|
// : todo : add badges for isAdmin, isModerator
|
||||||
<Account
|
<Account
|
||||||
compact
|
compact
|
||||||
key={id}
|
key={id}
|
||||||
id={id}
|
id={id}
|
||||||
actionIcon={(!isAdmin || id === me) ? undefined : 'ellipsis'}
|
actionIcon={(!isAdminOrMod || id === me) ? undefined : 'ellipsis'}
|
||||||
onActionClick={(data, event) => {
|
onActionClick={(data, event) => {
|
||||||
return !isAdmin ? false : this.handleOpenGroupMemberOptions(event, id)
|
return !isAdminOrMod ? false : this.handleOpenGroupMemberOptions(event, id)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
|
@ -125,11 +129,12 @@ const mapDispatchToProps = (dispatch) => ({
|
||||||
onExpandMembers(groupId) {
|
onExpandMembers(groupId) {
|
||||||
dispatch(expandMembers(groupId))
|
dispatch(expandMembers(groupId))
|
||||||
},
|
},
|
||||||
onOpenGroupMemberOptions(targetRef, accountId, groupId) {
|
onOpenGroupMemberOptions(targetRef, accountId, groupId, isModerator) {
|
||||||
dispatch(openPopover('GROUP_MEMBER_OPTIONS', {
|
dispatch(openPopover('GROUP_MEMBER_OPTIONS', {
|
||||||
targetRef,
|
targetRef,
|
||||||
accountId,
|
accountId,
|
||||||
groupId,
|
groupId,
|
||||||
|
isModerator,
|
||||||
position: 'top',
|
position: 'top',
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,6 +13,10 @@ module GroupInteractions
|
||||||
follow_mapping(GroupAccount.where(group_id: target_group_ids, account_id: account_id, role: :admin), :group_id)
|
follow_mapping(GroupAccount.where(group_id: target_group_ids, account_id: account_id, role: :admin), :group_id)
|
||||||
end
|
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
|
private
|
||||||
|
|
||||||
def follow_mapping(query, field)
|
def follow_mapping(query, field)
|
||||||
|
|
|
@ -13,7 +13,10 @@
|
||||||
|
|
||||||
class GroupAccount < ApplicationRecord
|
class GroupAccount < ApplicationRecord
|
||||||
self.ignored_columns = ["unread_count"]
|
self.ignored_columns = ["unread_count"]
|
||||||
enum role: { admin: "admin" }
|
enum role: {
|
||||||
|
admin: "admin",
|
||||||
|
moderator: "moderator"
|
||||||
|
}
|
||||||
|
|
||||||
belongs_to :group
|
belongs_to :group
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class GroupRelationshipsPresenter
|
class GroupRelationshipsPresenter
|
||||||
attr_reader :member, :admin
|
attr_reader :member, :admin, :moderator
|
||||||
|
|
||||||
def initialize(group_ids, current_account_id, **options)
|
def initialize(group_ids, current_account_id, **options)
|
||||||
@group_ids = group_ids.map { |a| a.is_a?(Group) ? a.id : a }
|
@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)
|
@member = Group.member_map(@group_ids, @current_account_id)
|
||||||
@admin = Group.admin_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
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class REST::GroupRelationshipSerializer < ActiveModel::Serializer
|
class REST::GroupRelationshipSerializer < ActiveModel::Serializer
|
||||||
attributes :id, :member, :admin
|
attributes :id, :member, :admin, :moderator
|
||||||
|
|
||||||
def id
|
def id
|
||||||
object.id.to_s
|
object.id.to_s
|
||||||
|
@ -15,4 +15,8 @@ class REST::GroupRelationshipSerializer < ActiveModel::Serializer
|
||||||
instance_options[:relationships].admin[object.id] ? true : false
|
instance_options[:relationships].admin[object.id] ? true : false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def moderator
|
||||||
|
instance_options[:relationships].moderator[object.id] ? true : false
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue