Skip to content

Commit

Permalink
HF 30 - Private groups - managing groups
Browse files Browse the repository at this point in the history
  • Loading branch information
1aerostorm committed Jul 22, 2024
1 parent 44992e0 commit 3a704e9
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/assets/icons/ionicons/lock-closed-outline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion src/assets/icons/ionicons/lock-open-outline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
187 changes: 179 additions & 8 deletions src/components/modules/MessagesTopCenter.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import React from 'react'
import {connect} from 'react-redux'
import { withRouter } from 'react-router'
import { Link } from 'react-router-dom'
import { LinkWithDropdown } from 'react-foundation-components/lib/global/dropdown'
import tt from 'counterpart'
import cn from 'classnames'

import { showLoginDialog } from 'app/components/dialogs/LoginDialog'
import DropdownMenu from 'app/components/elements/DropdownMenu'
import ExtLink from 'app/components/elements/ExtLink'
import Icon from 'app/components/elements/Icon'
import TimeAgoWrapper from 'app/components/elements/TimeAgoWrapper'
import transaction from 'app/redux/TransactionReducer'
import user from 'app/redux/UserReducer'
import { getGroupLogo, } from 'app/utils/groups'
import { getGroupLogo, getGroupMeta, getGroupTitle, } from 'app/utils/groups'
import { getLastSeen } from 'app/utils/NormalizeProfile'

