A app/chewy/instances_index.rb => app/chewy/instances_index.rb +12 -0
@@ 0,0 1,12 @@
+# frozen_string_literal: true
+
+class InstancesIndex < Chewy::Index
+ settings index: { refresh_interval: '30s' }
+
+ index_scope ::Instance.searchable
+
+ root date_detection: false do
+ field :domain, type: 'text', index_prefixes: { min_chars: 1 }
+ field :accounts_count, type: 'long'
+ end
+end
M app/controllers/api/v1/instances/peers_controller.rb => app/controllers/api/v1/instances/peers_controller.rb +1 -1
@@ 15,7 15,7 @@ class Api::V1::Instances::PeersController < Api::BaseController
def index
cache_even_if_authenticated!
- render_with_cache(expires_in: 1.day) { Instance.where.not(domain: DomainBlock.select(:domain)).pluck(:domain) }
+ render_with_cache(expires_in: 1.day) { Instance.searchable.pluck(:domain) }
end
private
A app/controllers/api/v1/peers/search_controller.rb => app/controllers/api/v1/peers/search_controller.rb +45 -0
@@ 0,0 1,45 @@
+# frozen_string_literal: true
+
+class Api::V1::Peers::SearchController < Api::BaseController
+ before_action :require_enabled_api!
+ before_action :set_domains
+
+ skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
+ skip_around_action :set_locale
+
+ vary_by ''
+
+ def index
+ cache_even_if_authenticated!
+ render json: @domains
+ end
+
+ private
+
+ def require_enabled_api!
+ head 404 unless Setting.peers_api_enabled && !whitelist_mode?
+ end
+
+ def set_domains
+ return if params[:q].blank?
+
+ if Chewy.enabled?
+ @domains = InstancesIndex.query(function_score: {
+ query: {
+ prefix: {
+ domain: params[:q],
+ },
+ },
+
+ field_value_factor: {
+ field: 'accounts_count',
+ modifier: 'log2p',
+ },
+ }).limit(10).pluck(:domain)
+ else
+ domain = params[:q].strip
+ domain = TagManager.instance.normalize_domain(domain)
+ @domains = Instance.searchable.where(Instance.arel_table[:domain].matches("#{Instance.sanitize_sql_like(domain)}%", false, true)).limit(10).pluck(:domain)
+ end
+ end
+end
M app/controllers/authorize_interactions_controller.rb => app/controllers/authorize_interactions_controller.rb +2 -19
@@ 3,32 3,19 @@
class AuthorizeInteractionsController < ApplicationController
include Authorization
- layout 'modal'
-
before_action :authenticate_user!
- before_action :set_body_classes
before_action :set_resource
def show
if @resource.is_a?(Account)
- render :show
+ redirect_to web_url("@#{@resource.pretty_acct}")
elsif @resource.is_a?(Status)
redirect_to web_url("@#{@resource.account.pretty_acct}/#{@resource.id}")
else
- render :error
+ not_found
end
end
- def create
- if @resource.is_a?(Account) && FollowService.new.call(current_account, @resource, with_rate_limit: true)
- render :success
- else
- render :error
- end
- rescue ActiveRecord::RecordNotFound
- render :error
- end
-
private
def set_resource
@@ 61,8 48,4 @@ class AuthorizeInteractionsController < ApplicationController
def uri_param
params[:uri] || params.fetch(:acct, '').delete_prefix('acct:')
end
-
- def set_body_classes
- @body_classes = 'modal-layout'
- end
end
A app/controllers/remote_interaction_helper_controller.rb => app/controllers/remote_interaction_helper_controller.rb +43 -0
@@ 0,0 1,43 @@
+# frozen_string_literal: true
+
+class RemoteInteractionHelperController < ApplicationController
+ vary_by ''
+
+ skip_before_action :require_functional!
+ skip_around_action :set_locale
+ skip_before_action :update_user_sign_in
+
+ content_security_policy do |p|
+ # We inherit the normal `script-src`
+
+ # Set every directive that does not have a fallback
+ p.default_src :none
+ p.form_action :none
+ p.base_uri :none
+
+ # Disable every directive with a fallback to cut on response size
+ p.base_uri false
+ p.font_src false
+ p.img_src false
+ p.style_src false
+ p.media_src false
+ p.frame_src false
+ p.manifest_src false
+ p.connect_src false
+ p.child_src false
+ p.worker_src false
+
+ # Widen the directives that we do need
+ p.frame_ancestors :self
+ p.connect_src :https
+ end
+
+ def index
+ expires_in(5.minutes, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day)
+
+ response.headers['X-Frame-Options'] = 'SAMEORIGIN'
+ response.headers['Referrer-Policy'] = 'no-referrer'
+
+ render layout: 'helper_frame'
+ end
+end
M app/controllers/well_known/webfinger_controller.rb => app/controllers/well_known/webfinger_controller.rb +1 -0
@@ 19,6 19,7 @@ module WellKnown
def set_account
username = username_from_resource
+
@account = begin
if username == Rails.configuration.x.local_domain
Account.representative
M app/javascript/mastodon/containers/status_container.jsx => app/javascript/mastodon/containers/status_container.jsx +1 -1
@@ 278,7 278,7 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({
modalProps: {
type,
accountId: status.getIn(['account', 'id']),
- url: status.get('url'),
+ url: status.get('uri'),
},
}));
},
M => +1 -1
@@ 83,7 83,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
modalProps: {
type: 'follow',
accountId: account.get('id'),
url: account.get('url'),
url: account.get('uri'),
},
}));
},
M app/javascript/mastodon/features/compose/components/search.jsx => app/javascript/mastodon/features/compose/components/search.jsx +0 -4
@@ 139,10 139,6 @@ class Search extends PureComponent {
this.setState({ expanded: false, selectedOption: -1 });
};
- findTarget = () => {
- return this.searchForm;
- };
-
handleHashtagClick = () => {
const { router } = this.context;
const { value, onClickSearchResult } = this.props;
M app/javascript/mastodon/features/interaction_modal/index.jsx => app/javascript/mastodon/features/interaction_modal/index.jsx +245 -53
@@ 1,95 1,296 @@
import PropTypes from 'prop-types';
-import { PureComponent } from 'react';
+import React from 'react';
-import { FormattedMessage } from 'react-intl';
+import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import classNames from 'classnames';
import { connect } from 'react-redux';
+import { throttle, escapeRegExp } from 'lodash';
+
import { openModal, closeModal } from 'mastodon/actions/modal';
+import api from 'mastodon/api';
+import Button from 'mastodon/components/button';
import { Icon } from 'mastodon/components/icon';
import { registrationsOpen } from 'mastodon/initial_state';
+const messages = defineMessages({
+ loginPrompt: { id: 'interaction_modal.login.prompt', defaultMessage: 'Domain of your home server, e.g. mastodon.social' },
+});
+
const mapStateToProps = (state, { accountId }) => ({
displayNameHtml: state.getIn(['accounts', accountId, 'display_name_html']),
- signupUrl: state.getIn(['server', 'server', 'registrations', 'url'], null) || '/auth/sign_up',
});
const mapDispatchToProps = (dispatch) => ({
onSignupClick() {
- dispatch(closeModal({
- modalType: undefined,
- ignoreFocus: false,
- }));
- dispatch(openModal({ modalType: 'CLOSED_REGISTRATIONS' }));
+ dispatch(closeModal());
+ dispatch(openModal('CLOSED_REGISTRATIONS'));
},
});
-class Copypaste extends PureComponent {
+const PERSISTENCE_KEY = 'mastodon_home';
+
+const isValidDomain = value => {
+ const url = new URL('https:///path');
+ url.hostname = value;
+ return url.hostname === value;
+};
+
+const valueToDomain = value => {
+ // If the user starts typing an URL
+ if (/^https?:\/\//.test(value)) {
+ try {
+ const url = new URL(value);
+
+ // Consider that if there is a path, the URL is more meaningful than a bare domain
+ if (url.pathname.length > 1) {
+ return '';
+ }
+
+ return url.host;
+ } catch {
+ return undefined;
+ }
+ // If the user writes their full handle including username
+ } else if (value.includes('@')) {
+ if (value.replace(/^@/, '').split('@').length > 2) {
+ return undefined;
+ }
+ return '';
+ }
+
+ return value;
+};
+
+const addInputToOptions = (value, options) => {
+ value = value.trim();
+
+ if (value.includes('.') && isValidDomain(value)) {
+ return [value].concat(options.filter((x) => x !== value));
+ }
+
+ return options;
+};
+
+class LoginForm extends React.PureComponent {
static propTypes = {
- value: PropTypes.string,
+ resourceUrl: PropTypes.string,
+ intl: PropTypes.object.isRequired,
};
state = {
- copied: false,
+ value: localStorage ? (localStorage.getItem(PERSISTENCE_KEY) || '') : '',
+ expanded: false,
+ selectedOption: -1,
+ isLoading: false,
+ isSubmitting: false,
+ error: false,
+ options: [],
+ networkOptions: [],
};
setRef = c => {
this.input = c;
};
- handleInputClick = () => {
- this.setState({ copied: false });
- this.input.focus();
- this.input.select();
- this.input.setSelectionRange(0, this.input.value.length);
+ handleChange = ({ target }) => {
+ this.setState(state => ({ value: target.value, isLoading: true, error: false, options: addInputToOptions(target.value, state.networkOptions) }), () => this._loadOptions());
};
- handleButtonClick = () => {
- const { value } = this.props;
- navigator.clipboard.writeText(value);
- this.input.blur();
- this.setState({ copied: true });
- this.timeout = setTimeout(() => this.setState({ copied: false }), 700);
+ handleMessage = (event) => {
+ const { resourceUrl } = this.props;
+
+ if (event.origin !== window.origin || event.source !== this.iframeRef.contentWindow) {
+ return;
+ }
+
+ if (event.data?.type === 'fetchInteractionURL-failure') {
+ this.setState({ isSubmitting: false, error: true });
+ } else if (event.data?.type === 'fetchInteractionURL-success') {
+ if (/^https?:\/\//.test(event.data.template)) {
+ if (localStorage) {
+ localStorage.setItem(PERSISTENCE_KEY, event.data.uri_or_domain);
+ }
+
+ window.location.href = event.data.template.replace('{uri}', encodeURIComponent(resourceUrl));
+ } else {
+ this.setState({ isSubmitting: false, error: true });
+ }
+ }
};
+ componentDidMount () {
+ window.addEventListener('message', this.handleMessage);
+ }
+
componentWillUnmount () {
- if (this.timeout) clearTimeout(this.timeout);
+ window.removeEventListener('message', this.handleMessage);
}
+ handleSubmit = () => {
+ const { value } = this.state;
+
+ this.setState({ isSubmitting: true });
+
+ this.iframeRef.contentWindow.postMessage({
+ type: 'fetchInteractionURL',
+ uri_or_domain: value.trim(),
+ }, window.origin);
+ };
+
+ setIFrameRef = (iframe) => {
+ this.iframeRef = iframe;
+ }
+
+ handleFocus = () => {
+ this.setState({ expanded: true });
+ };
+
+ handleBlur = () => {
+ this.setState({ expanded: false });
+ };
+
+ handleKeyDown = (e) => {
+ const { options, selectedOption } = this.state;
+
+ switch(e.key) {
+ case 'ArrowDown':
+ e.preventDefault();
+
+ if (options.length > 0) {
+ this.setState({ selectedOption: Math.min(selectedOption + 1, options.length - 1) });
+ }
+
+ break;
+ case 'ArrowUp':
+ e.preventDefault();
+
+ if (options.length > 0) {
+ this.setState({ selectedOption: Math.max(selectedOption - 1, -1) });
+ }
+
+ break;
+ case 'Enter':
+ e.preventDefault();
+
+ if (selectedOption === -1) {
+ this.handleSubmit();
+ } else if (options.length > 0) {
+ this.setState({ value: options[selectedOption], error: false }, () => this.handleSubmit());
+ }
+
+ break;
+ }
+ };
+
+ handleOptionClick = e => {
+ const index = Number(e.currentTarget.getAttribute('data-index'));
+ const option = this.state.options[index];
+
+ e.preventDefault();
+ this.setState({ selectedOption: index, value: option, error: false }, () => this.handleSubmit());
+ };
+
+ _loadOptions = throttle(() => {
+ const { value } = this.state;
+
+ const domain = valueToDomain(value.trim());
+
+ if (typeof domain === 'undefined') {
+ this.setState({ options: [], networkOptions: [], isLoading: false, error: true });
+ return;
+ }
+
+ if (domain.length === 0) {
+ this.setState({ options: [], networkOptions: [], isLoading: false });
+ return;
+ }
+
+ api().get('/api/v1/peers/search', { params: { q: domain } }).then(({ data }) => {
+ if (!data) {
+ data = [];
+ }
+
+ this.setState((state) => ({ networkOptions: data, options: addInputToOptions(state.value, data), isLoading: false }));
+ }).catch(() => {
+ this.setState({ isLoading: false });
+ });
+ }, 200, { leading: true, trailing: true });
+
render () {
- const { value } = this.props;
- const { copied } = this.state;
+ const { intl } = this.props;
+ const { value, expanded, options, selectedOption, error, isSubmitting } = this.state;
+ const domain = (valueToDomain(value) || '').trim();
+ const domainRegExp = new RegExp(`(${escapeRegExp(domain)})`, 'gi');
+ const hasPopOut = domain.length > 0 && options.length > 0;
return (
- <div className={classNames('copypaste', { copied })}>
- <input
- type='text'
- ref={this.setRef}
- value={value}
- readOnly
- onClick={this.handleInputClick}
+ <div className={classNames('interaction-modal__login', { focused: expanded, expanded: hasPopOut, invalid: error })}>
+
+ <iframe
+ ref={this.setIFrameRef}
+ style={{display: 'none'}}
+ src='/remote_interaction_helper'
+ sandbox='allow-scripts allow-same-origin'
+ title='remote interaction helper'
/>
- <button className='button' onClick={this.handleButtonClick}>
- {copied ? <FormattedMessage id='copypaste.copied' defaultMessage='Copied' /> : <FormattedMessage id='copypaste.copy' defaultMessage='Copy' />}
- </button>
+ <div className='interaction-modal__login__input'>
+ <input
+ ref={this.setRef}
+ type='text'
+ value={value}
+ placeholder={intl.formatMessage(messages.loginPrompt)}
+ aria-label={intl.formatMessage(messages.loginPrompt)}
+ autoFocus
+ onChange={this.handleChange}
+ onFocus={this.handleFocus}
+ onBlur={this.handleBlur}
+ onKeyDown={this.handleKeyDown}
+ />
+
+ <Button onClick={this.handleSubmit} disabled={isSubmitting}><FormattedMessage id='interaction_modal.login.action' defaultMessage='Take me home' /></Button>
+ </div>
+
+ {hasPopOut && (
+ <div className='search__popout'>
+ <div className='search__popout__menu'>
+ {options.map((option, i) => (
+ <button key={option} onMouseDown={this.handleOptionClick} data-index={i} className={classNames('search__popout__menu__item', { selected: selectedOption === i })}>
+ {option.split(domainRegExp).map((part, i) => (
+ part.toLowerCase() === domain.toLowerCase() ? (
+ <mark key={i}>
+ {part}
+ </mark>
+ ) : (
+ <span key={i}>
+ {part}
+ </span>
+ )
+ ))}
+ </button>
+ ))}
+ </div>
+ </div>
+ )}
</div>
);
}
}
-class InteractionModal extends PureComponent {
+const IntlLoginForm = injectIntl(LoginForm);
+
+class InteractionModal extends React.PureComponent {
static propTypes = {
displayNameHtml: PropTypes.string,
url: PropTypes.string,
type: PropTypes.oneOf(['reply', 'reblog', 'favourite', 'follow']),
onSignupClick: PropTypes.func.isRequired,
- signupUrl: PropTypes.string.isRequired,
};
handleSignupClick = () => {
@@ 97,7 298,7 @@ class InteractionModal extends PureComponent {
};
render () {
- const { url, type, displayNameHtml, signupUrl } = this.props;
+ const { url, type, displayNameHtml } = this.props;
const name = <bdi dangerouslySetInnerHTML={{ __html: displayNameHtml }} />;
@@ 130,13 331,13 @@ class InteractionModal extends PureComponent {
if (registrationsOpen) {
signupButton = (
- <a href={signupUrl} className='button button--block button-tertiary'>
+ <a href='/auth/sign_up' className='link-button'>
<FormattedMessage id='sign_in_banner.create_account' defaultMessage='Create account' />
</a>
);
} else {
signupButton = (
- <button className='button button--block button-tertiary' onClick={this.handleSignupClick}>
+ <button className='link-button' onClick={this.handleSignupClick}>
<FormattedMessage id='sign_in_banner.create_account' defaultMessage='Create account' />
</button>
);
@@ 146,22 347,13 @@ class InteractionModal extends PureComponent {
<div className='modal-root__modal interaction-modal'>
<div className='interaction-modal__lead'>
<h3><span className='interaction-modal__icon'>{icon}</span> {title}</h3>
- <p>{actionDescription} <FormattedMessage id='interaction_modal.preamble' defaultMessage="Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one." /></p>
+ <p>{actionDescription} <strong><FormattedMessage id='interaction_modal.sign_in' defaultMessage='You are not logged in to this server. Where is your account hosted?' /></strong></p>
</div>
- <div className='interaction-modal__choices'>
- <div className='interaction-modal__choices__choice'>
- <h3><FormattedMessage id='interaction_modal.on_this_server' defaultMessage='On this server' /></h3>
- <a href='/auth/sign_in' className='button button--block'><FormattedMessage id='sign_in_banner.sign_in' defaultMessage='Login' /></a>
- {signupButton}
- </div>
+ <IntlLoginForm resourceUrl={url} />
- <div className='interaction-modal__choices__choice'>
- <h3><FormattedMessage id='interaction_modal.on_another_server' defaultMessage='On a different server' /></h3>
- <p><FormattedMessage id='interaction_modal.other_server_instructions' defaultMessage='Copy and paste this URL into the search field of your favorite Mastodon app or the web interface of your Mastodon server.' /></p>
- <Copypaste value={url} />
- </div>
- </div>
+ <p className='hint'><FormattedMessage id='interaction_modal.sign_in_hint' defaultMessage="Tip: That's the website where you signed up. If you don't remember, look for the welcome e-mail in your inbox. You can also enter your full username! (e.g. @Mastodon@mastodon.social)" /></p>
+ <p><FormattedMessage id='interaction_modal.no_account_yet' defaultMessage='Not on Mastodon?' /> {signupButton}</p>
</div>
);
}
M => +3 -3
@@ 91,7 91,7 @@ class Footer extends ImmutablePureComponent {
modalProps: {
type: 'reply',
accountId: status.getIn(['account', 'id']),
url: status.get('url'),
url: status.get('uri'),
},
}));
}
@@ 113,7 113,7 @@ class Footer extends ImmutablePureComponent {
modalProps: {
type: 'favourite',
accountId: status.getIn(['account', 'id']),
url: status.get('url'),
url: status.get('uri'),
},
}));
}
@@ 142,7 142,7 @@ class Footer extends ImmutablePureComponent {
modalProps: {
type: 'reblog',
accountId: status.getIn(['account', 'id']),
url: status.get('url'),
url: status.get('uri'),
},
}));
}
M app/javascript/mastodon/features/status/index.jsx => app/javascript/mastodon/features/status/index.jsx +3 -3
@@ 252,7 252,7 @@ class Status extends ImmutablePureComponent {
modalProps: {
type: 'favourite',
accountId: status.getIn(['account', 'id']),
- url: status.get('url'),
+ url: status.get('uri'),
},
}));
}
@@ 289,7 289,7 @@ class Status extends ImmutablePureComponent {
modalProps: {
type: 'reply',
accountId: status.getIn(['account', 'id']),
- url: status.get('url'),
+ url: status.get('uri'),
},
}));
}
@@ 319,7 319,7 @@ class Status extends ImmutablePureComponent {
modalProps: {
type: 'reblog',
accountId: status.getIn(['account', 'id']),
- url: status.get('url'),
+ url: status.get('uri'),
},
}));
}
M app/javascript/mastodon/locales/en.json => app/javascript/mastodon/locales/en.json +5 -3
@@ 191,7 191,6 @@
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"copypaste.copied": "Copied",
- "copypaste.copy": "Copy",
"copypaste.copy_to_clipboard": "Copy to clipboard",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
@@ 311,10 310,13 @@
"interaction_modal.description.follow": "With an account on Mastodon, you can follow {name} to receive their posts in your home feed.",
"interaction_modal.description.reblog": "With an account on Mastodon, you can boost this post to share it with your own followers.",
"interaction_modal.description.reply": "With an account on Mastodon, you can respond to this post.",
+ "interaction_modal.login.action": "Take me home",
+ "interaction_modal.login.prompt": "Domain of your home server, e.g. mastodon.social",
+ "interaction_modal.no_account_yet": "Not on Mastodon?",
"interaction_modal.on_another_server": "On a different server",
"interaction_modal.on_this_server": "On this server",
- "interaction_modal.other_server_instructions": "Copy and paste this URL into the search field of your favorite Mastodon app or the web interface of your Mastodon server.",
- "interaction_modal.preamble": "Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one.",
+ "interaction_modal.sign_in": "You are not logged in to this server. Where is your account hosted?",
+ "interaction_modal.sign_in_hint": "Tip: That's the website where you signed up. If you don't remember, look for the welcome e-mail in your inbox. You can also enter your full username! (e.g. @Mastodon@mastodon.social)",
"interaction_modal.title.favourite": "Favorite {name}'s post",
"interaction_modal.title.follow": "Follow {name}",
"interaction_modal.title.reblog": "Boost {name}'s post",
A app/javascript/packs/remote_interaction_helper.ts => app/javascript/packs/remote_interaction_helper.ts +172 -0
@@ 0,0 1,172 @@
+/*
+
+This script is meant to to be used in an `iframe` with the sole purpose of doing webfinger queries
+client-side without being restricted by a strict `connect-src` Content-Security-Policy directive.
+
+It communicates with the parent window through message events that are authenticated by origin,
+and performs no other task.
+
+*/
+
+import './public-path';
+
+import axios from 'axios';
+
+interface JRDLink {
+ rel: string;
+ template?: string;
+ href?: string;
+}
+
+const isJRDLink = (link: unknown): link is JRDLink =>
+ typeof link === 'object' &&
+ link !== null &&
+ 'rel' in link &&
+ typeof link.rel === 'string' &&
+ (!('template' in link) || typeof link.template === 'string') &&
+ (!('href' in link) || typeof link.href === 'string');
+
+const findLink = (rel: string, data: unknown): JRDLink | undefined => {
+ if (
+ typeof data === 'object' &&
+ data !== null &&
+ 'links' in data &&
+ data.links instanceof Array
+ ) {
+ return data.links.find(
+ (link): link is JRDLink => isJRDLink(link) && link.rel === rel,
+ );
+ } else {
+ return undefined;
+ }
+};
+
+const findTemplateLink = (data: unknown) =>
+ findLink('http://ostatus.org/schema/1.0/subscribe', data)?.template;
+
+const fetchInteractionURLSuccess = (
+ uri_or_domain: string,
+ template: string,
+) => {
+ window.parent.postMessage(
+ {
+ type: 'fetchInteractionURL-success',
+ uri_or_domain,
+ template,
+ },
+ window.origin,
+ );
+};
+
+const fetchInteractionURLFailure = () => {
+ window.parent.postMessage(
+ {
+ type: 'fetchInteractionURL-failure',
+ },
+ window.origin,
+ );
+};
+
+const isValidDomain = (value: string) => {
+ const url = new URL('https:///path');
+ url.hostname = value;
+ return url.hostname === value;
+};
+
+// Attempt to find a remote interaction URL from a domain
+const fromDomain = (domain: string) => {
+ const fallbackTemplate = `https://${domain}/authorize_interaction?uri={uri}`;
+
+ axios
+ .get(`https://${domain}/.well-known/webfinger`, {
+ params: { resource: `https://${domain}` },
+ })
+ .then(({ data }) => {
+ const template = findTemplateLink(data);
+ fetchInteractionURLSuccess(domain, template ?? fallbackTemplate);
+ return;
+ })
+ .catch(() => {
+ fetchInteractionURLSuccess(domain, fallbackTemplate);
+ });
+};
+
+// Attempt to find a remote interaction URL from an arbitrary URL
+const fromURL = (url: string) => {
+ const domain = new URL(url).host;
+ const fallbackTemplate = `https://${domain}/authorize_interaction?uri={uri}`;
+
+ axios
+ .get(`https://${domain}/.well-known/webfinger`, {
+ params: { resource: url },
+ })
+ .then(({ data }) => {
+ const template = findTemplateLink(data);
+ fetchInteractionURLSuccess(url, template ?? fallbackTemplate);
+ return;
+ })
+ .catch(() => {
+ fromDomain(domain);
+ });
+};
+
+// Attempt to find a remote interaction URL from a `user@domain` string
+const fromAcct = (acct: string) => {
+ acct = acct.replace(/^@/, '');
+
+ const segments = acct.split('@');
+
+ if (segments.length !== 2 || !segments[0] || !isValidDomain(segments[1])) {
+ fetchInteractionURLFailure();
+ return;
+ }
+
+ const domain = segments[1];
+ const fallbackTemplate = `https://${domain}/authorize_interaction?uri={uri}`;
+
+ axios
+ .get(`https://${domain}/.well-known/webfinger`, {
+ params: { resource: `acct:${acct}` },
+ })
+ .then(({ data }) => {
+ const template = findTemplateLink(data);
+ fetchInteractionURLSuccess(acct, template ?? fallbackTemplate);
+ return;
+ })
+ .catch(() => {
+ // TODO: handle host-meta?
+ fromDomain(domain);
+ });
+};
+
+const fetchInteractionURL = (uri_or_domain: string) => {
+ if (/^https?:\/\//.test(uri_or_domain)) {
+ fromURL(uri_or_domain);
+ } else if (uri_or_domain.includes('@')) {
+ fromAcct(uri_or_domain);
+ } else {
+ fromDomain(uri_or_domain);
+ }
+};
+
+window.addEventListener('message', (event: MessageEvent<unknown>) => {
+ // Check message origin
+ if (
+ !window.origin ||
+ window.parent !== event.source ||
+ event.origin !== window.origin
+ ) {
+ return;
+ }
+
+ if (
+ event.data &&
+ typeof event.data === 'object' &&
+ 'type' in event.data &&
+ event.data.type === 'fetchInteractionURL' &&
+ 'uri_or_domain' in event.data &&
+ typeof event.data.uri_or_domain === 'string'
+ ) {
+ fetchInteractionURL(event.data.uri_or_domain);
+ }
+});
M app/javascript/styles/mastodon/components.scss => app/javascript/styles/mastodon/components.scss +74 -37
@@ 8356,13 8356,13 @@ noscript {
.interaction-modal {
max-width: 90vw;
width: 600px;
- background: $ui-base-color;
+ background: var(--modal-background-color);
+ border: 1px solid var(--modal-border-color);
border-radius: 8px;
- overflow-x: hidden;
- overflow-y: auto;
+ overflow: visible;
position: relative;
display: block;
- padding: 20px;
+ padding: 40px;
h3 {
font-size: 22px;
@@ 8371,64 8371,101 @@ noscript {
text-align: center;
}
+ p {
+ font-size: 17px;
+ line-height: 22px;
+ color: $darker-text-color;
+
+ strong {
+ color: $primary-text-color;
+ font-weight: 700;
+ }
+ }
+
+ p.hint {
+ margin-bottom: 14px;
+ font-size: 14px;
+ }
+
&__icon {
color: $highlight-text-color;
margin: 0 5px;
}
&__lead {
- padding: 20px;
- text-align: center;
+ margin-bottom: 20px;
h3 {
margin-bottom: 15px;
}
-
- p {
- font-size: 17px;
- line-height: 22px;
- color: $darker-text-color;
- }
}
- &__choices {
- display: flex;
+ &__login {
+ position: relative;
+ margin-bottom: 20px;
- &__choice {
- flex: 0 0 auto;
- width: 50%;
- box-sizing: border-box;
- padding: 20px;
+ &__input {
+ @include search-input;
- h3 {
- margin-bottom: 20px;
- }
+ border: 1px solid lighten($ui-base-color, 8%);
+ padding: 4px 6px;
+ color: $primary-text-color;
+ font-size: 16px;
+ line-height: 18px;
+ display: flex;
+ align-items: center;
- p {
- color: $darker-text-color;
- margin-bottom: 20px;
- }
+ input {
+ background: transparent;
+ color: inherit;
+ font: inherit;
+ border: 0;
+ padding: 15px - 4px 15px - 6px;
+ flex: 1 1 auto;
- .button {
- margin-bottom: 10px;
+ &::placeholder {
+ color: lighten($darker-text-color, 4%);
+ }
- &:last-child {
- margin-bottom: 0;
+ &:focus {
+ outline: 0;
}
}
+
+ .button {
+ flex: 0 0 auto;
+ }
+ }
+
+ .search__popout {
+ margin-top: -1px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ border: 1px solid lighten($ui-base-color, 8%);
+ }
+
+ &.focused &__input {
+ border-color: $highlight-text-color;
+ background: lighten($ui-base-color, 4%);
+ }
+
+ &.invalid &__input {
+ border-color: $error-red;
}
- }
- @media screen and (max-width: $no-gap-breakpoint - 1px) {
- &__choices {
+ &.expanded .search__popout {
display: block;
+ }
- &__choice {
- width: auto;
- margin-bottom: 20px;
- }
+ &.expanded &__input {
+ border-radius: 4px 4px 0 0;
}
}
+
+ .link-button {
+ font-size: inherit;
+ display: inline;
+ }
}
.copypaste {
M app/javascript/styles/mastodon/variables.scss => app/javascript/styles/mastodon/variables.scss +2 -0
@@ 96,4 96,6 @@ $font-monospace: 'mastodon-font-monospace' !default;
--dropdown-background-color: #{lighten($ui-base-color, 4%)};
--dropdown-shadow: 0 20px 25px -5px #{rgba($base-shadow-color, 0.25)},
0 8px 10px -6px #{rgba($base-shadow-color, 0.25)};
+ --modal-background-color: #{darken($ui-base-color, 4%)};
+ --modal-border-color: #{lighten($ui-base-color, 4%)};
}
M app/javascript/types/resources.ts => app/javascript/types/resources.ts +1 -0
@@ 33,6 33,7 @@ interface AccountApiResponseValues {
note: string;
statuses_count: number;
url: string;
+ uri: string;
username: string;
}
A app/lib/importer/instances_index_importer.rb => app/lib/importer/instances_index_importer.rb +26 -0
@@ 0,0 1,26 @@
+# frozen_string_literal: true
+
+class Importer::InstancesIndexImporter < Importer::BaseImporter
+ def import!
+ index.adapter.default_scope.find_in_batches(batch_size: @batch_size) do |tmp|
+ in_work_unit(tmp) do |instances|
+ bulk = Chewy::Index::Import::BulkBuilder.new(index, to_index: instances).bulk_body
+
+ indexed = bulk.count { |entry| entry[:index] }
+ deleted = bulk.count { |entry| entry[:delete] }
+
+ Chewy::Index::Import::BulkRequest.new(index).perform(bulk)
+
+ [indexed, deleted]
+ end
+ end
+
+ wait!
+ end
+
+ private
+
+ def index
+ InstancesIndex
+ end
+end
M app/lib/webfinger_resource.rb => app/lib/webfinger_resource.rb +9 -0
@@ 11,6 11,8 @@ class WebfingerResource
def username
case resource
+ when %r{\A(https?://)?#{instance_actor_regexp}/?\Z}
+ Rails.configuration.x.local_domain
when /\Ahttps?/i
username_from_url
when /@/
@@ 22,6 24,13 @@ class WebfingerResource
private
+ def instance_actor_regexp
+ hosts = [Rails.configuration.x.local_domain, Rails.configuration.x.web_domain]
+ hosts.concat(Rails.configuration.x.alternate_domains) if Rails.configuration.x.alternate_domains.present?
+
+ Regexp.union(hosts)
+ end
+
def username_from_url
if account_show_page?
path_params[:username]
M app/models/instance.rb => app/models/instance.rb +1 -0
@@ 21,6 21,7 @@ class Instance < ApplicationRecord
belongs_to :unavailable_domain # skipcq: RB-RL1031
end
+ scope :searchable, -> { where.not(domain: DomainBlock.select(:domain)) }
scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) }
scope :by_domain_and_subdomains, ->(domain) { where("reverse('.' || domain) LIKE reverse(?)", "%.#{domain}") }
M app/serializers/rest/account_serializer.rb => app/serializers/rest/account_serializer.rb +5 -1
@@ 5,7 5,7 @@ class REST::AccountSerializer < ActiveModel::Serializer
include FormattingHelper
attributes :id, :username, :acct, :display_name, :locked, :bot, :discoverable, :group, :created_at,
- :note, :url, :avatar, :avatar_static, :header, :header_static,
+ :note, :url, :uri, :avatar, :avatar_static, :header, :header_static,
:followers_count, :following_count, :statuses_count, :last_status_at
has_one :moved_to_account, key: :moved, serializer: REST::AccountSerializer, if: :moved_and_not_nested?
@@ 66,6 66,10 @@ class REST::AccountSerializer < ActiveModel::Serializer
ActivityPub::TagManager.instance.url_for(object)
end
+ def uri
+ ActivityPub::TagManager.instance.uri_for(object)
+ end
+
def avatar
full_asset_url(object.suspended? ? object.avatar.default_url : object.avatar_original_url)
end
M app/serializers/webfinger_serializer.rb => app/serializers/webfinger_serializer.rb +1 -0
@@ 22,6 22,7 @@ class WebfingerSerializer < ActiveModel::Serializer
[
{ rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: about_more_url(instance_actor: true) },
{ rel: 'self', type: 'application/activity+json', href: instance_actor_url },
+ { rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_interaction_url}?uri={uri}" },
]
else
[
D app/views/authorize_interactions/_post_follow_actions.html.haml => app/views/authorize_interactions/_post_follow_actions.html.haml +0 -4
@@ 1,4 0,0 @@
-.post-follow-actions
- %div= link_to t('authorize_follow.post_follow.web'), web_url("@#{@resource.pretty_acct}"), class: 'button button--block'
- %div= link_to t('authorize_follow.post_follow.return'), ActivityPub::TagManager.instance.url_for(@resource), class: 'button button--block'
- %div= t('authorize_follow.post_follow.close')
D app/views/authorize_interactions/error.html.haml => app/views/authorize_interactions/error.html.haml +0 -3
@@ 1,3 0,0 @@
-.form-container
- .flash-message#error_explanation
- = t('authorize_follow.error')
D app/views/authorize_interactions/show.html.haml => app/views/authorize_interactions/show.html.haml +0 -24
@@ 1,24 0,0 @@
-- content_for :page_title do
- = t('authorize_follow.title', acct: @resource.pretty_acct)
-
-.form-container
- .follow-prompt
- = render 'application/card', account: @resource
-
- - if current_account.following?(@resource)
- .flash-message
- %strong
- = t('authorize_follow.already_following')
-
- = render 'post_follow_actions'
- - elsif current_account.requested?(@resource)
- .flash-message
- %strong
- = t('authorize_follow.already_requested')
-
- = render 'post_follow_actions'
- - else
- = form_tag authorize_interaction_path, method: :post, class: 'simple_form' do
- = hidden_field_tag :action, :follow
- = hidden_field_tag :acct, @resource.acct
- = button_tag t('authorize_follow.follow'), type: :submit
D app/views/authorize_interactions/success.html.haml => app/views/authorize_interactions/success.html.haml +0 -13
@@ 1,13 0,0 @@
-- content_for :page_title do
- = t('authorize_follow.title', acct: @resource.pretty_acct)
-
-.form-container
- .follow-prompt
- - if @resource.locked?
- %h2= t('authorize_follow.follow_request')
- - else
- %h2= t('authorize_follow.following')
-
- = render 'application/card', account: @resource
-
- = render 'post_follow_actions'
A app/views/layouts/helper_frame.html.haml => app/views/layouts/helper_frame.html.haml +8 -0
@@ 0,0 1,8 @@
+!!! 5
+%html
+ %head
+ %meta{ charset: 'utf-8' }/
+
+ = javascript_pack_tag 'common', crossorigin: 'anonymous'
+
+ = yield :header_tags
A app/views/remote_interaction_helper/index.html.haml => app/views/remote_interaction_helper/index.html.haml +4 -0
@@ 0,0 1,4 @@
+- content_for :header_tags do
+ %meta{ name: 'robots', content: 'noindex' }/
+
+ = javascript_pack_tag 'remote_interaction_helper', crossorigin: 'anonymous'
M app/workers/scheduler/instance_refresh_scheduler.rb => app/workers/scheduler/instance_refresh_scheduler.rb +1 -0
@@ 7,5 7,6 @@ class Scheduler::InstanceRefreshScheduler
def perform
Instance.refresh
+ InstancesIndex.import if Chewy.enabled?
end
end
M config/locales/an.yml => config/locales/an.yml +0 -12
@@ 982,18 982,6 @@ an:
view_strikes: Veyer amonestacions pasadas contra la tuya cuenta
too_fast: Formulario ninviau masiau rapido, lo intente de nuevo.
use_security_key: Usar la clau de seguranza
- authorize_follow:
- already_following: Ya yes seguindo a esta cuenta
- already_requested: Ya has ninviau una solicitut de seguimiento a ixa cuenta
- error: Desafortunadament, ha ocurriu una error buscando la cuenta remota
- follow: Seguir
- follow_request: 'Tiens una solicitut de seguimiento de:'
- following: 'Exito! Agora yes seguindo a:'
- post_follow:
- close: U, puetz simplament zarrar esta finestra.
- return: Tornar ta lo perfil de l'usuario
- web: Ir ta lo puesto web
- title: Seguir a %{acct}
challenge:
confirm: Continar
hint_html: "<strong>Tip:</strong> No tornaremos a preguntar-te per la clau entre la siguient hora."
M config/locales/ar.yml => config/locales/ar.yml +0 -12
@@ 1065,18 1065,6 @@ ar:
view_strikes: عرض السجلات السابقة ضد حسابك
too_fast: تم إرسال النموذج بسرعة كبيرة، حاول مرة أخرى.
use_security_key: استخدام مفتاح الأمان
- authorize_follow:
- already_following: أنت تتابع بالفعل هذا الحساب
- already_requested: لقد قُمتَ بإرسال طلب متابَعة إلى هذا الحساب مِن قَبل
- error: يا للأسف، وقع هناك خطأ إثر عملية البحث عن الحساب عن بعد
- follow: اتبع
- follow_request: 'لقد قمت بإرسال طلب متابعة إلى:'
- following: 'مرحى! أنت الآن تتبع:'
- post_follow:
- close: أو يمكنك إغلاق هذه النافذة.
- return: اظهر الملف التعريفي للمستخدم
- web: واصل إلى الويب
- title: إتباع %{acct}
challenge:
confirm: واصل
hint_html: "<strong>توصية:</strong> لن نطلب منك ثانية كلمتك السرية في غضون الساعة اللاحقة."
M config/locales/ast.yml => config/locales/ast.yml +0 -9
@@ 481,15 481,6 @@ ast:
functional: La cuenta ta completamente operativa.
pending: La to solicitú ta pendiente de que la revise'l nuesu personal ya ye posible que tarde tiempu. Vas recibir un mensaxe si s'aprueba.
too_fast: El formulariu xubióse mui rápido, volvi tentalo.
- authorize_follow:
- already_following: Xá tas siguiendo a esta cuenta
- already_requested: Yá unviesti una solicitú de siguimientu a esa cuenta
- error: Desafortunadamente, hebo un error al buscar la cuenta remota
- follow_request: 'Unviesti una solicitú de siguimientu a:'
- post_follow:
- close: O pues zarrar esta ventana.
- return: Amosar el perfil de la cuenta
- web: Dir a la web
challenge:
confirm: Siguir
hint_html: "<strong>Conseyu:</strong> nun vamos volver pidite la contraseña hasta dientro d'una hora."
M config/locales/be.yml => config/locales/be.yml +0 -12
@@ 1095,18 1095,6 @@ be:
view_strikes: Праглядзець мінулыя папярэджанні для вашага ўліковага запісу
too_fast: Форма адпраўлена занадта хутка, паспрабуйце яшчэ раз.
use_security_key: Выкарыстаеце ключ бяспекі
- authorize_follow:
- already_following: Вы ўжо падпісаныя на гэты ўліковы запіс
- already_requested: Вы ўжо адправілі запыт на гэты ўліковы запіс
- error: На жаль, падчас пошуку аддаленага ўліковага запісу здарылася памылка
- follow: Падпісацца
- follow_request: 'Вы адправілі запыт на падпіску:'
- following: 'Поспех! Цяпер вы падпісаны на:'
- post_follow:
- close: Або, вы можаце проста закрыць гэтае акно.
- return: Паказаць профіль карыстальніка
- web: Перайсці ў вэб-версію
- title: Падпісацца на %{acct}
challenge:
confirm: Працягнуць
hint_html: "<strong>Парада:</strong> Мы не будзем запытваць ваш пароль зноўку на працягу наступнай гадзіны."
M config/locales/bg.yml => config/locales/bg.yml +0 -12
@@ 1059,18 1059,6 @@ bg:
view_strikes: Преглед на предишните предупреждения против акаунта ви
too_fast: Образецът подаден пребързо, опитайте пак.
use_security_key: Употреба на ключ за сигурност
- authorize_follow:
- already_following: Вече следвате този акаунт
- already_requested: Вече сте изпратили заявка за последване до този акаунт
- error: Възникна грешка, търсейки отдалечения акаунт
- follow: Последвай
- follow_request: 'Изпратихте следната заявка до:'
- following: 'Успешно! Сега сте последвали:'
- post_follow:
- close: Или просто затворете този прозорец.
- return: Показване на профила на потребителя
- web: Към мрежата
- title: Последвай %{acct}
challenge:
confirm: Продължаване
hint_html: "<strong>Съвет</strong>: няма да ви питаме пак за паролата през следващия час."
M config/locales/br.yml => config/locales/br.yml +0 -5
@@ 299,11 299,6 @@ br:
security: Diogelroez
status:
account_status: Statud ar gont
- authorize_follow:
- follow: Heuliañ
- post_follow:
- web: Distreiñ d'an etrefas web
- title: Heuliañ %{acct}
challenge:
confirm: Kenderc' hel
invalid_password: Ger-tremen diwiriek
M config/locales/ca.yml => config/locales/ca.yml +0 -12
@@ 1060,18 1060,6 @@ ca:
view_strikes: Veure accions del passat contra el teu compte
too_fast: Formulari enviat massa ràpid, torna a provar-ho.
use_security_key: Usa clau de seguretat
- authorize_follow:
- already_following: Ja estàs seguint aquest compte
- already_requested: Ja has enviat una sol·licitud de seguiment a aquest usuari
- error: Malauradament, ha ocorregut un error cercant el compte remot
- follow: Segueix
- follow_request: 'Has enviat una sol·licitud de seguiment a:'
- following: 'Perfecte! Ara segueixes:'
- post_follow:
- close: O bé, pots tancar aquesta finestra.
- return: Mostra el perfil de l'usuari
- web: Vés a la web
- title: Segueix %{acct}
challenge:
confirm: Continua
hint_html: "<strong>Pista:</strong> No et preguntarem un altre cop la teva contrasenya en la pròxima hora."
M config/locales/ckb.yml => config/locales/ckb.yml +0 -12
@@ 620,18 620,6 @@ ckb:
view_strikes: بینینی لێدانەکانی ڕابردوو لە دژی ئەکاونتەکەت
too_fast: فۆڕم زۆر خێرا پێشکەش کراوە، دووبارە هەوڵبدەرەوە.
use_security_key: کلیلی ئاسایش بەکاربهێنە
- authorize_follow:
- already_following: ئێوە ئێستا شوێن کەوتووی ئەم هەژمارەیەی
- already_requested: تۆ پێشتر داواکاری بەدواداچوت ناردوە بۆ ئەو هەژمارە
- error: بەداخەوە هەڵەیەک هەبوو لە کاتی گەڕان بەدوای ئەو هەژمارەیە
- follow: شوێن کەوە
- follow_request: 'تۆ داواکاری شوێنکەوتنت ناردووە بۆ:'
- following: 'ئەنجام بوو! تۆ ئێستا بەدوای ئەم بەکارهێنەرە دەکەویت:'
- post_follow:
- close: یان، دەتوانیت ئەم پەنجەرەیە دابخەیت.
- return: پرۆفایلی بەکارهێنەر نیشان بدە
- web: بڕۆ بۆ وێب
- title: دوای %{acct} بکەوە
challenge:
confirm: بەردەوام بە
hint_html: "<strong>خاڵ:</strong> ئیمە لە کاتژمێری داهاتوو تێپەروشەت لێداوا ناکەین."
M config/locales/co.yml => config/locales/co.yml +0 -12
@@ 583,18 583,6 @@ co:
redirecting_to: U vostru contu hè inattivu perchè riindirizza versu %{acct}.
too_fast: Furmulariu mandatu troppu prestu, ripruvate.
use_security_key: Utilizà a chjave di sicurità
- authorize_follow:
- already_following: Site digià abbunatu·a à stu contu
- already_requested: Avete digià mandatu una dumanda d'abbunamentu à stu contu
- error: Peccatu, c’hè statu un prublemu ricercandu u contu
- follow: Siguità
- follow_request: 'Avete dumandatu di siguità:'
- following: 'Eccu! Avà seguitate:'
- post_follow:
- close: O pudete ancu chjude sta finestra.
- return: Vede u prufile di l’utilizatore
- web: Andà à l’interfaccia web
- title: Siguità %{acct}
challenge:
confirm: Cuntinuvà
hint_html: "<strong>Astuzia:</strong> Ùn avemu micca da dumandavvi stu codice per l'ore chì vene."
M config/locales/cs.yml => config/locales/cs.yml +0 -12
@@ 1075,18 1075,6 @@ cs:
view_strikes: Zobrazit minulé prohřešky vašeho účtu
too_fast: Formulář byl odeslán příliš rychle, zkuste to znovu.
use_security_key: Použít bezpečnostní klíč
- authorize_follow:
- already_following: Tento účet již sledujete
- already_requested: Tomuto účtu už jste žádost o sledování zaslali
- error: Při hledání vzdáleného účtu bohužel nastala chyba
- follow: Sledovat
- follow_request: 'Poslali jste žádost o sledování uživateli:'
- following: 'Podařilo se! Nyní sledujete uživatele:'
- post_follow:
- close: Nebo můžete toto okno klidně zavřít.
- return: Zobrazit profil uživatele
- web: Přejít na web
- title: Sledovat %{acct}
challenge:
confirm: Pokračovat
hint_html: "<strong>Tip:</strong> Po dobu jedné hodiny vás o heslo nebudeme znovu žádat."
M config/locales/cy.yml => config/locales/cy.yml +0 -12
@@ 1132,18 1132,6 @@ cy:
view_strikes: Gweld rybuddion y gorffennol yn erbyn eich cyfrif
too_fast: Cafodd y ffurflen ei chyflwyno'n rhy gyflym, ceisiwch eto.
use_security_key: Defnyddiwch allwedd diogelwch
- authorize_follow:
- already_following: Rydych yn dilyn y cyfrif hwn yn barod
- already_requested: Rydych chi eisoes wedi anfon cais i ddilyn y cyfrif hwnnw
- error: Yn anffodus, roedd gwall tra'n edrych am y cyfrif pell
- follow: Dilyn
- follow_request: 'Rydych wedi anfon cais dilyn at:'
- following: 'Llwyddiant! Rydych nawr yn dilyn:'
- post_follow:
- close: Neu, gallwch gau'r ffenest hon.
- return: Dangos proffil y defnyddiwr
- web: Ewch i'r we
- title: Dilyn %{acct}
challenge:
confirm: Parhau
hint_html: "<strong>Awgrym:</strong> Fyddwn ni ddim yn gofyn i chi am eich cyfrinair eto am yr awr nesaf."
M config/locales/da.yml => config/locales/da.yml +0 -12
@@ 1060,18 1060,6 @@ da:
view_strikes: Se tidligere anmeldelser af din konto
too_fast: Formularen indsendt for hurtigt, forsøg igen.
use_security_key: Brug sikkerhedsnøgle
- authorize_follow:
- already_following: Du følger allerede denne konto
- already_requested: Du har allerede sendt en følgeanmodning til den konto
- error: Desværre opstod en fejl under søgning af fjernkontoen
- follow: Følg
- follow_request: 'Du har sendt en følgeanmodning til:'
- following: 'Accepteret! Du følger nu:'
- post_follow:
- close: Du kan også bare lukke dette vindue.
- return: Vis brugerens profil
- web: Gå til web
- title: Følg %{acct}
challenge:
confirm: Fortsæt
hint_html: "<strong>Tip:</strong> Du bliver ikke anmodet om din adgangskode igen den næste time."
M config/locales/de.yml => config/locales/de.yml +0 -12
@@ 1060,18 1060,6 @@ de:
view_strikes: Vorherige Verstöße deines Kontos ansehen
too_fast: Formular zu schnell übermittelt. Bitte versuche es erneut.
use_security_key: Sicherheitsschlüssel verwenden
- authorize_follow:
- already_following: Du folgst diesem Konto bereits
- already_requested: Du hast bereits eine Anfrage zum Folgen an dieses Konto gestellt
- error: Bedauerlicherweise konnte das externe Konto nicht geladen werden
- follow: Folgen
- follow_request: 'Du hast eine Anfrage zum Folgen gestellt an:'
- following: 'Erfolg! Du folgst nun:'
- post_follow:
- close: Oder du schließt einfach dieses Fenster.
- return: Profil anzeigen
- web: Im Webinterface öffnen
- title: "%{acct} folgen"
challenge:
confirm: Fortfahren
hint_html: "<strong>Hinweis:</strong> Wir werden dich für die nächste Stunde nicht erneut nach deinem Passwort fragen."
M config/locales/el.yml => config/locales/el.yml +0 -12
@@ 1039,18 1039,6 @@ el:
view_strikes: Προβολή προηγούμενων ποινών εναντίον του λογαριασμού σας
too_fast: Η φόρμα υποβλήθηκε πολύ γρήγορα, προσπαθήστε ξανά.
use_security_key: Χρήση κλειδιού ασφαλείας
- authorize_follow:
- already_following: Ήδη ακολουθείς αυτό το λογαριασμό
- already_requested: Έχετε ήδη στείλει ένα αίτημα ακολούθησης σε αυτόν τον λογαριασμό
- error: Δυστυχώς παρουσιάστηκε ένα σφάλμα κατά την αναζήτηση του απομακρυσμένου λογαριασμού
- follow: Ακολούθησε
- follow_request: 'Έστειλες αίτημα παρακολούθησης προς:'
- following: 'Επιτυχία! Πλέον ακολουθείς τον/την:'
- post_follow:
- close: Ή, μπορείς απλά να κλείσεις αυτό το παράθυρο.
- return: Δείξε το προφίλ του χρήστη
- web: Πήγαινε στο δίκτυο
- title: Ακολούθησε %{acct}
challenge:
confirm: Συνέχεια
hint_html: "<strong>Συμβουλή:</strong> Δεν θα σου ζητήσουμε τον κωδικό ασφαλείας σου ξανά για την επόμενη ώρα."
M config/locales/en-GB.yml => config/locales/en-GB.yml +0 -12
@@ 1060,18 1060,6 @@ en-GB:
view_strikes: View past strikes against your account
too_fast: Form submitted too fast, try again.
use_security_key: Use security key
- authorize_follow:
- already_following: You are already following this account
- already_requested: You have already sent a follow request to that account
- error: Unfortunately, there was an error looking up the remote account
- follow: Follow
- follow_request: 'You have sent a follow request to:'
- following: 'Success! You are now following:'
- post_follow:
- close: Or, you can just close this window.
- return: Show the user's profile
- web: Go to web
- title: Follow %{acct}
challenge:
confirm: Continue
hint_html: "<strong>Tip:</strong> We won't ask you for your password again for the next hour."
M config/locales/en.yml => config/locales/en.yml +0 -12
@@ 1060,18 1060,6 @@ en:
view_strikes: View past strikes against your account
too_fast: Form submitted too fast, try again.
use_security_key: Use security key
- authorize_follow:
- already_following: You are already following this account
- already_requested: You have already sent a follow request to that account
- error: Unfortunately, there was an error looking up the remote account
- follow: Follow
- follow_request: 'You have sent a follow request to:'
- following: 'Success! You are now following:'
- post_follow:
- close: Or, you can just close this window.
- return: Show the user's profile
- web: Go to web
- title: Follow %{acct}
challenge:
confirm: Continue
hint_html: "<strong>Tip:</strong> We won't ask you for your password again for the next hour."
M config/locales/eo.yml => config/locales/eo.yml +0 -12
@@ 1056,18 1056,6 @@ eo:
view_strikes: Vidi antauaj admonoj kontra via konto
too_fast: Formularo sendita tro rapide, klopodu denove.
use_security_key: Uzi sekurecan ŝlosilon
- authorize_follow:
- already_following: Vi jam sekvas tiun konton
- already_requested: Vi jam sendis peton de sekvado al ĉi tiu konto
- error: Bedaŭrinde, estis eraro en la serĉado de la fora konto
- follow: Sekvi
- follow_request: 'Vi sendis peton de sekvado al:'
- following: 'Sukceson! Vi nun sekvas:'
- post_follow:
- close: Aŭ, vi povas simple fermi ĉi tiun fenestron.
- return: Montri la profilon de la uzanto
- web: Iri al reto
- title: Sekvi %{acct}
challenge:
confirm: Daŭrigi
hint_html: "<strong>Konsileto:</strong> Ni ne demandos pri via pasvorto ĝis 1 horo."
M config/locales/es-AR.yml => config/locales/es-AR.yml +0 -12
@@ 1060,18 1060,6 @@ es-AR:
view_strikes: Ver incumplimientos pasados contra tu cuenta
too_fast: Formulario enviado demasiado rápido, probá de nuevo.
use_security_key: Usar la llave de seguridad
- authorize_follow:
- already_following: Ya estás siguiendo a esta cuenta
- already_requested: Ya enviaste una solicitud de seguimiento a esa cuenta
- error: Lamentablemente, ocurrió un error buscando la cuenta remota
- follow: Seguir
- follow_request: 'Enviaste una solicitud de seguimiento a:'
- following: "¡Listo! Ahora estás siguiendo a:"
- post_follow:
- close: O simplemente podés cerrar esta ventana.
- return: Mostrar el perfil del usuario
- web: Ir a la web
- title: Seguir a %{acct}
challenge:
confirm: Continuar
hint_html: "<strong>Dato:</strong> No volveremos a preguntarte por la contraseña durante la siguiente hora."
M config/locales/es-MX.yml => config/locales/es-MX.yml +0 -12
@@ 1060,18 1060,6 @@ es-MX:
view_strikes: Ver amonestaciones pasadas contra tu cuenta
too_fast: Formulario enviado demasiado rápido, inténtelo de nuevo.
use_security_key: Usar la clave de seguridad
- authorize_follow:
- already_following: Ya estás siguiendo a esta cuenta
- already_requested: Ya has enviado una solicitud de seguimiento a esa cuenta
- error: Desafortunadamente, ha ocurrido un error buscando la cuenta remota
- follow: Seguir
- follow_request: 'Tienes una solicitud de seguimiento de:'
- following: "¡Éxito! Ahora estás siguiendo a:"
- post_follow:
- close: O, puedes simplemente cerrar esta ventana.
- return: Regresar al perfil del usuario
- web: Ir al sitio web
- title: Seguir a %{acct}
challenge:
confirm: Continuar
hint_html: "<strong>Tip:</strong> No volveremos a preguntarte por la contraseña durante la siguiente hora."
M config/locales/es.yml => config/locales/es.yml +0 -12
@@ 1060,18 1060,6 @@ es:
view_strikes: Ver amonestaciones pasadas contra tu cuenta
too_fast: Formulario enviado demasiado rápido, inténtelo de nuevo.
use_security_key: Usar la clave de seguridad
- authorize_follow:
- already_following: Ya estás siguiendo a esta cuenta
- already_requested: Ya has enviado una solicitud de seguimiento a esa cuenta
- error: Desafortunadamente, ha ocurrido un error buscando la cuenta remota
- follow: Seguir
- follow_request: 'Tienes una solicitud de seguimiento de:'
- following: "¡Éxito! Ahora estás siguiendo a:"
- post_follow:
- close: O, puedes simplemente cerrar esta ventana.
- return: Regresar al perfil del usuario
- web: Ir al sitio web
- title: Seguir a %{acct}
challenge:
confirm: Continuar
hint_html: "<strong>Tip:</strong> No volveremos a preguntarte por la contraseña durante la siguiente hora."
M config/locales/et.yml => config/locales/et.yml +0 -12
@@ 1060,18 1060,6 @@ et:
view_strikes: Vaata enda eelnevaid juhtumeid
too_fast: Vorm esitatud liiga kiirelt, proovi uuesti.
use_security_key: Kasuta turvavõtit
- authorize_follow:
- already_following: Juba jälgid seda kontot
- already_requested: Saatsid juba sellele kontole jälgimistaotluse
- error: Kahjuks ilmus viga kasutaja kaugserverist otsimisel
- follow: Jälgi
- follow_request: 'Oled saatnud jälgimistaotluse kasutajale:'
- following: 'Õnnestus! Jälgid nüüd kasutajat:'
- post_follow:
- close: Või sulge lihtsalt see aken.
- return: Näita kasutaja profiili
- web: Mine veebi
- title: Jälgi %{acct}
challenge:
confirm: Jätka
hint_html: "<strong>Nõuanne:</strong> Me ei küsi salasõna uuesti järgmise tunni jooksul."
M config/locales/eu.yml => config/locales/eu.yml +0 -12
@@ 1051,18 1051,6 @@ eu:
view_strikes: Ikusi zure kontuaren aurkako neurriak
too_fast: Formularioa azkarregi bidali duzu, saiatu berriro.
use_security_key: Erabili segurtasun gakoa
- authorize_follow:
- already_following: Kontu hau aurretik jarraitzen duzu
- already_requested: Bidali duzu dagoeneko kontu hori jarraitzeko eskaera bat
- error: Zoritxarrez, urruneko kontua bilatzean errore bat gertatu da
- follow: Jarraitu
- follow_request: 'Jarraitzeko eskari bat bidali duzu hona:'
- following: 'Ongi! Orain jarraitzen duzu:'
- post_follow:
- close: Edo, leiho hau besterik gabe itxi dezakezu.
- return: Erakutsi erabiltzailearen profila
- web: Joan webera
- title: Jarraitu %{acct}
challenge:
confirm: Jarraitu
hint_html: "<strong>Oharra:</strong> Ez dizugu pasahitza berriro eskatuko ordu batez."
M config/locales/fa.yml => config/locales/fa.yml +0 -12
@@ 889,18 889,6 @@ fa:
view_strikes: دیدن شکایتهای گذشته از حسابتان
too_fast: فرم با سرعت بسیار زیادی فرستاده شد، دوباره تلاش کنید.
use_security_key: استفاده از کلید امنیتی
- authorize_follow:
- already_following: شما همین الان هم این حساب را پیمیگیرید
- already_requested: درخواست پیگیریای برای آن حساب فرستاده بودید
- error: متأسفانه حین یافتن آن حساب خطایی رخ داد
- follow: پی بگیرید
- follow_request: 'شما درخواست پیگیری فرستادهاید به:'
- following: 'انجام شد! شما هماینک پیگیر این کاربر هستید:'
- post_follow:
- close: یا این پنجره را ببندید.
- return: نمایهٔ این کاربر را نشان بده
- web: رفتن به وب
- title: پیگیری %{acct}
challenge:
confirm: ادامه
hint_html: "<strong>نکته:</strong> ما در یک ساعت آینده گذرواژهتان را از شما نخواهیم پرسید."
M config/locales/fi.yml => config/locales/fi.yml +0 -12
@@ 1060,18 1060,6 @@ fi:
view_strikes: Näytä tiliäsi koskevia aiempia varoituksia
too_fast: Lomake lähetettiin liian nopeasti, yritä uudelleen.
use_security_key: Käytä suojausavainta
- authorize_follow:
- already_following: Sinä seuraat jo tätä tiliä
- already_requested: Olet jo lähettänyt seurantapyynnön tälle tilille
- error: Valitettavasti etätilin haussa tapahtui virhe
- follow: Seuraa
- follow_request: 'Olet lähettänyt seuraamispyynnön käyttäjälle:'
- following: 'Onnistui! Seuraat käyttäjää:'
- post_follow:
- close: Tai voit sulkea tämän ikkunan.
- return: Palaa käyttäjän profiiliin
- web: Siirry verkkosivulle
- title: Seuraa käyttäjää %{acct}
challenge:
confirm: Jatka
hint_html: "<strong>Vihje:</strong> Emme pyydä sinulta salasanaa uudelleen seuraavan tunnin aikana."
M config/locales/fo.yml => config/locales/fo.yml +0 -12
@@ 1060,18 1060,6 @@ fo:
view_strikes: Vís eldri atsóknir móti tíni kontu
too_fast: Oyðublaðið innsent ov skjótt, royn aftur.
use_security_key: Brúka trygdarlykil
- authorize_follow:
- already_following: Tú fylgir longu hesi kontuni
- already_requested: Tú hevur longu sent eina fylgiumbøn til hasa kontuna
- error: Tíverri kom ein feilur, tá vit royndu at finna fjarkontuna
- follow: Fylg
- follow_request: 'Tú hevur sent eina fylgjaraumbøn til:'
- following: 'Góðkent! Tú fylgir nú:'
- post_follow:
- close: Ella kanst tú bara lata hetta vindeygað aftur.
- return: Vís vangan hjá brúkaranum
- web: Far á vevið
- title: Fylg %{acct}
challenge:
confirm: Hald á
hint_html: "<strong>Góð ráð:</strong> vit spyrja teg ikki aftur um loyniorðið næsta tíman."
M config/locales/fr-QC.yml => config/locales/fr-QC.yml +0 -12
@@ 1060,18 1060,6 @@ fr-QC:
view_strikes: Voir les sanctions précédemment appliquées à votre compte
too_fast: Formulaire envoyé trop rapidement, veuillez réessayer.
use_security_key: Utiliser la clé de sécurité
- authorize_follow:
- already_following: Vous suivez déjà ce compte
- already_requested: Vous avez déjà envoyé une demande d’abonnement à ce compte
- error: Malheureusement, une erreur s'est produite lors de la recherche du compte distant
- follow: Suivre
- follow_request: 'Vous avez demandé à suivre :'
- following: 'Youpi ! Vous suivez maintenant :'
- post_follow:
- close: Ou bien, vous pouvez fermer cette fenêtre.
- return: Afficher le profil de l’utilisateur·ice
- web: Retour à l’interface web
- title: Suivre %{acct}
challenge:
confirm: Continuer
hint_html: "<strong>Astuce :</strong> Nous ne vous demanderons plus votre mot de passe pour la prochaine heure."
M config/locales/fr.yml => config/locales/fr.yml +0 -12
@@ 1060,18 1060,6 @@ fr:
view_strikes: Voir les sanctions précédemment appliquées à votre compte
too_fast: Formulaire envoyé trop rapidement, veuillez réessayer.
use_security_key: Utiliser la clé de sécurité
- authorize_follow:
- already_following: Vous suivez déjà ce compte
- already_requested: Vous avez déjà envoyé une demande d’abonnement à ce compte
- error: Malheureusement, une erreur s'est produite lors de la recherche du compte distant
- follow: Suivre
- follow_request: 'Vous avez demandé à suivre :'
- following: 'Youpi ! Vous suivez maintenant :'
- post_follow:
- close: Ou bien, vous pouvez fermer cette fenêtre.
- return: Afficher le profil de l’utilisateur·ice
- web: Retour à l’interface web
- title: Suivre %{acct}
challenge:
confirm: Continuer
hint_html: "<strong>Astuce :</strong> Nous ne vous demanderons plus votre mot de passe pour la prochaine heure."
M config/locales/fy.yml => config/locales/fy.yml +0 -12
@@ 1060,18 1060,6 @@ fy:
view_strikes: Besjoch de earder troch moderatoaren fêststelde skeiningen dy’t jo makke hawwe
too_fast: Formulier is te fluch yntsjinne. Probearje it nochris.
use_security_key: Befeiligingskaai brûke
- authorize_follow:
- already_following: Jo folgje dizze account al
- already_requested: Jo hawwe al in folchfersyk nei dat account ferstjoerd
- error: Spitiger, der is in flater bard by it opsykjen fan de eksterne account
- follow: Folgje
- follow_request: 'Jo hawwe in folchfersyk yntsjinne by:'
- following: 'Slagge! Jo folgje no:'
- post_follow:
- close: Of jo kinne dit finster gewoan slute.
- return: Profyl fan dizze brûker toane
- web: Gean nei de webapp
- title: "%{acct} folgje"
challenge:
confirm: Trochgean
hint_html: "<strong>Tip:</strong> Wy freegje jo it kommende oere net mear nei jo wachtwurd."
M config/locales/ga.yml => config/locales/ga.yml +0 -5
@@ 331,11 331,6 @@ ga:
status:
account_status: Stádas cuntais
too_fast: Cuireadh an fhoirm isteach róthapa, triail arís.
- authorize_follow:
- follow: Lean
- post_follow:
- return: Taispeáin próifíl an úsáideora
- title: Lean %{acct}
challenge:
confirm: Lean ar aghaidh
datetime:
M config/locales/gd.yml => config/locales/gd.yml +0 -12
@@ 1095,18 1095,6 @@ gd:
view_strikes: Seall na rabhaidhean a fhuair an cunntas agad roimhe
too_fast: Chaidh am foirm a chur a-null ro luath, feuch ris a-rithist.
use_security_key: Cleachd iuchair tèarainteachd
- authorize_follow:
- already_following: Tha thu a’ leantainn a’ chunntais seo mu thràth
- already_requested: Chuir thu iarrtas leantainn dhan chunntas seo mu thràth
- error: Gu mì-fhortanach, thachair mearachd le lorg a’ chunntais chèin
- follow: Lean
- follow_request: 'Chuir thu iarrtas leantainn gu:'
- following: 'Taghta! Chaidh leat a’ leantainn:'
- post_follow:
- close: Air neo dùin an uinneag seo.
- return: Seall pròifil a’ chleachdaiche
- web: Tadhail air an duilleag-lìn
- title: Lean %{acct}
challenge:
confirm: Lean air adhart
hint_html: "<strong>Gliocas:</strong> Chan iarr sinn am facal-faire agad ort a-rithist fad uair a thìde."
M config/locales/gl.yml => config/locales/gl.yml +0 -12
@@ 1060,18 1060,6 @@ gl:
view_strikes: Ver avisos anteriores respecto da túa conta
too_fast: Formulario enviado demasiado rápido, inténtao outra vez.
use_security_key: Usa chave de seguridade
- authorize_follow:
- already_following: Xa está a seguir esta conta
- already_requested: Xa tes enviada unha solicitude de seguimento a esa conta
- error: Desgraciadamente, algo fallou ao buscar a conta remota
- follow: Seguir
- follow_request: 'Enviaches unha petición de seguimento a:'
- following: 'Parabéns! Agora segues a:'
- post_follow:
- close: Ou, podes pechar esta ventá.
- return: Mostrar o perfil da usuaria
- web: Ir á web
- title: Seguir %{acct}
challenge:
confirm: Continuar
hint_html: "<strong>Nota:</strong> Non che pediremos o contrasinal na seguinte hora."
M config/locales/he.yml => config/locales/he.yml +0 -12
@@ 1096,18 1096,6 @@ he:
view_strikes: צפיה בעברות קודמות שנרשמו נגד חשבונך
too_fast: הטופס הוגש מהר מדי, נסה/י שוב.
use_security_key: שימוש במפתח אבטחה
- authorize_follow:
- already_following: את/ה כבר עוקב/ת אחרי חשבון זה
- already_requested: כבר נשלחה בקשת מעקב לחשבון זה
- error: למרבה הצער, היתה שגיאה בחיפוש החשבון המרוחק
- follow: לעקוב
- follow_request: 'שלחת בקשת מעקב ל:'
- following: 'הצלחה! הינך עוקב עכשיו אחרי:'
- post_follow:
- close: או, פשוט לסגור חלון זה.
- return: הצג את פרופיל המשתמש
- web: מעבר לווב
- title: לעקוב אחרי %{acct}
challenge:
confirm: המשך
hint_html: "<strong>טיפ:</strong> לא נבקש את סיסמתך שוב בשעה הקרובה."
M config/locales/hr.yml => config/locales/hr.yml +0 -4
@@ 64,10 64,6 @@ hr:
reset_password: Ponovno postavi lozinku
security: Sigurnost
set_new_password: Postavi novu lozinku
- authorize_follow:
- error: Nažalost, došlo je do greške tijekom traženja udaljenog računa
- follow: Prati
- title: Prati %{acct}
datetime:
distance_in_words:
about_x_months: "%{count}mj"
M config/locales/hu.yml => config/locales/hu.yml +0 -12
@@ 1060,18 1060,6 @@ hu:
view_strikes: Fiókod ellen felrótt korábbi vétségek megtekintése
too_fast: Túl gyorsan küldted el az űrlapot, próbáld később.
use_security_key: Biztonsági kulcs használata
- authorize_follow:
- already_following: Már követed ezt a felhasználót
- already_requested: Már küldtél követési kérelmet ennek a fióknak
- error: Hiba történt a távoli felhasználó keresésekor
- follow: Követés
- follow_request: 'Engedélyt kértél az alábbi felhasználó követésére:'
- following: 'Siker! Mostantól követed az alábbi felhasználót:'
- post_follow:
- close: Akár be is zárhatod ezt az ablakot.
- return: A felhasználó profiljának mutatása
- web: Megtekintés a weben
- title: "%{acct} követése"
challenge:
confirm: Folytatás
hint_html: "<strong>Hasznos:</strong> Nem fogjuk megint a jelszavadat kérdezni a következő órában."
M config/locales/hy.yml => config/locales/hy.yml +0 -11
@@ 481,17 481,6 @@ hy:
account_status: Հաշուի կարգավիճակ
pending: Դիմումը պէտք է քննուի մեր անձնակազմի կողմից, ինչը կարող է մի փոքր ժամանակ խլել։ Դիմումի հաստատուելու դէպքում, կտեղեկացնենք նամակով։
use_security_key: Օգտագործել անվտանգութեան բանալի
- authorize_follow:
- already_following: Դու արդէն հետեւում ես այս հաշուին
- already_requested: Դու արդէն ուղարկել ես հետեւմանն յայտ այս հաշուին
- follow: Հետևել
- follow_request: Դու ուղարկել ես հետեւելու հայց՝
- following: Յաջողութի՜ւն։ Դու այժմ հետեւում ես․
- post_follow:
- close: Կամ, կարող ես պարզապէս փակել այս պատուհանը։
- return: Ցուցադրել օգտատիրոջ էջը
- web: Անցնել վէբին
- title: Հետեւել %{acct}
challenge:
confirm: Շարունակել
invalid_password: Անվաւեր ծածկագիր
M config/locales/id.yml => config/locales/id.yml +0 -12
@@ 959,18 959,6 @@ id:
view_strikes: Lihat hukuman lalu yang pernah terjadi kepada akun Anda
too_fast: Formulir dikirim terlalu cepat, coba lagi.
use_security_key: Gunakan kunci keamanan
- authorize_follow:
- already_following: Anda sudah mengikuti akun ini
- already_requested: Anda sudah mengirimkan permintaan untuk mengikuti akun tersebut
- error: Sayangnya, ada error saat melihat akun remote
- follow: Ikuti
- follow_request: 'Anda telah mengirim permintaan untuk mengikuti ke:'
- following: 'Berhasil! Anda sekarang mengikuti:'
- post_follow:
- close: Atau Anda dapat menutup jendela ini.
- return: Tampilkan profil pengguna
- web: Ke web
- title: Mengikuti %{acct}
challenge:
confirm: Lanjut
hint_html: "<strong>Tip:</strong> Kami tidak akan meminta kata sandi Anda lagi untuk beberapa jam ke depan."
M config/locales/io.yml => config/locales/io.yml +0 -12
@@ 935,18 935,6 @@ io:
view_strikes: Videz antea streki kontre vua konto
too_fast: Formulario sendesis tro rapide, probez itere.
use_security_key: Uzes sekuresklefo
- authorize_follow:
- already_following: Vu ja sequis ca konto
- already_requested: Vu ja sendis sequodemando a ta konto
- error: Regretinde, eventis eraro probante konsultar la fora konto
- follow: Sequar
- follow_request: 'Vu sendis sequodemando a:'
- following: 'Suceso! Vu nun sequas:'
- post_follow:
- close: O, vu volas jus klozar ca panelo.
- return: Montrez priflo de uzanti
- web: Irez a interreto
- title: Sequar %{acct}
challenge:
confirm: Durez
hint_html: "<strong>Guidilo:</strong> Ni ne demandos vua pasvorto itere til 1 horo."
M config/locales/is.yml => config/locales/is.yml +0 -12
@@ 1064,18 1064,6 @@ is:
view_strikes: Skoða fyrri bönn notandaaðgangsins þíns
too_fast: Innfyllingarform sent inn of hratt, prófaðu aftur.
use_security_key: Nota öryggislykil
- authorize_follow:
- already_following: Þú ert að þegar fylgjast með þessum aðgangi
- already_requested: Þú ert þegar búin/n að senda fylgjendabeiðni á þennan notanda
- error: Því miður, það kom upp villa við að fletta upp fjartengda notandaaðgangnum
- follow: Fylgjast með
- follow_request: 'Þú sendir beiðni um að fylgjast með til:'
- following: 'Tókst! Þú ert núna að fylgjast með:'
- post_follow:
- close: Eða að þú getur lokað þessum glugga.
- return: Birta notandasnið notandans
- web: Fara á vefinn
- title: Fylgjast með %{acct}
challenge:
confirm: Halda áfram
hint_html: "<strong>Ábending:</strong> Við munum ekki spyrja þig um lykilorðið aftur næstu klukkustundina."
M config/locales/it.yml => config/locales/it.yml +0 -12
@@ 1062,18 1062,6 @@ it:
view_strikes: Visualizza le sanzioni precedenti prese nei confronti del tuo account
too_fast: Modulo inviato troppo velocemente, riprova.
use_security_key: Usa la chiave di sicurezza
- authorize_follow:
- already_following: Stai già seguendo questo account
- already_requested: Hai già mandato una richiesta di seguire questo account
- error: Sfortunatamente c'è stato un errore nel consultare l'account remoto
- follow: Segui
- follow_request: 'Hai mandato una richiesta di seguire:'
- following: 'Accettato! Ora stai seguendo:'
- post_follow:
- close: Oppure puoi chiudere questa finestra.
- return: Mostra il profilo dell'utente
- web: Vai al web
- title: Segui %{acct}
challenge:
confirm: Continua
hint_html: "<strong>Suggerimento:</strong> Non ti chiederemo di nuovo la tua password per la prossima ora."
M config/locales/ja.yml => config/locales/ja.yml +0 -12
@@ 1042,18 1042,6 @@ ja:
view_strikes: 過去のストライクを表示
too_fast: フォームの送信が速すぎます。もう一度やり直してください。
use_security_key: セキュリティキーを使用
- authorize_follow:
- already_following: あなたは既にこのアカウントをフォローしています
- already_requested: 既にこのアカウントへフォローリクエストを送信しています
- error: 残念ながら、リモートアカウント情報の取得中にエラーが発生しました
- follow: フォロー
- follow_request: 'あなたは以下のアカウントにフォローリクエストを送信しました:'
- following: '成功! あなたは現在以下のアカウントをフォローしています:'
- post_follow:
- close: またはこのウィンドウを閉じます。
- return: ユーザーのプロフィールを見る
- web: Webを開く
- title: "%{acct}さんをフォロー"
challenge:
confirm: 続ける
hint_html: 以後1時間はパスワードの再入力を求めません
M config/locales/ka.yml => config/locales/ka.yml +0 -11
@@ 232,17 232,6 @@ ka:
reset_password: პაროლის გადატვირთვა
security: უსაფრთხოება
set_new_password: ახალი პაროლის დაყენება
- authorize_follow:
- already_following: უკვე მიჰყვებით ამ ანგარიშს
- error: სამწუხაროთ, დისტანციური სერვერის წაკითხვამ გამოიწვია შეცდომა
- follow: გაყევი
- follow_request: 'დადევნების მოთხონვა გაეგზავნა:'
- following: 'წარმატება! ახლა მიჰყვებით:'
- post_follow:
- close: ან შეგიძლიათ დახუროთ ეს ფანჯარა.
- return: მომხმარებლის პროფილის ჩვენება
- web: ვებზე გადასვლა
- title: გაყევი %{acct}-ს
datetime:
distance_in_words:
about_x_hours: "%{count}სთ"
M config/locales/kab.yml => config/locales/kab.yml +0 -8
@@ 461,14 461,6 @@ kab:
status:
account_status: Addad n umiḍan
use_security_key: Seqdec tasarut n teɣlist
- authorize_follow:
- already_following: Teṭafareḍ ya kan amiḍan-a
- follow: Ḍfeṛ
- following: 'Igerrez! Aqlik teṭafareḍ tura:'
- post_follow:
- return: Ssken-d amaɣnu n useqdac
- web: Ddu γer Web
- title: Ḍfeṛ %{acct}
challenge:
confirm: Kemmel
invalid_password: Yir awal uffir
M config/locales/kk.yml => config/locales/kk.yml +0 -11
@@ 360,17 360,6 @@ kk:
confirming: Электрондық поштаны растау аяқталуын күтуде.
pending: Сіздің өтінішіңіз біздің қызметкерлеріміздің қарауында. Бұл біраз уақыт алуы мүмкін. Өтінішіңіз мақұлданса, сізге электрондық пошта хабарламасы келеді.
redirecting_to: Сіздің есептік жазбаңыз белсенді емес, себебі ол %{acct} жүйесіне қайта бағытталуда.
- authorize_follow:
- already_following: Бұл аккаунтқа жазылғансыз
- error: Өкінішке орай, қашықтағы тіркелгіні іздеуде қате пайда болды
- follow: Жазылу
- follow_request: 'Сіз жазылуға өтініш жібердіңіз:'
- following: 'Керемет! Сіз енді жазылдыңыз:'
- post_follow:
- close: Немесе терезені жаба салыңыз.
- return: Қолданушы профилін көрсет
- web: Вебте ашу
- title: Жазылу %{acct}
challenge:
confirm: Жалғастыру
hint_html: "<strong> Кеңес: </strong> біз келесі сағат ішінде сізден құпия сөзді қайта сұрамаймыз."
M config/locales/ko.yml => config/locales/ko.yml +0 -12
@@ 1044,18 1044,6 @@ ko:
view_strikes: 내 계정에 대한 과거 중재 기록 보기
too_fast: 너무 빠르게 양식이 제출되었습니다, 다시 시도하세요.
use_security_key: 보안 키 사용
- authorize_follow:
- already_following: 이미 이 계정을 팔로우 하고 있습니다
- already_requested: 이미 이 계정에게 팔로우 요청을 보냈습니다
- error: 리모트 계정을 확인하는 도중 오류가 발생했습니다
- follow: 팔로우
- follow_request: '팔로우 요청을 보냄:'
- following: '성공! 당신은 다음 계정을 팔로우 하고 있습니다:'
- post_follow:
- close: 혹은, 그저 이 창을 닫을 수도 있습니다.
- return: 사용자 프로필 보기
- web: 웹으로 가기
- title: "%{acct} 를 팔로우"
challenge:
confirm: 계속
hint_html: "<strong>팁:</strong> 한 시간 동안 다시 암호를 묻지 않을 것입니다."
M config/locales/ku.yml => config/locales/ku.yml +0 -12
@@ 979,18 979,6 @@ ku:
view_strikes: Binpêkirinên berê yên dijî ajimêrê xwe bibîne
too_fast: Form pir zû hat şandin, dîsa biceribîne.
use_security_key: Kilîteke ewlehiyê bi kar bîne
- authorize_follow:
- already_following: Jixwe tu vê ajimêrê dişopînî
- already_requested: Jixwe te ji vê ajimêrê re daxwazîya şopandinê şandi bû
- error: Mixabin, dema ajimêr hat gerandin çewtiyek çêbû
- follow: Bişopîne
- follow_request: 'Te ji vê kesê re daxwazîya şopandinê şand:'
- following: 'Serkeftin! Tu êdî dikarî bişopînî:'
- post_follow:
- close: An jî, tu dikarî tenê ev çarçoveyê bigirî.
- return: Profîla vê bikarhênerê nîşan bike
- web: Biçe tevneyê
- title: "%{acct} bişopîne"
challenge:
confirm: Bidomîne
hint_html: "<strong>Nîşe:</strong>Ji bo demjimêreke din em ê borînpeyva te careke din ji te nexwazin."
M config/locales/lt.yml => config/locales/lt.yml +0 -11
@@ 267,17 267,6 @@ lt:
reset_password: Atstatyti slaptažodį
security: Apsauga
set_new_password: Nustatyti naują slaptažodį
- authorize_follow:
- already_following: Jūs jau sekate šią paskyrą
- error: Dėja, aptikta klaida ieškant tolimosios paskyros
- follow: Sekti
- follow_request: 'Jūs išsiuntėte sekimo prašymą:'
- following: 'Puiku! Jūs pradėjote sekti:'
- post_follow:
- close: Arba, Jūs galite uždaryti šį langą.
- return: Rodyti vartotojo paskyrą
- web: Eiti į
- title: Sekti %{acct}
datetime:
distance_in_words:
about_x_hours: "%{count} val"
M config/locales/lv.yml => config/locales/lv.yml +0 -12
@@ 1057,18 1057,6 @@ lv:
view_strikes: Skati iepriekšējos brīdinājumus par savu kontu
too_fast: Veidlapa ir iesniegta pārāk ātri, mēģini vēlreiz.
use_security_key: Lietot drošības atslēgu
- authorize_follow:
- already_following: Tu jau seko šim kontam
- already_requested: Tu jau esi nosūtījis sekošanas pieteikumu šim kontam
- error: Diemžēl, meklējot attālināto kontu, radās kļūda
- follow: Sekot
- follow_request: 'Tu esi nosūtījis sekošanas pieteikumu:'
- following: 'Veiksmīgi! Tu tagad seko:'
- post_follow:
- close: Vai vienkārši aizver šo logu.
- return: Parādīt lietotāja profilu
- web: Doties uz tīmekli
- title: Sekot %{acct}
challenge:
confirm: Turpināt
hint_html: "<strong>Padoms:</strong> Nākamās stundas laikā mēs tev vairs neprasīsim paroli."
M config/locales/ml.yml => config/locales/ml.yml +0 -10
@@ 76,16 76,6 @@ ml:
invites:
filter:
all: എല്ലാം
- authorize_follow:
- following: 'വിജയകരം! നിങ്ങൾ ഇപ്പോൾ പിന്തുടരുന്നു:'
- errors:
- '400': The request you submitted was invalid or malformed.
- '403': You don't have permission to view this page.
- '404': The page you are looking for isn't here.
- '406': This page is not available in the requested format.
- '410': The page you were looking for doesn't exist here anymore.
- '429': Too many requests
- '503': The page could not be served due to a temporary server failure.
filters:
contexts:
notifications: അറിയിപ്പുകൾ
M config/locales/ms.yml => config/locales/ms.yml +0 -8
@@ 767,14 767,6 @@ ms:
account_status: Status akaun
view_strikes: Lihat pelanggaran yang lepas terhadap akaun anda
use_security_key: Gunakan kunci keselamatan
- authorize_follow:
- follow: Ikut
- follow_request: 'Anda telah menghantar permintaan mengikut kepada:'
- post_follow:
- close: Atau anda boleh tutup tetingkap ini.
- return: Tunjukkan profil pengguna
- web: Pergi ke web
- title: Ikuti %{acct}
challenge:
confirm: Teruskan
invalid_password: Kata laluan tidak sah
M config/locales/my.yml => config/locales/my.yml +0 -12
@@ 1042,18 1042,6 @@ my:
view_strikes: သင့်အကောင့်ကို ဆန့်ကျင်သည့် ယခင်ကလုပ်ဆောင်ချက်များကို ကြည့်ပါ
too_fast: ဖောင်တင်သည်မှာ မြန်နေပါသည်။ ထပ်စမ်းကြည့်ပါ။
use_security_key: လုံခြုံရေးကီးကို သုံးပါ
- authorize_follow:
- already_following: သင်သည် ဤအကောင့်ကို စောင့်ကြည့်နေပြီဖြစ်ပါသည်
- already_requested: သင်သည် ထိုအကောင့်စောင့်ကြည့်ရန် တောင်းဆိုမှုတစ်ခု ပေးပို့ခဲ့ပြီးပါပြီ
- error: ကံမကောင်းစွာဖြင့် အဝေးမှထိန်းချုပ်သောအကောင့်ရှာဖွေရာတွင် အမှားအယွင်းတစ်ခုရှိခဲ့သည်
- follow: စောင့်ကြည့်မယ်
- follow_request: သင်သည် စောင့်ကြည့်မည် တောင်းဆိုချက်တစ်ခု ပေးပို့ထားသည်-
- following: သင် ယခု အောက်ပါအတိုင်း လုပ်ဆောင်နေပါသည် -
- post_follow:
- close: သို့မဟုတ် သင်သည် ဤဝင်းဒိုးကို ပိတ်နိုင်သည်
- return: အသုံးပြုသူ၏ ပရိုဖိုင်ကိုပြရန်
- web: ဝဘ်သို့ သွားပါ
- title: "%{acct} ကို စောင့်ကြည့်မယ်"
challenge:
confirm: ဆက်လုပ်မည်
hint_html: "<strong>အကြံပြုချက် -</strong> နောက်နာရီများတွင် သင့်စကားဝှက်ကို ထပ်မံတောင်းဆိုမည်မဟုတ်ပါ။"
M config/locales/nl.yml => config/locales/nl.yml +0 -12
@@ 1060,18 1060,6 @@ nl:
view_strikes: Bekijk de eerder door moderatoren vastgestelde overtredingen die je hebt gemaakt
too_fast: Formulier is te snel ingediend. Probeer het nogmaals.
use_security_key: Beveiligingssleutel gebruiken
- authorize_follow:
- already_following: Je volgt dit account al
- already_requested: Je hebt al een volgverzoek naar dat account verstuurd
- error: Helaas, er is een fout opgetreden bij het opzoeken van de externe account
- follow: Volgen
- follow_request: 'Jij hebt een volgverzoek ingediend bij:'
- following: 'Succes! Jij volgt nu:'
- post_follow:
- close: Of je kunt dit venster gewoon sluiten.
- return: Profiel van deze gebruiker tonen
- web: Ga naar de webapp
- title: Volg %{acct}
challenge:
confirm: Doorgaan
hint_html: "<strong>Tip:</strong> We vragen jou het komende uur niet meer naar jouw wachtwoord."
M config/locales/nn.yml => config/locales/nn.yml +0 -12
@@ 1049,18 1049,6 @@ nn:
view_strikes: Vis tidligere advarsler mot kontoen din
too_fast: Skjemaet ble sendt inn for raskt, prøv på nytt.
use_security_key: Bruk sikkerhetsnøkkel
- authorize_follow:
- already_following: Du fylgjer allereie denne kontoen
- already_requested: Du har allereie sendt ein fylgjespurnad til den kontoen
- error: Uheldigvis skjedde det en feil da vi prøvde å få tak i en bruker fra en annen instans
- follow: Fylg
- follow_request: 'Du har sendt ein fylgjeførespurnad til:'
- following: 'Suksess! No fylgjer du:'
- post_follow:
- close: Eller så kan du berre lukka att dette vindauget.
- return: Vis brukarprofilen
- web: Gå til nettet
- title: Fylg %{acct}
challenge:
confirm: Hald fram
hint_html: "<strong>Tips:</strong> Vi skal ikkje spørja deg om passordet ditt igjen i laupet av den neste timen."
M config/locales/no.yml => config/locales/no.yml +0 -12
@@ 988,18 988,6 @@
view_strikes: Vis tidligere advarsler mot kontoen din
too_fast: Skjemaet ble sendt inn for raskt, prøv på nytt.
use_security_key: Bruk sikkerhetsnøkkel
- authorize_follow:
- already_following: Du følger allerede denne kontoen
- already_requested: Du har allerede sendt en følgeforespørsel til denne kontoen
- error: Dessverre oppstod det en feil da vi prøvde å få tak i brukeren fra tjeneren
- follow: Følg
- follow_request: 'Du har sendt en følgeforespørsel til:'
- following: 'Suksess! Nå følger du:'
- post_follow:
- close: Eller så kan du lukke dette vinduet.
- return: Gå tilbake til brukerens profil
- web: Gå til nettsiden
- title: Følg %{acct}
challenge:
confirm: Fortsett
hint_html: "<strong>Tips:</strong> Vi ber deg ikke om passordet ditt igjen i løpet av neste time."
M config/locales/oc.yml => config/locales/oc.yml +0 -11
@@ 502,17 502,6 @@ oc:
account_status: Estat del compte
functional: Vòstre compte es complètament foncional.
use_security_key: Utilizar clau de seguretat
- authorize_follow:
- already_following: Seguètz ja aqueste compte
- error: O planhèm, i a agut una error al moment de cercar lo compte
- follow: Sègre
- follow_request: 'Avètz demandat de sègre :'
- following: 'Felicitacion ! Seguètz ara :'
- post_follow:
- close: O podètz tampar aquesta fenèstra.
- return: Veire lo perfil a la persona
- web: Tornar a l’interfàcia Web
- title: Sègre %{acct}
challenge:
confirm: Contunhar
hint_html: "<strong>Asutúcia :</strong> vos demandarem pas vòstre senhal de nòu d’aquí unas oras."
M config/locales/pl.yml => config/locales/pl.yml +0 -12
@@ 1096,18 1096,6 @@ pl:
view_strikes: Zobacz dawne ostrzeżenia nałożone na twoje konto
too_fast: Zbyt szybko przesłano formularz, spróbuj ponownie.
use_security_key: Użyj klucza bezpieczeństwa
- authorize_follow:
- already_following: Już obserwujesz to konto
- already_requested: Już wysłałeś(-aś) prośbę o możliwość obserwowania tego konta
- error: Niestety, podczas sprawdzania zdalnego konta wystąpił błąd
- follow: Obserwuj
- follow_request: 'Wysłano prośbę o możliwość obserwowania:'
- following: 'Pomyślnie! Od teraz obserwujesz:'
- post_follow:
- close: Ewentualnie, możesz po prostu zamknąć tę stronę.
- return: Pokaż stronę użytkownika
- web: Przejdź do sieci
- title: Obserwuj %{acct}
challenge:
confirm: Kontynuuj
hint_html: "<strong>Informacja:</strong> Nie będziemy prosić Cię o ponowne podanie hasła przez następną godzinę."
M config/locales/pt-BR.yml => config/locales/pt-BR.yml +0 -12
@@ 1059,18 1059,6 @@ pt-BR:
view_strikes: Veja os avisos anteriores em relação à sua conta
too_fast: O formulário foi enviado muito rapidamente, tente novamente.
use_security_key: Usar chave de segurança
- authorize_follow:
- already_following: Você já segue
- already_requested: Você já enviou uma solicitação para seguir esta conta
- error: Infelizmente, ocorreu um erro ao buscar a conta remota
- follow: Seguir
- follow_request: 'Você mandou solicitação para seguir para:'
- following: 'Sucesso! Agora você está seguindo:'
- post_follow:
- close: Ou você pode simplesmente fechar esta janela.
- return: Mostrar o perfil do usuário
- web: Voltar à página inicial
- title: Seguir %{acct}
challenge:
confirm: Continuar
hint_html: "<strong>Dica:</strong> Não pediremos novamente sua senha pela próxima hora."
M config/locales/pt-PT.yml => config/locales/pt-PT.yml +0 -12
@@ 1060,18 1060,6 @@ pt-PT:
view_strikes: Veja as reprimendas anteriores sobre a sua conta
too_fast: Formulário enviado demasiado rapidamente, tente novamente.
use_security_key: Usar chave de segurança
- authorize_follow:
- already_following: Tu já estás a seguir esta conta
- already_requested: Já enviou anteriormente um pedido para seguir esta conta
- error: Infelizmente, ocorreu um erro ao buscar a conta remota
- follow: Seguir
- follow_request: 'Enviaste uma solicitação de seguidor para:'
- following: 'Sucesso! Agora estás a seguir a:'
- post_follow:
- close: Ou podes simplesmente fechar esta janela.
- return: Mostrar perfil do utilizador
- web: Ir para a página na teia
- title: Seguir %{acct}
challenge:
confirm: Continuar
hint_html: "<strong>Dica:</strong> Não vamos pedir novamente a sua palavra-passe durante a próxima hora."
M config/locales/ro.yml => config/locales/ro.yml +0 -12
@@ 445,18 445,6 @@ ro:
confirming: Se așteaptă finalizarea confirmării prin e-mail.
pending: Cererea dvs. este în curs de revizuire de către personalul nostru. Este posibil să dureze ceva timp. Veți primi un e-mail dacă cererea dvs. este aprobată.
redirecting_to: Contul dvs. este inactiv deoarece în prezent se redirecționează către %{acct}.
- authorize_follow:
- already_following: Urmărești deja acest cont
- already_requested: Ați trimis deja o cerere de urmărire către acel cont
- error: Din păcate a apărut o eroare
- follow: Urmărește
- follow_request: 'Ai trimis o cerere de urmărire către:'
- following: 'Gata! De acum urmărești:'
- post_follow:
- close: Sau, poți închide această fereastră.
- return: Arată profilul utilizatorului
- web: Mergi la web
- title: Urmărește %{acct}
challenge:
confirm: Continuă
hint_html: "<strong>Sfat:</strong> Nu vă vom mai cere parola pentru următoarea oră."
M config/locales/ru.yml => config/locales/ru.yml +0 -12
@@ 1094,18 1094,6 @@ ru:
view_strikes: Просмотр предыдущих замечаний в адрес вашей учетной записи
too_fast: Форма отправлена слишком быстро, попробуйте еще раз.
use_security_key: Использовать ключ безопасности
- authorize_follow:
- already_following: Вы уже подписаны на эту учётную запись
- already_requested: Вы уже отправили запрос на подписку на эту учётную запись
- error: К сожалению, при поиске удалённой учётной записи возникла ошибка
- follow: Подписаться
- follow_request: 'Вы отправили запрос на подписку:'
- following: 'Готово! Вы подписались на:'
- post_follow:
- close: Или просто закройте это окно.
- return: Вернуться к профилю пользователя
- web: Открыть в веб-версии
- title: Подписаться на %{acct}
challenge:
confirm: Продолжить
hint_html: "<strong>Подсказка</strong>: мы не будем спрашивать пароль повторно в течение часа."
M config/locales/sc.yml => config/locales/sc.yml +0 -12
@@ 537,18 537,6 @@ sc:
redirecting_to: Su contu tuo est inativu pro ite in die de oe est torrende a indiritzare a %{acct}.
too_fast: Formulàriu imbiadu tropu a lestru, torra a proare.
use_security_key: Imprea una crae de seguresa
- authorize_follow:
- already_following: Ses giai sighende custu contu
- already_requested: As giai imbiadu una dimanda de sighidura a custa persone
- error: Faddina in sa chirca de su contu remotu
- follow: Sighi
- follow_request: 'As imbiadu una dimanda de sighidura a:'
- following: 'Fatu! Immoe ses sighende a:'
- post_follow:
- close: O, podes serrare custa ventana.
- return: Ammustra su profilu de custa persone
- web: Bae a su situ web
- title: Sighi a %{acct}
challenge:
confirm: Sighi
hint_html: "<strong>Cussìgiu:</strong> No t'amus a torrare a dimandare sa crae in s'ora imbeniente."
M config/locales/sco.yml => config/locales/sco.yml +0 -12
@@ 969,18 969,6 @@ sco:
view_strikes: Luik at past strikes aginst yer accoont
too_fast: Form submittit ower fast, try again.
use_security_key: Uise security key
- authorize_follow:
- already_following: Ye'r awriddy follaein this accoont
- already_requested: Ye'v awriddy sent a follae request tae that accoont
- error: Unfortunately, there wis a error luikin up the remote accoont
- follow: Follae
- follow_request: 'Ye hae sent a follae request tae:'
- following: 'Success! Ye''r noo follaein:'
- post_follow:
- close: Or, ye kin juist shut this windae.
- return: Shaw the uiser's profile
- web: Gang tae the wab
- title: Follae %{acct}
challenge:
confirm: Continue
hint_html: "<strong>wee tip:</strong> We wullnae ask ye fir yer passwird again fir the neist oor."
M config/locales/si.yml => config/locales/si.yml +0 -12
@@ 803,18 803,6 @@ si:
view_strikes: ඔබගේ ගිණුමට එරෙහිව පසුගිය වර්ජන බලන්න
too_fast: පෝරමය ඉතා වේගයෙන් ඉදිරිපත් කර ඇත, නැවත උත්සාහ කරන්න.
use_security_key: ආරක්ෂක යතුර භාවිතා කරන්න
- authorize_follow:
- already_following: ඔබ දැනටමත් මෙම ගිණුම අනුගමනය කරයි
- already_requested: ඔබ දැනටමත් එම ගිණුමට අනුගමනය ඉල්ලීමක් යවා ඇත
- error: අවාසනාවකට, දුරස්ථ ගිණුම සෙවීමේදී දෝෂයක් ඇති විය
- follow: අනුගමනය
- follow_request: 'ඔබ පහත ඉල්ලීමක් යවා ඇත:'
- following: 'සාර්ථකත්වය! ඔබ දැන් පහත දැක්වේ:'
- post_follow:
- close: හෝ ඔබට මෙම කවුළුව වසාදැමිය හැකිය.
- return: පරිශීලකගේ පැතිකඩ පෙන්වන්න
- web: වියමන ට යන්න
- title: "%{acct} අනුගමනය"
challenge:
confirm: ඉදිරියට
hint_html: "<strong>ඉඟිය:</strong> අපි ඉදිරි පැය සඳහා නැවත ඔබගේ මුරපදය ඔබෙන් නොඉල්ලමු."
M config/locales/sk.yml => config/locales/sk.yml +0 -11
@@ 737,17 737,6 @@ sk:
pending: Tvoja žiadosť čaká na schvílenie od nášho týmu. Môže to chviľu potrvať. Ak bude tvoja žiadosť schválená, dostaneš o tom email.
redirecting_to: Tvoj účet je neaktívny, lebo v súčasnosti presmerováva na %{acct}.
use_security_key: Použi bezpečnostný kľúč
- authorize_follow:
- already_following: Tento účet už nasleduješ
- error: Naneštastie nastala chyba pri hľadaní vzdialeného účtu
- follow: Nasleduj
- follow_request: 'Poslal/a si žiadosť nasledovať užívateľa:'
- following: 'Podarilo sa! Teraz nasleduješ užívateľa:'
- post_follow:
- close: Alebo môžeš iba zatvoriť toto okno.
- return: Ukáž užívateľov profil
- web: Prejdi do siete
- title: Nasleduj %{acct}
challenge:
confirm: Pokračuj
hint_html: "<strong>Tip:</strong> Hodinu nebudeme znovu vyžadovať tvoje heslo."
M config/locales/sl.yml => config/locales/sl.yml +0 -12
@@ 1084,18 1084,6 @@ sl:
view_strikes: Pokaži pretekle ukrepe proti mojemu računu
too_fast: Obrazec oddan prehitro, poskusite znova.
use_security_key: Uporabi varnostni ključ
- authorize_follow:
- already_following: Temu računu že sledite
- already_requested: Temu računu ste že poslali zahtevo po sledenju
- error: Na žalost je prišlo do napake pri iskanju oddaljenega računa
- follow: Sledi
- follow_request: 'Prošnjo za sledenje se poslali:'
- following: 'Uspeh! Zdaj sledite:'
- post_follow:
- close: Lahko pa tudi zaprete to okno.
- return: Prikaži uporabnikov profil
- web: Pojdi na splet
- title: Sledi %{acct}
challenge:
confirm: Nadaljuj
hint_html: "<strong>Namig:</strong> naslednjo uro vas ne bomo več vprašali po vašem geslu."
M config/locales/sq.yml => config/locales/sq.yml +0 -12
@@ 1052,18 1052,6 @@ sq:
view_strikes: Shihni paralajmërime të dikurshme kundër llogarisë tuaj
too_fast: Formulari u parashtrua shumë shpejt, riprovoni.
use_security_key: Përdor kyç sigurie
- authorize_follow:
- already_following: E ndiqni tashmë këtë llogari
- already_requested: Keni dërguar tashmë një kërkesë ndjekjeje te ajo llogari
- error: Mjerisht, pati një gabim gjatë kërkimit të llogarisë së largët
- follow: Ndiqeni
- follow_request: 'Keni dërguar një kërkesë ndjekjeje te:'
- following: 'Sukses! Tani e ndiqni:'
- post_follow:
- close: Ose, thjesht mund të mbyllni këtë dritare.
- return: Shfaq profilin e përdoruesit
- web: Kalo në web
- title: Ndiq %{acct}
challenge:
confirm: Vazhdo
hint_html: "<strong>Ndihmëz:</strong> S’do t’ju pyesim për fjalëkalimin tuaj sërish, për një orë."
M config/locales/sr-Latn.yml => config/locales/sr-Latn.yml +0 -12
@@ 1078,18 1078,6 @@ sr-Latn:
view_strikes: Pogledajte prethodne prestupe upisane na Vaše ime
too_fast: Formular je podnet prebrzo, pokušajte ponovo.
use_security_key: Koristite sigurnosni ključ
- authorize_follow:
- already_following: Već pratite ovaj nalog
- already_requested: Već ste poslali zahtev za praćenje tom nalogu
- error: Nažalost, desila se greška pri traženju udaljenog naloga
- follow: Zaprati
- follow_request: 'Poslali ste zahtev za praćenjen za:'
- following: 'Sjajno! Sada pratite:'
- post_follow:
- close: Ili možete zatvoriti ovaj prozor.
- return: Vrati se na nalog ovog korisnika
- web: Idi na veb
- title: Zaprati %{acct}
challenge:
confirm: Nastavi
hint_html: "<strong>Savet:</strong> Nećemo Vas pitati za lozinku ponovo u narednih sat vremena."
M config/locales/sr.yml => config/locales/sr.yml +0 -12
@@ 1078,18 1078,6 @@ sr:
view_strikes: Погледајте претходне преступе уписане на Ваше име
too_fast: Формулар је поднет пребрзо, покушајте поново.
use_security_key: Користите сигурносни кључ
- authorize_follow:
- already_following: Већ пратите овај налог
- already_requested: Већ сте послали захтев за праћење том налогу
- error: Нажалост, десила се грешка при тражењу удаљеног налога
- follow: Запрати
- follow_request: 'Послали сте захтев за праћењен за:'
- following: 'Сјајно! Сада пратите:'
- post_follow:
- close: Или можете затворити овај прозор.
- return: Врати се на налог овог корисника
- web: Иди на веб
- title: Запрати %{acct}
challenge:
confirm: Настави
hint_html: "<strong>Савет:</strong> Нећемо Вас питати за лозинку поново у наредних сат времена."
M config/locales/sv.yml => config/locales/sv.yml +0 -12
@@ 1042,18 1042,6 @@ sv:
view_strikes: Visa tidigare prickar på ditt konto
too_fast: Formuläret har skickats för snabbt, försök igen.
use_security_key: Använd säkerhetsnyckel
- authorize_follow:
- already_following: Du följer redan detta konto
- already_requested: Du har redan skickat en vänförfrågan till det kontot
- error: Tyvärr inträffade ett fel när vi kontrollerade fjärrkontot
- follow: Följ
- follow_request: 'Du har skickat en följaförfrågan till:'
- following: 'Succé! Du följer nu:'
- post_follow:
- close: Eller så kan du stänga detta fönster.
- return: Visa användarens profil
- web: Gå till webb
- title: Följ %{acct}
challenge:
confirm: Fortsätt
hint_html: "<strong>Tips:</strong> Vi frågar dig inte efter ditt lösenord igen under nästkommande timme."
M config/locales/ta.yml => config/locales/ta.yml +0 -2
@@ 191,8 191,6 @@ ta:
localization:
body: மாஸ்டோடான் தன்னார்வலர்களால் மொழிபெயர்க்கப்படுகிறது.
guide_link_text: அனைவரும் பங்களிக்கலாம்.
- authorize_follow:
- already_requested: இக்கணக்கைப் பின்தொடரும் கோரிக்கையை நீங்கள் ஏற்கனவே அனுப்பிவிட்டீர்கள்
crypto:
errors:
invalid_key: ஒரு முறையான Ed25519 அல்லது Curve25519 key அல்ல
M config/locales/th.yml => config/locales/th.yml +0 -12
@@ 1042,18 1042,6 @@ th:
view_strikes: ดูการดำเนินการที่ผ่านมาต่อบัญชีของคุณ
too_fast: ส่งแบบฟอร์มเร็วเกินไป ลองอีกครั้ง
use_security_key: ใช้กุญแจความปลอดภัย
- authorize_follow:
- already_following: คุณกำลังติดตามบัญชีนี้อยู่แล้ว
- already_requested: คุณได้ส่งคำขอติดตามไปยังบัญชีนั้นไปแล้ว
- error: น่าเสียดาย มีข้อผิดพลาดในการมองหาบัญชีระยะไกล
- follow: ติดตาม
- follow_request: 'คุณได้ส่งคำขอติดตามไปยัง:'
- following: 'สำเร็จ! ตอนนี้คุณกำลังติดตาม:'
- post_follow:
- close: หรือคุณสามารถปิดหน้าต่างนี้
- return: แสดงโปรไฟล์ของผู้ใช้
- web: ไปยังเว็บ
- title: ติดตาม %{acct}
challenge:
confirm: ดำเนินการต่อ
hint_html: "<strong>เคล็ดลับ:</strong> เราจะไม่ถามรหัสผ่านของคุณกับคุณสำหรับชั่วโมงถัดไป"
M config/locales/tr.yml => config/locales/tr.yml +0 -12
@@ 1060,18 1060,6 @@ tr:
view_strikes: Hesabınıza yönelik eski eylemleri görüntüleyin
too_fast: Form çok hızlı gönderildi, tekrar deneyin.
use_security_key: Güvenlik anahtarını kullan
- authorize_follow:
- already_following: Bu hesabı zaten takip ediyorsunuz
- already_requested: Bu hesaba zaten takip isteği gönderdiniz
- error: Uzak hesap aranırken bir hata oluştu
- follow: Takip et
- follow_request: 'Şuna takip isteği gönderdiniz:'
- following: 'Başarılı! Artık şunu takip ediyorsunuz:'
- post_follow:
- close: Ya da, sadece bu pencereyi kapatabilirsiniz.
- return: Kullanıcının profilini göster
- web: Web'e git
- title: "%{acct} takip et"
challenge:
confirm: Devam et
hint_html: "<strong>İpucu:</strong> Önümüzdeki saat boyunca sana parolanı sormayacağız."
M config/locales/tt.yml => config/locales/tt.yml +0 -6
@@ 337,12 337,6 @@ tt:
accept: Кабул итү
back: Кире
security: Хәвефсезлек
- status:
- account_status: Хисап халәте
- authorize_follow:
- follow: Язылу
- post_follow:
- web: Вебга күчү
challenge:
confirm: Дәвам итү
date:
M config/locales/uk.yml => config/locales/uk.yml +0 -12
@@ 1096,18 1096,6 @@ uk:
view_strikes: Переглянути попередні попередження вашому обліковому запису
too_fast: Форму подано занадто швидко, спробуйте ще раз.
use_security_key: Використовувати ключ безпеки
- authorize_follow:
- already_following: Ви вже слідкуєте за цим обліковим записом
- already_requested: Ви вже надіслали запит на підписку до цього облікового запису
- error: На жаль, під час пошуку віддаленого облікового запису сталася помилка
- follow: Підписатися
- follow_request: 'Вам надіслали запит на підписку:'
- following: 'Ура! Ви тепер підписані на:'
- post_follow:
- close: Або, ви можете просто закрити вікно.
- return: Перейти до профілю користувача
- web: Перейти до вебу
- title: Підписатися на %{acct}
challenge:
confirm: Далі
hint_html: "<strong>Підказка:</strong> ми не будемо запитувати ваш пароль впродовж наступної години."
M config/locales/vi.yml => config/locales/vi.yml +0 -12
@@ 1042,18 1042,6 @@ vi:
view_strikes: Xem những lần cảnh cáo cũ
too_fast: Nghi vấn đăng ký spam, xin thử lại.
use_security_key: Dùng khóa bảo mật
- authorize_follow:
- already_following: Bạn đang theo dõi người này
- already_requested: Bạn vừa gửi một yêu cầu theo dõi tới người này
- error: Rất tiếc, đã xảy ra lỗi khi tìm kiếm tài khoản từ nơi khác
- follow: Theo dõi
- follow_request: Bạn đã gửi yêu cầu theo dõi tới
- following: Chúc mừng! Bạn đã trở thành người theo dõi
- post_follow:
- close: Bạn có thể đóng cửa sổ này rồi.
- return: Xem trang hồ sơ
- web: Mở trong Mastodon
- title: Theo dõi %{acct}
challenge:
confirm: Tiếp tục
hint_html: "<strong>Mẹo:</strong> Chúng tôi sẽ không hỏi lại mật khẩu của bạn sau này."
M config/locales/zgh.yml => config/locales/zgh.yml +0 -3
@@ 77,9 77,6 @@ zgh:
register: ⵣⵎⵎⴻⵎ
status:
account_status: ⴰⴷⴷⴰⴷ ⵏ ⵓⵎⵉⴹⴰⵏ
- authorize_follow:
- follow: ⴹⴼⵕ
- title: ⴹⴼⵕ %{acct}
deletes:
proceed: ⴽⴽⵙ ⴰⵎⵉⴹⴰⵏ
errors:
M config/locales/zh-CN.yml => config/locales/zh-CN.yml +0 -12
@@ 1042,18 1042,6 @@ zh-CN:
view_strikes: 查看针对你账号的记录
too_fast: 表单提交过快,请重试。
use_security_key: 使用安全密钥
- authorize_follow:
- already_following: 你已经在关注此用户了
- already_requested: 你已经向那个账户发送过关注请求了
- error: 对不起,寻找这个跨站用户时出错
- follow: 关注
- follow_request: 关注请求已发送给:
- following: 成功!你正在关注:
- post_follow:
- close: 你也可以直接关闭这个窗口。
- return: 查看用户个人资料
- web: 返回本站
- title: 关注 %{acct}
challenge:
confirm: 继续
hint_html: "<strong>注意:</strong>接下来一小时内我们不会再次要求你输入密码。"
M config/locales/zh-HK.yml => config/locales/zh-HK.yml +0 -12
@@ 1005,18 1005,6 @@ zh-HK:
view_strikes: 查看針對你的帳戶的過往警告
too_fast: 你太快遞交了,請再試一次。
use_security_key: 使用安全密鑰裝置
- authorize_follow:
- already_following: 你已經關注了這個帳號
- already_requested: 你先前已向該帳號發送關注請求
- error: 對不起,尋找這個跨站用戶的過程發生錯誤
- follow: 關注
- follow_request: 關注請求已發送给:
- following: 成功!你正在關注:
- post_follow:
- close: 你也可以直接關閉這個頁面。
- return: 顯示個人資料頁
- web: 返回本站
- title: 關注 %{acct}
challenge:
confirm: 繼續
hint_html: "<strong>温馨提示</strong> 我們在未來一小時內不會再要求你填寫密碼。"
M config/locales/zh-TW.yml => config/locales/zh-TW.yml +0 -12
@@ 1046,18 1046,6 @@ zh-TW:
view_strikes: 檢視針對您帳號過去的警示
too_fast: 送出表單的速度太快跟不上,請稍後再試。
use_security_key: 使用安全金鑰
- authorize_follow:
- already_following: 您已經跟隨這個使用者
- already_requested: 您早已向該帳號寄送跟隨請求
- error: 對不起,搜尋其他站點使用者出現錯誤
- follow: 跟隨
- follow_request: 跟隨請求已發送給:
- following: 成功!您正在跟隨:
- post_follow:
- close: 您可以直接關閉此頁面。
- return: 顯示個人檔案
- web: 返回本站
- title: 跟隨 %{acct}
challenge:
confirm: 繼續
hint_html: "<strong>温馨小提醒:</strong> 我們在接下來一小時內不會再要求您輸入密碼。"
M config/routes.rb => config/routes.rb +4 -1
@@ 54,6 54,7 @@ Rails.application.routes.draw do
get '.well-known/nodeinfo', to: 'well_known/nodeinfo#index', as: :nodeinfo, defaults: { format: 'json' }
get '.well-known/webfinger', to: 'well_known/webfinger#show', as: :webfinger
get '.well-known/change-password', to: redirect('/auth/edit')
+ get '.well-known/proxy', to: redirect { |_, request| "/authorize_interaction?#{request.params.to_query}" }
get '/nodeinfo/2.0', to: 'well_known/nodeinfo#show', as: :nodeinfo_schema
@@ 61,6 62,8 @@ Rails.application.routes.draw do
get 'intent', to: 'intents#show'
get 'custom.css', to: 'custom_css#show', as: :custom_css
+ get 'remote_interaction_helper', to: 'remote_interaction_helper#index'
+
resource :instance_actor, path: 'actor', only: [:show] do
resource :inbox, only: [:create], module: :activitypub
resource :outbox, only: [:show], module: :activitypub
@@ 163,7 166,7 @@ Rails.application.routes.draw do
get '/media_proxy/:id/(*any)', to: 'media_proxy#show', as: :media_proxy, format: false
get '/backups/:id/download', to: 'backups#download', as: :download_backup, format: false
- resource :authorize_interaction, only: [:show, :create]
+ resource :authorize_interaction, only: [:show]
resource :share, only: [:show]
draw(:admin)
M config/routes/api.rb => config/routes/api.rb +4 -0
@@ 123,6 123,10 @@ namespace :api, format: false do
resource :activity, only: [:show], controller: 'instances/activity'
end
+ namespace :peers do
+ get :search, to: 'search#index'
+ end
+
resource :domain_blocks, only: [:show, :create, :destroy]
resource :directory, only: [:show]
M lib/mastodon/cli/search.rb => lib/mastodon/cli/search.rb +1 -0
@@ 7,6 7,7 @@ module Mastodon::CLI
# Indices are sorted by amount of data to be expected in each, so that
# smaller indices can go online sooner
INDICES = [
+ InstancesIndex,
AccountsIndex,
TagsIndex,
StatusesIndex,
M spec/controllers/authorize_interactions_controller_spec.rb => spec/controllers/authorize_interactions_controller_spec.rb +4 -47
@@ 24,7 24,7 @@ describe AuthorizeInteractionsController do
it 'renders error without acct param' do
get :show
- expect(response).to render_template(:error)
+ expect(response).to have_http_status(404)
end
it 'renders error when account cant be found' do
@@ 34,7 34,7 @@ describe AuthorizeInteractionsController do
get :show, params: { acct: 'acct:missing@hostname' }
- expect(response).to render_template(:error)
+ expect(response).to have_http_status(404)
expect(service).to have_received(:call).with('missing@hostname')
end
@@ 46,7 46,7 @@ describe AuthorizeInteractionsController do
get :show, params: { acct: 'http://example.com' }
- expect(response).to have_http_status(200)
+ expect(response).to have_http_status(302)
expect(assigns(:resource)).to eq account
end
@@ 58,52 58,9 @@ describe AuthorizeInteractionsController do
get :show, params: { acct: 'acct:found@hostname' }
- expect(response).to have_http_status(200)
+ expect(response).to have_http_status(302)
expect(assigns(:resource)).to eq account
end
end
end
-
- describe 'POST #create' do
- describe 'when signed out' do
- it 'redirects to sign in page' do
- post :create
-
- expect(response).to redirect_to(new_user_session_path)
- end
- end
-
- describe 'when signed in' do
- let!(:user) { Fabricate(:user) }
- let(:account) { user.account }
-
- before do
- sign_in(user)
- end
-
- it 'shows error when account not found' do
- service = instance_double(ResolveAccountService)
-
- allow(ResolveAccountService).to receive(:new).and_return(service)
- allow(service).to receive(:call).with('user@hostname').and_return(nil)
-
- post :create, params: { acct: 'acct:user@hostname' }
-
- expect(response).to render_template(:error)
- end
-
- it 'follows account when found' do
- target_account = Fabricate(:account)
- service = instance_double(ResolveAccountService)
-
- allow(ResolveAccountService).to receive(:new).and_return(service)
- allow(service).to receive(:call).with('user@hostname').and_return(target_account)
-
- post :create, params: { acct: 'acct:user@hostname' }
-
- expect(account.following?(target_account)).to be true
- expect(response).to render_template(:success)
- end
- end
- end
end