Merge pull request #578 from ThibG/glitch-soc/merge-upstream
Merge upstream changes
This commit is contained in:
commit
6eee447159
81 changed files with 3216 additions and 1806 deletions
2
.nvmrc
2
.nvmrc
|
@ -1 +1 @@
|
||||||
6
|
8
|
||||||
|
|
2
Aptfile
2
Aptfile
|
@ -5,6 +5,8 @@ libidn11
|
||||||
libidn11-dev
|
libidn11-dev
|
||||||
libpq-dev
|
libpq-dev
|
||||||
libprotobuf-dev
|
libprotobuf-dev
|
||||||
|
libssl-dev
|
||||||
libxdamage1
|
libxdamage1
|
||||||
libxfixes3
|
libxfixes3
|
||||||
protobuf-compiler
|
protobuf-compiler
|
||||||
|
zlib1g-dev
|
||||||
|
|
23
Dockerfile
23
Dockerfile
|
@ -1,3 +1,4 @@
|
||||||
|
FROM node:8.11.3-alpine as node
|
||||||
FROM ruby:2.4.4-alpine3.6
|
FROM ruby:2.4.4-alpine3.6
|
||||||
|
|
||||||
LABEL maintainer="https://github.com/tootsuite/mastodon" \
|
LABEL maintainer="https://github.com/tootsuite/mastodon" \
|
||||||
|
@ -11,8 +12,6 @@ ENV PATH=/mastodon/bin:$PATH \
|
||||||
RAILS_ENV=production \
|
RAILS_ENV=production \
|
||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
|
|
||||||
ARG YARN_VERSION=1.3.2
|
|
||||||
ARG YARN_DOWNLOAD_SHA256=6cfe82e530ef0837212f13e45c1565ba53f5199eec2527b85ecbcd88bf26821d
|
|
||||||
ARG LIBICONV_VERSION=1.15
|
ARG LIBICONV_VERSION=1.15
|
||||||
ARG LIBICONV_DOWNLOAD_SHA256=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
|
ARG LIBICONV_DOWNLOAD_SHA256=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
|
||||||
|
|
||||||
|
@ -20,6 +19,11 @@ EXPOSE 3000 4000
|
||||||
|
|
||||||
WORKDIR /mastodon
|
WORKDIR /mastodon
|
||||||
|
|
||||||
|
COPY --from=node /usr/local/bin/node /usr/local/bin/node
|
||||||
|
COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules
|
||||||
|
COPY --from=node /usr/local/bin/npm /usr/local/bin/npm
|
||||||
|
COPY --from=node /opt/yarn-* /opt/yarn
|
||||||
|
|
||||||
RUN apk -U upgrade \
|
RUN apk -U upgrade \
|
||||||
&& apk add -t build-dependencies \
|
&& apk add -t build-dependencies \
|
||||||
build-base \
|
build-base \
|
||||||
|
@ -39,20 +43,13 @@ RUN apk -U upgrade \
|
||||||
imagemagick \
|
imagemagick \
|
||||||
libidn \
|
libidn \
|
||||||
libpq \
|
libpq \
|
||||||
nodejs \
|
|
||||||
nodejs-npm \
|
|
||||||
protobuf \
|
protobuf \
|
||||||
tini \
|
tini \
|
||||||
tzdata \
|
tzdata \
|
||||||
&& update-ca-certificates \
|
&& update-ca-certificates \
|
||||||
&& mkdir -p /tmp/src /opt \
|
|
||||||
&& wget -O yarn.tar.gz "https://github.com/yarnpkg/yarn/releases/download/v$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \
|
|
||||||
&& echo "$YARN_DOWNLOAD_SHA256 *yarn.tar.gz" | sha256sum -c - \
|
|
||||||
&& tar -xzf yarn.tar.gz -C /tmp/src \
|
|
||||||
&& rm yarn.tar.gz \
|
|
||||||
&& mv /tmp/src/yarn-v$YARN_VERSION /opt/yarn \
|
|
||||||
&& ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
|
&& ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
|
||||||
&& ln -s /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg \
|
&& ln -s /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg \
|
||||||
|
&& mkdir -p /tmp/src /opt \
|
||||||
&& wget -O libiconv.tar.gz "https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$LIBICONV_VERSION.tar.gz" \
|
&& wget -O libiconv.tar.gz "https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$LIBICONV_VERSION.tar.gz" \
|
||||||
&& echo "$LIBICONV_DOWNLOAD_SHA256 *libiconv.tar.gz" | sha256sum -c - \
|
&& echo "$LIBICONV_DOWNLOAD_SHA256 *libiconv.tar.gz" | sha256sum -c - \
|
||||||
&& tar -xzf libiconv.tar.gz -C /tmp/src \
|
&& tar -xzf libiconv.tar.gz -C /tmp/src \
|
||||||
|
@ -72,7 +69,7 @@ RUN rm /lib/stack-fix.c
|
||||||
|
|
||||||
RUN bundle config build.nokogiri --with-iconv-lib=/usr/local/lib --with-iconv-include=/usr/local/include \
|
RUN bundle config build.nokogiri --with-iconv-lib=/usr/local/lib --with-iconv-include=/usr/local/include \
|
||||||
&& bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without test development \
|
&& bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without test development \
|
||||||
&& yarn --pure-lockfile \
|
&& yarn install --pure-lockfile --ignore-engines \
|
||||||
&& yarn cache clean
|
&& yarn cache clean
|
||||||
|
|
||||||
RUN addgroup -g ${GID} mastodon && adduser -h /mastodon -s /bin/sh -D -G mastodon -u ${UID} mastodon \
|
RUN addgroup -g ${GID} mastodon && adduser -h /mastodon -s /bin/sh -D -G mastodon -u ${UID} mastodon \
|
||||||
|
@ -83,9 +80,11 @@ COPY . /mastodon
|
||||||
|
|
||||||
RUN chown -R mastodon:mastodon /mastodon
|
RUN chown -R mastodon:mastodon /mastodon
|
||||||
|
|
||||||
VOLUME /mastodon/public/system /mastodon/public/assets /mastodon/public/packs
|
VOLUME /mastodon/public/system
|
||||||
|
|
||||||
USER mastodon
|
USER mastodon
|
||||||
|
|
||||||
ENV LD_PRELOAD=/lib/stack-fix.so
|
ENV LD_PRELOAD=/lib/stack-fix.so
|
||||||
|
RUN OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder bundle exec rails assets:precompile
|
||||||
|
|
||||||
ENTRYPOINT ["/sbin/tini", "--"]
|
ENTRYPOINT ["/sbin/tini", "--"]
|
||||||
|
|
58
app/controllers/admin/relays_controller.rb
Normal file
58
app/controllers/admin/relays_controller.rb
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
class RelaysController < BaseController
|
||||||
|
before_action :set_relay, except: [:index, :new, :create]
|
||||||
|
|
||||||
|
def index
|
||||||
|
authorize :relay, :update?
|
||||||
|
@relays = Relay.all
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
authorize :relay, :update?
|
||||||
|
@relay = Relay.new(inbox_url: Relay::PRESET_RELAY)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
authorize :relay, :update?
|
||||||
|
|
||||||
|
@relay = Relay.new(resource_params)
|
||||||
|
|
||||||
|
if @relay.save
|
||||||
|
@relay.enable!
|
||||||
|
redirect_to admin_relays_path
|
||||||
|
else
|
||||||
|
render action: :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
authorize :relay, :update?
|
||||||
|
@relay.destroy
|
||||||
|
redirect_to admin_relays_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def enable
|
||||||
|
authorize :relay, :update?
|
||||||
|
@relay.enable!
|
||||||
|
redirect_to admin_relays_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def disable
|
||||||
|
authorize :relay, :update?
|
||||||
|
@relay.disable!
|
||||||
|
redirect_to admin_relays_path
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_relay
|
||||||
|
@relay = Relay.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def resource_params
|
||||||
|
params.require(:relay).permit(:inbox_url)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -67,7 +67,7 @@ module StreamEntriesHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def acct(account)
|
def acct(account)
|
||||||
if embedded_view? && account.local?
|
if account.local?
|
||||||
"@#{account.acct}@#{Rails.configuration.x.local_domain}"
|
"@#{account.acct}@#{Rails.configuration.x.local_domain}"
|
||||||
else
|
else
|
||||||
"@#{account.acct}"
|
"@#{account.acct}"
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
// This file will be loaded on admin pages, regardless of theme.
|
// This file will be loaded on admin pages, regardless of theme.
|
||||||
|
|
||||||
import { delegate } from 'rails-ujs';
|
import { delegate } from 'rails-ujs';
|
||||||
|
import { start } from '../mastodon/common';
|
||||||
|
|
||||||
|
start();
|
||||||
|
|
||||||
function handleDeleteStatus(event) {
|
function handleDeleteStatus(event) {
|
||||||
const [data] = event.detail;
|
const [data] = event.detail;
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
// This file will be loaded on all pages, regardless of theme.
|
// This file will be loaded on all pages, regardless of theme.
|
||||||
|
|
||||||
import { start } from 'rails-ujs';
|
|
||||||
import 'font-awesome/css/font-awesome.css';
|
import 'font-awesome/css/font-awesome.css';
|
||||||
|
|
||||||
require.context('../images/', true);
|
require.context('../images/', true);
|
||||||
|
|
||||||
start();
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
import { start } from 'rails-ujs';
|
||||||
|
|
||||||
|
start();
|
||||||
|
|
||||||
import 'flavours/glitch/styles/index.scss';
|
import 'flavours/glitch/styles/index.scss';
|
||||||
|
|
||||||
// This ensures that webpack compiles our images.
|
// This ensures that webpack compiles our images.
|
||||||
|
|
|
@ -128,7 +128,7 @@ export function expandDomainBlocks() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const url = getState().getIn(['domain_lists', 'blocks', 'next']);
|
const url = getState().getIn(['domain_lists', 'blocks', 'next']);
|
||||||
|
|
||||||
if (url === null) {
|
if (!url) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
app/javascript/mastodon/common.js
Normal file
8
app/javascript/mastodon/common.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import Rails from 'rails-ujs';
|
||||||
|
|
||||||
|
export function start() {
|
||||||
|
require('font-awesome/css/font-awesome.css');
|
||||||
|
require.context('../images/', true);
|
||||||
|
|
||||||
|
Rails.start();
|
||||||
|
};
|
|
@ -7,7 +7,7 @@ import { connect } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import { me, invitesEnabled } from '../../initial_state';
|
import { me, invitesEnabled, version } from '../../initial_state';
|
||||||
import { fetchFollowRequests } from '../../actions/accounts';
|
import { fetchFollowRequests } from '../../actions/accounts';
|
||||||
import { List as ImmutableList } from 'immutable';
|
import { List as ImmutableList } from 'immutable';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
@ -149,7 +149,7 @@ export default class GettingStarted extends ImmutablePureComponent {
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='getting_started.open_source_notice'
|
id='getting_started.open_source_notice'
|
||||||
defaultMessage='Mastodon is open source software. You can contribute or report issues on GitHub at {github}.'
|
defaultMessage='Mastodon is open source software. You can contribute or report issues on GitHub at {github}.'
|
||||||
values={{ github: <a href='https://github.com/tootsuite/mastodon' rel='noopener' target='_blank'>tootsuite/mastodon</a> }}
|
values={{ github: <span><a href='https://github.com/tootsuite/mastodon' rel='noopener' target='_blank'>tootsuite/mastodon</a> (v{version})</span> }}
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { LoadingBar } from 'react-redux-loading-bar';
|
||||||
import ZoomableImage from './zoomable_image';
|
import ZoomableImage from './zoomable_image';
|
||||||
|
|
||||||
export default class ImageLoader extends React.PureComponent {
|
export default class ImageLoader extends React.PureComponent {
|
||||||
|
@ -23,6 +24,7 @@ export default class ImageLoader extends React.PureComponent {
|
||||||
state = {
|
state = {
|
||||||
loading: true,
|
loading: true,
|
||||||
error: false,
|
error: false,
|
||||||
|
width: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
removers = [];
|
removers = [];
|
||||||
|
@ -122,6 +124,7 @@ export default class ImageLoader extends React.PureComponent {
|
||||||
|
|
||||||
setCanvasRef = c => {
|
setCanvasRef = c => {
|
||||||
this.canvas = c;
|
this.canvas = c;
|
||||||
|
if (c) this.setState({ width: c.offsetWidth });
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
@ -135,6 +138,7 @@ export default class ImageLoader extends React.PureComponent {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className}>
|
<div className={className}>
|
||||||
|
<LoadingBar loading={loading ? 1 : 0} className='loading-bar' style={{ width: this.state.width || width }} />
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<canvas
|
<canvas
|
||||||
className='image-loader__preview-canvas'
|
className='image-loader__preview-canvas'
|
||||||
|
|
|
@ -13,5 +13,6 @@ export const me = getMeta('me');
|
||||||
export const searchEnabled = getMeta('search_enabled');
|
export const searchEnabled = getMeta('search_enabled');
|
||||||
export const maxChars = getMeta('max_toot_chars') || 500;
|
export const maxChars = getMeta('max_toot_chars') || 500;
|
||||||
export const invitesEnabled = getMeta('invites_enabled');
|
export const invitesEnabled = getMeta('invites_enabled');
|
||||||
|
export const version = getMeta('version');
|
||||||
|
|
||||||
export default initialState;
|
export default initialState;
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
"account.direct": "Direct message @{name}",
|
"account.direct": "Direct message @{name}",
|
||||||
"account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
|
"account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
|
||||||
"account.domain_blocked": "Domain hidden",
|
"account.domain_blocked": "Domain hidden",
|
||||||
"account.edit_profile": "Edit profile",
|
"account.edit_profile": "Uprav profil",
|
||||||
"account.follow": "Follow",
|
"account.follow": "Sleduj",
|
||||||
"account.followers": "Followers",
|
"account.followers": "Sledovatelé",
|
||||||
"account.follows": "Follows",
|
"account.follows": "Sleduje",
|
||||||
"account.follows_you": "Follows you",
|
"account.follows_you": "Follows you",
|
||||||
"account.hide_reblogs": "Hide boosts from @{name}",
|
"account.hide_reblogs": "Hide boosts from @{name}",
|
||||||
"account.media": "Media",
|
"account.media": "Media",
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
"compose_form.hashtag_warning": "Αυτό το τουτ δεν θα εμφανίζεται κάτω από κανένα hashtag καθώς είναι αφανές. Μόνο τα δημόσια τουτ μπορούν να αναζητηθούν ανά hashtag.",
|
"compose_form.hashtag_warning": "Αυτό το τουτ δεν θα εμφανίζεται κάτω από κανένα hashtag καθώς είναι αφανές. Μόνο τα δημόσια τουτ μπορούν να αναζητηθούν ανά hashtag.",
|
||||||
"compose_form.lock_disclaimer": "Ο λογαριασμός σου δεν είναι {locked}. Οποιοσδήποτε μπορεί να σε ακολουθήσει για να δει τις δημοσιεύσεις σας προς τους ακολούθους σας.",
|
"compose_form.lock_disclaimer": "Ο λογαριασμός σου δεν είναι {locked}. Οποιοσδήποτε μπορεί να σε ακολουθήσει για να δει τις δημοσιεύσεις σας προς τους ακολούθους σας.",
|
||||||
"compose_form.lock_disclaimer.lock": "κλειδωμένος",
|
"compose_form.lock_disclaimer.lock": "κλειδωμένος",
|
||||||
"compose_form.placeholder": "Τι έχεις στο μυαλό σου;",
|
"compose_form.placeholder": "Τι σκέφτεσαι;",
|
||||||
"compose_form.publish": "Τουτ",
|
"compose_form.publish": "Τουτ",
|
||||||
"compose_form.publish_loud": "{publish}!",
|
"compose_form.publish_loud": "{publish}!",
|
||||||
"compose_form.sensitive.marked": "Το πολυμέσο έχει σημειωθεί ως ευαίσθητο",
|
"compose_form.sensitive.marked": "Το πολυμέσο έχει σημειωθεί ως ευαίσθητο",
|
||||||
|
|
|
@ -166,7 +166,7 @@
|
||||||
"navigation_bar.domain_blocks": "دامینهای پنهانشده",
|
"navigation_bar.domain_blocks": "دامینهای پنهانشده",
|
||||||
"navigation_bar.edit_profile": "ویرایش نمایه",
|
"navigation_bar.edit_profile": "ویرایش نمایه",
|
||||||
"navigation_bar.favourites": "پسندیدهها",
|
"navigation_bar.favourites": "پسندیدهها",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "واژگان بیصداشده",
|
||||||
"navigation_bar.follow_requests": "درخواستهای پیگیری",
|
"navigation_bar.follow_requests": "درخواستهای پیگیری",
|
||||||
"navigation_bar.info": "اطلاعات تکمیلی",
|
"navigation_bar.info": "اطلاعات تکمیلی",
|
||||||
"navigation_bar.keyboard_shortcuts": "میانبرهای صفحهکلید",
|
"navigation_bar.keyboard_shortcuts": "میانبرهای صفحهکلید",
|
||||||
|
|
|
@ -170,7 +170,7 @@
|
||||||
"navigation_bar.domain_blocks": "非表示にしたドメイン",
|
"navigation_bar.domain_blocks": "非表示にしたドメイン",
|
||||||
"navigation_bar.edit_profile": "プロフィールを編集",
|
"navigation_bar.edit_profile": "プロフィールを編集",
|
||||||
"navigation_bar.favourites": "お気に入り",
|
"navigation_bar.favourites": "お気に入り",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "フィルター設定",
|
||||||
"navigation_bar.follow_requests": "フォローリクエスト",
|
"navigation_bar.follow_requests": "フォローリクエスト",
|
||||||
"navigation_bar.info": "このインスタンスについて",
|
"navigation_bar.info": "このインスタンスについて",
|
||||||
"navigation_bar.keyboard_shortcuts": "ホットキー",
|
"navigation_bar.keyboard_shortcuts": "ホットキー",
|
||||||
|
|
|
@ -166,7 +166,7 @@
|
||||||
"navigation_bar.domain_blocks": "Verborgen domeinen",
|
"navigation_bar.domain_blocks": "Verborgen domeinen",
|
||||||
"navigation_bar.edit_profile": "Profiel bewerken",
|
"navigation_bar.edit_profile": "Profiel bewerken",
|
||||||
"navigation_bar.favourites": "Favorieten",
|
"navigation_bar.favourites": "Favorieten",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Genegeerde woorden",
|
||||||
"navigation_bar.follow_requests": "Volgverzoeken",
|
"navigation_bar.follow_requests": "Volgverzoeken",
|
||||||
"navigation_bar.info": "Over deze server",
|
"navigation_bar.info": "Over deze server",
|
||||||
"navigation_bar.keyboard_shortcuts": "Sneltoetsen",
|
"navigation_bar.keyboard_shortcuts": "Sneltoetsen",
|
||||||
|
|
|
@ -166,7 +166,7 @@
|
||||||
"navigation_bar.domain_blocks": "Domenis resconduts",
|
"navigation_bar.domain_blocks": "Domenis resconduts",
|
||||||
"navigation_bar.edit_profile": "Modificar lo perfil",
|
"navigation_bar.edit_profile": "Modificar lo perfil",
|
||||||
"navigation_bar.favourites": "Favorits",
|
"navigation_bar.favourites": "Favorits",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Mots ignorats",
|
||||||
"navigation_bar.follow_requests": "Demandas d’abonament",
|
"navigation_bar.follow_requests": "Demandas d’abonament",
|
||||||
"navigation_bar.info": "Mai informacions",
|
"navigation_bar.info": "Mai informacions",
|
||||||
"navigation_bar.keyboard_shortcuts": "Acorchis clavièr",
|
"navigation_bar.keyboard_shortcuts": "Acorchis clavièr",
|
||||||
|
|
|
@ -166,7 +166,7 @@
|
||||||
"navigation_bar.domain_blocks": "Domínios escondidos",
|
"navigation_bar.domain_blocks": "Domínios escondidos",
|
||||||
"navigation_bar.edit_profile": "Editar perfil",
|
"navigation_bar.edit_profile": "Editar perfil",
|
||||||
"navigation_bar.favourites": "Favoritos",
|
"navigation_bar.favourites": "Favoritos",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Palavras silenciadas",
|
||||||
"navigation_bar.follow_requests": "Seguidores pendentes",
|
"navigation_bar.follow_requests": "Seguidores pendentes",
|
||||||
"navigation_bar.info": "Mais informações",
|
"navigation_bar.info": "Mais informações",
|
||||||
"navigation_bar.keyboard_shortcuts": "Atalhos de teclado",
|
"navigation_bar.keyboard_shortcuts": "Atalhos de teclado",
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
"account.disclaimer_full": "Inofrmácie uvedené nižšie nemusia byť úplným odrazom uživateľovho účtu.",
|
"account.disclaimer_full": "Inofrmácie uvedené nižšie nemusia byť úplným odrazom uživateľovho účtu.",
|
||||||
"account.domain_blocked": "Doména ukrytá",
|
"account.domain_blocked": "Doména ukrytá",
|
||||||
"account.edit_profile": "Upraviť profil",
|
"account.edit_profile": "Upraviť profil",
|
||||||
"account.follow": "Následovať",
|
"account.follow": "Následuj",
|
||||||
"account.followers": "Sledujúci",
|
"account.followers": "Sledujúci",
|
||||||
"account.follows": "Následuje",
|
"account.follows": "Následuje",
|
||||||
"account.follows_you": "Následuje ťa",
|
"account.follows_you": "Následuje ťa",
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import loadPolyfills from '../mastodon/load_polyfills';
|
import loadPolyfills from '../mastodon/load_polyfills';
|
||||||
|
import { start } from '../mastodon/common';
|
||||||
|
|
||||||
|
start();
|
||||||
|
|
||||||
function loaded() {
|
function loaded() {
|
||||||
const TimelineContainer = require('../mastodon/containers/timeline_container').default;
|
const TimelineContainer = require('../mastodon/containers/timeline_container').default;
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import loadPolyfills from '../mastodon/load_polyfills';
|
import loadPolyfills from '../mastodon/load_polyfills';
|
||||||
|
import { start } from '../mastodon/common';
|
||||||
|
|
||||||
|
start();
|
||||||
|
|
||||||
loadPolyfills().then(() => {
|
loadPolyfills().then(() => {
|
||||||
require('../mastodon/main').default();
|
require('../mastodon/main').default();
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import loadPolyfills from '../mastodon/load_polyfills';
|
import loadPolyfills from '../mastodon/load_polyfills';
|
||||||
import ready from '../mastodon/ready';
|
import ready from '../mastodon/ready';
|
||||||
|
import { start } from '../mastodon/common';
|
||||||
|
|
||||||
|
start();
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
const IntlRelativeFormat = require('intl-relativeformat').default;
|
const IntlRelativeFormat = require('intl-relativeformat').default;
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import loadPolyfills from '../mastodon/load_polyfills';
|
import loadPolyfills from '../mastodon/load_polyfills';
|
||||||
|
import { start } from '../mastodon/common';
|
||||||
|
|
||||||
|
start();
|
||||||
|
|
||||||
function loaded() {
|
function loaded() {
|
||||||
const ComposeContainer = require('../mastodon/containers/compose_container').default;
|
const ComposeContainer = require('../mastodon/containers/compose_container').default;
|
||||||
|
|
|
@ -165,6 +165,11 @@
|
||||||
color: $valid-value-color;
|
color: $valid-value-color;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.negative-hint {
|
||||||
|
color: $error-value-color;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.simple_form {
|
.simple_form {
|
||||||
|
|
|
@ -1478,6 +1478,7 @@ a.account__display-name {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
.image-loader__preview-canvas {
|
.image-loader__preview-canvas {
|
||||||
max-width: $media-modal-media-max-width;
|
max-width: $media-modal-media-max-width;
|
||||||
|
@ -1486,8 +1487,8 @@ a.account__display-name {
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.image-loader--loading .image-loader__preview-canvas {
|
.loading-bar {
|
||||||
filter: blur(2px);
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.image-loader--amorphous .image-loader__preview-canvas {
|
&.image-loader--amorphous .image-loader__preview-canvas {
|
||||||
|
|
|
@ -3,12 +3,16 @@
|
||||||
class LanguageDetector
|
class LanguageDetector
|
||||||
include Singleton
|
include Singleton
|
||||||
|
|
||||||
|
CHARACTER_THRESHOLD = 140
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@identifier = CLD3::NNetLanguageIdentifier.new(1, 2048)
|
@identifier = CLD3::NNetLanguageIdentifier.new(1, 2048)
|
||||||
end
|
end
|
||||||
|
|
||||||
def detect(text, account)
|
def detect(text, account)
|
||||||
detect_language_code(text) || default_locale(account)
|
input_text = prepare_text(text)
|
||||||
|
return if input_text.blank?
|
||||||
|
detect_language_code(input_text) || default_locale(account)
|
||||||
end
|
end
|
||||||
|
|
||||||
def language_names
|
def language_names
|
||||||
|
@ -23,8 +27,13 @@ class LanguageDetector
|
||||||
simplify_text(text).strip
|
simplify_text(text).strip
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def unreliable_input?(text)
|
||||||
|
text.size < CHARACTER_THRESHOLD
|
||||||
|
end
|
||||||
|
|
||||||
def detect_language_code(text)
|
def detect_language_code(text)
|
||||||
result = @identifier.find_language(prepare_text(text))
|
return if unreliable_input?(text)
|
||||||
|
result = @identifier.find_language(text)
|
||||||
iso6391(result.language.to_s).to_sym if result.reliable?
|
iso6391(result.language.to_s).to_sym if result.reliable?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -66,6 +75,6 @@ class LanguageDetector
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_locale(account)
|
def default_locale(account)
|
||||||
account.user_locale&.to_sym
|
account.user_locale&.to_sym || I18n.default_locale
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,6 +12,8 @@ class PotentialFriendshipTracker
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def record(account_id, target_account_id, action)
|
def record(account_id, target_account_id, action)
|
||||||
|
return if account_id == target_account_id
|
||||||
|
|
||||||
key = "interactions:#{account_id}"
|
key = "interactions:#{account_id}"
|
||||||
weight = WEIGHTS[action]
|
weight = WEIGHTS[action]
|
||||||
|
|
||||||
|
|
74
app/models/relay.rb
Normal file
74
app/models/relay.rb
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: relays
|
||||||
|
#
|
||||||
|
# id :bigint(8) not null, primary key
|
||||||
|
# inbox_url :string default(""), not null
|
||||||
|
# enabled :boolean default(FALSE), not null
|
||||||
|
# follow_activity_id :string
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
|
||||||
|
class Relay < ApplicationRecord
|
||||||
|
PRESET_RELAY = 'https://relay.joinmastodon.org/inbox'
|
||||||
|
|
||||||
|
validates :inbox_url, presence: true, uniqueness: true, url: true, if: :will_save_change_to_inbox_url?
|
||||||
|
|
||||||
|
scope :enabled, -> { where(enabled: true) }
|
||||||
|
|
||||||
|
before_destroy :ensure_disabled
|
||||||
|
|
||||||
|
def enable!
|
||||||
|
activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
|
||||||
|
payload = Oj.dump(follow_activity(activity_id))
|
||||||
|
|
||||||
|
ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
|
||||||
|
update(enabled: true, follow_activity_id: activity_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def disable!
|
||||||
|
activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
|
||||||
|
payload = Oj.dump(unfollow_activity(activity_id))
|
||||||
|
|
||||||
|
ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
|
||||||
|
update(enabled: false, follow_activity_id: nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def follow_activity(activity_id)
|
||||||
|
{
|
||||||
|
'@context': ActivityPub::TagManager::CONTEXT,
|
||||||
|
id: activity_id,
|
||||||
|
type: 'Follow',
|
||||||
|
actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
|
||||||
|
object: ActivityPub::TagManager::COLLECTIONS[:public],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def unfollow_activity(activity_id)
|
||||||
|
{
|
||||||
|
'@context': ActivityPub::TagManager::CONTEXT,
|
||||||
|
id: activity_id,
|
||||||
|
type: 'Undo',
|
||||||
|
actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
|
||||||
|
object: {
|
||||||
|
id: follow_activity_id,
|
||||||
|
type: 'Follow',
|
||||||
|
actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
|
||||||
|
object: ActivityPub::TagManager::COLLECTIONS[:public],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def some_local_account
|
||||||
|
@some_local_account ||= Account.local.find_by(suspended: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ensure_disabled
|
||||||
|
return unless enabled?
|
||||||
|
disable!
|
||||||
|
end
|
||||||
|
end
|
7
app/policies/relay_policy.rb
Normal file
7
app/policies/relay_policy.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class RelayPolicy < ApplicationPolicy
|
||||||
|
def update?
|
||||||
|
admin?
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ActivityPub::DeleteActorSerializer < ActiveModel::Serializer
|
class ActivityPub::DeleteActorSerializer < ActiveModel::Serializer
|
||||||
attributes :id, :type, :actor
|
attributes :id, :type, :actor, :to
|
||||||
attribute :virtual_object, key: :object
|
attribute :virtual_object, key: :object
|
||||||
|
|
||||||
def id
|
def id
|
||||||
|
@ -19,4 +19,8 @@ class ActivityPub::DeleteActorSerializer < ActiveModel::Serializer
|
||||||
def virtual_object
|
def virtual_object
|
||||||
actor
|
actor
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to
|
||||||
|
[ActivityPub::TagManager::COLLECTIONS[:public]]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,7 +17,7 @@ class ActivityPub::DeleteSerializer < ActiveModel::Serializer
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
attributes :id, :type, :actor
|
attributes :id, :type, :actor, :to
|
||||||
|
|
||||||
has_one :object, serializer: TombstoneSerializer
|
has_one :object, serializer: TombstoneSerializer
|
||||||
|
|
||||||
|
@ -32,4 +32,8 @@ class ActivityPub::DeleteSerializer < ActiveModel::Serializer
|
||||||
def actor
|
def actor
|
||||||
ActivityPub::TagManager.instance.uri_for(object.account)
|
ActivityPub::TagManager.instance.uri_for(object.account)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to
|
||||||
|
[ActivityPub::TagManager::COLLECTIONS[:public]]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ActivityPub::UndoAnnounceSerializer < ActiveModel::Serializer
|
class ActivityPub::UndoAnnounceSerializer < ActiveModel::Serializer
|
||||||
attributes :id, :type, :actor
|
attributes :id, :type, :actor, :to
|
||||||
|
|
||||||
has_one :object, serializer: ActivityPub::ActivitySerializer
|
has_one :object, serializer: ActivityPub::ActivitySerializer
|
||||||
|
|
||||||
|
@ -16,4 +16,8 @@ class ActivityPub::UndoAnnounceSerializer < ActiveModel::Serializer
|
||||||
def actor
|
def actor
|
||||||
ActivityPub::TagManager.instance.uri_for(object.account)
|
ActivityPub::TagManager.instance.uri_for(object.account)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to
|
||||||
|
[ActivityPub::TagManager::COLLECTIONS[:public]]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ActivityPub::UpdateSerializer < ActiveModel::Serializer
|
class ActivityPub::UpdateSerializer < ActiveModel::Serializer
|
||||||
attributes :id, :type, :actor
|
attributes :id, :type, :actor, :to
|
||||||
|
|
||||||
has_one :object, serializer: ActivityPub::ActorSerializer
|
has_one :object, serializer: ActivityPub::ActorSerializer
|
||||||
|
|
||||||
|
@ -16,4 +16,8 @@ class ActivityPub::UpdateSerializer < ActiveModel::Serializer
|
||||||
def actor
|
def actor
|
||||||
ActivityPub::TagManager.instance.uri_for(object)
|
ActivityPub::TagManager.instance.uri_for(object)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to
|
||||||
|
[ActivityPub::TagManager::COLLECTIONS[:public]]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,6 +19,7 @@ class InitialStateSerializer < ActiveModel::Serializer
|
||||||
domain: Rails.configuration.x.local_domain,
|
domain: Rails.configuration.x.local_domain,
|
||||||
admin: object.admin&.id&.to_s,
|
admin: object.admin&.id&.to_s,
|
||||||
search_enabled: Chewy.enabled?,
|
search_enabled: Chewy.enabled?,
|
||||||
|
version: Mastodon::Version.to_s,
|
||||||
invites_enabled: Setting.min_invite_role == 'user',
|
invites_enabled: Setting.min_invite_role == 'user',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,18 @@ class RemoveStatusService < BaseService
|
||||||
ActivityPub::DeliveryWorker.push_bulk(@account.followers.inboxes) do |inbox_url|
|
ActivityPub::DeliveryWorker.push_bulk(@account.followers.inboxes) do |inbox_url|
|
||||||
[signed_activity_json, @account.id, inbox_url]
|
[signed_activity_json, @account.id, inbox_url]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
relay! if relayable?
|
||||||
|
end
|
||||||
|
|
||||||
|
def relayable?
|
||||||
|
@status.public_visibility?
|
||||||
|
end
|
||||||
|
|
||||||
|
def relay!
|
||||||
|
ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
|
||||||
|
[signed_activity_json, @account.id, inbox_url]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def salmon_xml
|
def salmon_xml
|
||||||
|
|
|
@ -22,7 +22,13 @@ class SuspendAccountService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def purge_content!
|
def purge_content!
|
||||||
ActivityPub::RawDistributionWorker.perform_async(delete_actor_json, @account.id) if @account.local?
|
if @account.local?
|
||||||
|
ActivityPub::RawDistributionWorker.perform_async(delete_actor_json, @account.id)
|
||||||
|
|
||||||
|
ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
|
||||||
|
[delete_actor_json, @account.id, inbox_url]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@account.statuses.reorder(nil).find_in_batches do |statuses|
|
@account.statuses.reorder(nil).find_in_batches do |statuses|
|
||||||
BatchedRemoveStatusService.new.call(statuses)
|
BatchedRemoveStatusService.new.call(statuses)
|
||||||
|
@ -59,12 +65,14 @@ class SuspendAccountService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_actor_json
|
def delete_actor_json
|
||||||
|
return @delete_actor_json if defined?(@delete_actor_json)
|
||||||
|
|
||||||
payload = ActiveModelSerializers::SerializableResource.new(
|
payload = ActiveModelSerializers::SerializableResource.new(
|
||||||
@account,
|
@account,
|
||||||
serializer: ActivityPub::DeleteActorSerializer,
|
serializer: ActivityPub::DeleteActorSerializer,
|
||||||
adapter: ActivityPub::Adapter
|
adapter: ActivityPub::Adapter
|
||||||
).as_json
|
).as_json
|
||||||
|
|
||||||
Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account))
|
@delete_actor_json = Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
21
app/views/admin/relays/_relay.html.haml
Normal file
21
app/views/admin/relays/_relay.html.haml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%samp= relay.inbox_url
|
||||||
|
%td
|
||||||
|
- if relay.enabled?
|
||||||
|
%span.positive-hint
|
||||||
|
= fa_icon('check')
|
||||||
|
= ' '
|
||||||
|
= t 'admin.relays.enabled'
|
||||||
|
- else
|
||||||
|
%span.negative-hint
|
||||||
|
= fa_icon('times')
|
||||||
|
= ' '
|
||||||
|
= t 'admin.relays.disabled'
|
||||||
|
%td
|
||||||
|
- if relay.enabled?
|
||||||
|
= table_link_to 'power-off', t('admin.relays.disable'), disable_admin_relay_path(relay), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
|
||||||
|
- else
|
||||||
|
= table_link_to 'power-off', t('admin.relays.enable'), enable_admin_relay_path(relay), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
|
||||||
|
|
||||||
|
= table_link_to 'times', t('admin.relays.delete'), admin_relay_path(relay), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
|
20
app/views/admin/relays/index.html.haml
Normal file
20
app/views/admin/relays/index.html.haml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
- content_for :page_title do
|
||||||
|
= t('admin.relays.title')
|
||||||
|
|
||||||
|
.simple_form
|
||||||
|
%p.hint= t('admin.relays.description_html')
|
||||||
|
= link_to @relays.empty? ? t('admin.relays.setup') : t('admin.relays.add_new'), new_admin_relay_path, class: 'block-button'
|
||||||
|
|
||||||
|
- unless @relays.empty?
|
||||||
|
%hr.spacer
|
||||||
|
|
||||||
|
.table-wrapper
|
||||||
|
%table.table
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th= t('admin.relays.inbox_url')
|
||||||
|
%th= t('admin.relays.status')
|
||||||
|
%th
|
||||||
|
%tbody
|
||||||
|
= render @relays
|
||||||
|
|
13
app/views/admin/relays/new.html.haml
Normal file
13
app/views/admin/relays/new.html.haml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
- content_for :page_title do
|
||||||
|
= t('admin.relays.add_new')
|
||||||
|
|
||||||
|
= simple_form_for @relay, url: admin_relays_path do |f|
|
||||||
|
= render 'shared/error_messages', object: @relay
|
||||||
|
|
||||||
|
.field-group
|
||||||
|
= f.input :inbox_url, as: :string, wrapper: :with_block_label
|
||||||
|
|
||||||
|
.actions
|
||||||
|
= f.button :button, t('admin.relays.save_and_enable'), type: :submit
|
||||||
|
|
||||||
|
%p.hint.subtle-hint= t('admin.relays.enable_hint')
|
|
@ -14,6 +14,8 @@ class ActivityPub::DistributionWorker
|
||||||
ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
|
ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
|
||||||
[signed_payload, @account.id, inbox_url]
|
[signed_payload, @account.id, inbox_url]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
relay! if relayable?
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
@ -24,6 +26,10 @@ class ActivityPub::DistributionWorker
|
||||||
@status.direct_visibility?
|
@status.direct_visibility?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def relayable?
|
||||||
|
@status.public_visibility?
|
||||||
|
end
|
||||||
|
|
||||||
def inboxes
|
def inboxes
|
||||||
@inboxes ||= @account.followers.inboxes
|
@inboxes ||= @account.followers.inboxes
|
||||||
end
|
end
|
||||||
|
@ -39,4 +45,10 @@ class ActivityPub::DistributionWorker
|
||||||
adapter: ActivityPub::Adapter
|
adapter: ActivityPub::Adapter
|
||||||
).as_json
|
).as_json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def relay!
|
||||||
|
ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
|
||||||
|
[signed_payload, @account.id, inbox_url]
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,11 @@ class ActivityPub::UpdateDistributionWorker
|
||||||
@account = Account.find(account_id)
|
@account = Account.find(account_id)
|
||||||
|
|
||||||
ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
|
ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
|
||||||
[payload, @account.id, inbox_url]
|
[signed_payload, @account.id, inbox_url]
|
||||||
|
end
|
||||||
|
|
||||||
|
ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
|
||||||
|
[signed_payload, @account.id, inbox_url]
|
||||||
end
|
end
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
true
|
true
|
||||||
|
@ -21,6 +25,10 @@ class ActivityPub::UpdateDistributionWorker
|
||||||
@inboxes ||= @account.followers.inboxes
|
@inboxes ||= @account.followers.inboxes
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def signed_payload
|
||||||
|
@signed_payload ||= Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account))
|
||||||
|
end
|
||||||
|
|
||||||
def payload
|
def payload
|
||||||
@payload ||= ActiveModelSerializers::SerializableResource.new(
|
@payload ||= ActiveModelSerializers::SerializableResource.new(
|
||||||
@account,
|
@account,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
cs:
|
cs:
|
||||||
about:
|
about:
|
||||||
about_hashtag_html: Toto jsou veřejné příspěvky typu označené jako <strong>#%{hashtag}</strong>. Pokud máte účet kdekoliv na fediverse, můžete s nimi interagovat.
|
about_hashtag_html: Toto jsou veřejné tooty označené jako <strong>#%{hashtag}</strong>. Pokud máte účet kdekoliv na fediverse, můžete s nimi interagovat.
|
||||||
about_mastodon_html: Mastodon je sociální síť založená na otevřených webových protokolech a svobodném, otevřeném softwaru. Je decentrovalizovaná jako e-mail.
|
about_mastodon_html: Mastodon je sociální síť založená na otevřených webových protokolech a svobodném, otevřeném softwaru. Je decentrovalizovaná jako e-mail.
|
||||||
about_this: O této instanci
|
about_this: O této instanci
|
||||||
administered_by: 'Server spravuje:'
|
administered_by: 'Server spravuje:'
|
||||||
|
@ -18,7 +18,7 @@ cs:
|
||||||
features:
|
features:
|
||||||
humane_approach_body: Mastodon, poučen z chyb jiných sociálních sítí, se snaží bojovat se zneužíváním sociálních sítí vytvářením etických možností.
|
humane_approach_body: Mastodon, poučen z chyb jiných sociálních sítí, se snaží bojovat se zneužíváním sociálních sítí vytvářením etických možností.
|
||||||
humane_approach_title: Lidštější přístup
|
humane_approach_title: Lidštější přístup
|
||||||
not_a_product_title: Jste osoba, ne produkt.
|
not_a_product_title: Jste osoba, ne produkt
|
||||||
generic_description: "%{domain} je jedním serverem v síti"
|
generic_description: "%{domain} je jedním serverem v síti"
|
||||||
learn_more: Zjistit více
|
learn_more: Zjistit více
|
||||||
source_code: Zdrojový kód
|
source_code: Zdrojový kód
|
||||||
|
|
|
@ -10,7 +10,7 @@ da:
|
||||||
contact_missing: Ikke sat
|
contact_missing: Ikke sat
|
||||||
contact_unavailable: Ikke tilgængeligt
|
contact_unavailable: Ikke tilgængeligt
|
||||||
description_headline: Hvad er %{domain}?
|
description_headline: Hvad er %{domain}?
|
||||||
domain_count_after: andre instancer
|
domain_count_after: andre instanser
|
||||||
domain_count_before: Forbundet til
|
domain_count_before: Forbundet til
|
||||||
extended_description_html: |
|
extended_description_html: |
|
||||||
<h3>Et godt sted for regler</h3>
|
<h3>Et godt sted for regler</h3>
|
||||||
|
@ -27,7 +27,7 @@ da:
|
||||||
generic_description: "%{domain} er en server i netværket"
|
generic_description: "%{domain} er en server i netværket"
|
||||||
hosted_on: Mostodon hostet på %{domain}
|
hosted_on: Mostodon hostet på %{domain}
|
||||||
learn_more: Lær mere
|
learn_more: Lær mere
|
||||||
other_instances: Liste over instancer
|
other_instances: Liste over instanser
|
||||||
source_code: Kildekode
|
source_code: Kildekode
|
||||||
status_count_after: statusser
|
status_count_after: statusser
|
||||||
status_count_before: Som har skrevet
|
status_count_before: Som har skrevet
|
||||||
|
@ -46,7 +46,7 @@ da:
|
||||||
people_who_follow: Folk der følger %{name}
|
people_who_follow: Folk der følger %{name}
|
||||||
posts: Dyt
|
posts: Dyt
|
||||||
posts_with_replies: Toots og svar
|
posts_with_replies: Toots og svar
|
||||||
remote_follow: Følg fra andre instancer
|
remote_follow: Følg fra andre instanser
|
||||||
reserved_username: Brugernavnet er reserveret
|
reserved_username: Brugernavnet er reserveret
|
||||||
roles:
|
roles:
|
||||||
admin: Administrator
|
admin: Administrator
|
||||||
|
@ -256,6 +256,10 @@ da:
|
||||||
expired: Udløbet
|
expired: Udløbet
|
||||||
title: Filtre
|
title: Filtre
|
||||||
title: Invitationer
|
title: Invitationer
|
||||||
|
relays:
|
||||||
|
setup: Opsæt en videresendelses forbindelse
|
||||||
|
status: Status
|
||||||
|
title: Videresendelser
|
||||||
reports:
|
reports:
|
||||||
account:
|
account:
|
||||||
note: notat
|
note: notat
|
||||||
|
@ -297,7 +301,11 @@ da:
|
||||||
username: Kontakt brugernavn
|
username: Kontakt brugernavn
|
||||||
hero:
|
hero:
|
||||||
title: Billede af helt
|
title: Billede af helt
|
||||||
|
peers_api_enabled:
|
||||||
|
title: Udgiv liste over opdagede instanser
|
||||||
registrations:
|
registrations:
|
||||||
|
closed_message:
|
||||||
|
title: Besked for lukkede registreringer
|
||||||
deletion:
|
deletion:
|
||||||
desc_html: Tillad alle at slette deres konto
|
desc_html: Tillad alle at slette deres konto
|
||||||
title: Åben konto sletning
|
title: Åben konto sletning
|
||||||
|
@ -338,6 +346,7 @@ da:
|
||||||
new_report:
|
new_report:
|
||||||
body: "%{reporter} har anmeldt %{target}"
|
body: "%{reporter} har anmeldt %{target}"
|
||||||
body_remote: Nogen fra %{domain} har anmeldt %{target}
|
body_remote: Nogen fra %{domain} har anmeldt %{target}
|
||||||
|
subject: Ny anmeldelse for %{instance} (#%{id})
|
||||||
application_mailer:
|
application_mailer:
|
||||||
notification_preferences: Ændre email indstillinger
|
notification_preferences: Ændre email indstillinger
|
||||||
salutation: "%{name},"
|
salutation: "%{name},"
|
||||||
|
@ -359,6 +368,9 @@ da:
|
||||||
migrate_account: Flyt til en anden konto
|
migrate_account: Flyt til en anden konto
|
||||||
or: eller
|
or: eller
|
||||||
or_log_in_with: Eller log in med
|
or_log_in_with: Eller log in med
|
||||||
|
providers:
|
||||||
|
cas: CAS
|
||||||
|
saml: SAML
|
||||||
register: Opret dig
|
register: Opret dig
|
||||||
register_elsewhere: Opret dig på en anden server
|
register_elsewhere: Opret dig på en anden server
|
||||||
reset_password: Nulstil kodeord
|
reset_password: Nulstil kodeord
|
||||||
|
@ -378,8 +390,15 @@ da:
|
||||||
distance_in_words:
|
distance_in_words:
|
||||||
about_x_hours: "%{count}t"
|
about_x_hours: "%{count}t"
|
||||||
about_x_months: "%{count} måneder"
|
about_x_months: "%{count} måneder"
|
||||||
|
about_x_years: "%{count}år"
|
||||||
|
almost_x_years: "%{count}år"
|
||||||
half_a_minute: Lige nu
|
half_a_minute: Lige nu
|
||||||
|
less_than_x_minutes: "%{count}m"
|
||||||
less_than_x_seconds: Lige nu
|
less_than_x_seconds: Lige nu
|
||||||
|
over_x_years: "%{count}år"
|
||||||
|
x_days: "%{count}d"
|
||||||
|
x_minutes: "%{count}m"
|
||||||
|
x_months: "%{count}md"
|
||||||
x_seconds: "%{count}s"
|
x_seconds: "%{count}s"
|
||||||
deletes:
|
deletes:
|
||||||
bad_password_msg: Godt forsøg, hackere! Forkert kodeord
|
bad_password_msg: Godt forsøg, hackere! Forkert kodeord
|
||||||
|
@ -401,6 +420,7 @@ da:
|
||||||
download: Hent dit arkiv
|
download: Hent dit arkiv
|
||||||
size: Størrelse
|
size: Størrelse
|
||||||
blocks: Du blokerer
|
blocks: Du blokerer
|
||||||
|
csv: CSV
|
||||||
follows: Du følger
|
follows: Du følger
|
||||||
mutes: Du dæmper
|
mutes: Du dæmper
|
||||||
filters:
|
filters:
|
||||||
|
@ -445,9 +465,13 @@ da:
|
||||||
expires_in_prompt: Aldrig
|
expires_in_prompt: Aldrig
|
||||||
generate: Generer
|
generate: Generer
|
||||||
invited_by: 'Du er blevet inviteret af:'
|
invited_by: 'Du er blevet inviteret af:'
|
||||||
|
max_uses:
|
||||||
|
one: 1 benyttelse
|
||||||
|
other: "%{count} benyttelser"
|
||||||
max_uses_prompt: Ubegrænset
|
max_uses_prompt: Ubegrænset
|
||||||
table:
|
table:
|
||||||
expires_at: Udløber
|
expires_at: Udløber
|
||||||
|
uses: Benyttelser
|
||||||
title: Inviter folk
|
title: Inviter folk
|
||||||
media_attachments:
|
media_attachments:
|
||||||
validations:
|
validations:
|
||||||
|
|
|
@ -133,7 +133,7 @@ ja:
|
||||||
write:blocks: ユーザーのブロックやドメインの非表示
|
write:blocks: ユーザーのブロックやドメインの非表示
|
||||||
write:favourites: トゥートのお気に入り登録
|
write:favourites: トゥートのお気に入り登録
|
||||||
write:filters: フィルターの変更
|
write:filters: フィルターの変更
|
||||||
write:follows: フォローの変更
|
write:follows: あなたの代わりにフォロー、アンフォロー
|
||||||
write:lists: リストの変更
|
write:lists: リストの変更
|
||||||
write:media: メディアのアップロード
|
write:media: メディアのアップロード
|
||||||
write:mutes: アカウントや会話のミュート
|
write:mutes: アカウントや会話のミュート
|
||||||
|
|
|
@ -114,7 +114,29 @@ pt-BR:
|
||||||
application:
|
application:
|
||||||
title: Autorização OAuth obrigatória
|
title: Autorização OAuth obrigatória
|
||||||
scopes:
|
scopes:
|
||||||
follow: seguir, bloquear, desbloquear e deixar de seguir outras contas
|
follow: modificar as relações com outras contas
|
||||||
push: receber notificações push na sua conta
|
push: receber suas notificações push
|
||||||
read: ler os dados da sua conta
|
read: ler todos os dados da sua conta
|
||||||
write: postar em seu nome
|
read:accounts: ver as informações da conta
|
||||||
|
read:blocks: ver seus bloqueios
|
||||||
|
read:favourites: ver seus favoritos
|
||||||
|
read:filters: ver seus filtros
|
||||||
|
read:follows: ver quem você segue
|
||||||
|
read:lists: ver suas listas
|
||||||
|
read:mutes: ver seus usuários silenciados
|
||||||
|
read:notifications: ver suas notificações
|
||||||
|
read:reports: ver suas denúncias
|
||||||
|
read:search: buscar em seu nome
|
||||||
|
read:statuses: ver todos os status
|
||||||
|
write: modificar todos os dados da sua conta
|
||||||
|
write:accounts: modificar seu perfil
|
||||||
|
write:blocks: bloquear contas e domínios
|
||||||
|
write:favourites: status favoritos
|
||||||
|
write:filters: criar filtros
|
||||||
|
write:follows: seguir pessoas
|
||||||
|
write:lists: criar listas
|
||||||
|
write:media: enviar arquivos de mídia
|
||||||
|
write:mutes: silenciar pessoas e conversas
|
||||||
|
write:notifications: limpar suas notificações
|
||||||
|
write:reports: reportar outras pessoas
|
||||||
|
write:statuses: publicar status
|
||||||
|
|
|
@ -261,6 +261,14 @@ el:
|
||||||
expired: Ληγμένες
|
expired: Ληγμένες
|
||||||
title: Φίλτρο
|
title: Φίλτρο
|
||||||
title: Προσκλήσεις
|
title: Προσκλήσεις
|
||||||
|
relays:
|
||||||
|
add_new: Πρόσθεσε νέο ανταποκριτή (relay)
|
||||||
|
description_html: Ο <strong>ομοσπονδιακός ανταποκριτής</strong> είναι ένας ενδιάμεσος εξυπηρετητής (server) που ανταλλάσσει μεγάλους όγκους δημόσιων τουτ μεταξύ εξυπηρετητών που εγγράφονται και δημοσιεύουν σε αυτόν. <strong>Βοηθάει μικρούς και μεσαίους εξυπηρετητές να ανακαλύψουν περιεχόμενο στο fediverse</strong>, που υπό άλλες συνθήκες θα χρειαζόταν κάποιους τοπικούς χρήστες που να ακολουθούν χρήστες σε απομακρυσμένους εξυπηρετητές.
|
||||||
|
enable_hint: Μόλις ενεργοποιηθεί, ο εξυπηρετητής (server) σου θα εγγραφεί σε όλα τα δημόσια τουτ αυτού του ανταποκριτή (relay) και θα αρχίσει να προωθεί τα δικά του δημόσια τουτ σε αυτόν.
|
||||||
|
inbox_url: URL ανταποκριτή
|
||||||
|
setup: Όρισε μια σύνδεση ανταπόκρισης
|
||||||
|
status: Κατάσταση
|
||||||
|
title: Ανταποκριτές
|
||||||
report_notes:
|
report_notes:
|
||||||
created_msg: Επιτυχής δημιουργία σημείωσης καταγγελίας!
|
created_msg: Επιτυχής δημιουργία σημείωσης καταγγελίας!
|
||||||
destroyed_msg: Επιτυχής διαγραφή σημείωσης καταγγελίας!
|
destroyed_msg: Επιτυχής διαγραφή σημείωσης καταγγελίας!
|
||||||
|
@ -316,6 +324,9 @@ el:
|
||||||
peers_api_enabled:
|
peers_api_enabled:
|
||||||
desc_html: Ονόματα τομέων που αυτός ο κόμβος έχει ήδη συναντήσει στο fediverse
|
desc_html: Ονόματα τομέων που αυτός ο κόμβος έχει ήδη συναντήσει στο fediverse
|
||||||
title: Δημοσίευση λίστας κόμβων που έχουν ανακαλυφθεί
|
title: Δημοσίευση λίστας κόμβων που έχουν ανακαλυφθεί
|
||||||
|
preview_sensitive_media:
|
||||||
|
desc_html: Οι προεπισκοπήσεις συνδέσμων σε τρίτους ιστότοπους θα είναι ορατές ακόμα κι όταν το πολυμέσο έχει σημειωθεί ως ευαίσθητο
|
||||||
|
title: Εμφάνιση ευαίσθητων πολυμέσων στις προεπισκοπήσεις OpenGraph
|
||||||
registrations:
|
registrations:
|
||||||
closed_message:
|
closed_message:
|
||||||
desc_html: Εμφανίζεται στην εισαγωγική σελίδα όταν οι εγγραφές είναι κλειστές. Μπορείς να χρησιμοποιήσεις HTML tags
|
desc_html: Εμφανίζεται στην εισαγωγική σελίδα όταν οι εγγραφές είναι κλειστές. Μπορείς να χρησιμοποιήσεις HTML tags
|
||||||
|
|
|
@ -261,6 +261,14 @@ en:
|
||||||
expired: Expired
|
expired: Expired
|
||||||
title: Filter
|
title: Filter
|
||||||
title: Invites
|
title: Invites
|
||||||
|
relays:
|
||||||
|
add_new: Add new relay
|
||||||
|
description_html: A <strong>federation relay</strong> is an intermediary server that exchanges large volumes of public toots between servers that subscribe and publish to it. <strong>It can help small and medium servers discover content from the fediverse</strong>, which would otherwise require local users manually following other people on remote servers.
|
||||||
|
enable_hint: Once enabled, your server will subscribe to all public toots from this relay, and will begin sending this server's public toots to it.
|
||||||
|
inbox_url: Relay URL
|
||||||
|
setup: Setup a relay connection
|
||||||
|
status: Status
|
||||||
|
title: Relays
|
||||||
report_notes:
|
report_notes:
|
||||||
created_msg: Report note successfully created!
|
created_msg: Report note successfully created!
|
||||||
destroyed_msg: Report note successfully deleted!
|
destroyed_msg: Report note successfully deleted!
|
||||||
|
|
|
@ -261,6 +261,14 @@ gl:
|
||||||
expired: Cadudado
|
expired: Cadudado
|
||||||
title: Filtro
|
title: Filtro
|
||||||
title: Convida
|
title: Convida
|
||||||
|
relays:
|
||||||
|
add_new: Engadir un novo repetidor
|
||||||
|
description_html: Un <strong>repetidor da federación</strong> é un servidor intermedio que intercambia grandes volumes de toots públicos entre servidores que se suscriban e publiquen nel. <strong>Pode axudar a servidores pequenos e medios a descubrir contido no fediverso</strong>, o que de outro xeito precisaría que as usuarias locais seguisen a outra xente en servidores remotos.
|
||||||
|
enable_hint: Unha vez activado, o seu servidor suscribirase a todos os toots públicos de este servidor, e tamén comezará a eviar a el os toots públicos do servidor.
|
||||||
|
inbox_url: URL do repetidor
|
||||||
|
setup: Configurar a conexión ao repetidor
|
||||||
|
status: Estado
|
||||||
|
title: Repetidores
|
||||||
report_notes:
|
report_notes:
|
||||||
created_msg: Creouse correctamente a nota do informe!
|
created_msg: Creouse correctamente a nota do informe!
|
||||||
destroyed_msg: Nota do informe eliminouse con éxito!
|
destroyed_msg: Nota do informe eliminouse con éxito!
|
||||||
|
|
|
@ -261,6 +261,11 @@ ja:
|
||||||
expired: 期限切れ
|
expired: 期限切れ
|
||||||
title: フィルター
|
title: フィルター
|
||||||
title: 招待
|
title: 招待
|
||||||
|
relays:
|
||||||
|
add_new: リレーを追加
|
||||||
|
inbox_url: Relay URL
|
||||||
|
status: ステータス
|
||||||
|
title: リレー
|
||||||
report_notes:
|
report_notes:
|
||||||
created_msg: レポートメモを書き込みました!
|
created_msg: レポートメモを書き込みました!
|
||||||
destroyed_msg: レポートメモを削除しました!
|
destroyed_msg: レポートメモを削除しました!
|
||||||
|
@ -706,7 +711,7 @@ ja:
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
one: '許可されていないハッシュタグが含まれています: %{tags}'
|
one: '許可されていないハッシュタグが含まれています: %{tags}'
|
||||||
other: '許可されていないハッシュタグが含まれています: %{tags}'
|
other: '許可されていないハッシュタグが含まれています: %{tags}'
|
||||||
language_detection: 自動的に言語を検出する
|
language_detection: 自動検出
|
||||||
open_in_web: Webで開く
|
open_in_web: Webで開く
|
||||||
over_character_limit: 上限は %{max}文字までです
|
over_character_limit: 上限は %{max}文字までです
|
||||||
pin_errors:
|
pin_errors:
|
||||||
|
|
|
@ -261,6 +261,14 @@ nl:
|
||||||
expired: Verlopen
|
expired: Verlopen
|
||||||
title: Filter
|
title: Filter
|
||||||
title: Uitnodigingen
|
title: Uitnodigingen
|
||||||
|
relays:
|
||||||
|
add_new: Nieuwe relayserver toevoegen
|
||||||
|
description_html: Een <strong>federatie-relay</strong> is een tussenliggende server die grote hoeveelheden openbare toots uitwisselt tussen servers die zich hierop hebben geabonneerd. <strong>Het kan kleine en middelgrote servers helpen om content uit de fediverse te ontdekken</strong>, waarvoor anders lokale gebruikers handmatig mensen van externe servers moeten volgen.
|
||||||
|
enable_hint: Eenmaal ingeschakeld gaat jouw server zich op alle openbare toots van deze relayserver abonneren en stuurt het de openbare toots van jouw server naar de relayserver.
|
||||||
|
inbox_url: Relay-URL
|
||||||
|
setup: Een verbinding met een relayserver maken
|
||||||
|
status: Status
|
||||||
|
title: Relayservers
|
||||||
report_notes:
|
report_notes:
|
||||||
created_msg: Opmerking bij gerapporteerde toot succesvol aangemaakt!
|
created_msg: Opmerking bij gerapporteerde toot succesvol aangemaakt!
|
||||||
destroyed_msg: Opmerking bij gerapporteerde toot succesvol verwijderd!
|
destroyed_msg: Opmerking bij gerapporteerde toot succesvol verwijderd!
|
||||||
|
@ -492,7 +500,7 @@ nl:
|
||||||
delete: Verwijderen
|
delete: Verwijderen
|
||||||
title: Filters
|
title: Filters
|
||||||
new:
|
new:
|
||||||
title: Nieuwe filter toevoegen
|
title: Nieuw filter toevoegen
|
||||||
followers:
|
followers:
|
||||||
domain: Domein
|
domain: Domein
|
||||||
explanation_html: Wanneer je de privacy van jouw toots wilt garanderen, moet je goed weten wie jouw volgers zijn. <strong>Toots die alleen aan jouw volgers zijn gericht, worden aan de Mastodonservers van jouw volgers afgeleverd.</strong> Daarom wil je ze misschien controleren en desnoods volgers verwijderen die zich op een Mastodonserver bevinden die jij niet vertrouwd. Bijvoorbeeld omdat de beheerder(s) of de software van zo'n server jouw privacy niet respecteert.
|
explanation_html: Wanneer je de privacy van jouw toots wilt garanderen, moet je goed weten wie jouw volgers zijn. <strong>Toots die alleen aan jouw volgers zijn gericht, worden aan de Mastodonservers van jouw volgers afgeleverd.</strong> Daarom wil je ze misschien controleren en desnoods volgers verwijderen die zich op een Mastodonserver bevinden die jij niet vertrouwd. Bijvoorbeeld omdat de beheerder(s) of de software van zo'n server jouw privacy niet respecteert.
|
||||||
|
|
|
@ -25,6 +25,7 @@ da:
|
||||||
setting_hide_network: Hvem du følger og hvem der følger dig vil ikke blive vist på din profil
|
setting_hide_network: Hvem du følger og hvem der følger dig vil ikke blive vist på din profil
|
||||||
setting_noindex: Påvirker din offentlige profil og status sider
|
setting_noindex: Påvirker din offentlige profil og status sider
|
||||||
setting_theme: Påvirker hvordan Mastodon ser ud nåt du er logget ind via en hvilken som helst enhed.
|
setting_theme: Påvirker hvordan Mastodon ser ud nåt du er logget ind via en hvilken som helst enhed.
|
||||||
|
whole_word: Når nøgle ordet eller udtrykket kun er alfabetisk, vil det kun blive brugt hvis det passer hele ordet
|
||||||
imports:
|
imports:
|
||||||
data: CSV fil eksporteret fra en anden Mastodon instans
|
data: CSV fil eksporteret fra en anden Mastodon instans
|
||||||
sessions:
|
sessions:
|
||||||
|
@ -77,6 +78,7 @@ da:
|
||||||
type: Importtype
|
type: Importtype
|
||||||
username: Brugernavn
|
username: Brugernavn
|
||||||
username_or_email: Brugernavn eller Email
|
username_or_email: Brugernavn eller Email
|
||||||
|
whole_word: Helt ord
|
||||||
interactions:
|
interactions:
|
||||||
must_be_follower: Bloker notifikationer fra folk der ikke følger dig
|
must_be_follower: Bloker notifikationer fra folk der ikke følger dig
|
||||||
must_be_following: Bloker notifikationer fra folk du ikke følger
|
must_be_following: Bloker notifikationer fra folk du ikke følger
|
||||||
|
|
|
@ -48,7 +48,7 @@ de:
|
||||||
data: Daten
|
data: Daten
|
||||||
display_name: Anzeigename
|
display_name: Anzeigename
|
||||||
email: E-Mail-Adresse
|
email: E-Mail-Adresse
|
||||||
expires_in: Gültig bis
|
expires_in: Läuft ab
|
||||||
fields: Profil-Metadaten
|
fields: Profil-Metadaten
|
||||||
header: Kopfbild
|
header: Kopfbild
|
||||||
irreversible: Fallen lassen anstatt es zu verstecken
|
irreversible: Fallen lassen anstatt es zu verstecken
|
||||||
|
|
|
@ -13,6 +13,7 @@ el:
|
||||||
other: απομένουν <span class="name-counter">%{count}</span> χαρακτήρες
|
other: απομένουν <span class="name-counter">%{count}</span> χαρακτήρες
|
||||||
fields: Μπορείς να έχεις έως 4 σημειώσεις σε μορφή πίνακα στο προφίλ σου
|
fields: Μπορείς να έχεις έως 4 σημειώσεις σε μορφή πίνακα στο προφίλ σου
|
||||||
header: PNG, GIF ή JPG. Έως 2MB. Θα μειωθεί σε διάσταση 700x335px
|
header: PNG, GIF ή JPG. Έως 2MB. Θα μειωθεί σε διάσταση 700x335px
|
||||||
|
inbox_url: Αντέγραψε το URL της αρχικής σελίδας του ανταποκριτή (relay) που θέλεις να χρησιμοποιήσεις
|
||||||
irreversible: Τα φιλτραρισμένα τουτ θα εξαφανιστούν αμετάκλητα, ακόμα και αν το φίλτρο αργότερα αφαιρεθεί
|
irreversible: Τα φιλτραρισμένα τουτ θα εξαφανιστούν αμετάκλητα, ακόμα και αν το φίλτρο αργότερα αφαιρεθεί
|
||||||
locale: Η γλώσσα του περιβάλλοντος χρήσης, των email και των ειδοποιήσεων ώθησης
|
locale: Η γλώσσα του περιβάλλοντος χρήσης, των email και των ειδοποιήσεων ώθησης
|
||||||
locked: Απαιτεί να εγκρίνεις χειροκίνητα τους ακόλουθούς σου
|
locked: Απαιτεί να εγκρίνεις χειροκίνητα τους ακόλουθούς σου
|
||||||
|
@ -25,6 +26,7 @@ el:
|
||||||
setting_hide_network: Το ποιους ακολουθείς και το ποιοι σε ακολουθούν δε θα φαίνεται στο προφίλ σου
|
setting_hide_network: Το ποιους ακολουθείς και το ποιοι σε ακολουθούν δε θα φαίνεται στο προφίλ σου
|
||||||
setting_noindex: Επηρεάζει το δημόσιο προφίλ και τις δημοσιεύσεις σου
|
setting_noindex: Επηρεάζει το δημόσιο προφίλ και τις δημοσιεύσεις σου
|
||||||
setting_theme: Επηρεάζει την εμφάνιση του Mastodon όταν συνδέεται από οποιαδήποτε συσκευή.
|
setting_theme: Επηρεάζει την εμφάνιση του Mastodon όταν συνδέεται από οποιαδήποτε συσκευή.
|
||||||
|
whole_word: Όταν η λέξη ή η φράση κλειδί είναι μόνο αλφαριθμητική, θα εφαρμοστεί μόνο αν ταιριάζει με ολόκληρη τη λέξη
|
||||||
imports:
|
imports:
|
||||||
data: Αρχείο CSV που έχει εξαχθεί από διαφορετικό κόμβο Mastodon
|
data: Αρχείο CSV που έχει εξαχθεί από διαφορετικό κόμβο Mastodon
|
||||||
sessions:
|
sessions:
|
||||||
|
@ -51,6 +53,7 @@ el:
|
||||||
expires_in: Λήξη μετά από
|
expires_in: Λήξη μετά από
|
||||||
fields: Μετεδεδομένα προφίλ
|
fields: Μετεδεδομένα προφίλ
|
||||||
header: Επικεφαλίδα
|
header: Επικεφαλίδα
|
||||||
|
inbox_url: Το URL του inbox του ανταποκριτή (relay)
|
||||||
irreversible: Απόρριψη αντί για κρύψιμο
|
irreversible: Απόρριψη αντί για κρύψιμο
|
||||||
locale: Γλώσσα περιβάλλοντος
|
locale: Γλώσσα περιβάλλοντος
|
||||||
locked: Κλείδωμα λογαριασμού
|
locked: Κλείδωμα λογαριασμού
|
||||||
|
@ -77,6 +80,7 @@ el:
|
||||||
type: Τύπος εισαγωγής
|
type: Τύπος εισαγωγής
|
||||||
username: Όνομα χρηστη
|
username: Όνομα χρηστη
|
||||||
username_or_email: Όνομα ή διεύθυνση email χρήστη
|
username_or_email: Όνομα ή διεύθυνση email χρήστη
|
||||||
|
whole_word: Ολόκληρη λέξη
|
||||||
interactions:
|
interactions:
|
||||||
must_be_follower: Μπλόκαρε τις ειδοποιήσεις από όσους δεν ακολουθείς
|
must_be_follower: Μπλόκαρε τις ειδοποιήσεις από όσους δεν ακολουθείς
|
||||||
must_be_following: Μπλόκαρε τις ειδοποιήσεις που προέρχονται από άτομα που δεν τα ακολουθείς
|
must_be_following: Μπλόκαρε τις ειδοποιήσεις που προέρχονται από άτομα που δεν τα ακολουθείς
|
||||||
|
|
|
@ -13,6 +13,7 @@ en:
|
||||||
other: <span class="name-counter">%{count}</span> characters left
|
other: <span class="name-counter">%{count}</span> characters left
|
||||||
fields: You can have up to 4 items displayed as a table on your profile
|
fields: You can have up to 4 items displayed as a table on your profile
|
||||||
header: PNG, GIF or JPG. At most 2MB. Will be downscaled to 700x335px
|
header: PNG, GIF or JPG. At most 2MB. Will be downscaled to 700x335px
|
||||||
|
inbox_url: Copy the URL from the frontpage of the relay you want to use
|
||||||
irreversible: Filtered toots will disappear irreversibly, even if filter is later removed
|
irreversible: Filtered toots will disappear irreversibly, even if filter is later removed
|
||||||
locale: The language of the user interface, e-mails and push notifications
|
locale: The language of the user interface, e-mails and push notifications
|
||||||
locked: Requires you to manually approve followers
|
locked: Requires you to manually approve followers
|
||||||
|
@ -52,6 +53,7 @@ en:
|
||||||
expires_in: Expire after
|
expires_in: Expire after
|
||||||
fields: Profile metadata
|
fields: Profile metadata
|
||||||
header: Header
|
header: Header
|
||||||
|
inbox_url: URL of the relay inbox
|
||||||
irreversible: Drop instead of hide
|
irreversible: Drop instead of hide
|
||||||
locale: Interface language
|
locale: Interface language
|
||||||
locked: Lock account
|
locked: Lock account
|
||||||
|
|
|
@ -13,6 +13,7 @@ fa:
|
||||||
other: <span class="name-counter">%{count}</span> حرف باقی مانده
|
other: <span class="name-counter">%{count}</span> حرف باقی مانده
|
||||||
fields: شما میتوانید تا چهار مورد را در یک جدول در نمایهٔ خود نمایش دهید
|
fields: شما میتوانید تا چهار مورد را در یک جدول در نمایهٔ خود نمایش دهید
|
||||||
header: یکی از قالبهای PNG یا GIF یا JPG. بیشترین اندازه ۲ مگابایت. تصویر به اندازهٔ ۳۳۵×۷۰۰ پیکسل تبدیل خواهد شد
|
header: یکی از قالبهای PNG یا GIF یا JPG. بیشترین اندازه ۲ مگابایت. تصویر به اندازهٔ ۳۳۵×۷۰۰ پیکسل تبدیل خواهد شد
|
||||||
|
inbox_url: نشانی صفحهٔ اصلی رلهای را که میخواهید به کار ببرید کپی کنید
|
||||||
irreversible: بوقهای فیلترشده به طور برگشتناپذیری ناپدید میشوند، حتی اگر فیلتر را بعداً بردارید
|
irreversible: بوقهای فیلترشده به طور برگشتناپذیری ناپدید میشوند، حتی اگر فیلتر را بعداً بردارید
|
||||||
locale: زبان محیط کاربری، ایمیلها، و اعلانها
|
locale: زبان محیط کاربری، ایمیلها، و اعلانها
|
||||||
locked: باید پیگیران تازه را خودتان تأیید کنید
|
locked: باید پیگیران تازه را خودتان تأیید کنید
|
||||||
|
@ -20,10 +21,12 @@ fa:
|
||||||
one: <span class="note-counter">1</span> حرف باقی مانده
|
one: <span class="note-counter">1</span> حرف باقی مانده
|
||||||
other: <span class="note-counter">%{count}</span> حرف باقی مانده
|
other: <span class="note-counter">%{count}</span> حرف باقی مانده
|
||||||
phrase: مستقل از کوچکی و بزرگی حروف، با متن اصلی یا هشدار محتوای بوقها مقایسه میشود
|
phrase: مستقل از کوچکی و بزرگی حروف، با متن اصلی یا هشدار محتوای بوقها مقایسه میشود
|
||||||
|
scopes: واسطهای برنامهنویسی که این برنامه به آن دسترسی دارد. اگر بالاترین سطح دسترسی را انتخاب کنید، دیگر نیازی به انتخاب سطحهای پایینی ندارید.
|
||||||
setting_default_language: زبان نوشتههای شما به طور خودکار تشخیص داده میشود، ولی این تشخصی همیشه دقیق نیست
|
setting_default_language: زبان نوشتههای شما به طور خودکار تشخیص داده میشود، ولی این تشخصی همیشه دقیق نیست
|
||||||
setting_hide_network: فهرست پیگیران شما و فهرست کسانی که شما پی میگیرید روی نمایهٔ شما دیده نخواهد شد
|
setting_hide_network: فهرست پیگیران شما و فهرست کسانی که شما پی میگیرید روی نمایهٔ شما دیده نخواهد شد
|
||||||
setting_noindex: روی نمایهٔ عمومی و صفحهٔ نوشتههای شما تأثیر میگذارد
|
setting_noindex: روی نمایهٔ عمومی و صفحهٔ نوشتههای شما تأثیر میگذارد
|
||||||
setting_theme: ظاهر ماستدون را وقتی که از هر دستگاهی به آن وارد میشوید تعیین میکند.
|
setting_theme: ظاهر ماستدون را وقتی که از هر دستگاهی به آن وارد میشوید تعیین میکند.
|
||||||
|
whole_word: اگر کلیدواژه فقط دارای حروف و اعداد باشد، تنها وقتی پیدا میشود که با کل یک واژه در متن منطبق باشد، نه با بخشی از یک واژه
|
||||||
imports:
|
imports:
|
||||||
data: پروندهٔ CSV که از سرور ماستدون دیگری برونسپاری شده
|
data: پروندهٔ CSV که از سرور ماستدون دیگری برونسپاری شده
|
||||||
sessions:
|
sessions:
|
||||||
|
@ -50,6 +53,7 @@ fa:
|
||||||
expires_in: تاریخ انقضا
|
expires_in: تاریخ انقضا
|
||||||
fields: اطلاعات تکمیلی نمایه
|
fields: اطلاعات تکمیلی نمایه
|
||||||
header: تصویر زمینه
|
header: تصویر زمینه
|
||||||
|
inbox_url: نشانی صندوق ورودی رله
|
||||||
irreversible: به جای پنهانسازی، حذف کن
|
irreversible: به جای پنهانسازی، حذف کن
|
||||||
locale: زبان محیط کاربری
|
locale: زبان محیط کاربری
|
||||||
locked: خصوصیکردن حساب
|
locked: خصوصیکردن حساب
|
||||||
|
@ -76,6 +80,7 @@ fa:
|
||||||
type: نوع درونریزی
|
type: نوع درونریزی
|
||||||
username: نام کاربری (تنها حروف انگلیسی)
|
username: نام کاربری (تنها حروف انگلیسی)
|
||||||
username_or_email: نام کاربری یا ایمیل
|
username_or_email: نام کاربری یا ایمیل
|
||||||
|
whole_word: تطابق واژهٔ کامل
|
||||||
interactions:
|
interactions:
|
||||||
must_be_follower: مسدودکردن اعلانهای همه به جز پیگیران
|
must_be_follower: مسدودکردن اعلانهای همه به جز پیگیران
|
||||||
must_be_following: مسدودکردن اعلانهای کسانی که شما پی نمیگیرید
|
must_be_following: مسدودکردن اعلانهای کسانی که شما پی نمیگیرید
|
||||||
|
|
|
@ -13,6 +13,7 @@ gl:
|
||||||
other: <span class="name-counter">%{count}</span> caracteres restantes
|
other: <span class="name-counter">%{count}</span> caracteres restantes
|
||||||
fields: Pode ter ate 4 elementos no seu perfil mostrados como unha táboa
|
fields: Pode ter ate 4 elementos no seu perfil mostrados como unha táboa
|
||||||
header: PNG, GIF ou JPG. Máximo 2MB. Será reducida a 700x335px
|
header: PNG, GIF ou JPG. Máximo 2MB. Será reducida a 700x335px
|
||||||
|
inbox_url: Copiar o URL desde a páxina de inicio do repetidor que quere utilizar
|
||||||
irreversible: Os toots filtrados desaparecerán de xeito irreversible, incluso si despois se elimina o filtro
|
irreversible: Os toots filtrados desaparecerán de xeito irreversible, incluso si despois se elimina o filtro
|
||||||
locale: O idioma da interface de usuaria, correos e notificacións
|
locale: O idioma da interface de usuaria, correos e notificacións
|
||||||
locked: Require que vostede acepte as seguidoras de xeito manual
|
locked: Require que vostede acepte as seguidoras de xeito manual
|
||||||
|
@ -25,6 +26,7 @@ gl:
|
||||||
setting_hide_network: Non se mostrará no seu perfil quen a segue e quen a está a seguir
|
setting_hide_network: Non se mostrará no seu perfil quen a segue e quen a está a seguir
|
||||||
setting_noindex: Afecta ao seu perfil público e páxinas de estado
|
setting_noindex: Afecta ao seu perfil público e páxinas de estado
|
||||||
setting_theme: Afecta ao aspecto de Mastodon en calquer dispositivo cando está conectada.
|
setting_theme: Afecta ao aspecto de Mastodon en calquer dispositivo cando está conectada.
|
||||||
|
whole_word: Si a chave ou frase de paso é só alfanumérica, só se aplicará si concorda a palabra completa
|
||||||
imports:
|
imports:
|
||||||
data: Ficheiro CSV exportado desde outra instancia Mastodon
|
data: Ficheiro CSV exportado desde outra instancia Mastodon
|
||||||
sessions:
|
sessions:
|
||||||
|
@ -51,6 +53,7 @@ gl:
|
||||||
expires_in: Caducidade despois de
|
expires_in: Caducidade despois de
|
||||||
fields: Metadatos do perfil
|
fields: Metadatos do perfil
|
||||||
header: Cabeceira
|
header: Cabeceira
|
||||||
|
inbox_url: URL da caixa de entrada do repetidor
|
||||||
irreversible: Soltar en lugar de agochar
|
irreversible: Soltar en lugar de agochar
|
||||||
locale: Idioma da interface
|
locale: Idioma da interface
|
||||||
locked: Protexer conta
|
locked: Protexer conta
|
||||||
|
@ -77,6 +80,7 @@ gl:
|
||||||
type: Tipo de importación
|
type: Tipo de importación
|
||||||
username: Nome de usuaria
|
username: Nome de usuaria
|
||||||
username_or_email: Nome de usuaria ou Correo-e
|
username_or_email: Nome de usuaria ou Correo-e
|
||||||
|
whole_word: Palabra completa
|
||||||
interactions:
|
interactions:
|
||||||
must_be_follower: Bloquear as notificacións de non-seguidoras
|
must_be_follower: Bloquear as notificacións de non-seguidoras
|
||||||
must_be_following: Bloquea as notificacións de personas que non segue
|
must_be_following: Bloquea as notificacións de personas que non segue
|
||||||
|
|
|
@ -40,7 +40,7 @@ ja:
|
||||||
chosen_languages: 表示する言語
|
chosen_languages: 表示する言語
|
||||||
confirm_new_password: 新しいパスワード(確認用)
|
confirm_new_password: 新しいパスワード(確認用)
|
||||||
confirm_password: パスワード(確認用)
|
confirm_password: パスワード(確認用)
|
||||||
context: フィルター対象
|
context: 除外対象
|
||||||
current_password: 現在のパスワード
|
current_password: 現在のパスワード
|
||||||
data: データ
|
data: データ
|
||||||
display_name: 表示名
|
display_name: 表示名
|
||||||
|
@ -48,6 +48,7 @@ ja:
|
||||||
expires_in: 有効期限
|
expires_in: 有効期限
|
||||||
fields: プロフィール補足情報
|
fields: プロフィール補足情報
|
||||||
header: ヘッダー
|
header: ヘッダー
|
||||||
|
inbox_url: URL of the relay inbox
|
||||||
irreversible: 隠すのではなく除外する
|
irreversible: 隠すのではなく除外する
|
||||||
locale: 言語
|
locale: 言語
|
||||||
locked: 承認制アカウントにする
|
locked: 承認制アカウントにする
|
||||||
|
@ -56,7 +57,7 @@ ja:
|
||||||
note: プロフィール
|
note: プロフィール
|
||||||
otp_attempt: 二段階認証コード
|
otp_attempt: 二段階認証コード
|
||||||
password: パスワード
|
password: パスワード
|
||||||
phrase: 単語または語句
|
phrase: キーワードまたはフレーズ
|
||||||
setting_auto_play_gif: アニメーションGIFを自動再生する
|
setting_auto_play_gif: アニメーションGIFを自動再生する
|
||||||
setting_boost_modal: ブーストする前に確認ダイアログを表示する
|
setting_boost_modal: ブーストする前に確認ダイアログを表示する
|
||||||
setting_default_language: 投稿する言語
|
setting_default_language: 投稿する言語
|
||||||
|
|
|
@ -20,10 +20,12 @@ ko:
|
||||||
one: <span class="note-counter">1</span> 글자 남음
|
one: <span class="note-counter">1</span> 글자 남음
|
||||||
other: <span class="note-counter">%{count}</span> 글자 남음
|
other: <span class="note-counter">%{count}</span> 글자 남음
|
||||||
phrase: 툿 내용이나 CW 내용 안에서 대소문자 구분 없이 매칭 됩니다
|
phrase: 툿 내용이나 CW 내용 안에서 대소문자 구분 없이 매칭 됩니다
|
||||||
|
scopes: 애플리케이션에 허용할 API들입니다. 최상위 스코프를 선택하면 개별적인 것은 선택하지 않아도 됩니다.
|
||||||
setting_default_language: 작성한 툿의 언어는 자동으로 인식할 수 있지만, 언제나 정확한 건 아닙니다
|
setting_default_language: 작성한 툿의 언어는 자동으로 인식할 수 있지만, 언제나 정확한 건 아닙니다
|
||||||
setting_hide_network: 나를 팔로우 하는 사람들과 내가 팔로우 하는 사람들이 내 프로필에 표시되지 않게 합니다
|
setting_hide_network: 나를 팔로우 하는 사람들과 내가 팔로우 하는 사람들이 내 프로필에 표시되지 않게 합니다
|
||||||
setting_noindex: 공개 프로필 및 각 툿페이지에 영향을 미칩니다
|
setting_noindex: 공개 프로필 및 각 툿페이지에 영향을 미칩니다
|
||||||
setting_theme: 로그인중인 모든 디바이스에 적용되는 디자인입니다.
|
setting_theme: 로그인중인 모든 디바이스에 적용되는 디자인입니다.
|
||||||
|
whole_word: 키워드가 영문과 숫자로만 이루어 진 경우, 단어 전체에 매칭 되었을 때에만 작동하게 합니다
|
||||||
imports:
|
imports:
|
||||||
data: 다른 마스토돈 인스턴스에서 추출된 CSV 파일
|
data: 다른 마스토돈 인스턴스에서 추출된 CSV 파일
|
||||||
sessions:
|
sessions:
|
||||||
|
@ -76,6 +78,7 @@ ko:
|
||||||
type: 불러오기 종류
|
type: 불러오기 종류
|
||||||
username: 유저 이름
|
username: 유저 이름
|
||||||
username_or_email: 유저네임 또는 이메일
|
username_or_email: 유저네임 또는 이메일
|
||||||
|
whole_word: 단어 전체에 매칭
|
||||||
interactions:
|
interactions:
|
||||||
must_be_follower: 나를 팔로우 하지 않는 사람에게서 온 알림을 차단
|
must_be_follower: 나를 팔로우 하지 않는 사람에게서 온 알림을 차단
|
||||||
must_be_following: 내가 팔로우 하지 않는 사람에게서 온 알림을 차단
|
must_be_following: 내가 팔로우 하지 않는 사람에게서 온 알림을 차단
|
||||||
|
|
|
@ -13,6 +13,7 @@ nl:
|
||||||
other: <span class="name-counter">%{count}</span> tekens over
|
other: <span class="name-counter">%{count}</span> tekens over
|
||||||
fields: Je kan maximaal 4 items als een tabel op je profiel weergeven
|
fields: Je kan maximaal 4 items als een tabel op je profiel weergeven
|
||||||
header: PNG, GIF of JPG. Maximaal 2MB. Wordt teruggeschaald naar 700x335px
|
header: PNG, GIF of JPG. Maximaal 2MB. Wordt teruggeschaald naar 700x335px
|
||||||
|
inbox_url: Kopieer de URL van de voorpagina van de relayserver die je wil gebruiken
|
||||||
irreversible: Gefilterde toots verdwijnen onomkeerbaar, zelfs als de filter later wordt verwijderd
|
irreversible: Gefilterde toots verdwijnen onomkeerbaar, zelfs als de filter later wordt verwijderd
|
||||||
locale: De taal van de gebruikersomgeving, e-mails en pushmeldingen
|
locale: De taal van de gebruikersomgeving, e-mails en pushmeldingen
|
||||||
locked: Vereist dat je handmatig volgers moet accepteren
|
locked: Vereist dat je handmatig volgers moet accepteren
|
||||||
|
@ -25,6 +26,7 @@ nl:
|
||||||
setting_hide_network: Wie jij volgt en wie jou volgen wordt niet op jouw profiel getoond
|
setting_hide_network: Wie jij volgt en wie jou volgen wordt niet op jouw profiel getoond
|
||||||
setting_noindex: Heeft invloed op jouw openbare profiel en toots
|
setting_noindex: Heeft invloed op jouw openbare profiel en toots
|
||||||
setting_theme: Heeft invloed op hoe de webapp van Mastodon eruitziet (op elk apparaat waarmee je inlogt).
|
setting_theme: Heeft invloed op hoe de webapp van Mastodon eruitziet (op elk apparaat waarmee je inlogt).
|
||||||
|
whole_word: Wanneer het trefwoord of zinsdeel alfanumeriek is, wordt het alleen gefilterd wanneer het hele woord overeenkomt
|
||||||
imports:
|
imports:
|
||||||
data: CSV-bestand dat op een andere Mastodonserver werd geëxporteerd
|
data: CSV-bestand dat op een andere Mastodonserver werd geëxporteerd
|
||||||
sessions:
|
sessions:
|
||||||
|
@ -51,6 +53,7 @@ nl:
|
||||||
expires_in: Vervalt na
|
expires_in: Vervalt na
|
||||||
fields: Metadata profiel
|
fields: Metadata profiel
|
||||||
header: Omslagfoto
|
header: Omslagfoto
|
||||||
|
inbox_url: Inbox-URL van de relayserver
|
||||||
irreversible: Verwijderen in plaats van verbergen
|
irreversible: Verwijderen in plaats van verbergen
|
||||||
locale: Taal van de gebruikersomgeving
|
locale: Taal van de gebruikersomgeving
|
||||||
locked: Maak account besloten
|
locked: Maak account besloten
|
||||||
|
@ -77,6 +80,7 @@ nl:
|
||||||
type: Importtype
|
type: Importtype
|
||||||
username: Gebruikersnaam
|
username: Gebruikersnaam
|
||||||
username_or_email: Gebruikersnaam of e-mailadres
|
username_or_email: Gebruikersnaam of e-mailadres
|
||||||
|
whole_word: Heel woord
|
||||||
interactions:
|
interactions:
|
||||||
must_be_follower: Meldingen van mensen die jou niet volgen blokkeren
|
must_be_follower: Meldingen van mensen die jou niet volgen blokkeren
|
||||||
must_be_following: Meldingen van mensen die jij niet volgt blokkeren
|
must_be_following: Meldingen van mensen die jij niet volgt blokkeren
|
||||||
|
|
|
@ -27,6 +27,7 @@ sk:
|
||||||
setting_hide_network: Koho následuješ, a kto následuje teba nebude zobrazené na tvojom profile
|
setting_hide_network: Koho následuješ, a kto následuje teba nebude zobrazené na tvojom profile
|
||||||
setting_noindex: Ovplyvňuje verejný profil a statusy
|
setting_noindex: Ovplyvňuje verejný profil a statusy
|
||||||
setting_theme: Toto ovplyvňuje ako Mastodon vyzerá pri prihlásení z hociakého zariadenia.
|
setting_theme: Toto ovplyvňuje ako Mastodon vyzerá pri prihlásení z hociakého zariadenia.
|
||||||
|
whole_word: Ak je kľúčové slovo, alebo fráza poskladaná iba s písmen a čísel, bude použité iba ak sa zhoduje s celým výrazom
|
||||||
imports:
|
imports:
|
||||||
data: CSV súbor vyexportovaný z inej Mastodon inštancie
|
data: CSV súbor vyexportovaný z inej Mastodon inštancie
|
||||||
sessions:
|
sessions:
|
||||||
|
@ -53,6 +54,7 @@ sk:
|
||||||
expires_in: Expirovať po
|
expires_in: Expirovať po
|
||||||
fields: Metadáta profilu
|
fields: Metadáta profilu
|
||||||
header: Obrázok v hlavičke
|
header: Obrázok v hlavičke
|
||||||
|
inbox_url: URL adresa prechodnej schránky
|
||||||
irreversible: Zahoď, namiesto skritia
|
irreversible: Zahoď, namiesto skritia
|
||||||
locale: Jazyk rozhrania
|
locale: Jazyk rozhrania
|
||||||
locked: Zamknúť účet
|
locked: Zamknúť účet
|
||||||
|
@ -79,6 +81,7 @@ sk:
|
||||||
type: Typ importu
|
type: Typ importu
|
||||||
username: Prezývka
|
username: Prezývka
|
||||||
username_or_email: Prezívka, alebo email
|
username_or_email: Prezívka, alebo email
|
||||||
|
whole_word: Celé slovo
|
||||||
interactions:
|
interactions:
|
||||||
must_be_follower: Blokovať oznámenia od užívateľov, ktorí ťa nesledujú
|
must_be_follower: Blokovať oznámenia od užívateľov, ktorí ťa nesledujú
|
||||||
must_be_following: Blokovať oboznámenia ohľadom ľudí ktorých nesleduješ
|
must_be_following: Blokovať oboznámenia ohľadom ľudí ktorých nesleduješ
|
||||||
|
|
|
@ -259,9 +259,12 @@ sk:
|
||||||
filter:
|
filter:
|
||||||
all: Všetky
|
all: Všetky
|
||||||
available: Dostupné
|
available: Dostupné
|
||||||
expired: Expirované
|
expired: Vypršalo
|
||||||
title: Filtrovať
|
title: Filtrovať
|
||||||
title: Pozvánky
|
title: Pozvánky
|
||||||
|
relays:
|
||||||
|
add_new: Pridaj novú priechodnú oporu
|
||||||
|
status: Stav
|
||||||
report_notes:
|
report_notes:
|
||||||
created_msg: Poznámka o nahlásení úspešne vytvorená!
|
created_msg: Poznámka o nahlásení úspešne vytvorená!
|
||||||
destroyed_msg: Poznámka o nahlásení úspešne vymazaná!
|
destroyed_msg: Poznámka o nahlásení úspešne vymazaná!
|
||||||
|
@ -423,11 +426,11 @@ sk:
|
||||||
authorize_follow:
|
authorize_follow:
|
||||||
already_following: Tento účet už následuješ
|
already_following: Tento účet už následuješ
|
||||||
error: Naneštastie nastala chyba pri hľadaní vzdialeného účtu
|
error: Naneštastie nastala chyba pri hľadaní vzdialeného účtu
|
||||||
follow: Následovať
|
follow: Následuj
|
||||||
follow_request: 'Poslali ste požiadavku následovať užívateľa:'
|
follow_request: 'Poslal/a si žiadosť následovať užívateľa:'
|
||||||
following: 'Podarilo sa! Teraz už následujete užívateľa:'
|
following: 'Podarilo sa! Teraz už následuješ užívateľa:'
|
||||||
post_follow:
|
post_follow:
|
||||||
close: Alebo môžete iba zatvoriť toto okno.
|
close: Alebo môžeš iba zatvoriť toto okno.
|
||||||
return: Ukáž užívateľov profil
|
return: Ukáž užívateľov profil
|
||||||
web: Prejdi do siete
|
web: Prejdi do siete
|
||||||
title: Následuj %{acct}
|
title: Následuj %{acct}
|
||||||
|
@ -635,6 +638,7 @@ sk:
|
||||||
browser: Prehliadač
|
browser: Prehliadač
|
||||||
browsers:
|
browsers:
|
||||||
alipay: Alipay
|
alipay: Alipay
|
||||||
|
blackberry: RIM Blackberry
|
||||||
chrome: Google Chrome
|
chrome: Google Chrome
|
||||||
edge: Microsoft Edge
|
edge: Microsoft Edge
|
||||||
electron: Electron
|
electron: Electron
|
||||||
|
|
|
@ -42,6 +42,7 @@ SimpleNavigation::Configuration.run do |navigation|
|
||||||
primary.item :admin, safe_join([fa_icon('cogs fw'), t('admin.title')]), proc { current_user.admin? ? edit_admin_settings_url : admin_custom_emojis_url }, if: proc { current_user.staff? } do |admin|
|
primary.item :admin, safe_join([fa_icon('cogs fw'), t('admin.title')]), proc { current_user.admin? ? edit_admin_settings_url : admin_custom_emojis_url }, if: proc { current_user.staff? } do |admin|
|
||||||
admin.item :settings, safe_join([fa_icon('cogs fw'), t('admin.settings.title')]), edit_admin_settings_url, if: -> { current_user.admin? }
|
admin.item :settings, safe_join([fa_icon('cogs fw'), t('admin.settings.title')]), edit_admin_settings_url, if: -> { current_user.admin? }
|
||||||
admin.item :custom_emojis, safe_join([fa_icon('smile-o fw'), t('admin.custom_emojis.title')]), admin_custom_emojis_url, highlights_on: %r{/admin/custom_emojis}
|
admin.item :custom_emojis, safe_join([fa_icon('smile-o fw'), t('admin.custom_emojis.title')]), admin_custom_emojis_url, highlights_on: %r{/admin/custom_emojis}
|
||||||
|
admin.item :relays, safe_join([fa_icon('exchange fw'), t('admin.relays.title')]), admin_relays_url, if: -> { current_user.admin? }, highlights_on: %r{/admin/relays}
|
||||||
admin.item :subscriptions, safe_join([fa_icon('paper-plane-o fw'), t('admin.subscriptions.title')]), admin_subscriptions_url, if: -> { current_user.admin? }
|
admin.item :subscriptions, safe_join([fa_icon('paper-plane-o fw'), t('admin.subscriptions.title')]), admin_subscriptions_url, if: -> { current_user.admin? }
|
||||||
admin.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url, link_html: { target: 'sidekiq' }, if: -> { current_user.admin? }
|
admin.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url, link_html: { target: 'sidekiq' }, if: -> { current_user.admin? }
|
||||||
admin.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_url, link_html: { target: 'pghero' }, if: -> { current_user.admin? }
|
admin.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_url, link_html: { target: 'pghero' }, if: -> { current_user.admin? }
|
||||||
|
|
|
@ -134,6 +134,13 @@ Rails.application.routes.draw do
|
||||||
resource :settings, only: [:edit, :update]
|
resource :settings, only: [:edit, :update]
|
||||||
resources :invites, only: [:index, :create, :destroy]
|
resources :invites, only: [:index, :create, :destroy]
|
||||||
|
|
||||||
|
resources :relays, only: [:index, :new, :create, :destroy] do
|
||||||
|
member do
|
||||||
|
post :enable
|
||||||
|
post :disable
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
resources :instances, only: [:index] do
|
resources :instances, only: [:index] do
|
||||||
collection do
|
collection do
|
||||||
post :resubscribe
|
post :resubscribe
|
||||||
|
|
|
@ -16,6 +16,8 @@ if (process.env.VAGRANT) {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = merge(sharedConfig, {
|
module.exports = merge(sharedConfig, {
|
||||||
|
mode: 'development',
|
||||||
|
|
||||||
devtool: 'cheap-module-eval-source-map',
|
devtool: 'cheap-module-eval-source-map',
|
||||||
|
|
||||||
stats: {
|
stats: {
|
||||||
|
|
|
@ -1,15 +1,27 @@
|
||||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
const { env } = require('../configuration.js');
|
const { env } = require('../configuration.js');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
test: /\.(scss|sass|css)$/i,
|
test: /\.s?css$/i,
|
||||||
use: ExtractTextPlugin.extract({
|
|
||||||
fallback: 'style-loader',
|
|
||||||
use: [
|
use: [
|
||||||
{ loader: 'css-loader', options: { minimize: env.NODE_ENV === 'production' } },
|
MiniCssExtractPlugin.loader,
|
||||||
{ loader: 'postcss-loader', options: { sourceMap: true } },
|
{
|
||||||
'resolve-url-loader',
|
loader: 'css-loader',
|
||||||
{ loader: 'sass-loader', options: { includePaths: ['app/javascript'] } },
|
options: {
|
||||||
|
minimize: env.NODE_ENV === 'production',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: 'postcss-loader',
|
||||||
|
options: {
|
||||||
|
sourceMap: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: 'sass-loader',
|
||||||
|
options: {
|
||||||
|
includePaths: ['app/javascript'],
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}),
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Note: You must restart bin/webpack-dev-server for changes to take effect
|
// Note: You must restart bin/webpack-dev-server for changes to take effect
|
||||||
|
|
||||||
const webpack = require('webpack');
|
|
||||||
const merge = require('webpack-merge');
|
const merge = require('webpack-merge');
|
||||||
|
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
||||||
const CompressionPlugin = require('compression-webpack-plugin');
|
const CompressionPlugin = require('compression-webpack-plugin');
|
||||||
const sharedConfig = require('./shared.js');
|
const sharedConfig = require('./shared.js');
|
||||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||||
|
@ -36,6 +36,8 @@ if (process.env.S3_ENABLED === 'true') {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = merge(sharedConfig, {
|
module.exports = merge(sharedConfig, {
|
||||||
|
mode: 'production',
|
||||||
|
|
||||||
output: {
|
output: {
|
||||||
filename: '[name]-[chunkhash].js',
|
filename: '[name]-[chunkhash].js',
|
||||||
chunkFilename: '[name]-[chunkhash].js',
|
chunkFilename: '[name]-[chunkhash].js',
|
||||||
|
@ -44,9 +46,13 @@ module.exports = merge(sharedConfig, {
|
||||||
devtool: 'source-map', // separate sourcemap file, suitable for production
|
devtool: 'source-map', // separate sourcemap file, suitable for production
|
||||||
stats: 'normal',
|
stats: 'normal',
|
||||||
|
|
||||||
plugins: [
|
optimization: {
|
||||||
new webpack.optimize.UglifyJsPlugin({
|
minimize: true,
|
||||||
|
minimizer: [
|
||||||
|
new UglifyJsPlugin({
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
|
|
||||||
|
uglifyOptions: {
|
||||||
mangle: true,
|
mangle: true,
|
||||||
|
|
||||||
compress: {
|
compress: {
|
||||||
|
@ -56,7 +62,12 @@ module.exports = merge(sharedConfig, {
|
||||||
output: {
|
output: {
|
||||||
comments: false,
|
comments: false,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
plugins: [
|
||||||
new CompressionPlugin({
|
new CompressionPlugin({
|
||||||
asset: '[path].gz[query]',
|
asset: '[path].gz[query]',
|
||||||
algorithm: compressionAlgorithm,
|
algorithm: compressionAlgorithm,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
// Note: You must restart bin/webpack-dev-server for changes to take effect
|
// Note: You must restart bin/webpack-dev-server for changes to take effect
|
||||||
|
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
const { join, resolve } = require('path');
|
const { basename, dirname, join, relative, resolve } = require('path');
|
||||||
const { sync } = require('glob');
|
const { sync } = require('glob');
|
||||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
const ManifestPlugin = require('webpack-manifest-plugin');
|
const ManifestPlugin = require('webpack-manifest-plugin');
|
||||||
const { env, settings, core, flavours, output, loadersDir } = require('./configuration.js');
|
const { env, settings, core, flavours, output, loadersDir } = require('./configuration.js');
|
||||||
const localePacks = require('./generateLocalePacks');
|
const localePacks = require('./generateLocalePacks');
|
||||||
|
@ -59,6 +59,25 @@ module.exports = {
|
||||||
publicPath: output.publicPath,
|
publicPath: output.publicPath,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
optimization: {
|
||||||
|
runtimeChunk: {
|
||||||
|
name: 'locales',
|
||||||
|
},
|
||||||
|
splitChunks: {
|
||||||
|
cacheGroups: {
|
||||||
|
default: false,
|
||||||
|
vendors: false,
|
||||||
|
locales: {
|
||||||
|
name: 'locales',
|
||||||
|
chunks: 'all',
|
||||||
|
minChunks: Infinity,
|
||||||
|
minSize: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
occurrenceOrder: true,
|
||||||
|
},
|
||||||
|
|
||||||
module: {
|
module: {
|
||||||
rules: sync(join(loadersDir, '*.js')).map(loader => require(loader)),
|
rules: sync(join(loadersDir, '*.js')).map(loader => require(loader)),
|
||||||
},
|
},
|
||||||
|
@ -72,17 +91,13 @@ module.exports = {
|
||||||
resource.request = resource.request.replace(/^history/, 'history/es');
|
resource.request = resource.request.replace(/^history/, 'history/es');
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
new ExtractTextPlugin({
|
new MiniCssExtractPlugin({
|
||||||
filename: env.NODE_ENV === 'production' ? '[name]-[contenthash].css' : '[name].css',
|
filename: env.NODE_ENV === 'production' ? '[name]-[contenthash].css' : '[name].css',
|
||||||
allChunks: true,
|
|
||||||
}),
|
}),
|
||||||
new ManifestPlugin({
|
new ManifestPlugin({
|
||||||
publicPath: output.publicPath,
|
publicPath: output.publicPath,
|
||||||
writeToFileEmit: true,
|
writeToFileEmit: true,
|
||||||
}),
|
filter: file => !file.isAsset || file.isModuleAsset,
|
||||||
new webpack.optimize.CommonsChunkPlugin({
|
|
||||||
name: 'locales',
|
|
||||||
minChunks: Infinity, // It doesn't make sense to use common chunks with multiple frontend support.
|
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
|
@ -3,4 +3,6 @@
|
||||||
const merge = require('webpack-merge');
|
const merge = require('webpack-merge');
|
||||||
const sharedConfig = require('./shared.js');
|
const sharedConfig = require('./shared.js');
|
||||||
|
|
||||||
module.exports = merge(sharedConfig, {});
|
module.exports = merge(sharedConfig, {
|
||||||
|
mode: 'development',
|
||||||
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@ class RevertIndexChangeOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecor
|
||||||
|
|
||||||
def change
|
def change
|
||||||
safety_assured do
|
safety_assured do
|
||||||
add_index :statuses, [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106 unless index_exists?(:statuses, name: "index_statuses_20180106")
|
add_index :statuses, [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106 unless index_name_exists?(:statuses, "index_statuses_20180106")
|
||||||
end
|
end
|
||||||
|
|
||||||
# These index may not exists (see migration 20180514130000)
|
# These index may not exists (see migration 20180514130000)
|
||||||
|
|
12
db/migrate/20180711152640_create_relays.rb
Normal file
12
db/migrate/20180711152640_create_relays.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
class CreateRelays < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
create_table :relays do |t|
|
||||||
|
t.string :inbox_url, default: '', null: false
|
||||||
|
t.boolean :enabled, default: false, null: false, index: true
|
||||||
|
|
||||||
|
t.string :follow_activity_id
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
11
db/schema.rb
11
db/schema.rb
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2018_07_07_193142) do
|
ActiveRecord::Schema.define(version: 2018_07_11_152640) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -381,6 +381,15 @@ ActiveRecord::Schema.define(version: 2018_07_07_193142) do
|
||||||
t.index ["status_id", "preview_card_id"], name: "index_preview_cards_statuses_on_status_id_and_preview_card_id"
|
t.index ["status_id", "preview_card_id"], name: "index_preview_cards_statuses_on_status_id_and_preview_card_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "relays", force: :cascade do |t|
|
||||||
|
t.string "inbox_url", default: "", null: false
|
||||||
|
t.boolean "enabled", default: false, null: false
|
||||||
|
t.string "follow_activity_id"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
t.index ["enabled"], name: "index_relays_on_enabled"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "report_notes", force: :cascade do |t|
|
create_table "report_notes", force: :cascade do |t|
|
||||||
t.text "content", null: false
|
t.text "content", null: false
|
||||||
t.bigint "report_id", null: false
|
t.bigint "report_id", null: false
|
||||||
|
|
|
@ -5,14 +5,7 @@ module Paperclip
|
||||||
# to convert animated gifs to webm
|
# to convert animated gifs to webm
|
||||||
class GifTranscoder < Paperclip::Processor
|
class GifTranscoder < Paperclip::Processor
|
||||||
def make
|
def make
|
||||||
num_frames = identify('-format %n :file', file: file.path).to_i
|
return File.open(@file.path) unless needs_convert?
|
||||||
|
|
||||||
unless options[:style] == :original && num_frames > 1
|
|
||||||
tmp_file = Paperclip::TempfileFactory.new.generate(attachment.instance.file_file_name)
|
|
||||||
tmp_file << file.read
|
|
||||||
tmp_file.flush
|
|
||||||
return tmp_file
|
|
||||||
end
|
|
||||||
|
|
||||||
final_file = Paperclip::Transcoder.make(file, options, attachment)
|
final_file = Paperclip::Transcoder.make(file, options, attachment)
|
||||||
|
|
||||||
|
@ -22,5 +15,12 @@ module Paperclip
|
||||||
|
|
||||||
final_file
|
final_file
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def needs_convert?
|
||||||
|
num_frames = identify('-format %n :file', file: file.path).to_i
|
||||||
|
options[:style] == :original && num_frames > 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
71
package.json
71
package.json
|
@ -22,29 +22,29 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"array-includes": "^3.0.3",
|
"array-includes": "^3.0.3",
|
||||||
"atrament": "^0.2.3",
|
"atrament": "^0.2.3",
|
||||||
"autoprefixer": "^7.1.6",
|
"autoprefixer": "^8.6.5",
|
||||||
"axios": "~0.16.2",
|
"axios": "~0.16.2",
|
||||||
"babel-core": "^6.25.0",
|
"babel-core": "^6.26.3",
|
||||||
"babel-loader": "^7.1.1",
|
"babel-loader": "^7.1.5",
|
||||||
"babel-plugin-lodash": "^3.3.2",
|
"babel-plugin-lodash": "^3.3.4",
|
||||||
"babel-plugin-preval": "^1.6.1",
|
"babel-plugin-preval": "^1.6.1",
|
||||||
"babel-plugin-react-intl": "^2.3.1",
|
"babel-plugin-react-intl": "^2.4.0",
|
||||||
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
||||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||||
"babel-plugin-transform-decorators-legacy": "^1.3.4",
|
"babel-plugin-transform-decorators-legacy": "^1.3.5",
|
||||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
|
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
|
||||||
"babel-plugin-transform-object-rest-spread": "^6.23.0",
|
"babel-plugin-transform-object-rest-spread": "^6.23.0",
|
||||||
"babel-plugin-transform-react-inline-elements": "^6.22.0",
|
"babel-plugin-transform-react-inline-elements": "^6.22.0",
|
||||||
"babel-plugin-transform-react-jsx-self": "^6.22.0",
|
"babel-plugin-transform-react-jsx-self": "^6.22.0",
|
||||||
"babel-plugin-transform-react-jsx-source": "^6.22.0",
|
"babel-plugin-transform-react-jsx-source": "^6.22.0",
|
||||||
"babel-plugin-transform-react-remove-prop-types": "^0.4.10",
|
"babel-plugin-transform-react-remove-prop-types": "^0.4.13",
|
||||||
"babel-plugin-transform-runtime": "^6.23.0",
|
"babel-plugin-transform-runtime": "^6.23.0",
|
||||||
"babel-preset-env": "^1.6.1",
|
"babel-preset-env": "^1.7.0",
|
||||||
"babel-preset-react": "^6.24.1",
|
"babel-preset-react": "^6.24.1",
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
"compression-webpack-plugin": "^1.0.1",
|
"compression-webpack-plugin": "^1.1.11",
|
||||||
"cross-env": "^5.1.1",
|
"cross-env": "^5.1.4",
|
||||||
"css-loader": "^0.28.4",
|
"css-loader": "^0.28.11",
|
||||||
"detect-passive-events": "^1.0.2",
|
"detect-passive-events": "^1.0.2",
|
||||||
"dotenv": "^4.0.0",
|
"dotenv": "^4.0.0",
|
||||||
"emoji-mart": "Gargron/emoji-mart#build",
|
"emoji-mart": "Gargron/emoji-mart#build",
|
||||||
|
@ -52,8 +52,7 @@
|
||||||
"escape-html": "^1.0.3",
|
"escape-html": "^1.0.3",
|
||||||
"exif-js": "^2.3.0",
|
"exif-js": "^2.3.0",
|
||||||
"express": "^4.16.2",
|
"express": "^4.16.2",
|
||||||
"extract-text-webpack-plugin": "^3.0.2",
|
"file-loader": "^1.1.11",
|
||||||
"file-loader": "^0.11.2",
|
|
||||||
"font-awesome": "^4.7.0",
|
"font-awesome": "^4.7.0",
|
||||||
"glob": "^7.1.1",
|
"glob": "^7.1.1",
|
||||||
"http-link-header": "^0.8.0",
|
"http-link-header": "^0.8.0",
|
||||||
|
@ -64,27 +63,28 @@
|
||||||
"intl-messageformat": "^2.2.0",
|
"intl-messageformat": "^2.2.0",
|
||||||
"intl-relativeformat": "^2.1.0",
|
"intl-relativeformat": "^2.1.0",
|
||||||
"is-nan": "^1.2.1",
|
"is-nan": "^1.2.1",
|
||||||
"js-yaml": "^3.9.0",
|
"js-yaml": "^3.11.0",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.5",
|
||||||
"mark-loader": "^0.1.6",
|
"mark-loader": "^0.1.6",
|
||||||
"marky": "^1.2.0",
|
"marky": "^1.2.0",
|
||||||
|
"mini-css-extract-plugin": "^0.4.1",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"node-sass": "^4.7.2",
|
"node-sass": "^4.9.2",
|
||||||
"npm-run-all": "^4.1.2",
|
"npm-run-all": "^4.1.2",
|
||||||
"npmlog": "^4.1.2",
|
"npmlog": "^4.1.2",
|
||||||
"object-assign": "^4.1.1",
|
"object-assign": "^4.1.1",
|
||||||
"object-fit-images": "^3.2.3",
|
"object-fit-images": "^3.2.3",
|
||||||
"object.values": "^1.0.4",
|
"object.values": "^1.0.4",
|
||||||
"offline-plugin": "^4.8.3",
|
"offline-plugin": "^5.0.5",
|
||||||
"path-complete-extname": "^0.1.0",
|
"path-complete-extname": "^1.0.0",
|
||||||
"pg": "^6.4.0",
|
"pg": "^6.4.0",
|
||||||
"postcss-loader": "^2.0.9",
|
"postcss-loader": "^2.1.6",
|
||||||
"postcss-object-fit-images": "^1.1.2",
|
"postcss-object-fit-images": "^1.1.2",
|
||||||
"postcss-smart-import": "^0.7.5",
|
"postcss-smart-import": "^0.7.6",
|
||||||
"precss": "^2.0.0",
|
"precss": "^3.1.2",
|
||||||
"prop-types": "^15.5.10",
|
"prop-types": "^15.5.10",
|
||||||
"punycode": "^2.1.0",
|
"punycode": "^2.1.0",
|
||||||
"rails-ujs": "^5.1.2",
|
"rails-ujs": "^5.2.0",
|
||||||
"react": "^16.3.0",
|
"react": "^16.3.0",
|
||||||
"react-dom": "^16.3.0",
|
"react-dom": "^16.3.0",
|
||||||
"react-hotkeys": "^0.10.0",
|
"react-hotkeys": "^0.10.0",
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
"react-router-dom": "^4.1.1",
|
"react-router-dom": "^4.1.1",
|
||||||
"react-router-scroll-4": "^1.0.0-beta.1",
|
"react-router-scroll-4": "^1.0.0-beta.1",
|
||||||
"react-sparklines": "^1.7.0",
|
"react-sparklines": "^1.7.0",
|
||||||
"react-swipeable-views": "^0.12.3",
|
"react-swipeable-views": "0.12.13",
|
||||||
"react-textarea-autosize": "^5.2.1",
|
"react-textarea-autosize": "^5.2.1",
|
||||||
"react-toggle": "^4.0.1",
|
"react-toggle": "^4.0.1",
|
||||||
"redis": "^2.7.1",
|
"redis": "^2.7.1",
|
||||||
|
@ -108,25 +108,26 @@
|
||||||
"redux-thunk": "^2.2.0",
|
"redux-thunk": "^2.2.0",
|
||||||
"requestidlecallback": "^0.3.0",
|
"requestidlecallback": "^0.3.0",
|
||||||
"reselect": "^3.0.1",
|
"reselect": "^3.0.1",
|
||||||
"resolve-url-loader": "^2.2.0",
|
|
||||||
"rimraf": "^2.6.1",
|
"rimraf": "^2.6.1",
|
||||||
"sass-loader": "^6.0.6",
|
"sass-loader": "^7.0.3",
|
||||||
"stringz": "^0.3.0",
|
"stringz": "^0.3.0",
|
||||||
"style-loader": "^0.19.0",
|
"style-loader": "^0.21.0",
|
||||||
"substring-trie": "^1.0.2",
|
"substring-trie": "^1.0.2",
|
||||||
"throng": "^4.0.0",
|
"throng": "^4.0.0",
|
||||||
"tiny-queue": "^0.2.1",
|
"tiny-queue": "^0.2.1",
|
||||||
|
"uglifyjs-webpack-plugin": "^1.2.7",
|
||||||
"uuid": "^3.1.0",
|
"uuid": "^3.1.0",
|
||||||
"uws": "^8.14.0",
|
"uws": "10.148.0",
|
||||||
"webpack": "^3.9.1",
|
"webpack": "^4.16.0",
|
||||||
"webpack-bundle-analyzer": "^2.9.1",
|
"webpack-bundle-analyzer": "^2.13.1",
|
||||||
"webpack-manifest-plugin": "^1.2.1",
|
"webpack-cli": "^3.0.8",
|
||||||
"webpack-merge": "^4.1.1",
|
"webpack-manifest-plugin": "^2.0.3",
|
||||||
|
"webpack-merge": "^4.1.3",
|
||||||
"websocket.js": "^0.1.12",
|
"websocket.js": "^0.1.12",
|
||||||
"whatwg-url": "^6.4.1"
|
"whatwg-url": "^6.4.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-eslint": "^8.2.3",
|
"babel-eslint": "^8.2.6",
|
||||||
"enzyme": "^3.2.0",
|
"enzyme": "^3.2.0",
|
||||||
"enzyme-adapter-react-16": "^1.1.0",
|
"enzyme-adapter-react-16": "^1.1.0",
|
||||||
"eslint": "^4.19.1",
|
"eslint": "^4.19.1",
|
||||||
|
@ -136,9 +137,9 @@
|
||||||
"eslint-plugin-react": "^7.8.2",
|
"eslint-plugin-react": "^7.8.2",
|
||||||
"jest": "^21.2.1",
|
"jest": "^21.2.1",
|
||||||
"raf": "^3.4.0",
|
"raf": "^3.4.0",
|
||||||
"react-intl-translations-manager": "^5.0.0",
|
"react-intl-translations-manager": "^5.0.3",
|
||||||
"react-test-renderer": "^16.2.0",
|
"react-test-renderer": "^16.2.0",
|
||||||
"webpack-dev-server": "^2.9.5",
|
"webpack-dev-server": "^3.1.4",
|
||||||
"yargs": "^8.0.2"
|
"yargs": "^8.0.2"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
|
|
4
spec/fabricators/relay_fabricator.rb
Normal file
4
spec/fabricators/relay_fabricator.rb
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
Fabricator(:relay) do
|
||||||
|
inbox_url "https://example.com/inbox"
|
||||||
|
enabled true
|
||||||
|
end
|
|
@ -58,13 +58,14 @@ RSpec.describe StreamEntriesHelper, type: :helper do
|
||||||
expect(acct).to eq '@user@foreign_server.com'
|
expect(acct).to eq '@user@foreign_server.com'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'is the shortname for non embedded local accounts' do
|
it 'is fully qualified for non embedded local accounts' do
|
||||||
|
allow(Rails.configuration.x).to receive(:local_domain).and_return('local_domain')
|
||||||
set_not_embedded_view
|
set_not_embedded_view
|
||||||
account = Account.new(domain: nil, username: 'user')
|
account = Account.new(domain: nil, username: 'user')
|
||||||
|
|
||||||
acct = helper.acct(account)
|
acct = helper.acct(account)
|
||||||
|
|
||||||
expect(acct).to eq '@user'
|
expect(acct).to eq '@user@local_domain'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ describe LanguageDetector do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'detects spanish language' do
|
it 'detects spanish language' do
|
||||||
string = 'Obtener un Hola y bienvenidos a Mastodon'
|
string = 'Obtener un Hola y bienvenidos a Mastodon. Obtener un Hola y bienvenidos a Mastodon. Obtener un Hola y bienvenidos a Mastodon. Obtener un Hola y bienvenidos a Mastodon'
|
||||||
result = described_class.instance.detect(string, account_without_user_locale)
|
result = described_class.instance.detect(string, account_without_user_locale)
|
||||||
|
|
||||||
expect(result).to eq :es
|
expect(result).to eq :es
|
||||||
|
@ -86,7 +86,7 @@ describe LanguageDetector do
|
||||||
account = double(user_locale: 'fr')
|
account = double(user_locale: 'fr')
|
||||||
result = described_class.instance.detect('', account)
|
result = described_class.instance.detect('', account)
|
||||||
|
|
||||||
expect(result).to eq :fr
|
expect(result).to eq nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'uses nil when account is present but has no locale' do
|
it 'uses nil when account is present but has no locale' do
|
||||||
|
|
4
spec/models/relay_spec.rb
Normal file
4
spec/models/relay_spec.rb
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Relay, type: :model do
|
||||||
|
end
|
|
@ -192,7 +192,7 @@ const startWorker = (workerId) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
client.query('SELECT oauth_access_tokens.resource_owner_id, users.account_id, users.filtered_languages FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL LIMIT 1', [token], (err, result) => {
|
client.query('SELECT oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL LIMIT 1', [token], (err, result) => {
|
||||||
done();
|
done();
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -209,7 +209,7 @@ const startWorker = (workerId) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
req.accountId = result.rows[0].account_id;
|
req.accountId = result.rows[0].account_id;
|
||||||
req.filteredLanguages = result.rows[0].filtered_languages;
|
req.chosenLanguages = result.rows[0].chosen_languages;
|
||||||
|
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
@ -340,7 +340,7 @@ const startWorker = (workerId) => {
|
||||||
const targetAccountIds = [unpackedPayload.account.id].concat(unpackedPayload.mentions.map(item => item.id));
|
const targetAccountIds = [unpackedPayload.account.id].concat(unpackedPayload.mentions.map(item => item.id));
|
||||||
const accountDomain = unpackedPayload.account.acct.split('@')[1];
|
const accountDomain = unpackedPayload.account.acct.split('@')[1];
|
||||||
|
|
||||||
if (Array.isArray(req.filteredLanguages) && req.filteredLanguages.indexOf(unpackedPayload.language) !== -1) {
|
if (Array.isArray(req.chosenLanguages) && unpackedPayload.language !== null && req.chosenLanguages.indexOf(unpackedPayload.language) === -1) {
|
||||||
log.silly(req.requestId, `Message ${unpackedPayload.id} filtered by language (${unpackedPayload.language})`);
|
log.silly(req.requestId, `Message ${unpackedPayload.id} filtered by language (${unpackedPayload.language})`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue