diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2016-11-16 17:20:52 +0100 |
---|---|---|
committer | Eugen Rochko <eugen@zeonfederated.com> | 2016-11-16 17:20:52 +0100 |
commit | 01e43c3e5799b575a70798056945365ddf51f3ad (patch) | |
tree | 75801dd3733930cc05cd3c26795cef382a4c1e5d /app/assets/javascripts/components/components | |
parent | 546c4718e781f8900ba6498307ccb1e659de5edd (diff) |
Adding react-intl i18n to the frontend. No translations yet
Diffstat (limited to 'app/assets/javascripts/components/components')
8 files changed, 61 insertions, 81 deletions
diff --git a/app/assets/javascripts/components/components/column_back_button.jsx b/app/assets/javascripts/components/components/column_back_button.jsx index c3ed8f8d0..2f499c749 100644 --- a/app/assets/javascripts/components/components/column_back_button.jsx +++ b/app/assets/javascripts/components/components/column_back_button.jsx @@ -1,4 +1,5 @@ import PureRenderMixin from 'react-addons-pure-render-mixin'; +import { FormattedMessage } from 'react-intl'; const outerStyle = { padding: '15px', @@ -30,7 +31,7 @@ const ColumnBackButton = React.createClass({ return ( <div onClick={this.handleClick} style={outerStyle} className='column-back-button'> <i className='fa fa-fw fa-chevron-left' style={iconStyle} /> - Back + <FormattedMessage id='column_back_button.label' defaultMessage='Back' /> </div> ); } diff --git a/app/assets/javascripts/components/components/lightbox.jsx b/app/assets/javascripts/components/components/lightbox.jsx index aef0bac14..537bab954 100644 --- a/app/assets/javascripts/components/components/lightbox.jsx +++ b/app/assets/javascripts/components/components/lightbox.jsx @@ -1,6 +1,7 @@ import PureRenderMixin from 'react-addons-pure-render-mixin'; import IconButton from './icon_button'; import { Motion, spring } from 'react-motion'; +import { injectIntl } from 'react-intl'; const overlayStyle = { position: 'fixed', @@ -40,14 +41,14 @@ const Lightbox = React.createClass({ mixins: [PureRenderMixin], render () { - const { isVisible, onOverlayClicked, onCloseClicked, children } = this.props; + const { intl, 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} /> + <IconButton title={intl.formatMessage({ id: 'lightbox.close', defaultMessage: 'Close' })} icon='times' onClick={onCloseClicked} size={16} style={closeStyle} /> {children} </div> } @@ -58,4 +59,4 @@ const Lightbox = React.createClass({ }); -export default Lightbox; +export default injectIntl(Lightbox); diff --git a/app/assets/javascripts/components/components/loading_indicator.jsx b/app/assets/javascripts/components/components/loading_indicator.jsx index 7b738ac32..fd5acae84 100644 --- a/app/assets/javascripts/components/components/loading_indicator.jsx +++ b/app/assets/javascripts/components/components/loading_indicator.jsx @@ -1,3 +1,5 @@ +import { FormattedMessage } from 'react-intl'; + const LoadingIndicator = () => { const style = { textAlign: 'center', @@ -7,7 +9,7 @@ const LoadingIndicator = () => { paddingTop: '120px' }; - return <div style={style}>Loading...</div>; + return <div style={style}><FormattedMessage id='loading_indicator.label' defaultMessage='Loading...' /></div>; }; export default LoadingIndicator; diff --git a/app/assets/javascripts/components/components/relative_timestamp.jsx b/app/assets/javascripts/components/components/relative_timestamp.jsx index 1de44bb95..96f99cca8 100644 --- a/app/assets/javascripts/components/components/relative_timestamp.jsx +++ b/app/assets/javascripts/components/components/relative_timestamp.jsx @@ -1,52 +1,24 @@ -import moment from 'moment'; -import PureRenderMixin from 'react-addons-pure-render-mixin'; - -moment.updateLocale('en', { - relativeTime : { - future: "in %s", - past: "%s", - s: "%ds", - m: "1m", - mm: "%dm", - h: "1h", - hh: "%dh", - d: "1d", - dd: "%dd", - M: "1mo", - MM: "%dmo", - y: "1y", - yy: "%dy" - } -}); - -const RelativeTimestamp = React.createClass({ - - propTypes: { - timestamp: React.PropTypes.string.isRequired, - now: React.PropTypes.any - }, - - mixins: [PureRenderMixin], - - render () { - const timestamp = moment(this.props.timestamp); - const now = this.props.now; - - let string = ''; - - if (timestamp.isAfter(now)) { - string = 'Just now'; - } else { - string = timestamp.from(now); - } - - return ( - <span> - {string} - </span> - ); +import { + FormattedMessage, + FormattedDate, + FormattedRelative +} from 'react-intl'; + +const RelativeTimestamp = ({ timestamp, now }) => { + const diff = (new Date(now)) - (new Date(timestamp)); + + if (diff < 0) { + return <FormattedMessage id='relative_time.just_now' defaultMessage='Just now' /> + } else if (diff > (3600 * 24 * 7 * 1000)) { + return <FormattedDate value={timestamp} /> + } else { + return <FormattedRelative value={timestamp} initialNow={now} updateInterval={0} /> } +}; -}); +RelativeTimestamp.propTypes = { + timestamp: React.PropTypes.string.isRequired, + now: React.PropTypes.any +}; export default RelativeTimestamp; diff --git a/app/assets/javascripts/components/components/status.jsx b/app/assets/javascripts/components/components/status.jsx index ff14ba4f1..8077308c4 100644 --- a/app/assets/javascripts/components/components/status.jsx +++ b/app/assets/javascripts/components/components/status.jsx @@ -1,12 +1,13 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; -import Avatar from './avatar'; -import RelativeTimestamp from './relative_timestamp'; -import PureRenderMixin from 'react-addons-pure-render-mixin'; -import DisplayName from './display_name'; -import MediaGallery from './media_gallery'; -import VideoPlayer from './video_player'; -import StatusContent from './status_content'; -import StatusActionBar from './status_action_bar'; +import Avatar from './avatar'; +import RelativeTimestamp from './relative_timestamp'; +import PureRenderMixin from 'react-addons-pure-render-mixin'; +import DisplayName from './display_name'; +import MediaGallery from './media_gallery'; +import VideoPlayer from './video_player'; +import StatusContent from './status_content'; +import StatusActionBar from './status_action_bar'; +import { FormattedMessage } from 'react-intl'; const Status = React.createClass({ @@ -59,7 +60,7 @@ const Status = React.createClass({ <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 + <FormattedMessage id='status.reblogged_by' defaultMessage='{name} reblogged' values={{ name: <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> }} /> </div> <Status {...other} wrapped={true} status={status.get('reblog')} /> diff --git a/app/assets/javascripts/components/components/status_action_bar.jsx b/app/assets/javascripts/components/components/status_action_bar.jsx index e80ce824f..8883d0806 100644 --- a/app/assets/javascripts/components/components/status_action_bar.jsx +++ b/app/assets/javascripts/components/components/status_action_bar.jsx @@ -1,7 +1,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; -import PureRenderMixin from 'react-addons-pure-render-mixin'; -import IconButton from './icon_button'; -import DropdownMenu from './dropdown_menu'; +import PureRenderMixin from 'react-addons-pure-render-mixin'; +import IconButton from './icon_button'; +import DropdownMenu from './dropdown_menu'; +import { injectIntl } from 'react-intl'; const StatusActionBar = React.createClass({ propTypes: { @@ -36,20 +37,20 @@ const StatusActionBar = React.createClass({ }, render () { - const { status, me } = this.props; + const { status, me, intl } = this.props; let menu = []; if (status.getIn(['account', 'id']) === me) { - menu.push({ text: 'Delete', action: this.handleDeleteClick }); + menu.push({ text: intl.formatMessage({ id: 'status.delete', defaultMessage: 'Delete' }), action: this.handleDeleteClick }); } else { - menu.push({ text: 'Mention', action: this.handleMentionClick }); + menu.push({ text: intl.formatMessage({ id: 'status.mention', defaultMessage: 'Mention' }), action: this.handleMentionClick }); } return ( <div style={{ marginTop: '10px', overflow: 'hidden' }}> - <div style={{ float: 'left', marginRight: '18px'}}><IconButton title='Reply' icon='reply' onClick={this.handleReplyClick} /></div> - <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 style={{ float: 'left', marginRight: '18px'}}><IconButton title={intl.formatMessage({ id: 'status.reply', defaultMessage: 'Reply' })} icon='reply' onClick={this.handleReplyClick} /></div> + <div style={{ float: 'left', marginRight: '18px'}}><IconButton active={status.get('reblogged')} title={intl.formatMessage({ id: 'status.reblog', defaultMessage: 'Reblog' })} icon='retweet' onClick={this.handleReblogClick} /></div> + <div style={{ float: 'left', marginRight: '18px'}}><IconButton active={status.get('favourited')} title={intl.formatMessage({ id: 'status.favourite', defaultMessage: 'Favourite' })} icon='star' onClick={this.handleFavouriteClick} activeStyle={{ color: '#ca8f04' }} /></div> <div style={{ width: '18px', height: '18px', float: 'left' }}> <DropdownMenu items={menu} icon='ellipsis-h' size={18} /> @@ -60,4 +61,4 @@ const StatusActionBar = React.createClass({ }); -export default StatusActionBar; +export default injectIntl(StatusActionBar); diff --git a/app/assets/javascripts/components/components/status_list.jsx b/app/assets/javascripts/components/components/status_list.jsx index 58aa94cc0..d5d69c989 100644 --- a/app/assets/javascripts/components/components/status_list.jsx +++ b/app/assets/javascripts/components/components/status_list.jsx @@ -3,7 +3,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import PureRenderMixin from 'react-addons-pure-render-mixin'; import { ScrollContainer } from 'react-router-scroll'; import StatusContainer from '../containers/status_container'; -import moment from 'moment'; const StatusList = React.createClass({ @@ -21,14 +20,14 @@ const StatusList = React.createClass({ getInitialState () { return { - now: moment() + now: new Date() }; }, mixins: [PureRenderMixin], componentDidMount () { - this._interval = setInterval(() => this.setState({ now: moment() }), 60000); + this._interval = setInterval(() => this.setState({ now: new Date() }), 60000); }, componentWillUnmount () { diff --git a/app/assets/javascripts/components/components/video_player.jsx b/app/assets/javascripts/components/components/video_player.jsx index 209db33a7..2c236b996 100644 --- a/app/assets/javascripts/components/components/video_player.jsx +++ b/app/assets/javascripts/components/components/video_player.jsx @@ -1,6 +1,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; -import PureRenderMixin from 'react-addons-pure-render-mixin'; -import IconButton from './icon_button'; +import PureRenderMixin from 'react-addons-pure-render-mixin'; +import IconButton from './icon_button'; +import { injectIntl } from 'react-intl'; const videoStyle = { position: 'relative', @@ -59,14 +60,16 @@ const VideoPlayer = React.createClass({ }, render () { + const { media, intl, width, height } = this.props; + return ( - <div style={{ cursor: 'default', marginTop: '8px', overflow: 'hidden', width: `${this.props.width}px`, height: `${this.props.height}px`, boxSizing: 'border-box', background: '#000', position: 'relative' }}> - <div style={muteStyle}><IconButton title='Toggle sound' icon={this.state.muted ? 'volume-up' : 'volume-off'} onClick={this.handleClick} /></div> - <video src={this.props.media.get('url')} autoPlay='true' loop={true} muted={this.state.muted} style={videoStyle} onClick={this.handleVideoClick} /> + <div style={{ cursor: 'default', marginTop: '8px', overflow: 'hidden', width: `${width}px`, height: `${height}px`, boxSizing: 'border-box', background: '#000', position: 'relative' }}> + <div style={muteStyle}><IconButton title={intl.formatMessage({ id: 'video_player.toggle_sound', defaultMessage: 'Toggle sound' })} icon={this.state.muted ? 'volume-up' : 'volume-off'} onClick={this.handleClick} /></div> + <video src={media.get('url')} autoPlay='true' loop={true} muted={this.state.muted} style={videoStyle} onClick={this.handleVideoClick} /> </div> ); } }); -export default VideoPlayer; +export default injectIntl(VideoPlayer); |