[Glitch] Add number animations
Port 76f1ed834efd3b58b6ebc8e951b661bbc1b7bf9b to glitch-soc Signed-off-by: Thibaut Girka <thib@sitedethib.com>
This commit is contained in:
		
							parent
							
								
									3c4bd03949
								
							
						
					
					
						commit
						f1e4738f81
					
				
							
								
								
									
										47
									
								
								app/javascript/flavours/glitch/components/animated_number.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								app/javascript/flavours/glitch/components/animated_number.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | ||||
| import React from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import { FormattedNumber } from 'react-intl'; | ||||
| import TransitionMotion from 'react-motion/lib/TransitionMotion'; | ||||
| import spring from 'react-motion/lib/spring'; | ||||
| import { reduceMotion } from 'flavours/glitch/util/initial_state'; | ||||
| 
 | ||||
| export default class AnimatedNumber extends React.PureComponent { | ||||
| 
 | ||||
|   static propTypes = { | ||||
|     value: PropTypes.number.isRequired, | ||||
|   }; | ||||
| 
 | ||||
|   willEnter () { | ||||
|     return { y: -1 }; | ||||
|   } | ||||
| 
 | ||||
|   willLeave () { | ||||
|     return { y: spring(1, { damping: 35, stiffness: 400 }) }; | ||||
|   } | ||||
| 
 | ||||
|   render () { | ||||
|     const { value } = this.props; | ||||
| 
 | ||||
|     if (reduceMotion) { | ||||
|       return <FormattedNumber value={value} />; | ||||
|     } | ||||
| 
 | ||||
|     const styles = [{ | ||||
|       key: value, | ||||
|       style: { y: spring(0, { damping: 35, stiffness: 400 }) }, | ||||
|     }]; | ||||
| 
 | ||||
|     return ( | ||||
|       <TransitionMotion styles={styles} willEnter={this.willEnter} willLeave={this.willLeave}> | ||||
|         {items => ( | ||||
|           <span className='animated-number'> | ||||
|             {items.map(({ key, style }) => ( | ||||
|               <span key={key} style={{ position: style.y > 0 ? 'absolute' : 'static', transform: `translateY(${style.y * 100}%)` }}><FormattedNumber value={key} /></span> | ||||
|             ))} | ||||
|           </span> | ||||
|         )} | ||||
|       </TransitionMotion> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| @ -5,13 +5,14 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import IconButton from 'flavours/glitch/components/icon_button'; | ||||
| import Icon from 'flavours/glitch/components/icon'; | ||||
| import { defineMessages, injectIntl, FormattedMessage, FormattedDate, FormattedNumber } from 'react-intl'; | ||||
| import { defineMessages, injectIntl, FormattedMessage, FormattedDate } from 'react-intl'; | ||||
| import { autoPlayGif } from 'flavours/glitch/util/initial_state'; | ||||
| import elephantUIPlane from 'mastodon/../images/elephant_ui_plane.svg'; | ||||
| import { mascot } from 'flavours/glitch/util/initial_state'; | ||||
| import unicodeMapping from 'flavours/glitch/util/emoji/emoji_unicode_mapping_light'; | ||||
| import classNames from 'classnames'; | ||||
| import EmojiPickerDropdown from 'flavours/glitch/features/emoji_picker'; | ||||
| import AnimatedNumber from 'flavours/glitch/components/animated_number'; | ||||
| 
 | ||||
| const messages = defineMessages({ | ||||
|   close: { id: 'lightbox.close', defaultMessage: 'Close' }, | ||||
| @ -225,7 +226,7 @@ class Reaction extends ImmutablePureComponent { | ||||
|     return ( | ||||
|       <button className={classNames('reactions-bar__item', { active: reaction.get('me') })} onClick={this.handleClick} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} title={`:${shortCode}:`}> | ||||
|         <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'><FormattedNumber value={reaction.get('count')} /></span> | ||||
|         <span className='reactions-bar__item__count'><AnimatedNumber value={reaction.get('count')} /></span> | ||||
|       </button> | ||||
|     ); | ||||
|   } | ||||
|  | ||||
| @ -7,7 +7,7 @@ import StatusContent from 'flavours/glitch/components/status_content'; | ||||
| import MediaGallery from 'flavours/glitch/components/media_gallery'; | ||||
| import AttachmentList from 'flavours/glitch/components/attachment_list'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| import { FormattedDate, FormattedNumber } from 'react-intl'; | ||||
| import { FormattedDate } from 'react-intl'; | ||||
| import Card from './card'; | ||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||
| import Video from 'flavours/glitch/features/video'; | ||||
| @ -17,6 +17,7 @@ import scheduleIdleTask from 'flavours/glitch/util/schedule_idle_task'; | ||||
| import classNames from 'classnames'; | ||||
| import PollContainer from 'flavours/glitch/containers/poll_container'; | ||||
| import Icon from 'flavours/glitch/components/icon'; | ||||
| import AnimatedNumber from 'flavours/glitch/components/animated_number'; | ||||
| 
 | ||||
| export default class DetailedStatus extends ImmutablePureComponent { | ||||
| 
 | ||||
| @ -204,7 +205,7 @@ export default class DetailedStatus extends ImmutablePureComponent { | ||||
|         <Link to={`/statuses/${status.get('id')}/reblogs`} className='detailed-status__link'> | ||||
|           <Icon id={reblogIcon} /> | ||||
|           <span className='detailed-status__reblogs'> | ||||
|             <FormattedNumber value={status.get('reblogs_count')} /> | ||||
|             <AnimatedNumber value={status.get('reblogs_count')} /> | ||||
|           </span> | ||||
|         </Link> | ||||
|       ); | ||||
| @ -213,7 +214,7 @@ export default class DetailedStatus extends ImmutablePureComponent { | ||||
|         <a href={`/interact/${status.get('id')}?type=reblog`} className='detailed-status__link' onClick={this.handleModalLink}> | ||||
|           <Icon id={reblogIcon} /> | ||||
|           <span className='detailed-status__reblogs'> | ||||
|             <FormattedNumber value={status.get('reblogs_count')} /> | ||||
|             <AnimatedNumber value={status.get('reblogs_count')} /> | ||||
|           </span> | ||||
|         </a> | ||||
|       ); | ||||
| @ -224,7 +225,7 @@ export default class DetailedStatus extends ImmutablePureComponent { | ||||
|         <Link to={`/statuses/${status.get('id')}/favourites`} className='detailed-status__link'> | ||||
|           <Icon id='star' /> | ||||
|           <span className='detailed-status__favorites'> | ||||
|             <FormattedNumber value={status.get('favourites_count')} /> | ||||
|             <AnimatedNumber value={status.get('favourites_count')} /> | ||||
|           </span> | ||||
|         </Link> | ||||
|       ); | ||||
| @ -233,7 +234,7 @@ export default class DetailedStatus extends ImmutablePureComponent { | ||||
|         <a href={`/interact/${status.get('id')}?type=favourite`} className='detailed-status__link' onClick={this.handleModalLink}> | ||||
|           <Icon id='star' /> | ||||
|           <span className='detailed-status__favorites'> | ||||
|             <FormattedNumber value={status.get('favourites_count')} /> | ||||
|             <AnimatedNumber value={status.get('favourites_count')} /> | ||||
|           </span> | ||||
|         </a> | ||||
|       ); | ||||
|  | ||||
| @ -168,10 +168,10 @@ | ||||
|     &.active { | ||||
|       transition: all 100ms ease-in; | ||||
|       transition-property: background-color, color; | ||||
|       background-color: mix(lighten($ui-base-color, 12%), $ui-highlight-color, 90%); | ||||
|       background-color: mix(lighten($ui-base-color, 12%), $ui-highlight-color, 80%); | ||||
| 
 | ||||
|       .reactions-bar__item__count { | ||||
|         color: $highlight-text-color; | ||||
|         color: lighten($highlight-text-color, 8%); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @ -3,6 +3,14 @@ | ||||
|   -ms-overflow-style: -ms-autohiding-scrollbar; | ||||
| } | ||||
| 
 | ||||
| .animated-number { | ||||
|   display: inline-flex; | ||||
|   flex-direction: column; | ||||
|   align-items: stretch; | ||||
|   overflow: hidden; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .link-button { | ||||
|   display: block; | ||||
|   font-size: 15px; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user