Fix modals sizing and add animation to it, fix #140 by only making the text of
status clickable (this also fixes multiple dropdown being openable at the same time)
This commit is contained in:
		
							parent
							
								
									0320ea4b85
								
							
						
					
					
						commit
						82fd74d101
					
				| @ -28,7 +28,7 @@ const ColumnBackButton = React.createClass({ | ||||
| 
 | ||||
|   render () { | ||||
|     return ( | ||||
|       <div onClick={this.handleClick} style={outerStyle}> | ||||
|       <div onClick={this.handleClick} style={outerStyle} className='column-back-button'> | ||||
|         <i className='fa fa-fw fa-chevron-left' style={iconStyle} /> | ||||
|         Back | ||||
|       </div> | ||||
|  | ||||
| @ -7,7 +7,7 @@ const DropdownMenu = ({ icon, items, size }) => { | ||||
|         <i className={`fa fa-fw fa-${icon}`} style={{ verticalAlign: 'middle' }} /> | ||||
|       </DropdownTrigger> | ||||
| 
 | ||||
|       <DropdownContent style={{ lineHeight: '18px' }}> | ||||
|       <DropdownContent style={{ lineHeight: '18px', textAlign: 'left' }}> | ||||
|         <ul> | ||||
|           {items.map(({ text, action, href = '#' }, i) => <li key={i}><a href={href} target='_blank' rel='noopener' onClick={e => { | ||||
|             if (typeof action === 'function') { | ||||
|  | ||||
| @ -1,4 +1,6 @@ | ||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||
| import IconButton from './icon_button'; | ||||
| import { Motion, spring } from 'react-motion'; | ||||
| 
 | ||||
| const overlayStyle = { | ||||
|   position: 'fixed', | ||||
| @ -6,19 +8,17 @@ const overlayStyle = { | ||||
|   left: '0', | ||||
|   width: '100%', | ||||
|   height: '100%', | ||||
|   justifyContent: 'center', | ||||
|   alignContent: 'center', | ||||
|   background: 'rgba(0, 0, 0, 0.5)', | ||||
|   display: 'flex', | ||||
|   justifyContent: 'center', | ||||
|   alignContent: 'center', | ||||
|   flexDirection: 'row', | ||||
|   zIndex: '9999' | ||||
| }; | ||||
| 
 | ||||
| const dialogStyle = { | ||||
|   color: '#282c37', | ||||
|   background: '#d9e1e8', | ||||
|   borderRadius: '4px', | ||||
|   boxShadow: '0 0 15px rgba(0, 0, 0, 0.4)', | ||||
|   padding: '10px', | ||||
|   boxShadow: '0 0 30px rgba(0, 0, 0, 0.8)', | ||||
|   margin: 'auto', | ||||
|   position: 'relative' | ||||
| }; | ||||
| @ -29,25 +29,33 @@ const closeStyle = { | ||||
|   right: '4px' | ||||
| }; | ||||
| 
 | ||||
| const Lightbox = ({ isVisible, onOverlayClicked, onCloseClicked, children }) => { | ||||
|   if (!isVisible) { | ||||
|     return <div />; | ||||
| const Lightbox = React.createClass({ | ||||
| 
 | ||||
|   propTypes: { | ||||
|     isVisible: React.PropTypes.bool, | ||||
|     onOverlayClicked: React.PropTypes.func, | ||||
|     onCloseClicked: React.PropTypes.func | ||||
|   }, | ||||
| 
 | ||||
|   mixins: [PureRenderMixin], | ||||
| 
 | ||||
|   render () { | ||||
|     const { isVisible, onOverlayClicked, onCloseClicked, children } = this.props; | ||||
| 
 | ||||
|     return ( | ||||
|       <div className='lightbox' style={{...overlayStyle, display: isVisible ? 'flex' : 'none'}} onClick={onOverlayClicked}> | ||||
|         <Motion defaultStyle={{ y: -200 }} style={{ y: spring(isVisible ? 0 : -200) }}> | ||||
|           {({ y }) => | ||||
|             <div style={{...dialogStyle, transform: `translateY(${y}px)`}}> | ||||
|               <IconButton title='Close' icon='times' onClick={onCloseClicked} size={16} style={closeStyle} /> | ||||
|               {children} | ||||
|             </div> | ||||
|           } | ||||
|         </Motion> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   return ( | ||||
|     <div className='lightbox' style={overlayStyle} onClick={onOverlayClicked}> | ||||
|       <div style={dialogStyle}> | ||||
|         <IconButton title='Close' icon='times' onClick={onCloseClicked} size={16} style={closeStyle} /> | ||||
|         {children} | ||||
|       </div> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| Lightbox.propTypes = { | ||||
|   isVisible: React.PropTypes.bool, | ||||
|   onOverlayClicked: React.PropTypes.func, | ||||
|   onCloseClicked: React.PropTypes.func | ||||
| }; | ||||
| }); | ||||
| 
 | ||||
| export default Lightbox; | ||||
|  | ||||
| @ -58,7 +58,7 @@ const Status = React.createClass({ | ||||
|       } | ||||
| 
 | ||||
|       return ( | ||||
|         <div style={{ cursor: 'pointer' }} onClick={this.handleClick}> | ||||
|         <div style={{ cursor: 'default' }}> | ||||
|           <div style={{ marginLeft: '68px', color: '#616b86', padding: '8px 0', paddingBottom: '2px', fontSize: '14px', position: 'relative' }}> | ||||
|             <div style={{ position: 'absolute', 'left': '-26px'}}><i className='fa fa-fw fa-retweet'></i></div> | ||||
|             <a onClick={this.handleAccountClick.bind(this, status.getIn(['account', 'id']))} href={status.getIn(['account', 'url'])} className='status__display-name'><strong style={{ color: '#616b86'}}>{displayName}</strong></a> reblogged | ||||
| @ -78,7 +78,7 @@ const Status = React.createClass({ | ||||
|     } | ||||
| 
 | ||||
|     return ( | ||||
|       <div style={{ padding: '8px 10px', paddingLeft: '68px', position: 'relative', minHeight: '48px', borderBottom: '1px solid #363c4b', cursor: 'pointer' }} onClick={this.handleClick}> | ||||
|       <div style={{ padding: '8px 10px', paddingLeft: '68px', position: 'relative', minHeight: '48px', borderBottom: '1px solid #363c4b', cursor: 'default' }}> | ||||
|         <div style={{ fontSize: '15px' }}> | ||||
|           <div style={{ float: 'right', fontSize: '14px' }}> | ||||
|             <a href={status.get('url')} className='status__relative-time' style={{ color: '#616b86' }} target='_blank' rel='noopener'><RelativeTimestamp timestamp={status.get('created_at')} now={now} /></a> | ||||
| @ -93,7 +93,7 @@ const Status = React.createClass({ | ||||
|           </a> | ||||
|         </div> | ||||
| 
 | ||||
|         <StatusContent status={status} /> | ||||
|         <StatusContent status={status} onClick={this.handleClick} /> | ||||
| 
 | ||||
|         {media} | ||||
| 
 | ||||
|  | ||||
| @ -51,7 +51,7 @@ const StatusActionBar = React.createClass({ | ||||
|         <div style={{ float: 'left', marginRight: '18px'}}><IconButton active={status.get('reblogged')} title='Reblog' icon='retweet' onClick={this.handleReblogClick} /></div> | ||||
|         <div style={{ float: 'left', marginRight: '18px'}}><IconButton active={status.get('favourited')} title='Favourite' icon='star' onClick={this.handleFavouriteClick} activeStyle={{ color: '#ca8f04' }} /></div> | ||||
| 
 | ||||
|         <div onClick={e => e.stopPropagation()} style={{ width: '18px', height: '18px', float: 'left' }}> | ||||
|         <div style={{ width: '18px', height: '18px', float: 'left' }}> | ||||
|           <DropdownMenu items={menu} icon='ellipsis-h' size={18} /> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
| @ -13,7 +13,8 @@ const StatusContent = React.createClass({ | ||||
|   }, | ||||
| 
 | ||||
|   propTypes: { | ||||
|     status: ImmutablePropTypes.map.isRequired | ||||
|     status: ImmutablePropTypes.map.isRequired, | ||||
|     onClick: React.PropTypes.func | ||||
|   }, | ||||
| 
 | ||||
|   mixins: [PureRenderMixin], | ||||
| @ -61,7 +62,7 @@ const StatusContent = React.createClass({ | ||||
| 
 | ||||
|   render () { | ||||
|     const content = { __html: emojione.unicodeToImage(this.props.status.get('content')) }; | ||||
|     return <div className='status__content' dangerouslySetInnerHTML={content} />; | ||||
|     return <div className='status__content' style={{ cursor: 'pointer' }} dangerouslySetInnerHTML={content} onClick={this.props.onClick} />; | ||||
|   }, | ||||
| 
 | ||||
| }); | ||||
|  | ||||
| @ -28,7 +28,7 @@ const Header = React.createClass({ | ||||
| 
 | ||||
|     return ( | ||||
|       <div style={{ flex: '0 0 auto', background: '#2f3441', textAlign: 'center', backgroundImage: `url(${account.get('header')})`, backgroundSize: 'cover', position: 'relative' }}> | ||||
|         <div style={{ background: 'rgba(47, 52, 65, 0.8)', padding: '20px 10px' }}> | ||||
|         <div style={{ background: 'rgba(47, 52, 65, 0.9)', padding: '20px 10px' }}> | ||||
|           <a href={account.get('url')} target='_blank' rel='noopener' style={{ display: 'block', color: 'inherit', textDecoration: 'none' }}> | ||||
|             <div style={{ width: '90px', margin: '0 auto', marginBottom: '10px' }}> | ||||
|               <img src={account.get('avatar')} alt='' style={{ display: 'block', width: '90px', height: '90px', borderRadius: '90px' }} /> | ||||
|  | ||||
| @ -18,23 +18,23 @@ const ActionBar = React.createClass({ | ||||
|   mixins: [PureRenderMixin], | ||||
| 
 | ||||
|   handleReplyClick () { | ||||
|     this.props.onReply(status); | ||||
|     this.props.onReply(this.props.status); | ||||
|   }, | ||||
| 
 | ||||
|   handleReblogClick () { | ||||
|     this.props.onReblog(status); | ||||
|     this.props.onReblog(this.props.status); | ||||
|   }, | ||||
| 
 | ||||
|   handleFavouriteClick () { | ||||
|     this.props.onFavourite(status); | ||||
|     this.props.onFavourite(this.props.status); | ||||
|   }, | ||||
| 
 | ||||
|   handleDeleteClick () { | ||||
|     this.props.onDelete(status); | ||||
|     this.props.onDelete(this.props.status); | ||||
|   }, | ||||
| 
 | ||||
|   handleMentionClick () { | ||||
|     this.props.onMention(status.get('account')); | ||||
|     this.props.onMention(this.props.status.get('account')); | ||||
|   }, | ||||
| 
 | ||||
|   render () { | ||||
|  | ||||
| @ -19,9 +19,8 @@ const mapDispatchToProps = dispatch => ({ | ||||
| 
 | ||||
| const imageStyle = { | ||||
|   display: 'block', | ||||
|   maxWidth: '100%', | ||||
|   height: 'auto', | ||||
|   margin: '0 auto' | ||||
|   maxWidth: '80vw', | ||||
|   maxHeight: '80vh' | ||||
| }; | ||||
| 
 | ||||
| const Modal = React.createClass({ | ||||
|  | ||||
| @ -350,3 +350,9 @@ | ||||
|   flex: 1 1 auto; | ||||
|   -webkit-overflow-scrolling: touch; | ||||
| } | ||||
| 
 | ||||
| .column-back-button { | ||||
|   &:hover { | ||||
|     text-decoration: underline; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -43,6 +43,7 @@ | ||||
|   "dependencies": { | ||||
|     "emojione": "^2.2.6", | ||||
|     "react-autosuggest": "^7.0.1", | ||||
|     "react-motion": "^0.4.5", | ||||
|     "react-responsive": "^1.1.5", | ||||
|     "react-router-scroll": "^0.3.2" | ||||
|   } | ||||
|  | ||||
							
								
								
									
										17
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								yarn.lock
									
									
									
									
									
								
							| @ -3431,6 +3431,10 @@ pbkdf2@^3.0.3: | ||||
|   dependencies: | ||||
|     create-hmac "^1.1.2" | ||||
| 
 | ||||
| performance-now@^0.2.0, performance-now@~0.2.0: | ||||
|   version "0.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" | ||||
| 
 | ||||
| pinkie-promise@^2.0.0: | ||||
|   version "2.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" | ||||
| @ -3779,6 +3783,12 @@ querystring@^0.2.0, querystring@0.2.0: | ||||
|   version "0.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" | ||||
| 
 | ||||
| raf@^3.1.0: | ||||
|   version "3.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/raf/-/raf-3.3.0.tgz#93845eeffc773f8129039f677f80a36044eee2c3" | ||||
|   dependencies: | ||||
|     performance-now "~0.2.0" | ||||
| 
 | ||||
| randomatic@^1.1.3: | ||||
|   version "1.1.5" | ||||
|   resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.5.tgz#5e9ef5f2d573c67bd2b8124ae90b5156e457840b" | ||||
| @ -3887,6 +3897,13 @@ react-modal@^1.2.0, react-modal@^1.2.1: | ||||
|     exenv "1.2.0" | ||||
|     lodash.assign "^3.2.0" | ||||
| 
 | ||||
| react-motion: | ||||
|   version "0.4.5" | ||||
|   resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.4.5.tgz#ecc42f692fec9b2de4c92f85e26375071f779b76" | ||||
|   dependencies: | ||||
|     performance-now "^0.2.0" | ||||
|     raf "^3.1.0" | ||||
| 
 | ||||
| react-notification@^6.1.1: | ||||
|   version "6.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/react-notification/-/react-notification-6.2.1.tgz#deeccf15c0899badc24adaa704a1e78583762438" | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user