Skip to content

Instantly share code, notes, and snippets.

@dumpsayamrat
Created August 18, 2017 19:52
Show Gist options
  • Save dumpsayamrat/d7401767f75959957b24ff902ee2f34d to your computer and use it in GitHub Desktop.
Save dumpsayamrat/d7401767f75959957b24ff902ee2f34d to your computer and use it in GitHub Desktop.
// 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);
// 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);
// 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