Merge pull request #232 from glitch-soc/hotkeys-glitch
Implement status hotkeys + spoiler expanding
This commit is contained in:
		
						commit
						84840e8d8c
					
				| @ -9,6 +9,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||
| import { MediaGallery, Video } from 'themes/glitch/util/async-components'; | ||||
| import { HotKeys } from 'react-hotkeys'; | ||||
| import NotificationOverlayContainer from 'themes/glitch/features/notifications/containers/overlay_container'; | ||||
| import classNames from 'classnames'; | ||||
| 
 | ||||
| // We use the component (and not the container) since we do not want
 | ||||
| // to use the progress bar to show download progress
 | ||||
| @ -21,6 +22,7 @@ export default class Status extends ImmutablePureComponent { | ||||
|   }; | ||||
| 
 | ||||
|   static propTypes = { | ||||
|     containerId: PropTypes.string, | ||||
|     id: PropTypes.string, | ||||
|     status: ImmutablePropTypes.map, | ||||
|     account: ImmutablePropTypes.map, | ||||
| @ -188,7 +190,9 @@ export default class Status extends ImmutablePureComponent { | ||||
|   } | ||||
| 
 | ||||
|   handleExpandedToggle = () => { | ||||
|     this.setExpansion(this.state.isExpanded || !this.props.status.get('spoiler') ? null : true); | ||||
|     if (this.props.status.get('spoiler_text')) { | ||||
|       this.setExpansion(this.state.isExpanded ? null : true); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   handleOpenVideo = startTime => { | ||||
| @ -222,11 +226,11 @@ export default class Status extends ImmutablePureComponent { | ||||
|   } | ||||
| 
 | ||||
|   handleHotkeyMoveUp = () => { | ||||
|     this.props.onMoveUp(this.props.status.get('id')); | ||||
|     this.props.onMoveUp(this.props.containerId || this.props.id); | ||||
|   } | ||||
| 
 | ||||
|   handleHotkeyMoveDown = () => { | ||||
|     this.props.onMoveDown(this.props.status.get('id')); | ||||
|     this.props.onMoveDown(this.props.containerId || this.props.id); | ||||
|   } | ||||
| 
 | ||||
|   handleRef = c => { | ||||
| @ -371,31 +375,24 @@ export default class Status extends ImmutablePureComponent { | ||||
|       openProfile: this.handleHotkeyOpenProfile, | ||||
|       moveUp: this.handleHotkeyMoveUp, | ||||
|       moveDown: this.handleHotkeyMoveDown, | ||||
|       toggleSpoiler: this.handleExpandedToggle, | ||||
|     }; | ||||
| 
 | ||||
|     const computedClass = classNames('status', `status-${status.get('visibility')}`, { | ||||
|       collapsed: isExpanded === false, | ||||
|       'has-background': isExpanded === false && background, | ||||
|       'marked-for-delete': this.state.markedForDelete, | ||||
|       muted, | ||||
|     }, 'focusable'); | ||||
| 
 | ||||
|     return ( | ||||
|       <HotKeys handlers={handlers}> | ||||
|         <div | ||||
|           className={ | ||||
|             `status${ | ||||
|               muted ? ' muted' : '' | ||||
|             } status-${status.get('visibility')}${ | ||||
|               isExpanded === false ? ' collapsed' : '' | ||||
|             }${ | ||||
|               isExpanded === false && background ? ' has-background' : '' | ||||
|             }${ | ||||
|               this.state.markedForDelete ? ' marked-for-delete' : '' | ||||
|             }` | ||||
|           } | ||||
|           style={{ | ||||
|             backgroundImage: ( | ||||
|               isExpanded === false && background ? | ||||
|               `url(${background})` : | ||||
|               'none' | ||||
|             ), | ||||
|           }} | ||||
|           className={computedClass} | ||||
|           style={isExpanded === false && background ? { backgroundImage: `url(${background})` } : null} | ||||
|           {...selectorAttribs} | ||||
|           ref={handleRef} | ||||
|           tabIndex='0' | ||||
|         > | ||||
|           {prepend && account ? ( | ||||
|             <StatusPrepend | ||||
|  | ||||
| @ -45,6 +45,7 @@ const makeMapStateToProps = () => { | ||||
|     } | ||||
| 
 | ||||
|     return { | ||||
|       containerId : props.containerId || props.id,  //  Should match reblogStatus's id for reblogs
 | ||||
|       status      : status, | ||||
|       account     : account || props.account, | ||||
|       settings    : state.get('local_settings'), | ||||
|  | ||||
| @ -14,6 +14,7 @@ import NotificationOverlayContainer from '../containers/overlay_container'; | ||||
| export default class NotificationFollow extends ImmutablePureComponent { | ||||
| 
 | ||||
|   static propTypes = { | ||||
|     hidden: PropTypes.bool, | ||||
|     id: PropTypes.string.isRequired, | ||||
|     account: ImmutablePropTypes.map.isRequired, | ||||
|     notification: ImmutablePropTypes.map.isRequired, | ||||
| @ -57,7 +58,7 @@ export default class NotificationFollow extends ImmutablePureComponent { | ||||
|   } | ||||
| 
 | ||||
|   render () { | ||||
|     const { account, notification } = this.props; | ||||
|     const { account, notification, hidden } = this.props; | ||||
| 
 | ||||
|     //  Links to the display name.
 | ||||
|     const displayName = account.get('display_name_html') || account.get('username'); | ||||
| @ -87,7 +88,7 @@ export default class NotificationFollow extends ImmutablePureComponent { | ||||
|             /> | ||||
|           </div> | ||||
| 
 | ||||
|           <AccountContainer id={account.get('id')} withNote={false} /> | ||||
|           <AccountContainer hidden={hidden} id={account.get('id')} withNote={false} /> | ||||
|           <NotificationOverlayContainer notification={notification} /> | ||||
|         </div> | ||||
|       </HotKeys> | ||||
|  | ||||
| @ -16,70 +16,75 @@ export default class Notification extends ImmutablePureComponent { | ||||
|     onMoveUp: PropTypes.func.isRequired, | ||||
|     onMoveDown: PropTypes.func.isRequired, | ||||
|     onMention: PropTypes.func.isRequired, | ||||
|     settings: ImmutablePropTypes.map.isRequired, | ||||
|   }; | ||||
| 
 | ||||
|   renderFollow () { | ||||
|     const { notification } = this.props; | ||||
|   render () { | ||||
|     const { | ||||
|       hidden, | ||||
|       notification, | ||||
|       onMoveDown, | ||||
|       onMoveUp, | ||||
|       onMention, | ||||
|     } = this.props; | ||||
| 
 | ||||
|     switch(notification.get('type')) { | ||||
|     case 'follow': | ||||
|       return ( | ||||
|         <NotificationFollow | ||||
|           hidden={hidden} | ||||
|           id={notification.get('id')} | ||||
|           account={notification.get('account')} | ||||
|           notification={notification} | ||||
|           onMoveDown={onMoveDown} | ||||
|           onMoveUp={onMoveUp} | ||||
|           onMention={onMention} | ||||
|         /> | ||||
|       ); | ||||
|   } | ||||
| 
 | ||||
|   renderMention () { | ||||
|     const { notification } = this.props; | ||||
|     case 'mention': | ||||
|       return ( | ||||
|         <StatusContainer | ||||
|           containerId={notification.get('id')} | ||||
|           hidden={hidden} | ||||
|           id={notification.get('status')} | ||||
|           notification={notification} | ||||
|           onMoveDown={onMoveDown} | ||||
|           onMoveUp={onMoveUp} | ||||
|           onMention={onMention} | ||||
|           withDismiss | ||||
|         /> | ||||
|       ); | ||||
|   } | ||||
| 
 | ||||
|   renderFavourite () { | ||||
|     const { notification } = this.props; | ||||
|     case 'favourite': | ||||
|       return ( | ||||
|         <StatusContainer | ||||
|           containerId={notification.get('id')} | ||||
|           hidden={hidden} | ||||
|           id={notification.get('status')} | ||||
|           account={notification.get('account')} | ||||
|           prepend='favourite' | ||||
|           muted | ||||
|           notification={notification} | ||||
|           onMoveDown={onMoveDown} | ||||
|           onMoveUp={onMoveUp} | ||||
|           onMention={onMention} | ||||
|           withDismiss | ||||
|         /> | ||||
|       ); | ||||
|   } | ||||
| 
 | ||||
|   renderReblog () { | ||||
|     const { notification } = this.props; | ||||
|     case 'reblog': | ||||
|       return ( | ||||
|         <StatusContainer | ||||
|           containerId={notification.get('id')} | ||||
|           hidden={hidden} | ||||
|           id={notification.get('status')} | ||||
|           account={notification.get('account')} | ||||
|           prepend='reblog' | ||||
|           muted | ||||
|           notification={notification} | ||||
|           onMoveDown={onMoveDown} | ||||
|           onMoveUp={onMoveUp} | ||||
|           onMention={onMention} | ||||
|           withDismiss | ||||
|         /> | ||||
|       ); | ||||
|   } | ||||
| 
 | ||||
|   render () { | ||||
|     const { notification } = this.props; | ||||
|     switch(notification.get('type')) { | ||||
|     case 'follow': | ||||
|       return this.renderFollow(); | ||||
|     case 'mention': | ||||
|       return this.renderMention(); | ||||
|     case 'favourite': | ||||
|       return this.renderFavourite(); | ||||
|     case 'reblog': | ||||
|       return this.renderReblog(); | ||||
|     default: | ||||
|       return null; | ||||
|     } | ||||
|  | ||||
| @ -11,7 +11,6 @@ const makeMapStateToProps = () => { | ||||
| 
 | ||||
|   const mapStateToProps = (state, props) => ({ | ||||
|     notification: getNotification(state, props.notification, props.accountId), | ||||
|     settings: state.get('local_settings'), | ||||
|     notifCleaning: state.getIn(['notifications', 'cleaningMode']), | ||||
|   }); | ||||
| 
 | ||||
|  | ||||
| @ -41,7 +41,7 @@ export default class DetailedStatus extends ImmutablePureComponent { | ||||
| 
 | ||||
|   render () { | ||||
|     const status = this.props.status.get('reblog') ? this.props.status.get('reblog') : this.props.status; | ||||
|     const { settings } = this.props; | ||||
|     const { expanded, setExpansion, settings } = this.props; | ||||
| 
 | ||||
|     let media           = ''; | ||||
|     let mediaIcon       = null; | ||||
| @ -109,6 +109,8 @@ export default class DetailedStatus extends ImmutablePureComponent { | ||||
|           status={status} | ||||
|           media={media} | ||||
|           mediaIcon={mediaIcon} | ||||
|           expanded={expanded} | ||||
|           setExpansion={setExpansion} | ||||
|         /> | ||||
| 
 | ||||
|         <div className='detailed-status__meta'> | ||||
|  | ||||
| @ -71,6 +71,7 @@ export default class Status extends ImmutablePureComponent { | ||||
| 
 | ||||
|   state = { | ||||
|     fullscreen: false, | ||||
|     isExpanded: null, | ||||
|   }; | ||||
| 
 | ||||
|   componentWillMount () { | ||||
| @ -88,6 +89,12 @@ export default class Status extends ImmutablePureComponent { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   handleExpandedToggle = () => { | ||||
|     if (this.props.status.get('spoiler_text')) { | ||||
|       this.setExpansion(this.state.isExpanded ? null : true); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   handleFavouriteClick = (status) => { | ||||
|     if (status.get('favourited')) { | ||||
|       this.props.dispatch(unfavourite(status)); | ||||
| @ -241,6 +248,10 @@ export default class Status extends ImmutablePureComponent { | ||||
|     )); | ||||
|   } | ||||
| 
 | ||||
|   setExpansion = value => { | ||||
|     this.setState({ isExpanded: value ? true : null }); | ||||
|   } | ||||
| 
 | ||||
|   setRef = c => { | ||||
|     this.node = c; | ||||
|   } | ||||
| @ -272,8 +283,9 @@ export default class Status extends ImmutablePureComponent { | ||||
| 
 | ||||
|   render () { | ||||
|     let ancestors, descendants; | ||||
|     const { setExpansion } = this; | ||||
|     const { status, settings, ancestorsIds, descendantsIds } = this.props; | ||||
|     const { fullscreen } = this.state; | ||||
|     const { fullscreen, isExpanded } = this.state; | ||||
| 
 | ||||
|     if (status === null) { | ||||
|       return ( | ||||
| @ -300,6 +312,7 @@ export default class Status extends ImmutablePureComponent { | ||||
|       boost: this.handleHotkeyBoost, | ||||
|       mention: this.handleHotkeyMention, | ||||
|       openProfile: this.handleHotkeyOpenProfile, | ||||
|       toggleSpoiler: this.handleExpandedToggle, | ||||
|     }; | ||||
| 
 | ||||
|     return ( | ||||
| @ -317,6 +330,8 @@ export default class Status extends ImmutablePureComponent { | ||||
|                   settings={settings} | ||||
|                   onOpenVideo={this.handleOpenVideo} | ||||
|                   onOpenMedia={this.handleOpenMedia} | ||||
|                   expanded={isExpanded} | ||||
|                   setExpansion={setExpansion} | ||||
|                 /> | ||||
| 
 | ||||
|                 <ActionBar | ||||
|  | ||||
| @ -84,6 +84,7 @@ const keyMap = { | ||||
|   goToProfile: 'g u', | ||||
|   goToBlocked: 'g b', | ||||
|   goToMuted: 'g m', | ||||
|   toggleSpoiler: 'x', | ||||
| }; | ||||
| 
 | ||||
| @connect(mapStateToProps) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user