Adding german localization
This commit is contained in:
		
							parent
							
								
									c1be1ac7c6
								
							
						
					
					
						commit
						85d1b74ac3
					
				| @ -2,7 +2,15 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; | |||||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||||
| import IconButton from './icon_button'; | import IconButton from './icon_button'; | ||||||
| import DropdownMenu from './dropdown_menu'; | import DropdownMenu from './dropdown_menu'; | ||||||
| import { injectIntl } from 'react-intl'; | import { defineMessages, injectIntl } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | const messages = defineMessages({ | ||||||
|  |   delete: { id: 'status.delete', defaultMessage: 'Delete' }, | ||||||
|  |   mention: { id: 'status.mention', defaultMessage: 'Mention' }, | ||||||
|  |   reply: { id: 'status.reply', defaultMessage: 'Reply' }, | ||||||
|  |   reblog: { id: 'status.reblog', defaultMessage: 'Reblog' }, | ||||||
|  |   favourite: { id: 'status.favourite', defaultMessage: 'Favourite' } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| const StatusActionBar = React.createClass({ | const StatusActionBar = React.createClass({ | ||||||
|   propTypes: { |   propTypes: { | ||||||
| @ -41,16 +49,16 @@ const StatusActionBar = React.createClass({ | |||||||
|     let menu = []; |     let menu = []; | ||||||
| 
 | 
 | ||||||
|     if (status.getIn(['account', 'id']) === me) { |     if (status.getIn(['account', 'id']) === me) { | ||||||
|       menu.push({ text: intl.formatMessage({ id: 'status.delete', defaultMessage: 'Delete' }), action: this.handleDeleteClick }); |       menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick }); | ||||||
|     } else { |     } else { | ||||||
|       menu.push({ text: intl.formatMessage({ id: 'status.mention', defaultMessage: 'Mention' }), action: this.handleMentionClick }); |       menu.push({ text: intl.formatMessage(messages.mention), action: this.handleMentionClick }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <div style={{ marginTop: '10px', overflow: 'hidden' }}> |       <div style={{ marginTop: '10px', overflow: 'hidden' }}> | ||||||
|         <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 title={intl.formatMessage(messages.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('reblogged')} title={intl.formatMessage(messages.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={{ float: 'left', marginRight: '18px'}}><IconButton active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} activeStyle={{ color: '#ca8f04' }} /></div> | ||||||
| 
 | 
 | ||||||
|         <div style={{ width: '18px', height: '18px', float: 'left' }}> |         <div style={{ width: '18px', height: '18px', float: 'left' }}> | ||||||
|           <DropdownMenu items={menu} icon='ellipsis-h' size={18} /> |           <DropdownMenu items={menu} icon='ellipsis-h' size={18} /> | ||||||
|  | |||||||
| @ -1,7 +1,11 @@ | |||||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||||
| import IconButton from './icon_button'; | import IconButton from './icon_button'; | ||||||
| import { injectIntl } from 'react-intl'; | import { defineMessages, injectIntl } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | const messages = defineMessages({ | ||||||
|  |   toggle_sound: { id: 'video_player.toggle_sound', defaultMessage: 'Toggle sound' } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| const videoStyle = { | const videoStyle = { | ||||||
|   position: 'relative', |   position: 'relative', | ||||||
| @ -64,7 +68,7 @@ const VideoPlayer = React.createClass({ | |||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <div style={{ cursor: 'default', marginTop: '8px', overflow: 'hidden', width: `${width}px`, height: `${height}px`, boxSizing: 'border-box', background: '#000', position: 'relative' }}> |       <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> |         <div style={muteStyle}><IconButton title={intl.formatMessage(messages.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} /> |         <video src={media.get('url')} autoPlay='true' loop={true} muted={this.state.muted} style={videoStyle} onClick={this.handleVideoClick} /> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|  | |||||||
| @ -34,6 +34,8 @@ import Favourites from '../features/favourites'; | |||||||
| import HashtagTimeline from '../features/hashtag_timeline'; | import HashtagTimeline from '../features/hashtag_timeline'; | ||||||
| import { IntlProvider, addLocaleData } from 'react-intl'; | import { IntlProvider, addLocaleData } from 'react-intl'; | ||||||
| import en from 'react-intl/locale-data/en'; | import en from 'react-intl/locale-data/en'; | ||||||
|  | import de from 'react-intl/locale-data/de'; | ||||||
|  | import getMessagesForLocale from '../locales'; | ||||||
| 
 | 
 | ||||||
| const store = configureStore(); | const store = configureStore(); | ||||||
| 
 | 
 | ||||||
| @ -41,7 +43,7 @@ const browserHistory = useRouterHistory(createBrowserHistory)({ | |||||||
|   basename: '/web' |   basename: '/web' | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| addLocaleData([...en]); | addLocaleData([...en, ...de]); | ||||||
| 
 | 
 | ||||||
| const Mastodon = React.createClass({ | const Mastodon = React.createClass({ | ||||||
| 
 | 
 | ||||||
| @ -89,7 +91,7 @@ const Mastodon = React.createClass({ | |||||||
|     const { locale } = this.props; |     const { locale } = this.props; | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <IntlProvider locale={locale}> |       <IntlProvider locale={locale} messages={getMessagesForLocale(locale)}> | ||||||
|         <Provider store={store}> |         <Provider store={store}> | ||||||
|           <Router history={browserHistory} render={applyRouterMiddleware(useScroll())}> |           <Router history={browserHistory} render={applyRouterMiddleware(useScroll())}> | ||||||
|             <Route path='/' component={UI}> |             <Route path='/' component={UI}> | ||||||
|  | |||||||
| @ -2,7 +2,17 @@ import PureRenderMixin from 'react-addons-pure-render-mixin'; | |||||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||||
| import DropdownMenu from '../../../components/dropdown_menu'; | import DropdownMenu from '../../../components/dropdown_menu'; | ||||||
| import { Link } from 'react-router'; | import { Link } from 'react-router'; | ||||||
| import { injectIntl, FormattedMessage, FormattedNumber } from 'react-intl'; | import { defineMessages, injectIntl, FormattedMessage, FormattedNumber } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | const messages = defineMessages({ | ||||||
|  |   mention: { id: 'account.mention', defaultMessage: 'Mention' }, | ||||||
|  |   edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, | ||||||
|  |   unblock: { id: 'account.unblock', defaultMessage: 'Unblock' }, | ||||||
|  |   unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, | ||||||
|  |   block: { id: 'account.block', defaultMessage: 'Block' }, | ||||||
|  |   follow: { id: 'account.follow', defaultMessage: 'Follow' }, | ||||||
|  |   block: { id: 'account.block', defaultMessage: 'Block' } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| const outerStyle = { | const outerStyle = { | ||||||
|   borderTop: '1px solid #363c4b', |   borderTop: '1px solid #363c4b', | ||||||
| @ -41,18 +51,18 @@ const ActionBar = React.createClass({ | |||||||
| 
 | 
 | ||||||
|     let menu = []; |     let menu = []; | ||||||
| 
 | 
 | ||||||
|     menu.push({ text: intl.formatMessage({ id: 'account.mention', defaultMessage: 'Mention' }), action: this.props.onMention }); |     menu.push({ text: intl.formatMessage(messages.mention), action: this.props.onMention }); | ||||||
| 
 | 
 | ||||||
|     if (account.get('id') === me) { |     if (account.get('id') === me) { | ||||||
|       menu.push({ text: intl.formatMessage({ id: 'account.edit_profile', defaultMessage: 'Edit profile' }), href: '/settings/profile' }); |       menu.push({ text: intl.formatMessage(messages.edit_profile), href: '/settings/profile' }); | ||||||
|     } else if (account.getIn(['relationship', 'blocking'])) { |     } else if (account.getIn(['relationship', 'blocking'])) { | ||||||
|       menu.push({ text: intl.formatMessage({ id: 'account.unblock', defaultMessage: 'Unblock' }), action: this.props.onBlock }); |       menu.push({ text: intl.formatMessage(messages.unblock), action: this.props.onBlock }); | ||||||
|     } else if (account.getIn(['relationship', 'following'])) { |     } else if (account.getIn(['relationship', 'following'])) { | ||||||
|       menu.push({ text: intl.formatMessage({ id: 'account.unfollow', defaultMessage: 'Unfollow' }), action: this.props.onFollow }); |       menu.push({ text: intl.formatMessage(messages.unfollow), action: this.props.onFollow }); | ||||||
|       menu.push({ text: intl.formatMessage({ id: 'account.block', defaultMessage: 'Block' }), action: this.props.onBlock }); |       menu.push({ text: intl.formatMessage(messages.block), action: this.props.onBlock }); | ||||||
|     } else { |     } else { | ||||||
|       menu.push({ text: intl.formatMessage({ id: 'account.follow', defaultMessage: 'Follow' }), action: this.props.onFollow }); |       menu.push({ text: intl.formatMessage(messages.follow), action: this.props.onFollow }); | ||||||
|       menu.push({ text: intl.formatMessage({ id: 'account.block', defaultMessage: 'Block' }), action: this.props.onBlock }); |       menu.push({ text: intl.formatMessage(messages.block), action: this.props.onBlock }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ import PureRenderMixin from 'react-addons-pure-render-mixin'; | |||||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||||
| import emojify from '../../../emoji'; | import emojify from '../../../emoji'; | ||||||
| import escapeTextContentForBrowser from 'react/lib/escapeTextContentForBrowser'; | import escapeTextContentForBrowser from 'react/lib/escapeTextContentForBrowser'; | ||||||
|  | import { FormattedMessage } from 'react-intl'; | ||||||
| 
 | 
 | ||||||
| const Header = React.createClass({ | const Header = React.createClass({ | ||||||
| 
 | 
 | ||||||
| @ -23,7 +24,7 @@ const Header = React.createClass({ | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (me !== account.get('id') && account.getIn(['relationship', 'followed_by'])) { |     if (me !== account.get('id') && account.getIn(['relationship', 'followed_by'])) { | ||||||
|       info = <span style={{ position: 'absolute', top: '10px', right: '10px', opacity: '0.7', display: 'inline-block', verticalAlign: 'top', background: 'rgba(0, 0, 0, 0.4)', color: '#fff', textTransform: 'uppercase', fontSize: '11px', fontWeight: '500', padding: '4px', borderRadius: '4px' }}>Follows you</span> |       info = <span style={{ position: 'absolute', top: '10px', right: '10px', opacity: '0.7', display: 'inline-block', verticalAlign: 'top', background: 'rgba(0, 0, 0, 0.4)', color: '#fff', textTransform: 'uppercase', fontSize: '11px', fontWeight: '500', padding: '4px', borderRadius: '4px' }}><FormattedMessage id='account.follows_you' defaultMessage='Follows you' /></span> | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const content         = { __html: emojify(account.get('note')) }; |     const content         = { __html: emojify(account.get('note')) }; | ||||||
|  | |||||||
| @ -8,7 +8,12 @@ import Autosuggest from 'react-autosuggest'; | |||||||
| import AutosuggestAccountContainer from '../../compose/containers/autosuggest_account_container'; | import AutosuggestAccountContainer from '../../compose/containers/autosuggest_account_container'; | ||||||
| import { debounce } from 'react-decoration'; | import { debounce } from 'react-decoration'; | ||||||
| import UploadButtonContainer from '../containers/upload_button_container'; | import UploadButtonContainer from '../containers/upload_button_container'; | ||||||
| import { injectIntl } from 'react-intl'; | import { defineMessages, injectIntl } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | const messages = defineMessages({ | ||||||
|  |   placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' }, | ||||||
|  |   publish: { id: 'compose_form.publish', defaultMessage: 'Publish' } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| const getTokenForSuggestions = (str, caretPosition) => { | const getTokenForSuggestions = (str, caretPosition) => { | ||||||
|   let word; |   let word; | ||||||
| @ -53,7 +58,7 @@ const textareaStyle = { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const renderInputComponent = inputProps => ( | const renderInputComponent = inputProps => ( | ||||||
|   <textarea {...inputProps} placeholder='What is on your mind?'  className='compose-form__textarea' style={textareaStyle} /> |   <textarea {...inputProps} className='compose-form__textarea' style={textareaStyle} /> | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| const ComposeForm = React.createClass({ | const ComposeForm = React.createClass({ | ||||||
| @ -144,7 +149,7 @@ const ComposeForm = React.createClass({ | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const inputProps = { |     const inputProps = { | ||||||
|       placeholder: intl.formatMessage({ id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' }), |       placeholder: intl.formatMessage(messages.placeholder), | ||||||
|       value: this.props.text, |       value: this.props.text, | ||||||
|       onKeyUp: this.handleKeyUp, |       onKeyUp: this.handleKeyUp, | ||||||
|       onChange: this.handleChange, |       onChange: this.handleChange, | ||||||
| @ -169,7 +174,7 @@ const ComposeForm = React.createClass({ | |||||||
|         /> |         /> | ||||||
| 
 | 
 | ||||||
|         <div style={{ marginTop: '10px', overflow: 'hidden' }}> |         <div style={{ marginTop: '10px', overflow: 'hidden' }}> | ||||||
|           <div style={{ float: 'right' }}><Button text={intl.formatMessage({ id: 'compose_form.publish', defaultMessage: 'Publish' })} onClick={this.handleSubmit} disabled={disabled} /></div> |           <div style={{ float: 'right' }}><Button text={intl.formatMessage(messages.publish)} onClick={this.handleSubmit} disabled={disabled} /></div> | ||||||
|           <div style={{ float: 'right', marginRight: '16px', lineHeight: '36px' }}><CharacterCounter max={500} text={this.props.text} /></div> |           <div style={{ float: 'right', marginRight: '16px', lineHeight: '36px' }}><CharacterCounter max={500} text={this.props.text} /></div> | ||||||
|           <UploadButtonContainer style={{ paddingTop: '4px' }} /> |           <UploadButtonContainer style={{ paddingTop: '4px' }} /> | ||||||
|         </div> |         </div> | ||||||
|  | |||||||
| @ -4,7 +4,11 @@ import Avatar from '../../../components/avatar'; | |||||||
| import IconButton from '../../../components/icon_button'; | import IconButton from '../../../components/icon_button'; | ||||||
| import DisplayName from '../../../components/display_name'; | import DisplayName from '../../../components/display_name'; | ||||||
| import emojify from '../../../emoji'; | import emojify from '../../../emoji'; | ||||||
| import { injectIntl } from 'react-intl'; | import { defineMessages, injectIntl } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | const messages = defineMessages({ | ||||||
|  |   cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| const ReplyIndicator = React.createClass({ | const ReplyIndicator = React.createClass({ | ||||||
| 
 | 
 | ||||||
| @ -37,7 +41,7 @@ const ReplyIndicator = React.createClass({ | |||||||
|     return ( |     return ( | ||||||
|       <div style={{ background: '#9baec8', padding: '10px' }}> |       <div style={{ background: '#9baec8', padding: '10px' }}> | ||||||
|         <div style={{ overflow: 'hidden', marginBottom: '5px' }}> |         <div style={{ overflow: 'hidden', marginBottom: '5px' }}> | ||||||
|           <div style={{ float: 'right', lineHeight: '24px' }}><IconButton title={intl.formatMessage({ id: 'reply_indicator.cancel', defaultMessage: 'Cancel' })} icon='times' onClick={this.handleClick} /></div> |           <div style={{ float: 'right', lineHeight: '24px' }}><IconButton title={intl.formatMessage(messages.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' }}> |           <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> |             <div style={{ float: 'left', marginRight: '5px' }}><Avatar size={24} src={this.props.status.getIn(['account', 'avatar'])} /></div> | ||||||
|  | |||||||
| @ -3,7 +3,11 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; | |||||||
| import Autosuggest from 'react-autosuggest'; | import Autosuggest from 'react-autosuggest'; | ||||||
| import AutosuggestAccountContainer from '../containers/autosuggest_account_container'; | import AutosuggestAccountContainer from '../containers/autosuggest_account_container'; | ||||||
| import { debounce } from 'react-decoration'; | import { debounce } from 'react-decoration'; | ||||||
| import { injectIntl } from 'react-intl'; | import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | const messages = defineMessages({ | ||||||
|  |   placeholder: { id: 'search.placeholder', defaultMessage: 'Search' } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| const getSuggestionValue = suggestion => suggestion.value; | const getSuggestionValue = suggestion => suggestion.value; | ||||||
| 
 | 
 | ||||||
| @ -16,7 +20,7 @@ const renderSuggestion = suggestion => { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const renderSectionTitle = section => ( | const renderSectionTitle = section => ( | ||||||
|   <strong>{section.title}</strong> |   <strong><FormattedMessage id={`search.${section.title}`} defaultMessage={section.title} /></strong> | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| const getSectionSuggestions = section => section.items; | const getSectionSuggestions = section => section.items; | ||||||
| @ -95,7 +99,7 @@ const Search = React.createClass({ | |||||||
| 
 | 
 | ||||||
|   render () { |   render () { | ||||||
|     const inputProps = { |     const inputProps = { | ||||||
|       placeholder: this.props.intl.formatMessage({ id: 'search.placeholder', defaultMessage: 'Search' }), |       placeholder: this.props.intl.formatMessage(messages.placeholder), | ||||||
|       value: this.props.value, |       value: this.props.value, | ||||||
|       onChange: this.onChange, |       onChange: this.onChange, | ||||||
|       style: inputStyle |       style: inputStyle | ||||||
|  | |||||||
| @ -1,6 +1,10 @@ | |||||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||||
| import IconButton from '../../../components/icon_button'; | import IconButton from '../../../components/icon_button'; | ||||||
| import { injectIntl } from 'react-intl'; | import { defineMessages, injectIntl } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | const messages = defineMessages({ | ||||||
|  |   upload: { id: 'upload_button.label', defaultMessage: 'Add media' } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| const UploadButton = React.createClass({ | const UploadButton = React.createClass({ | ||||||
| 
 | 
 | ||||||
| @ -31,7 +35,7 @@ const UploadButton = React.createClass({ | |||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <div style={this.props.style}> |       <div style={this.props.style}> | ||||||
|         <IconButton icon='photo' title={intl.formatMessage({ id: 'upload_button.label', defaultMessage: 'Add media' })} disabled={this.props.disabled} onClick={this.handleClick} size={24} /> |         <IconButton icon='photo' title={intl.formatMessage(messages.upload)} 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' }} /> |         <input ref={this.setRef} type='file' multiple={false} onChange={this.handleChange} disabled={this.props.disabled} style={{ display: 'none' }} /> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|  | |||||||
| @ -1,7 +1,11 @@ | |||||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||||
| import IconButton from '../../../components/icon_button'; | import IconButton from '../../../components/icon_button'; | ||||||
| import { injectIntl } from 'react-intl'; | import { defineMessages, injectIntl } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | const messages = defineMessages({ | ||||||
|  |   undo: { id: 'upload_form.undo', defaultMessage: 'Undo' } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| const UploadForm = React.createClass({ | const UploadForm = React.createClass({ | ||||||
| 
 | 
 | ||||||
| @ -19,7 +23,7 @@ const UploadForm = React.createClass({ | |||||||
|     const uploads = this.props.media.map(attachment => ( |     const uploads = this.props.media.map(attachment => ( | ||||||
|       <div key={attachment.get('id')} style={{ borderRadius: '4px', marginBottom: '10px' }} className='transparent-background'> |       <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' }}> |         <div style={{ width: '100%', height: '100px', borderRadius: '4px', background: `url(${attachment.get('preview_url')}) no-repeat center`, backgroundSize: 'cover' }}> | ||||||
|           <IconButton icon='times' title={intl.formatMessage({ id: 'upload_form.undo', defaultMessage: 'Undo' })} size={36} onClick={this.props.onRemoveFile.bind(this, attachment.get('id'))} /> |           <IconButton icon='times' title={intl.formatMessage(messages.undo)} size={36} onClick={this.props.onRemoveFile.bind(this, attachment.get('id'))} /> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|     )); |     )); | ||||||
|  | |||||||
| @ -4,7 +4,11 @@ import Avatar from '../../../components/avatar'; | |||||||
| import DisplayName from '../../../components/display_name'; | import DisplayName from '../../../components/display_name'; | ||||||
| import { Link } from 'react-router'; | import { Link } from 'react-router'; | ||||||
| import IconButton from '../../../components/icon_button'; | import IconButton from '../../../components/icon_button'; | ||||||
| import { injectIntl } from 'react-intl'; | import { defineMessages, injectIntl } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | const messages = defineMessages({ | ||||||
|  |   follow: { id: 'account.follow', defaultMessage: 'Follow' } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| const outerStyle = { | const outerStyle = { | ||||||
|   padding: '10px', |   padding: '10px', | ||||||
| @ -69,7 +73,7 @@ const Account = React.createClass({ | |||||||
| 
 | 
 | ||||||
|       buttons = ( |       buttons = ( | ||||||
|         <div style={buttonsStyle}> |         <div style={buttonsStyle}> | ||||||
|           <IconButton icon={following ? 'user-times' : 'user-plus'} title={intl.formatMessage({ id: 'account.follow', defaultMessage: 'Follow' })} onClick={this.handleFollow} active={following} /> |           <IconButton icon={following ? 'user-times' : 'user-plus'} title={intl.formatMessage(messages.follow)} onClick={this.handleFollow} active={following} /> | ||||||
|         </div> |         </div> | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -3,7 +3,11 @@ import PureRenderMixin from 'react-addons-pure-render-mixin'; | |||||||
| import StatusListContainer from '../ui/containers/status_list_container'; | import StatusListContainer from '../ui/containers/status_list_container'; | ||||||
| import Column from '../ui/components/column'; | import Column from '../ui/components/column'; | ||||||
| import { refreshTimeline } from '../../actions/timelines'; | import { refreshTimeline } from '../../actions/timelines'; | ||||||
| import { injectIntl } from 'react-intl'; | import { defineMessages, injectIntl } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | const messages = defineMessages({ | ||||||
|  |   title: { id: 'column.home', defaultMessage: 'Home' } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| const HomeTimeline = React.createClass({ | const HomeTimeline = React.createClass({ | ||||||
| 
 | 
 | ||||||
| @ -21,7 +25,7 @@ const HomeTimeline = React.createClass({ | |||||||
|     const { intl } = this.props; |     const { intl } = this.props; | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <Column icon='home' heading={intl.formatMessage({ id: 'column.home', defaultMessage: 'Home' })}> |       <Column icon='home' heading={intl.formatMessage(messages.title)}> | ||||||
|         <StatusListContainer {...this.props} type='home' /> |         <StatusListContainer {...this.props} type='home' /> | ||||||
|       </Column> |       </Column> | ||||||
|     ); |     ); | ||||||
|  | |||||||
| @ -3,7 +3,11 @@ import PureRenderMixin from 'react-addons-pure-render-mixin'; | |||||||
| import StatusListContainer from '../ui/containers/status_list_container'; | import StatusListContainer from '../ui/containers/status_list_container'; | ||||||
| import Column from '../ui/components/column'; | import Column from '../ui/components/column'; | ||||||
| import { refreshTimeline } from '../../actions/timelines'; | import { refreshTimeline } from '../../actions/timelines'; | ||||||
| import { injectIntl } from 'react-intl'; | import { defineMessages, injectIntl } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | const messages = defineMessages({ | ||||||
|  |   title: { id: 'column.mentions', defaultMessage: 'Mentions' } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| const MentionsTimeline = React.createClass({ | const MentionsTimeline = React.createClass({ | ||||||
| 
 | 
 | ||||||
| @ -21,7 +25,7 @@ const MentionsTimeline = React.createClass({ | |||||||
|     const { intl } = this.props; |     const { intl } = this.props; | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <Column icon='at' heading={intl.formatMessage({ id: 'column.mentions', defaultMessage: 'Mentions' })}> |       <Column icon='at' heading={intl.formatMessage(messages.title)}> | ||||||
|         <StatusListContainer {...this.props} type='mentions' /> |         <StatusListContainer {...this.props} type='mentions' /> | ||||||
|       </Column> |       </Column> | ||||||
|     ); |     ); | ||||||
|  | |||||||
| @ -7,7 +7,11 @@ import { | |||||||
|   updateTimeline, |   updateTimeline, | ||||||
|   deleteFromTimelines |   deleteFromTimelines | ||||||
| } from '../../actions/timelines'; | } from '../../actions/timelines'; | ||||||
| import { injectIntl } from 'react-intl'; | import { defineMessages, injectIntl } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | const messages = defineMessages({ | ||||||
|  |   title: { id: 'column.public', defaultMessage: 'Public' } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| const PublicTimeline = React.createClass({ | const PublicTimeline = React.createClass({ | ||||||
| 
 | 
 | ||||||
| @ -48,7 +52,7 @@ const PublicTimeline = React.createClass({ | |||||||
|     const { intl } = this.props; |     const { intl } = this.props; | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <Column icon='globe' heading={intl.formatMessage({ id: 'column.public', defaultMessage: 'Public' })}> |       <Column icon='globe' heading={intl.formatMessage(messages.title)}> | ||||||
|         <StatusListContainer type='public' /> |         <StatusListContainer type='public' /> | ||||||
|       </Column> |       </Column> | ||||||
|     ); |     ); | ||||||
|  | |||||||
| @ -2,7 +2,15 @@ import PureRenderMixin from 'react-addons-pure-render-mixin'; | |||||||
| import IconButton from '../../../components/icon_button'; | import IconButton from '../../../components/icon_button'; | ||||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||||
| import DropdownMenu from '../../../components/dropdown_menu'; | import DropdownMenu from '../../../components/dropdown_menu'; | ||||||
| import { injectIntl } from 'react-intl'; | import { defineMessages, injectIntl } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | const messages = defineMessages({ | ||||||
|  |   delete: { id: 'status.delete', defaultMessage: 'Delete' }, | ||||||
|  |   mention: { id: 'status.mention', defaultMessage: 'Mention' }, | ||||||
|  |   reply: { id: 'status.reply', defaultMessage: 'Reply' }, | ||||||
|  |   reblog: { id: 'status.reblog', defaultMessage: 'Reblog' }, | ||||||
|  |   favourite: { id: 'status.favourite', defaultMessage: 'Favourite' } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| const ActionBar = React.createClass({ | const ActionBar = React.createClass({ | ||||||
| 
 | 
 | ||||||
| @ -44,16 +52,16 @@ const ActionBar = React.createClass({ | |||||||
|     let menu = []; |     let menu = []; | ||||||
| 
 | 
 | ||||||
|     if (me === status.getIn(['account', 'id'])) { |     if (me === status.getIn(['account', 'id'])) { | ||||||
|       menu.push({ text: intl.formatMessage({ id: 'status.delete', defaultMessage: 'Delete' }), action: this.handleDeleteClick }); |       menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick }); | ||||||
|     } else { |     } else { | ||||||
|       menu.push({ text: intl.formatMessage({ id: 'status.mention', defaultMessage: 'Mention' }), action: this.handleMentionClick }); |       menu.push({ text: intl.formatMessage(messages.mention), action: this.handleMentionClick }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <div style={{ background: '#2f3441', display: 'flex', flexDirection: 'row', borderTop: '1px solid #363c4b', borderBottom: '1px solid #363c4b', padding: '10px 0' }}> |       <div style={{ background: '#2f3441', display: 'flex', flexDirection: 'row', borderTop: '1px solid #363c4b', borderBottom: '1px solid #363c4b', padding: '10px 0' }}> | ||||||
|         <div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton title={intl.formatMessage({ id: 'status.reply', defaultMessage: 'Reply' })} icon='reply' onClick={this.handleReplyClick} /></div> |         <div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton title={intl.formatMessage(messages.reply)} icon='reply' onClick={this.handleReplyClick} /></div> | ||||||
|         <div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton active={status.get('reblogged')} title={intl.formatMessage({ id: 'status.reblog', defaultMessage: 'Reblog' })} icon='retweet' onClick={this.handleReblogClick} /></div> |         <div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton active={status.get('reblogged')} title={intl.formatMessage(messages.reblog)} icon='retweet' onClick={this.handleReblogClick} /></div> | ||||||
|         <div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton active={status.get('favourited')} title={intl.formatMessage({ id: 'status.favourite', defaultMessage: 'Favourite' })} icon='star' onClick={this.handleFavouriteClick} activeStyle={{ color: '#ca8f04' }} /></div> |         <div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} activeStyle={{ color: '#ca8f04' }} /></div> | ||||||
|         <div style={{ flex: '1 1 auto', textAlign: 'center' }}><DropdownMenu size={18} icon='ellipsis-h' items={menu} /></div> |         <div style={{ flex: '1 1 auto', textAlign: 'center' }}><DropdownMenu size={18} icon='ellipsis-h' items={menu} /></div> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|  | |||||||
							
								
								
									
										48
									
								
								app/assets/javascripts/components/locales/de.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								app/assets/javascripts/components/locales/de.jsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | const en = { | ||||||
|  |   "column_back_button.label": "Zurück", | ||||||
|  |   "lightbox.close": "Schließen", | ||||||
|  |   "loading_indicator.label": "Lade...", | ||||||
|  |   "status.mention": "Erwähnen", | ||||||
|  |   "status.delete": "Löschen", | ||||||
|  |   "status.reply": "Antworten", | ||||||
|  |   "status.reblog": "Teilen", | ||||||
|  |   "status.favourite": "Favorisieren", | ||||||
|  |   "status.reblogged_by": "{name} teilte", | ||||||
|  |   "video_player.toggle_sound": "Ton umschalten", | ||||||
|  |   "account.mention": "Erwähnen", | ||||||
|  |   "account.edit_profile": "Profil bearbeiten", | ||||||
|  |   "account.unblock": "Entblocken", | ||||||
|  |   "account.unfollow": "Entfolgen", | ||||||
|  |   "account.block": "Blocken", | ||||||
|  |   "account.follow": "Folgen", | ||||||
|  |   "account.posts": "Beiträge", | ||||||
|  |   "account.follows": "Folgt", | ||||||
|  |   "account.followers": "Folger", | ||||||
|  |   "account.follows_you": "Folgt dir", | ||||||
|  |   "getting_started.heading": "Erste Schritte", | ||||||
|  |   "getting_started.about_addressing": "Du kannst Leuten folgen, falls du ihren Nutzernamen und ihre Domain kennst, in dem du eine e-mail-artige Addresse in das Suchfeld oben an der Seite eingibst.", | ||||||
|  |   "getting_started.about_shortcuts": "Falls der Zielnutzer an derselben Domain ist wie du, funktioniert der Nutzername auch alleine. Das gilt auch für Erwähnungen in Beiträgen.", | ||||||
|  |   "getting_started.about_developer": "Der Entwickler des Projekts kann unter Gargron@mastodon.social gefunden werden", | ||||||
|  |   "column.home": "Home", | ||||||
|  |   "column.mentions": "Erwähnungen", | ||||||
|  |   "column.public": "Gesamtes Bekanntes Netz", | ||||||
|  |   "tabs_bar.compose": "Schreiben", | ||||||
|  |   "tabs_bar.home": "Home", | ||||||
|  |   "tabs_bar.mentions": "Erwähnungen", | ||||||
|  |   "tabs_bar.public": "Gesamtes Netz", | ||||||
|  |   "compose_form.placeholder": "Worüber möchstest du schreiben?", | ||||||
|  |   "compose_form.publish": "Veröffentlichen", | ||||||
|  |   "navigation_bar.settings": "Einstellungen", | ||||||
|  |   "navigation_bar.public_timeline": "Öffentlich", | ||||||
|  |   "navigation_bar.logout": "Abmelden", | ||||||
|  |   "reply_indicator.cancel": "Abbrechen", | ||||||
|  |   "search.placeholder": "Suche", | ||||||
|  |   "search.account": "Konto", | ||||||
|  |   "search.hashtag": "Hashtag", | ||||||
|  |   "suggestions_box.who_to_follow": "Wem folgen", | ||||||
|  |   "suggestions_box.refresh": "Aktualisieren", | ||||||
|  |   "upload_button.label": "Media-Datei anfügen", | ||||||
|  |   "upload_form.undo": "Entfernen" | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default en; | ||||||
							
								
								
									
										49
									
								
								app/assets/javascripts/components/locales/en.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								app/assets/javascripts/components/locales/en.jsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | |||||||
|  | const en = { | ||||||
|  |   "column_back_button.label": "Back", | ||||||
|  |   "lightbox.close": "Close", | ||||||
|  |   "loading_indicator.label": "Loading...", | ||||||
|  |   "status.mention": "Mention", | ||||||
|  |   "status.delete": "Delete", | ||||||
|  |   "status.reply": "Reply", | ||||||
|  |   "status.reblog": "Reblog", | ||||||
|  |   "status.favourite": "Favourite", | ||||||
|  |   "status.reblogged_by": "{name} reblogged", | ||||||
|  |   "video_player.toggle_sound": "Toggle sound", | ||||||
|  |   "account.mention": "Mention", | ||||||
|  |   "account.edit_profile": "Edit profile", | ||||||
|  |   "account.unblock": "Unblock", | ||||||
|  |   "account.unfollow": "Unfollow", | ||||||
|  |   "account.block": "Block", | ||||||
|  |   "account.follow": "Follow", | ||||||
|  |   "account.block": "Block", | ||||||
|  |   "account.posts": "Posts", | ||||||
|  |   "account.follows": "Follows", | ||||||
|  |   "account.followers": "Followers", | ||||||
|  |   "account.follows_you": "Follows you", | ||||||
|  |   "getting_started.heading": "Getting started", | ||||||
|  |   "getting_started.about_addressing": "You can follow people if you know their username and the domain they are on by entering an e-mail-esque address into the form at the top of the sidebar.", | ||||||
|  |   "getting_started.about_shortcuts": "If the target user is on the same domain as you, just the username will work. The same rule applies to mentioning people in statuses.", | ||||||
|  |   "getting_started.about_developer": "The developer of this project can be followed as Gargron@mastodon.social", | ||||||
|  |   "column.home": "Home", | ||||||
|  |   "column.mentions": "Mentions", | ||||||
|  |   "column.public": "Public", | ||||||
|  |   "tabs_bar.compose": "Compose", | ||||||
|  |   "tabs_bar.home": "Home", | ||||||
|  |   "tabs_bar.mentions": "Mentions", | ||||||
|  |   "tabs_bar.public": "Public", | ||||||
|  |   "compose_form.placeholder": "What is on your mind?", | ||||||
|  |   "compose_form.publish": "Publish", | ||||||
|  |   "navigation_bar.settings": "Settings", | ||||||
|  |   "navigation_bar.public_timeline": "Public timeline", | ||||||
|  |   "navigation_bar.logout": "Logout", | ||||||
|  |   "reply_indicator.cancel": "Cancel", | ||||||
|  |   "search.placeholder": "Search", | ||||||
|  |   "search.account": "Account", | ||||||
|  |   "search.hashtag": "Hashtag", | ||||||
|  |   "suggestions_box.who_to_follow": "Who to follow", | ||||||
|  |   "suggestions_box.refresh": "Refresh", | ||||||
|  |   "upload_button.label": "Add media", | ||||||
|  |   "upload_form.undo": "Undo" | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default en; | ||||||
							
								
								
									
										11
									
								
								app/assets/javascripts/components/locales/index.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								app/assets/javascripts/components/locales/index.jsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | import en from './en'; | ||||||
|  | import de from './de'; | ||||||
|  | 
 | ||||||
|  | const locales = { | ||||||
|  |   en, | ||||||
|  |   de | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default function getMessagesForLocale (locale) { | ||||||
|  |   return locales[locale]; | ||||||
|  | }; | ||||||
| @ -14,7 +14,7 @@ const initialState = Immutable.Map({ | |||||||
| const normalizeSuggestions = (state, value, accounts) => { | const normalizeSuggestions = (state, value, accounts) => { | ||||||
|   let newSuggestions = [ |   let newSuggestions = [ | ||||||
|     { |     { | ||||||
|       title: 'Account', |       title: 'account', | ||||||
|       items: accounts.map(item => ({ |       items: accounts.map(item => ({ | ||||||
|         type: 'account', |         type: 'account', | ||||||
|         id: item.id, |         id: item.id, | ||||||
| @ -25,7 +25,7 @@ const normalizeSuggestions = (state, value, accounts) => { | |||||||
| 
 | 
 | ||||||
|   if (value.indexOf('@') === -1) { |   if (value.indexOf('@') === -1) { | ||||||
|     newSuggestions.push({ |     newSuggestions.push({ | ||||||
|       title: 'Hashtag', |       title: 'hashtag', | ||||||
|       items: [ |       items: [ | ||||||
|         { |         { | ||||||
|           type: 'hashtag', |           type: 'hashtag', | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ module Mastodon | |||||||
| 
 | 
 | ||||||
|     # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. |     # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. | ||||||
|     # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] |     # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] | ||||||
|     config.i18n.available_locales = [:en] |     config.i18n.available_locales = [:en, :de] | ||||||
|     config.i18n.default_locale    = :en |     config.i18n.default_locale    = :en | ||||||
| 
 | 
 | ||||||
|     # config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb') |     # config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb') | ||||||
|  | |||||||
							
								
								
									
										59
									
								
								config/locales/de.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								config/locales/de.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | |||||||
|  | --- | ||||||
|  | de: | ||||||
|  |   about: | ||||||
|  |     about_instance: "<em>%{instance}</em> ist eine Instanz von Mastodon." | ||||||
|  |     about_mastodon: Mastodon ist ein <em>freier, quelloffener</em> soziales Netzwerkserver. Eine <em>dezentralisierte</em> Alternative zu kommerziellen Plattformen, verhindert es die Risiken, die entstehen, wenn eine einzelne Firma deine Kommunikation monopolisiert. Jeder kann Mastodon verwenden und ganz einfach am <em>sozialen Netzwerk</em> teilnehmen. | ||||||
|  |     get_started: Erste Schritte | ||||||
|  |     source_code: Quellcode | ||||||
|  |     terms: AGB | ||||||
|  |   accounts: | ||||||
|  |     follow: Folgen | ||||||
|  |     followers: Folger | ||||||
|  |     following: Folgt | ||||||
|  |     nothing_here: Hier gibt es nichts! | ||||||
|  |     people_followed_by: Nutzer, denen %{name} folgt | ||||||
|  |     people_who_follow: Nutzer, die %{name} folgen | ||||||
|  |     posts: Beiträge | ||||||
|  |     unfollow: Entfolgen | ||||||
|  |   application_mailer: | ||||||
|  |     signature: Mastodon-Benachrichtigungen von %{instance} | ||||||
|  |   auth: | ||||||
|  |     change_password: Passwort ändern | ||||||
|  |     didnt_get_confirmation: Keine Bestätigung bekommen? | ||||||
|  |     forgot_password: Passwort vergessen? | ||||||
|  |     login: Anmelden | ||||||
|  |     register: Registrieren | ||||||
|  |     resend_confirmation: Bestätigung nochmal versenden | ||||||
|  |     reset_password: Passwort zurücksetzen | ||||||
|  |     set_new_password: Neues Passwort setzen | ||||||
|  |   generic: | ||||||
|  |     changes_saved_msg: Änderungen gespeichert! | ||||||
|  |     powered_by: angetrieben von %{link} | ||||||
|  |     save_changes: Änderungen speichern | ||||||
|  |     validation_errors: | ||||||
|  |       one: Etwas ist noch nicht ganz richtig! Bitte korrigiere den Fehler | ||||||
|  |       other: Etwas ist noch nicht ganz richtig! Bitte korrigiere %{count} Fehler | ||||||
|  |   notification_mailer: | ||||||
|  |     favourite: | ||||||
|  |       body: "Dein Beitrag wurde von %{name} favorisiert:" | ||||||
|  |       subject: "%{name} hat deinen Beitrag favorisiert" | ||||||
|  |     follow: | ||||||
|  |       body: "%{name} folgt dir jetzt!" | ||||||
|  |       subject: "%{name} folgt dir nun" | ||||||
|  |     mention: | ||||||
|  |       body: "%{name} hat dich erwähnt:" | ||||||
|  |       subject: "%{name} hat dich erwähnt" | ||||||
|  |     reblog: | ||||||
|  |       body: "Dein Beitrag wurde von %{name} geteilt:" | ||||||
|  |       subject: "%{name} teilte deinen Beitrag" | ||||||
|  |   pagination: | ||||||
|  |     next: Vorwärts | ||||||
|  |     prev: Zurück | ||||||
|  |   settings: | ||||||
|  |     edit_profile: Profil bearbeiten | ||||||
|  |     preferences: Einstellungen | ||||||
|  |   stream_entries: | ||||||
|  |     favourited: favorisierte einen Beitrag von | ||||||
|  |     is_now_following: folgt nun | ||||||
|  |   will_paginate: | ||||||
|  |     page_gap: "…" | ||||||
							
								
								
									
										61
									
								
								config/locales/devise.de.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								config/locales/devise.de.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | |||||||
|  | --- | ||||||
|  | de: | ||||||
|  |   devise: | ||||||
|  |     confirmations: | ||||||
|  |       confirmed: "Vielen Dank für Deine Registrierung. Bitte melde dich jetzt an." | ||||||
|  |       send_instructions: "Du erhältst in wenigen Minuten eine E-Mail, mit der Du Deine Registrierung bestätigen kannst." | ||||||
|  |       send_paranoid_instructions: "Falls Deine E-Mail-Adresse in unserer Datenbank existiert erhältst Du in wenigen Minuten eine E-Mail mit der Du Deine Registrierung bestätigen kannst." | ||||||
|  |     failure: | ||||||
|  |       already_authenticated: "Du bist bereits angemeldet." | ||||||
|  |       inactive: "Dein Account ist nicht aktiv." | ||||||
|  |       invalid: "Ungültige Anmeldedaten." | ||||||
|  |       last_attempt: "Du hast noch einen Versuch bevor dein Account gesperrt wird" | ||||||
|  |       locked: "Dein Account ist gesperrt." | ||||||
|  |       not_found_in_database: "E-Mail-Adresse oder Passwort ungültig." | ||||||
|  |       timeout: "Deine Sitzung ist abgelaufen, bitte melde Dich erneut an." | ||||||
|  |       unauthenticated: "Du musst Dich anmelden oder registrieren, bevor Du fortfahren kannst." | ||||||
|  |       unconfirmed: "Du musst Deinen Account bestätigen, bevor Du fortfahren kannst." | ||||||
|  |     mailer: | ||||||
|  |       confirmation_instructions: | ||||||
|  |         subject: "Mastodon: Anleitung zur Bestätigung Deines Accounts" | ||||||
|  |       password_change: | ||||||
|  |         subject: 'Mastodon: Passwort wurde geändert' | ||||||
|  |       reset_password_instructions: | ||||||
|  |         subject: "Mastodon: Anleitung um Dein Passwort zurückzusetzen" | ||||||
|  |       unlock_instructions: | ||||||
|  |         subject: "Mastodon: Anleitung um Deinen Account freizuschalten" | ||||||
|  |     omniauth_callbacks: | ||||||
|  |       failure: "Du konntest nicht Deinem %{kind}-Account angemeldet werden, weil '%{reason}'." | ||||||
|  |       success: "Du hast Dich erfolgreich mit Deinem %{kind}-Account angemeldet." | ||||||
|  |     passwords: | ||||||
|  |       no_token: "Du kannst diese Seite nur von dem Link aus einer E-Mail zum Passwort-Zurücksetzen aufrufen. Wenn du einen solchen Link aufgerufen hast stelle bitte sicher, dass du die vollständige Adresse aufrufst." | ||||||
|  |       send_instructions: "Du erhältst in wenigen Minuten eine E-Mail mit der Anleitung, wie Du Dein Passwort zurücksetzen kannst." | ||||||
|  |       send_paranoid_instructions: "Falls Deine E-Mail-Adresse in unserer Datenbank existiert erhältst Du in wenigen Minuten eine E-Mail mit der Anleitung, wie Du Dein Passwort zurücksetzen können." | ||||||
|  |       updated: "Dein Passwort wurde geändert. Du bist jetzt angemeldet." | ||||||
|  |       updated_not_active: "Dein Passwort wurde geändert." | ||||||
|  |     registrations: | ||||||
|  |       destroyed: "Dein Account wurde gelöscht." | ||||||
|  |       signed_up: "Du hast dich erfolgreich registriert." | ||||||
|  |       signed_up_but_inactive: "Du hast dich erfolgreich registriert. Wir konnten Dich noch nicht anmelden, da Dein Account inaktiv ist." | ||||||
|  |       signed_up_but_locked: "Du hast dich erfolgreich registriert. Wir konnten Dich noch nicht anmelden, da Dein Account gesperrt ist." | ||||||
|  |       signed_up_but_unconfirmed: "Du hast Dich erfolgreich registriert. Wir konnten Dich noch nicht anmelden, da Dein Account noch nicht bestätigt ist. Du erhältst in Kürze eine E-Mail mit der Anleitung, wie Du Deinen Account freischalten kannst." | ||||||
|  |       update_needs_confirmation: "Deine Daten wurden aktualisiert, aber Du musst Deine neue E-Mail-Adresse bestätigen. Du erhälst in wenigen Minuten eine E-Mail, mit der Du die Änderung Deiner E-Mail-Adresse abschließen kannst." | ||||||
|  |       updated: "Deine Daten wurden aktualisiert." | ||||||
|  |     sessions: | ||||||
|  |       already_signed_out: "Erfolgreich abgemeldet." | ||||||
|  |       signed_in: "Erfolgreich angemeldet." | ||||||
|  |       signed_out: "Erfolgreich abgemeldet." | ||||||
|  |     unlocks: | ||||||
|  |       send_instructions: "Du erhältst in wenigen Minuten eine E-Mail mit der Anleitung, wie Du Deinen Account entsperren können." | ||||||
|  |       send_paranoid_instructions: "Falls Deine E-Mail-Adresse in unserer Datenbank existiert erhältst Du in wenigen Minuten eine E-Mail mit der Anleitung, wie Du Deinen Account entsperren kannst." | ||||||
|  |       unlocked: "Dein Account wurde entsperrt. Du bist jetzt angemeldet." | ||||||
|  |   errors: | ||||||
|  |     messages: | ||||||
|  |       already_confirmed: "wurde bereits bestätigt" | ||||||
|  |       confirmation_period_expired: "muss innerhalb %{period} bestätigt werden, bitte fordere einen neuen Link an" | ||||||
|  |       expired: "ist abgelaufen, bitte neu anfordern" | ||||||
|  |       not_found: "nicht gefunden" | ||||||
|  |       not_locked: "ist nicht gesperrt" | ||||||
|  |       not_saved: | ||||||
|  |         one: "Konnte %{resource} nicht speichern: ein Fehler." | ||||||
|  |         other: "Konnte %{resource} nicht speichern: %{count} Fehler." | ||||||
							
								
								
									
										112
									
								
								config/locales/doorkeeper.de.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								config/locales/doorkeeper.de.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,112 @@ | |||||||
|  | --- | ||||||
|  | de: | ||||||
|  |   activerecord: | ||||||
|  |     attributes: | ||||||
|  |       doorkeeper/application: | ||||||
|  |         name: Name | ||||||
|  |         redirect_uri: Redirect URI | ||||||
|  |     errors: | ||||||
|  |       models: | ||||||
|  |         doorkeeper/application: | ||||||
|  |           attributes: | ||||||
|  |             redirect_uri: | ||||||
|  |               fragment_present: darf kein Fragment enthalten. | ||||||
|  |               invalid_uri: muss ein valider URI (Identifier) sein. | ||||||
|  |               relative_uri: muss ein absoluter URI (Identifier) sein. | ||||||
|  |               secured_uri: muss ein HTTPS/SSL URI (Identifier) sein. | ||||||
|  |   doorkeeper: | ||||||
|  |     applications: | ||||||
|  |       buttons: | ||||||
|  |         authorize: Autorisieren | ||||||
|  |         cancel: Abbrechen | ||||||
|  |         destroy: Löschen | ||||||
|  |         edit: Bearbeiten | ||||||
|  |         submit: Übertragen | ||||||
|  |       confirmations: | ||||||
|  |         destroy: Bist du sicher? | ||||||
|  |       edit: | ||||||
|  |         title: Applikation bearbeiten | ||||||
|  |       form: | ||||||
|  |         error: Whoops! Bitte überprüfe das Formular auf Fehler! | ||||||
|  |       help: | ||||||
|  |         native_redirect_uri: "%{native_redirect_uri} für lokale Tests benutzen" | ||||||
|  |         redirect_uri: Bitte benutze eine Zeile pro URI | ||||||
|  |         scopes: Bitte die "Scopes" mit Leerzeichen trennen. Bitte frei lassen für die Verwendung der Default-Werte. | ||||||
|  |       index: | ||||||
|  |         callback_url: Callback URL | ||||||
|  |         name: Name | ||||||
|  |         new: Neue Applikation | ||||||
|  |         title: Deine Applikationen | ||||||
|  |       new: | ||||||
|  |         title: Neue Applikation | ||||||
|  |       show: | ||||||
|  |         actions: Aktionen | ||||||
|  |         application_id: Applikations-ID | ||||||
|  |         callback_urls: Callback URLs | ||||||
|  |         scopes: Scopes | ||||||
|  |         secret: Secret | ||||||
|  |         title: 'Applikation: %{name}' | ||||||
|  |     authorizations: | ||||||
|  |       buttons: | ||||||
|  |         authorize: Autorisieren | ||||||
|  |         deny: Verweigern | ||||||
|  |       error: | ||||||
|  |         title: Ein Fehler ist aufgetreten | ||||||
|  |       new: | ||||||
|  |         able_to: 'Diese Anwendung wird folgende Rechte haben:' | ||||||
|  |         prompt: Soll %{client_name} für die Benutzung dieses Accounts autorisiert werden? | ||||||
|  |         title: Autorisierung erforderlich | ||||||
|  |       show: | ||||||
|  |         title: Autorisierungscode | ||||||
|  |     authorized_applications: | ||||||
|  |       buttons: | ||||||
|  |         revoke: Ungültig machen | ||||||
|  |       confirmations: | ||||||
|  |         revoke: Bist du sicher? | ||||||
|  |       index: | ||||||
|  |         application: Applikation | ||||||
|  |         created_at: erstellt am | ||||||
|  |         date_format: "%Y-%m-%d %H:%M:%S" | ||||||
|  |         title: Deine autorisierten Applikationen | ||||||
|  |     errors: | ||||||
|  |       messages: | ||||||
|  |         access_denied: Der Resource Owner oder der Autorisierungs-Server hat die Anfrage verweigert. | ||||||
|  |         credential_flow_not_configured: 'Die Prozedur "Resource Owner Password Credentials" ist fehlgeschlagen: Doorkeeper.configure.resource_owner_from_credentials ist nicht konfiguriert.' | ||||||
|  |         invalid_client: 'Client-Autorisierung MKIM ist fehlgeschlagen: Unbekannter Client, keine Autorisierung mitgeliefert oder Autorisierungsmethode nicht unterstützt.' | ||||||
|  |         invalid_grant: Die bereitgestellte Autorisierung ist inkorrekt, abgelaufen, widerrufen, ist mit einem anderen Client verknüpft oder der Redirection URI stimmt nicht mit der Autorisierungs-Anfrage überein. | ||||||
|  |         invalid_redirect_uri: Der Redirect-URI in der Anfrage ist ungültig. | ||||||
|  |         invalid_request: Die Anfrage enthält einen nicht-unterstützten Parameter, ein Parameter fehlt oder sie ist anderweitig fehlerhaft. | ||||||
|  |         invalid_resource_owner: Die angegebenen Zugangsdaten für den "Resource Owner" sind inkorrekt oder dieser Benutzer existiert nicht. | ||||||
|  |         invalid_scope: Der angeforderte Scope ist inkorrekt, unbekannt oder fehlerhaft. | ||||||
|  |         invalid_token: | ||||||
|  |           expired: Der Access Token ist abgelaufen | ||||||
|  |           revoked: Der Access Token wurde annuliert | ||||||
|  |           unknown: Der Access Token ist nicht gültig/korrekt | ||||||
|  |         resource_owner_authenticator_not_configured: 'Die Prozedur "Resource Owner find" ist fehlgeschlagen: Doorkeeper.configure.resource_owner_authenticator ist nicht konfiguriert.' | ||||||
|  |         server_error: Der Autorisierungs-Server hat ein unerwartetes Problem festgestellt und konnte die Anfrage nicht beenden. | ||||||
|  |         temporarily_unavailable: Der Autorisierungs-Server ist derzeit auf Grund von temporärer Überlastung oder Wartungsarbeiten am Server nicht in der Lage, die Anfrage zu bearbeiten . | ||||||
|  |         unauthorized_client: Der Client ist nicht autorisiert, diese Anfrage mit dieser Methode auszuführen. | ||||||
|  |         unsupported_grant_type: Der Autorisierungs-Typ wird nicht vom Autorisierungs-Server unterstützt. | ||||||
|  |         unsupported_response_type: Der Autorisierungs-Server unterstützt diesen Antwort-Typ nicht. | ||||||
|  |     flash: | ||||||
|  |       applications: | ||||||
|  |         create: | ||||||
|  |           notice: Applikation erstellt. | ||||||
|  |         destroy: | ||||||
|  |           notice: Applikation gelöscht. | ||||||
|  |         update: | ||||||
|  |           notice: Applikation geupdated. | ||||||
|  |       authorized_applications: | ||||||
|  |         destroy: | ||||||
|  |           notice: Applikation widerrufen. | ||||||
|  |     layouts: | ||||||
|  |       admin: | ||||||
|  |         nav: | ||||||
|  |           applications: Applikationen | ||||||
|  |           oauth2_provider: OAuth2 Provider | ||||||
|  |       application: | ||||||
|  |         title: OAuth Autorisierung nötig | ||||||
|  |     scopes: | ||||||
|  |       follow: Nutzer folgen, blocken, entblocken und entfolgen | ||||||
|  |       read: deine Daten lesen | ||||||
|  |       write: Beiträge von deinem Konto aus veröffentlichen | ||||||
| @ -55,3 +55,5 @@ en: | |||||||
|   stream_entries: |   stream_entries: | ||||||
|     favourited: favourited a post by |     favourited: favourited a post by | ||||||
|     is_now_following: is now following |     is_now_following: is now following | ||||||
|  |   will_paginate: | ||||||
|  |     page_gap: "…" | ||||||
|  | |||||||
							
								
								
									
										27
									
								
								config/locales/simple_form.de.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								config/locales/simple_form.de.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | --- | ||||||
|  | de: | ||||||
|  |   simple_form: | ||||||
|  |     labels: | ||||||
|  |       defaults: | ||||||
|  |         avatar: Avatar | ||||||
|  |         confirm_new_password: Neues Passwort bestätigen | ||||||
|  |         confirm_password: Passwort bestätigen | ||||||
|  |         current_password: Derzeitiges Passwort | ||||||
|  |         display_name: Anzeigename | ||||||
|  |         email: E-mail-Addresse | ||||||
|  |         header: Kopfbild | ||||||
|  |         locale: Sprache | ||||||
|  |         new_password: Neues Passwort | ||||||
|  |         note: Über mich | ||||||
|  |         password: Passwort | ||||||
|  |         username: Nutzername | ||||||
|  |       notification_emails: | ||||||
|  |         favourite: E-mail senden, wenn jemand meinen Beitrag favorisiert | ||||||
|  |         follow: E-mail senden, wenn mir jemand folgt | ||||||
|  |         mention: E-mail senden, wenn mich jemand erwähnt | ||||||
|  |         reblog: E-mail senden, wenn jemand meinen Beitrag teilt | ||||||
|  |     'no': 'Nein' | ||||||
|  |     required: | ||||||
|  |       mark: "*" | ||||||
|  |       text: Pflichtfeld | ||||||
|  |     'yes': 'Ja' | ||||||
| @ -1,8 +1,6 @@ | |||||||
| --- | --- | ||||||
| en: | en: | ||||||
|   simple_form: |   simple_form: | ||||||
|     error_notification: |  | ||||||
|       default_message: 'Please review the problems below:' |  | ||||||
|     labels: |     labels: | ||||||
|       defaults: |       defaults: | ||||||
|         avatar: Avatar |         avatar: Avatar | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user