Change report modal to include category selection in web UI (#17565)

* Change report modal to include category selection in web UI

* Various fixes and improvements

- Change thank you text to be different based on category
- Change starting headline to be different for account and status reports
- Change toggle components to have a checkmark when checked
- Fix report dialog being cut off on small screens
- Fix thank you screen offering mute or block if already muted or blocked
- Refactor toggle components in report dialog into one component

* Change wording on final screen

* Change checkboxes to be square when multiple options are possible
This commit is contained in:
Eugen Rochko
2022-02-23 20:03:46 +01:00
committed by GitHub
parent 1c3e5e44e2
commit a9a43de6d1
15 changed files with 954 additions and 232 deletions

View File

@ -0,0 +1,60 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Check from 'mastodon/components/check';
export default class Option extends React.PureComponent {
static propTypes = {
name: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
checked: PropTypes.bool,
label: PropTypes.node,
description: PropTypes.node,
onToggle: PropTypes.func,
multiple: PropTypes.bool,
labelComponent: PropTypes.node,
};
handleKeyPress = e => {
const { value, checked, onToggle } = this.props;
if (e.key === 'Enter' || e.key === ' ') {
e.stopPropagation();
e.preventDefault();
onToggle(value, !checked);
}
}
handleChange = e => {
const { value, onToggle } = this.props;
onToggle(value, e.target.checked);
}
render () {
const { name, value, checked, label, labelComponent, description, multiple } = this.props;
return (
<label className='dialog-option poll__option selectable'>
<input type={multiple ? 'checkbox' : 'radio'} name={name} value={value} checked={checked} onChange={this.handleChange} />
<span
className={classNames('poll__input', { active: checked, checkbox: multiple })}
tabIndex='0'
role='radio'
onKeyPress={this.handleKeyPress}
aria-checked={checked}
aria-label={label}
>{checked && <Check />}</span>
{labelComponent ? labelComponent : (
<span className='poll__option__text'>
<strong>{label}</strong>
{description}
</span>
)}
</label>
);
}
}

View File

@ -1,23 +1,32 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import Toggle from 'react-toggle';
import noop from 'lodash/noop';
import StatusContent from '../../../components/status_content';
import { MediaGallery, Video } from '../../ui/util/async-components';
import Bundle from '../../ui/components/bundle';
import StatusContent from 'mastodon/components/status_content';
import { MediaGallery, Video } from 'mastodon/features/ui/util/async-components';
import Bundle from 'mastodon/features/ui/components/bundle';
import Avatar from 'mastodon/components/avatar';
import DisplayName from 'mastodon/components/display_name';
import RelativeTimestamp from 'mastodon/components/relative_timestamp';
import Option from './option';
export default class StatusCheckBox extends React.PureComponent {
static propTypes = {
id: PropTypes.string.isRequired,
status: ImmutablePropTypes.map.isRequired,
checked: PropTypes.bool,
onToggle: PropTypes.func.isRequired,
disabled: PropTypes.bool,
};
handleStatusesToggle = (value, checked) => {
const { onToggle } = this.props;
onToggle(value, checked);
};
render () {
const { status, checked, onToggle, disabled } = this.props;
const { status, checked } = this.props;
let media = null;
if (status.get('reblog')) {
@ -50,24 +59,46 @@ export default class StatusCheckBox extends React.PureComponent {
} else {
media = (
<Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery} >
{Component => <Component media={status.get('media_attachments')} sensitive={status.get('sensitive')} height={110} onOpenMedia={noop} />}
{Component => (
<Component
media={status.get('media_attachments')}
sensitive={status.get('sensitive')}
height={110}
onOpenMedia={noop}
/>
)}
</Bundle>
);
}
}
return (
<div className='status-check-box'>
<div className='status-check-box__status'>
<StatusContent status={status} />
{media}
const labelComponent = (
<div className='status-check-box__status poll__option__text'>
<div className='detailed-status__display-name'>
<div className='detailed-status__display-avatar'>
<Avatar account={status.get('account')} size={46} />
</div>
<div><DisplayName account={status.get('account')} /> · <RelativeTimestamp timestamp={status.get('created_at')} /></div>
</div>
<div className='status-check-box-toggle'>
<Toggle checked={checked} onChange={onToggle} disabled={disabled} />
</div>
<StatusContent status={status} />
{media}
</div>
);
return (
<Option
name='status_ids'
value={status.get('id')}
checked={checked}
onToggle={this.handleStatusesToggle}
label={status.get('search_index')}
labelComponent={labelComponent}
multiple
/>
);
}
}