Replace sprockets/browserify with Webpack (#2617)
* Replace browserify with webpack * Add react-intl-translations-manager * Do not minify in development, add offline-plugin for ServiceWorker background cache updates * Adjust tests and dependencies * Fix production deployments * Fix tests * More optimizations * Improve travis cache for npm stuff * Re-run travis * Add back support for custom.scss as before * Remove offline-plugin and babili * Fix issue with Immutable.List().unshift(...values) not working as expected * Make travis load schema instead of running all migrations in sequence * Fix missing React import in WarningContainer. Optimize rendering performance by using ImmutablePureComponent instead of React.PureComponent. ImmutablePureComponent uses Immutable.is() to compare props. Replace dynamic callback bindings in <UI /> * Add react definitions to places that use JSX * Add Procfile.dev for running rails, webpack and streaming API at the same time
22
.babelrc
@ -1,7 +1,25 @@
|
||||
{
|
||||
"presets": ["es2015", "react"],
|
||||
"presets": [
|
||||
"es2015",
|
||||
"react",
|
||||
[
|
||||
"env",
|
||||
{
|
||||
"loose": true,
|
||||
"modules": false
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": [
|
||||
"transform-react-jsx-source",
|
||||
"transform-react-jsx-self",
|
||||
"transform-decorators-legacy",
|
||||
"transform-object-rest-spread"
|
||||
"transform-object-rest-spread",
|
||||
[
|
||||
"react-intl",
|
||||
{
|
||||
"messagesDir": "./build/messages"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
4
.gitignore
vendored
@ -22,7 +22,7 @@ public/assets
|
||||
.env
|
||||
.env.production
|
||||
node_modules/
|
||||
neo4j/
|
||||
build/
|
||||
|
||||
# Ignore Vagrant files
|
||||
.vagrant/
|
||||
@ -43,3 +43,5 @@ redis
|
||||
# Ignore vim files
|
||||
*~
|
||||
*.swp
|
||||
/public/packs
|
||||
/node_modules
|
||||
|
4
.postcssrc.yml
Normal file
@ -0,0 +1,4 @@
|
||||
plugins:
|
||||
postcss-smart-import: {}
|
||||
precss: {}
|
||||
autoprefixer: {}
|
@ -1,9 +1,7 @@
|
||||
language: ruby
|
||||
cache:
|
||||
bundler: true
|
||||
yarn: true
|
||||
directories:
|
||||
- node_modules
|
||||
yarn: false
|
||||
dist: trusty
|
||||
sudo: false
|
||||
|
||||
@ -42,7 +40,8 @@ install:
|
||||
- yarn install
|
||||
|
||||
before_script:
|
||||
- bundle exec rails db:create db:migrate
|
||||
- bundle exec rails db:create db:schema:load
|
||||
- bundle exec rails assets:precompile
|
||||
|
||||
script:
|
||||
- bundle exec rspec
|
||||
|
15
Dockerfile
@ -10,8 +10,6 @@ EXPOSE 3000 4000
|
||||
|
||||
WORKDIR /mastodon
|
||||
|
||||
COPY Gemfile Gemfile.lock package.json yarn.lock /mastodon/
|
||||
|
||||
RUN echo "@edge https://nl.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories \
|
||||
&& BUILD_DEPS=" \
|
||||
postgresql-dev \
|
||||
@ -23,6 +21,7 @@ RUN echo "@edge https://nl.alpinelinux.org/alpine/edge/main" >> /etc/apk/reposit
|
||||
$BUILD_DEPS \
|
||||
nodejs@edge \
|
||||
nodejs-npm@edge \
|
||||
git \
|
||||
libpq \
|
||||
libxml2 \
|
||||
libxslt \
|
||||
@ -31,14 +30,14 @@ RUN echo "@edge https://nl.alpinelinux.org/alpine/edge/main" >> /etc/apk/reposit
|
||||
imagemagick@edge \
|
||||
ca-certificates \
|
||||
&& npm install -g npm@3 && npm install -g yarn \
|
||||
&& bundle install --deployment --without test development \
|
||||
&& yarn --ignore-optional \
|
||||
&& yarn cache clean \
|
||||
&& npm -g cache clean \
|
||||
&& update-ca-certificates \
|
||||
&& apk del $BUILD_DEPS \
|
||||
&& rm -rf /tmp/* /var/cache/apk/*
|
||||
|
||||
COPY Gemfile Gemfile.lock package.json yarn.lock /mastodon/
|
||||
|
||||
RUN bundle install --deployment --without test development \
|
||||
&& yarn --ignore-optional --pure-lockfile
|
||||
|
||||
COPY . /mastodon
|
||||
|
||||
VOLUME /mastodon/public/system /mastodon/public/assets
|
||||
VOLUME /mastodon/public/system /mastodon/public/assets /mastodon/public/packs
|
||||
|
34
Gemfile
@ -5,22 +5,19 @@ ruby '>= 2.3.0', '< 2.5.0'
|
||||
|
||||
gem 'pkg-config'
|
||||
|
||||
gem 'rails', '~> 5.0.2'
|
||||
gem 'sass-rails', '~> 5.0'
|
||||
gem 'uglifier', '>= 1.3.0'
|
||||
gem 'jquery-rails'
|
||||
gem 'puma'
|
||||
gem 'rails', '~> 5.0.2'
|
||||
gem 'uglifier', '>= 1.3.0'
|
||||
|
||||
gem 'hamlit-rails'
|
||||
gem 'pg'
|
||||
gem 'pghero'
|
||||
gem 'dotenv-rails'
|
||||
gem 'font-awesome-rails'
|
||||
gem 'best_in_place', '~> 3.0.1'
|
||||
|
||||
gem 'aws-sdk', '>= 2.0'
|
||||
gem 'paperclip', '~> 5.1'
|
||||
gem 'paperclip-av-transcoder'
|
||||
gem 'aws-sdk', '>= 2.0'
|
||||
|
||||
gem 'addressable'
|
||||
gem 'devise'
|
||||
@ -58,18 +55,18 @@ gem 'sprockets-rails', require: 'sprockets/railtie'
|
||||
gem 'statsd-instrument'
|
||||
gem 'twitter-text'
|
||||
gem 'tzinfo-data'
|
||||
gem 'webpacker', '~>1.2'
|
||||
gem 'whatlanguage'
|
||||
|
||||
# For some reason the view specs start failing without this
|
||||
gem 'react-rails'
|
||||
gem 'browserify-rails'
|
||||
gem 'autoprefixer-rails'
|
||||
|
||||
group :development, :test do
|
||||
gem 'rspec-rails'
|
||||
gem 'pry-rails'
|
||||
gem 'fuubar'
|
||||
gem 'fabrication'
|
||||
gem 'fuubar'
|
||||
gem 'i18n-tasks', '~> 0.9.6'
|
||||
gem 'pry-rails'
|
||||
gem 'rspec-rails'
|
||||
end
|
||||
|
||||
group :test do
|
||||
@ -83,24 +80,23 @@ group :test do
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'rubocop', '0.46.0', require: false
|
||||
gem 'better_errors'
|
||||
gem 'binding_of_caller'
|
||||
gem 'letter_opener'
|
||||
gem 'letter_opener_web'
|
||||
gem 'bullet'
|
||||
gem 'active_record_query_trace'
|
||||
gem 'annotate'
|
||||
gem 'better_errors'
|
||||
gem 'binding_of_caller'
|
||||
gem 'bullet'
|
||||
gem 'letter_opener'
|
||||
gem 'letter_opener_web'
|
||||
gem 'rubocop', '0.46.0', require: false
|
||||
|
||||
gem 'capistrano', '3.8.0'
|
||||
gem 'capistrano-rails'
|
||||
gem 'capistrano-rbenv'
|
||||
gem 'capistrano-yarn'
|
||||
gem 'capistrano-faster-assets', '~> 1.0'
|
||||
end
|
||||
|
||||
group :production do
|
||||
gem 'lograge'
|
||||
gem 'rails_12factor'
|
||||
gem 'redis-rails'
|
||||
gem 'lograge'
|
||||
end
|
||||
|
43
Gemfile.lock
@ -43,15 +43,13 @@ GEM
|
||||
public_suffix (~> 2.0, >= 2.0.2)
|
||||
airbrussh (1.2.0)
|
||||
sshkit (>= 1.6.1, != 1.7.0)
|
||||
annotate (2.7.1)
|
||||
activerecord (>= 3.2, < 6.0)
|
||||
rake (>= 10.4, < 12.0)
|
||||
annotate (2.6.5)
|
||||
activerecord (>= 2.3.0)
|
||||
rake (>= 0.8.7)
|
||||
arel (7.1.4)
|
||||
ast (2.3.0)
|
||||
attr_encrypted (3.0.3)
|
||||
encryptor (~> 3.0.0)
|
||||
autoprefixer-rails (6.7.7.2)
|
||||
execjs
|
||||
av (0.9.0)
|
||||
cocaine (~> 0.5.3)
|
||||
aws-sdk (2.9.12)
|
||||
@ -76,10 +74,6 @@ GEM
|
||||
rack (>= 0.9.0)
|
||||
binding_of_caller (0.7.2)
|
||||
debug_inspector (>= 0.0.1)
|
||||
browserify-rails (4.1.0)
|
||||
addressable (>= 2.4.0)
|
||||
railties (>= 4.0.0, < 5.1)
|
||||
sprockets (>= 3.6.0)
|
||||
builder (3.2.3)
|
||||
bullet (5.5.1)
|
||||
activesupport (>= 3.0.0)
|
||||
@ -92,8 +86,6 @@ GEM
|
||||
capistrano-bundler (1.2.0)
|
||||
capistrano (~> 3.1)
|
||||
sshkit (~> 1.2)
|
||||
capistrano-faster-assets (1.0.2)
|
||||
capistrano (>= 3.1)
|
||||
capistrano-rails (1.2.3)
|
||||
capistrano (~> 3.1)
|
||||
capistrano-bundler (~> 1.1)
|
||||
@ -161,8 +153,6 @@ GEM
|
||||
faker (1.7.3)
|
||||
i18n (~> 0.5)
|
||||
fast_blank (1.0.0)
|
||||
font-awesome-rails (4.7.0.1)
|
||||
railties (>= 3.2, < 5.1)
|
||||
fuubar (2.2.0)
|
||||
rspec-core (~> 3.0)
|
||||
ruby-progressbar (~> 1.4)
|
||||
@ -210,10 +200,6 @@ GEM
|
||||
rainbow (~> 2.2)
|
||||
terminal-table (>= 1.5.1)
|
||||
jmespath (1.3.1)
|
||||
jquery-rails (4.3.1)
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (2.1.0)
|
||||
kaminari (1.0.1)
|
||||
activesupport (>= 4.1.0)
|
||||
@ -257,6 +243,7 @@ GEM
|
||||
mimemagic (0.3.2)
|
||||
mini_portile2 (2.1.0)
|
||||
minitest (5.10.1)
|
||||
multi_json (1.12.1)
|
||||
net-scp (1.2.1)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (4.1.0)
|
||||
@ -348,8 +335,8 @@ GEM
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rainbow (2.2.2)
|
||||
rake
|
||||
rake (11.3.0)
|
||||
react-rails (1.11.0)
|
||||
rake (12.0.0)
|
||||
react-rails (2.1.0)
|
||||
babel-transpiler (>= 0.7.0)
|
||||
connection_pool
|
||||
execjs
|
||||
@ -410,13 +397,6 @@ GEM
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.4.4)
|
||||
nokogumbo (~> 1.4.1)
|
||||
sass (3.4.23)
|
||||
sass-rails (5.0.6)
|
||||
railties (>= 4.0.0, < 6)
|
||||
sass (~> 3.1)
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
sprockets-rails (>= 2.0, < 4.0)
|
||||
tilt (>= 1.1, < 3)
|
||||
sidekiq (4.2.10)
|
||||
concurrent-ruby (~> 1.0)
|
||||
connection_pool (~> 2.2, >= 2.2.0)
|
||||
@ -473,6 +453,10 @@ GEM
|
||||
addressable (>= 2.3.6)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff
|
||||
webpacker (1.2)
|
||||
activesupport (>= 4.2)
|
||||
multi_json (~> 1.2)
|
||||
railties (>= 4.2)
|
||||
websocket-driver (0.6.5)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.2)
|
||||
@ -487,15 +471,12 @@ DEPENDENCIES
|
||||
active_record_query_trace
|
||||
addressable
|
||||
annotate
|
||||
autoprefixer-rails
|
||||
aws-sdk (>= 2.0)
|
||||
best_in_place (~> 3.0.1)
|
||||
better_errors
|
||||
binding_of_caller
|
||||
browserify-rails
|
||||
bullet
|
||||
capistrano (= 3.8.0)
|
||||
capistrano-faster-assets (~> 1.0)
|
||||
capistrano-rails
|
||||
capistrano-rbenv
|
||||
capistrano-yarn
|
||||
@ -507,7 +488,6 @@ DEPENDENCIES
|
||||
fabrication
|
||||
faker
|
||||
fast_blank
|
||||
font-awesome-rails
|
||||
fuubar
|
||||
goldfinger
|
||||
hamlit-rails
|
||||
@ -517,7 +497,6 @@ DEPENDENCIES
|
||||
http_accept_language
|
||||
httplog
|
||||
i18n-tasks (~> 0.9.6)
|
||||
jquery-rails
|
||||
kaminari
|
||||
letter_opener
|
||||
letter_opener_web
|
||||
@ -554,7 +533,6 @@ DEPENDENCIES
|
||||
rubocop (= 0.46.0)
|
||||
ruby-oembed
|
||||
sanitize
|
||||
sass-rails (~> 5.0)
|
||||
sidekiq
|
||||
sidekiq-unique-jobs
|
||||
simple-navigation
|
||||
@ -566,6 +544,7 @@ DEPENDENCIES
|
||||
tzinfo-data
|
||||
uglifier (>= 1.3.0)
|
||||
webmock
|
||||
webpacker (~> 1.2)
|
||||
whatlanguage
|
||||
|
||||
RUBY VERSION
|
||||
|
3
Procfile.dev
Normal file
@ -0,0 +1,3 @@
|
||||
web: bundle exec rails s -p 3000
|
||||
stream: yarn run start
|
||||
webpack: ./bin/webpack-dev-server
|
@ -1,15 +0,0 @@
|
||||
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||
// listed below.
|
||||
//
|
||||
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
||||
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
||||
//
|
||||
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||
// compiled file.
|
||||
//
|
||||
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
||||
// about supported directives.
|
||||
//
|
||||
//= require jquery2
|
||||
//= require jquery_ujs
|
||||
//= require components
|
@ -1,9 +0,0 @@
|
||||
//= require jquery2
|
||||
//= require jquery_ujs
|
||||
//= require extras
|
||||
//= require best_in_place
|
||||
//= require local_time
|
||||
|
||||
$(function () {
|
||||
$(".best_in_place").best_in_place();
|
||||
});
|
@ -1,15 +0,0 @@
|
||||
//= require_self
|
||||
//= require react_ujs
|
||||
|
||||
window.React = require('react');
|
||||
window.ReactDOM = require('react-dom');
|
||||
window.Perf = require('react-addons-perf');
|
||||
|
||||
if (!window.Intl) {
|
||||
require('intl');
|
||||
require('intl/locale-data/jsonp/en.js');
|
||||
}
|
||||
|
||||
//= require_tree ./components
|
||||
|
||||
window.Mastodon = require('./components/containers/mastodon');
|
@ -1,16 +0,0 @@
|
||||
import Avatar from '../../../components/avatar';
|
||||
import DisplayName from '../../../components/display_name';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
|
||||
const AutosuggestAccount = ({ account }) => (
|
||||
<div className='autosuggest-account'>
|
||||
<div className='autosuggest-account-icon'><Avatar src={account.get('avatar')} staticSrc={account.get('avatar_static')} size={18} /></div>
|
||||
<DisplayName account={account} />
|
||||
</div>
|
||||
);
|
||||
|
||||
AutosuggestAccount.propTypes = {
|
||||
account: ImmutablePropTypes.map.isRequired
|
||||
};
|
||||
|
||||
export default AutosuggestAccount;
|
@ -1,15 +0,0 @@
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import DisplayName from '../../../components/display_name';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
|
||||
const AutosuggestStatus = ({ status }) => (
|
||||
<div className='autosuggest-status'>
|
||||
<FormattedMessage id='search.status_by' defaultMessage='Status by {name}' values={{ name: <strong>@{status.getIn(['account', 'acct'])}</strong> }} />
|
||||
</div>
|
||||
);
|
||||
|
||||
AutosuggestStatus.propTypes = {
|
||||
status: ImmutablePropTypes.map.isRequired
|
||||
};
|
||||
|
||||
export default AutosuggestStatus;
|
@ -1,44 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import Permalink from '../../../components/permalink';
|
||||
import Avatar from '../../../components/avatar';
|
||||
import DisplayName from '../../../components/display_name';
|
||||
import emojify from '../../../emoji';
|
||||
import IconButton from '../../../components/icon_button';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
|
||||
const messages = defineMessages({
|
||||
authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' },
|
||||
reject: { id: 'follow_request.reject', defaultMessage: 'Reject' }
|
||||
});
|
||||
|
||||
const AccountAuthorize = ({ intl, account, onAuthorize, onReject }) => {
|
||||
const content = { __html: emojify(account.get('note')) };
|
||||
|
||||
return (
|
||||
<div className='account-authorize__wrapper'>
|
||||
<div className='account-authorize'>
|
||||
<Permalink href={account.get('url')} to={`/accounts/${account.get('id')}`} className='detailed-status__display-name'>
|
||||
<div className='account-authorize__avatar'><Avatar src={account.get('avatar')} staticSrc={account.get('avatar_static')} size={48} /></div>
|
||||
<DisplayName account={account} />
|
||||
</Permalink>
|
||||
|
||||
<div className='account__header__content' dangerouslySetInnerHTML={content} />
|
||||
</div>
|
||||
|
||||
<div className='account--panel'>
|
||||
<div className='account--panel__button'><IconButton title={intl.formatMessage(messages.authorize)} icon='check' onClick={onAuthorize} /></div>
|
||||
<div className='account--panel__button'><IconButton title={intl.formatMessage(messages.reject)} icon='times' onClick={onReject} /></div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
AccountAuthorize.propTypes = {
|
||||
account: ImmutablePropTypes.map.isRequired,
|
||||
onAuthorize: PropTypes.func.isRequired,
|
||||
onReject: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default injectIntl(AccountAuthorize);
|
@ -1,66 +0,0 @@
|
||||
import Column from '../ui/components/column';
|
||||
import ColumnLink from '../ui/components/column_link';
|
||||
import ColumnSubheading from '../ui/components/column_subheading';
|
||||
import { Link } from 'react-router';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
|
||||
const messages = defineMessages({
|
||||
heading: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
|
||||
public_timeline: { id: 'navigation_bar.public_timeline', defaultMessage: 'Federated timeline' },
|
||||
navigation_subheading: { id: 'column_subheading.navigation', defaultMessage: 'Navigation'},
|
||||
settings_subheading: { id: 'column_subheading.settings', defaultMessage: 'Settings'},
|
||||
community_timeline: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
|
||||
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
||||
follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
|
||||
sign_out: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
||||
favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' },
|
||||
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
|
||||
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
|
||||
info: { id: 'navigation_bar.info', defaultMessage: 'Extended information' }
|
||||
});
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
me: state.getIn(['accounts', state.getIn(['meta', 'me'])])
|
||||
});
|
||||
|
||||
const GettingStarted = ({ intl, me }) => {
|
||||
let followRequests = '';
|
||||
|
||||
if (me.get('locked')) {
|
||||
followRequests = <ColumnLink icon='users' text={intl.formatMessage(messages.follow_requests)} to='/follow_requests' />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Column icon='asterisk' heading={intl.formatMessage(messages.heading)} hideHeadingOnMobile={true}>
|
||||
<div className='getting-started__wrapper'>
|
||||
<ColumnSubheading text={intl.formatMessage(messages.navigation_subheading)}/>
|
||||
<ColumnLink icon='users' hideOnMobile={true} text={intl.formatMessage(messages.community_timeline)} to='/timelines/public/local' />
|
||||
<ColumnLink icon='globe' hideOnMobile={true} text={intl.formatMessage(messages.public_timeline)} to='/timelines/public' />
|
||||
<ColumnLink icon='star' text={intl.formatMessage(messages.favourites)} to='/favourites' />
|
||||
{followRequests}
|
||||
<ColumnLink icon='volume-off' text={intl.formatMessage(messages.mutes)} to='/mutes' />
|
||||
<ColumnLink icon='ban' text={intl.formatMessage(messages.blocks)} to='/blocks' />
|
||||
<ColumnSubheading text={intl.formatMessage(messages.settings_subheading)}/>
|
||||
<ColumnLink icon='book' text={intl.formatMessage(messages.info)} href='/about/more' />
|
||||
<ColumnLink icon='cog' text={intl.formatMessage(messages.preferences)} href='/settings/preferences' />
|
||||
<ColumnLink icon='sign-out' text={intl.formatMessage(messages.sign_out)} href='/auth/sign_out' method='delete' />
|
||||
</div>
|
||||
|
||||
<div className='scrollable optionally-scrollable' style={{ display: 'flex', flexDirection: 'column' }}>
|
||||
<div className='static-content getting-started'>
|
||||
<p><FormattedMessage id='getting_started.open_source_notice' defaultMessage='Mastodon is open source software. You can contribute or report issues on GitHub at {github}. {apps}.' values={{ github: <a href="https://github.com/tootsuite/mastodon" target="_blank">tootsuite/mastodon</a>, apps: <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md" target="_blank"><FormattedMessage id='getting_started.apps' defaultMessage='Various apps are available' /></a> }} /></p>
|
||||
</div>
|
||||
</div>
|
||||
</Column>
|
||||
);
|
||||
};
|
||||
|
||||
GettingStarted.propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
me: ImmutablePropTypes.map.isRequired
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(injectIntl(GettingStarted));
|
@ -1,68 +0,0 @@
|
||||
const bg = {
|
||||
"column_back_button.label": "Назад",
|
||||
"lightbox.close": "Затвори",
|
||||
"loading_indicator.label": "Зареждане...",
|
||||
"status.mention": "Споменаване",
|
||||
"status.delete": "Изтриване",
|
||||
"status.reply": "Отговор",
|
||||
"status.reblog": "Споделяне",
|
||||
"status.favourite": "Предпочитани",
|
||||
"status.reblogged_by": "{name} сподели",
|
||||
"status.sensitive_warning": "Деликатно съдържание",
|
||||
"status.sensitive_toggle": "Покажи",
|
||||
"video_player.toggle_sound": "Звук",
|
||||
"account.mention": "Споменаване",
|
||||
"account.edit_profile": "Редактирай профила си",
|
||||
"account.unblock": "Не блокирай",
|
||||
"account.unfollow": "Не следвай",
|
||||
"account.block": "Блокирай",
|
||||
"account.follow": "Последвай",
|
||||
"account.posts": "Публикации",
|
||||
"account.follows": "Следвам",
|
||||
"account.followers": "Последователи",
|
||||
"account.follows_you": "Твой последовател",
|
||||
"account.requested": "В очакване на одобрение",
|
||||
"getting_started.heading": "Първи стъпки",
|
||||
"getting_started.about_addressing": "Можеш да последваш потребител, ако знаеш потребителското му име и домейна, на който се намира, като в полето за търсене ги въведеш по този начин: име@домейн",
|
||||
"getting_started.about_shortcuts": "Ако с търсения потребител се намирате на един и същ домейн, достатъчно е да въведеш само името. Същото важи и за споменаване на хора в публикации.",
|
||||
"getting_started.about_developer": "Можеш да потърсиш разработчика на този проект като: Gargron@mastodon.social",
|
||||
"getting_started.open_source_notice": "Mastodon е софтуер с отворен код. Можеш да помогнеш или да докладваш за проблеми в Github: {github}.",
|
||||
"column.home": "Начало",
|
||||
"column.mentions": "Споменавания",
|
||||
"column.public": "Публичен канал",
|
||||
"column.notifications": "Известия",
|
||||
"tabs_bar.compose": "Съставяне",
|
||||
"tabs_bar.home": "Начало",
|
||||
"tabs_bar.mentions": "Споменавания",
|
||||
"tabs_bar.public": "Публичен канал",
|
||||
"tabs_bar.notifications": "Известия",
|
||||
"compose_form.placeholder": "Какво си мислиш?",
|
||||
"compose_form.publish": "Раздумай",
|
||||
"compose_form.sensitive": "Отбележи съдържанието като деликатно",
|
||||
"compose_form.spoiler": "Скрий текста зад предупреждение",
|
||||
"compose_form.private": "Отбележи като поверително",
|
||||
"compose_form.privacy_disclaimer": "Поверителни публикации ще бъдат изпратени до споменатите потребители на {domains}. Доверяваш ли се на {domainsCount, plural, one {that server} other {those servers}}, че няма да издаде твоята публикация?",
|
||||
"compose_form.unlisted": "Не показвай в публичния канал",
|
||||
"navigation_bar.edit_profile": "Редактирай профил",
|
||||
"navigation_bar.preferences": "Предпочитания",
|
||||
"navigation_bar.public_timeline": "Публичен канал",
|
||||
"navigation_bar.logout": "Излизане",
|
||||
"reply_indicator.cancel": "Отказ",
|
||||
"search.placeholder": "Търсене",
|
||||
"search.account": "Акаунт",
|
||||
"search.hashtag": "Хаштаг",
|
||||
"upload_button.label": "Добави медия",
|
||||
"upload_form.undo": "Отмяна",
|
||||
"notification.follow": "{name} те последва",
|
||||
"notification.favourite": "{name} хареса твоята публикация",
|
||||
"notification.reblog": "{name} сподели твоята публикация",
|
||||
"notification.mention": "{name} те спомена",
|
||||
"notifications.column_settings.alert": "Десктоп известия",
|
||||
"notifications.column_settings.show": "Покажи в колона",
|
||||
"notifications.column_settings.follow": "Нови последователи:",
|
||||
"notifications.column_settings.favourite": "Предпочитани:",
|
||||
"notifications.column_settings.mention": "Споменавания:",
|
||||
"notifications.column_settings.reblog": "Споделяния:",
|
||||
};
|
||||
|
||||
export default bg;
|
@ -1,68 +0,0 @@
|
||||
const eo = {
|
||||
"column_back_button.label": "Reveni",
|
||||
"lightbox.close": "Fermi",
|
||||
"loading_indicator.label": "Ŝarĝanta...",
|
||||
"status.mention": "Mencii @{name}",
|
||||
"status.delete": "Forigi",
|
||||
"status.reply": "Respondi",
|
||||
"status.reblog": "Diskonigi",
|
||||
"status.favourite": "Favori",
|
||||
"status.reblogged_by": "{name} diskonigita",
|
||||
"status.sensitive_warning": "Tikla enhavo",
|
||||
"status.sensitive_toggle": "Alklaki por vidi",
|
||||
"video_player.toggle_sound": "Aktivigi sonojn",
|
||||
"account.mention": "Mencii @{name}",
|
||||
"account.edit_profile": "Redakti la profilon",
|
||||
"account.unblock": "Malbloki @{name}",
|
||||
"account.unfollow": "Malsekvi",
|
||||
"account.block": "Bloki @{name}",
|
||||
"account.follow": "Sekvi",
|
||||
"account.posts": "Mesaĝoj",
|
||||
"account.follows": "Sekvatoj",
|
||||
"account.followers": "Sekvantoj",
|
||||
"account.follows_you": "Sekvas vin",
|
||||
"account.requested": "Atendas aprobon",
|
||||
"getting_started.heading": "Por komenci",
|
||||
"getting_started.about_addressing": "Vi povas sekvi homojn se vi konas la uzantnomon kaj domajnon tajpinte retpoŝtecan adreson en la serĉilon.",
|
||||
"getting_started.about_shortcuts": "Se la celita uzanto troviĝas en la sama domajno de vi, uzi nur la uzantnomon sufiĉos. La sama regulo validas por mencii aliajn uzantojn en mesaĝo.",
|
||||
"getting_started.open_source_notice": "Mastodon estas malfermitkoda programo. Vi povas kontribui aŭ raporti problemojn en github je {github}. {apps}.",
|
||||
"column.home": "Hejmo",
|
||||
"column.community": "Loka tempolinio",
|
||||
"column.public": "Fratara tempolinio",
|
||||
"column.notifications": "Sciigoj",
|
||||
"tabs_bar.compose": "Ekskribi",
|
||||
"tabs_bar.home": "Hejmo",
|
||||
"tabs_bar.mentions": "Sciigoj",
|
||||
"tabs_bar.public": "Fratara tempolinio",
|
||||
"tabs_bar.notifications": "Sciigoj",
|
||||
"compose_form.placeholder": "Pri kio vi pensas?",
|
||||
"compose_form.publish": "Hup",
|
||||
"compose_form.sensitive": "Marki ke la enhavo estas tikla",
|
||||
"compose_form.spoiler": "Kaŝi la tekston malantaŭ averto",
|
||||
"compose_form.private": "Marki ke la enhavo estas privata",
|
||||
"compose_form.privacy_disclaimer": "Via privata mesaĝo estos sendita nur al menciitaj uzantoj en {domains}. Ĉu vi fidas {domainsCount, plural, one {tiun servilon} other {tiujn servilojn}}? Mesaĝa privateco funkcias nur en aperaĵoj de Mastodon. Se {domains} {domainsCount, plural, one {ne estas aperaĵo de Mastodon} other {ne estas aperaĵoj de Mastodon}}, estos neniu indiko ke via mesaĝo estas privata, kaj ĝi povus esti diskonigita aŭ videbligita al necelitaj ricevantoj.",
|
||||
"compose_form.unlisted": "Ne afiŝi en publikaj tempolinioj",
|
||||
"navigation_bar.edit_profile": "Redakti la profilon",
|
||||
"navigation_bar.preferences": "Preferoj",
|
||||
"navigation_bar.community_timeline": "Loka tempolinio",
|
||||
"navigation_bar.public_timeline": "Fratara tempolinio",
|
||||
"navigation_bar.logout": "Elsaluti",
|
||||
"reply_indicator.cancel": "Rezigni",
|
||||
"search.placeholder": "Serĉi",
|
||||
"search.account": "Konto",
|
||||
"search.hashtag": "Kradvorto",
|
||||
"upload_button.label": "Aldoni enhavaĵon",
|
||||
"upload_form.undo": "Malfari",
|
||||
"notification.follow": "{name} sekvis vin",
|
||||
"notification.favourite": "{name} favoris vian mesaĝon",
|
||||
"notification.reblog": "{name} diskonigis vian mesaĝon",
|
||||
"notification.mention": "{name} menciis vin",
|
||||
"notifications.column_settings.alert": "Retumilaj atentigoj",
|
||||
"notifications.column_settings.show": "Montri en kolono",
|
||||
"notifications.column_settings.follow": "Novaj sekvantoj:",
|
||||
"notifications.column_settings.favourite": "Favoroj:",
|
||||
"notifications.column_settings.mention": "Mencioj:",
|
||||
"notifications.column_settings.reblog": "Diskonigoj:",
|
||||
};
|
||||
|
||||
export default eo;
|
@ -1,93 +0,0 @@
|
||||
const es = {
|
||||
"column_back_button.label": "Atrás",
|
||||
"lightbox.close": "Cerrar",
|
||||
"loading_indicator.label": "Cargando...",
|
||||
"status.mention": "Mencionar",
|
||||
"status.delete": "Borrar",
|
||||
"status.reply": "Responder",
|
||||
"status.reblog": "Retoot",
|
||||
"status.favourite": "Favorito",
|
||||
"status.reblogged_by": "Retooteado por {name}",
|
||||
"status.sensitive_warning": "Contenido sensible",
|
||||
"status.sensitive_toggle": "Click para ver",
|
||||
"status.show_more": "Mostrar más",
|
||||
"status.show_less": "Mostrar menos",
|
||||
"status.open": "Expandir estado",
|
||||
"status.report": "Reportar",
|
||||
"video_player.toggle_sound": "Act/Desac. sonido",
|
||||
"account.mention": "Mencionar",
|
||||
"account.edit_profile": "Editar perfil",
|
||||
"account.unblock": "Desbloquear",
|
||||
"account.unfollow": "Dejar de seguir",
|
||||
"account.mute": "Silenciar",
|
||||
"account.block": "Bloquear",
|
||||
"account.follow": "Seguir",
|
||||
"account.posts": "Publicaciones",
|
||||
"account.follows": "Seguir",
|
||||
"account.followers": "Seguidores",
|
||||
"account.follows_you": "Te sigue",
|
||||
"account.requested": "Esperando aprobación",
|
||||
"getting_started.heading": "Primeros pasos",
|
||||
"getting_started.about_addressing": "Puedes seguir a gente si conoces su nombre de usuario y el dominio en el que están registrados, introduciendo algo similar a una dirección de correo electrónico en el formulario en la parte superior de la barra lateral.",
|
||||
"getting_started.about_shortcuts": "Si el usuario que buscas está en el mismo dominio que tú, simplemente funcionará introduciendo el nombre de usuario. La misma regla se aplica para mencionar a usuarios.",
|
||||
"getting_started.open_source_notice": "Mastodon es software libre. Puedes contribuir o reportar errores en {github}. {apps}.",
|
||||
"column.home": "Inicio",
|
||||
"column.community": "Historia local",
|
||||
"column.public": "Historia federada",
|
||||
"column.notifications": "Notificaciones",
|
||||
"column.blocks": "Usuarios bloqueados",
|
||||
"column.favourites": "Favoritos",
|
||||
"column.follow_requests": "Solicitudes para seguirte",
|
||||
"column.mutes": "Usuarios silenciados",
|
||||
"tabs_bar.compose": "Redactar",
|
||||
"tabs_bar.home": "Inicio",
|
||||
"tabs_bar.mentions": "Menciones",
|
||||
"tabs_bar.public": "Público",
|
||||
"tabs_bar.notifications": "Notificaciones",
|
||||
"compose_form.placeholder": "¿En qué estás pensando?",
|
||||
"compose_form.publish": "Tootear",
|
||||
"compose_form.sensitive": "Marcar contenido como sensible",
|
||||
"compose_form.spoiler": "Ocultar texto tras advertencia",
|
||||
"compose_form.spoiler_placeholder": "Advertencia de contenido",
|
||||
"composer_form.private": "Marcar como privado",
|
||||
"composer_form.privacy_disclaimer": "Tu estado se mostrará a los usuarios mencionados en {domains}. Tu estado podrá ser visto en otras instancias, quizás no quieras que tu estado sea visto por otros usuarios.",
|
||||
"compose_form.unlisted": "No mostrar en la historia federada",
|
||||
"navigation_bar.edit_profile": "Editar perfil",
|
||||
"navigation_bar.preferences": "Preferencias",
|
||||
"navigation_bar.community_timeline": "Historia local",
|
||||
"navigation_bar.public_timeline": "Historia federada",
|
||||
"navigation_bar.favourites": "Favoritos",
|
||||
"navigation_bar.blocks": "Usuarios bloqueados",
|
||||
"navigation_bar.info": "Información adicional",
|
||||
"navigation_bar.logout": "Cerrar sesión",
|
||||
"navigation_bar.follow_requests": "Solicitudes para seguirte",
|
||||
"navigation_bar.mutes": "Usuarios silenciados",
|
||||
"reply_indicator.cancel": "Cancelar",
|
||||
"search.placeholder": "Buscar",
|
||||
"search.account": "Cuenta",
|
||||
"search.hashtag": "Etiqueta",
|
||||
"upload_button.label": "Subir multimedia",
|
||||
"upload_form.undo": "Deshacer",
|
||||
"notification.follow": "{name} te empezó a seguir",
|
||||
"notification.favourite": "{name} marcó tu estado como favorito",
|
||||
"notification.reblog": "{name} ha retooteado tu estado",
|
||||
"notification.mention": "{name} te ha mencionado",
|
||||
"notifications.column_settings.alert": "Notificaciones de escritorio",
|
||||
"notifications.column_settings.show": "Mostrar en columna",
|
||||
"notifications.column_settings.follow": "Nuevos seguidores:",
|
||||
"notifications.column_settings.favourite": "Favoritos:",
|
||||
"notifications.column_settings.mention": "Menciones:",
|
||||
"notifications.column_settings.reblog": "Retoots:",
|
||||
"emoji_button.label": "Insertar emoji",
|
||||
"privacy.public.short": "Público",
|
||||
"privacy.public.long": "Mostrar en la historia federada",
|
||||
"privacy.unlisted.short": "Sin federar",
|
||||
"privacy.unlisted.long": "No mostrar en la historia federada",
|
||||
"privacy.private.short": "Privado",
|
||||
"privacy.private.long": "Sólo mostrar a seguidores",
|
||||
"privacy.direct.short": "Directo",
|
||||
"privacy.direct.long": "Sólo mostrar a los usuarios mencionados",
|
||||
"privacy.change": "Ajustar privacidad"
|
||||
};
|
||||
|
||||
export default es;
|
@ -1,68 +0,0 @@
|
||||
const fi = {
|
||||
"column_back_button.label": "Takaisin",
|
||||
"lightbox.close": "Sulje",
|
||||
"loading_indicator.label": "Ladataan...",
|
||||
"status.mention": "Mainitse @{name}",
|
||||
"status.delete": "Poista",
|
||||
"status.reply": "Vastaa",
|
||||
"status.reblog": "Buustaa",
|
||||
"status.favourite": "Tykkää",
|
||||
"status.reblogged_by": "{name} buustasi",
|
||||
"status.sensitive_warning": "Arkaluontoista sisältöä",
|
||||
"status.sensitive_toggle": "Klikkaa nähdäksesi",
|
||||
"video_player.toggle_sound": "Äänet päälle/pois",
|
||||
"account.mention": "Mainitse @{name}",
|
||||
"account.edit_profile": "Muokkaa",
|
||||
"account.unblock": "Salli @{name}",
|
||||
"account.unfollow": "Lopeta seuraaminen",
|
||||
"account.block": "Estä @{name}",
|
||||
"account.follow": "Seuraa",
|
||||
"account.posts": "Postit",
|
||||
"account.follows": "Seuraa",
|
||||
"account.followers": "Seuraajia",
|
||||
"account.follows_you": "Seuraa sinua",
|
||||
"account.requested": "Odottaa hyväksyntää",
|
||||
"getting_started.heading": "Aloitus",
|
||||
"getting_started.about_addressing": "Voit seurata ihmisiä jos tiedät heidän käyttäjänimensä ja domainin missä he ovat syöttämällä e-mail-esque osoitteen Etsi kenttään.",
|
||||
"getting_started.about_shortcuts": "Jos etsimäsi henkilö on samassa domainissa kuin sinä, pelkkä käyttäjänimi kelpaa. Sama pätee kun mainitset ihmisiä statuksessasi",
|
||||
"getting_started.open_source_notice": "Mastodon Mastodon on avoimen lähdekoodin ohjelma. Voit avustaa tai raportoida ongelmia GitHub palvelussa {github}. {apps}.",
|
||||
"column.home": "Koti",
|
||||
"column.community": "Paikallinen aikajana",
|
||||
"column.public": "Yleinen aikajana",
|
||||
"column.notifications": "Ilmoitukset",
|
||||
"tabs_bar.compose": "Luo",
|
||||
"tabs_bar.home": "Koti",
|
||||
"tabs_bar.mentions": "Maininnat",
|
||||
"tabs_bar.public": "Yleinen aikajana",
|
||||
"tabs_bar.notifications": "Ilmoitukset",
|
||||
"compose_form.placeholder": "Mitä sinulla on mielessä?",
|
||||
"compose_form.publish": "Toot",
|
||||
"compose_form.sensitive": "Merkitse media herkäksi",
|
||||
"compose_form.spoiler": "Piiloita teksti varoituksen taakse",
|
||||
"compose_form.private": "Merkitse yksityiseksi",
|
||||
"compose_form.privacy_disclaimer": "Sinun yksityinen status toimitetaan mainitsemallesi käyttäjille domaineissa {domains}. Luotatko {domainsCount, plural, one {tähän palvelimeen} other {näihin palvelimiin}}? Postauksen yksityisyys toimii van Mastodon palvelimilla. Jos {domains} {domainsCount, plural, one {ei ole Mastodon palvelin} other {eivät ole Mastodon palvelin}}, viestiin ei tule Yksityinen-merkintää, ja sitä voidaan boostata tai muuten tehdä näkyväksi muille vastaanottajille.",
|
||||
"compose_form.unlisted": "Älä näytä yleisillä aikajanoilla",
|
||||
"navigation_bar.edit_profile": "Muokkaa profiilia",
|
||||
"navigation_bar.preferences": "Ominaisuudet",
|
||||
"navigation_bar.community_timeline": "Paikallinen aikajana",
|
||||
"navigation_bar.public_timeline": "Yleinen aikajana",
|
||||
"navigation_bar.logout": "Kirjaudu ulos",
|
||||
"reply_indicator.cancel": "Peruuta",
|
||||
"search.placeholder": "Hae",
|
||||
"search.account": "Tili",
|
||||
"search.hashtag": "Hashtag",
|
||||
"upload_button.label": "Lisää mediaa",
|
||||
"upload_form.undo": "Peru",
|
||||
"notification.follow": "{name} seurasi sinua",
|
||||
"notification.favourite": "{name} tykkäsi statuksestasi",
|
||||
"notification.reblog": "{name} buustasi statustasi",
|
||||
"notification.mention": "{name} mainitsi sinut",
|
||||
"notifications.column_settings.alert": "Työpöytä ilmoitukset",
|
||||
"notifications.column_settings.show": "Näytä sarakkeessa",
|
||||
"notifications.column_settings.follow": "Uusia seuraajia:",
|
||||
"notifications.column_settings.favourite": "Tykkäyksiä:",
|
||||
"notifications.column_settings.mention": "Mainintoja:",
|
||||
"notifications.column_settings.reblog": "Buusteja:",
|
||||
};
|
||||
|
||||
export default fi;
|
@ -1,57 +0,0 @@
|
||||
const hu = {
|
||||
"column_back_button.label": "Vissza",
|
||||
"lightbox.close": "Bezárás",
|
||||
"loading_indicator.label": "Betöltés...",
|
||||
"status.mention": "Említés",
|
||||
"status.delete": "Törlés",
|
||||
"status.reply": "Válasz",
|
||||
"status.reblog": "Reblog",
|
||||
"status.favourite": "Kedvenc",
|
||||
"status.reblogged_by": "{name} reblogolta",
|
||||
"status.sensitive_warning": "Érzékeny tartalom",
|
||||
"status.sensitive_toggle": "Katt a megtekintéshez",
|
||||
"video_player.toggle_sound": "Hang kapcsolása",
|
||||
"account.mention": "Említés",
|
||||
"account.edit_profile": "Profil szerkesztése",
|
||||
"account.unblock": "Blokkolás levétele",
|
||||
"account.unfollow": "Követés abbahagyása",
|
||||
"account.block": "Blokkolás",
|
||||
"account.follow": "Követés",
|
||||
"account.posts": "Posts",
|
||||
"account.follows": "Követve",
|
||||
"account.followers": "Követők",
|
||||
"account.follows_you": "Követnek téged",
|
||||
"getting_started.heading": "Első lépések",
|
||||
"getting_started.about_addressing": "Követhetsz embereket felhasználónevük és a doménjük ismeretében, amennyiben megadod ezt az e-mail-szerű címet az oldalsáv tetején lévő rubrikában.",
|
||||
"getting_started.about_shortcuts": "Ha a célzott személy azonos doménen tartózkodik, a felhasználónév elegendő. Ugyanez érvényes mikor személyeket említesz az állapotokban.",
|
||||
"getting_started.about_developer": "A projekt fejlesztője követhető, mint Gargron@mastodon.social",
|
||||
"column.home": "Kezdőlap",
|
||||
"column.mentions": "Említések",
|
||||
"column.public": "Nyilvános",
|
||||
"column.notifications": "Értesítések",
|
||||
"tabs_bar.compose": "Összeállítás",
|
||||
"tabs_bar.home": "Kezdőlap",
|
||||
"tabs_bar.mentions": "Említések",
|
||||
"tabs_bar.public": "Nyilvános",
|
||||
"tabs_bar.notifications": "Notifications",
|
||||
"compose_form.placeholder": "Mire gondolsz?",
|
||||
"compose_form.publish": "Tülk!",
|
||||
"compose_form.sensitive": "Tartalom érzékenynek jelölése",
|
||||
"compose_form.unlisted": "Listázatlan mód",
|
||||
"navigation_bar.edit_profile": "Profil szerkesztése",
|
||||
"navigation_bar.preferences": "Beállítások",
|
||||
"navigation_bar.public_timeline": "Nyilvános időfolyam",
|
||||
"navigation_bar.logout": "Kijelentkezés",
|
||||
"reply_indicator.cancel": "Mégsem",
|
||||
"search.placeholder": "Keresés",
|
||||
"search.account": "Fiók",
|
||||
"search.hashtag": "Hashtag",
|
||||
"upload_button.label": "Média hozzáadása",
|
||||
"upload_form.undo": "Mégsem",
|
||||
"notification.follow": "{name} követ téged",
|
||||
"notification.favourite": "{name} kedvencnek jelölte az állapotod",
|
||||
"notification.reblog": "{name} reblogolta az állapotod",
|
||||
"notification.mention": "{name} megemlített"
|
||||
};
|
||||
|
||||
export default hu;
|
@ -1,57 +0,0 @@
|
||||
import ar from './ar';
|
||||
import en from './en';
|
||||
import de from './de';
|
||||
import es from './es';
|
||||
import fa from './fa';
|
||||
import he from './he';
|
||||
import hr from './hr';
|
||||
import hu from './hu';
|
||||
import io from './io';
|
||||
import it from './it';
|
||||
import fr from './fr';
|
||||
import nl from './nl';
|
||||
import no from './no';
|
||||
import oc from './oc';
|
||||
import pt from './pt';
|
||||
import pt_br from './pt-br';
|
||||
import uk from './uk';
|
||||
import fi from './fi';
|
||||
import eo from './eo';
|
||||
import ru from './ru';
|
||||
import ja from './ja';
|
||||
import zh_hk from './zh-hk';
|
||||
import zh_cn from './zh-cn';
|
||||
import bg from './bg';
|
||||
import id from './id';
|
||||
|
||||
const locales = {
|
||||
ar,
|
||||
en,
|
||||
de,
|
||||
es,
|
||||
fa,
|
||||
he,
|
||||
hr,
|
||||
hu,
|
||||
io,
|
||||
it,
|
||||
fr,
|
||||
nl,
|
||||
no,
|
||||
oc,
|
||||
pt,
|
||||
'pt-BR': pt_br,
|
||||
uk,
|
||||
fi,
|
||||
eo,
|
||||
ru,
|
||||
ja,
|
||||
'zh-HK': zh_hk,
|
||||
'zh-CN': zh_cn,
|
||||
bg,
|
||||
id,
|
||||
};
|
||||
|
||||
export default function getMessagesForLocale (locale) {
|
||||
return locales[locale];
|
||||
};
|
@ -1,57 +0,0 @@
|
||||
const uk = {
|
||||
"column_back_button.label": "Назад",
|
||||
"lightbox.close": "Закрити",
|
||||
"loading_indicator.label": "Завантаження...",
|
||||
"status.mention": "Згадати",
|
||||
"status.delete": "Видалити",
|
||||
"status.reply": "Відповісти",
|
||||
"status.reblog": "Передмухнути",
|
||||
"status.favourite": "Подобається",
|
||||
"status.reblogged_by": "{name} передмухнув(-ла)",
|
||||
"status.sensitive_warning": "Непристойний зміст",
|
||||
"status.sensitive_toggle": "Натисніть, щоб подивитися",
|
||||
"video_player.toggle_sound": "Увімкнути/вимкнути звук",
|
||||
"account.mention": "Згадати",
|
||||
"account.edit_profile": "Налаштування профілю",
|
||||
"account.unblock": "Розблокувати",
|
||||
"account.unfollow": "Відписатися",
|
||||
"account.block": "Заблокувати",
|
||||
"account.follow": "Підписатися",
|
||||
"account.posts": "Пости",
|
||||
"account.follows": "Підписки",
|
||||
"account.followers": "Підписники",
|
||||
"account.follows_you": "Підписаний",
|
||||
"getting_started.heading": "Ласкаво просимо",
|
||||
"getting_started.about_addressing": "Ви можете підписуватись на людей, якщо ви знаєте їх ім'я користувача чи домен, шляхом введення email-подібної адреси у верхньому рядку бокової панелі.",
|
||||
"getting_started.about_shortcuts": "Якщо користувач, якого ви шукаєте, знаходиться на тому ж домені, що й ви, можна просто ввести ім'я користувача. Це правило стосується й згадування людей у статусах.",
|
||||
"getting_started.about_developer": "Розробник проекту знаходиться за адресою Gargron@mastodon.social",
|
||||
"column.home": "Головна",
|
||||
"column.mentions": "Згадування",
|
||||
"column.public": "Стіна",
|
||||
"column.notifications": "Сповіщення",
|
||||
"tabs_bar.compose": "Написати",
|
||||
"tabs_bar.home": "Головна",
|
||||
"tabs_bar.mentions": "Згадування",
|
||||
"tabs_bar.public": "Стіна",
|
||||
"tabs_bar.notifications": "Сповіщення",
|
||||
"compose_form.placeholder": "Що у Вас на думці?",
|
||||
"compose_form.publish": "Дмухнути",
|
||||
"compose_form.sensitive": "Непристойний зміст",
|
||||
"compose_form.unlisted": "Таємний режим",
|
||||
"navigation_bar.edit_profile": "Редагувати профіль",
|
||||
"navigation_bar.preferences": "Налаштування",
|
||||
"navigation_bar.public_timeline": "Публічна стіна",
|
||||
"navigation_bar.logout": "Вийти",
|
||||
"reply_indicator.cancel": "Відмінити",
|
||||
"search.placeholder": "Пошук",
|
||||
"search.account": "Аккаунт",
|
||||
"search.hashtag": "Хештеґ",
|
||||
"upload_button.label": "Додати медіа",
|
||||
"upload_form.undo": "Відмінити",
|
||||
"notification.follow": "{name} підписався(-лась) на Вас",
|
||||
"notification.favourite": "{name} сподобався ваш допис",
|
||||
"notification.reblog": "{name} передмухнув(-ла) Ваш статус",
|
||||
"notification.mention": "{name} згадав(-ла) Вас"
|
||||
};
|
||||
|
||||
export default uk;
|
@ -1,11 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: local('Montserrat');
|
||||
src: font-url('montserrat/Montserrat-Regular.eot');
|
||||
src: font-url('montserrat/Montserrat-Regular.eot?#iefix') format('embedded-opentype'),
|
||||
font-url('montserrat/Montserrat-Regular.woff2') format('woff2'),
|
||||
font-url('montserrat/Montserrat-Regular.woff') format('woff'),
|
||||
font-url('montserrat/Montserrat-Regular.ttf') format('truetype');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'Roboto Mono';
|
||||
src: local('Roboto Mono');
|
||||
src: font-url('roboto-mono/robotomono-regular-webfont.eot');
|
||||
src: font-url('roboto-mono/robotomono-regular-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
font-url('roboto-mono/robotomono-regular-webfont.woff2') format('woff2'),
|
||||
font-url('roboto-mono/robotomono-regular-webfont.woff') format('woff'),
|
||||
font-url('roboto-mono/robotomono-regular-webfont.ttf') format('truetype'),
|
||||
font-url('roboto-mono/robotomono-regular-webfont.svg#roboto_monoregular') format('svg');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto');
|
||||
src: font-url('roboto/roboto-italic-webfont.eot');
|
||||
src: font-url('roboto/roboto-italic-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
font-url('roboto/roboto-italic-webfont.woff2') format('woff2'),
|
||||
font-url('roboto/roboto-italic-webfont.woff') format('woff'),
|
||||
font-url('roboto/roboto-italic-webfont.ttf') format('truetype'),
|
||||
font-url('roboto/roboto-italic-webfont.svg#roboto-italic-webfont') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto');
|
||||
src: font-url('roboto/roboto-bold-webfont.eot');
|
||||
src: local('Roboto bold'), local('roboto-bold'),
|
||||
font-url('roboto/roboto-bold-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
font-url('roboto/roboto-bold-webfont.woff2') format('woff2'),
|
||||
font-url('roboto/roboto-bold-webfont.woff') format('woff'),
|
||||
font-url('roboto/roboto-bold-webfont.ttf') format('truetype'),
|
||||
font-url('roboto/roboto-bold-webfont.svg#roboto-bold-webfont') format('svg');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto');
|
||||
src: font-url('roboto/roboto-medium-webfont.eot');
|
||||
src: font-url('roboto/roboto-medium-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
font-url('roboto/roboto-medium-webfont.woff2') format('woff2'),
|
||||
font-url('roboto/roboto-medium-webfont.woff') format('woff'),
|
||||
font-url('roboto/roboto-medium-webfont.ttf') format('truetype'),
|
||||
font-url('roboto/roboto-medium-webfont.svg#roboto-medium-webfont') format('svg');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto');
|
||||
src: font-url('roboto/roboto-regular-webfont.eot');
|
||||
src: font-url('roboto/roboto-regular-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
font-url('roboto/roboto-regular-webfont.woff2') format('woff2'),
|
||||
font-url('roboto/roboto-regular-webfont.woff') format('woff'),
|
||||
font-url('roboto/roboto-regular-webfont.ttf') format('truetype'),
|
||||
font-url('roboto/roboto-regular-webfont.svg#roboto-regular-webfont') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
@ -10,7 +10,7 @@ module ApplicationHelper
|
||||
end
|
||||
|
||||
def add_rtl_body_class(other_classes)
|
||||
other_classes = "#{other_classes} rtl" if [:ar, :fa].include?(I18n.locale)
|
||||
other_classes = "#{other_classes} rtl" if [:ar, :fa, :he].include?(I18n.locale)
|
||||
other_classes
|
||||
end
|
||||
|
||||
@ -22,4 +22,8 @@ module ApplicationHelper
|
||||
def title
|
||||
Rails.env.production? ? site_title : "#{site_title} (Dev)"
|
||||
end
|
||||
|
||||
def fa_icon(icon)
|
||||
content_tag(:i, nil, class: 'fa ' + icon.split(' ').map { |cl| "fa-#{cl}" }.join(' '))
|
||||
end
|
||||
end
|
||||
|
Before Width: | Height: | Size: 339 KiB After Width: | Height: | Size: 339 KiB |
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
Before Width: | Height: | Size: 258 KiB After Width: | Height: | Size: 258 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 131 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 244 KiB After Width: | Height: | Size: 244 KiB |
Before Width: | Height: | Size: 174 B After Width: | Height: | Size: 174 B |
0
app/javascript/mastodon/.gitkeep
Normal file
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import PropTypes from 'prop-types';
|
||||
import Avatar from './avatar';
|
||||
@ -5,6 +6,7 @@ import DisplayName from './display_name';
|
||||
import Permalink from './permalink';
|
||||
import IconButton from './icon_button';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
|
||||
const messages = defineMessages({
|
||||
follow: { id: 'account.follow', defaultMessage: 'Follow' },
|
||||
@ -14,7 +16,7 @@ const messages = defineMessages({
|
||||
unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' }
|
||||
});
|
||||
|
||||
class Account extends React.PureComponent {
|
||||
class Account extends ImmutablePureComponent {
|
||||
|
||||
constructor (props, context) {
|
||||
super(props, context);
|
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
|
||||
const filename = url => url.split('/').pop().split('#')[0].split('?')[0];
|
@ -1,7 +1,9 @@
|
||||
import React from 'react';
|
||||
import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import PropTypes from 'prop-types';
|
||||
import { isRtl } from '../rtl';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
|
||||
const textAtCursorMatchesToken = (str, caretPosition) => {
|
||||
let word;
|
||||
@ -28,7 +30,7 @@ const textAtCursorMatchesToken = (str, caretPosition) => {
|
||||
}
|
||||
};
|
||||
|
||||
class AutosuggestTextarea extends React.Component {
|
||||
class AutosuggestTextarea extends ImmutablePureComponent {
|
||||
|
||||
constructor (props, context) {
|
||||
super(props, context);
|
@ -1,21 +1,26 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
class Avatar extends React.PureComponent {
|
||||
|
||||
constructor (props, context) {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
hovering: false
|
||||
};
|
||||
|
||||
this.handleMouseEnter = this.handleMouseEnter.bind(this);
|
||||
this.handleMouseLeave = this.handleMouseLeave.bind(this);
|
||||
}
|
||||
|
||||
handleMouseEnter () {
|
||||
if (this.props.animate) return;
|
||||
this.setState({ hovering: true });
|
||||
}
|
||||
|
||||
handleMouseLeave () {
|
||||
if (this.props.animate) return;
|
||||
this.setState({ hovering: false });
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
class Button extends React.PureComponent {
|
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import { Motion, spring } from 'react-motion';
|
||||
import PropTypes from 'prop-types';
|
||||
|
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
|
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
|
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import { Motion, spring } from 'react-motion';
|
||||
import PropTypes from 'prop-types';
|
||||
|
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import escapeTextContentForBrowser from 'escape-html';
|
||||
import emojify from '../emoji';
|
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import Dropdown, { DropdownTrigger, DropdownContent } from 'react-simple-dropdown';
|
||||
import PropTypes from 'prop-types';
|
||||
|