class MessagesTopCenter extends React.Component {
Expand All @@ -31,15 +36,149 @@ class MessagesTopCenter extends React.Component {
this.props.showGroupMembers({ group: the_group })
}

editGroup = (e) => {
e.preventDefault()
const { the_group } = this.props
if (!the_group) return
this.props.showGroupSettings({ group: the_group })
}

deleteGroup = (e, title) => {
e.preventDefault()
const { history, the_group } = this.props
if (!the_group) return
showLoginDialog(the_group.owner, (res) => {
const password = res && res.password
if (!password) {
return
}
this.props.deleteGroup({
owner: the_group.owner,
name: the_group.name,
password,
onSuccess: () => {
if (!history || !history.push) {
console.error('No react-router history', history)
return
}
history.push('/')
},
onError: (err, errStr) => {
alert(errStr)
}
})
}, 'active', false, tt('my_groups_jsx.login_hint_GROUP', {
GROUP: title
}))
}

_renderGroupDropdown = () => {
return <div>
Test
const { the_group, username } = this.props
if (!the_group) {
return null
}

const { name, json_metadata, privacy, is_encrypted,
owner, member_list, members, moders } = the_group
const logo = getGroupLogo(json_metadata)

const meta = getGroupMeta(json_metadata)
const title = getGroupTitle(meta, name)

const totalMembers = members + moders

let groupType
if (privacy === 'public_group') {
groupType = tt('msgs_group_dropdown.public')
} else if (privacy === 'public_read_only') {
groupType = tt('msgs_group_dropdown.read_only')
} else {
groupType = tt('msgs_group_dropdown.private')
}
const lock = <Icon size='0_5x'
title={is_encrypted ? tt('msgs_group_dropdown.encrypted') : tt('msgs_group_dropdown.not_encrypted')}
name={is_encrypted ? 'ionicons/lock-closed-outline' : 'ionicons/lock-open-outline'} />
groupType = <div className='group-type'>{groupType}&nbsp;{lock}</div>

let myStatus = null
let btnType
let showKebab, isOwner, banned
if (owner === username) {
myStatus = tt('msgs_group_dropdown.owner')
showKebab = true
} else {
const mem = member_list.find(pgm => pgm.account === username)
const { member_type } = (mem || {})

const isMember = member_type === 'member'
const isModer = member_type === 'moder'

if (!member_type) {
btnType = 'join'
} else if (isModer) {
myStatus = tt('msgs_group_dropdown.moder')
btnType = 'retire'
} else if (isMember) {
btnType = 'retire'
} else if (member_type === 'banned') {
myStatus = tt('msgs_group_dropdown.banned')
banned = true
btnType = 'disabled'
} else if (member_type === 'pending') {
myStatus = tt('msgs_group_dropdown.pending')
btnType = 'cancel'
}
}
if (myStatus) {
myStatus = <div className='group-type'>{myStatus}</div>
}

let btn
if (btnType) {
if (btnType === 'join') {
btn = <button className='button small'>
{tt('msgs_group_dropdown.join')}
</button>
} else {
let btnTitle = tt('msgs_group_dropdown.retire')
if (btnType === 'cancel') {
btnTitle = tt('msgs_group_dropdown.cancel')
}
btn = <button className='button small hollow alert float-right' disabled={btnType === 'disabled'}>
{btnTitle}
</button>
}
}

let kebabItems = [
{ link: '#', value: tt('g.edit'), onClick: this.editGroup },
{ link: '#', value: tt('g.delete'), onClick: e => this.deleteGroup(e, title) },
]

return <div className='msgs-group-dropdown'>
<img className='logo' src={logo} />
<div className='title'>
<b>{title}</b>
</div>
{groupType}
{myStatus}
<div className='buttons'>
{showKebab ? <DropdownMenu className='float-right' el='div' items={kebabItems}>
<Icon name='new/more' size='0_95x' />
</DropdownMenu> : null}
<button className='button small hollow float-right' onClick={e => {
this.openDropdown(e) // hides
this.showGroupMembers(e)
}}>{tt('my_groups_jsx.members') + ' (' + totalMembers + ')'}</button>
{btn}
</div>
</div>
}

render() {
let avatar = []
let items = []
let clickable = false

const { to, toAcc, isSmall, notifyErrors, the_group } = this.props

Expand All @@ -56,7 +195,7 @@ class MessagesTopCenter extends React.Component {
if (the_group) {
const { json_metadata } = the_group
const logo = getGroupLogo(json_metadata)
avatar.push(<div className='group-logo' onClick={this.openDropdown}>
avatar.push(<div className='group-logo'>
<img src={logo} />
</div>)
}
Expand All @@ -71,6 +210,7 @@ class MessagesTopCenter extends React.Component {
</LinkWithDropdown>
{checkmark}
</div>)
clickable = true
} else {
items.push(<div key='to-link' style={{fontSize: '15px', width: '100%', textAlign: 'center'}}>
<ExtLink href={to}>{to}{checkmark}</ExtLink>
Expand Down Expand Up @@ -110,7 +250,7 @@ class MessagesTopCenter extends React.Component {
if (the_group) {
const totalMembers = the_group.members + the_group.moders
items.push(<div key='group-stats' className='group-stats'
style={secondStyle} onClick={this.showGroupMembers}>
style={secondStyle}>
{tt('plurals.member_count', {
count: totalMembers
})}
Expand All @@ -119,14 +259,16 @@ class MessagesTopCenter extends React.Component {
}
}

return <div className='MessagesTopCenter'>
return <div className={cn('MessagesTopCenter', {
clickable
})} onClick={clickable ? this.openDropdown : null}>
<div className='avatar-items'>{avatar}</div>
<div className='main-items'>{items}</div>
</div>
}
}

export default connect(
export default withRouter(connect(
(state, ownProps) => {
const currentUser = state.user.get('current')
const accounts = state.global.get('accounts')
Expand All @@ -148,5 +290,34 @@ export default connect(
showGroupMembers({ group }) {
dispatch(user.actions.showGroupMembers({ group }))
},
showGroupSettings({ group }) {
dispatch(user.actions.showGroupSettings({ group }))
},
deleteGroup: ({ owner, name, password,
onSuccess, onError }) => {
const opData = {
owner,
name,
extensions: [],
}

const json = JSON.stringify(['private_group_delete', opData])

dispatch(transaction.actions.broadcastOperation({
type: 'custom_json',
operation: {
id: 'private_message',
required_auths: [owner],
json,
},
username: owner,
keys: [password],
successCallback: onSuccess,
errorCallback: (err, errStr) => {
console.error(err)
if (onError) onError(err, errStr)
},
}));
}
}),
)(MessagesTopCenter)
)(MessagesTopCenter))
39 changes: 39 additions & 0 deletions src/components/modules/MessagesTopCenter.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
.MessagesTopCenter {
&.clickable {
cursor: pointer;
}

.avatar-items {
display: inline-block;
vertical-align: top;
Expand All @@ -13,6 +17,7 @@
}
}
}

.main-items {
display: inline-block;
.to-group {
Expand All @@ -24,3 +29,37 @@
}
}
}

.msgs-group-dropdown {
.logo {
margin-top: 1rem;
width: 100%;
max-height: 100px;
object-fit: contain;
}
.title {
padding-left: 0.75rem;
padding-right: 0.75rem;
margin-top: 0.5rem;
margin-bottom: 0.15rem;
}
.group-type {
padding-left: 0.75rem;
padding-right: 0.75rem;
margin-bottom: 0.05rem;
}
.buttons {
margin-top: 0.5rem;
padding-left: 0.75rem;
padding-bottom: 0.75rem;
padding-right: 0.75rem;
.button {
margin-right: 0px !important;
margin-bottom: 0.55rem;
}
.DropdownMenu {
margin-left: 0.25rem;
margin-top: 0.25rem;
}
}
}
6 changes: 4 additions & 2 deletions src/components/modules/groups/GroupName.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ export default class GroupName extends React.Component {

onPrivacyChange = (e) => {
const { applyFieldValue } = this.props
applyFieldValue('privacy', e.target.value)
applyFieldValue('is_encrypted', true)
const { value } = e.target
applyFieldValue('privacy', value)
if (value === 'private_group')
applyFieldValue('is_encrypted', true)
}

render() {
Expand Down
1 change: 0 additions & 1 deletion src/components/modules/groups/MyGroups.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { session } from 'app/redux/UserSaga'
import DropdownMenu from 'app/components/elements/DropdownMenu'
import Icon from 'app/components/elements/Icon'
import LoadingIndicator from 'app/components/elements/LoadingIndicator'
import DialogManager from 'app/components/elements/common/DialogManager'
import { showLoginDialog } from 'app/components/dialogs/LoginDialog'
import { getGroupLogo, getGroupMeta } from 'app/utils/groups'

Expand Down
14 changes: 14 additions & 0 deletions src/locales/ru-RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@
"blocked_BY": "Вы заблокированы пользователем @%(BY)s.",
"do_not_bother_BY": "@%(BY)s просит пользователей с низкой репутацией не беспокоить."
},
"msgs_group_dropdown": {
"join": "Вступить",
"retire": "Покинуть",
"cancel": "Отменить",
"public": "Открытая группа",
"read_only": "Группа, открытая только для чтения",
"private": "Закрытая группа",
"encrypted": "Сообщения шифруются",
"not_encrypted": "Сообщения не шифруются",
"banned": "Вы забанены.",
"pending": "Вы подали заявку.",
"moder": "Вы модератор.",
"owner": "Вы владелец."
},
"msgs_start_panel": {
"start_chat": "Начать чат",
"create_group": "Создать группу"
Expand Down

0 comments on commit 3a704e9

Please sign in to comment.