Remove global boosts state and convert boosts modal to Typescript (#29774)
		
	This commit is contained in:
		
					parent
					
						
							
								8a498f4e65
							
						
					
				
			
			
				commit
				
					
						67442f9039
					
				
			
		
					 13 changed files with 175 additions and 198 deletions
				
			
		|  | @ -1,32 +0,0 @@ | ||||||
| import { openModal } from './modal'; |  | ||||||
| 
 |  | ||||||
| export const BOOSTS_INIT_MODAL = 'BOOSTS_INIT_MODAL'; |  | ||||||
| export const BOOSTS_CHANGE_PRIVACY = 'BOOSTS_CHANGE_PRIVACY'; |  | ||||||
| 
 |  | ||||||
| export function initBoostModal(props) { |  | ||||||
|   return (dispatch, getState) => { |  | ||||||
|     const default_privacy = getState().getIn(['compose', 'default_privacy']); |  | ||||||
| 
 |  | ||||||
|     const privacy = props.status.get('visibility') === 'private' ? 'private' : default_privacy; |  | ||||||
| 
 |  | ||||||
|     dispatch({ |  | ||||||
|       type: BOOSTS_INIT_MODAL, |  | ||||||
|       privacy, |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     dispatch(openModal({ |  | ||||||
|       modalType: 'BOOST', |  | ||||||
|       modalProps: props, |  | ||||||
|     })); |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| export function changeBoostPrivacy(privacy) { |  | ||||||
|   return dispatch => { |  | ||||||
|     dispatch({ |  | ||||||
|       type: BOOSTS_CHANGE_PRIVACY, |  | ||||||
|       privacy, |  | ||||||
|     }); |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
|  | @ -4,11 +4,10 @@ import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?re | ||||||
| import LockIcon from '@/material-icons/400-24px/lock.svg?react'; | import LockIcon from '@/material-icons/400-24px/lock.svg?react'; | ||||||
| import PublicIcon from '@/material-icons/400-24px/public.svg?react'; | import PublicIcon from '@/material-icons/400-24px/public.svg?react'; | ||||||
| import QuietTimeIcon from '@/material-icons/400-24px/quiet_time.svg?react'; | import QuietTimeIcon from '@/material-icons/400-24px/quiet_time.svg?react'; | ||||||
|  | import type { StatusVisibility } from 'mastodon/models/status'; | ||||||
| 
 | 
 | ||||||
| import { Icon } from './icon'; | import { Icon } from './icon'; | ||||||
| 
 | 
 | ||||||
| type Visibility = 'public' | 'unlisted' | 'private' | 'direct'; |  | ||||||
| 
 |  | ||||||
| const messages = defineMessages({ | const messages = defineMessages({ | ||||||
|   public_short: { id: 'privacy.public.short', defaultMessage: 'Public' }, |   public_short: { id: 'privacy.public.short', defaultMessage: 'Public' }, | ||||||
|   unlisted_short: { |   unlisted_short: { | ||||||
|  | @ -25,7 +24,7 @@ const messages = defineMessages({ | ||||||
|   }, |   }, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export const VisibilityIcon: React.FC<{ visibility: Visibility }> = ({ | export const VisibilityIcon: React.FC<{ visibility: StatusVisibility }> = ({ | ||||||
|   visibility, |   visibility, | ||||||
| }) => { | }) => { | ||||||
|   const intl = useIntl(); |   const intl = useIntl(); | ||||||
|  |  | ||||||
|  | @ -8,7 +8,6 @@ import { | ||||||
| } from '../actions/accounts'; | } from '../actions/accounts'; | ||||||
| import { showAlertForError } from '../actions/alerts'; | import { showAlertForError } from '../actions/alerts'; | ||||||
| import { initBlockModal } from '../actions/blocks'; | import { initBlockModal } from '../actions/blocks'; | ||||||
| import { initBoostModal } from '../actions/boosts'; |  | ||||||
| import { | import { | ||||||
|   replyCompose, |   replyCompose, | ||||||
|   mentionCompose, |   mentionCompose, | ||||||
|  | @ -107,7 +106,7 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ | ||||||
|     if ((e && e.shiftKey) || !boostModal) { |     if ((e && e.shiftKey) || !boostModal) { | ||||||
|       this.onModalReblog(status); |       this.onModalReblog(status); | ||||||
|     } else { |     } else { | ||||||
|       dispatch(initBoostModal({ status, onReblog: this.onModalReblog })); |       dispatch(openModal({ modalType: 'BOOST', modalProps: { status, onReblog: this.onModalReblog } })); | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,5 @@ | ||||||
| import { connect } from 'react-redux'; | import { connect } from 'react-redux'; | ||||||
| 
 | 
 | ||||||
| import { initBoostModal } from '../../../actions/boosts'; |  | ||||||
| import { mentionCompose } from '../../../actions/compose'; | import { mentionCompose } from '../../../actions/compose'; | ||||||
| import { | import { | ||||||
|   reblog, |   reblog, | ||||||
|  | @ -8,6 +7,7 @@ import { | ||||||
|   unreblog, |   unreblog, | ||||||
|   unfavourite, |   unfavourite, | ||||||
| } from '../../../actions/interactions'; | } from '../../../actions/interactions'; | ||||||
|  | import { openModal } from '../../../actions/modal'; | ||||||
| import { | import { | ||||||
|   hideStatus, |   hideStatus, | ||||||
|   revealStatus, |   revealStatus, | ||||||
|  | @ -49,7 +49,7 @@ const mapDispatchToProps = dispatch => ({ | ||||||
|       if (e.shiftKey || !boostModal) { |       if (e.shiftKey || !boostModal) { | ||||||
|         this.onModalReblog(status); |         this.onModalReblog(status); | ||||||
|       } else { |       } else { | ||||||
|         dispatch(initBoostModal({ status, onReblog: this.onModalReblog })); |         dispatch(openModal({ modalType: 'BOOST', modalProps: { status, onReblog: this.onModalReblog } })); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|  | @ -14,7 +14,6 @@ import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; | ||||||
| import ReplyIcon from '@/material-icons/400-24px/reply.svg?react'; | import ReplyIcon from '@/material-icons/400-24px/reply.svg?react'; | ||||||
| import ReplyAllIcon from '@/material-icons/400-24px/reply_all.svg?react'; | import ReplyAllIcon from '@/material-icons/400-24px/reply_all.svg?react'; | ||||||
| import StarIcon from '@/material-icons/400-24px/star.svg?react'; | import StarIcon from '@/material-icons/400-24px/star.svg?react'; | ||||||
| import { initBoostModal } from 'mastodon/actions/boosts'; |  | ||||||
| import { replyCompose } from 'mastodon/actions/compose'; | import { replyCompose } from 'mastodon/actions/compose'; | ||||||
| import { reblog, favourite, unreblog, unfavourite } from 'mastodon/actions/interactions'; | import { reblog, favourite, unreblog, unfavourite } from 'mastodon/actions/interactions'; | ||||||
| import { openModal } from 'mastodon/actions/modal'; | import { openModal } from 'mastodon/actions/modal'; | ||||||
|  | @ -140,7 +139,7 @@ class Footer extends ImmutablePureComponent { | ||||||
|       } else if ((e && e.shiftKey) || !boostModal) { |       } else if ((e && e.shiftKey) || !boostModal) { | ||||||
|         this._performReblog(status); |         this._performReblog(status); | ||||||
|       } else { |       } else { | ||||||
|         dispatch(initBoostModal({ status, onReblog: this._performReblog })); |         dispatch(openModal({ modalType: 'BOOST', modalProps: { status, onReblog: this._performReblog } })); | ||||||
|       } |       } | ||||||
|     } else { |     } else { | ||||||
|       dispatch(openModal({ |       dispatch(openModal({ | ||||||
|  |  | ||||||
|  | @ -4,7 +4,6 @@ import { connect } from 'react-redux'; | ||||||
| 
 | 
 | ||||||
| import { showAlertForError } from '../../../actions/alerts'; | import { showAlertForError } from '../../../actions/alerts'; | ||||||
| import { initBlockModal } from '../../../actions/blocks'; | import { initBlockModal } from '../../../actions/blocks'; | ||||||
| import { initBoostModal } from '../../../actions/boosts'; |  | ||||||
| import { | import { | ||||||
|   replyCompose, |   replyCompose, | ||||||
|   mentionCompose, |   mentionCompose, | ||||||
|  | @ -85,7 +84,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||||
|       if (e.shiftKey || !boostModal) { |       if (e.shiftKey || !boostModal) { | ||||||
|         this.onModalReblog(status); |         this.onModalReblog(status); | ||||||
|       } else { |       } else { | ||||||
|         dispatch(initBoostModal({ status, onReblog: this.onModalReblog })); |         dispatch(openModal({ modalType: 'BOOST', modalProps: { status, onReblog: this.onModalReblog } })); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|  | @ -27,7 +27,6 @@ import { | ||||||
|   unmuteAccount, |   unmuteAccount, | ||||||
| } from '../../actions/accounts'; | } from '../../actions/accounts'; | ||||||
| import { initBlockModal } from '../../actions/blocks'; | import { initBlockModal } from '../../actions/blocks'; | ||||||
| import { initBoostModal } from '../../actions/boosts'; |  | ||||||
| import { | import { | ||||||
|   replyCompose, |   replyCompose, | ||||||
|   mentionCompose, |   mentionCompose, | ||||||
|  | @ -317,7 +316,7 @@ class Status extends ImmutablePureComponent { | ||||||
|         if ((e && e.shiftKey) || !boostModal) { |         if ((e && e.shiftKey) || !boostModal) { | ||||||
|           this.handleModalReblog(status); |           this.handleModalReblog(status); | ||||||
|         } else { |         } else { | ||||||
|           dispatch(initBoostModal({ status, onReblog: this.handleModalReblog })); |           dispatch(openModal({ modalType: 'BOOST', modalProps: { status, onReblog: this.handleModalReblog } })); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } else { |     } else { | ||||||
|  |  | ||||||
|  | @ -1,125 +0,0 @@ | ||||||
| import PropTypes from 'prop-types'; |  | ||||||
| 
 |  | ||||||
| import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; |  | ||||||
| 
 |  | ||||||
| import classNames from 'classnames'; |  | ||||||
| import { withRouter } from 'react-router-dom'; |  | ||||||
| 
 |  | ||||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; |  | ||||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; |  | ||||||
| import { connect } from 'react-redux'; |  | ||||||
| 
 |  | ||||||
| import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; |  | ||||||
| import { changeBoostPrivacy } from 'mastodon/actions/boosts'; |  | ||||||
| import AttachmentList from 'mastodon/components/attachment_list'; |  | ||||||
| import { Icon }  from 'mastodon/components/icon'; |  | ||||||
| import { VisibilityIcon } from 'mastodon/components/visibility_icon'; |  | ||||||
| import PrivacyDropdown from 'mastodon/features/compose/components/privacy_dropdown'; |  | ||||||
| import { WithRouterPropTypes } from 'mastodon/utils/react_router'; |  | ||||||
| 
 |  | ||||||
| import { Avatar } from '../../../components/avatar'; |  | ||||||
| import { Button } from '../../../components/button'; |  | ||||||
| import { DisplayName } from '../../../components/display_name'; |  | ||||||
| import { RelativeTimestamp } from '../../../components/relative_timestamp'; |  | ||||||
| import StatusContent from '../../../components/status_content'; |  | ||||||
| 
 |  | ||||||
| const messages = defineMessages({ |  | ||||||
|   cancel_reblog: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' }, |  | ||||||
|   reblog: { id: 'status.reblog', defaultMessage: 'Boost' }, |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| const mapStateToProps = state => { |  | ||||||
|   return { |  | ||||||
|     privacy: state.getIn(['boosts', 'new', 'privacy']), |  | ||||||
|   }; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| const mapDispatchToProps = dispatch => { |  | ||||||
|   return { |  | ||||||
|     onChangeBoostPrivacy(value) { |  | ||||||
|       dispatch(changeBoostPrivacy(value)); |  | ||||||
|     }, |  | ||||||
|   }; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| class BoostModal extends ImmutablePureComponent { |  | ||||||
|   static propTypes = { |  | ||||||
|     status: ImmutablePropTypes.map.isRequired, |  | ||||||
|     onReblog: PropTypes.func.isRequired, |  | ||||||
|     onClose: PropTypes.func.isRequired, |  | ||||||
|     onChangeBoostPrivacy: PropTypes.func.isRequired, |  | ||||||
|     privacy: PropTypes.string.isRequired, |  | ||||||
|     intl: PropTypes.object.isRequired, |  | ||||||
|     ...WithRouterPropTypes, |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   handleReblog = () => { |  | ||||||
|     this.props.onReblog(this.props.status, this.props.privacy); |  | ||||||
|     this.props.onClose(); |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   handleAccountClick = (e) => { |  | ||||||
|     if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { |  | ||||||
|       e.preventDefault(); |  | ||||||
|       this.props.onClose(); |  | ||||||
|       this.props.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`); |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   _findContainer = () => { |  | ||||||
|     return document.getElementsByClassName('modal-root__container')[0]; |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   render () { |  | ||||||
|     const { status, privacy, intl } = this.props; |  | ||||||
|     const buttonText = status.get('reblogged') ? messages.cancel_reblog : messages.reblog; |  | ||||||
| 
 |  | ||||||
|     return ( |  | ||||||
|       <div className='modal-root__modal boost-modal'> |  | ||||||
|         <div className='boost-modal__container'> |  | ||||||
|           <div className={classNames('status', `status-${status.get('visibility')}`, 'light')}> |  | ||||||
|             <div className='status__info'> |  | ||||||
|               <a href={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} className='status__relative-time' target='_blank' rel='noopener noreferrer'> |  | ||||||
|                 <span className='status__visibility-icon'><VisibilityIcon visibility={status.get('visibility')} /></span> |  | ||||||
|                 <RelativeTimestamp timestamp={status.get('created_at')} /> |  | ||||||
|               </a> |  | ||||||
| 
 |  | ||||||
|               <a onClick={this.handleAccountClick} href={`/@${status.getIn(['account', 'acct'])}`} className='status__display-name'> |  | ||||||
|                 <div className='status__avatar'> |  | ||||||
|                   <Avatar account={status.get('account')} size={48} /> |  | ||||||
|                 </div> |  | ||||||
| 
 |  | ||||||
|                 <DisplayName account={status.get('account')} /> |  | ||||||
|               </a> |  | ||||||
|             </div> |  | ||||||
| 
 |  | ||||||
|             <StatusContent status={status} /> |  | ||||||
| 
 |  | ||||||
|             {status.get('media_attachments').size > 0 && ( |  | ||||||
|               <AttachmentList |  | ||||||
|                 compact |  | ||||||
|                 media={status.get('media_attachments')} |  | ||||||
|               /> |  | ||||||
|             )} |  | ||||||
|           </div> |  | ||||||
|         </div> |  | ||||||
| 
 |  | ||||||
|         <div className='boost-modal__action-bar'> |  | ||||||
|           <div><FormattedMessage id='boost_modal.combo' defaultMessage='You can press {combo} to skip this next time' values={{ combo: <span>Shift + <Icon id='retweet' icon={RepeatIcon} /></span> }} /></div> |  | ||||||
|           {status.get('visibility') !== 'private' && !status.get('reblogged') && ( |  | ||||||
|             <PrivacyDropdown |  | ||||||
|               noDirect |  | ||||||
|               value={privacy} |  | ||||||
|               container={this._findContainer} |  | ||||||
|               onChange={this.props.onChangeBoostPrivacy} |  | ||||||
|             /> |  | ||||||
|           )} |  | ||||||
|           <Button text={intl.formatMessage(buttonText)} onClick={this.handleReblog} autoFocus /> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     ); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export default withRouter(connect(mapStateToProps, mapDispatchToProps)(injectIntl(BoostModal))); |  | ||||||
							
								
								
									
										162
									
								
								app/javascript/mastodon/features/ui/components/boost_modal.tsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								app/javascript/mastodon/features/ui/components/boost_modal.tsx
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,162 @@ | ||||||
|  | import type { MouseEventHandler } from 'react'; | ||||||
|  | import { useCallback, useState } from 'react'; | ||||||
|  | 
 | ||||||
|  | import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | import classNames from 'classnames'; | ||||||
|  | import { useHistory } from 'react-router'; | ||||||
|  | 
 | ||||||
|  | import type Immutable from 'immutable'; | ||||||
|  | 
 | ||||||
|  | import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; | ||||||
|  | import AttachmentList from 'mastodon/components/attachment_list'; | ||||||
|  | import { Icon } from 'mastodon/components/icon'; | ||||||
|  | import { VisibilityIcon } from 'mastodon/components/visibility_icon'; | ||||||
|  | import PrivacyDropdown from 'mastodon/features/compose/components/privacy_dropdown'; | ||||||
|  | import type { Account } from 'mastodon/models/account'; | ||||||
|  | import type { Status, StatusVisibility } from 'mastodon/models/status'; | ||||||
|  | import { useAppSelector } from 'mastodon/store'; | ||||||
|  | 
 | ||||||
|  | import { Avatar } from '../../../components/avatar'; | ||||||
|  | import { Button } from '../../../components/button'; | ||||||
|  | import { DisplayName } from '../../../components/display_name'; | ||||||
|  | import { RelativeTimestamp } from '../../../components/relative_timestamp'; | ||||||
|  | import StatusContent from '../../../components/status_content'; | ||||||
|  | 
 | ||||||
|  | const messages = defineMessages({ | ||||||
|  |   cancel_reblog: { | ||||||
|  |     id: 'status.cancel_reblog_private', | ||||||
|  |     defaultMessage: 'Unboost', | ||||||
|  |   }, | ||||||
|  |   reblog: { id: 'status.reblog', defaultMessage: 'Boost' }, | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | export const BoostModal: React.FC<{ | ||||||
|  |   status: Status; | ||||||
|  |   onClose: () => void; | ||||||
|  |   onReblog: (status: Status, privacy: StatusVisibility) => void; | ||||||
|  | }> = ({ status, onReblog, onClose }) => { | ||||||
|  |   const intl = useIntl(); | ||||||
|  |   const history = useHistory(); | ||||||
|  | 
 | ||||||
|  |   const default_privacy = useAppSelector( | ||||||
|  |     // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
 | ||||||
|  |     (state) => state.compose.get('default_privacy') as StatusVisibility, | ||||||
|  |   ); | ||||||
|  | 
 | ||||||
|  |   const account = status.get('account') as Account; | ||||||
|  |   const statusVisibility = status.get('visibility') as StatusVisibility; | ||||||
|  | 
 | ||||||
|  |   const [privacy, setPrivacy] = useState<StatusVisibility>( | ||||||
|  |     statusVisibility === 'private' ? 'private' : default_privacy, | ||||||
|  |   ); | ||||||
|  | 
 | ||||||
|  |   const onPrivacyChange = useCallback((value: StatusVisibility) => { | ||||||
|  |     setPrivacy(value); | ||||||
|  |   }, []); | ||||||
|  | 
 | ||||||
|  |   const handleReblog = useCallback(() => { | ||||||
|  |     onReblog(status, privacy); | ||||||
|  |     onClose(); | ||||||
|  |   }, [onClose, onReblog, status, privacy]); | ||||||
|  | 
 | ||||||
|  |   const handleAccountClick = useCallback<MouseEventHandler>( | ||||||
|  |     (e) => { | ||||||
|  |       if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { | ||||||
|  |         e.preventDefault(); | ||||||
|  |         onClose(); | ||||||
|  |         history.push(`/@${account.acct}`); | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     [history, onClose, account], | ||||||
|  |   ); | ||||||
|  | 
 | ||||||
|  |   const buttonText = status.get('reblogged') | ||||||
|  |     ? messages.cancel_reblog | ||||||
|  |     : messages.reblog; | ||||||
|  | 
 | ||||||
|  |   const findContainer = useCallback( | ||||||
|  |     () => document.getElementsByClassName('modal-root__container')[0], | ||||||
|  |     [], | ||||||
|  |   ); | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className='modal-root__modal boost-modal'> | ||||||
|  |       <div className='boost-modal__container'> | ||||||
|  |         <div | ||||||
|  |           className={classNames( | ||||||
|  |             'status', | ||||||
|  |             `status-${statusVisibility}`, | ||||||
|  |             'light', | ||||||
|  |           )} | ||||||
|  |         > | ||||||
|  |           <div className='status__info'> | ||||||
|  |             <a | ||||||
|  |               href={`/@${account.acct}/${status.get('id') as string}`} | ||||||
|  |               className='status__relative-time' | ||||||
|  |               target='_blank' | ||||||
|  |               rel='noopener noreferrer' | ||||||
|  |             > | ||||||
|  |               <span className='status__visibility-icon'> | ||||||
|  |                 <VisibilityIcon visibility={statusVisibility} /> | ||||||
|  |               </span> | ||||||
|  |               <RelativeTimestamp | ||||||
|  |                 timestamp={status.get('created_at') as string} | ||||||
|  |               /> | ||||||
|  |             </a> | ||||||
|  | 
 | ||||||
|  |             <a | ||||||
|  |               onClick={handleAccountClick} | ||||||
|  |               href={`/@${account.acct}`} | ||||||
|  |               className='status__display-name' | ||||||
|  |             > | ||||||
|  |               <div className='status__avatar'> | ||||||
|  |                 <Avatar account={account} size={48} /> | ||||||
|  |               </div> | ||||||
|  | 
 | ||||||
|  |               <DisplayName account={account} /> | ||||||
|  |             </a> | ||||||
|  |           </div> | ||||||
|  | 
 | ||||||
|  |           {/* @ts-expect-error Expected until StatusContent is typed */} | ||||||
|  |           <StatusContent status={status} /> | ||||||
|  | 
 | ||||||
|  |           {(status.get('media_attachments') as Immutable.List<unknown>).size > | ||||||
|  |             0 && ( | ||||||
|  |             <AttachmentList compact media={status.get('media_attachments')} /> | ||||||
|  |           )} | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  | 
 | ||||||
|  |       <div className='boost-modal__action-bar'> | ||||||
|  |         <div> | ||||||
|  |           <FormattedMessage | ||||||
|  |             id='boost_modal.combo' | ||||||
|  |             defaultMessage='You can press {combo} to skip this next time' | ||||||
|  |             values={{ | ||||||
|  |               combo: ( | ||||||
|  |                 <span> | ||||||
|  |                   Shift + <Icon id='retweet' icon={RepeatIcon} /> | ||||||
|  |                 </span> | ||||||
|  |               ), | ||||||
|  |             }} | ||||||
|  |           /> | ||||||
|  |         </div> | ||||||
|  |         {statusVisibility !== 'private' && !status.get('reblogged') && ( | ||||||
|  |           <PrivacyDropdown | ||||||
|  |             noDirect | ||||||
|  |             value={privacy} | ||||||
|  |             container={findContainer} | ||||||
|  |             onChange={onPrivacyChange} | ||||||
|  |           /> | ||||||
|  |         )} | ||||||
|  |         <Button | ||||||
|  |           text={intl.formatMessage(buttonText)} | ||||||
|  |           onClick={handleReblog} | ||||||
|  |           // eslint-disable-next-line jsx-a11y/no-autofocus
 | ||||||
|  |           autoFocus | ||||||
|  |         /> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | @ -24,7 +24,7 @@ import BundleContainer from '../containers/bundle_container'; | ||||||
| 
 | 
 | ||||||
| import ActionsModal from './actions_modal'; | import ActionsModal from './actions_modal'; | ||||||
| import AudioModal from './audio_modal'; | import AudioModal from './audio_modal'; | ||||||
| import BoostModal from './boost_modal'; | import { BoostModal } from './boost_modal'; | ||||||
| import BundleModalError from './bundle_modal_error'; | import BundleModalError from './bundle_modal_error'; | ||||||
| import ConfirmationModal from './confirmation_modal'; | import ConfirmationModal from './confirmation_modal'; | ||||||
| import FocalPointModal from './focal_point_modal'; | import FocalPointModal from './focal_point_modal'; | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								app/javascript/mastodon/models/status.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								app/javascript/mastodon/models/status.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | ||||||
|  | export type StatusVisibility = 'public' | 'unlisted' | 'private' | 'direct'; | ||||||
|  | 
 | ||||||
|  | // Temporary until we type it correctly
 | ||||||
|  | export type Status = Immutable.Map<string, unknown>; | ||||||
|  | @ -1,25 +0,0 @@ | ||||||
| import Immutable from 'immutable'; |  | ||||||
| 
 |  | ||||||
| import { |  | ||||||
|   BOOSTS_INIT_MODAL, |  | ||||||
|   BOOSTS_CHANGE_PRIVACY, |  | ||||||
| } from 'mastodon/actions/boosts'; |  | ||||||
| 
 |  | ||||||
| const initialState = Immutable.Map({ |  | ||||||
|   new: Immutable.Map({ |  | ||||||
|     privacy: 'public', |  | ||||||
|   }), |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| export default function mutes(state = initialState, action) { |  | ||||||
|   switch (action.type) { |  | ||||||
|   case BOOSTS_INIT_MODAL: |  | ||||||
|     return state.withMutations((state) => { |  | ||||||
|       state.setIn(['new', 'privacy'], action.privacy); |  | ||||||
|     }); |  | ||||||
|   case BOOSTS_CHANGE_PRIVACY: |  | ||||||
|     return state.setIn(['new', 'privacy'], action.privacy); |  | ||||||
|   default: |  | ||||||
|     return state; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  | @ -7,7 +7,6 @@ import { accountsReducer } from './accounts'; | ||||||
| import accounts_map from './accounts_map'; | import accounts_map from './accounts_map'; | ||||||
| import alerts from './alerts'; | import alerts from './alerts'; | ||||||
| import announcements from './announcements'; | import announcements from './announcements'; | ||||||
| import boosts from './boosts'; |  | ||||||
| import compose from './compose'; | import compose from './compose'; | ||||||
| import contexts from './contexts'; | import contexts from './contexts'; | ||||||
| import conversations from './conversations'; | import conversations from './conversations'; | ||||||
|  | @ -60,7 +59,6 @@ const reducers = { | ||||||
|   relationships: relationshipsReducer, |   relationships: relationshipsReducer, | ||||||
|   settings, |   settings, | ||||||
|   push_notifications, |   push_notifications, | ||||||
|   boosts, |  | ||||||
|   server, |   server, | ||||||
|   contexts, |   contexts, | ||||||
|   compose, |   compose, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue