Skip to content

Commit

Permalink
HF 30 - Private message groups
Browse files Browse the repository at this point in the history
  • Loading branch information
1aerostorm committed Jun 23, 2024
1 parent 50cbc0b commit 58e7238
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 24 deletions.
1 change: 0 additions & 1 deletion src/components/modules/CreateGroup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ class CreateGroup extends React.Component {
}
})
}, 'active')

}

goNext = (e, setFieldValue) => {
Expand Down
213 changes: 191 additions & 22 deletions src/components/modules/groups/GroupSettings.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react'
import DropZone from 'react-dropzone'
import {connect} from 'react-redux'
import { Formik, Form, Field, ErrorMessage, } from 'formik'
import { Map } from 'immutable'
Expand All @@ -15,7 +16,10 @@ 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 { validateLogoStep } from 'app/components/modules/groups/GroupLogo'
import { validateAdminStep } from 'app/components/modules/groups/GroupAdmin'
import { getGroupLogo, getGroupMeta, getGroupTitle } from 'app/utils/groups'
import { proxifyImageUrlWithStrip } from 'app/utils/ProxifyUrl'

class GroupSettings extends React.Component {
constructor(props) {
Expand All @@ -28,7 +32,7 @@ class GroupSettings extends React.Component {
componentDidMount() {
const { currentGroup } = this.props
const group = currentGroup.toJS()
const { name, member_list, privacy, json_metadata } = group
const { name, member_list, privacy, json_metadata, is_encrypted } = group
const meta = getGroupMeta(json_metadata)
let admin
for (const mem of member_list) {
Expand All @@ -38,10 +42,12 @@ class GroupSettings extends React.Component {
break
}
const initialValues = {
name,
title: meta.title,
logo: meta.logo,
admin,
privacy
privacy,
is_encrypted,
}
this.setState({
initialValues
Expand All @@ -66,19 +72,100 @@ class GroupSettings extends React.Component {
applyFieldValue('admin', value)
}

validate = async () => {
uploadLogo = (file, name, { applyFieldValue }) => {
const { uploadImage } = this.props
this.setState({ uploading: true })
uploadImage(file, progress => {
if (progress.url) {
applyFieldValue('logo', progress.url)
}
if (progress.error) {
const { error } = progress;
notify(error, 10000)
}
this.setState({ uploading: false })
})
}

onDrop = (acceptedFiles, rejectedFiles, { applyFieldValue }) => {
const file = acceptedFiles[0]

if (!file) {
if (rejectedFiles.length) {
DialogManager.alert(
tt('post_editor.please_insert_only_image_files')
)
}
return
}

this.uploadLogo(file, file.name, { applyFieldValue })
};

onPrivacyChange = (e, { applyFieldValue }) => {
applyFieldValue('privacy', e.target.value)
}

onSubmit = async () => {
validate = async (values) => {
const errors = {}
if (!values.title) {
errors.title = tt('g.required')
} else if (values.title.length < 3) {
errors.title = tt('create_group_jsx.group_min_length')
}
await validateLogoStep(values, errors)
await validateAdminStep(values, errors)
return errors
}

_onSubmit = async (values, actions) => {
const { currentUser } = this.props
const creator = currentUser.get('username')

this.setState({
submitError: ''
})

showLoginDialog(creator, (res) => {
const password = res && res.password
if (!password) {
actions.setSubmitting(false)
return
}
this.props.privateGroup({
creator,
password,
...values,
onSuccess: () => {
actions.setSubmitting(false)
const { closeMe } = this.props
if (closeMe) closeMe()
},
onError: (err, errStr) => {
this.setState({ submitError: errStr })
actions.setSubmitting(false)
}
})
}, 'active', false)
}

closeMe = (e) => {
e.preventDefault()
this.props.closeMe()
}

_renderPreview = ({ values, errors }) => {
let { logo } = values
if (logo && !errors.logo) {
const size = '75x75' // main size of Userpic
logo = proxifyImageUrlWithStrip(logo, size);
return <a href={logo} target='_blank' rel='noopener noreferrer' style={{ marginLeft: '0.5rem' }}>
{tt('group_settings_jsx.preview')}
</a>
}
return null
}

render() {
const { currentGroup } = this.props
const group = currentGroup.toJS()
Expand All @@ -87,7 +174,7 @@ class GroupSettings extends React.Component {
const meta = getGroupMeta(json_metadata)
const title = getGroupTitle(meta, name)

const { initialValues } = this.state
const { initialValues, submitError } = this.state

let form
if (!initialValues) {
Expand All @@ -104,7 +191,7 @@ class GroupSettings extends React.Component {
{({
handleSubmit, isSubmitting, isValid, values, errors, setFieldValue, applyFieldValue, setFieldTouched, handleChange,
}) => {
const disabled = !isValid
const disabled = !isValid || this.state.uploading
return (
<Form>
<div className='row'>
Expand All @@ -118,32 +205,43 @@ class GroupSettings extends React.Component {
autoFocus
validateOnBlur={false}
/>
<ErrorMessage name='title' component='div' className='error' />
</div>
<div className='column small-6'>
<div className='column small-6' title={tt('group_settings_jsx.name_cannot_change')}>
{tt('create_group_jsx.name2')}<br/>
<div style={{ marginTop: '0.5rem' }}>
{tt('create_group_jsx.name3')}{name}
</div>
</div>
</div>

<div className='row' style={{ marginTop: '1rem' }}>
<div className='column small-12'>
{tt('create_group_jsx.logo')}
<div className="input-group">
<Field
type='text'
name='logo'
className="input-group-field"
maxLength='1024'
placeholder='https://'
onChange={e => this.onLogoChange(e, { applyFieldValue })}
validateOnBlur={false}
/>
<span className="input-group-label">{tt('group_settings_jsx.upload')}</span>
</div>
{tt('create_group_jsx.logo')}{this._renderPreview({ values, errors })}
<DropZone
multiple={false}
noClick={true}
accept='image/*'
onDrop={(af, rf) => this.onDrop(af, rf, { applyFieldValue })}
>
{({getRootProps, getInputProps, open}) => (<div className="input-group" {...getRootProps()}>
<input {...getInputProps()} />
<Field
type='text'
name='logo'
className="input-group-field"
maxLength='1024'
placeholder='https://'
onChange={e => this.onLogoChange(e, { applyFieldValue })}
validateOnBlur={false}
/>
<span className="input-group-label button" onClick={open}>{tt('group_settings_jsx.upload')}</span>
</div>)}
</DropZone>
<ErrorMessage name='logo' component='div' className='error' />
</div>
</div>
<div className='row' style={{ marginTop: '0rem' }}>
<div className='row' style={{ marginTop: '1rem' }}>
<div className='column small-12'>
{tt('create_group_jsx.admin')}
<Field
Expand All @@ -153,13 +251,40 @@ class GroupSettings extends React.Component {
onChange={e => this.onAdminChange(e, { applyFieldValue })}
validateOnBlur={false}
/>
<ErrorMessage name='admin' component='div' className='error' />
</div>
</div>

<div className='row' style={{ marginTop: '1.0rem', }}>
<div className='column small-12'>
{tt('create_group_jsx.access')}
<Icon name='info_o' className='icon-hint' title={tt('create_group_jsx.access_hint')} />
<Field
as='select'
name='privacy'
onChange={e => this.onPrivacyChange(e, { applyFieldValue })}
>
<option value='public_group'>{tt('create_group_jsx.access_all')}</option>
<option value='public_read_only'>{tt('create_group_jsx.all_read_only')}</option>
{values.is_encrypted && <option value='private_group'>{tt('create_group_jsx.access_private')}</option>}
</Field>
<ErrorMessage name='privacy' component='div' className='error' />
</div>
</div>

<div className='row' style={{ marginTop: '1.0rem', }}>
<div className='column small-12' title={tt('group_settings_jsx.encrypted_hint')}>
{tt('group_settings_jsx.encrypted')}
{values.is_encrypted ? tt('group_settings_jsx.encrypted2') : tt('group_settings_jsx.encrypted3')}
</div>
</div>

{submitError && <div style={{ marginTop: '1rem' }} className='error submit-error'>{submitError}</div>}
<div style={{ marginTop: '1rem' }}>
<button className='button hollow float-right' onClick={this.closeMe}>
{tt('g.cancel')}
</button>
<button type='submit' className='button float-right'>
<button type='submit' disabled={disabled} className='button float-right'>
{tt('group_settings_jsx.submit')}
</button>
</div>
Expand Down Expand Up @@ -190,5 +315,49 @@ export default connect(
}
},
dispatch => ({
uploadImage: (file, progress) => {
dispatch({
type: 'user/UPLOAD_IMAGE',
payload: {file, progress},
})
},
privateGroup: ({ password, creator, name, title, logo, admin, is_encrypted, privacy,
onSuccess, onError }) => {
let json_metadata = {
app: 'golos-messenger',
version: 1,
title,
logo
}
json_metadata = JSON.stringify(json_metadata)

const opData = {
creator,
name,
json_metadata,
admin: admin,
is_encrypted,
privacy,
extensions: [],
}

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

dispatch(transaction.actions.broadcastOperation({
type: 'custom_json',
operation: {
id: 'private_message',
required_auths: [creator],
json,
},
username: creator,
password,
successCallback: onSuccess,
errorCallback: (err, errStr) => {
console.error(err)
if (onError) onError(err, errStr)
},
}));
}
})
)(GroupSettings)
14 changes: 14 additions & 0 deletions src/components/modules/groups/GroupSettings.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,18 @@
h3 {
padding-left: 0.75rem;
}
.input-group-label.button {
margin-bottom: 0px;
}
.input-group {
margin-bottom: 0px;
}
.error {
margin-bottom: 0px;
margin-top: 5px;
}
.submit-error {
padding-left: 1rem;
padding-right: 1rem;
}
}
9 changes: 8 additions & 1 deletion src/locales/ru-RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,14 @@
"title_GROUP": "Группа %(GROUP)s",
"submit": "Сохранить",
"owner": "Владелец",
"upload": "Загрузить"
"upload": "Загрузить",
"name_cannot_change": "Ссылку на группу изменить нельзя.",
"preview": "(просмотр)",
"login_hint_GROUP": "(изменения группы \"%(GROUP)s\")",
"encrypted": "Сообщения в группе ",
"encrypted2": " шифруются.",
"encrypted3": " не шифруются.",
"encrypted_hint": "Изменить это нельзя."
},
"emoji_i18n": {
"categoriesLabel": "Категории",
Expand Down
1 change: 1 addition & 0 deletions src/redux/FetchDataSaga.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ export function* fetchMyGroups({ payload: { account } }) {
accounts: [account]
}
})
console.log('LOO', groups)

yield put(g.actions.receiveMyGroups({ groups }))
} catch (err) {
Expand Down
Loading

0 comments on commit 58e7238

Please sign in to comment.