Add animations to announcement reactions (#12970)
This commit is contained in:
		
							parent
							
								
									42d2a915e4
								
							
						
					
					
						commit
						dd4eec6bf6
					
				| @ -6,13 +6,15 @@ import PropTypes from 'prop-types'; | |||||||
| import IconButton from 'mastodon/components/icon_button'; | import IconButton from 'mastodon/components/icon_button'; | ||||||
| import Icon from 'mastodon/components/icon'; | import Icon from 'mastodon/components/icon'; | ||||||
| import { defineMessages, injectIntl, FormattedMessage, FormattedDate } from 'react-intl'; | import { defineMessages, injectIntl, FormattedMessage, FormattedDate } from 'react-intl'; | ||||||
| import { autoPlayGif } from 'mastodon/initial_state'; | import { autoPlayGif, reduceMotion } from 'mastodon/initial_state'; | ||||||
| import elephantUIPlane from 'mastodon/../images/elephant_ui_plane.svg'; | import elephantUIPlane from 'mastodon/../images/elephant_ui_plane.svg'; | ||||||
| import { mascot } from 'mastodon/initial_state'; | import { mascot } from 'mastodon/initial_state'; | ||||||
| import unicodeMapping from 'mastodon/features/emoji/emoji_unicode_mapping_light'; | import unicodeMapping from 'mastodon/features/emoji/emoji_unicode_mapping_light'; | ||||||
| import classNames from 'classnames'; | import classNames from 'classnames'; | ||||||
| import EmojiPickerDropdown from 'mastodon/features/compose/containers/emoji_picker_dropdown_container'; | import EmojiPickerDropdown from 'mastodon/features/compose/containers/emoji_picker_dropdown_container'; | ||||||
| import AnimatedNumber from 'mastodon/components/animated_number'; | import AnimatedNumber from 'mastodon/components/animated_number'; | ||||||
|  | import TransitionMotion from 'react-motion/lib/TransitionMotion'; | ||||||
|  | import spring from 'react-motion/lib/spring'; | ||||||
| 
 | 
 | ||||||
| const messages = defineMessages({ | const messages = defineMessages({ | ||||||
|   close: { id: 'lightbox.close', defaultMessage: 'Close' }, |   close: { id: 'lightbox.close', defaultMessage: 'Close' }, | ||||||
| @ -194,6 +196,7 @@ class Reaction extends ImmutablePureComponent { | |||||||
|     addReaction: PropTypes.func.isRequired, |     addReaction: PropTypes.func.isRequired, | ||||||
|     removeReaction: PropTypes.func.isRequired, |     removeReaction: PropTypes.func.isRequired, | ||||||
|     emojiMap: ImmutablePropTypes.map.isRequired, |     emojiMap: ImmutablePropTypes.map.isRequired, | ||||||
|  |     style: PropTypes.object, | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   state = { |   state = { | ||||||
| @ -224,7 +227,7 @@ class Reaction extends ImmutablePureComponent { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <button className={classNames('reactions-bar__item', { active: reaction.get('me') })} onClick={this.handleClick} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} title={`:${shortCode}:`}> |       <button className={classNames('reactions-bar__item', { active: reaction.get('me') })} onClick={this.handleClick} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} title={`:${shortCode}:`} style={this.props.style}> | ||||||
|         <span className='reactions-bar__item__emoji'><Emoji hovered={this.state.hovered} emoji={reaction.get('name')} emojiMap={this.props.emojiMap} /></span> |         <span className='reactions-bar__item__emoji'><Emoji hovered={this.state.hovered} emoji={reaction.get('name')} emojiMap={this.props.emojiMap} /></span> | ||||||
|         <span className='reactions-bar__item__count'><AnimatedNumber value={reaction.get('count')} /></span> |         <span className='reactions-bar__item__count'><AnimatedNumber value={reaction.get('count')} /></span> | ||||||
|       </button> |       </button> | ||||||
| @ -248,16 +251,33 @@ class ReactionsBar extends ImmutablePureComponent { | |||||||
|     addReaction(announcementId, data.native.replace(/:/g, '')); |     addReaction(announcementId, data.native.replace(/:/g, '')); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   willEnter () { | ||||||
|  |     return { scale: reduceMotion ? 1 : 0 }; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   willLeave () { | ||||||
|  |     return { scale: reduceMotion ? 0 : spring(0, { stiffness: 170, damping: 26 }) }; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   render () { |   render () { | ||||||
|     const { reactions } = this.props; |     const { reactions } = this.props; | ||||||
|     const visibleReactions = reactions.filter(x => x.get('count') > 0); |     const visibleReactions = reactions.filter(x => x.get('count') > 0); | ||||||
| 
 | 
 | ||||||
|  |     const styles = visibleReactions.map(reaction => ({ | ||||||
|  |       key: reaction.get('name'), | ||||||
|  |       data: reaction, | ||||||
|  |       style: { scale: reduceMotion ? 1 : spring(1, { stiffness: 150, damping: 13 }) }, | ||||||
|  |     })).toArray(); | ||||||
|  | 
 | ||||||
|     return ( |     return ( | ||||||
|  |       <TransitionMotion styles={styles} willEnter={this.willEnter} willLeave={this.willLeave}> | ||||||
|  |         {items => ( | ||||||
|           <div className={classNames('reactions-bar', { 'reactions-bar--empty': visibleReactions.isEmpty() })}> |           <div className={classNames('reactions-bar', { 'reactions-bar--empty': visibleReactions.isEmpty() })}> | ||||||
|         {visibleReactions.map(reaction => ( |             {items.map(({ key, data, style }) => ( | ||||||
|               <Reaction |               <Reaction | ||||||
|             key={reaction.get('name')} |                 key={key} | ||||||
|             reaction={reaction} |                 reaction={data} | ||||||
|  |                 style={{ transform: `scale(${style.scale})`, position: style.scale < 0.5 ? 'absolute' : 'static' }} | ||||||
|                 announcementId={this.props.announcementId} |                 announcementId={this.props.announcementId} | ||||||
|                 addReaction={this.props.addReaction} |                 addReaction={this.props.addReaction} | ||||||
|                 removeReaction={this.props.removeReaction} |                 removeReaction={this.props.removeReaction} | ||||||
| @ -267,6 +287,8 @@ class ReactionsBar extends ImmutablePureComponent { | |||||||
| 
 | 
 | ||||||
|             {visibleReactions.size < 8 && <EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} button={<Icon id='plus' />} />} |             {visibleReactions.size < 8 && <EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} button={<Icon id='plus' />} />} | ||||||
|           </div> |           </div> | ||||||
|  |         )} | ||||||
|  |       </TransitionMotion> | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user