diff --git a/Gemfile b/Gemfile index cab4c4139..7a6e1568d 100644 --- a/Gemfile +++ b/Gemfile @@ -66,7 +66,6 @@ gem 'pundit', '~> 1.1' gem 'premailer-rails' gem 'rack-attack', '~> 5.2' gem 'rack-cors', '~> 1.0', require: 'rack/cors' -gem 'rack-timeout', '~> 0.4' gem 'rails-i18n', '~> 5.1' gem 'rails-settings-cached', '~> 0.6' gem 'redis', '~> 4.0', require: ['redis', 'redis/connection/hiredis'] diff --git a/Gemfile.lock b/Gemfile.lock index f7a377d45..a99575147 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -88,7 +88,7 @@ GEM aws-sdk-kms (~> 1) aws-sigv4 (~> 1.0) aws-sigv4 (1.0.2) - bcrypt (3.1.11) + bcrypt (3.1.12) benchmark-ips (2.7.2) better_errors (2.4.0) coderay (>= 1.0.0) @@ -425,7 +425,6 @@ GEM rack rack-test (1.0.0) rack (>= 1.0, < 3) - rack-timeout (0.4.2) rails (5.2.0) actioncable (= 5.2.0) actionmailer (= 5.2.0) @@ -726,7 +725,6 @@ DEPENDENCIES pundit (~> 1.1) rack-attack (~> 5.2) rack-cors (~> 1.0) - rack-timeout (~> 0.4) rails (~> 5.2.0) rails-controller-testing (~> 1.0) rails-i18n (~> 5.1) diff --git a/app/controllers/api/v1/accounts/credentials_controller.rb b/app/controllers/api/v1/accounts/credentials_controller.rb index 259d07be8..2d0737ee4 100644 --- a/app/controllers/api/v1/accounts/credentials_controller.rb +++ b/app/controllers/api/v1/accounts/credentials_controller.rb @@ -32,6 +32,7 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController { 'setting_default_privacy' => source_params.fetch(:privacy, @account.user.setting_default_privacy), 'setting_default_sensitive' => source_params.fetch(:sensitive, @account.user.setting_default_sensitive), + 'setting_default_language' => source_params.fetch(:language, @account.user.setting_default_language), } end end diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb index 417e2b63b..c095411c1 100644 --- a/app/controllers/auth/registrations_controller.rb +++ b/app/controllers/auth/registrations_controller.rb @@ -3,6 +3,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController layout :determine_layout + before_action :set_invite, only: [:new, :create] before_action :check_enabled_registrations, only: [:new, :create] before_action :configure_sign_up_params, only: [:create] before_action :set_sessions, only: [:edit, :update] @@ -51,7 +52,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController end def allowed_registrations? - Setting.open_registrations || (invite_code.present? && Invite.find_by(code: invite_code)&.valid_for_use?) + Setting.open_registrations || @invite&.valid_for_use? end def invite_code @@ -68,6 +69,10 @@ class Auth::RegistrationsController < Devise::RegistrationsController @instance_presenter = InstancePresenter.new end + def set_invite + @invite = invite_code.present? ? Invite.find_by(code: invite_code) : nil + end + def determine_layout %w(edit update).include?(action_name) ? 'admin' : 'auth' end diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index 26ef99b7e..5c30313f4 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -11,7 +11,7 @@ class InvitesController < ApplicationController authorize :invite, :create? @invites = invites - @invite = Invite.new(expires_in: 1.day.to_i) + @invite = Invite.new end def create @@ -42,6 +42,6 @@ class InvitesController < ApplicationController end def resource_params - params.require(:invite).permit(:max_uses, :expires_in) + params.require(:invite).permit(:max_uses, :expires_in, :autofollow) end end diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb index 57793d776..e2cb13167 100644 --- a/app/controllers/settings/preferences_controller.rb +++ b/app/controllers/settings/preferences_controller.rb @@ -27,7 +27,7 @@ class Settings::PreferencesController < ApplicationController def user_params params.require(:user).permit( :locale, - filtered_languages: [] + chosen_languages: [] ) end @@ -35,6 +35,7 @@ class Settings::PreferencesController < ApplicationController params.require(:user).permit( :setting_default_privacy, :setting_default_sensitive, + :setting_default_language, :setting_unfollow_modal, :setting_boost_modal, :setting_delete_modal, diff --git a/app/javascript/mastodon/actions/columns.js b/app/javascript/mastodon/actions/columns.js index f550e6c48..9b87415fb 100644 --- a/app/javascript/mastodon/actions/columns.js +++ b/app/javascript/mastodon/actions/columns.js @@ -40,12 +40,13 @@ export function moveColumn(uuid, direction) { }; }; -export function changeColumnParams(uuid, params) { +export function changeColumnParams(uuid, path, value) { return dispatch => { dispatch({ type: COLUMN_PARAMS_CHANGE, uuid, - params, + path, + value, }); dispatch(saveSettings()); diff --git a/app/javascript/mastodon/actions/importer/normalizer.js b/app/javascript/mastodon/actions/importer/normalizer.js index c015d3a99..10a39e050 100644 --- a/app/javascript/mastodon/actions/importer/normalizer.js +++ b/app/javascript/mastodon/actions/importer/normalizer.js @@ -50,13 +50,14 @@ export function normalizeStatus(status, normalOldStatus) { normalStatus.spoilerHtml = normalOldStatus.get('spoilerHtml'); normalStatus.hidden = normalOldStatus.get('hidden'); } else { - const searchContent = [status.spoiler_text, status.content].join('\n\n').replace(//g, '\n').replace(/<\/p>

/g, '\n\n'); - const emojiMap = makeEmojiMap(normalStatus); + const spoilerText = normalStatus.spoiler_text || ''; + const searchContent = [spoilerText, status.content].join('\n\n').replace(//g, '\n').replace(/<\/p>

/g, '\n\n'); + const emojiMap = makeEmojiMap(normalStatus); normalStatus.search_index = domParser.parseFromString(searchContent, 'text/html').documentElement.textContent; normalStatus.contentHtml = emojify(normalStatus.content, emojiMap); - normalStatus.spoilerHtml = emojify(escapeTextContentForBrowser(normalStatus.spoiler_text || ''), emojiMap); - normalStatus.hidden = normalStatus.sensitive; + normalStatus.spoilerHtml = emojify(escapeTextContentForBrowser(spoilerText), emojiMap); + normalStatus.hidden = spoilerText.length > 0 || normalStatus.sensitive; } return normalStatus; diff --git a/app/javascript/mastodon/features/account/components/action_bar.js b/app/javascript/mastodon/features/account/components/action_bar.js index 2d0f72be2..69726a416 100644 --- a/app/javascript/mastodon/features/account/components/action_bar.js +++ b/app/javascript/mastodon/features/account/components/action_bar.js @@ -140,10 +140,6 @@ export default class ActionBar extends React.PureComponent { {extraInfo}

-
- -
-
@@ -160,6 +156,10 @@ export default class ActionBar extends React.PureComponent { {shortNumberFormat(account.get('followers_count'))}
+ +
+ +
); diff --git a/app/javascript/mastodon/features/community_timeline/components/column_settings.js b/app/javascript/mastodon/features/community_timeline/components/column_settings.js index a992b27bb..3a1d19aa8 100644 --- a/app/javascript/mastodon/features/community_timeline/components/column_settings.js +++ b/app/javascript/mastodon/features/community_timeline/components/column_settings.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import SettingText from '../../../components/setting_text'; +import SettingToggle from '../../notifications/components/setting_toggle'; const messages = defineMessages({ filter_regex: { id: 'home.column_settings.filter_regex', defaultMessage: 'Filter out by regular expressions' }, @@ -16,6 +17,7 @@ export default class ColumnSettings extends React.PureComponent { settings: ImmutablePropTypes.map.isRequired, onChange: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, + columnId: PropTypes.string, }; render () { @@ -23,6 +25,10 @@ export default class ColumnSettings extends React.PureComponent { return (
+
+ } /> +
+
diff --git a/app/javascript/mastodon/features/community_timeline/components/section_headline.js b/app/javascript/mastodon/features/community_timeline/components/section_headline.js deleted file mode 100644 index c7176d04b..000000000 --- a/app/javascript/mastodon/features/community_timeline/components/section_headline.js +++ /dev/null @@ -1,59 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component, Fragment } from 'react'; -import { FormattedMessage } from 'react-intl'; -import { NavLink } from 'react-router-dom'; - -export default class SectionHeadline extends Component { - - static propTypes = { - timelineId: PropTypes.string.isRequired, - to: PropTypes.string.isRequired, - pinned: PropTypes.bool.isRequired, - onlyMedia: PropTypes.bool.isRequired, - onClick: PropTypes.func, - }; - - shouldComponentUpdate (nextProps) { - return ( - this.props.onlyMedia !== nextProps.onlyMedia || - this.props.pinned !== nextProps.pinned || - this.props.to !== nextProps.to || - this.props.timelineId !== nextProps.timelineId - ); - } - - handleClick = e => { - const { onClick } = this.props; - - if (typeof onClick === 'function') { - e.preventDefault(); - - onClick.call(this, e); - } - } - - render () { - const { timelineId, to, pinned, onlyMedia } = this.props; - - return ( -
- {pinned ? ( - - - - - - - - - ) : ( - - - - - )} -
- ); - } - -} diff --git a/app/javascript/mastodon/features/community_timeline/containers/column_settings_container.js b/app/javascript/mastodon/features/community_timeline/containers/column_settings_container.js index f3489b409..405064c3f 100644 --- a/app/javascript/mastodon/features/community_timeline/containers/column_settings_container.js +++ b/app/javascript/mastodon/features/community_timeline/containers/column_settings_container.js @@ -1,17 +1,28 @@ import { connect } from 'react-redux'; import ColumnSettings from '../components/column_settings'; import { changeSetting } from '../../../actions/settings'; +import { changeColumnParams } from '../../../actions/columns'; -const mapStateToProps = state => ({ - settings: state.getIn(['settings', 'community']), -}); +const mapStateToProps = (state, { columnId }) => { + const uuid = columnId; + const columns = state.getIn(['settings', 'columns']); + const index = columns.findIndex(c => c.get('uuid') === uuid); -const mapDispatchToProps = dispatch => ({ + return { + settings: (uuid && index >= 0) ? columns.get(index).get('params') : state.getIn(['settings', 'community']), + }; +}; - onChange (key, checked) { - dispatch(changeSetting(['community', ...key], checked)); - }, - -}); +const mapDispatchToProps = (dispatch, { columnId }) => { + return { + onChange (key, checked) { + if (columnId) { + dispatch(changeColumnParams(columnId, key, checked)); + } else { + dispatch(changeSetting(['community', ...key], checked)); + } + }, + }; +}; export default connect(mapStateToProps, mapDispatchToProps)(ColumnSettings); diff --git a/app/javascript/mastodon/features/community_timeline/index.js b/app/javascript/mastodon/features/community_timeline/index.js index d375edbd5..eb9ad97a2 100644 --- a/app/javascript/mastodon/features/community_timeline/index.js +++ b/app/javascript/mastodon/features/community_timeline/index.js @@ -6,23 +6,33 @@ import StatusListContainer from '../ui/containers/status_list_container'; import Column from '../../components/column'; import ColumnHeader from '../../components/column_header'; import { expandCommunityTimeline } from '../../actions/timelines'; -import { addColumn, removeColumn, moveColumn, changeColumnParams } from '../../actions/columns'; +import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; import ColumnSettingsContainer from './containers/column_settings_container'; -import SectionHeadline from './components/section_headline'; import { connectCommunityStream } from '../../actions/streaming'; const messages = defineMessages({ title: { id: 'column.community', defaultMessage: 'Local timeline' }, }); -const mapStateToProps = (state, { onlyMedia }) => ({ - hasUnread: state.getIn(['timelines', `community${onlyMedia ? ':media' : ''}`, 'unread']) > 0, -}); +const mapStateToProps = (state, { onlyMedia, columnId }) => { + const uuid = columnId; + const columns = state.getIn(['settings', 'columns']); + const index = columns.findIndex(c => c.get('uuid') === uuid); + + return { + hasUnread: state.getIn(['timelines', `community${onlyMedia ? ':media' : ''}`, 'unread']) > 0, + onlyMedia: (columnId && index >= 0) ? columns.get(index).getIn(['params', 'other', 'onlyMedia']) : state.getIn(['settings', 'community', 'other', 'onlyMedia']), + }; +}; @connect(mapStateToProps) @injectIntl export default class CommunityTimeline extends React.PureComponent { + static contextTypes = { + router: PropTypes.object, + }; + static defaultProps = { onlyMedia: false, }; @@ -89,27 +99,10 @@ export default class CommunityTimeline extends React.PureComponent { dispatch(expandCommunityTimeline({ maxId, onlyMedia })); } - handleHeadlineLinkClick = e => { - const { columnId, dispatch } = this.props; - const onlyMedia = /\/media$/.test(e.currentTarget.href); - - dispatch(changeColumnParams(columnId, { other: { onlyMedia } })); - } - render () { const { intl, hasUnread, columnId, multiColumn, onlyMedia } = this.props; const pinned = !!columnId; - const headline = ( - - ); - return ( - + +
+ +
+
+ ); + } + +} diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js index 83f2f4d34..6eb01123e 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ b/app/javascript/mastodon/features/compose/components/compose_form.js @@ -127,9 +127,7 @@ export default class ComposeForm extends ImmutablePureComponent { this.autosuggestTextarea.textarea.focus(); } else if(prevProps.is_submitting && !this.props.is_submitting) { this.autosuggestTextarea.textarea.focus(); - } - - if (this.props.spoiler !== prevProps.spoiler) { + } else if (this.props.spoiler !== prevProps.spoiler) { if (this.props.spoiler) { this.spoilerText.focus(); } else { diff --git a/app/javascript/mastodon/features/compose/components/navigation_bar.js b/app/javascript/mastodon/features/compose/components/navigation_bar.js index 3014c4033..9910eb4f9 100644 --- a/app/javascript/mastodon/features/compose/components/navigation_bar.js +++ b/app/javascript/mastodon/features/compose/components/navigation_bar.js @@ -1,9 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; +import ActionBar from './action_bar'; import Avatar from '../../../components/avatar'; -import IconButton from '../../../components/icon_button'; import Permalink from '../../../components/permalink'; +import IconButton from '../../../components/icon_button'; import { FormattedMessage } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; @@ -30,7 +31,10 @@ export default class NavigationBar extends ImmutablePureComponent {
- +
+ + +
); } diff --git a/app/javascript/mastodon/features/direct_timeline/components/column_settings.js b/app/javascript/mastodon/features/direct_timeline/components/column_settings.js new file mode 100644 index 000000000..a992b27bb --- /dev/null +++ b/app/javascript/mastodon/features/direct_timeline/components/column_settings.js @@ -0,0 +1,35 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import SettingText from '../../../components/setting_text'; + +const messages = defineMessages({ + filter_regex: { id: 'home.column_settings.filter_regex', defaultMessage: 'Filter out by regular expressions' }, + settings: { id: 'home.settings', defaultMessage: 'Column settings' }, +}); + +@injectIntl +export default class ColumnSettings extends React.PureComponent { + + static propTypes = { + settings: ImmutablePropTypes.map.isRequired, + onChange: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, + }; + + render () { + const { settings, onChange, intl } = this.props; + + return ( +
+ + +
+ +
+
+ ); + } + +} diff --git a/app/javascript/mastodon/features/direct_timeline/containers/column_settings_container.js b/app/javascript/mastodon/features/direct_timeline/containers/column_settings_container.js index 1833f69e5..38054ce9e 100644 --- a/app/javascript/mastodon/features/direct_timeline/containers/column_settings_container.js +++ b/app/javascript/mastodon/features/direct_timeline/containers/column_settings_container.js @@ -1,5 +1,5 @@ import { connect } from 'react-redux'; -import ColumnSettings from '../../community_timeline/components/column_settings'; +import ColumnSettings from '../components/column_settings'; import { changeSetting } from '../../../actions/settings'; const mapStateToProps = state => ({ diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js index 115dfd2b9..34c7a4298 100644 --- a/app/javascript/mastodon/features/getting_started/index.js +++ b/app/javascript/mastodon/features/getting_started/index.js @@ -7,7 +7,7 @@ import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; -import { me } from '../../initial_state'; +import { me, invitesEnabled } from '../../initial_state'; import { fetchFollowRequests } from '../../actions/accounts'; import { List as ImmutableList } from 'immutable'; import { Link } from 'react-router-dom'; @@ -95,7 +95,7 @@ export default class GettingStarted extends ImmutablePureComponent { navItems.push( , , - + ); height += 48*3; @@ -135,9 +135,13 @@ export default class GettingStarted extends ImmutablePureComponent {
    +
  • ·
  • + {invitesEnabled &&
  • ·
  • } {multiColumn &&
  • ·
  • } +
  • ·
  • ·
  • ·
  • +
  • ·
  • ·
diff --git a/app/javascript/mastodon/features/list_timeline/index.js b/app/javascript/mastodon/features/list_timeline/index.js index 9a1e3c6d6..f08e77b7a 100644 --- a/app/javascript/mastodon/features/list_timeline/index.js +++ b/app/javascript/mastodon/features/list_timeline/index.js @@ -138,7 +138,7 @@ export default class ListTimeline extends React.PureComponent { return ( + @@ -66,7 +66,7 @@ export default class Lists extends ImmutablePureComponent { {lists.map(list => - + )}
diff --git a/app/javascript/mastodon/features/public_timeline/containers/column_settings_container.js b/app/javascript/mastodon/features/public_timeline/containers/column_settings_container.js index 203e1da92..c56caa59e 100644 --- a/app/javascript/mastodon/features/public_timeline/containers/column_settings_container.js +++ b/app/javascript/mastodon/features/public_timeline/containers/column_settings_container.js @@ -1,17 +1,28 @@ import { connect } from 'react-redux'; import ColumnSettings from '../../community_timeline/components/column_settings'; import { changeSetting } from '../../../actions/settings'; +import { changeColumnParams } from '../../../actions/columns'; -const mapStateToProps = state => ({ - settings: state.getIn(['settings', 'public']), -}); +const mapStateToProps = (state, { columnId }) => { + const uuid = columnId; + const columns = state.getIn(['settings', 'columns']); + const index = columns.findIndex(c => c.get('uuid') === uuid); -const mapDispatchToProps = dispatch => ({ + return { + settings: (uuid && index >= 0) ? columns.get(index).get('params') : state.getIn(['settings', 'public']), + }; +}; - onChange (key, checked) { - dispatch(changeSetting(['public', ...key], checked)); - }, - -}); +const mapDispatchToProps = (dispatch, { columnId }) => { + return { + onChange (key, checked) { + if (columnId) { + dispatch(changeColumnParams(columnId, key, checked)); + } else { + dispatch(changeSetting(['public', ...key], checked)); + } + }, + }; +}; export default connect(mapStateToProps, mapDispatchToProps)(ColumnSettings); diff --git a/app/javascript/mastodon/features/public_timeline/index.js b/app/javascript/mastodon/features/public_timeline/index.js index 341af582a..2d5bb3baf 100644 --- a/app/javascript/mastodon/features/public_timeline/index.js +++ b/app/javascript/mastodon/features/public_timeline/index.js @@ -6,23 +6,33 @@ import StatusListContainer from '../ui/containers/status_list_container'; import Column from '../../components/column'; import ColumnHeader from '../../components/column_header'; import { expandPublicTimeline } from '../../actions/timelines'; -import { addColumn, removeColumn, moveColumn, changeColumnParams } from '../../actions/columns'; +import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; import ColumnSettingsContainer from './containers/column_settings_container'; -import SectionHeadline from '../community_timeline/components/section_headline'; import { connectPublicStream } from '../../actions/streaming'; const messages = defineMessages({ title: { id: 'column.public', defaultMessage: 'Federated timeline' }, }); -const mapStateToProps = (state, { onlyMedia }) => ({ - hasUnread: state.getIn(['timelines', `public${onlyMedia ? ':media' : ''}`, 'unread']) > 0, -}); +const mapStateToProps = (state, { onlyMedia, columnId }) => { + const uuid = columnId; + const columns = state.getIn(['settings', 'columns']); + const index = columns.findIndex(c => c.get('uuid') === uuid); + + return { + hasUnread: state.getIn(['timelines', `public${onlyMedia ? ':media' : ''}`, 'unread']) > 0, + onlyMedia: (columnId && index >= 0) ? columns.get(index).getIn(['params', 'other', 'onlyMedia']) : state.getIn(['settings', 'public', 'other', 'onlyMedia']), + }; +}; @connect(mapStateToProps) @injectIntl export default class PublicTimeline extends React.PureComponent { + static contextTypes = { + router: PropTypes.object, + }; + static defaultProps = { onlyMedia: false, }; @@ -89,27 +99,17 @@ export default class PublicTimeline extends React.PureComponent { dispatch(expandPublicTimeline({ maxId, onlyMedia })); } - handleHeadlineLinkClick = e => { - const { columnId, dispatch } = this.props; - const onlyMedia = /\/media$/.test(e.currentTarget.href); - - dispatch(changeColumnParams(columnId, { other: { onlyMedia } })); + handleSettingChanged = (key, checked) => { + const { columnId } = this.props; + if (!columnId && key[0] === 'other' && key[1] === 'onlyMedia') { + this.context.router.history.replace(`/timelines/public${checked ? '/media' : ''}`); + } } render () { const { intl, columnId, hasUnread, multiColumn, onlyMedia } = this.props; const pinned = !!columnId; - const headline = ( - - ); - return ( - + { .set('saved', false); }; -const changeColumnParams = (state, uuid, params) => { +const changeColumnParams = (state, uuid, path, value) => { const columns = state.get('columns'); const index = columns.findIndex(item => item.get('uuid') === uuid); - const newColumns = columns.update(index, column => column.update('params', () => fromJS(params))); + const newColumns = columns.update(index, column => column.updateIn(['params', ...path], () => value)); return state .set('columns', newColumns) @@ -127,7 +127,7 @@ export default function settings(state = initialState, action) { case COLUMN_MOVE: return moveColumn(state, action.uuid, action.direction); case COLUMN_PARAMS_CHANGE: - return changeColumnParams(state, action.uuid, action.params); + return changeColumnParams(state, action.uuid, action.path, action.value); case EMOJI_USE: return updateFrequentEmojis(state, action.emoji); case SETTING_SAVE: diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss index fad7feb98..84ccd326e 100644 --- a/app/javascript/styles/mastodon-light/diff.scss +++ b/app/javascript/styles/mastodon-light/diff.scss @@ -25,33 +25,51 @@ background: $ui-base-color url('data:image/svg+xml;utf8,') no-repeat bottom / 100% auto; } -.compose-form .compose-form__modifiers .compose-form__upload__actions .icon-button { - color: lighten($white, 7%); +// Change the colors used in compose-form +.compose-form { + .compose-form__modifiers { + .compose-form__upload__actions .icon-button { + color: lighten($white, 7%); - &:active, - &:focus, - &:hover { - color: $white; + &:active, + &:focus, + &:hover { + color: $white; + } + } + + .compose-form__upload-description input { + color: lighten($white, 7%); + + &::placeholder { + color: lighten($white, 7%); + } + } } -} -.compose-form .compose-form__modifiers .compose-form__upload-description input { - color: lighten($white, 7%); - - &::placeholder { - color: lighten($white, 7%); + .compose-form__buttons-wrapper { + background: darken($ui-base-color, 6%); } -} -.compose-form .compose-form__buttons-wrapper { - background: darken($ui-base-color, 6%); + .autosuggest-textarea__suggestions { + background: darken($ui-base-color, 6%); + } + + .autosuggest-textarea__suggestions__item { + &:hover, + &:focus, + &:active, + &.selected { + background: lighten($ui-base-color, 4%); + } + } } .emoji-mart-bar { - border-color: lighten($ui-base-color, 8%); + border-color: lighten($ui-base-color, 4%); &:first-child { - background: $ui-base-color; + background: darken($ui-base-color, 6%); } } @@ -60,6 +78,7 @@ border-color: $ui-base-color; } +// Change the background colors of statuses .focusable:focus { background: $ui-base-color; } @@ -77,7 +96,7 @@ background: darken($ui-base-color, 6%); } -// Change the background color of status__content__spoiler-link +// Change the background colors of status__content__spoiler-link .reply-indicator__content .status__content__spoiler-link, .status__content .status__content__spoiler-link { background: $ui-base-lighter-color; @@ -87,8 +106,7 @@ } } -// Change the background colors of media and video spoiler - +// Change the background colors of media and video spoilers .media-spoiler, .video-player__spoiler { background: $ui-base-color; @@ -101,30 +119,30 @@ // Change the colors used in the dropdown menu .dropdown-menu { background: $ui-base-color; -} -.dropdown-menu__arrow { - &.left { - border-left-color: $ui-base-color; + &__arrow { + &.left { + border-left-color: $ui-base-color; + } + + &.top { + border-top-color: $ui-base-color; + } + + &.bottom { + border-bottom-color: $ui-base-color; + } + + &.right { + border-right-color: $ui-base-color; + } } - &.top { - border-top-color: $ui-base-color; - } - - &.bottom { - border-bottom-color: $ui-base-color; - } - - &.right { - border-right-color: $ui-base-color; - } -} - -.dropdown-menu__item { - a { - background: $ui-base-color; - color: $darker-text-color; + &__item { + a { + background: $ui-base-color; + color: $darker-text-color; + } } } diff --git a/app/javascript/styles/mastodon/accounts.scss b/app/javascript/styles/mastodon/accounts.scss index 3ccce383b..14dc5dd62 100644 --- a/app/javascript/styles/mastodon/accounts.scss +++ b/app/javascript/styles/mastodon/accounts.scss @@ -458,23 +458,31 @@ } .account-card { - padding: 14px 10px; - background: $simple-background-color; border-radius: 4px; text-align: left; box-shadow: 0 0 15px rgba($base-shadow-color, 0.2); + background: $simple-background-color; - .detailed-status__display-name { + &__header { + background-size: cover; + background-position: center center; + height: 90px; + border-radius: 4px 4px 0 0; + } + + & > .detailed-status__display-name { display: block; overflow: hidden; - margin-bottom: 15px; + display: flex; + align-items: center; + padding: 10px; &:last-child { margin-bottom: 0; } - & > div { - float: left; + & > div:first-child { + flex: 0 0 auto; margin-right: 10px; width: 48px; height: 48px; @@ -483,9 +491,11 @@ .avatar { display: block; border-radius: 4px; + margin: 0; } .display-name { + flex: 1 0 auto; display: block; max-width: 100%; overflow: hidden; @@ -493,6 +503,10 @@ text-overflow: ellipsis; cursor: default; + & > .detailed-status__display-name { + margin-bottom: 0; + } + strong { font-weight: 500; color: $ui-base-color; @@ -519,9 +533,28 @@ } } - .account__header__content { - font-size: 14px; - color: $inverted-text-color; + .counter { + box-sizing: border-box; + flex: 0 0 auto; + color: $light-text-color; + padding: 0 10px; + cursor: default; + text-align: center; + position: relative; + line-height: 24px; + + .counter-label { + font-size: 12px; + display: block; + text-transform: uppercase; + } + + .counter-number { + font-weight: 500; + font-size: 16px; + color: $inverted-text-color; + font-family: 'mastodon-font-display', sans-serif; + } } } diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index cb790ac05..28daac6a3 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -1211,6 +1211,10 @@ a .account__avatar { flex: 0 1 calc(50% - 140px); padding: 10px; + .icon-button { + vertical-align: middle; + } + .dropdown--active { .dropdown__content.dropdown__right { left: 6px; @@ -1230,13 +1234,14 @@ a .account__avatar { display: flex; flex: 1 1 auto; line-height: 18px; + text-align: center; } .account__action-bar__tab { text-decoration: none; overflow: hidden; flex: 0 1 80px; - border-left: 1px solid lighten($ui-base-color, 8%); + border-right: 1px solid lighten($ui-base-color, 8%); padding: 10px 5px; & > span { @@ -1494,6 +1499,7 @@ a.account__display-name { .navigation-bar { padding: 10px; display: flex; + align-items: center; flex-shrink: 0; cursor: default; color: $darker-text-color; @@ -1510,15 +1516,29 @@ a.account__display-name { text-decoration: none; } - .icon-button { - pointer-events: none; - opacity: 0; + .navigation-bar__actions { + position: relative; + + .icon-button.close { + position: absolute; + pointer-events: none; + transform: scale(0.0, 1.0) translate(-100%, 0); + opacity: 0; + } + + .compose__action-bar .icon-button { + pointer-events: auto; + transform: scale(1.0, 1.0) translate(0, 0); + opacity: 1; + } } } .navigation-bar__profile { flex: 1 1 auto; margin-left: 8px; + line-height: 20px; + margin-top: -1px; overflow: hidden; } @@ -4794,8 +4814,6 @@ a.status-card { } } -.community-timeline__section-headline, -.public-timeline__section-headline, .account__section-headline { background: darken($ui-base-color, 4%); border-bottom: 1px solid lighten($ui-base-color, 8%); @@ -4923,8 +4941,8 @@ noscript { .navigation-bar { & > a:first-child { - will-change: margin-top, margin-left, width; - transition: margin-top $duration $delay, margin-left $duration ($duration + $delay); + will-change: margin-top, margin-left, margin-right, width; + transition: margin-top $duration $delay, margin-left $duration ($duration + $delay), margin-right $duration ($duration + $delay); } & > .navigation-bar__profile-edit { @@ -4932,9 +4950,18 @@ noscript { transition: margin-top $duration $delay; } - & > .icon-button { - will-change: opacity; - transition: opacity $duration $delay; + .navigation-bar__actions { + & > .icon-button.close { + will-change: opacity transform; + transition: opacity $duration * 0.5 $delay, + transform $duration $delay; + } + + & > .compose__action-bar .icon-button { + will-change: opacity transform; + transition: opacity $duration * 0.5 $delay + $duration * 0.5, + transform $duration $delay; + } } } @@ -4948,8 +4975,7 @@ noscript { padding-bottom: 0; & > a:first-child { - margin-top: -50px; - margin-left: -40px; + margin: -100px 10px 0 -50px; } .navigation-bar__profile { @@ -4958,12 +4984,22 @@ noscript { .navigation-bar__profile-edit { position: absolute; - margin-top: -50px; + margin-top: -60px; } - .icon-button { - pointer-events: auto; - opacity: 1; + .navigation-bar__actions { + .icon-button.close { + pointer-events: auto; + opacity: 1; + transform: scale(1.0, 1.0) translate(0, 0); + bottom: 5px; + } + + .compose__action-bar .icon-button { + pointer-events: none; + opacity: 0; + transform: scale(0.0, 1.0) translate(100%, 0); + } } } } diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index de16784a8..f1ed2c90b 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -140,6 +140,8 @@ code { } .input.with_block_label { + padding-top: 15px; + & > label { font-family: inherit; font-size: 16px; diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb index a82f8974b..833959397 100644 --- a/app/lib/user_settings_decorator.rb +++ b/app/lib/user_settings_decorator.rb @@ -19,6 +19,7 @@ class UserSettingsDecorator user.settings['interactions'] = merged_interactions if change?('interactions') user.settings['default_privacy'] = default_privacy_preference if change?('setting_default_privacy') user.settings['default_sensitive'] = default_sensitive_preference if change?('setting_default_sensitive') + user.settings['default_language'] = default_language_preference if change?('setting_default_language') user.settings['unfollow_modal'] = unfollow_modal_preference if change?('setting_unfollow_modal') user.settings['boost_modal'] = boost_modal_preference if change?('setting_boost_modal') user.settings['delete_modal'] = delete_modal_preference if change?('setting_delete_modal') @@ -87,6 +88,10 @@ class UserSettingsDecorator settings['setting_theme'] end + def default_language_preference + settings['setting_default_language'] + end + def boolean_cast_setting(key) ActiveModel::Type::Boolean.new.cast(settings[key]) end diff --git a/app/models/account.rb b/app/models/account.rb index 72e850aa7..c3eea79cc 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -141,7 +141,7 @@ class Account < ApplicationRecord prefix: true, allow_nil: true - delegate :filtered_languages, to: :user, prefix: false, allow_nil: true + delegate :chosen_languages, to: :user, prefix: false, allow_nil: true def local? domain.nil? diff --git a/app/models/concerns/attachmentable.rb b/app/models/concerns/attachmentable.rb index 6f8489b89..db63c3eca 100644 --- a/app/models/concerns/attachmentable.rb +++ b/app/models/concerns/attachmentable.rb @@ -41,7 +41,9 @@ module Attachmentable extensions_for_mime_type = mime_type.empty? ? [] : mime_type.first.extensions original_extension = Paperclip::Interpolations.extension(attachment, :original) + proper_extension = extensions_for_mime_type.first.to_s + proper_extension = 'jpeg' if proper_extension == 'jpe' - extensions_for_mime_type.include?(original_extension) ? original_extension : extensions_for_mime_type.first + extensions_for_mime_type.include?(original_extension) ? original_extension : proper_extension end end diff --git a/app/models/invite.rb b/app/models/invite.rb index 2250e588e..d0cc427c4 100644 --- a/app/models/invite.rb +++ b/app/models/invite.rb @@ -11,6 +11,7 @@ # uses :integer default(0), not null # created_at :datetime not null # updated_at :datetime not null +# autofollow :boolean default(FALSE), not null # class Invite < ApplicationRecord diff --git a/app/models/status.rb b/app/models/status.rb index 7fa069083..e7dd0df29 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -190,8 +190,8 @@ class Status < ApplicationRecord before_validation :set_local class << self - def not_in_filtered_languages(account) - where(language: nil).or where.not(language: account.filtered_languages) + def in_chosen_languages(account) + where(language: nil).or where(language: account.chosen_languages) end def as_home_timeline(account) @@ -333,7 +333,7 @@ class Status < ApplicationRecord def filter_timeline_for_account(query, account, local_only) query = query.not_excluded_by_account(account) query = query.not_domain_blocked_by_account(account) unless local_only - query = query.not_in_filtered_languages(account) if account.filtered_languages.present? + query = query.in_chosen_languages(account) if account.chosen_languages.present? query.merge(account_silencing_filter(account)) end diff --git a/app/models/user.rb b/app/models/user.rb index 0becfa7e9..c820c553a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -35,6 +35,7 @@ # moderator :boolean default(FALSE), not null # invite_id :bigint(8) # remember_token :string +# chosen_languages :string is an Array # class User < ApplicationRecord @@ -88,7 +89,7 @@ class User < ApplicationRecord delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :delete_modal, :reduce_motion, :system_font_ui, :noindex, :theme, :display_sensitive_media, :hide_network, - to: :settings, prefix: :setting, allow_nil: false + :default_language, to: :settings, prefix: :setting, allow_nil: false attr_accessor :invite_code @@ -317,7 +318,9 @@ class User < ApplicationRecord private def sanitize_languages - filtered_languages.reject!(&:blank?) + return if chosen_languages.nil? + chosen_languages.reject!(&:blank?) + self.chosen_languages = nil if chosen_languages.empty? end def prepare_new_user! diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb index ddafb540d..82b7ffe95 100644 --- a/app/serializers/activitypub/note_serializer.rb +++ b/app/serializers/activitypub/note_serializer.rb @@ -1,12 +1,15 @@ # frozen_string_literal: true class ActivityPub::NoteSerializer < ActiveModel::Serializer - attributes :id, :type, :summary, :content, + attributes :id, :type, :summary, :in_reply_to, :published, :url, :attributed_to, :to, :cc, :sensitive, :atom_uri, :in_reply_to_atom_uri, :conversation + attribute :content + attribute :content_map, if: :language? + has_many :media_attachments, key: :attachment has_many :virtual_tags, key: :tag @@ -26,6 +29,14 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer Formatter.instance.format(object) end + def content_map + { object.language => Formatter.instance.format(object) } + end + + def language? + object.language.present? + end + def in_reply_to return unless object.reply? && !object.thread.nil? diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index 6c9fba2f5..42d0e4bf3 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -14,6 +14,7 @@ class InitialStateSerializer < ActiveModel::Serializer domain: Rails.configuration.x.local_domain, admin: object.admin&.id&.to_s, search_enabled: Chewy.enabled?, + invites_enabled: Setting.min_invite_role == 'user', } if object.current_account diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb index 6adcd7039..3a724aa7c 100644 --- a/app/serializers/rest/account_serializer.rb +++ b/app/serializers/rest/account_serializer.rb @@ -25,7 +25,7 @@ class REST::AccountSerializer < ActiveModel::Serializer end def note - Formatter.instance.simplified_format(object, custom_emojify: true) + Formatter.instance.simplified_format(object) end def url diff --git a/app/serializers/rest/credential_account_serializer.rb b/app/serializers/rest/credential_account_serializer.rb index 56857cba8..fb195eb07 100644 --- a/app/serializers/rest/credential_account_serializer.rb +++ b/app/serializers/rest/credential_account_serializer.rb @@ -9,6 +9,7 @@ class REST::CredentialAccountSerializer < REST::AccountSerializer { privacy: user.setting_default_privacy, sensitive: user.setting_default_sensitive, + language: user.setting_default_language, note: object.note, fields: object.fields.map(&:to_h), } diff --git a/app/services/bootstrap_timeline_service.rb b/app/services/bootstrap_timeline_service.rb index c01e25824..db2c83e5d 100644 --- a/app/services/bootstrap_timeline_service.rb +++ b/app/services/bootstrap_timeline_service.rb @@ -2,13 +2,25 @@ class BootstrapTimelineService < BaseService def call(source_account) - bootstrap_timeline_accounts.each do |target_account| - FollowService.new.call(source_account, target_account) - end + @source_account = source_account + + autofollow_inviter! + autofollow_bootstrap_timeline_accounts! end private + def autofollow_inviter! + return unless @source_account&.user&.invite&.autofollow? + FollowService.new.call(@source_account, @source_account.user.invite.user.account) + end + + def autofollow_bootstrap_timeline_accounts! + bootstrap_timeline_accounts.each do |target_account| + FollowService.new.call(@source_account, target_account) + end + end + def bootstrap_timeline_accounts return @bootstrap_timeline_accounts if defined?(@bootstrap_timeline_accounts) diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index d072e581d..735985725 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -22,7 +22,6 @@ class PostStatusService < BaseService media = validate_media!(options[:media_ids]) status = nil text = options.delete(:spoiler_text) if text.blank? && options[:spoiler_text].present? - text = '.' if text.blank? && media.present? ApplicationRecord.transaction do status = account.statuses.create!(text: text, @@ -31,7 +30,7 @@ class PostStatusService < BaseService sensitive: (options[:sensitive].nil? ? account.user&.setting_default_sensitive : options[:sensitive]) || options[:spoiler_text].present?, spoiler_text: options[:spoiler_text] || '', visibility: options[:visibility] || account.user&.setting_default_privacy, - language: language_from_option(options[:language]) || LanguageDetector.instance.detect(text, account), + language: language_from_option(options[:language]) || account.user&.setting_default_language&.presence || LanguageDetector.instance.detect(text, account), application: options[:application]) end diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml index 2d4c0f5ac..0fac8e10d 100644 --- a/app/views/auth/registrations/new.html.haml +++ b/app/views/auth/registrations/new.html.haml @@ -7,6 +7,11 @@ = simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| = render 'shared/error_messages', object: resource + - if @invite.present? && @invite.autofollow? + .fields-group{ style: 'margin-bottom: 30px' } + %p.hint{ style: 'text-align: center' }= t('invites.invited_by') + = render 'authorize_follows/card', account: @invite.user.account + = f.simple_fields_for :account do |ff| .input-with-append = ff.input :username, autofocus: true, placeholder: t('simple_form.labels.defaults.username'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off' } diff --git a/app/views/authorize_follows/_card.html.haml b/app/views/authorize_follows/_card.html.haml index 9abcfd37e..edc03131f 100644 --- a/app/views/authorize_follows/_card.html.haml +++ b/app/views/authorize_follows/_card.html.haml @@ -1,4 +1,5 @@ .account-card + .account-card__header{ style: "background-image: url(#{account.header.url(:original)})" } .detailed-status__display-name %div = image_tag account.avatar.url(:original), alt: '', width: 48, height: 48, class: 'avatar' @@ -9,5 +10,14 @@ %strong.emojify= display_name(account, custom_emojify: true) %span @#{account.acct} - - if account.note? - .account__header__content.emojify= Formatter.instance.simplified_format(account) + .counter + %span.counter-number= number_to_human account.statuses_count, strip_insignificant_zeros: true + %span.counter-label= t('accounts.posts') + + .counter + %span.counter-number= number_to_human account.following_count, strip_insignificant_zeros: true + %span.counter-label= t('accounts.following') + + .counter + %span.counter-number= number_to_human account.followers_count, strip_insignificant_zeros: true + %span.counter-label= t('accounts.followers') diff --git a/app/views/invites/_form.html.haml b/app/views/invites/_form.html.haml index 3f0871f47..42a107bb2 100644 --- a/app/views/invites/_form.html.haml +++ b/app/views/invites/_form.html.haml @@ -5,5 +5,8 @@ = f.input :max_uses, wrapper: :with_label, collection: [1, 5, 10, 25, 50, 100], label_method: lambda { |num| I18n.t('invites.max_uses', count: num) }, prompt: I18n.t('invites.max_uses_prompt') = f.input :expires_in, wrapper: :with_label, collection: [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].map(&:to_i), label_method: lambda { |i| I18n.t("invites.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt') + .fields-group + = f.input :autofollow, wrapper: :with_label + .actions = f.button :button, t('invites.generate'), type: :submit diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml index d2e866373..43430069f 100644 --- a/app/views/settings/preferences/show.html.haml +++ b/app/views/settings/preferences/show.html.haml @@ -12,7 +12,9 @@ .fields-group = f.input :locale, collection: I18n.available_locales, wrapper: :with_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, selected: I18n.locale - = f.input :filtered_languages, collection: filterable_languages, wrapper: :with_block_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + = f.input :setting_default_language, collection: [nil] + filterable_languages.sort, wrapper: :with_label, label_method: lambda { |locale| locale.nil? ? I18n.t('statuses.language_detection') : human_locale(locale) }, required: false, include_blank: false + + = f.input :chosen_languages, collection: filterable_languages.sort, wrapper: :with_block_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' %h4= t 'preferences.publishing' diff --git a/config/initializers/timeout.rb b/config/initializers/timeout.rb deleted file mode 100644 index de87fd906..000000000 --- a/config/initializers/timeout.rb +++ /dev/null @@ -1,6 +0,0 @@ -Rack::Timeout::Logger.disable -Rack::Timeout.service_timeout = false - -if Rails.env.production? - Rack::Timeout.service_timeout = 90 -end diff --git a/config/initializers/twitter_regex.rb b/config/initializers/twitter_regex.rb index 7fa828300..c227f92d3 100644 --- a/config/initializers/twitter_regex.rb +++ b/config/initializers/twitter_regex.rb @@ -30,7 +30,7 @@ module Twitter ( # $1 total match (#{REGEXEN[:valid_url_preceding_chars]}) # $2 Preceeding chracter ( # $3 URL - (https?:\/\/)? # $4 Protocol (optional) + ((https?|dat|dweb|ipfs|ipns|ssb|gopher):\/\/)? # $4 Protocol (optional) (#{REGEXEN[:valid_domain]}) # $5 Domain(s) (?::(#{REGEXEN[:valid_port_number]}))? # $6 Port number (optional) (/#{REGEXEN[:valid_url_path]}*)? # $7 URL Path and anchor diff --git a/config/locales/ar.yml b/config/locales/ar.yml index ad194a17c..bea04e942 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -426,7 +426,7 @@ ar: following: 'مرحى ! أنت الآن تتبع :' post_follow: close: أو يمكنك إغلاق هذه النافذة. - return: العودة إلى الملف الشخصي للمستخدم + return: عرض الملف الشخصي للمستخدم web: واصل إلى الويب title: إتباع %{acct} datetime: @@ -455,6 +455,7 @@ ar: '422': content: فشل التحقق الآمن. ربما منعتَ كعكات الكوكيز ؟ title: فشِل التحقق الآمن + '429': طلبات كثيرة جدا '500': content: نحن متأسفون، لقد حدث خطأ ما مِن جانبنا. title: هذه الصفحة خاطئة @@ -476,6 +477,9 @@ ar: followers_count: عدد المتابِعين lock_link: قم بتجميد حسابك purge: تنحية من بين متابعيك + success: + one: جارية عملية حظر المتابِعين بسلاسة من نطاق آخر ... + other: جارية عملية حظر المتابِعين بسلاسة من %{count} نطاقات أخرى ... unlocked_warning_title: إنّ حسابك غير مقفل generic: changes_saved_msg: تم حفظ التعديلات بنجاح ! @@ -504,6 +508,7 @@ ar: '86400': يوم واحد expires_in_prompt: أبدا generate: توليد + invited_by: 'تمت دعوتك من طرف :' max_uses: one: إستعمال واحد other: "%{count} استخدامات" @@ -589,7 +594,8 @@ ar: prompt: 'إنك بصدد متابعة :' remote_unfollow: error: خطأ - title: '' + title: العنوان + unfollowed: غير متابَع sessions: activity: آخر نشاط browser: المتصفح @@ -603,6 +609,7 @@ ar: generic: متصفح مجهول ie: إنترنت إكسبلورر micro_messenger: مايكرو ميسنجر + nokia: متصفح Nokia S40 Ovi opera: أوبرا otter: أوتر phantom_js: فانتوم جي آس @@ -647,17 +654,22 @@ ar: your_apps: تطبيقاتك statuses: attached: + description: 'مُرفَق : %{attached}' image: - one: '' - other: '' + one: "%{count} صورة" + other: "%{count} صور" video: - one: '' - other: '' - content_warning: '' + one: "%{count} فيديو" + other: "%{count} فيديوهات" + content_warning: 'تحذير عن المحتوى : %{warning}' + disallowed_hashtags: + one: 'يحتوي على وسم ممنوع : %{tags}' + other: 'يحتوي على وسوم ممنوعة : %{tags}' + language_detection: اكتشاف اللغة تلقائيا open_in_web: إفتح في الويب over_character_limit: تم تجاوز حد الـ %{max} حرف المسموح بها pin_errors: - limit: '' + limit: لقد بلغت الحد الأقصى للتبويقات المدبسة ownership: لا يمكن تدبيس تبويق نشره شخص آخر private: لا يمكن تثبيت تبويق لم يُنشر للعامة reblog: لا يمكن تثبيت ترقية @@ -678,7 +690,9 @@ ar: terms: title: شروط الخدمة وسياسة الخصوصية على %{instance} themes: + contrast: تباين عالٍ default: ماستدون + mastodon-light: ماستدون (فاتح) time: formats: default: "%b %d, %Y, %H:%M" @@ -702,15 +716,17 @@ ar: subject: نسخة بيانات حسابك جاهزة للتنزيل title: المغادرة بأرشيف الحساب welcome: - edit_profile_action: '' - explanation: '' - full_handle: '' - review_preferences_action: '' - subject: '' + edit_profile_action: تهيئة الملف الشخصي + explanation: ها هي بعض النصائح قبل بداية الإستخدام + final_action: اشرَع في النشر + full_handle: عنوانك الكامل + review_preferences_action: تعديل التفضيلات + subject: أهلًا بك على ماستدون tips: نصائح title: أهلاً بك، %{name} ! users: invalid_email: عنوان البريد الإلكتروني غير صالح invalid_otp_token: رمز المصادقة بخطوتين غير صالح + otp_lost_help_html: إن فقدتَهُما ، يمكنك الإتصال بـ %{email} seamless_external_login: لقد قمت بتسجيل الدخول عبر خدمة خارجية، إنّ إعدادات الكلمة السرية و البريد الإلكتروني غير متوفرة. signed_in_as: 'تم تسجيل دخولك بصفة :' diff --git a/config/locales/ca.yml b/config/locales/ca.yml index e536ea8c3..3cd4281f0 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -514,6 +514,7 @@ ca: '86400': 1 dia expires_in_prompt: Mai generate: Genera + invited_by: 'Has estat invitat per:' max_uses: one: 1 ús other: "%{count} usos" @@ -674,6 +675,7 @@ ca: disallowed_hashtags: one: 'conté una etiqueta no permesa: %{tags}' other: 'conté les etiquetes no permeses: %{tags}' + language_detection: Detecta automàticament el llenguatge open_in_web: Obre en la web over_character_limit: Límit de caràcters de %{max} superat pin_errors: diff --git a/config/locales/de.yml b/config/locales/de.yml index fbd81b6eb..cd06ef0e6 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -283,7 +283,7 @@ de: create_and_resolve: Mit Kommentar lösen create_and_unresolve: Mit Kommentar wieder öffnen delete: Löschen - placeholder: Beschreibe, welche Maßnahmen ergriffen wurden oder andere Neuigkeiten zu dieser Meldung… + placeholder: Beschreibe, welche Maßnahmen ergriffen wurden oder irgendwelche andere Neuigkeiten… reopen: Meldung wieder öffnen report: 'Meldung #%{id}' report_contents: Inhalt @@ -424,7 +424,7 @@ de: following: 'Erfolg! Du folgst nun:' post_follow: close: Oder du schließt einfach dieses Fenster. - return: Zurück zum Profil dieses Wesens + return: Zeige Profil des Benutzers web: Das Web öffnen title: "%{acct} folgen" datetime: @@ -514,6 +514,7 @@ de: '86400': 1 Tag expires_in_prompt: Nie generate: Generieren + invited_by: 'Du wurdest eingeladen von:' max_uses: one: 1 mal verwendet other: "%{count} mal verwendet" @@ -550,7 +551,7 @@ de: subject: one: "1 neue Mitteilung seit deinem letzten Besuch \U0001F418" other: "%{count} neue Mitteilungen seit deinem letzten Besuch \U0001F418" - title: In deiner Abwesenheit… + title: In deiner Abwesenheit... favourite: body: 'Dein Beitrag wurde von %{name} favorisiert:' subject: "%{name} hat deinen Beitrag favorisiert" @@ -669,6 +670,7 @@ de: video: one: "%{count} Video" other: "%{count} Videos" + boosted_from_html: Geteilt von %{acct_link} content_warning: 'Inhaltswarnung: %{warning}' disallowed_hashtags: one: 'Enthält den unerlaubten Hashtag: %{tags}' @@ -699,6 +701,7 @@ de: themes: contrast: Hoher Kontrast default: Mastodon + mastodon-light: Mastodon (hell) time: formats: default: "%d.%m.%Y %H:%M" diff --git a/config/locales/devise.sk.yml b/config/locales/devise.sk.yml index 4bbc723e9..173622bc5 100644 --- a/config/locales/devise.sk.yml +++ b/config/locales/devise.sk.yml @@ -6,11 +6,11 @@ sk: send_instructions: O niekoľko minút obdržíte email s inštrukciami ako potvrdiť váš účet. send_paranoid_instructions: Ak sa váš email nachádza v našej databáze, obdržíte email s inštrukciami ako potvrdiť váš účet. failure: - already_authenticated: Už ste prihlásený/á. - inactive: Váš účet ešte nebol aktivovaný. - invalid: Nesprávny %{authentication_keys} alebo heslo. - last_attempt: Máte posledný pokus pred zamknutím vašeho účtu. - locked: Váš účet je zamknutý. + already_authenticated: Už si prihlásený/á. + inactive: Tvoj účet ešte nebol potvrdený. + invalid: Nesprávny %{authentication_keys}, alebo heslo. + last_attempt: Máš posledný pokus pred zamknutím tvojho účtu. + locked: Tvoj účet je zamknutý. not_found_in_database: Nesprávny %{authentication_keys} alebo heslo. timeout: Vaša aktívna sezóna vypršala. Pre pokračovanie sa prosím znovu prihláste. unauthenticated: K pokračovaniu sa musíš zaregistrovať alebo prihlásiť. @@ -52,11 +52,11 @@ sk: no_token: Túto stránku nemôžete navštíviť pokiaľ neprichádzate z emailu s inštrukciami na obnovu hesla. Pokiaľ prichádzate z tohto emailu, prosím uistite sa že ste použili celú URL z emailu. send_instructions: Ak zadaný email existuje v našej databázi, tak o niekoľko minút obdržíte email s inštrukciami ako nastaviť nové heslo. send_paranoid_instructions: Ak zadaný email existuje v našej databázi, zachvíľu obdržíte odkaz na obnovu hesla na svoj email. Skontrolujte aj spam ak tento email nevidíte. - updated: Vaše heslo bolo úspešne zmenené. Teraz ste prihlásený/á. - updated_not_active: Vaše heslo bolo úspešne zmenené. + updated: Tvoje heslo bolo úspešne zmenené. Teraz si prihlásený/á. + updated_not_active: Tvoje heslo bolo úspešne zmenené. registrations: - destroyed: Dovidenia! Váš účet bol úspešne zrušený. Dúfame ale, že sa tu opäť niekedy zastavíte. - signed_up: Vitajte! Vaša registrácia bola úspešná. + destroyed: Dovidenia! Tvoj účet bol úspešne zrušený. Dúfame ale, že ťa tu opäť niekedy uvidíme. + signed_up: Vitaj! Tvoja registrácia bola úspešná. signed_up_but_inactive: Registrácia bola úspešná. Avšak, účet ešte nebol aktivovaný, takže ťa nemôžeme prihlásiť. signed_up_but_locked: Prihlasovanie úspešné. Avšak tvoj účet je zamknutý, takže ťa nieje možné prihlásiť. signed_up_but_unconfirmed: Správa s odkazom potvrdzujúcim registráciu bola poslaná na váš email. Pre aktváciu účtu, kliknite na daný odkaz. diff --git a/config/locales/doorkeeper.de.yml b/config/locales/doorkeeper.de.yml index 670f5ec2a..cec4a586b 100644 --- a/config/locales/doorkeeper.de.yml +++ b/config/locales/doorkeeper.de.yml @@ -115,5 +115,6 @@ de: title: OAuth-Autorisierung nötig scopes: follow: Konten folgen, blocken, entblocken und entfolgen + push: erhalte Push-Benachrichtigungen von deinem Account read: deine Daten auslesen write: Beiträge in deinem Namen veröffentlichen diff --git a/config/locales/doorkeeper.fa.yml b/config/locales/doorkeeper.fa.yml index 2293f1115..e19126554 100644 --- a/config/locales/doorkeeper.fa.yml +++ b/config/locales/doorkeeper.fa.yml @@ -37,8 +37,8 @@ fa: index: application: برنامه callback_url: نشانی Callback - delete: Delete - name: Name + delete: حذف + name: نام new: برنامهٔ تازه scopes: دامنه‌ها show: نمایش diff --git a/config/locales/doorkeeper.sk.yml b/config/locales/doorkeeper.sk.yml index d90927189..b998d9c37 100644 --- a/config/locales/doorkeeper.sk.yml +++ b/config/locales/doorkeeper.sk.yml @@ -25,7 +25,7 @@ sk: edit: Upraviť submit: Poslať confirmations: - destroy: Ste si istý? + destroy: Si si istý/á? edit: title: Upraviť aplikáciu form: @@ -55,7 +55,7 @@ sk: authorizations: buttons: authorize: Overiť - deny: Zamietnuť + deny: Zamietni error: title: Nastala chyba new: @@ -115,6 +115,6 @@ sk: title: Požadovaná OAuth autorizácia scopes: follow: sledovať, blokovať, povoliť a zušiť sledovanie účtov - push: dostávaj oznámenia ohľadom tvojho účtu ako notifikácie na plochu - read: prezrieť dáta na vašom účete - write: poslať vo vašom mene + push: dostávaj oboznámenia ohľadom tvojho účtu ako notifikácie na plochu + read: prezrieť dáta svojho účetu + write: poslať v tvojom mene diff --git a/config/locales/el.yml b/config/locales/el.yml index 353e43732..e160396f3 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -221,7 +221,7 @@ el: suspend: Αναστολή title: Αποκλεισμός νέου τομέα reject_media: Απόρριψη πολυμέσων - reject_media_hint: Αφαιρεί τα τοπικά αποθηκευμένα αρχεία πολυμέσων και αποτρέπει το κατέβασμα άλλων στο μέλλον. Δεν έχει σημασία για τις αναστολές + reject_media_hint: Αφαιρεί τα τοπικά αποθηκευμένα αρχεία πολυμέσων και αποτρέπει τη λήψη άλλων στο μέλλον. Δεν έχει σημασία για τις αναστολές severities: noop: Κανένα silence: Αποσιώπηση @@ -444,11 +444,11 @@ el: deletes: bad_password_msg: Καλή προσπάθεια χάκερς! Λάθος συνθηματικό confirm_password: Γράψε το τρέχον συνθηματικό σου για να πιστοποιήσεις την ταυτότητά σου - description_html: Αυτό θα οριστικά και αμετάκλητα διαγράψει το περιεχόμενο του λογαριασμού σου και θα τον απενεργοποιήσει. Το όνομα χρήστη θα παραμείνει δεσμευμένο για να αποφευχθούν μελλοντικές πλαστοπροσωπίες. + description_html: Αυτό θα διαγράψει οριστικά και αμετάκλητα το περιεχόμενο του λογαριασμού σου και θα τον απενεργοποιήσει. Το όνομα χρήστη θα παραμείνει δεσμευμένο για να αποφευχθούν μελλοντικές πλαστοπροσωπίες. proceed: Διαγραφή λογαριασμού success_msg: Ο λογαριασμός σου διαγράφηκε με επιτυχία warning_html: Μόνο η διαγραφή περιεχομένου από αυτό τον συγκεκριμένο κόμβο είναι εγγυημένη. Το περιεχόμενο που έχει διαμοιραστεί ευρέως είναι πιθανό να αφήσει ίχνη. Όσοι διακομιστές είναι εκτός σύνδεσης και όσοι έχουν διακόψει τη λήψη των ενημερώσεων του κόμβου σου, δε θα ενημερώσουν τις βάσεις δεδομένων τους. - warning_title: Διαθεσιμότητα περιεχομένου προς διανομή + warning_title: Διαθεσιμότητα ήδη διανεμημένου περιεχομένου errors: '403': Δεν έχεις δικαίωμα πρόσβασης σε αυτή τη σελίδα. '404': Η σελίδα που ψάχνεις δεν υπάρχει. @@ -480,16 +480,273 @@ el: followers_count: Πλήθος ακολούθων lock_link: Κλείδωσε το λογαριασμό σου purge: Αφαίρεσε από ακόλουθο + success: + one: Ημι-μπλοκάροντας τους ακόλουθους από έναν τομέα... + other: Ημι-μπλοκάροντας τους ακόλουθους από %{count} τομείς... + true_privacy_html: Έχε υπ' όψιν σου πως η πραγματική ιδιωτικότητα επιτυγχάνεται μόνο με κρυπτογράφηση από άκρη σε άκρη. + unlocked_warning_html: Μπορεί ο οποιοσδήποτε να σε ακολουθήσει και να βλέπει κατευθείαν τις ιδιωτικές ενημερώσεις σου. %{lock_link} για να αναθεωρήσεις και απορρίψεις ακόλουθους. + unlocked_warning_title: Ο λογαριασμός σου δεν είναι κλειδωμένος + generic: + changes_saved_msg: Οι αλλαγές αποθηκεύτηκαν! + powered_by: παρέχεται από %{link} + save_changes: Αποθήκευσε αλλαγές + validation_errors: + one: Κάτι δεν είναι εντάξει ακόμα! Για κοίταξε το παρακάτω σφάλμα + other: Κάτι δεν είναι εντάξει ακόμα! Για κοίταξε τα παρακάτω %{count} σφάλματα imports: preface: Μπορείς να εισάγεις τα δεδομένα που έχεις εξάγει από άλλο κόμβο, όπως τη λίστα των ανθρώπων που ακολουθείς ή μπλοκάρεις. + success: Τα δεδομένα σου μεταφορτώθηκαν επιτυχώς και θα επεξεργαστούν εν καιρώ + types: + blocking: Λίστα αποκλεισμού + following: Λίστα ακολούθων + muting: Λίστα αποσιωπήσεων + upload: Ανέβασμα + in_memoriam_html: Εις μνήμην. invites: + delete: Απενεργοποίησε + expired: Ληγμένη + expires_in: + '1800': 30 λεπτά + '21600': 6 ώρες + '3600': 1 ώρα + '43200': 12 ώρες + '604800': 1 εβδομάδα + '86400': 1 μέρα + expires_in_prompt: Ποτέ + generate: Δημιούργησε + invited_by: 'Σε προσκάλεσε ο/η:' + max_uses: + one: 1 χρήσης + other: "%{count} χρήσεων" + max_uses_prompt: Απεριόριστη prompt: Φτιάξε και μοίρασε συνδέσμους με τρίτους για να δώσεις πρόσβαση σε αυτόν τον κόμβο + table: + expires_at: Λήγει + uses: Χρήσεις + title: Προσκάλεσε άτομα + landing_strip_html: Ο/Η %{name} είναι χρήστης στο %{link_to_root_path}. Μπορείς να ακολουθήσεις ή να αλληλεπιδράσεις μαζί τους αν έχεις λογαριασμό οπουδήποτε στο fediverse. + landing_strip_signup_html: Αν όχι, μπορείς να γραφτείς εδώ. + lists: + errors: + limit: Έχεις φτάσει το μέγιστο πλήθος επιτρεπτών λιστών + media_attachments: + validations: + images_and_video: Δεν γίνεται να προσθέσεις βίντεο σε ενημέρωση που ήδη περιέχει εικόνες + too_many: Δεν γίνεται να προσθέσεις περισσότερα από 4 αρχεία + migrations: + acct: ΌνομαΧρήστη@Τομέας του νέου λογαριασμού + currently_redirecting: 'Το προφίλ σου έχει ρυθμιστεί να ανακατευθύνει στο:' + proceed: Αποθήκευση + updated_msg: Οι ρυθμίσεις μετακόμισης του λογαριασμού σου ενημερώθηκαν! + moderation: + title: Συντονισμός + notification_mailer: + digest: + action: Δες όλες τις ειδοποιήσεις + body: Μια σύνοψη των μηνυμάτων που έχασες από την τελευταία επίσκεψή σου στις %{since} + mention: 'Ο/Η %{name} σε ανέφερε στις:' + new_followers_summary: + one: Επίσης, απέκτησες έναν νέο ακόλουθο ενώ ήσουν μακριά! + other: Επίσης, απέκτησες %{count} νέους ακόλουθους ενώ ήσουν μακριά! Εκπληκτικό! + subject: + one: "1 νέα ειδοποίηση από την τελευταία επίσκεψή σου \U0001F418" + other: "%{count} νέες ειδοποιήσεις από την τελευταία επίσκεψή σου \U0001F418" + title: Ενώ έλειπες... + favourite: + body: 'Η κατάστασή σου αγαπήθηκε από τον/την %{name}:' + subject: Ο/Η %{name} αγάπησε την κατάστασή σου + title: Νέο αγαπημένο + follow: + body: Ο/Η %{name} πλέον σε ακολουθεί! + subject: Ο/Η %{name} πλέον σε ακολουθεί + title: Νέος/α ακόλουθος + follow_request: + action: Διαχειρίσου τα αιτήματα παρακολούθησης + body: "%{name} αιτήθηκε να σε ακολουθήσει" + subject: 'Ακόλουθος που εκκρεμεί: %{name}' + title: Νέο αίτημα ακολούθησης + mention: + action: Απάντησε + body: 'Αναφέρθηκες από τον/την %{name} στο:' + subject: Αναφέρθηκες από τον/την %{name} + title: Νέα αναφορά + reblog: + body: 'Η κατάστασή σου προωθήθηκε από τον/την %{name}:' + subject: Ο/Η %{name} προώθησε την κατάστασή σου + title: Νέα προώθηση + number: + human: + decimal_units: + format: "%n%u" + units: + billion: Δις. + million: Εκ. + quadrillion: Τετρ. + thousand: Χ. + trillion: Τρις. + pagination: + newer: Νεότερο + next: Επόμενο + older: Παλιότερο + prev: Προηγούμενο + truncate: "…" + preferences: + languages: Γλώσσες + other: Άλλο + publishing: Δημοσίευση + web: Διαδίκτυο + remote_follow: + acct: Γράψε το ΌνομαΧρήστη@τομέας από όπου θέλεις να ακολουθήσεις + missing_resource: Δεν βρέθηκε το απαιτούμενο URL ανακατεύθυνσης για το λογαριασμό σου + proceed: Συνέχισε για να ακολουθήσεις + prompt: 'Θα ακολουθήσεις:' + remote_unfollow: + error: Σφάλμα + title: Τίτλος + unfollowed: Σταμάτησες να ακολουθείς + sessions: + activity: Τελευταία δραστηριότητα + browser: Φυλλομετρητής (Browser) + browsers: + alipay: Alipay + blackberry: Blackberry + chrome: Chrome + edge: Microsoft Edge + electron: Electron + firefox: Firefox + generic: Άγνωστος φυλλομετρητής + ie: Internet Explorer + micro_messenger: MicroMessenger + nokia: Nokia S40 Ovi Browser + opera: Opera + otter: Otter + phantom_js: PhantomJS + qq: QQ Browser + safari: Safari + uc_browser: UCBrowser + weibo: Weibo + current_session: Τρέχουσα σύνδεση + description: "%{browser} σε %{platform}" + explanation: Αυτοί είναι οι φυλλομετρητές (browsers) που είναι συνδεδεμένοι στον λογαριασμό σου στο Mastodon αυτή τη στιγμή. + ip: IP + platforms: + adobe_air: Adobe Air + android: Android + blackberry: Blackberry + chrome_os: ChromeOS + firefox_os: Firefox OS + ios: iOS + linux: Linux + mac: Mac + other: άγνωστη πλατφόρμα + windows: Windows + windows_mobile: Windows Mobile + windows_phone: Windows Phone + revoke: Ανακάλεσε + revoke_success: Η σύνδεση ανακλήθηκε επιτυχώς + title: Σύνδεση + settings: + authorized_apps: Εγκεκριμένες εφαρμογές + back: Πίσω στο Mastodon + delete: Διαγραφή λογαριασμού + development: Ανάπτυξη + edit_profile: Επεξεργασία προφίλ + export: Εξαγωγή δεδομένων + followers: Εγκεκριμένοι ακόλουθοι + import: Εισαγωγή + migrate: Μετακόμιση λογαριασμού + notifications: Ειδοποιήσεις + preferences: Προτιμήσεις + settings: Ρυθμίσεις + two_factor_authentication: Πιστοποίηση 2 παραγόντων (2FA) + your_apps: Οι εφαρμογές σου + statuses: + attached: + description: 'Συνημμένα: %{attached}' + image: + one: "%{count} εικόνα" + other: "%{count} εικόνες" + video: + one: "%{count} βίντεο" + other: "%{count} βίντεο" + boosted_from_html: Προωθήθηκε από %{acct_link} + content_warning: 'Προειδοποίηση περιεχομένου: %{warning}' + disallowed_hashtags: + one: 'περιέχει μη επιτρεπτή ταμπέλα: %{tags}' + other: 'περιέχει μη επιτρεπτές ταμπέλες: %{tags}' + language_detection: Αυτόματη αναγνώριση γλώσσας + open_in_web: Δες στο διαδίκτυο + over_character_limit: υπέρβαση μέγιστου ορίου %{max} χαρακτήρων + pin_errors: + limit: Έχεις ήδη καρφιτσώσει το μέγιστο αριθμό επιτρεπτών τουτ + ownership: Δεν μπορείς να καρφιτσώσεις μη δικό σου τουτ + private: Τα μη δημόσια τουτ δεν καρφιτσώνονται + reblog: Οι προωθήσεις δεν καρφιτσώνονται + show_more: Περισσότερα + title: '%{name}: "%{quote}"' + visibilities: + private: Μόνο ακόλουθοι + private_long: Εμφάνιση μόνο σε ακόλουθους + public: Δημόσιο + public_long: Βλέπει οποιοσδήποτε + unlisted: Ακαταχώριστο + unlisted_long: Βλέπει οποιοσδήποτε, αλλά δεν καταχωρείται στις δημόσιες ροές + stream_entries: + click_to_show: Κλικ για εμφάνιση + pinned: Καρφιτσωμένο τουτ + reblogged: προωθημένο + sensitive_content: Ευαίσθητο περιεχόμενο terms: title: Όροι Χρήσης και Πολιτική Απορρήτου του κόμβου %{instance} + themes: + contrast: Υψηλή αντίθεση + default: Mastodon + mastodon-light: Mastodon (ανοιχτόχρωμο) + time: + formats: + default: "%b %d, %Y, %H:%M" + two_factor_authentication: + code_hint: Βάλε τον κωδικό που δημιούργησε η εφαρμογή πιστοποίησής σου για επιβεβαίωση + description_html: Αν ενεργοποιήσεις την πιστοποίηση 2 παραγόντων (2FA), για να συνδεθείς θα πρέπει να έχεις το τηλέφωνό σου, που θα σου δημιουργήσει κλειδιά εισόδου. + disable: Απενεργοποίησε + enable: Ενεργοποίησε + enabled: Η πιστοποίηση 2 παραγόντων (2FA) είναι ενεργοποιημένη + enabled_success: Η πιστοποίηση 2 παραγόντων (2FA) ενεργοποιήθηκε επιτυχώς + generate_recovery_codes: Δημιούργησε κωδικούς ανάκτησης + instructions_html: "Σάρωσε αυτόν τον κωδικό QR με την εφαρμογή Google Authenticator ή κάποια άλλη αντίστοιχη στο τηλέφωνό σου. Από εδώ και στο εξής, η εφαρμογή αυτή θα δημιουργεί κλειδιά που θα πρέπει να εισάγεις όταν συνδέεσαι." + lost_recovery_codes: Οι κωδικοί ανάκτησης σου επιτρέπουν να ανακτήσεις ξανά πρόσβαση στον λογαριασμό σου αν χάσεις το τηλέφωνό σου. Αν έχεις χάσει τους κωδικούς ανάκτησης, μπορείς να τους δημιουργήσεις ξανά εδώ. Οι παλιοί κωδικοί σου θα ακυρωθούν. + manual_instructions: 'Αν δεν μπορείς να σαρώσεις τον κωδικό QR και χρειάζεσαι να τον εισάγεις χειροκίνητα, ορίστε η μυστική φράση σε μορφή κειμένου:' + recovery_codes: Εφεδρικοί κωδικοί ανάκτησης + recovery_codes_regenerated: Οι εφεδρικοί κωδικοί ανάκτησης δημιουργήθηκαν επιτυχώς + recovery_instructions_html: Αν ποτέ δεν έχεις πρόσβαση στο κινητό σου, μπορείς να χρησιμοποιήσεις έναν από τους παρακάτω κωδικούς ανάκτησης για να αποκτήσεις πρόσβαση στο λογαριασμό σου. Διαφύλαξε τους κωδικούς ανάκτησης. Για παράδειγμα, μπορείς να τους εκτυπώσεις και να τους φυλάξεις μαζί με άλλα σημαντικά σου έγγραφα. + setup: Στήσιμο + wrong_code: Ο κωδικός που έβαλες ήταν άκυρος! Τα ρολόγια στον διακομιστή και τη συσκευή είναι σωστά; user_mailer: + backup_ready: + explanation: Ζήτησες ένα εφεδρικό αντίγραφο του λογαριασμού σου στο Mastodon. Είναι έτοιμο για κατέβασμα! + subject: Το εφεδρικό αντίγραφό σου είναι έτοιμο για κατέβασμα + title: Λήψη εφεδρικού αρχείου welcome: + edit_profile_action: Στήσιμο προφίλ + edit_profile_step: Μπορείς να προσαρμόσεις το προφίλ σου ανεβάζοντας μια εικόνα εμφάνισης & επικεφαλίδας, αλλάζοντας το εμφανιζόμενο όνομά σου και άλλα. Αν θες να ελέγχεις τους νέου σου ακόλουθους πριν αυτοί σε ακολουθήσουν, μπορείς να κλειδώσεις το λογαριασμό σου. + explanation: Μερικές συμβουλές για να ξεκινήσεις + final_action: Ξεκίνα τις δημοσιεύσεις final_step: 'Ξεκίνα τις δημοσιεύσεις! Ακόμα και χωρίς ακόλουθους τα δημόσια μηνύματά σου μπορεί να τα δουν άλλοι, για παράδειγμα στην τοπική ροή και στις ετικέτες. Ίσως να θέλεις να κάνεις μια εισαγωγή του εαυτού σου με την ετικέτα #introductions.' + full_handle: Το πλήρες όνομά σου full_handle_hint: Αυτό θα εδώ θα πεις στους φίλους σου για να σου μιλήσουν ή να σε ακολουθήσουν από άλλο κόμβο. + review_preferences_action: Αλλαγή προτιμήσεων + review_preferences_step: Σιγουρέψου πως έχεις ορίσει τις προτιμήσεις σου, όπως το ποια email θέλεις να λαμβάνεις, ή ποιο επίπεδο ιδιωτικότητας θέλεις να έχουν οι δημοσιεύσεις σου. Αν δεν σε πιάνει ναυτία, μπορείς να ενεργοποιήσεις την αυτόματη αναπαραγωγή των GIF. + subject: Καλώς ήρθες στο Mastodon + tip_bridge_html: Αν έχεις έρθει από το Twitter, μπορείς να βρεις τους φίλους και τις φίλες σου στο Mastodon χρησιμοποιώντας την βοηθητική εφαρμογή. Υπόψιν πως δουλεύει μόνο αν την έχουν χρησιμοποιήσει και εκείνοι! tip_federated_timeline: Η ομοσπονδιακή ροή είναι μια όψη πραγματικού χρόνου στο δίκτυο του Mastodon. Παρόλα αυτά, περιλαμβάνει μόνο όσους ακολουθούν οι γείτονές σου, άρα δεν είναι πλήρης. tip_following: Ακολουθείς το διαχειριστή του διακομιστή σου αυτόματα. Για να βρεις περισσότερους ενδιαφέροντες ανθρώπους, έλεγξε την τοπική και την ομοσπονδιακή ροή. tip_local_timeline: Η τοπική ροή είναι η όψη πραγματικού χρόνου των ανθρώπων στον κόμβο %{instance}. Αυτοί είναι οι άμεσοι γείτονές σου! + tip_mobile_webapp: Αν ο φυλλομετρητής (browser) στο κινητό σού σου επιτρέπει να προσθέσεις το Mastodon στην αρχική οθόνη της συσκευής, θα λαμβάνεις και ειδοποιήσεις μέσω push. Σε πολλά πράγματα λειτουργεί σαν κανονική εφαρμογή! + tips: Συμβουλές + title: Καλώς όρισες, %{name}! + users: + invalid_email: Η διεύθυνση email είναι άκυρη + invalid_otp_token: Άκυρος κωδικός πιστοποίησης 2 παραγόντων (2FA) + otp_lost_help_html: Αν χάσεις και τα δύο, μπορείς να επικοινωνήσεις με τον/την %{email} + seamless_external_login: Επειδή έχεις συνδεθεί μέσω τρίτης υπηρεσίας, οι ρυθμίσεις συνθηματικού και email δεν είναι διαθέσιμες. + signed_in_as: 'Έχεις συνδεθεί ως:' diff --git a/config/locales/en.yml b/config/locales/en.yml index 0724a1dbb..2581d9383 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -514,6 +514,7 @@ en: '86400': 1 day expires_in_prompt: Never generate: Generate + invited_by: 'You were invited by:' max_uses: one: 1 use other: "%{count} uses" @@ -674,6 +675,7 @@ en: disallowed_hashtags: one: 'contained a disallowed hashtag: %{tags}' other: 'contained the disallowed hashtags: %{tags}' + language_detection: Automatically detect language open_in_web: Open in web over_character_limit: character limit of %{max} exceeded pin_errors: diff --git a/config/locales/eu.yml b/config/locales/eu.yml index dcfcd5b30..78cb82abe 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -29,10 +29,10 @@ eu: learn_more: Ikasi gehiago other_instances: Instantzien zerrenda source_code: Iturburu kodea - status_count_after: mezu - status_count_before: Idatzi dituzte - user_count_after: erabiltzaile - user_count_before: Baditugu + status_count_after: mezu idatzi dituzte + status_count_before: Hauek + user_count_after: erabiltzaile daude + user_count_before: Hemen what_is_mastodon: Zer da Mastodon? accounts: follow: Jarraitu @@ -514,6 +514,7 @@ eu: '86400': Egun 1 expires_in_prompt: Inoiz ez generate: Sortu + invited_by: 'Honek gonbidatu zaitu:' max_uses: one: Erabilera 1 other: "%{count} erabilera" diff --git a/config/locales/fa.yml b/config/locales/fa.yml index ec36afad0..61e7509c5 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -514,6 +514,7 @@ fa: '86400': ۱ روز expires_in_prompt: هیچ وقت generate: ساختن + invited_by: 'دعوت‌کنندهٔ شما:' max_uses: one: ۱ بار other: "%{count} بار" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index b3914ea2b..07d900cfa 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -55,7 +55,7 @@ fr: unfollow: Ne plus suivre admin: account_moderation_notes: - create: Créer une note + create: Laisser un commentaire created_msg: Note de modération créée avec succès ! delete: Supprimer destroyed_msg: Note de modération supprimée avec succès ! @@ -424,7 +424,7 @@ fr: following: 'Youpi ! Vous suivez  :' post_follow: close: Ou bien, vous pouvez fermer cette fenêtre. - return: Retour au profil de l’utilisateur⋅ice + return: Afficher le profil de l’utilisateur⋅ice web: Retour à l’interface web title: Suivre %{acct} datetime: diff --git a/config/locales/gl.yml b/config/locales/gl.yml index ffa6ebe05..305d5b17f 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -514,6 +514,7 @@ gl: '86400': 1 día expires_in_prompt: Nunca generate: Xerar + invited_by: 'Vostede foi convidada por:' max_uses: one: 1 uso other: "%{count} usos" diff --git a/config/locales/it.yml b/config/locales/it.yml index 5608c0574..cc79f352b 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -157,13 +157,17 @@ it: confirm_user: "%{name} ha confermato l'indirizzo email per l'utente %{target}" create_custom_emoji: "%{name} ha caricato un nuovo emoji %{target}" create_domain_block: "%{name} ha bloccato il dominio %{target}" + create_email_domain_block: "%{name} ha messo il dominio email %{target} nella blacklist" destroy_domain_block: "%{name} ha sbloccato il dominio %{target}" + destroy_email_domain_block: "%{name}ha messo il dominio email %{target} nella whitelist" destroy_status: "%{name} ha eliminato lo status di %{target}" disable_2fa_user: "%{name} ha disabilitato l'obbligo dei due fattori per l'utente %{target}" disable_custom_emoji: "%{name} ha disabilitato l'emoji %{target}" disable_user: "%{name} ha disabilitato il login per l'utente %{target}" enable_custom_emoji: "%{name} ha abilitato l'emoji %{target}" enable_user: "%{name} ha abilitato il login per l'utente %{target}" + memorialize_account: "%{name} ha trasformato l'account di %{target} in una pagina in memoriam" + promote_user: "%{name} ha promosso l'utente %{target}" remove_avatar_user: "%{name} ha eliminato l'avatar di %{target}" reopen_report: "%{name} ha riaperto il rapporto %{target}" reset_password_user: "%{name} ha reimpostato la password dell'utente %{target}" @@ -374,7 +378,7 @@ it: following: 'Accettato! Ora stai seguendo:' post_follow: close: Oppure puoi chiudere questa finestra. - return: Torna al profilo dell'utente + return: Mostra il profilo dell'utente title: Segui %{acct} datetime: distance_in_words: diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 759e1b5b5..ffc450038 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -424,7 +424,7 @@ ja: following: '成功! あなたは現在以下のアカウントをフォローしています:' post_follow: close: またはこのウィンドウを閉じます。 - return: ユーザーのプロフィールに戻る + return: ユーザーのプロフィールを見る web: Web を開く title: "%{acct} をフォロー" datetime: @@ -514,6 +514,7 @@ ja: '86400': 1 日 expires_in_prompt: 無期限 generate: 作成 + invited_by: '次の人に招待されました:' max_uses: one: '1' other: "%{count}" @@ -674,6 +675,7 @@ ja: disallowed_hashtags: one: '許可されていないハッシュタグが含まれています: %{tags}' other: '許可されていないハッシュタグが含まれています: %{tags}' + language_detection: 自動的に言語を検出する open_in_web: Webで開く over_character_limit: 上限は %{max}文字までです pin_errors: diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 3fff2c9d5..68a044eb5 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -2,7 +2,7 @@ ko: about: about_hashtag_html: "#%{hashtag} 라는 해시태그가 붙은 공개 툿 입니다. 같은 연합에 속한 임의의 인스턴스에 계정을 생성하면 당신도 대화에 참여할 수 있습니다." - about_mastodon_html: Mastodon은 오픈 소스 기반의 소셜 네트워크 서비스 입니다. 상용 플랫폼의 대체로서 분산형 구조를 채택해, 여러분의 대화가 한 회사에 독점되는 것을 방지합니다. 신뢰할 수 있는 인스턴스를 선택하세요 — 어떤 인스턴스를 고르더라도, 누구와도 대화할 수 있습니다. 누구나 자신만의 Mastodon 인스턴스를 만들 수 있으며, 아주 매끄럽게 소셜 네트워크에 참가할 수 있습니다. + about_mastodon_html: 마스토돈은 오픈 소스 기반의 소셜 네트워크 서비스 입니다. 상용 플랫폼의 대체로서 분산형 구조를 채택해, 여러분의 대화가 한 회사에 독점되는 것을 방지합니다. 신뢰할 수 있는 인스턴스를 선택하세요 — 어떤 인스턴스를 고르더라도, 누구와도 대화할 수 있습니다. 누구나 자신만의 마스토돈 인스턴스를 만들 수 있으며, 아주 매끄럽게 소셜 네트워크에 참가할 수 있습니다. about_this: 이 인스턴스에 대해서 administered_by: '관리자:' closed_registrations: 현재 이 인스턴스에서는 신규 등록을 받고 있지 않습니다. @@ -16,9 +16,9 @@ ko:

룰을 작성하는 장소

아직 설명이 작성되지 않았습니다.

features: - humane_approach_body: 다른 SNS의 실패를 교훈삼아, Mastodon은 소셜미디어가 잘못 사용되는 것을 막기 위하여 윤리적인 설계를 추구합니다. + humane_approach_body: 다른 SNS의 실패를 교훈삼아, 마스토돈은 소셜미디어가 잘못 사용되는 것을 막기 위하여 윤리적인 설계를 추구합니다. humane_approach_title: 보다 배려를 의식한 설계를 추구 - not_a_product_body: Mastodon은 이익을 추구하는 SNS가 아닙니다. 그러므로 광고와 데이터의 수집 및 분석이 존재하지 않고, 유저를 구속하지도 않습니다. + not_a_product_body: 마스토돈은 이익을 추구하는 SNS가 아닙니다. 그러므로 광고와 데이터의 수집 및 분석이 존재하지 않고, 유저를 구속하지도 않습니다. not_a_product_title: 여러분은 사람이며, 상품이 아닙니다 real_conversation_body: 자유롭게 사용할 수 있는 500문자의 메세지와 미디어 경고 내용을 바탕으로, 자기자신을 자유롭게 표현할 수 있습니다. real_conversation_title: 진정한 커뮤니케이션을 위하여 @@ -33,7 +33,7 @@ ko: status_count_before: 툿 수 user_count_after: 명 user_count_before: 사용자 수 - what_is_mastodon: Mastodon이란? + what_is_mastodon: 마스토돈이란? accounts: follow: 팔로우 followers: 팔로워 @@ -109,7 +109,7 @@ ko: not_subscribed: 구독하지 않음 order: alphabetic: 알파벳 순 - most_recent: 최근 활동 순 + most_recent: 최근 순 title: 순서 outbox_url: 발신함 URL perform_full_suspension: 완전히 정지시키기 @@ -242,13 +242,13 @@ ko: undo: 실행 취소 email_domain_blocks: add_new: 새로 추가 - created_msg: Email 도메인 차단 규칙을 생성했습니다 + created_msg: 이메일 도메인 차단 규칙을 생성했습니다 delete: 삭제 - destroyed_msg: Email 도메인 차단 규칙을 삭제했습니다 + destroyed_msg: 이메일 도메인 차단 규칙을 삭제했습니다 domain: 도메인 new: create: 차단 규칙 생성 - title: 새 Email 도메인 차단 + title: 새 이메일 도메인 차단 title: Email 도메인 차단 instances: account_count: 알려진 계정의 수 @@ -456,7 +456,7 @@ ko: '404': 당신이 찾으려는 페이지는 존재하지 않습니다. '410': 당신이 보려는 페이지는 더이상 존재하지 않습니다. '422': - content: 보안 인증에 실패했습니다. Cookie를 차단하고 있진 않습니까? + content: 보안 인증에 실패했습니다. 쿠키를 차단하고 있진 않습니까? title: 보안 인증 실패 '429': 요청 횟수 제한에 도달했습니다 '500': @@ -516,6 +516,7 @@ ko: '86400': 하루 expires_in_prompt: 영원히 generate: 생성 + invited_by: '당신을 초대한 사람:' max_uses: one: 일회용 other: "%{count} 회" @@ -629,7 +630,7 @@ ko: weibo: 웨이보 current_session: 현재 세션 description: "%{platform}의 %{browser}" - explanation: 내 Mastodon 계정에 현재 로그인 중인 웹 브라우저 목록입니다. + explanation: 내 마스토돈 계정에 현재 로그인 중인 웹 브라우저 목록입니다. ip: IP platforms: adobe_air: 어도비 에어 @@ -702,6 +703,7 @@ ko: themes: contrast: 고대비 default: 마스토돈 + mastodon-light: 마스토돈 (밝음) time: formats: default: "%Y년 %m월 %d일 %H:%M" diff --git a/config/locales/nl.yml b/config/locales/nl.yml index b723bcfc2..d6d2183cf 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -514,6 +514,7 @@ nl: '86400': 1 dag expires_in_prompt: Nooit generate: Genereren + invited_by: 'Jij bent uitgenodigd door:' max_uses: one: 1 keer other: "%{count} keer" @@ -674,6 +675,7 @@ nl: disallowed_hashtags: one: 'bevatte een niet toegestane hashtag: %{tags}' other: 'bevatte niet toegestane hashtags: %{tags}' + language_detection: Taal automatisch detecteren open_in_web: In de webapp openen over_character_limit: Limiet van %{max} tekens overschreden pin_errors: diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 451caa4f2..fdaecbbbf 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -483,38 +483,18 @@ oc: - :year datetime: distance_in_words: - about_x_hours: - one: Fa una ora - other: Fa %{count} oras - about_x_months: - one: Fa un mes - other: Fa %{count} meses - about_x_years: - one: Fa un an - other: Fa %{count} ans - almost_x_years: - one: Fa quasi un an - other: Fa quasi %{count} ans + about_x_hours: "%{count} h" + about_x_months: "%{count} meses" + about_x_years: "%{count} ans" + almost_x_years: "%{count}ans" half_a_minute: Ara - less_than_x_minutes: - one: Fa mens d’una minuta - other: Fa mens de %{count} minutas + less_than_x_minutes: "%{count} min" less_than_x_seconds: Ara meteis - over_x_years: - one: Fa mai d’un an - other: Fa mai de %{count} ans - x_days: - one: Fa un jorn - other: Fa %{count} jorns - x_minutes: - one: Fa una minuta - other: Fa %{count} minutas - x_months: - one: Fa un mes - other: Fa %{count} meses - x_seconds: - one: Fa una segonda - other: Fa %{count} segondas + over_x_years: "%{count} ans" + x_days: "%{count} jorns" + x_minutes: "%{count} min" + x_months: "%{count} meses" + x_seconds: "%{count}s" x_years: one: Fa un an other: Fa %{count} ans @@ -591,6 +571,7 @@ oc: '86400': 1 jorn expires_in_prompt: Jamai generate: Generar + invited_by: 'Vos a convidat :' max_uses: one: 1 persona other: "%{count} personas" @@ -751,6 +732,7 @@ oc: disallowed_hashtags: one: 'conten una etiqueta desactivada : %{tags}' other: 'conten las etiquetas desactivadas : %{tags}' + language_detection: Detectar automaticament la lenga open_in_web: Dobrir sul web over_character_limit: limit de %{max} caractèrs passat pin_errors: diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 3e342da42..94d1e6c7c 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -517,6 +517,7 @@ pl: '86400': dobie expires_in_prompt: Nigdy generate: Wygeneruj + invited_by: 'Zostałeś zaproszony przez:' max_uses: few: "%{count} użycia" many: "%{count} użyć" @@ -687,6 +688,7 @@ pl: disallowed_hashtags: one: 'zawiera niedozwolony hashtag: %{tags}' other: 'zawiera niedozwolone hashtagi: %{tags}' + language_detection: Automatycznie wykrywaj język open_in_web: Otwórz w przeglądarce over_character_limit: limit %{max} znaków przekroczony pin_errors: diff --git a/config/locales/simple_form.ar.yml b/config/locales/simple_form.ar.yml index 3d555718c..d560a9228 100644 --- a/config/locales/simple_form.ar.yml +++ b/config/locales/simple_form.ar.yml @@ -3,12 +3,21 @@ ar: simple_form: hints: defaults: + autofollow: سوف يتابعك تلقائيًا الأشخاص الذين يقومون بالتسجيل من خلال الدعوة avatar: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير 2MB. سيتم تصغيره إلى 400x400px bot: يُعلِم أنّ هذا الحساب لا يمثل شخصًا digest: تُرسَل إليك بعد مُضيّ مدة مِن خمول نشاطك و فقط إذا ما تلقيت رسائل شخصية مباشِرة أثناء فترة غيابك مِن الشبكة + display_name: + one: 1 حرف باق + other: %{count} حرف باق fields: يُمكنك عرض 4 عناصر على شكل جدول في ملفك الشخصي header: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير 2MB. سيتم تصغيره إلى 700x335px + locale: لغة واجهة المستخدم و الرسائل الإلكترونية و الإشعارات locked: يتطلب منك الموافقة يدويا على طلبات المتابعة + note: + one: 1 حرف باق + other: %{count} حرف باق + setting_default_language: يمكن الكشف التلقائي للّغة اللتي استخدمتها في تحرير تبويقاتك ، غيرَ أنّ العملية ليست دائما دقيقة setting_hide_network: الحسابات التي تُتابعها و التي تُتابِعك على حد سواء لن تُعرَض على صفحتك الشخصية setting_noindex: ذلك يؤثر على حالة ملفك الشخصي و صفحاتك setting_theme: ذلك يؤثر على الشكل الذي سيبدو عليه ماستدون عندما تقوم بالدخول مِن أي جهاز. @@ -17,15 +26,17 @@ ar: sessions: otp: 'قم بإدخال رمز المصادقة بخطوتين الذي قام بتوليده تطبيق جهازك أو إستخدم أحد رموز النفاذ الإحتياطية :' user: - filtered_languages: سوف يتم تصفية و إخفاء اللغات المختارة من خيوطك العمومية + chosen_languages: لن تظهر على الخيوط العمومية إلّا التبويقات المنشورة في اللغات المختارة labels: account: fields: name: التسمية value: المحتوى defaults: + autofollow: إرسال دعوة لمتابعة حسابك avatar: الصورة الرمزية bot: إنّ هذا الحساب روبوت آلي + chosen_languages: تصفية اللغات confirm_new_password: تأكيد كلمة السر الجديدة confirm_password: تأكيد كلمة السر current_password: كلمة السر الحالية @@ -34,9 +45,8 @@ ar: email: عنوان البريد الإلكتروني expires_in: تنتهي مدة صلاحيته بعد fields: واصفات بيانات الملف الشخصي - filtered_languages: اللغات التي تم تصفيتها header: الرأسية - locale: اللغة + locale: لغة الواجهة locked: تجميد الحساب max_uses: عدد مرات استخدام الرابط new_password: كلمة السر الجديدة @@ -45,6 +55,7 @@ ar: password: كلمة السر setting_auto_play_gif: تشغيل تلقائي لِوَسائط جيف المتحركة setting_boost_modal: إظهار مربع حوار للتأكيد قبل ترقية أي تبويق + setting_default_language: لغة النشر setting_default_privacy: خصوصية المنشور setting_default_sensitive: إعتبر الوسائط دائما كمحتوى حساس setting_delete_modal: إظهار مربع حوار للتأكيد قبل حذف أي تبويق diff --git a/config/locales/simple_form.ca.yml b/config/locales/simple_form.ca.yml index 5df7bf77b..eb0d67dfd 100644 --- a/config/locales/simple_form.ca.yml +++ b/config/locales/simple_form.ca.yml @@ -3,6 +3,7 @@ ca: simple_form: hints: defaults: + autofollow: Les persones que es registrin a través de la invitació et seguiran automàticament avatar: PNG, GIF o JPG. Màxim 2MB. S'escalarà a 400x400px bot: Aquest compte realitza principalment accions automatitzades i pot no estar controlat per cap persona digest: Només s'envia després d'un llarg període d'inactivitat amb un resum de les mencions que has rebut en la teva absència @@ -11,10 +12,12 @@ ca: other: %{count} càracters restans fields: Pots tenir fins a 4 elements que es mostren com a taula al teu perfil header: PNG, GIF o JPG. Màxim 2MB. S'escalarà a 700x335px + locale: El llenguatge de l’interfície d’usuari, els correus i les notificacions push locked: Requereix que aprovis manualment els seguidors note: one: 1 càracter restant other: %{count} caràcters restants + setting_default_language: La llengua dels teus toots pot ser detectada automàticament però no sempre acuradament setting_hide_network: Qui tu segueixes i els que et segueixen a tu no es mostraran en el teu perfil setting_noindex: Afecta el teu perfil públic i les pàgines d'estat setting_theme: Afecta l'aspecte de Mastodon quan es visita des de qualsevol dispositiu. @@ -23,15 +26,17 @@ ca: sessions: otp: 'Introdueix el codi de dos factors generat per el teu telèfon o utilitza un dels teus codis de recuperació:' user: - filtered_languages: Les llengües seleccionades s'eliminaran de les línies de temps públiques + chosen_languages: Quan estigui marcat, només es mostraran els toots de les llengües seleccionades en les línies de temps públiques labels: account: fields: name: Etiqueta value: Contingut defaults: + autofollow: Convida a seguir el teu compte avatar: Avatar bot: Aquest compte és un bot + chosen_languages: Filtrar llengües confirm_new_password: Confirma la contrasenya nova confirm_password: Confirma la contrasenya current_password: Contrasenya actual @@ -40,9 +45,8 @@ ca: email: Adreça de correu electrònic expires_in: Expira després fields: Metadades del perfil - filtered_languages: Llengües filtrades header: Capçalera - locale: Llengua + locale: Llengua de la interfície locked: Fes aquest compte privat max_uses: Nombre màxim d'usos new_password: Contrasenya nova @@ -51,6 +55,7 @@ ca: password: Contrasenya setting_auto_play_gif: Reproducció automàtica de GIFs animats setting_boost_modal: Mostra la finestra de confirmació abans d'un retoot + setting_default_language: Llengua de les publicacions setting_default_privacy: Privacitat de les publicacions setting_default_sensitive: Marca sempre els elements multimèdia com a sensibles setting_delete_modal: Mostra la finestra de confirmació abans de suprimir un toot diff --git a/config/locales/simple_form.co.yml b/config/locales/simple_form.co.yml index 25d4a05fb..ac8b89a7b 100644 --- a/config/locales/simple_form.co.yml +++ b/config/locales/simple_form.co.yml @@ -22,8 +22,6 @@ co: data: Un fugliale CSV da un’altr’istanza di Mastodon sessions: otp: 'Entrate u codice d’identificazione à dui fattori nant’à u vostru telefuninu, o unu di i vostri codici di ricuperazione:' - user: - filtered_languages: Ùn viderete micca e lingue selezziunate nant’à e linee pubbliche labels: account: fields: @@ -40,7 +38,6 @@ co: email: Indirizzu e-mail expires_in: Spira dopu à fields: Metadata di u prufile - filtered_languages: Lingue filtrate header: Ritrattu di cuprendula locale: Lingua locked: Privatizà u contu diff --git a/config/locales/simple_form.de.yml b/config/locales/simple_form.de.yml index c0a451000..596d89d81 100644 --- a/config/locales/simple_form.de.yml +++ b/config/locales/simple_form.de.yml @@ -3,6 +3,7 @@ de: simple_form: hints: defaults: + autofollow: Leute die sich über deine Einladung registrieren werden dir automatisch folgen avatar: PNG, GIF oder JPG. Maximal 2 MB. Wird auf 400×400 px herunterskaliert bot: Dieser Account führt hauptsächlich automatische Aktionen aus und wird möglicherweise nicht überwacht digest: Wenn du lange Zeit inaktiv bist, wird dir eine Zusammenfassung von Erwähnungen in deiner Abwesenheit zugeschickt @@ -15,21 +16,20 @@ de: note: one: 1 Zeichen verbleibt other: %{count} Zeichen verbleiben - setting_hide_network: Wem du folgst und wer dir folgt, wird in deinem Profil nicht angezeigt + setting_hide_network: Wem du folgst und wer dir folgt wird in deinem Profil nicht angezeigt setting_noindex: Betrifft dein öffentliches Profil und deine Beiträge setting_theme: Wirkt sich darauf aus, wie Mastodon aussieht, egal auf welchem Gerät du eingeloggt bist. imports: data: CSV-Datei, die aus einer anderen Mastodon-Instanz exportiert wurde sessions: otp: 'Gib den Zwei-Faktor-Authentisierungscode von deinem Telefon ein oder benutze einen deiner Wiederherstellungscodes:' - user: - filtered_languages: Ausgewählte Sprachen werden aus deinen öffentlichen Zeitleisten gefiltert labels: account: fields: name: Bezeichnung value: Inhalt defaults: + autofollow: Einladen, um deinen Account zu folgen avatar: Profilbild bot: Dies ist ein bot Benutzer confirm_new_password: Neues Passwort bestätigen @@ -40,7 +40,6 @@ de: email: E-Mail-Adresse expires_in: Gültig bis fields: Profil-Metadaten - filtered_languages: Gefilterte Sprachen header: Kopfbild locale: Sprache locked: Gesperrtes Profil @@ -55,6 +54,7 @@ de: setting_default_sensitive: Medien immer als heikel markieren setting_delete_modal: Bestätigungsdialog anzeigen, bevor ein Beitrag gelöscht wird setting_display_sensitive_media: Medien, die als heikel markiert sind, immer anzeigen + setting_hide_network: Verstecke dein Netzwerk setting_noindex: Suchmaschinen-Indexierung verhindern setting_reduce_motion: Bewegung in Animationen verringern setting_system_font_ui: Standardschriftart des Systems verwenden diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 85597e9a7..6783f0045 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -3,6 +3,7 @@ en: simple_form: hints: defaults: + autofollow: People who sign up through the invite will automatically follow you avatar: PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px bot: This account mainly performs automated actions and might not be monitored digest: Only sent after a long period of inactivity and only if you have received any personal messages in your absence @@ -11,10 +12,12 @@ en: other: %{count} characters left fields: You can have up to 4 items displayed as a table on your profile header: PNG, GIF or JPG. At most 2MB. Will be downscaled to 700x335px + locale: The language of the user interface, e-mails and push notifications locked: Requires you to manually approve followers note: one: 1 character left other: %{count} characters left + setting_default_language: The language of your toots can be detected automatically, but it's not always accurate setting_hide_network: Who you follow and who follows you will not be shown on your profile setting_noindex: Affects your public profile and status pages setting_theme: Affects how Mastodon looks when you're logged in from any device. @@ -23,15 +26,17 @@ en: sessions: otp: 'Enter the two-factor code generated by your phone app or use one of your recovery codes:' user: - filtered_languages: Checked languages will be filtered from public timelines for you + chosen_languages: When checked, only toots in selected languages will be displayed in public timelines labels: account: fields: name: Label value: Content defaults: + autofollow: Invite to follow your account avatar: Avatar bot: This is a bot account + chosen_languages: Filter languages confirm_new_password: Confirm new password confirm_password: Confirm password current_password: Current password @@ -40,9 +45,8 @@ en: email: E-mail address expires_in: Expire after fields: Profile metadata - filtered_languages: Filtered languages header: Header - locale: Language + locale: Interface language locked: Lock account max_uses: Max number of uses new_password: New password @@ -51,6 +55,7 @@ en: password: Password setting_auto_play_gif: Auto-play animated GIFs setting_boost_modal: Show confirmation dialog before boosting + setting_default_language: Posting language setting_default_privacy: Post privacy setting_default_sensitive: Always mark media as sensitive setting_delete_modal: Show confirmation dialog before deleting a toot diff --git a/config/locales/simple_form.eo.yml b/config/locales/simple_form.eo.yml index 4027c1b60..884c3a989 100644 --- a/config/locales/simple_form.eo.yml +++ b/config/locales/simple_form.eo.yml @@ -3,6 +3,7 @@ eo: simple_form: hints: defaults: + autofollow: Homoj, kiuj registriĝos per la invito aŭtomate sekvos vin avatar: Formato PNG, GIF aŭ JPG. Ĝis 2MB. Estos malgrandigita al 400x400px bot: Tiu konto ĉefe faras aŭtomatajn agojn, kaj povas esti ne kontrolata digest: Sendita nur post longa tempo de neaktiveco, kaj nur se vi ricevis personan mesaĝon en via foresto @@ -22,14 +23,13 @@ eo: data: CSV-dosiero el alia nodo de Mastodon sessions: otp: 'Enmetu la kodon de dufaktora aŭtentigo el via telefono aŭ uzu unu el viaj realiraj kodoj:' - user: - filtered_languages: Markitaj lingvoj estos elfiltritaj de publikaj tempolinioj por vi labels: account: fields: name: Etikedo value: Enhavo defaults: + autofollow: Inviti al sekvi vian konton avatar: Profilbildo bot: Tio estas robota konto confirm_new_password: Konfirmi novan pasvorton @@ -40,7 +40,6 @@ eo: email: Retadreso expires_in: Eksvalidiĝas post fields: Profilaj metadatumoj - filtered_languages: Filtritaj lingvoj header: Fonbildo locale: Lingvo locked: Ŝlosi konton diff --git a/config/locales/simple_form.es.yml b/config/locales/simple_form.es.yml index 38661b00f..000a33edc 100644 --- a/config/locales/simple_form.es.yml +++ b/config/locales/simple_form.es.yml @@ -19,8 +19,6 @@ es: data: Archivo CSV exportado desde otra instancia de Mastodon sessions: otp: Introduce el código de autenticación de dos factores de tu teléfono o usa uno de tus códigos de recuperación. - user: - filtered_languages: Los idiomas seleccionados dejarán de mostrarse para ti en las líneas de tiempo públicas labels: defaults: avatar: Avatar @@ -31,7 +29,6 @@ es: display_name: Nombre para mostrar email: Dirección de correo electrónico expires_in: Expirar tras - filtered_languages: Idiomas filtrados header: Img. cabecera locale: Idioma locked: Hacer privada esta cuenta diff --git a/config/locales/simple_form.eu.yml b/config/locales/simple_form.eu.yml index 364a2e118..ff34fdf50 100644 --- a/config/locales/simple_form.eu.yml +++ b/config/locales/simple_form.eu.yml @@ -3,6 +3,7 @@ eu: simple_form: hints: defaults: + autofollow: Gonbidapena erabiliz izena ematen dutenek automatikoki jarraituko zaituzte avatar: PNG, GIF edo JPG. Gehienez 2MB. 400x400px neurrira eskalatuko da bot: Kontu honek nagusiki automatizatutako ekintzak burutzen ditu eta agian ez du inork monitorizatzen digest: Soilik jarduerarik gabeko epe luze bat eta gero, eta soilik ez zeudela mezu pertsonalen bat jaso baduzu @@ -22,14 +23,13 @@ eu: data: Beste Mastodon instantzia batetik esportatutako CSV fitxategia sessions: otp: 'Sartu zure telefonoko aplikazioak sortutako bi faktoreetako kodea, edo erabili zure berreskuratze kodeetako bat:' - user: - filtered_languages: Ez dira aukeratutako hizkuntzak erakutsiko zure denbora-lerro publikoetan labels: account: fields: name: Etiketa value: Edukia defaults: + autofollow: Gonbidatu zure kontua jarraitzera avatar: Abatarra bot: Hau bot kontu bat da confirm_new_password: Berretsi pasahitz berria @@ -40,7 +40,6 @@ eu: email: E-mail helbidea expires_in: Iraungitzea fields: Profilaren metadatuak - filtered_languages: Iragazitako hizkuntzak header: Goiburua locale: Hizkuntza locked: Giltzapetu kontua diff --git a/config/locales/simple_form.fa.yml b/config/locales/simple_form.fa.yml index 13ff7801e..e8a2c38aa 100644 --- a/config/locales/simple_form.fa.yml +++ b/config/locales/simple_form.fa.yml @@ -3,6 +3,7 @@ fa: simple_form: hints: defaults: + autofollow: کسانی که از راه دعوت‌نامه عضو می‌شوند به طور خودکار پیگیر شما خواهند شد avatar: یکی از قالب‌های PNG یا GIF یا JPG. بیشترین اندازه ۲ مگابایت. تصویر به اندازهٔ ۴۰۰×۴۰۰ پیکسل تبدیل خواهد شد bot: این حساب بیشتر به طور خودکار فعالیت می‌کند و نظارت پیوسته‌ای روی آن وجود ندارد digest: تنها وقتی فرستاده می‌شود که مدتی طولانی فعالیتی نداشته باشید و در این مدت برای شما پیغام خصوصی‌ای نوشته شده باشد @@ -22,14 +23,13 @@ fa: data: پروندهٔ CSV که از سرور ماستدون دیگری برون‌سپاری شده sessions: otp: 'کد تأیید دومرحله‌ای که اپ روی تلفن شما ساخته را وارد کنید یا یکی از کدهای بازیابی را به کار ببرید:' - user: - filtered_languages: زبان‌های انتخاب‌شده از فهرست عمومی نوشته‌هایی که می‌بینید حذف می‌شوند labels: account: fields: name: برچسب value: محتوا defaults: + autofollow: دعوت از دیگران برای عضو شدن و پیگیری حساب شما avatar: تصویر نمایه bot: این حساب یک ربات است confirm_new_password: تأیید رمز تازه @@ -40,7 +40,6 @@ fa: email: نشانی ایمیل expires_in: تاریخ انقضا fields: اطلاعات تکمیلی نمایه - filtered_languages: زبان‌های فیلترشده header: تصویر زمینه locale: زبان locked: خصوصی‌کردن حساب diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml index b7b97395a..190790ca5 100644 --- a/config/locales/simple_form.fi.yml +++ b/config/locales/simple_form.fi.yml @@ -20,8 +20,6 @@ fi: data: Toisesta Mastodon-instanssista tuotu CSV-tiedosto sessions: otp: Syötä puhelimeen saamasi kaksivaiheisen tunnistautumisen koodi tai käytä palautuskoodia. - user: - filtered_languages: Valitut kielet suodatetaan pois julkisilta aikajanoilta labels: account: fields: @@ -36,7 +34,6 @@ fi: email: Sähköpostiosoite expires_in: Vanhenee fields: Profiilin metadata - filtered_languages: Suodatetut kielet header: Otsakekuva locale: Kieli locked: Lukitse tili diff --git a/config/locales/simple_form.fr.yml b/config/locales/simple_form.fr.yml index 4e535cdf4..5da562e19 100644 --- a/config/locales/simple_form.fr.yml +++ b/config/locales/simple_form.fr.yml @@ -3,6 +3,7 @@ fr: simple_form: hints: defaults: + autofollow: Les personnes qui s'inscrivent grâce à l'invitation vous suivront automatiquement avatar: Au format PNG, GIF ou JPG. 2 Mo maximum. Sera réduit à 400x400px bot: Ce compte exécute principalement des actions automatisées et pourrait ne pas être surveillé digest: Uniquement envoyé après une longue période d’inactivité et uniquement si vous avez reçu des messages personnels pendant votre absence @@ -22,14 +23,13 @@ fr: data: Un fichier CSV généré par une autre instance de Mastodon sessions: otp: 'Entrez le code d’authentification à deux facteurs généré par votre téléphone ou utilisez un de vos codes de récupération :' - user: - filtered_languages: Les langues sélectionnées seront filtrées hors de vos fils publics pour vous labels: account: fields: name: Étiquette value: Contenu defaults: + autofollow: Invitation à suivre votre compte avatar: Image de profil bot: Ceci est un robot confirm_new_password: Confirmation du nouveau mot de passe @@ -40,7 +40,6 @@ fr: email: Adresse courriel expires_in: Expire après fields: Métadonnées du profil - filtered_languages: Langues filtrées header: Image d’en-tête locale: Langue locked: Verrouiller le compte diff --git a/config/locales/simple_form.gl.yml b/config/locales/simple_form.gl.yml index bae49a65d..f4e1ec640 100644 --- a/config/locales/simple_form.gl.yml +++ b/config/locales/simple_form.gl.yml @@ -3,6 +3,7 @@ gl: simple_form: hints: defaults: + autofollow: As persoas que se conectaron a través de un convite seguirana automáticamente a vostede avatar: PNG, GIF ou JPG. Máximo 2MB. Será reducida a 400x400px bot: Esta conta realiza principalmente accións automatizadas e podería non estar monitorizada digest: Enviar só tras un longo período de inactividade e só si recibeu algunha mensaxe personal na súa ausencia @@ -22,14 +23,13 @@ gl: data: Ficheiro CSV exportado desde outra instancia Mastodon sessions: otp: Introduza o código de doble-factor xerado no aplicativo do seu móbil ou utilice un dos seus códigos de recuperación. - user: - filtered_languages: Os idiomas marcados filtraranse das liñas temporais públicas para vostede labels: account: fields: name: Etiqueta value: Contido defaults: + autofollow: Convide a seguir a súa conta avatar: Avatar bot: Esta conta é de un bot confirm_new_password: Confirme o novo contrasinal @@ -40,7 +40,6 @@ gl: email: enderezo correo electrónico expires_in: Caducidade despois de fields: Metadatos do perfil - filtered_languages: Idiomas filtrados header: Cabeceira locale: Idioma locked: Protexer conta diff --git a/config/locales/simple_form.he.yml b/config/locales/simple_form.he.yml index 20cf1029e..96cdccd2b 100644 --- a/config/locales/simple_form.he.yml +++ b/config/locales/simple_form.he.yml @@ -19,8 +19,6 @@ he: data: קובץ CSV שיוצא משרת מסטודון אחר sessions: otp: נא להקליד קוד אימות דו-שלבי ממכשירך או קוד אחזור גישה. - user: - filtered_languages: שפות שנבחרו יוסתרו מציר הזמן הציבורי בשבילך labels: defaults: avatar: תמונת פרופיל @@ -31,7 +29,6 @@ he: display_name: שם להצגה email: כתובת דוא"ל expires_in: תפוגה לאחר - filtered_languages: שפות מסוננות header: ראשה locale: שפה locked: הפוך חשבון לפרטי diff --git a/config/locales/simple_form.hu.yml b/config/locales/simple_form.hu.yml index 6ec39aa79..2b36dc85b 100644 --- a/config/locales/simple_form.hu.yml +++ b/config/locales/simple_form.hu.yml @@ -19,8 +19,6 @@ hu: data: Egy másik Mastodon szerverről exportált CSV fájl sessions: otp: Add meg a Második-faktor kódodat a telefonodról vagy használd az egyik tartalék bejelentkező kódodat. - user: - filtered_languages: A kiválasztott nyelvek nem jelennek majd meg a nyilvános idővonaladon labels: defaults: avatar: Profilkép @@ -31,7 +29,6 @@ hu: display_name: Megjelenített név email: E-mail cím expires_in: Elévül - filtered_languages: Szűrt nyelvek header: Fejléc locale: Nyelv locked: Zárt felhasználói fiók diff --git a/config/locales/simple_form.it.yml b/config/locales/simple_form.it.yml index cd77bffe3..948343240 100644 --- a/config/locales/simple_form.it.yml +++ b/config/locales/simple_form.it.yml @@ -3,6 +3,7 @@ it: simple_form: hints: defaults: + autofollow: Le persone che si iscrivono attraverso l'invito ti seguiranno automaticamente avatar: PNG, GIF o JPG. Al massimo 2MB. Verranno scalate a 400x400px bot: Questo account esegue principalmente operazioni automatiche e potrebbe non essere tenuto sotto controllo da una persona digest: Inviata solo dopo un lungo periodo di inattività e solo se hai ricevuto qualche messaggio personale in tua assenza @@ -22,14 +23,13 @@ it: data: File CSV esportato da un'altra istanza di Mastodon sessions: otp: 'Inserisci il codice a due fattori generato dall''app del tuo telefono o usa uno dei codici di recupero:' - user: - filtered_languages: Le lingue selezionate verranno filtrate dalla tua timeline pubblica labels: account: fields: name: Etichetta value: Contenuto defaults: + autofollow: Invita a seguire il tuo account avatar: Avatar bot: Questo account è un bot confirm_new_password: Conferma nuova password @@ -40,7 +40,6 @@ it: email: Indirizzo email expires_in: Scade dopo fields: Metadati del profilo - filtered_languages: Lingue filtrate header: Header locale: Lingua locked: Blocca account diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index d30afb4ab..4a475f831 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -3,14 +3,17 @@ ja: simple_form: hints: defaults: + autofollow: 招待から登録した人が自動的にあなたをフォローするようになります avatar: 2MBまでのPNG、GIF、JPGが利用可能です。400x400pxまで縮小されます bot: このアカウントは主に自動で動作し、人が見ていない可能性があります digest: 長期間使用していない場合と不在時に返信を受けた場合のみ送信されます display_name: あと%{count}文字入力できます。 fields: プロフィールに表として4つまでの項目を表示することができます header: 2MBまでのPNG、GIF、JPGが利用可能です。 700x335pxまで縮小されます + locale: ユーザーインターフェース、メールやプッシュ通知の言語 locked: フォロワーを手動で承認する必要があります note: あと%{count}文字入力できます。 + setting_default_language: トゥートの言語は自動的に検出されますが、必ずしも正確とは限りません setting_hide_network: フォローとフォロワーの情報がプロフィールページで見られないようにします setting_noindex: 公開プロフィールおよび各投稿ページに影響します setting_theme: ログインしている全てのデバイスで適用されるデザインです。 @@ -19,15 +22,17 @@ ja: sessions: otp: '携帯電話のアプリで生成された二段階認証コードを入力するか、リカバリーコードを使用してください:' user: - filtered_languages: 選択した言語があなたの公開タイムラインから取り除かれます + chosen_languages: 選択すると、選択した言語のトゥートのみが公開タイムラインに表示されるようになります labels: account: fields: name: ラベル value: 内容 defaults: + autofollow: あなたのアカウントに招待する avatar: アイコン bot: これは BOT アカウントです + chosen_languages: 除外する言語 confirm_new_password: 新しいパスワード(確認用) confirm_password: パスワード(確認用) current_password: 現在のパスワード @@ -36,7 +41,6 @@ ja: email: メールアドレス expires_in: 有効期限 fields: プロフィール補足情報 - filtered_languages: 除外する言語 header: ヘッダー locale: 言語 locked: 承認制アカウントにする @@ -47,6 +51,7 @@ ja: password: パスワード setting_auto_play_gif: アニメーションGIFを自動再生する setting_boost_modal: ブーストする前に確認ダイアログを表示する + setting_default_language: 投稿する言語 setting_default_privacy: 投稿の公開範囲 setting_default_sensitive: メディアを常に閲覧注意としてマークする setting_delete_modal: トゥートを削除する前に確認ダイアログを表示する diff --git a/config/locales/simple_form.ko.yml b/config/locales/simple_form.ko.yml index b9954e0ad..7eb0da8b1 100644 --- a/config/locales/simple_form.ko.yml +++ b/config/locales/simple_form.ko.yml @@ -3,6 +3,7 @@ ko: simple_form: hints: defaults: + autofollow: 이 초대를 통해 가입하는 사람은 당신을 자동으로 팔로우 하게 됩니다 avatar: PNG, GIF 혹은 JPG. 최대 2MB. 400x400px로 다운스케일 될 것임 bot: 사람들에게 계정이 사람이 아님을 알립니다 digest: 오랫동안 활동하지 않았을 때 받은 멘션들에 대한 요약 받기 @@ -11,10 +12,12 @@ ko: other: %{count} 글자 남음 fields: 당신의 프로파일에 최대 4개까지 표 형식으로 나타낼 수 있습니다 header: PNG, GIF 혹은 JPG. 최대 2MB. 700x335px로 다운스케일 됨 + locale: 유저 인터페이스, 이메일, 푸시 알림 언어 locked: 수동으로 팔로워를 승인하고, 기본 툿 프라이버시 설정을 팔로워 전용으로 변경 note: one: 1 글자 남음 other: %{count} 글자 남음 + setting_default_language: 작성한 툿의 언어는 자동으로 인식할 수 있지만, 언제나 정확한 건 아닙니다 setting_hide_network: 나를 팔로우 하는 사람들과 내가 팔로우 하는 사람들이 내 프로필에 표시되지 않게 합니다 setting_noindex: 공개 프로필 및 각 툿페이지에 영향을 미칩니다 setting_theme: 로그인중인 모든 디바이스에 적용되는 디자인입니다. @@ -23,15 +26,17 @@ ko: sessions: otp: '휴대전화에서 생성 된 2단계 인증 코드를 입력하거나, 복구 코드 중 하나를 사용하세요:' user: - filtered_languages: 선택된 언어가 공개 타임라인에서 제외 될 것입니다 + chosen_languages: 체크하면, 선택 된 언어들만 공개 타임라인에 보여집니다 labels: account: fields: name: 라벨 value: 내용 defaults: + autofollow: 초대를 통한 팔로우 avatar: 아바타 bot: 이것은 봇 계정입니다 + chosen_languages: 언어 필터링 confirm_new_password: 새로운 비밀번호 다시 입력 confirm_password: 현재 비밀번호 다시 입력 current_password: 현재 비밀번호 입력 @@ -40,9 +45,8 @@ ko: email: 이메일 주소 expires_in: 만료시각 fields: 프로필 메타데이터 - filtered_languages: 숨긴 언어들 header: 헤더 - locale: 언어 + locale: 인터페이스 언어 locked: 계정 잠금 max_uses: 사용 횟수 제한 new_password: 새로운 비밀번호 입력 @@ -51,6 +55,7 @@ ko: password: 비밀번호 setting_auto_play_gif: 애니메이션 GIF를 자동 재생 setting_boost_modal: 부스트 전 확인 창을 표시 + setting_default_language: 게시물 언어 setting_default_privacy: 툿 프라이버시 setting_default_sensitive: 미디어를 언제나 민감한 컨텐츠로 설정 setting_delete_modal: 툿 삭제 전 확인 창을 표시 diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml index 68aa0635d..591a9f2d9 100644 --- a/config/locales/simple_form.nl.yml +++ b/config/locales/simple_form.nl.yml @@ -3,6 +3,7 @@ nl: simple_form: hints: defaults: + autofollow: Mensen die zich via de uitnodiging hebben geregistreerd, volgen jou automatisch avatar: PNG, GIF of JPG. Maximaal 2MB. Wordt teruggeschaald naar 400x400px bot: Dit is een geautomatiseerd account en wordt mogelijk niet gemonitord digest: Wordt alleen na een lange periode van inactiviteit verzonden en alleen wanneer je tijdens jouw afwezigheid persoonlijke berichten hebt ontvangen @@ -11,10 +12,12 @@ nl: other: %{count} tekens over fields: Je kan maximaal 4 items als een tabel op je profiel weergeven header: PNG, GIF of JPG. Maximaal 2MB. Wordt teruggeschaald naar 700x335px + locale: De taal van de gebruikersomgeving, e-mails en pushmeldingen locked: Vereist dat je handmatig volgers moet accepteren note: one: 1 teken over other: %{count} tekens over + setting_default_language: De taal van jouw toots kan automatisch worden gedetecteerd, maar het is niet altijd accuraat setting_hide_network: Wie jij volgt en wie jou volgen wordt niet op jouw profiel getoond setting_noindex: Heeft invloed op jouw openbare profiel en toots setting_theme: Heeft invloed op hoe de webapp van Mastodon eruitziet (op elk apparaat waarmee je inlogt). @@ -23,15 +26,17 @@ nl: sessions: otp: Voer de tweestaps-aanmeldcode vanaf jouw mobiele telefoon in of gebruik een van jouw herstelcodes. user: - filtered_languages: Geselecteerde talen worden uit de lokale en globale tijdlijn verwijderd + chosen_languages: Alleen toots in de aangevinkte talen worden op de openbare tijdlijnen getoond labels: account: fields: name: Label value: Inhoud defaults: + autofollow: Uitnodigen om jouw account te volgen avatar: Avatar bot: Dit is een bot-account + chosen_languages: Talen filteren confirm_new_password: Nieuw wachtwoord bevestigen confirm_password: Wachtwoord bevestigen current_password: Huidig wachtwoord @@ -40,9 +45,8 @@ nl: email: E-mailadres expires_in: Vervalt na fields: Metadata profiel - filtered_languages: Gefilterde talen header: Omslagfoto - locale: Taal + locale: Taal van de gebruikersomgeving locked: Maak account besloten max_uses: Max. aantal keer te gebruiken new_password: Nieuwe wachtwoord @@ -51,6 +55,7 @@ nl: password: Wachtwoord setting_auto_play_gif: Speel geanimeerde GIF's automatisch af setting_boost_modal: Vraag voor het boosten van een toot een bevestiging + setting_default_language: Taal van jouw toots setting_default_privacy: Zichtbaarheid toots setting_default_sensitive: Media altijd als gevoelig markeren setting_delete_modal: Vraag voor het verwijderen van een toot een bevestiging diff --git a/config/locales/simple_form.no.yml b/config/locales/simple_form.no.yml index 48710cabd..aba8feeb6 100644 --- a/config/locales/simple_form.no.yml +++ b/config/locales/simple_form.no.yml @@ -19,8 +19,6 @@ data: CSV-fil eksportert fra en annen Mastodon-instans sessions: otp: Angi tofaktorkoden fra din telefon eller bruk en av dine gjenopprettingskoder. - user: - filtered_languages: Språk som er avhuket vil ikke vises på offentlige tidslinjer fra deg labels: defaults: avatar: Avatar @@ -31,7 +29,6 @@ display_name: Visningsnavn email: E-postadresse expires_in: Utløper etter - filtered_languages: Filtrerte språk header: Overskrift locale: Språk locked: Lås konto diff --git a/config/locales/simple_form.oc.yml b/config/locales/simple_form.oc.yml index 65b27e716..df3ffe793 100644 --- a/config/locales/simple_form.oc.yml +++ b/config/locales/simple_form.oc.yml @@ -3,6 +3,7 @@ oc: simple_form: hints: defaults: + autofollow: Lo monde que se marcan gràcia a l’invitacion vos segràn automaticament avatar: PNG, GIF o JPG. Maximum 2 Mo. Serà retalhat en 400x400px bot: Avisar lo monde qu’aqueste compte es pas d’una persona digest: Solament enviat aprèp un long moment d’inactivitat e solament s’avètz recebut de messatges personals pendent vòstra abséncia @@ -11,10 +12,12 @@ oc: other: Demòran encara %{count} caractèrs fields: Podètz far veire cap a 4 elements sus vòstre perfil header: PNG, GIF o JPG. Maximum 2 Mo. Serà retalhada en 700x335px + locale: La lenga de l’interfàcia d’utilizacion, los messatges e las notificacions locked: Demanda qu’acceptetz manualament lo mond que vos sègon e botarà la visibilitat de vòstras publicacions coma accessiblas a vòstres seguidors solament note: one: Demòra encara 1 caractèr other: Demòran encara %{count} caractèrs + setting_default_language: La lenga de vòstres tuts pòt èsser detectada automaticament, mas de còps es pas corrèctament determinada setting_hide_network: Vòstre perfil mostrarà pas los que vos sègon e lo monde que seguètz setting_noindex: Aquò es destinat a vòstre perfil public e vòstra pagina d’estatuts setting_theme: Aquò càmbia lo tèma grafic de Mastodon quand sètz connectat qual que siasque lo periferic. @@ -23,15 +26,17 @@ oc: sessions: otp: 'Picatz lo còdi d’autentificacion en dos temps (Two factor code) de vòstra aplicacion mobil o utilizatz un de vòstres còdis de recuperacion :' user: - filtered_languages: Las lengas seleccionadas seràn levadas de vòstre flux d’actualitat + chosen_languages: Quand seleccionadas, solament los tuts dins las lengas triadas seràn mostrats dins vòstre flux d’actualitat labels: account: fields: name: Nom value: Contengut defaults: + autofollow: Convidar a sègre vòstre compte avatar: Avatar bot: Aquò es lo compte a un robòt + chosen_languages: Filtrar las lengas confirm_new_password: Confirmacion del nòu senhal confirm_password: Confirmatz lo nòu senhal current_password: Senhal actual @@ -40,9 +45,8 @@ oc: email: Corrièl expires_in: Expira aprèp fields: Metadonada del perfil - filtered_languages: Lengas filtradas header: Bandièra - locale: Lenga + locale: Lenga de l’interfàcia locked: Far venir lo compte privat max_uses: Limit d’utilizacions new_password: Nòu senhal @@ -51,6 +55,7 @@ oc: password: Senhal setting_auto_play_gif: Lectura automatica dels GIFS animats setting_boost_modal: Afichar una fenèstra de confirmacion abans de partejar un estatut + setting_default_language: Lenga de publicacion setting_default_privacy: Confidencialitat de las publicacions setting_default_sensitive: Totjorn marcar los mèdias coma sensibles setting_delete_modal: Afichar una fenèstra de confirmacion abans de suprimir un estatut diff --git a/config/locales/simple_form.pl.yml b/config/locales/simple_form.pl.yml index 66f2a0f0b..237bd0342 100644 --- a/config/locales/simple_form.pl.yml +++ b/config/locales/simple_form.pl.yml @@ -3,8 +3,9 @@ pl: simple_form: hints: defaults: + autofollow: Osoby, które zarejestrują się z Twojego zaproszenia automatycznie zaczną Cię śledzić avatar: PNG, GIF lub JPG. Maksymalnie 2MB. Zostanie zmniejszony do 400x400px - bot: Informuje użytkowników, że konto nie jest prowadzone przez człowieka + bot: To konto wykonuje głównie zautomatyzowane działania i może nie być monitorowane digest: Wysyłane tylko po długiej nieaktywności, jeżeli w tym czasie otrzymaleś jakąś wiadomość bezpośrednią display_name: few: Pozostały %{count} znaki. @@ -13,12 +14,14 @@ pl: other: Pozostało %{count} znaków fields: Możesz ustawić maksymalnie 4 niestandardowe pola wyświetlane jako tabela na Twoim profilu header: PNG, GIF lub JPG. Maksymalnie 2MB. Zostanie zmniejszony do 700x335px + locale: Język interfejsu, wiadomości e-mail i powiadomieniach push locked: Musisz akceptować prośby o śledzenie note: few: Pozostały %{count} znaki. many: Pozostało %{count} znaków one: Pozostał 1 znak other: Pozostało %{count} znaków + setting_default_language: Język Twoich wpisów może być wykrywany automatycznie, ale nie zawsze jest to dokładne setting_hide_network: Informacje o tym, kto Cię śledzi i kogo śledzisz nie będą widoczne setting_noindex: Wpływa na widoczność strony profilu i Twoich wpisów setting_theme: Zmienia wygląd Mastodona po zalogowaniu z dowolnego urządzenia. @@ -27,15 +30,17 @@ pl: sessions: otp: 'Wprowadź kod weryfikacji dwuetapowej z telefonu lub wykorzystaj jeden z kodów zapasowych:' user: - filtered_languages: Wpisy w wybranych językach nie będą wyświetlać się na publicznych osiach czasu + chosen_languages: Jeżeli zaznaczone, tylko wpisy w wybranych językach będą wyświetlane na publicznych osiach czasu labels: account: fields: name: Nazwa value: Zawartość defaults: + autofollow: Zapraszaj do śledzenia swojego konta avatar: Awatar bot: To konto jest prowadzone przez bota + chosen_languages: Filtrowanie języków confirm_new_password: Potwierdź nowe hasło confirm_password: Potwierdź hasło current_password: Obecne hasło @@ -44,9 +49,8 @@ pl: email: Adres e-mail expires_in: Wygaśnie po fields: Metadane profilu - filtered_languages: Filtrowane języki header: Nagłówek - locale: Język + locale: Język interfejsu locked: Ustaw konto jako prywatne max_uses: Maksymalna liczba użyć new_password: Nowe hasło @@ -55,6 +59,7 @@ pl: password: Hasło setting_auto_play_gif: Automatycznie odtwarzaj animowane GIFy setting_boost_modal: Pytaj o potwierdzenie przed podbiciem + setting_default_language: Język wpisów setting_default_privacy: Widoczność wpisów setting_default_sensitive: Zawsze oznaczaj zawartość multimedialną jako wrażliwą setting_delete_modal: Pytaj o potwierdzenie przed usunięciem wpisu diff --git a/config/locales/simple_form.pt-BR.yml b/config/locales/simple_form.pt-BR.yml index 50ed5eb1a..cec96739f 100644 --- a/config/locales/simple_form.pt-BR.yml +++ b/config/locales/simple_form.pt-BR.yml @@ -22,8 +22,6 @@ pt-BR: data: Arquivo CSV exportado de outra instância do Mastodon sessions: otp: 'Insira o código de autenticação gerado pelo app no seu celular ou use um dos códigos de recuperação:' - user: - filtered_languages: Selecione os idiomas que devem ser removidos de suas timelines públicas labels: account: fields: @@ -40,7 +38,6 @@ pt-BR: email: Endereço de e-mail expires_in: Expira em fields: Metadados do perfil - filtered_languages: Idiomas filtrados header: Cabeçalho locale: Idioma locked: Trancar conta diff --git a/config/locales/simple_form.pt.yml b/config/locales/simple_form.pt.yml index 67fed495c..5b79bd29f 100644 --- a/config/locales/simple_form.pt.yml +++ b/config/locales/simple_form.pt.yml @@ -19,8 +19,6 @@ pt: data: Arquivo CSV exportado de outra instância do Mastodon sessions: otp: Inserir o código de autenticação de dois factores do teu telemóvel ou usa um dos códigos de recuperação. - user: - filtered_languages: Seleciona os idiomas que devem ser removidos das tuas timelines públicas labels: defaults: avatar: Imagem de Perfil @@ -31,7 +29,6 @@ pt: display_name: Nome Público email: Endereço de e-mail expires_in: Expira em - filtered_languages: Idiomas filtrados header: Cabeçalho locale: Idioma locked: Trancar conta diff --git a/config/locales/simple_form.ru.yml b/config/locales/simple_form.ru.yml index a6b50b9d2..6bb95b13f 100644 --- a/config/locales/simple_form.ru.yml +++ b/config/locales/simple_form.ru.yml @@ -26,8 +26,6 @@ ru: data: Файл CSV, экспортированный с другого узла Mastodon sessions: otp: 'Введите код двухфакторной аутентификации, сгенерированный в мобильном приложении, или используйте один из Ваших кодов восстановления:' - user: - filtered_languages: Выбранные языки будут убраны из Ваших публичных лет. labels: account: fields: @@ -44,7 +42,6 @@ ru: email: Адрес e-mail expires_in: Срок действия fields: Метаданные профиля - filtered_languages: Фильтруемые языки header: Заголовок locale: Язык locked: Сделать аккаунт закрытым diff --git a/config/locales/simple_form.sk.yml b/config/locales/simple_form.sk.yml index ae0dc6af5..7ebd26630 100644 --- a/config/locales/simple_form.sk.yml +++ b/config/locales/simple_form.sk.yml @@ -3,6 +3,7 @@ sk: simple_form: hints: defaults: + autofollow: Ľudia ktorí sa zaregistrujú prostredníctvom pozvánky, ťa budú inheď následovať avatar: PNG, GIF alebo JPG. Maximálne 2MB. Bude zmenšený na 400x400px bot: Tento účet vykonáva hlavne automatizované akcie, a je pravdepodobne nespravovaný digest: Odoslané iba v prípade dlhodobej neprítomnosti, a len ak si obdŕžal/a nejaké osobné správy kým si bol/a preč @@ -12,6 +13,7 @@ sk: other: Ostáva ti %{count} znakov fields: Môžeš mať 4 položky na svojom profile zobrazené vo forme tabuľky header: PNG, GIF alebo JPG. Maximálne 2MB. Bude zmenšený na 700x335px + locale: Jazyk užívateľského rozhrania, emailových a nástenkových oboznámení locked: Vyžaduje manuálne schvalovať sledujúcich note: few: Ostávajú ti %{count} znaky @@ -24,16 +26,16 @@ sk: data: CSV súbor vyexportovaný z inej Mastodon inštancie sessions: otp: 'Napíš sem dvoj-faktorový kód z telefónu, alebo použi jeden z tvojích obnovovacích kódov:' - user: - filtered_languages: Zaškrtnuté jazyky budú pre teba vynechané z verejnej časovej osi labels: account: fields: name: Označenie value: Obsah defaults: + autofollow: Pozvi k následovaniu tvojho profilu avatar: Avatar bot: Toto je automatizovaný bot účet + chosen_languages: Filtruj jazyky confirm_new_password: Znovu tvoje nové heslo, pre potvrdenie confirm_password: Potvrď heslo current_password: Súčasné heslo @@ -42,9 +44,8 @@ sk: email: Emailová adresa expires_in: Expirovať po fields: Metadáta profilu - filtered_languages: Vynechanie jazykov header: Obrázok v hlavičke - locale: Jazyk + locale: Jazyk rozhrania locked: Zamknúť účet max_uses: Maximálne možno použiť new_password: Nové heslo @@ -69,7 +70,7 @@ sk: username_or_email: Prezívka, alebo email interactions: must_be_follower: Blokovať oznámenia od užívateľov, ktorí ťa nesledujú - must_be_following: Blokovať oznámenia od ľudí ktorých nesleduješ + must_be_following: Blokovať oboznámenia ohľadom ľudí ktorých nesleduješ must_be_following_dm: Blokovať súkromné správy od ľudí ktorých nesleduješ notification_emails: digest: Posielať súhrnné emaily diff --git a/config/locales/simple_form.sr-Latn.yml b/config/locales/simple_form.sr-Latn.yml index 30f7eada7..608630c0c 100644 --- a/config/locales/simple_form.sr-Latn.yml +++ b/config/locales/simple_form.sr-Latn.yml @@ -23,8 +23,6 @@ sr-Latn: data: CSV fajl izvezen sa druge Mastodont instance sessions: otp: Unesite dvofaktorski kod sa Vašeg telefona ili koristite jedan od kodova za oporavak. - user: - filtered_languages: Označeni jezici će za Vas biti isfiltrirani sa javnih lajni labels: defaults: avatar: Avatar @@ -35,7 +33,6 @@ sr-Latn: display_name: Ime za prikaz email: Adresa e-pošte expires_in: Ističe nakon - filtered_languages: Filtrirani jezici header: Zaglavlje locale: Jezik locked: Zaključaj nalog diff --git a/config/locales/simple_form.sr.yml b/config/locales/simple_form.sr.yml index 3345f7b41..ab9ef0f49 100644 --- a/config/locales/simple_form.sr.yml +++ b/config/locales/simple_form.sr.yml @@ -23,8 +23,6 @@ sr: data: CSV фајл извезен са друге Мастодонт инстанце sessions: otp: Унесите двофакторски код са Вашег телефона или користите један од кодова за опоравак. - user: - filtered_languages: Означени језици ће за Вас бити исфилтрирани са јавних лајни labels: defaults: avatar: Аватар @@ -35,7 +33,6 @@ sr: display_name: Име за приказ email: Адреса е-поште expires_in: Истиче након - filtered_languages: Филтрирани језици header: Заглавље locale: Језик locked: Закључај налог diff --git a/config/locales/simple_form.sv.yml b/config/locales/simple_form.sv.yml index f027d684b..346ab3931 100644 --- a/config/locales/simple_form.sv.yml +++ b/config/locales/simple_form.sv.yml @@ -22,8 +22,6 @@ sv: data: CSV-fil som exporteras från en annan Mastodon-instans sessions: otp: 'Ange tvåfaktorkoden genererad från din telefonapp eller använd någon av dina återställningskoder:' - user: - filtered_languages: Kontrollerade språk filtreras från offentliga tidslinjer för dig labels: account: fields: @@ -40,7 +38,6 @@ sv: email: E-postadress expires_in: Förfaller efter fields: Profil-metadata - filtered_languages: Filtrerade språk header: Bakgrundsbild locale: Språk locked: Lås konto diff --git a/config/locales/simple_form.zh-CN.yml b/config/locales/simple_form.zh-CN.yml index 5b3b25ab1..f1947e961 100644 --- a/config/locales/simple_form.zh-CN.yml +++ b/config/locales/simple_form.zh-CN.yml @@ -3,6 +3,7 @@ zh-CN: simple_form: hints: defaults: + autofollow: 通过邀请链接注册的用户将会自动关注你 avatar: 文件大小限制 2MB,只支持 PNG、GIF 或 JPG 格式。图片分辨率将会压缩至 400×400px bot: 来自这个帐户的绝大多数操作都是自动进行的,并且可能无人监控 digest: 仅在你长时间未登录,且收到了私信时发送 @@ -18,14 +19,13 @@ zh-CN: data: 请上传从其他 Mastodon 实例导出的 CSV 文件 sessions: otp: 输入你手机应用上生成的双重认证码,或者任意一个恢复代码: - user: - filtered_languages: 被勾选语言的嘟文将不会出现在你的公共时间轴上 labels: account: fields: name: 标签 value: 内容 defaults: + autofollow: 让被邀请人关注你的帐户 avatar: 头像 bot: 这是一个机器人帐户 confirm_new_password: 确认新密码 @@ -36,7 +36,6 @@ zh-CN: email: 电子邮件地址 expires_in: 失效时间 fields: 个人资料附加信息 - filtered_languages: 语言过滤 header: 个人资料页横幅图片 locale: 语言 locked: 保护你的帐户(锁嘟) diff --git a/config/locales/simple_form.zh-HK.yml b/config/locales/simple_form.zh-HK.yml index 06d3f6f6c..7a1cae68d 100644 --- a/config/locales/simple_form.zh-HK.yml +++ b/config/locales/simple_form.zh-HK.yml @@ -22,8 +22,6 @@ zh-HK: data: 自其他服務站匯出的 CSV 檔案 sessions: otp: 輸入你手機上生成的雙重認證碼,或者任意一個恢復代碼: - user: - filtered_languages: 下面被選擇的語言的文章將不會出現在你的公共時間軸上 labels: account: fields: @@ -40,7 +38,6 @@ zh-HK: email: 電郵地址 expires_in: 失效時間 fields: 資料 - filtered_languages: 封鎖下面語言的文章 header: 個人頁面頂部 locale: 語言 locked: 將用戶轉為「私人」 diff --git a/config/locales/simple_form.zh-TW.yml b/config/locales/simple_form.zh-TW.yml index c7c5a37f0..a3f6627af 100644 --- a/config/locales/simple_form.zh-TW.yml +++ b/config/locales/simple_form.zh-TW.yml @@ -10,8 +10,6 @@ zh-TW: note: 最多 160 個字元 imports: data: 自其他服務站匯出的 CSV 檔案 - user: - filtered_languages: 下面被選擇的語言的文章將不會出現在你的公共時間軸上。 labels: defaults: avatar: 大頭貼 @@ -21,7 +19,6 @@ zh-TW: data: 資料 display_name: 顯示名稱 email: 電子信箱 - filtered_languages: 封鎖下面語言的文章 header: 個人頁面頂部 locale: 語言 locked: 將帳號轉為「私密」 diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 6dd8ece09..278191599 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -26,7 +26,7 @@ sk: within_reach_title: Stále v dosahu generic_description: "%{domain} je jeden server v sieti" hosted_on: Mastodon hostovaný na %{domain} - learn_more: Dozvedieť sa viac + learn_more: Zisti viac other_instances: Zoznam ďalších inštancií source_code: Zdrojový kód status_count_after: príspevkov @@ -435,10 +435,11 @@ sk: about_x_years: "%{count}rok" almost_x_years: "%{count}rok" half_a_minute: Práve teraz + less_than_x_minutes: "%{count}min" less_than_x_seconds: Práve teraz over_x_years: "%{count}rok" x_days: "%{count}dni" - x_minutes: '' + x_minutes: "%{count}min" x_months: "%{count}mesiace" x_seconds: "%{count}sek" deletes: @@ -516,6 +517,7 @@ sk: '86400': 1 deň expires_in_prompt: Nikdy generate: Vygeneruj + invited_by: 'Bol/a si pozvan/á užívateľom:' max_uses: few: "%{count} použitia" one: jedno použitie @@ -660,6 +662,7 @@ sk: disallowed_hashtags: one: 'obsahuje nepovolený haštag: %{tags}' other: 'obsahuje nepovolené haštagy: %{tags}' + language_detection: Zisti jazyk automaticky open_in_web: Otvor v okne prehliadača over_character_limit: limit počtu %{max} znakov bol presiahnutý pin_errors: diff --git a/config/locales/sl.yml b/config/locales/sl.yml index 43c31b3b7..6f581f838 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -103,3 +103,4 @@ sl: alphabetic: Po abecedi most_recent: Najnovejše title: Red + promote: Spodbujanje diff --git a/config/locales/sr.yml b/config/locales/sr.yml index d34a2ecbf..040090932 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -4,6 +4,7 @@ sr: about_hashtag_html: Ово су јавни статуси таговани са #%{hashtag}. Можете одговарати на њих ако имате налог било где у федиверсу. about_mastodon_html: Мастодонт је друштвена мрежа базирана на отвореним протоколима и слободном софтверу отвореног кода. Децентрализована је као што је децентрализована е-пошта. about_this: О инстанци + administered_by: 'Администрирано од стране:' closed_registrations: Регистрације су тренутно затворене на овој инстанци. Ипак! Можете наћи другу инстанцу на којој ћете направити налог и одатле добити приступ истој овој мрежи. contact: Контакт contact_missing: Није постављено diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 267eeafc6..9abffa01a 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -510,6 +510,7 @@ zh-CN: '86400': 1 天后 expires_in_prompt: 永不过期 generate: 生成邀请链接 + invited_by: 你的邀请人是: max_uses: "%{count} 次" max_uses_prompt: 无限制 prompt: 生成分享链接,邀请他人在本实例注册 diff --git a/db/migrate/20180615122121_add_autofollow_to_invites.rb b/db/migrate/20180615122121_add_autofollow_to_invites.rb new file mode 100644 index 000000000..850b1d693 --- /dev/null +++ b/db/migrate/20180615122121_add_autofollow_to_invites.rb @@ -0,0 +1,17 @@ +require Rails.root.join('lib', 'mastodon', 'migration_helpers') + +class AddAutofollowToInvites < ActiveRecord::Migration[5.2] + include Mastodon::MigrationHelpers + + disable_ddl_transaction! + + def change + safety_assured do + add_column_with_default :invites, :autofollow, :bool, default: false, allow_null: false + end + end + + def down + remove_column :invites, :autofollow + end +end diff --git a/db/migrate/20180616192031_add_chosen_languages_to_users.rb b/db/migrate/20180616192031_add_chosen_languages_to_users.rb new file mode 100644 index 000000000..48b53019d --- /dev/null +++ b/db/migrate/20180616192031_add_chosen_languages_to_users.rb @@ -0,0 +1,5 @@ +class AddChosenLanguagesToUsers < ActiveRecord::Migration[5.2] + def change + add_column :users, :chosen_languages, :string, array: true, null: true, default: nil + end +end diff --git a/db/migrate/20180617162849_remove_unused_indexes.rb b/db/migrate/20180617162849_remove_unused_indexes.rb new file mode 100644 index 000000000..61add6385 --- /dev/null +++ b/db/migrate/20180617162849_remove_unused_indexes.rb @@ -0,0 +1,7 @@ +class RemoveUnusedIndexes < ActiveRecord::Migration[5.2] + def change + remove_index :statuses, name: "index_statuses_on_conversation_id" + remove_index :users, name: "index_users_on_filtered_languages" + remove_index :backups, name: "index_backups_on_user_id" + end +end diff --git a/db/schema.rb b/db/schema.rb index cf90cd6f0..bba0b6102 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_06_09_104432) do +ActiveRecord::Schema.define(version: 2018_06_17_162849) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -103,7 +103,6 @@ ActiveRecord::Schema.define(version: 2018_06_09_104432) do t.boolean "processed", default: false, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index ["user_id"], name: "index_backups_on_user_id" end create_table "blocks", force: :cascade do |t| @@ -219,6 +218,7 @@ ActiveRecord::Schema.define(version: 2018_06_09_104432) do t.integer "uses", default: 0, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.boolean "autofollow", default: false, null: false t.index ["code"], name: "index_invites_on_code", unique: true t.index ["user_id"], name: "index_invites_on_user_id" end @@ -448,7 +448,6 @@ ActiveRecord::Schema.define(version: 2018_06_09_104432) do t.bigint "application_id" t.bigint "in_reply_to_account_id" t.index ["account_id", "id", "visibility", "updated_at"], name: "index_statuses_20180106", order: { id: :desc } - t.index ["conversation_id"], name: "index_statuses_on_conversation_id" t.index ["in_reply_to_id"], name: "index_statuses_on_in_reply_to_id" t.index ["reblog_of_id", "account_id"], name: "index_statuses_on_reblog_of_id_and_account_id" t.index ["uri"], name: "index_statuses_on_uri", unique: true @@ -525,10 +524,10 @@ ActiveRecord::Schema.define(version: 2018_06_09_104432) do t.boolean "moderator", default: false, null: false t.bigint "invite_id" t.string "remember_token" + t.string "chosen_languages", array: true t.index ["account_id"], name: "index_users_on_account_id" t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true t.index ["email"], name: "index_users_on_email", unique: true - t.index ["filtered_languages"], name: "index_users_on_filtered_languages", using: :gin t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 0313f4ccf..45211f535 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -13,7 +13,7 @@ module Mastodon end def patch - 1 + 2 end def pre diff --git a/spec/controllers/admin/accounts_controller_spec.rb b/spec/controllers/admin/accounts_controller_spec.rb index ff9dbbfb8..197e019fe 100644 --- a/spec/controllers/admin/accounts_controller_spec.rb +++ b/spec/controllers/admin/accounts_controller_spec.rb @@ -3,13 +3,11 @@ require 'rails_helper' RSpec.describe Admin::AccountsController, type: :controller do render_views - let(:user) { Fabricate(:user, admin: true) } - - before do - sign_in user, scope: :user - end + before { sign_in current_user, scope: :user } describe 'GET #index' do + let(:current_user) { Fabricate(:user, admin: true) } + around do |example| default_per_page = Account.default_per_page Account.paginates_per 1 @@ -68,6 +66,7 @@ RSpec.describe Admin::AccountsController, type: :controller do end describe 'GET #show' do + let(:current_user) { Fabricate(:user, admin: true) } let(:account) { Fabricate(:account, username: 'bob') } it 'returns http success' do @@ -75,4 +74,219 @@ RSpec.describe Admin::AccountsController, type: :controller do expect(response).to have_http_status(200) end end + + + describe 'POST #subscribe' do + subject { post :subscribe, params: { id: account.id } } + + let(:current_user) { Fabricate(:user, admin: admin) } + let(:account) { Fabricate(:account) } + + context 'when user is admin' do + let(:admin) { true } + + it { is_expected.to redirect_to admin_account_path(account.id) } + end + + context 'when user is not admin' do + let(:admin) { false } + + it { is_expected.to have_http_status :forbidden } + end + end + + describe 'POST #unsubscribe' do + subject { post :unsubscribe, params: { id: account.id } } + + let(:current_user) { Fabricate(:user, admin: admin) } + let(:account) { Fabricate(:account) } + + context 'when user is admin' do + let(:admin) { true } + + it { is_expected.to redirect_to admin_account_path(account.id) } + end + + context 'when user is not admin' do + let(:admin) { false } + + it { is_expected.to have_http_status :forbidden } + end + end + + describe 'POST #memorialize' do + subject { post :memorialize, params: { id: account.id } } + + let(:current_user) { Fabricate(:user, admin: current_user_admin) } + let(:account) { Fabricate(:account, user: user) } + let(:user) { Fabricate(:user, admin: target_user_admin) } + + context 'when user is admin' do + let(:current_user_admin) { true } + + context 'when target user is admin' do + let(:target_user_admin) { true } + + it 'fails to memorialize account' do + is_expected.to have_http_status :forbidden + expect(account.reload).not_to be_memorial + end + end + + context 'when target user is not admin' do + let(:target_user_admin) { false } + + it 'succeeds in memorializing account' do + is_expected.to redirect_to admin_account_path(account.id) + expect(account.reload).to be_memorial + end + end + end + + context 'when user is not admin' do + let(:current_user_admin) { false } + + context 'when target user is admin' do + let(:target_user_admin) { true } + + it 'fails to memorialize account' do + is_expected.to have_http_status :forbidden + expect(account.reload).not_to be_memorial + end + end + + context 'when target user is not admin' do + let(:target_user_admin) { false } + + it 'fails to memorialize account' do + is_expected.to have_http_status :forbidden + expect(account.reload).not_to be_memorial + end + end + end + end + + describe 'POST #enable' do + subject { post :enable, params: { id: account.id } } + + let(:current_user) { Fabricate(:user, admin: admin) } + let(:account) { Fabricate(:account, user: user) } + let(:user) { Fabricate(:user, disabled: true) } + + context 'when user is admin' do + let(:admin) { true } + + it 'succeeds in enabling account' do + is_expected.to redirect_to admin_account_path(account.id) + expect(user.reload).not_to be_disabled + end + end + + context 'when user is not admin' do + let(:admin) { false } + + it 'fails to enable account' do + is_expected.to have_http_status :forbidden + expect(user.reload).to be_disabled + end + end + end + + describe 'POST #disable' do + subject { post :disable, params: { id: account.id } } + + let(:current_user) { Fabricate(:user, admin: current_user_admin) } + let(:account) { Fabricate(:account, user: user) } + let(:user) { Fabricate(:user, disabled: false, admin: target_user_admin) } + + context 'when user is admin' do + let(:current_user_admin) { true } + + context 'when target user is admin' do + let(:target_user_admin) { true } + + it 'fails to disable account' do + is_expected.to have_http_status :forbidden + expect(user.reload).not_to be_disabled + end + end + + context 'when target user is not admin' do + let(:target_user_admin) { false } + + it 'succeeds in disabling account' do + is_expected.to redirect_to admin_account_path(account.id) + expect(user.reload).to be_disabled + end + end + end + + context 'when user is not admin' do + let(:current_user_admin) { false } + + context 'when target user is admin' do + let(:target_user_admin) { true } + + it 'fails to disable account' do + is_expected.to have_http_status :forbidden + expect(user.reload).not_to be_disabled + end + end + + context 'when target user is not admin' do + let(:target_user_admin) { false } + + it 'fails to disable account' do + is_expected.to have_http_status :forbidden + expect(user.reload).not_to be_disabled + end + end + end + end + + describe 'POST #redownload' do + subject { post :redownload, params: { id: account.id } } + + let(:current_user) { Fabricate(:user, admin: admin) } + let(:account) { Fabricate(:account) } + + context 'when user is admin' do + let(:admin) { true } + + it 'succeeds in redownloadin' do + is_expected.to redirect_to admin_account_path(account.id) + end + end + + context 'when user is not admin' do + let(:admin) { false } + + it 'fails to redownload' do + is_expected.to have_http_status :forbidden + end + end + end + + describe 'POST #remove_avatar' do + subject { post :remove_avatar, params: { id: account.id } } + + let(:current_user) { Fabricate(:user, admin: admin) } + let(:account) { Fabricate(:account) } + + context 'when user is admin' do + let(:admin) { true } + + it 'succeeds in removing avatar' do + is_expected.to redirect_to admin_account_path(account.id) + end + end + + context 'when user is not admin' do + let(:admin) { false } + + it 'fails to remove avatar' do + is_expected.to have_http_status :forbidden + end + end + end end diff --git a/spec/controllers/follower_accounts_controller_spec.rb b/spec/controllers/follower_accounts_controller_spec.rb index 3a42a6e18..83032ab64 100644 --- a/spec/controllers/follower_accounts_controller_spec.rb +++ b/spec/controllers/follower_accounts_controller_spec.rb @@ -8,18 +8,45 @@ describe FollowerAccountsController do let(:follower1) { Fabricate(:account) } describe 'GET #index' do - it 'assigns follows' do - follow0 = follower0.follow!(alice) - follow1 = follower1.follow!(alice) + let!(:follow0) { follower0.follow!(alice) } + let!(:follow1) { follower1.follow!(alice) } - get :index, params: { account_username: alice.username } + context 'when format is html' do + subject(:response) { get :index, params: { account_username: alice.username, format: :html } } - assigned = assigns(:follows).to_a - expect(assigned.size).to eq 2 - expect(assigned[0]).to eq follow1 - expect(assigned[1]).to eq follow0 + it 'assigns follows' do + expect(response).to have_http_status(200) - expect(response).to have_http_status(200) + assigned = assigns(:follows).to_a + expect(assigned.size).to eq 2 + expect(assigned[0]).to eq follow1 + expect(assigned[1]).to eq follow0 + end + end + + context 'when format is json' do + subject(:response) { get :index, params: { account_username: alice.username, page: page, format: :json } } + subject(:body) { JSON.parse(response.body) } + + context 'with page' do + let(:page) { 1 } + + it 'returns followers' do + expect(response).to have_http_status(200) + expect(body['totalItems']).to eq 2 + expect(body['partOf']).to be_present + end + end + + context 'without page' do + let(:page) { nil } + + it 'returns followers' do + expect(response).to have_http_status(200) + expect(body['totalItems']).to eq 2 + expect(body['partOf']).to be_blank + end + end end end end diff --git a/spec/controllers/following_accounts_controller_spec.rb b/spec/controllers/following_accounts_controller_spec.rb index 33376365d..d5e4ee587 100644 --- a/spec/controllers/following_accounts_controller_spec.rb +++ b/spec/controllers/following_accounts_controller_spec.rb @@ -8,18 +8,45 @@ describe FollowingAccountsController do let(:followee1) { Fabricate(:account) } describe 'GET #index' do - it 'assigns followees' do - follow0 = alice.follow!(followee0) - follow1 = alice.follow!(followee1) + let!(:follow0) { alice.follow!(followee0) } + let!(:follow1) { alice.follow!(followee1) } - get :index, params: { account_username: alice.username } + context 'when format is html' do + subject(:response) { get :index, params: { account_username: alice.username, format: :html } } - assigned = assigns(:follows).to_a - expect(assigned.size).to eq 2 - expect(assigned[0]).to eq follow1 - expect(assigned[1]).to eq follow0 + it 'assigns follows' do + expect(response).to have_http_status(200) - expect(response).to have_http_status(200) + assigned = assigns(:follows).to_a + expect(assigned.size).to eq 2 + expect(assigned[0]).to eq follow1 + expect(assigned[1]).to eq follow0 + end + end + + context 'when format is json' do + subject(:response) { get :index, params: { account_username: alice.username, page: page, format: :json } } + subject(:body) { JSON.parse(response.body) } + + context 'with page' do + let(:page) { 1 } + + it 'returns followers' do + expect(response).to have_http_status(200) + expect(body['totalItems']).to eq 2 + expect(body['partOf']).to be_present + end + end + + context 'without page' do + let(:page) { nil } + + it 'returns followers' do + expect(response).to have_http_status(200) + expect(body['totalItems']).to eq 2 + expect(body['partOf']).to be_blank + end + end end end end diff --git a/spec/controllers/settings/preferences_controller_spec.rb b/spec/controllers/settings/preferences_controller_spec.rb index 7877c7362..f2028cf39 100644 --- a/spec/controllers/settings/preferences_controller_spec.rb +++ b/spec/controllers/settings/preferences_controller_spec.rb @@ -18,12 +18,12 @@ describe Settings::PreferencesController do describe 'PUT #update' do it 'updates the user record' do - put :update, params: { user: { locale: 'en', filtered_languages: ['es', 'fr', ''] } } + put :update, params: { user: { locale: 'en', chosen_languages: ['es', 'fr', ''] } } expect(response).to redirect_to(settings_preferences_path) user.reload expect(user.locale).to eq 'en' - expect(user.filtered_languages).to eq ['es', 'fr'] + expect(user.chosen_languages).to eq ['es', 'fr'] end it 'updates user settings' do diff --git a/spec/controllers/shares_controller_spec.rb b/spec/controllers/shares_controller_spec.rb new file mode 100644 index 000000000..a74e9af56 --- /dev/null +++ b/spec/controllers/shares_controller_spec.rb @@ -0,0 +1,22 @@ +require 'rails_helper' + +describe SharesController do + render_views + + let(:user) { Fabricate(:user) } + before { sign_in user } + + describe 'GTE #show' do + subject(:initial_state_json) { JSON.parse(assigns(:initial_state_json), symbolize_names: true) } + subject(:body_classes) { assigns(:body_classes) } + + before { get :show, params: { title: 'test title', text: 'test text', url: 'url1 url2' } } + + it 'assigns json' do + expect(response).to have_http_status :ok + expect(initial_state_json[:compose][:text]).to eq 'test title test text url1 url2' + expect(initial_state_json[:meta][:me]).to eq user.account.id.to_s + expect(body_classes).to eq 'modal-layout compose-standalone' + end + end +end diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb index 5113b652f..b3e475d99 100644 --- a/spec/models/status_spec.rb +++ b/spec/models/status_spec.rb @@ -259,18 +259,18 @@ RSpec.describe Status, type: :model do end end - describe '.not_in_filtered_languages' do + describe '.in_chosen_languages' do context 'for accounts with language filters' do - let(:user) { Fabricate(:user, filtered_languages: ['en']) } + let(:user) { Fabricate(:user, chosen_languages: ['en']) } - it 'does not include statuses in filtered languages' do - status = Fabricate(:status, language: 'en') - expect(Status.not_in_filtered_languages(user.account)).not_to include status + it 'does not include statuses in not in chosen languages' do + status = Fabricate(:status, language: 'de') + expect(Status.in_chosen_languages(user.account)).not_to include status end it 'includes status with unknown language' do status = Fabricate(:status, language: nil) - expect(Status.not_in_filtered_languages(user.account)).to include status + expect(Status.in_chosen_languages(user.account)).to include status end end end @@ -518,7 +518,7 @@ RSpec.describe Status, type: :model do context 'with language preferences' do it 'excludes statuses in languages not allowed by the account user' do - user = Fabricate(:user, filtered_languages: [:fr]) + user = Fabricate(:user, chosen_languages: [:en, :es]) @account.update(user: user) en_status = Fabricate(:status, language: 'en') es_status = Fabricate(:status, language: 'es') @@ -531,7 +531,7 @@ RSpec.describe Status, type: :model do end it 'includes all languages when user does not have a setting' do - user = Fabricate(:user, filtered_languages: []) + user = Fabricate(:user, chosen_languages: nil) @account.update(user: user) en_status = Fabricate(:status, language: 'en') diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index cc8d88cc8..93a6c26fb 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -41,9 +41,9 @@ RSpec.describe User, type: :model do end it 'cleans out empty string from languages' do - user = Fabricate.build(:user, filtered_languages: ['']) + user = Fabricate.build(:user, chosen_languages: ['']) user.valid? - expect(user.filtered_languages).to eq [] + expect(user.chosen_languages).to eq nil end end