Turn report screen into a modal (#3965)
This commit is contained in:
		
							parent
							
								
									16d0aed403
								
							
						
					
					
						commit
						12e7c81dd8
					
				
					 10 changed files with 98 additions and 125 deletions
				
			
		|  | @ -1,4 +1,5 @@ | |||
| import api from '../api'; | ||||
| import { openModal, closeModal } from './modal'; | ||||
| 
 | ||||
| export const REPORT_INIT   = 'REPORT_INIT'; | ||||
| export const REPORT_CANCEL = 'REPORT_CANCEL'; | ||||
|  | @ -11,10 +12,14 @@ export const REPORT_STATUS_TOGGLE  = 'REPORT_STATUS_TOGGLE'; | |||
| export const REPORT_COMMENT_CHANGE = 'REPORT_COMMENT_CHANGE'; | ||||
| 
 | ||||
| export function initReport(account, status) { | ||||
|   return { | ||||
|     type: REPORT_INIT, | ||||
|     account, | ||||
|     status, | ||||
|   return dispatch => { | ||||
|     dispatch({ | ||||
|       type: REPORT_INIT, | ||||
|       account, | ||||
|       status, | ||||
|     }); | ||||
| 
 | ||||
|     dispatch(openModal('REPORT')); | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
|  | @ -40,7 +45,10 @@ export function submitReport() { | |||
|       account_id: getState().getIn(['reports', 'new', 'account_id']), | ||||
|       status_ids: getState().getIn(['reports', 'new', 'status_ids']), | ||||
|       comment: getState().getIn(['reports', 'new', 'comment']), | ||||
|     }).then(response => dispatch(submitReportSuccess(response.data))).catch(error => dispatch(submitReportFail(error))); | ||||
|     }).then(response => { | ||||
|       dispatch(closeModal()); | ||||
|       dispatch(submitReportSuccess(response.data)); | ||||
|     }).catch(error => dispatch(submitReportFail(error))); | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -87,7 +87,6 @@ export default class StatusActionBar extends ImmutablePureComponent { | |||
| 
 | ||||
|   handleReport = () => { | ||||
|     this.props.onReport(this.props.status); | ||||
|     this.context.router.history.push('/report'); | ||||
|   } | ||||
| 
 | ||||
|   handleConversationMuteClick = () => { | ||||
|  |  | |||
|  | @ -38,7 +38,6 @@ export default class Header extends ImmutablePureComponent { | |||
| 
 | ||||
|   handleReport = () => { | ||||
|     this.props.onReport(this.props.account); | ||||
|     this.context.router.history.push('/report'); | ||||
|   } | ||||
| 
 | ||||
|   handleMute = () => { | ||||
|  |  | |||
|  | @ -56,7 +56,6 @@ export default class ActionBar extends React.PureComponent { | |||
| 
 | ||||
|   handleReport = () => { | ||||
|     this.props.onReport(this.props.status); | ||||
|     this.context.router.history.push('/report'); | ||||
|   } | ||||
| 
 | ||||
|   render () { | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ import OnboardingModal from './onboarding_modal'; | |||
| import VideoModal from './video_modal'; | ||||
| import BoostModal from './boost_modal'; | ||||
| import ConfirmationModal from './confirmation_modal'; | ||||
| import ReportModal from './report_modal'; | ||||
| import TransitionMotion from 'react-motion/lib/TransitionMotion'; | ||||
| import spring from 'react-motion/lib/spring'; | ||||
| 
 | ||||
|  | @ -14,6 +15,7 @@ const MODAL_COMPONENTS = { | |||
|   'VIDEO': VideoModal, | ||||
|   'BOOST': BoostModal, | ||||
|   'CONFIRM': ConfirmationModal, | ||||
|   'REPORT': ReportModal, | ||||
| }; | ||||
| 
 | ||||
| export default class ModalRoot extends React.PureComponent { | ||||
|  |  | |||
|  | @ -1,19 +1,17 @@ | |||
| import React from 'react'; | ||||
| import { connect } from 'react-redux'; | ||||
| import { changeReportComment, submitReport } from '../../actions/reports'; | ||||
| import { refreshAccountTimeline } from '../../actions/timelines'; | ||||
| import { changeReportComment, submitReport } from '../../../actions/reports'; | ||||
| import { refreshAccountTimeline } from '../../../actions/timelines'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import Column from '../ui/components/column'; | ||||
| import Button from '../../components/button'; | ||||
| import { makeGetAccount } from '../../selectors'; | ||||
| import { makeGetAccount } from '../../../selectors'; | ||||
| import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; | ||||
| import StatusCheckBox from './containers/status_check_box_container'; | ||||
| import StatusCheckBox from '../../report/containers/status_check_box_container'; | ||||
| import Immutable from 'immutable'; | ||||
| import ColumnBackButtonSlim from '../../components/column_back_button_slim'; | ||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||
| import Button from '../../../components/button'; | ||||
| 
 | ||||
| const messages = defineMessages({ | ||||
|   heading: { id: 'report.heading', defaultMessage: 'New report' }, | ||||
|   placeholder: { id: 'report.placeholder', defaultMessage: 'Additional comments' }, | ||||
|   submit: { id: 'report.submit', defaultMessage: 'Submit' }, | ||||
| }); | ||||
|  | @ -37,11 +35,7 @@ const makeMapStateToProps = () => { | |||
| 
 | ||||
| @connect(makeMapStateToProps) | ||||
| @injectIntl | ||||
| export default class Report extends React.PureComponent { | ||||
| 
 | ||||
|   static contextTypes = { | ||||
|     router: PropTypes.object, | ||||
|   }; | ||||
| export default class ReportModal extends ImmutablePureComponent { | ||||
| 
 | ||||
|   static propTypes = { | ||||
|     isSubmitting: PropTypes.bool, | ||||
|  | @ -52,17 +46,15 @@ export default class Report extends React.PureComponent { | |||
|     intl: PropTypes.object.isRequired, | ||||
|   }; | ||||
| 
 | ||||
|   componentWillMount () { | ||||
|     if (!this.props.account) { | ||||
|       this.context.router.history.replace('/'); | ||||
|     } | ||||
|   handleCommentChange = (e) => { | ||||
|     this.props.dispatch(changeReportComment(e.target.value)); | ||||
|   } | ||||
| 
 | ||||
|   handleSubmit = () => { | ||||
|     this.props.dispatch(submitReport()); | ||||
|   } | ||||
| 
 | ||||
|   componentDidMount () { | ||||
|     if (!this.props.account) { | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     this.props.dispatch(refreshAccountTimeline(this.props.account.get('id'))); | ||||
|   } | ||||
| 
 | ||||
|  | @ -72,15 +64,6 @@ export default class Report extends React.PureComponent { | |||
|     } | ||||
|   } | ||||
| 
 | ||||
|   handleCommentChange = (e) => { | ||||
|     this.props.dispatch(changeReportComment(e.target.value)); | ||||
|   } | ||||
| 
 | ||||
|   handleSubmit = () => { | ||||
|     this.props.dispatch(submitReport()); | ||||
|     this.context.router.history.replace('/'); | ||||
|   } | ||||
| 
 | ||||
|   render () { | ||||
|     const { account, comment, intl, statusIds, isSubmitting } = this.props; | ||||
| 
 | ||||
|  | @ -89,36 +72,33 @@ export default class Report extends React.PureComponent { | |||
|     } | ||||
| 
 | ||||
|     return ( | ||||
|       <Column heading={intl.formatMessage(messages.heading)} icon='flag'> | ||||
|         <ColumnBackButtonSlim /> | ||||
|       <div className='modal-root__modal report-modal'> | ||||
|         <div className='report-modal__target'> | ||||
|           <FormattedMessage id='report.target' defaultMessage='Report {target}' values={{ target: <strong>{account.get('acct')}</strong> }} /> | ||||
|         </div> | ||||
| 
 | ||||
|         <div className='report scrollable'> | ||||
|           <div className='report__target'> | ||||
|             <FormattedMessage id='report.target' defaultMessage='Reporting' /> | ||||
|             <strong>{account.get('acct')}</strong> | ||||
|           </div> | ||||
| 
 | ||||
|           <div className='scrollable report__statuses'> | ||||
|         <div className='report-modal__container'> | ||||
|           <div className='report-modal__statuses'> | ||||
|             <div> | ||||
|               {statusIds.map(statusId => <StatusCheckBox id={statusId} key={statusId} disabled={isSubmitting} />)} | ||||
|             </div> | ||||
|           </div> | ||||
| 
 | ||||
|           <div className='report__textarea-wrapper'> | ||||
|           <div className='report-modal__comment'> | ||||
|             <textarea | ||||
|               className='report__textarea' | ||||
|               className='setting-text light' | ||||
|               placeholder={intl.formatMessage(messages.placeholder)} | ||||
|               value={comment} | ||||
|               onChange={this.handleCommentChange} | ||||
|               disabled={isSubmitting} | ||||
|             /> | ||||
| 
 | ||||
|             <div className='report__submit'> | ||||
|               <div className='report__submit-button'><Button disabled={isSubmitting} text={intl.formatMessage(messages.submit)} onClick={this.handleSubmit} /></div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </Column> | ||||
| 
 | ||||
|         <div className='report-modal__action-bar'> | ||||
|           <Button disabled={isSubmitting} text={intl.formatMessage(messages.submit)} onClick={this.handleSubmit} /> | ||||
|         </div> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|  | @ -15,7 +15,6 @@ import { refreshHomeTimeline } from '../../actions/timelines'; | |||
| import { refreshNotifications } from '../../actions/notifications'; | ||||
| import UploadArea from './components/upload_area'; | ||||
| import ColumnsAreaContainer from './containers/columns_area_container'; | ||||
| 
 | ||||
| import Status from '../../features/status'; | ||||
| import GettingStarted from '../../features/getting_started'; | ||||
| import PublicTimeline from '../../features/public_timeline'; | ||||
|  | @ -35,7 +34,6 @@ import GenericNotFound from '../../features/generic_not_found'; | |||
| import FavouritedStatuses from '../../features/favourited_statuses'; | ||||
| import Blocks from '../../features/blocks'; | ||||
| import Mutes from '../../features/mutes'; | ||||
| import Report from '../../features/report'; | ||||
| 
 | ||||
| // Small wrapper to pass multiColumn to the route components
 | ||||
| const WrappedSwitch = ({ multiColumn, children }) => ( | ||||
|  | @ -206,7 +204,6 @@ export default class UI extends React.PureComponent { | |||
|             <WrappedRoute path='/follow_requests' component={FollowRequests} content={children} /> | ||||
|             <WrappedRoute path='/blocks' component={Blocks} content={children} /> | ||||
|             <WrappedRoute path='/mutes' component={Mutes} content={children} /> | ||||
|             <WrappedRoute path='/report' component={Report} content={children} /> | ||||
| 
 | ||||
|             <WrappedRoute component={GenericNotFound} content={children} /> | ||||
|           </WrappedSwitch> | ||||
|  |  | |||
|  | @ -1127,6 +1127,23 @@ | |||
|     ], | ||||
|     "path": "app/javascript/mastodon/features/ui/components/onboarding_modal.json" | ||||
|   }, | ||||
|   { | ||||
|     "descriptors": [ | ||||
|       { | ||||
|         "defaultMessage": "Additional comments", | ||||
|         "id": "report.placeholder" | ||||
|       }, | ||||
|       { | ||||
|         "defaultMessage": "Submit", | ||||
|         "id": "report.submit" | ||||
|       }, | ||||
|       { | ||||
|         "defaultMessage": "Report {target}", | ||||
|         "id": "report.target" | ||||
|       } | ||||
|     ], | ||||
|     "path": "app/javascript/mastodon/features/ui/components/report_modal.json" | ||||
|   }, | ||||
|   { | ||||
|     "descriptors": [ | ||||
|       { | ||||
|  |  | |||
|  | @ -136,10 +136,10 @@ | |||
|   "privacy.unlisted.long": "Do not post to public timelines", | ||||
|   "privacy.unlisted.short": "Unlisted", | ||||
|   "reply_indicator.cancel": "Cancel", | ||||
|   "report.heading": "New report", | ||||
|   "report.heading": "Report {target}", | ||||
|   "report.placeholder": "Additional comments", | ||||
|   "report.submit": "Submit", | ||||
|   "report.target": "Reporting", | ||||
|   "report.target": "Reporting {target}", | ||||
|   "search.placeholder": "Search", | ||||
|   "search_results.total": "{count, number} {count, plural, one {result} other {results}}", | ||||
|   "status.cannot_reblog": "This post cannot be boosted", | ||||
|  |  | |||
|  | @ -600,13 +600,15 @@ | |||
| } | ||||
| 
 | ||||
| .status-check-box { | ||||
|   border-bottom: 1px solid lighten($ui-base-color, 8%); | ||||
|   border-bottom: 1px solid $ui-secondary-color; | ||||
|   display: flex; | ||||
| 
 | ||||
|   .status__content { | ||||
|     background: lighten($ui-base-color, 4%); | ||||
|     flex: 1 1 auto; | ||||
|     padding: 10px; | ||||
|     overflow: hidden; | ||||
|     text-overflow: ellipsis; | ||||
|     white-space: nowrap; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -1830,6 +1832,17 @@ | |||
|   @media screen and (max-width: 600px) { | ||||
|     font-size: 16px; | ||||
|   } | ||||
| 
 | ||||
|   &.light { | ||||
|     color: $ui-base-color; | ||||
|     border-bottom: 2px solid lighten($ui-base-color, 27%); | ||||
| 
 | ||||
|     &:focus, | ||||
|     &:active { | ||||
|       color: $ui-base-color; | ||||
|       border-bottom-color: $ui-highlight-color; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @import 'boost'; | ||||
|  | @ -2287,67 +2300,6 @@ button.icon-button.active i.fa-retweet { | |||
|   vertical-align: middle; | ||||
| } | ||||
| 
 | ||||
| .report.scrollable { | ||||
|   box-sizing: border-box; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   max-height: 100%; | ||||
| } | ||||
| 
 | ||||
| .report__target { | ||||
|   border-bottom: 1px solid lighten($ui-base-color, 4%); | ||||
|   color: $ui-secondary-color; | ||||
|   flex: 0 0 auto; | ||||
|   padding: 10px; | ||||
| 
 | ||||
|   strong { | ||||
|     display: block; | ||||
|     color: $primary-text-color; | ||||
|     font-weight: 500; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .report__statuses { | ||||
|   flex: 1 1 auto; | ||||
| } | ||||
| 
 | ||||
| .report__textarea-wrapper { | ||||
|   flex: 0 0 100px; | ||||
|   padding: 10px; | ||||
| } | ||||
| 
 | ||||
| .report__textarea { | ||||
|   background: transparent; | ||||
|   box-sizing: border-box; | ||||
|   border: 0; | ||||
|   border-bottom: 2px solid $ui-primary-color; | ||||
|   border-radius: 2px 2px 0 0; | ||||
|   color: $primary-text-color; | ||||
|   display: block; | ||||
|   font-family: inherit; | ||||
|   font-size: 14px; | ||||
|   margin-bottom: 10px; | ||||
|   outline: 0; | ||||
|   padding: 7px 4px; | ||||
|   resize: vertical; | ||||
|   width: 100%; | ||||
| 
 | ||||
|   &:active, | ||||
|   &:focus { | ||||
|     border-bottom-color: $ui-highlight-color; | ||||
|     background: rgba($base-overlay-background, 0.1); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .report__submit { | ||||
|   margin-top: 10px; | ||||
|   overflow: hidden; | ||||
| } | ||||
| 
 | ||||
| .report__submit-button { | ||||
|   float: right; | ||||
| } | ||||
| 
 | ||||
| .empty-column-indicator { | ||||
|   color: lighten($ui-base-color, 20%); | ||||
|   background: $ui-base-color; | ||||
|  | @ -3245,7 +3197,8 @@ button.icon-button.active i.fa-retweet { | |||
| } | ||||
| 
 | ||||
| .boost-modal, | ||||
| .confirmation-modal { | ||||
| .confirmation-modal, | ||||
| .report-modal { | ||||
|   background: lighten($ui-secondary-color, 8%); | ||||
|   color: $ui-base-color; | ||||
|   border-radius: 8px; | ||||
|  | @ -3281,7 +3234,8 @@ button.icon-button.active i.fa-retweet { | |||
| } | ||||
| 
 | ||||
| .boost-modal__action-bar, | ||||
| .confirmation-modal__action-bar { | ||||
| .confirmation-modal__action-bar, | ||||
| .report-modal__action-bar { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   background: $ui-secondary-color; | ||||
|  | @ -3317,6 +3271,23 @@ button.icon-button.active i.fa-retweet { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| .report-modal__statuses, | ||||
| .report-modal__comment { | ||||
|   padding: 10px; | ||||
| } | ||||
| 
 | ||||
| .report-modal__statuses { | ||||
|   min-height: 20vh; | ||||
|   overflow-y: auto; | ||||
|   overflow-x: hidden; | ||||
| } | ||||
| 
 | ||||
| .report-modal__comment { | ||||
|   .setting-text { | ||||
|     margin-top: 10px; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .confirmation-modal__action-bar { | ||||
|   .confirmation-modal__cancel-button { | ||||
|     background-color: transparent; | ||||
|  | @ -3332,7 +3303,8 @@ button.icon-button.active i.fa-retweet { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| .confirmation-modal__container { | ||||
| .confirmation-modal__container, | ||||
| .report-modal__target { | ||||
|   padding: 30px; | ||||
|   font-size: 16px; | ||||
|   text-align: center; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue