Created
August 18, 2017 19:52
-
-
Save dumpsayamrat/d7401767f75959957b24ff902ee2f34d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Tweet.js | |
import React from 'react'; | |
import { compose, flattenProp, onlyUpdateForKeys } from 'recompose'; | |
const enhance = compose( | |
flattenProp('tweet'), | |
flattenProp('user'), | |
onlyUpdateForKeys(['username', 'image', 'name', 'tweet']), | |
); | |
const Tweet = props => ( | |
<div style={{ height: 'auto', display: 'flex', borderBottom: '1px solid #e6ecf0' }} className="tweet"> | |
<div style={{ flex: 1, position: 'relative' }}> | |
<img | |
style={{ | |
borderRadius: '50%', | |
left: 28, | |
position: 'absolute', | |
top: 13, | |
width: 64, | |
height: 64 | |
}} | |
src={props.image} | |
alt={props.name} | |
/> | |
</div> | |
<div style={{ flex: 5, padding: 10, display: 'flex', flexDirection: 'column' }}> | |
<div> | |
<strong>{props.name}</strong> {' '} <span style={{ color: '#585858' }}>@{props.username}</span> | |
</div> | |
<p style={{ whiteSpace: 'pre-line' }}>{props.tweet}</p> | |
</div> | |
</div> | |
); | |
export default enhance(Tweet); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// TweetBox.js | |
import React from 'react'; | |
import { compose, mapProps, flattenProp, onlyUpdateForKeys } from 'recompose'; | |
const enhance = compose( | |
mapProps(({ limit, message, ...rest }) => ({ | |
...rest, | |
limit, | |
message, | |
textRemaining: limit - message.length | |
})), | |
mapProps(({ textRemaining, ...rest }) => ({ | |
...rest, | |
textRemaining, | |
isLessThanTextRemaining: textRemaining < 0, | |
})), | |
mapProps(({ isLessThanTextRemaining, message, ...rest }) => ({ | |
...rest, | |
isLessThanTextRemaining, | |
message, | |
isButtonDisable: !message.length || isLessThanTextRemaining, | |
})), | |
flattenProp('user'), | |
onlyUpdateForKeys(['message', 'textRemaining', 'isLessThanTextRemaining', 'isButtonDisable']), | |
); | |
const TweetBox = props => ( | |
<div style={{ height: 150, display: 'flex' }}> | |
<div style={{ flex: 1, position: 'relative' }}> | |
<img | |
style={styles.imageStyle} | |
src={props.image} | |
alt={props.name} | |
/> | |
<h6 | |
style={styles.usernameStyle} | |
> | |
@{props.username} | |
</h6> | |
</div> | |
<div style={{ flex: 5, padding: 10, display: 'flex', flexDirection: 'column' }}> | |
<textarea | |
placeholder={'What\'s happening?'} | |
wrap="hard" | |
style={styles.textareaStyle} | |
onChange={props.onMessageChange} | |
value={props.message} | |
/> | |
<div style={{ alignSelf: 'flex-end', paddingTop: 10, display: 'flex', flexDirection: 'row' }}> | |
<h4 | |
style={{ | |
...styles.textRemainingStyle, | |
color: props.isLessThanTextRemaining ? 'red' : '#585858' | |
}} | |
> | |
{props.textRemaining} | |
</h4> | |
<button | |
style={{ | |
...styles.buttonStyle, | |
cursor: props.isButtonDisable ? 'default' : 'pointer', | |
opacity: props.isButtonDisable ? .3 : 1, | |
}} | |
disabled={props.isButtonDisable} | |
onClick={props.onTweetClick} | |
> | |
Tweet | |
</button> | |
</div> | |
</div> | |
</div> | |
); | |
const styles = { | |
usernameStyle: { | |
color: '#585858', | |
left: 35, | |
position: 'absolute', | |
top: 60, | |
width: 64, | |
height: 64 | |
}, | |
textareaStyle: { | |
resize: 'none', | |
width: '95%', | |
display: 'inline-block', | |
borderColor: '#55acee', | |
minHeight: 60, | |
fontSize: 16, | |
padding: 10, | |
}, | |
imageStyle: { | |
borderRadius: '50%', | |
left: 28, | |
position: 'absolute', | |
top: 13, | |
width: 64, | |
height: 64 | |
}, | |
textRemainingStyle: { | |
alignSelf: 'center', | |
marginRight: 10, | |
}, | |
buttonStyle: { | |
background: '#A7DBFB', | |
border: 'none', | |
width: 80, | |
padding: '6px 16px', | |
borderRadius: 100, | |
color: 'white', | |
fontWeight: 700, | |
fontSize: 14, | |
marginRight: 10, | |
}, | |
}; | |
export default enhance(TweetBox); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// TweetHome.js | |
import React from 'react'; | |
import { compose, withState, withHandlers } from 'recompose'; | |
import Tweet from './Tweet'; | |
import TweetBox from './TweetBox'; | |
import mockTweet from './mockTweets'; | |
const limit = 140; | |
const user = { | |
name: 'John Doe', | |
username: 'Ah_john', | |
image: './dog.jpg' | |
}; | |
const enhance = compose( | |
withState('limit', 'updateLimit', limit), | |
withState('user', 'updateUser', user), | |
withState('message', 'updateMessage', ''), | |
withState('tweets', 'updateTweets', mockTweet), | |
withHandlers({ | |
onMessageChange: ({ updateMessage }) => ({ target }) => updateMessage(() => target.value), | |
onTweetClick: ({ updateTweets, updateMessage, tweets, user, message }) => () => { | |
updateTweets(() => [ | |
...tweets, | |
{ | |
user, | |
tweet: message, | |
} | |
]); | |
updateMessage(() => ''); | |
}, | |
}), | |
); | |
const TweetHome = props => ( | |
<div style={{ display: 'flex', textAlign: 'left', width: 680, margin: 'auto', flexDirection: 'column' }}> | |
<div style={{ flex: 1, background: '#F4FAFE' }}> | |
<TweetBox | |
user={props.user} | |
message={props.message} | |
onMessageChange={props.onMessageChange} | |
limit={props.limit} | |
onTweetClick={props.onTweetClick} | |
/> | |
</div> | |
<div style={{ flex: 1, background: 'white', display: 'flex', flexDirection: 'column-reverse' }}> | |
{props.tweets.map((e, i) => <Tweet key={i} tweet={e} />)} | |
</div> | |
</div> | |
); | |
export default enhance(TweetHome); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment