Skip to content
Snippets Groups Projects
Commit 01e43c3e authored by Eugen Rochko's avatar Eugen Rochko
Browse files

Adding react-intl i18n to the frontend. No translations yet

parent 546c4718
No related branches found
No related tags found
No related merge requests found
Showing
with 170 additions and 173 deletions
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>
);
}
......
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);
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;
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;
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')} />
......
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);
......@@ -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 () {
......
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);
......@@ -32,6 +32,7 @@ import Following from '../features/following';
import Reblogs from '../features/reblogs';
import Favourites from '../features/favourites';
import HashtagTimeline from '../features/hashtag_timeline';
import { IntlProvider } from 'react-intl';
const store = configureStore();
......@@ -44,7 +45,8 @@ const Mastodon = React.createClass({
propTypes: {
token: React.PropTypes.string.isRequired,
timelines: React.PropTypes.object,
account: React.PropTypes.string
account: React.PropTypes.string,
locale: React.PropTypes.string.isRequired
},
mixins: [PureRenderMixin],
......@@ -81,30 +83,34 @@ const Mastodon = React.createClass({
},
render () {
const { locale } = this.props;
return (
<Provider store={store}>
<Router history={browserHistory} render={applyRouterMiddleware(useScroll())}>
<Route path='/' component={UI}>
<IndexRoute component={GettingStarted} />
<Route path='timelines/home' component={HomeTimeline} />
<Route path='timelines/mentions' component={MentionsTimeline} />
<Route path='timelines/public' component={PublicTimeline} />
<Route path='timelines/tag/:id' component={HashtagTimeline} />
<Route path='statuses/new' component={Compose} />
<Route path='statuses/:statusId' component={Status} />
<Route path='statuses/:statusId/reblogs' component={Reblogs} />
<Route path='statuses/:statusId/favourites' component={Favourites} />
<Route path='accounts/:accountId' component={Account}>
<IndexRoute component={AccountTimeline} />
<Route path='followers' component={Followers} />
<Route path='following' component={Following} />
<IntlProvider locale={locale}>
<Provider store={store}>
<Router history={browserHistory} render={applyRouterMiddleware(useScroll())}>
<Route path='/' component={UI}>
<IndexRoute component={GettingStarted} />
<Route path='timelines/home' component={HomeTimeline} />
<Route path='timelines/mentions' component={MentionsTimeline} />
<Route path='timelines/public' component={PublicTimeline} />
<Route path='timelines/tag/:id' component={HashtagTimeline} />
<Route path='statuses/new' component={Compose} />
<Route path='statuses/:statusId' component={Status} />
<Route path='statuses/:statusId/reblogs' component={Reblogs} />
<Route path='statuses/:statusId/favourites' component={Favourites} />
<Route path='accounts/:accountId' component={Account}>
<IndexRoute component={AccountTimeline} />
<Route path='followers' component={Followers} />
<Route path='following' component={Following} />
</Route>
</Route>
</Route>
</Router>
</Provider>
</Router>
</Provider>
</IntlProvider>
);
}
......
import PureRenderMixin from 'react-addons-pure-render-mixin';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import ImmutablePropTypes from 'react-immutable-proptypes';
import DropdownMenu from '../../../components/dropdown_menu';
import { Link } from 'react-router';
import DropdownMenu from '../../../components/dropdown_menu';
import { Link } from 'react-router';
import { injectIntl, FormattedMessage, FormattedNumber } from 'react-intl';
const outerStyle = {
borderTop: '1px solid #363c4b',
......@@ -36,22 +37,22 @@ const ActionBar = React.createClass({
mixins: [PureRenderMixin],
render () {
const { account, me } = this.props;
const { account, me, intl } = this.props;
let menu = [];
menu.push({ text: 'Mention', action: this.props.onMention });
menu.push({ text: intl.formatMessage({ id: 'account.mention', defaultMessage: 'Mention' }), action: this.props.onMention });
if (account.get('id') === me) {
menu.push({ text: 'Edit profile', href: '/settings/profile' });
menu.push({ text: intl.formatMessage({ id: 'account.edit_profile', defaultMessage: 'Edit profile' }), href: '/settings/profile' });
} else if (account.getIn(['relationship', 'blocking'])) {
menu.push({ text: 'Unblock', action: this.props.onBlock });
menu.push({ text: intl.formatMessage({ id: 'account.unblock', defaultMessage: 'Unblock' }), action: this.props.onBlock });
} else if (account.getIn(['relationship', 'following'])) {
menu.push({ text: 'Unfollow', action: this.props.onFollow });
menu.push({ text: 'Block', action: this.props.onBlock });
menu.push({ text: intl.formatMessage({ id: 'account.unfollow', defaultMessage: 'Unfollow' }), action: this.props.onFollow });
menu.push({ text: intl.formatMessage({ id: 'account.block', defaultMessage: 'Block' }), action: this.props.onBlock });
} else {
menu.push({ text: 'Follow', action: this.props.onFollow });
menu.push({ text: 'Block', action: this.props.onBlock });
menu.push({ text: intl.formatMessage({ id: 'account.follow', defaultMessage: 'Follow' }), action: this.props.onFollow });
menu.push({ text: intl.formatMessage({ id: 'account.block', defaultMessage: 'Block' }), action: this.props.onBlock });
}
return (
......@@ -62,24 +63,24 @@ const ActionBar = React.createClass({
<div style={outerLinksStyle}>
<Link to={`/accounts/${account.get('id')}`} style={{ textDecoration: 'none', overflow: 'hidden', width: '80px', borderLeft: '1px solid #363c4b', padding: '10px', paddingRight: '5px' }}>
<span style={{ display: 'block', textTransform: 'uppercase', fontSize: '11px', color: '#616b86' }}>Posts</span>
<span style={{ display: 'block', fontSize: '15px', fontWeight: '500', color: '#fff' }}>{account.get('statuses_count')}</span>
<span style={{ display: 'block', textTransform: 'uppercase', fontSize: '11px', color: '#616b86' }}><FormattedMessage id='account.posts' defaultMessage='Posts' /></span>
<span style={{ display: 'block', fontSize: '15px', fontWeight: '500', color: '#fff' }}><FormattedNumber value={account.get('statuses_count')} /></span>
</Link>
<Link to={`/accounts/${account.get('id')}/following`} style={{ textDecoration: 'none', overflow: 'hidden', width: '80px', borderLeft: '1px solid #363c4b', padding: '10px 5px' }}>
<span style={{ display: 'block', textTransform: 'uppercase', fontSize: '11px', color: '#616b86' }}>Follows</span>
<span style={{ display: 'block', fontSize: '15px', fontWeight: '500', color: '#fff' }}>{account.get('following_count')}</span>
<span style={{ display: 'block', textTransform: 'uppercase', fontSize: '11px', color: '#616b86' }}><FormattedMessage id='account.follows' defaultMessage='Follows' /></span>
<span style={{ display: 'block', fontSize: '15px', fontWeight: '500', color: '#fff' }}><FormattedNumber value={account.get('following_count')} /></span>
</Link>
<Link to={`/accounts/${account.get('id')}/followers`} style={{ textDecoration: 'none', overflow: 'hidden', width: '80px', padding: '10px 5px', borderLeft: '1px solid #363c4b' }}>
<span style={{ display: 'block', textTransform: 'uppercase', fontSize: '11px', color: '#616b86' }}>Followers</span>
<span style={{ display: 'block', fontSize: '15px', fontWeight: '500', color: '#fff' }}>{account.get('followers_count')}</span>
<span style={{ display: 'block', textTransform: 'uppercase', fontSize: '11px', color: '#616b86' }}><FormattedMessage id='account.followers' defaultMessage='Followers' /></span>
<span style={{ display: 'block', fontSize: '15px', fontWeight: '500', color: '#fff' }}><FormattedNumber value={account.get('followers_count')} /></span>
</Link>
</div>
</div>
);
},
}
});
export default ActionBar;
export default injectIntl(ActionBar);
import { connect } from 'react-redux';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import ImmutablePropTypes from 'react-immutable-proptypes';
import {
fetchAccountTimeline,
expandAccountTimeline
} from '../../actions/accounts';
import StatusList from '../../components/status_list';
import LoadingIndicator from '../../components/loading_indicator';
} from '../../actions/accounts';
import StatusList from '../../components/status_list';
import LoadingIndicator from '../../components/loading_indicator';
const mapStateToProps = (state, props) => ({
statusIds: state.getIn(['timelines', 'accounts_timelines', Number(props.params.accountId)]),
......
......@@ -8,6 +8,7 @@ import Autosuggest from 'react-autosuggest';
import AutosuggestAccountContainer from '../../compose/containers/autosuggest_account_container';
import { debounce } from 'react-decoration';
import UploadButtonContainer from '../containers/upload_button_container';
import { injectIntl } from 'react-intl';
const getTokenForSuggestions = (str, caretPosition) => {
let word;
......@@ -134,6 +135,7 @@ const ComposeForm = React.createClass({
},
render () {
const { intl } = this.props;
let replyArea = '';
const disabled = this.props.is_submitting || this.props.is_uploading;
......@@ -142,7 +144,7 @@ const ComposeForm = React.createClass({
}
const inputProps = {
placeholder: 'What is on your mind?',
placeholder: intl.formatMessage({ id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' }),
value: this.props.text,
onKeyUp: this.handleKeyUp,
onChange: this.handleChange,
......@@ -167,7 +169,7 @@ const ComposeForm = React.createClass({
/>
<div style={{ marginTop: '10px', overflow: 'hidden' }}>
<div style={{ float: 'right' }}><Button text='Publish' onClick={this.handleSubmit} disabled={disabled} /></div>
<div style={{ float: 'right' }}><Button text={intl.formatMessage({ id: 'compose_form.publish', defaultMessage: 'Publish' })} onClick={this.handleSubmit} disabled={disabled} /></div>
<div style={{ float: 'right', marginRight: '16px', lineHeight: '36px' }}><CharacterCounter max={500} text={this.props.text} /></div>
<UploadButtonContainer style={{ paddingTop: '4px' }} />
</div>
......@@ -177,4 +179,4 @@ const ComposeForm = React.createClass({
});
export default ComposeForm;
export default injectIntl(ComposeForm);
import PureRenderMixin from 'react-addons-pure-render-mixin';
import ImmutablePropTypes from 'react-immutable-proptypes';
import Avatar from '../../../components/avatar';
import IconButton from '../../../components/icon_button';
import DisplayName from '../../../components/display_name';
import { Link } from 'react-router';
import IconButton from '../../../components/icon_button';
import DisplayName from '../../../components/display_name';
import { Link } from 'react-router';
import { FormattedMessage } from 'react-intl';
const NavigationBar = React.createClass({
propTypes: {
......@@ -19,7 +20,7 @@ const NavigationBar = React.createClass({
<div style={{ flex: '1 1 auto', marginLeft: '8px', color: '#9baec8' }}>
<strong style={{ fontWeight: '500', display: 'block', color: '#fff' }}>{this.props.account.get('acct')}</strong>
<a href='/settings/profile' style={{ color: 'inherit', textDecoration: 'none' }}>Settings</a> · <Link to='/timelines/public' style={{ color: 'inherit', textDecoration: 'none' }}>Public timeline</Link> · <a href='/auth/sign_out' data-method='delete' style={{ color: 'inherit', textDecoration: 'none' }}>Logout</a>
<a href='/settings/profile' style={{ color: 'inherit', textDecoration: 'none' }}><FormattedMessage id='navigation_bar.settings' defaultMessage='Settings' /></a> · <Link to='/timelines/public' style={{ color: 'inherit', textDecoration: 'none' }}><FormattedMessage id='navigation_bar.public_timeline' defaultMessage='Public timeline' /></Link> · <a href='/auth/sign_out' data-method='delete' style={{ color: 'inherit', textDecoration: 'none' }}><FormattedMessage id='navigation_bar.logout' defaultMessage='Logout' /></a>
</div>
</div>
);
......
......@@ -3,11 +3,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import Avatar from '../../../components/avatar';
import IconButton from '../../../components/icon_button';
import DisplayName from '../../../components/display_name';
import emojione from 'emojione';
emojione.imageType = 'png';
emojione.sprites = false;
emojione.imagePathPNG = '/emoji/';
import emojify from '../../../emoji';
import { injectIntl } from 'react-intl';
const ReplyIndicator = React.createClass({
......@@ -34,12 +31,13 @@ const ReplyIndicator = React.createClass({
},
render () {
let content = { __html: emojione.unicodeToImage(this.props.status.get('content')) };
const { intl } = this.props;
const content = { __html: emojify(this.props.status.get('content')) };
return (
<div style={{ background: '#9baec8', padding: '10px' }}>
<div style={{ overflow: 'hidden', marginBottom: '5px' }}>
<div style={{ float: 'right', lineHeight: '24px' }}><IconButton title='Cancel' icon='times' onClick={this.handleClick} /></div>
<div style={{ float: 'right', lineHeight: '24px' }}><IconButton title={intl.formatMessage({ id: 'reply_indicator.cancel', defaultMessage: 'Cancel' })} icon='times' onClick={this.handleClick} /></div>
<a href={this.props.status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='reply-indicator__display-name' style={{ display: 'block', maxWidth: '100%', paddingRight: '25px', color: '#282c37', textDecoration: 'none', overflow: 'hidden', lineHeight: '24px' }}>
<div style={{ float: 'left', marginRight: '5px' }}><Avatar size={24} src={this.props.status.getIn(['account', 'avatar'])} /></div>
......@@ -54,4 +52,4 @@ const ReplyIndicator = React.createClass({
});
export default ReplyIndicator;
export default injectIntl(ReplyIndicator);
......@@ -3,6 +3,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import Autosuggest from 'react-autosuggest';
import AutosuggestAccountContainer from '../containers/autosuggest_account_container';
import { debounce } from 'react-decoration';
import { injectIntl } from 'react-intl';
const getSuggestionValue = suggestion => suggestion.value;
......@@ -94,7 +95,7 @@ const Search = React.createClass({
render () {
const inputProps = {
placeholder: 'Search',
placeholder: this.props.intl.formatMessage({ id: 'search.placeholder', defaultMessage: 'Search' }),
value: this.props.value,
onChange: this.onChange,
style: inputStyle
......@@ -125,4 +126,4 @@ const Search = React.createClass({
});
export default Search;
export default injectIntl(Search);
import PureRenderMixin from 'react-addons-pure-render-mixin';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import ImmutablePropTypes from 'react-immutable-proptypes';
import AccountContainer from '../../followers/containers/account_container';
import AccountContainer from '../../followers/containers/account_container';
import { FormattedMessage } from 'react-intl';
const outerStyle = {
position: 'relative'
......@@ -66,13 +67,13 @@ const SuggestionsBox = React.createClass({
let nextLink = '';
if (accountIds.size > perWindow) {
nextLink = <a href='#' style={nextStyle} onClick={this.handleNextClick}>Refresh</a>;
nextLink = <a href='#' style={nextStyle} onClick={this.handleNextClick}><FormattedMessage id='suggestions_box.refresh' defaultMessage='Refresh' /></a>;
}
return (
<div style={outerStyle}>
<strong style={headerStyle}>
Who to follow {nextLink}
<FormattedMessage id='suggestions_box.who_to_follow' defaultMessage='Who to follow' /> {nextLink}
</strong>
{accountIds.skip(perWindow * this.state.index).take(perWindow).map(accountId => <AccountContainer key={accountId} id={accountId} withNote={false} />)}
......
import PureRenderMixin from 'react-addons-pure-render-mixin';
import IconButton from '../../../components/icon_button';
import { injectIntl } from 'react-intl';
const UploadButton = React.createClass({
......@@ -26,9 +27,11 @@ const UploadButton = React.createClass({
},
render () {
const { intl } = this.props;
return (
<div style={this.props.style}>
<IconButton icon='photo' title='Add media' disabled={this.props.disabled} onClick={this.handleClick} size={24} />
<IconButton icon='photo' title={intl.formatMessage({ id: 'upload_button.label', defaultMessage: 'Add media' })} disabled={this.props.disabled} onClick={this.handleClick} size={24} />
<input ref={this.setRef} type='file' multiple={false} onChange={this.handleChange} disabled={this.props.disabled} style={{ display: 'none' }} />
</div>
);
......@@ -36,4 +39,4 @@ const UploadButton = React.createClass({
});
export default UploadButton;
export default injectIntl(UploadButton);
import PureRenderMixin from 'react-addons-pure-render-mixin';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import ImmutablePropTypes from 'react-immutable-proptypes';
import IconButton from '../../../components/icon_button';
import IconButton from '../../../components/icon_button';
import { injectIntl } from 'react-intl';
const UploadForm = React.createClass({
......@@ -13,10 +14,12 @@ const UploadForm = React.createClass({
mixins: [PureRenderMixin],
render () {
const { intl } = this.props;
const uploads = this.props.media.map(attachment => (
<div key={attachment.get('id')} style={{ borderRadius: '4px', marginBottom: '10px' }} className='transparent-background'>
<div style={{ width: '100%', height: '100px', borderRadius: '4px', background: `url(${attachment.get('preview_url')}) no-repeat center`, backgroundSize: 'cover' }}>
<IconButton icon='times' title='Undo' size={36} onClick={this.props.onRemoveFile.bind(this, attachment.get('id'))} />
<IconButton icon='times' title={intl.formatMessage({ id: 'upload_form.undo', defaultMessage: 'Undo' })} size={36} onClick={this.props.onRemoveFile.bind(this, attachment.get('id'))} />
</div>
</div>
));
......@@ -30,4 +33,4 @@ const UploadForm = React.createClass({
});
export default UploadForm;
export default injectIntl(UploadForm);
import { connect } from 'react-redux';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import ImmutablePropTypes from 'react-immutable-proptypes';
import LoadingIndicator from '../../components/loading_indicator';
import { fetchFavourites } from '../../actions/interactions';
import { ScrollContainer } from 'react-router-scroll';
import AccountContainer from '../followers/containers/account_container';
import Column from '../ui/components/column';
import ColumnBackButton from '../../components/column_back_button';
import { connect } from 'react-redux';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import ImmutablePropTypes from 'react-immutable-proptypes';
import LoadingIndicator from '../../components/loading_indicator';
import { fetchFavourites } from '../../actions/interactions';
import { ScrollContainer } from 'react-router-scroll';
import AccountContainer from '../followers/containers/account_container';
import Column from '../ui/components/column';
import ColumnBackButton from '../../components/column_back_button';
const mapStateToProps = (state, props) => ({
accountIds: state.getIn(['user_lists', 'favourited_by', Number(props.params.statusId)])
......
import PureRenderMixin from 'react-addons-pure-render-mixin';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import ImmutablePropTypes from 'react-immutable-proptypes';
import Avatar from '../../../components/avatar';
import DisplayName from '../../../components/display_name';
import { Link } from 'react-router';
import IconButton from '../../../components/icon_button';
import Avatar from '../../../components/avatar';
import DisplayName from '../../../components/display_name';
import { Link } from 'react-router';
import IconButton from '../../../components/icon_button';
import { injectIntl } from 'react-intl';
const outerStyle = {
padding: '10px',
......@@ -51,7 +52,7 @@ const Account = React.createClass({
},
render () {
const { account, me, withNote } = this.props;
const { account, me, withNote, intl } = this.props;
if (!account) {
return <div />;
......@@ -68,7 +69,7 @@ const Account = React.createClass({
buttons = (
<div style={buttonsStyle}>
<IconButton icon={following ? 'user-times' : 'user-plus'} title='Follow' onClick={this.handleFollow} active={following} />
<IconButton icon={following ? 'user-times' : 'user-plus'} title={intl.formatMessage({ id: 'account.follow', defaultMessage: 'Follow' })} onClick={this.handleFollow} active={following} />
</div>
);
}
......@@ -91,4 +92,4 @@ const Account = React.createClass({
});
export default Account;
export default injectIntl(Account);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment