Merge branch 'master' into master
commit
1a12fd14d4
|
@ -52,8 +52,8 @@ import no from 'react-intl/locale-data/no';
|
||||||
import ru from 'react-intl/locale-data/ru';
|
import ru from 'react-intl/locale-data/ru';
|
||||||
import uk from 'react-intl/locale-data/uk';
|
import uk from 'react-intl/locale-data/uk';
|
||||||
import zh from 'react-intl/locale-data/zh';
|
import zh from 'react-intl/locale-data/zh';
|
||||||
|
import bg from 'react-intl/locale-data/bg';
|
||||||
import { localeData as zh_hk } from '../locales/zh-hk';
|
import { localeData as zh_hk } from '../locales/zh-hk';
|
||||||
|
|
||||||
import getMessagesForLocale from '../locales';
|
import getMessagesForLocale from '../locales';
|
||||||
import { hydrateStore } from '../actions/store';
|
import { hydrateStore } from '../actions/store';
|
||||||
import createStream from '../stream';
|
import createStream from '../stream';
|
||||||
|
@ -66,7 +66,6 @@ const browserHistory = useRouterHistory(createBrowserHistory)({
|
||||||
basename: '/web'
|
basename: '/web'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
addLocaleData([
|
addLocaleData([
|
||||||
...en,
|
...en,
|
||||||
...de,
|
...de,
|
||||||
|
@ -82,9 +81,9 @@ addLocaleData([
|
||||||
...uk,
|
...uk,
|
||||||
...zh,
|
...zh,
|
||||||
...zh_hk,
|
...zh_hk,
|
||||||
|
...bg,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
const Mastodon = React.createClass({
|
const Mastodon = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
|
|
@ -14,7 +14,7 @@ import ColumnBackButtonSlim from '../../components/column_back_button_slim';
|
||||||
import createStream from '../../stream';
|
import createStream from '../../stream';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
title: { id: 'column.community', defaultMessage: 'Local' }
|
title: { id: 'column.community', defaultMessage: 'Local timeline' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
|
|
|
@ -19,7 +19,7 @@ import TextIconButton from './text_icon_button';
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' },
|
placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' },
|
||||||
spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Content warning' },
|
spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Content warning' },
|
||||||
publish: { id: 'compose_form.publish', defaultMessage: 'Publish' }
|
publish: { id: 'compose_form.publish', defaultMessage: 'Toot' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const ComposeForm = React.createClass({
|
const ComposeForm = React.createClass({
|
||||||
|
|
|
@ -12,7 +12,7 @@ import SearchResultsContainer from './containers/search_results_container';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
|
start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
|
||||||
public: { id: 'navigation_bar.public_timeline', defaultMessage: 'Whole Known Network' },
|
public: { id: 'navigation_bar.public_timeline', defaultMessage: 'Federated timeline' },
|
||||||
community: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
|
community: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
|
||||||
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
||||||
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' }
|
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' }
|
||||||
|
|
|
@ -7,11 +7,11 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
heading: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
|
heading: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
|
||||||
public_timeline: { id: 'navigation_bar.public_timeline', defaultMessage: 'Whole Known Network' },
|
public_timeline: { id: 'navigation_bar.public_timeline', defaultMessage: 'Federated timeline' },
|
||||||
community_timeline: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
|
community_timeline: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
|
||||||
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
||||||
follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
|
follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
|
||||||
sign_out: { id: 'navigation_bar.logout', defaultMessage: 'Sign out' },
|
sign_out: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
||||||
favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' },
|
favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' },
|
||||||
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
|
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
|
||||||
info: { id: 'navigation_bar.info', defaultMessage: 'Extended information' }
|
info: { id: 'navigation_bar.info', defaultMessage: 'Extended information' }
|
||||||
|
|
|
@ -14,7 +14,7 @@ import ColumnBackButtonSlim from '../../components/column_back_button_slim';
|
||||||
import createStream from '../../stream';
|
import createStream from '../../stream';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
title: { id: 'column.public', defaultMessage: 'Whole Known Network' }
|
title: { id: 'column.public', defaultMessage: 'Federated timeline' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
const bg = {
|
||||||
|
"column_back_button.label": "Назад",
|
||||||
|
"lightbox.close": "Затвори",
|
||||||
|
"loading_indicator.label": "Зареждане...",
|
||||||
|
"status.mention": "Споменаване",
|
||||||
|
"status.delete": "Изтриване",
|
||||||
|
"status.reply": "Отговор",
|
||||||
|
"status.reblog": "Споделяне",
|
||||||
|
"status.favourite": "Предпочитани",
|
||||||
|
"status.reblogged_by": "{name} сподели",
|
||||||
|
"status.sensitive_warning": "Деликатно съдържание",
|
||||||
|
"status.sensitive_toggle": "Покажи",
|
||||||
|
"video_player.toggle_sound": "Звук",
|
||||||
|
"account.mention": "Споменаване",
|
||||||
|
"account.edit_profile": "Редактирай профила си",
|
||||||
|
"account.unblock": "Не блокирай",
|
||||||
|
"account.unfollow": "Не следвай",
|
||||||
|
"account.block": "Блокирай",
|
||||||
|
"account.follow": "Последвай",
|
||||||
|
"account.posts": "Публикации",
|
||||||
|
"account.follows": "Следвам",
|
||||||
|
"account.followers": "Последователи",
|
||||||
|
"account.follows_you": "Твой последовател",
|
||||||
|
"account.requested": "В очакване на одобрение",
|
||||||
|
"getting_started.heading": "Първи стъпки",
|
||||||
|
"getting_started.about_addressing": "Можеш да последваш потребител, ако знаеш потребителското му име и домейна, на който се намира, като в полето за търсене ги въведеш по този начин: име@домейн",
|
||||||
|
"getting_started.about_shortcuts": "Ако с търсения потребител се намирате на един и същ домейн, достатъчно е да въведеш само името. Същото важи и за споменаване на хора в публикации.",
|
||||||
|
"getting_started.about_developer": "Можеш да потърсиш разработчика на този проект като: Gargron@mastodon.social",
|
||||||
|
"getting_started.open_source_notice": "Mastodon е софтуер с отворен код. Можеш да помогнеш или да докладваш за проблеми в Github: {github}.",
|
||||||
|
"column.home": "Начало",
|
||||||
|
"column.mentions": "Споменавания",
|
||||||
|
"column.public": "Публичен канал",
|
||||||
|
"column.notifications": "Известия",
|
||||||
|
"tabs_bar.compose": "Съставяне",
|
||||||
|
"tabs_bar.home": "Начало",
|
||||||
|
"tabs_bar.mentions": "Споменавания",
|
||||||
|
"tabs_bar.public": "Публичен канал",
|
||||||
|
"tabs_bar.notifications": "Известия",
|
||||||
|
"compose_form.placeholder": "Какво си мислиш?",
|
||||||
|
"compose_form.publish": "Раздумай",
|
||||||
|
"compose_form.sensitive": "Отбележи съдържанието като деликатно",
|
||||||
|
"compose_form.spoiler": "Скрий текста зад предупреждение",
|
||||||
|
"compose_form.private": "Отбележи като поверително",
|
||||||
|
"compose_form.privacy_disclaimer": "Поверителни публикации ще бъдат изпратени до споменатите потребители на {domains}. Доверяваш ли се на {domainsCount, plural, one {that server} other {those servers}}, че няма да издаде твоята публикация?",
|
||||||
|
"compose_form.unlisted": "Не показвай в публичния канал",
|
||||||
|
"navigation_bar.edit_profile": "Редактирай профил",
|
||||||
|
"navigation_bar.preferences": "Предпочитания",
|
||||||
|
"navigation_bar.public_timeline": "Публичен канал",
|
||||||
|
"navigation_bar.logout": "Излизане",
|
||||||
|
"reply_indicator.cancel": "Отказ",
|
||||||
|
"search.placeholder": "Търсене",
|
||||||
|
"search.account": "Акаунт",
|
||||||
|
"search.hashtag": "Хаштаг",
|
||||||
|
"upload_button.label": "Добави медия",
|
||||||
|
"upload_form.undo": "Отмяна",
|
||||||
|
"notification.follow": "{name} те последва",
|
||||||
|
"notification.favourite": "{name} хареса твоята публикация",
|
||||||
|
"notification.reblog": "{name} сподели твоята публикация",
|
||||||
|
"notification.mention": "{name} те спомена",
|
||||||
|
"notifications.column_settings.alert": "Десктоп известия",
|
||||||
|
"notifications.column_settings.show": "Покажи в колона",
|
||||||
|
"notifications.column_settings.follow": "Нови последователи:",
|
||||||
|
"notifications.column_settings.favourite": "Предпочитани:",
|
||||||
|
"notifications.column_settings.mention": "Споменавания:",
|
||||||
|
"notifications.column_settings.reblog": "Споделяния:",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default en;
|
|
@ -1,72 +1,129 @@
|
||||||
|
/**
|
||||||
|
* Note for Contributors:
|
||||||
|
* This file (en.jsx) serve as a template for other languages.
|
||||||
|
* To make other contributors' life easier, please REMEMBER:
|
||||||
|
* 1. to add your new string here; and
|
||||||
|
* 2. to remove old strings that are no longer needed; and
|
||||||
|
* 3. to sort the strings by the key.
|
||||||
|
* Thanks!
|
||||||
|
*/
|
||||||
const en = {
|
const en = {
|
||||||
"column_back_button.label": "Back",
|
|
||||||
"lightbox.close": "Close",
|
|
||||||
"loading_indicator.label": "Loading...",
|
|
||||||
"status.mention": "Mention @{name}",
|
|
||||||
"status.delete": "Delete",
|
|
||||||
"status.reply": "Reply",
|
|
||||||
"status.reblog": "Boost",
|
|
||||||
"status.favourite": "Favourite",
|
|
||||||
"status.reblogged_by": "{name} boosted",
|
|
||||||
"status.sensitive_warning": "Sensitive content",
|
|
||||||
"status.sensitive_toggle": "Click to view",
|
|
||||||
"status.show_more": "Show more",
|
|
||||||
"status.show_less": "Show less",
|
|
||||||
"status.open": "Expand this status",
|
|
||||||
"status.report": "Report @{name}",
|
|
||||||
"video_player.toggle_sound": "Toggle sound",
|
|
||||||
"account.mention": "Mention @{name}",
|
|
||||||
"account.edit_profile": "Edit profile",
|
|
||||||
"account.unblock": "Unblock @{name}",
|
|
||||||
"account.unfollow": "Unfollow",
|
|
||||||
"account.block": "Block @{name}",
|
"account.block": "Block @{name}",
|
||||||
|
"account.disclaimer": "This user is from another instance. This number may be larger.",
|
||||||
|
"account.edit_profile": "Edit profile",
|
||||||
"account.follow": "Follow",
|
"account.follow": "Follow",
|
||||||
"account.posts": "Posts",
|
|
||||||
"account.follows": "Follows",
|
|
||||||
"account.followers": "Followers",
|
"account.followers": "Followers",
|
||||||
"account.follows_you": "Follows you",
|
"account.follows_you": "Follows you",
|
||||||
|
"account.follows": "Follows",
|
||||||
|
"account.mention": "Mention @{name}",
|
||||||
|
"account.mute": "Mute @{name}",
|
||||||
|
"account.posts": "Posts",
|
||||||
|
"account.report": "Report @{name}",
|
||||||
"account.requested": "Awaiting approval",
|
"account.requested": "Awaiting approval",
|
||||||
"getting_started.heading": "Getting started",
|
"account.unblock": "Unblock @{name}",
|
||||||
"getting_started.about_addressing": "You can follow people if you know their username and the domain they are on by entering an e-mail-esque address into the search form.",
|
"account.unfollow": "Unfollow",
|
||||||
"getting_started.about_shortcuts": "If the target user is on the same domain as you, just the username will work. The same rule applies to mentioning people in statuses.",
|
"account.unmute": "Unmute @{name}",
|
||||||
"getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}. {apps}.",
|
"boost_modal.combo": "You can press {combo} to skip this next time",
|
||||||
"column.home": "Home",
|
"column_back_button.label": "Back",
|
||||||
|
"column.blocks": "Blocked users",
|
||||||
"column.community": "Local timeline",
|
"column.community": "Local timeline",
|
||||||
"column.public": "Federated timeline",
|
"column.favourites": "Favourites",
|
||||||
|
"column.follow_requests": "Follow requests",
|
||||||
|
"column.home": "Home",
|
||||||
"column.notifications": "Notifications",
|
"column.notifications": "Notifications",
|
||||||
"tabs_bar.compose": "Compose",
|
"column.public": "Federated timeline",
|
||||||
"tabs_bar.home": "Home",
|
|
||||||
"tabs_bar.mentions": "Mentions",
|
|
||||||
"tabs_bar.public": "Federated timeline",
|
|
||||||
"tabs_bar.notifications": "Notifications",
|
|
||||||
"compose_form.placeholder": "What is on your mind?",
|
"compose_form.placeholder": "What is on your mind?",
|
||||||
|
"compose_form.privacy_disclaimer": "Your private status will be delivered to mentioned users on {domains}. Do you trust {domainsCount, plural, one {that server} other {those servers}}? Post privacy only works on Mastodon instances. If {domains} {domainsCount, plural, one {is not a Mastodon instance} other {are not Mastodon instances}}, there will be no indication that your post is private, and it may be boosted or otherwise made visible to unintended recipients.",
|
||||||
"compose_form.publish": "Toot",
|
"compose_form.publish": "Toot",
|
||||||
"compose_form.sensitive": "Mark media as sensitive",
|
"compose_form.sensitive": "Mark media as sensitive",
|
||||||
|
"compose_form.spoiler_placeholder": "Content warning",
|
||||||
"compose_form.spoiler": "Hide text behind warning",
|
"compose_form.spoiler": "Hide text behind warning",
|
||||||
"compose_form.private": "Mark as private",
|
"emoji_button.label": "Insert emoji",
|
||||||
"compose_form.privacy_disclaimer": "Your private status will be delivered to mentioned users on {domains}. Do you trust {domainsCount, plural, one {that server} other {those servers}}? Post privacy only works on Mastodon instances. If {domains} {domainsCount, plural, one {is not a Mastodon instance} other {are not Mastodon instances}}, there will be no indication that your post is private, and it may be boosted or otherwise made visible to unintended recipients.",
|
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
|
||||||
"compose_form.unlisted": "Do not display on public timelines",
|
"empty_column.hashtag": "There is nothing in this hashtag yet.",
|
||||||
"navigation_bar.edit_profile": "Edit profile",
|
"empty_column.home.public_timeline": "the public timeline",
|
||||||
"navigation_bar.preferences": "Preferences",
|
"empty_column.home": "You aren't following anyone yet. Visit {public} or use search to get started and meet other users.",
|
||||||
|
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
|
||||||
|
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
|
||||||
|
"follow_request.authorize": "Authorize",
|
||||||
|
"follow_request.reject": "Rejec",
|
||||||
|
"getting_started.apps": "Various apps are available",
|
||||||
|
"getting_started.heading": "Getting started",
|
||||||
|
"getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}. {apps}.",
|
||||||
|
"home.column_settings.advanced": "Advanced",
|
||||||
|
"home.column_settings.basic": "Basic",
|
||||||
|
"home.column_settings.filter_regex": "Filter out by regular expressions",
|
||||||
|
"home.column_settings.show_reblogs": "Show boosts",
|
||||||
|
"home.column_settings.show_replies": "Show replies",
|
||||||
|
"home.settings": "Column settings",
|
||||||
|
"lightbox.close": "Close",
|
||||||
|
"loading_indicator.label": "Loading...",
|
||||||
|
"media_gallery.toggle_visible": "Toggle visibility",
|
||||||
|
"missing_indicator.label": "Not found",
|
||||||
|
"navigation_bar.blocks": "Blocked users",
|
||||||
"navigation_bar.community_timeline": "Local timeline",
|
"navigation_bar.community_timeline": "Local timeline",
|
||||||
"navigation_bar.public_timeline": "Federated timeline",
|
"navigation_bar.edit_profile": "Edit profile",
|
||||||
|
"navigation_bar.favourites": "Favourites",
|
||||||
|
"navigation_bar.follow_requests": "Follow requests",
|
||||||
|
"navigation_bar.info": "Extended information",
|
||||||
"navigation_bar.logout": "Logout",
|
"navigation_bar.logout": "Logout",
|
||||||
"reply_indicator.cancel": "Cancel",
|
"navigation_bar.preferences": "Preferences",
|
||||||
"search.placeholder": "Search",
|
"navigation_bar.public_timeline": "Federated timeline",
|
||||||
"search.account": "Account",
|
|
||||||
"search.hashtag": "Hashtag",
|
|
||||||
"upload_button.label": "Add media",
|
|
||||||
"upload_form.undo": "Undo",
|
|
||||||
"notification.follow": "{name} followed you",
|
|
||||||
"notification.favourite": "{name} favourited your status",
|
"notification.favourite": "{name} favourited your status",
|
||||||
|
"notification.follow": "{name} followed you",
|
||||||
"notification.reblog": "{name} boosted your status",
|
"notification.reblog": "{name} boosted your status",
|
||||||
"notification.mention": "{name} mentioned you",
|
"notifications.clear_confirmation": "Are you sure you want to clear all your notifications?",
|
||||||
|
"notifications.clear": "Clear notifications",
|
||||||
"notifications.column_settings.alert": "Desktop notifications",
|
"notifications.column_settings.alert": "Desktop notifications",
|
||||||
"notifications.column_settings.show": "Show in column",
|
|
||||||
"notifications.column_settings.follow": "New followers:",
|
|
||||||
"notifications.column_settings.favourite": "Favourites:",
|
"notifications.column_settings.favourite": "Favourites:",
|
||||||
|
"notifications.column_settings.follow": "New followers:",
|
||||||
"notifications.column_settings.mention": "Mentions:",
|
"notifications.column_settings.mention": "Mentions:",
|
||||||
"notifications.column_settings.reblog": "Boosts:",
|
"notifications.column_settings.reblog": "Boosts:",
|
||||||
|
"notifications.column_settings.show": "Show in column",
|
||||||
|
"notifications.column_settings.sound": "Play sound",
|
||||||
|
"notifications.settings": "Column settings",
|
||||||
|
"privacy.change": "Adjust status privacy",
|
||||||
|
"privacy.direct.long": "Post to mentioned users only",
|
||||||
|
"privacy.direct.short": "Direct",
|
||||||
|
"privacy.private.long": "Post to followers only",
|
||||||
|
"privacy.private.short": "Private",
|
||||||
|
"privacy.public.long": "Post to public timelines",
|
||||||
|
"privacy.public.short": "Public",
|
||||||
|
"privacy.unlisted.long": "Do not show in public timelines",
|
||||||
|
"privacy.unlisted.short": "Unlisted",
|
||||||
|
"reply_indicator.cancel": "Cancel",
|
||||||
|
"report.heading": "New report",
|
||||||
|
"report.placeholder": "Additional comments",
|
||||||
|
"report.submit": "Submit",
|
||||||
|
"report.target": "Reporting",
|
||||||
|
"search_results.total": "{count} {count, plural, one {result} other {results}}",
|
||||||
|
"search.placeholder": "Search",
|
||||||
|
"search.status_by": "Status by {name}",
|
||||||
|
"status.delete": "Delete",
|
||||||
|
"status.favourite": "Favourite",
|
||||||
|
"status.load_more": "Load more",
|
||||||
|
"status.media_hidden": "Media hidden",
|
||||||
|
"status.mention": "Mention @{name}",
|
||||||
|
"status.open": "Expand this status",
|
||||||
|
"status.reblog": "Boost",
|
||||||
|
"status.reblogged_by": "{name} boosted",
|
||||||
|
"status.reply": "Reply",
|
||||||
|
"status.report": "Report @{name}",
|
||||||
|
"status.sensitive_toggle": "Click to view",
|
||||||
|
"status.sensitive_warning": "Sensitive content",
|
||||||
|
"status.show_less": "Show less",
|
||||||
|
"status.show_more": "Show more",
|
||||||
|
"tabs_bar.compose": "Compose",
|
||||||
|
"tabs_bar.federated_timeline": "Federated",
|
||||||
|
"tabs_bar.home": "Home",
|
||||||
|
"tabs_bar.local_timeline": "Local",
|
||||||
|
"tabs_bar.notifications": "Notifications",
|
||||||
|
"upload_area.title": "Drag & drop to upload",
|
||||||
|
"upload_button.label": "Add media",
|
||||||
|
"upload_form.undo": "Undo",
|
||||||
|
"upload_progress.label": "Uploading...",
|
||||||
|
"video_player.toggle_sound": "Toggle sound",
|
||||||
|
"video_player.toggle_visible": "Toggle visibility",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default en;
|
export default en;
|
||||||
|
|
|
@ -11,7 +11,7 @@ import eo from './eo';
|
||||||
import ru from './ru';
|
import ru from './ru';
|
||||||
import ja from './ja';
|
import ja from './ja';
|
||||||
import zh_hk from './zh-hk';
|
import zh_hk from './zh-hk';
|
||||||
|
import bg from './bg';
|
||||||
|
|
||||||
const locales = {
|
const locales = {
|
||||||
en,
|
en,
|
||||||
|
@ -27,6 +27,7 @@ const locales = {
|
||||||
ru,
|
ru,
|
||||||
ja,
|
ja,
|
||||||
'zh-HK': zh_hk,
|
'zh-HK': zh_hk,
|
||||||
|
bg,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function getMessagesForLocale (locale) {
|
export default function getMessagesForLocale (locale) {
|
||||||
|
|
|
@ -39,8 +39,8 @@ const ja = {
|
||||||
"tabs_bar.compose": "投稿",
|
"tabs_bar.compose": "投稿",
|
||||||
"tabs_bar.home": "ホーム",
|
"tabs_bar.home": "ホーム",
|
||||||
"tabs_bar.mentions": "返信",
|
"tabs_bar.mentions": "返信",
|
||||||
"tabs_bar.local_timeline": "ローカルTL",
|
"tabs_bar.local_timeline": "ローカル",
|
||||||
"tabs_bar.federated_timeline": "連合TL",
|
"tabs_bar.federated_timeline": "連合",
|
||||||
"tabs_bar.notifications": "通知",
|
"tabs_bar.notifications": "通知",
|
||||||
"compose_form.placeholder": "今なにしてる?",
|
"compose_form.placeholder": "今なにしてる?",
|
||||||
"compose_form.publish": "トゥート",
|
"compose_form.publish": "トゥート",
|
||||||
|
|
|
@ -14,59 +14,115 @@ const pt = {
|
||||||
"status.show_less": "Mostrar menos",
|
"status.show_less": "Mostrar menos",
|
||||||
"status.open": "Expandir",
|
"status.open": "Expandir",
|
||||||
"status.report": "Reportar @{name}",
|
"status.report": "Reportar @{name}",
|
||||||
|
"status.load_more": "Carregar mais",
|
||||||
|
"status.media_hidden": "Media escondida",
|
||||||
"video_player.toggle_sound": "Ligar/Desligar som",
|
"video_player.toggle_sound": "Ligar/Desligar som",
|
||||||
|
"video_player.toggle_visible": "Ligar/Desligar vídeo",
|
||||||
"account.mention": "Mencionar @{name}",
|
"account.mention": "Mencionar @{name}",
|
||||||
"account.edit_profile": "Editar perfil",
|
"account.edit_profile": "Editar perfil",
|
||||||
"account.unblock": "Não bloquear @{name}",
|
"account.unblock": "Não bloquear @{name}",
|
||||||
"account.unfollow": "Não seguir",
|
"account.unfollow": "Não seguir",
|
||||||
"account.block": "Bloquear @{name}",
|
"account.block": "Bloquear @{name}",
|
||||||
|
"account.mute": "Mute",
|
||||||
|
"account.unmute": "Remover Mute",
|
||||||
"account.follow": "Seguir",
|
"account.follow": "Seguir",
|
||||||
"account.posts": "Posts",
|
"account.posts": "Posts",
|
||||||
"account.follows": "Segue",
|
"account.follows": "Segue",
|
||||||
"account.followers": "Seguidores",
|
"account.followers": "Seguidores",
|
||||||
"account.follows_you": "É teu seguidor",
|
"account.follows_you": "É teu seguidor",
|
||||||
"account.requested": "A aguardar aprovação",
|
"account.requested": "A aguardar aprovação",
|
||||||
|
"account.report": "Denunciar",
|
||||||
|
"account.disclaimer": "Essa conta está localizado em outra instância. Os nomes podem ser maiores.",
|
||||||
"getting_started.heading": "Primeiros passos",
|
"getting_started.heading": "Primeiros passos",
|
||||||
"getting_started.about_addressing": "Podes seguir pessoas se sabes o nome de usuário deles e o domínio em que estão colocando um endereço similar a e-mail no campo no topo da barra lateral.",
|
"getting_started.about_addressing": "Podes seguir pessoas se sabes o nome de usuário deles e o domínio em que estão colocando um endereço similar a e-mail no campo no topo da barra lateral.",
|
||||||
"getting_started.about_shortcuts": "Se o usuário alvo está no mesmo domínio, só o nome funcionará. A mesma regra se aplica a mencionar pessoas nas postagens.",
|
"getting_started.about_shortcuts": "Se o usuário alvo está no mesmo domínio, só o nome funcionará. A mesma regra se aplica a mencionar pessoas nas postagens.",
|
||||||
|
"getting_started.about_developer": "Pode seguir o developer deste projecto em Gargron@mastodon.social",
|
||||||
"getting_started.open_source_notice": "Mastodon é software de fonte aberta. Podes contribuir ou repostar problemas no GitHub do projecto: {github}. {apps}.",
|
"getting_started.open_source_notice": "Mastodon é software de fonte aberta. Podes contribuir ou repostar problemas no GitHub do projecto: {github}. {apps}.",
|
||||||
"column.home": "Home",
|
"column.home": "Home",
|
||||||
"column.community": "Local",
|
"column.community": "Local",
|
||||||
"column.public": "Público",
|
"column.public": "Global",
|
||||||
"column.notifications": "Notificações",
|
"column.notifications": "Notificações",
|
||||||
|
"column.blocks": "Utilizadores Bloqueados",
|
||||||
|
"column.favourites": "Favoritos",
|
||||||
|
"column.follow_requests": "Seguidores Pendentes",
|
||||||
|
"empty_column.notifications": "Não tens notificações. Interage com outros utilizadores para iniciar uma conversa.",
|
||||||
|
"empty_column.public": "Não há nada aqui! Escreve algo publicamente ou segue outros utilizadores para ver aqui os conteúdos públicos.",
|
||||||
|
"empty_column.home": "Ainda não segues qualquer utilizador. Visita {public} ou utiliza a pesquisa para procurar outros utilizadores.",
|
||||||
|
"empty_column.home.public_timeline": "global",
|
||||||
|
"empty_column.community": "Ainda não existem conteúdo local para mostrar!",
|
||||||
|
"empty_column.hashtag": "Não existe qualquer conteúdo com essa hashtag",
|
||||||
"tabs_bar.compose": "Criar",
|
"tabs_bar.compose": "Criar",
|
||||||
"tabs_bar.home": "Home",
|
"tabs_bar.home": "Home",
|
||||||
"tabs_bar.mentions": "Menções",
|
"tabs_bar.mentions": "Menções",
|
||||||
"tabs_bar.public": "Público",
|
"tabs_bar.public": "Público",
|
||||||
"tabs_bar.notifications": "Notificações",
|
"tabs_bar.notifications": "Notificações",
|
||||||
|
"tabs_bar.local_timeline": "Local",
|
||||||
|
"tabs_bar.federated_timeline": "Global",
|
||||||
"compose_form.placeholder": "Em que estás a pensar?",
|
"compose_form.placeholder": "Em que estás a pensar?",
|
||||||
"compose_form.publish": "Publicar",
|
"compose_form.publish": "Publicar",
|
||||||
"compose_form.sensitive": "Media com conteúdo sensível",
|
"compose_form.sensitive": "Marcar media como conteúdo sensível",
|
||||||
"compose_form.spoiler": "Esconder texto com aviso",
|
"compose_form.spoiler": "Esconder texto com aviso",
|
||||||
|
"compose_form.spoiler_placeholder": "Aviso",
|
||||||
"compose_form.private": "Tornar privado",
|
"compose_form.private": "Tornar privado",
|
||||||
"compose_form.privacy_disclaimer": "O teu conteúdo privado vai ser partilhado com os utilizadores do {domains}. Confias {domainsCount, plural, one {neste servidor} other {nestes servidores}}? A privacidade só funciona em instâncias do Mastodon. Se {domains} {domainsCount, plural, one {não é uma instância} other {não são instâncias}}, não existem indicadores da privacidade da tua partilha, e podem ser partilhados com outros.",
|
"compose_form.privacy_disclaimer": "O teu conteúdo privado vai ser partilhado com os utilizadores do {domains}. Confias {domainsCount, plural, one {neste servidor} other {nestes servidores}}? A privacidade só funciona em instâncias do Mastodon. Se {domains} {domainsCount, plural, one {não é uma instância} other {não são instâncias}}, não existem indicadores da privacidade da tua partilha, e podem ser partilhados com outros.",
|
||||||
"compose_form.unlisted": "Não mostrar na listagem pública",
|
"compose_form.unlisted": "Não mostrar na listagem pública",
|
||||||
|
"emoji_button.label": "Inserir Emoji",
|
||||||
"navigation_bar.edit_profile": "Editar perfil",
|
"navigation_bar.edit_profile": "Editar perfil",
|
||||||
"navigation_bar.preferences": "Preferências",
|
"navigation_bar.preferences": "Preferências",
|
||||||
"navigation_bar.community_timeline": "Local",
|
"navigation_bar.community_timeline": "Local",
|
||||||
"navigation_bar.public_timeline": "Público",
|
"navigation_bar.public_timeline": "Global",
|
||||||
|
"navigation_bar.blocks": "Utilizadores bloqueados",
|
||||||
|
"navigation_bar.favourites": "Favoritos",
|
||||||
|
"navigation_bar.info": "Mais informações",
|
||||||
"navigation_bar.logout": "Sair",
|
"navigation_bar.logout": "Sair",
|
||||||
|
"navigation_bar.follow_requests": "Seguidores pendentes",
|
||||||
"reply_indicator.cancel": "Cancelar",
|
"reply_indicator.cancel": "Cancelar",
|
||||||
"search.placeholder": "Pesquisar",
|
"search.placeholder": "Pesquisar",
|
||||||
"search.account": "Conta",
|
"search.account": "Conta",
|
||||||
"search.hashtag": "Hashtag",
|
"search.hashtag": "Hashtag",
|
||||||
|
"search_results.total": "{count} {count, plural, one {resultado} other {resultados}}",
|
||||||
|
"search.status_by": "Post de {name}",
|
||||||
"upload_button.label": "Adicionar media",
|
"upload_button.label": "Adicionar media",
|
||||||
"upload_form.undo": "Anular",
|
"upload_form.undo": "Anular",
|
||||||
|
"upload_progress.label": "A gravar…",
|
||||||
|
"upload_area.title": "Arraste e solte para enviar",
|
||||||
"notification.follow": "{name} seguiu-te",
|
"notification.follow": "{name} seguiu-te",
|
||||||
"notification.favourite": "{name} adicionou o teu post aos favoritos",
|
"notification.favourite": "{name} adicionou o teu post aos favoritos",
|
||||||
"notification.reblog": "{name} partilhou o teu post",
|
"notification.reblog": "{name} partilhou o teu post",
|
||||||
"notification.mention": "{name} mencionou-te",
|
"notification.mention": "{name} mencionou-te",
|
||||||
"notifications.column_settings.alert": "Notificações no computador",
|
"notifications.column_settings.alert": "Notificações no computador",
|
||||||
"notifications.column_settings.show": "Mostrar nas colunas",
|
"notifications.column_settings.show": "Mostrar nas colunas",
|
||||||
|
"notifications.column_settings.sound": "Reproduzir som",
|
||||||
"notifications.column_settings.follow": "Novos seguidores:",
|
"notifications.column_settings.follow": "Novos seguidores:",
|
||||||
"notifications.column_settings.favourite": "Favoritos:",
|
"notifications.column_settings.favourite": "Favoritos:",
|
||||||
"notifications.column_settings.mention": "Menções:",
|
"notifications.column_settings.mention": "Menções:",
|
||||||
"notifications.column_settings.reblog": "Partilhas:",
|
"notifications.column_settings.reblog": "Partilhas:",
|
||||||
|
"notifications.clear": "Limpar notificações",
|
||||||
|
"notifications.clear_confirmation": "Queres mesmo limpar todas as notificações?",
|
||||||
|
"notifications.settings": "Parâmetros da lista de Notificações",
|
||||||
|
"privacy.public.short": "Público",
|
||||||
|
"privacy.public.long": "Publicar em todos os feeds",
|
||||||
|
"privacy.unlisted.short": "Não listar",
|
||||||
|
"privacy.unlisted.long": "Não publicar nos feeds públicos",
|
||||||
|
"privacy.private.short": "Privado",
|
||||||
|
"privacy.private.long": "Apenas para os seguidores",
|
||||||
|
"privacy.direct.short": "Directo",
|
||||||
|
"privacy.direct.long": "Apenas para utilizadores mencionados",
|
||||||
|
"privacy.change": "Ajustar a privacidade da mensagem",
|
||||||
|
"media_gallery.toggle_visible": "Modificar a visibilidade",
|
||||||
|
"missing_indicator.label": "Não encontrado",
|
||||||
|
"follow_request.authorize": "Autorizar",
|
||||||
|
"follow_request.reject": "Rejeitar",
|
||||||
|
"home.settings": "Parâmetros da coluna Home",
|
||||||
|
"home.column_settings.basic": "Básico",
|
||||||
|
"home.column_settings.show_reblogs": "Mostrar as partilhas",
|
||||||
|
"home.column_settings.show_replies": "Mostrar as respostas",
|
||||||
|
"home.column_settings.advanced": "Avançadas",
|
||||||
|
"home.column_settings.filter_regex": "Filtrar com uma expressão regular",
|
||||||
|
"report.heading": "Nova denuncia",
|
||||||
|
"report.placeholder": "Comentários adicionais",
|
||||||
|
"report.submit": "Enviar",
|
||||||
|
"report.target": "Denunciar"
|
||||||
};
|
};
|
||||||
|
|
||||||
export default pt;
|
export default pt;
|
||||||
|
|
|
@ -10,22 +10,29 @@ const ru = {
|
||||||
"status.reblogged_by": "{name} продвинул(а)",
|
"status.reblogged_by": "{name} продвинул(а)",
|
||||||
"status.sensitive_warning": "Чувствительный контент",
|
"status.sensitive_warning": "Чувствительный контент",
|
||||||
"status.sensitive_toggle": "Нажмите для просмотра",
|
"status.sensitive_toggle": "Нажмите для просмотра",
|
||||||
|
"status.show_more": "Развернуть",
|
||||||
|
"status.show_less": "Свернуть",
|
||||||
|
"status.open": "Развернуть статус",
|
||||||
|
"status.report": "Пожаловаться",
|
||||||
|
"status.load_more": "Показать еще",
|
||||||
"video_player.toggle_sound": "Вкл./выкл. звук",
|
"video_player.toggle_sound": "Вкл./выкл. звук",
|
||||||
"account.mention": "Упомянуть @{name}",
|
"account.mention": "Упомянуть",
|
||||||
"account.edit_profile": "Изменить профиль",
|
"account.edit_profile": "Изменить профиль",
|
||||||
"account.unblock": "Разблокировать @{name}",
|
"account.unblock": "Разблокировать",
|
||||||
"account.unfollow": "Отписаться",
|
"account.unfollow": "Отписаться",
|
||||||
"account.block": "Блокировать @{name}",
|
"account.block": "Блокировать",
|
||||||
|
"account.mute": "Заглушить",
|
||||||
"account.follow": "Подписаться",
|
"account.follow": "Подписаться",
|
||||||
"account.posts": "Посты",
|
"account.posts": "Посты",
|
||||||
"account.follows": "Подписки",
|
"account.follows": "Подписки",
|
||||||
"account.followers": "Подписчики",
|
"account.followers": "Подписаны",
|
||||||
"account.follows_you": "Подписан(а) на Вас",
|
"account.follows_you": "Подписан(а) на Вас",
|
||||||
"account.requested": "Ожидает подтверждения",
|
"account.requested": "Ожидает подтверждения",
|
||||||
"getting_started.heading": "Добро пожаловать",
|
"getting_started.heading": "Добро пожаловать",
|
||||||
"getting_started.about_addressing": "Вы можете подписаться на человека, зная имя пользователя и домен, на котором он находится, введя e-mail-подобный адрес в форму поиска.",
|
"getting_started.about_addressing": "Вы можете подписаться на человека, зная имя пользователя и домен, на котором он находится, введя e-mail-подобный адрес в форму поиска.",
|
||||||
"getting_started.about_shortcuts": "Если пользователь находится на одном с Вами домене, можно использовать только имя. То же правило применимо к упоминанию пользователей в статусах.",
|
"getting_started.about_shortcuts": "Если пользователь находится на одном с Вами домене, можно использовать только имя. То же правило применимо к упоминанию пользователей в статусах.",
|
||||||
"getting_started.open_source_notice": "Mastodon - программа с открытым исходным кодом. Вы можете помочь проекту или сообщить о проблемах на GitHub по адресу {github}. {apps}.",
|
"getting_started.open_source_notice": "Mastodon - программа с открытым исходным кодом. Вы можете помочь проекту или сообщить о проблемах на GitHub по адресу {github}. {apps}.",
|
||||||
|
"getting_started.apps": "Доступны различные приложения.",
|
||||||
"column.home": "Главная",
|
"column.home": "Главная",
|
||||||
"column.community": "Локальная лента",
|
"column.community": "Локальная лента",
|
||||||
"column.public": "Глобальная лента",
|
"column.public": "Глобальная лента",
|
||||||
|
@ -36,7 +43,7 @@ const ru = {
|
||||||
"tabs_bar.public": "Глобальная лента",
|
"tabs_bar.public": "Глобальная лента",
|
||||||
"tabs_bar.notifications": "Уведомления",
|
"tabs_bar.notifications": "Уведомления",
|
||||||
"compose_form.placeholder": "О чем Вы думаете?",
|
"compose_form.placeholder": "О чем Вы думаете?",
|
||||||
"compose_form.publish": "Протрубить",
|
"compose_form.publish": "Трубить",
|
||||||
"compose_form.sensitive": "Отметить как чувствительный контент",
|
"compose_form.sensitive": "Отметить как чувствительный контент",
|
||||||
"compose_form.spoiler": "Скрыть текст за предупреждением",
|
"compose_form.spoiler": "Скрыть текст за предупреждением",
|
||||||
"compose_form.private": "Отметить как приватное",
|
"compose_form.private": "Отметить как приватное",
|
||||||
|
@ -47,6 +54,9 @@ const ru = {
|
||||||
"navigation_bar.community_timeline": "Локальная лента",
|
"navigation_bar.community_timeline": "Локальная лента",
|
||||||
"navigation_bar.public_timeline": "Глобальная лента",
|
"navigation_bar.public_timeline": "Глобальная лента",
|
||||||
"navigation_bar.logout": "Выйти",
|
"navigation_bar.logout": "Выйти",
|
||||||
|
"navigation_bar.info": "Об узле",
|
||||||
|
"navigation_bar.favourites": "Понравившееся",
|
||||||
|
"navigation_bar.blocks": "Список блокировки",
|
||||||
"reply_indicator.cancel": "Отмена",
|
"reply_indicator.cancel": "Отмена",
|
||||||
"search.placeholder": "Поиск",
|
"search.placeholder": "Поиск",
|
||||||
"search.account": "Аккаунт",
|
"search.account": "Аккаунт",
|
||||||
|
@ -57,12 +67,35 @@ const ru = {
|
||||||
"notification.favourite": "{name} понравился Ваш статус",
|
"notification.favourite": "{name} понравился Ваш статус",
|
||||||
"notification.reblog": "{name} продвинул(а) Ваш статус",
|
"notification.reblog": "{name} продвинул(а) Ваш статус",
|
||||||
"notification.mention": "{name} упомянул(а) Вас",
|
"notification.mention": "{name} упомянул(а) Вас",
|
||||||
|
"home.settings": "Настройки колонки",
|
||||||
|
"home.column_settings.basic": "Основные",
|
||||||
|
"home.column_settings.advanced": "Дополнительные",
|
||||||
|
"home.column_settings.filter_regex": "Отфильтровать регулярным выражением",
|
||||||
|
"home.column_settings.show_replies": "Показывать продвижения",
|
||||||
|
"home.column_settings.show_replies": "Показывать ответы",
|
||||||
|
"notifications.clear": "Очистить уведомления",
|
||||||
|
"notifications.settings": "Настройки колонки",
|
||||||
"notifications.column_settings.alert": "Десктопные уведомления",
|
"notifications.column_settings.alert": "Десктопные уведомления",
|
||||||
"notifications.column_settings.show": "Показывать в колонке",
|
"notifications.column_settings.show": "Показывать в колонке",
|
||||||
"notifications.column_settings.follow": "Новые подписчики:",
|
"notifications.column_settings.follow": "Новые подписчики:",
|
||||||
"notifications.column_settings.favourite": "Нравится:",
|
"notifications.column_settings.favourite": "Нравится:",
|
||||||
"notifications.column_settings.mention": "Упоминания:",
|
"notifications.column_settings.mention": "Упоминания:",
|
||||||
"notifications.column_settings.reblog": "Продвижения:",
|
"notifications.column_settings.reblog": "Продвижения:",
|
||||||
|
"notifications.column_settings.sound": "Проигрывать звук",
|
||||||
|
"empty_column.notifications": "У Вас еще нет уведомлений. Заведите знакомство с другими пользователями, чтобы начать разговор.",
|
||||||
|
"empty_column.hashtag": "Статусов с таким хэштегом еще не существует.",
|
||||||
|
"empty_column.community": "Локальная лента пуста. Напишите что-нибудь, чтобы разогреть народ!",
|
||||||
|
"empty_column.public": "Здесь ничего нет! Опубликуйте что-нибудь или подпишитесь на пользователей с других узлов, чтобы заполнить ленту.",
|
||||||
|
"empty_column.home": "Пока Вы ни на кого не подписаны. Полистайте {public} или используйте поиск, чтобы освоиться и завести новые знакомства.",
|
||||||
|
"empty_column.home.public_timeline": "публичные ленты",
|
||||||
|
"privacy.public.short": "Публичный",
|
||||||
|
"privacy.public.long": "Показать в публичных лентах",
|
||||||
|
"privacy.unlisted.short": "Скрытый",
|
||||||
|
"privacy.unlisted.long": "Не показывать в лентах",
|
||||||
|
"privacy.private.short": "Приватный",
|
||||||
|
"privacy.private.long": "Показать только подписчикам",
|
||||||
|
"privacy.direct.short": "Направленный",
|
||||||
|
"privacy.direct.long": "Показать только упомянутым",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ru;
|
export default ru;
|
||||||
|
|
|
@ -88,7 +88,7 @@ code {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=text], input[type=email], input[type=password], textarea {
|
input[type=text], input[type=number], input[type=email], input[type=password], textarea {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border: 0;
|
border: 0;
|
||||||
|
|
|
@ -2,49 +2,29 @@
|
||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class AccountsController < BaseController
|
class AccountsController < BaseController
|
||||||
before_action :set_account, except: :index
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@accounts = Account.alphabetic.page(params[:page])
|
@accounts = filtered_accounts.page(params[:page])
|
||||||
|
|
||||||
@accounts = @accounts.local if params[:local].present?
|
|
||||||
@accounts = @accounts.remote if params[:remote].present?
|
|
||||||
@accounts = @accounts.where(domain: params[:by_domain]) if params[:by_domain].present?
|
|
||||||
@accounts = @accounts.silenced if params[:silenced].present?
|
|
||||||
@accounts = @accounts.recent if params[:recent].present?
|
|
||||||
@accounts = @accounts.suspended if params[:suspended].present?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def show; end
|
def show
|
||||||
|
@account = Account.find(params[:id])
|
||||||
def suspend
|
|
||||||
Admin::SuspensionWorker.perform_async(@account.id)
|
|
||||||
redirect_to admin_accounts_path
|
|
||||||
end
|
|
||||||
|
|
||||||
def unsuspend
|
|
||||||
@account.update(suspended: false)
|
|
||||||
redirect_to admin_accounts_path
|
|
||||||
end
|
|
||||||
|
|
||||||
def silence
|
|
||||||
@account.update(silenced: true)
|
|
||||||
redirect_to admin_accounts_path
|
|
||||||
end
|
|
||||||
|
|
||||||
def unsilence
|
|
||||||
@account.update(silenced: false)
|
|
||||||
redirect_to admin_accounts_path
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_account
|
def filtered_accounts
|
||||||
@account = Account.find(params[:id])
|
AccountFilter.new(filter_params).results
|
||||||
end
|
end
|
||||||
|
|
||||||
def account_params
|
def filter_params
|
||||||
params.require(:account).permit(:silenced, :suspended)
|
params.permit(
|
||||||
|
:local,
|
||||||
|
:remote,
|
||||||
|
:by_domain,
|
||||||
|
:silenced,
|
||||||
|
:recent,
|
||||||
|
:suspended
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
class SilencesController < BaseController
|
||||||
|
before_action :set_account
|
||||||
|
|
||||||
|
def create
|
||||||
|
@account.update(silenced: true)
|
||||||
|
redirect_to admin_accounts_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@account.update(silenced: false)
|
||||||
|
redirect_to admin_accounts_path
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_account
|
||||||
|
@account = Account.find(params[:account_id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,23 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
class SuspensionsController < BaseController
|
||||||
|
before_action :set_account
|
||||||
|
|
||||||
|
def create
|
||||||
|
Admin::SuspensionWorker.perform_async(@account.id)
|
||||||
|
redirect_to admin_accounts_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@account.update(suspended: false)
|
||||||
|
redirect_to admin_accounts_path
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_account
|
||||||
|
@account = Account.find(params[:account_id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -6,7 +6,7 @@ module Settings
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
|
|
||||||
def index
|
def index
|
||||||
export_data = Export.new(export_accounts).to_csv
|
@export = Export.new(current_account)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.csv { send_data export_data, filename: export_filename }
|
format.csv { send_data export_data, filename: export_filename }
|
||||||
|
|
|
@ -5,8 +5,8 @@ module Settings
|
||||||
class BlockedAccountsController < BaseController
|
class BlockedAccountsController < BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def export_accounts
|
def export_data
|
||||||
current_account.blocking
|
@export.to_blocked_accounts_csv
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,8 +5,8 @@ module Settings
|
||||||
class FollowingAccountsController < BaseController
|
class FollowingAccountsController < BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def export_accounts
|
def export_data
|
||||||
current_account.following
|
@export.to_following_accounts_csv
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,8 +5,8 @@ module Settings
|
||||||
class MutedAccountsController < BaseController
|
class MutedAccountsController < BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def export_accounts
|
def export_data
|
||||||
current_account.muting
|
@export.to_muted_accounts_csv
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,9 +6,6 @@ class Settings::ExportsController < ApplicationController
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@total_storage = current_account.media_attachments.sum(:file_file_size)
|
@export = Export.new(current_account)
|
||||||
@total_follows = current_account.following.count
|
|
||||||
@total_blocks = current_account.blocking.count
|
|
||||||
@total_mutes = current_account.muting.count
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module WellKnown
|
||||||
|
class HostMetaController < ApplicationController
|
||||||
|
def show
|
||||||
|
@webfinger_template = "#{webfinger_url}?resource={uri}"
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.xml { render content_type: 'application/xrd+xml' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,43 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module WellKnown
|
||||||
|
class WebfingerController < ApplicationController
|
||||||
|
def show
|
||||||
|
@account = Account.find_local!(username_from_resource)
|
||||||
|
@canonical_account_uri = @account.to_webfinger_s
|
||||||
|
@magic_key = pem_to_magic_key(@account.keypair.public_key)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.xml { render content_type: 'application/xrd+xml' }
|
||||||
|
format.json { render content_type: 'application/jrd+json' }
|
||||||
|
end
|
||||||
|
rescue ActiveRecord::RecordNotFound
|
||||||
|
head 404
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def username_from_resource
|
||||||
|
WebfingerResource.new(resource_param).username
|
||||||
|
end
|
||||||
|
|
||||||
|
def pem_to_magic_key(public_key)
|
||||||
|
modulus, exponent = [public_key.n, public_key.e].map do |component|
|
||||||
|
result = []
|
||||||
|
|
||||||
|
until component.zero?
|
||||||
|
result << [component % 256].pack('C')
|
||||||
|
component >>= 8
|
||||||
|
end
|
||||||
|
|
||||||
|
result.reverse.join
|
||||||
|
end
|
||||||
|
|
||||||
|
(['RSA'] + [modulus, exponent].map { |n| Base64.urlsafe_encode64(n) }).join('.')
|
||||||
|
end
|
||||||
|
|
||||||
|
def resource_param
|
||||||
|
params.require(:resource)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,55 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class XrdController < ApplicationController
|
|
||||||
before_action :set_default_format_xml, only: :host_meta
|
|
||||||
|
|
||||||
def host_meta
|
|
||||||
@webfinger_template = "#{webfinger_url}?resource={uri}"
|
|
||||||
|
|
||||||
respond_to do |format|
|
|
||||||
format.xml { render content_type: 'application/xrd+xml' }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def webfinger
|
|
||||||
@account = Account.find_local!(username_from_resource)
|
|
||||||
@canonical_account_uri = @account.to_webfinger_s
|
|
||||||
@magic_key = pem_to_magic_key(@account.keypair.public_key)
|
|
||||||
|
|
||||||
respond_to do |format|
|
|
||||||
format.xml { render content_type: 'application/xrd+xml' }
|
|
||||||
format.json { render content_type: 'application/jrd+json' }
|
|
||||||
end
|
|
||||||
rescue ActiveRecord::RecordNotFound
|
|
||||||
head 404
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_default_format_xml
|
|
||||||
request.format = 'xml' if request.headers['HTTP_ACCEPT'].nil? && params[:format].nil?
|
|
||||||
end
|
|
||||||
|
|
||||||
def username_from_resource
|
|
||||||
WebfingerResource.new(resource_param).username
|
|
||||||
end
|
|
||||||
|
|
||||||
def pem_to_magic_key(public_key)
|
|
||||||
modulus, exponent = [public_key.n, public_key.e].map do |component|
|
|
||||||
result = []
|
|
||||||
|
|
||||||
until component.zero?
|
|
||||||
result << [component % 256].pack('C')
|
|
||||||
component >>= 8
|
|
||||||
end
|
|
||||||
|
|
||||||
result.reverse.join
|
|
||||||
end
|
|
||||||
|
|
||||||
(['RSA'] + [modulus, exponent].map { |n| Base64.urlsafe_encode64(n) }).join('.')
|
|
||||||
end
|
|
||||||
|
|
||||||
def resource_param
|
|
||||||
params.require(:resource)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -16,6 +16,7 @@ module SettingsHelper
|
||||||
ja: '日本語',
|
ja: '日本語',
|
||||||
'zh-CN': '简体中文',
|
'zh-CN': '简体中文',
|
||||||
'zh-HK': '繁體中文(香港)',
|
'zh-HK': '繁體中文(香港)',
|
||||||
|
bg: 'Български',
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
def human_locale(locale)
|
def human_locale(locale)
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AccountFilter
|
||||||
|
attr_reader :params
|
||||||
|
|
||||||
|
def initialize(params)
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def results
|
||||||
|
scope = Account.alphabetic
|
||||||
|
params.each do |key, value|
|
||||||
|
scope = scope.merge scope_for(key, value)
|
||||||
|
end
|
||||||
|
scope
|
||||||
|
end
|
||||||
|
|
||||||
|
def scope_for(key, value)
|
||||||
|
case key
|
||||||
|
when /local/
|
||||||
|
Account.local
|
||||||
|
when /remote/
|
||||||
|
Account.remote
|
||||||
|
when /by_domain/
|
||||||
|
Account.where(domain: value)
|
||||||
|
when /silenced/
|
||||||
|
Account.silenced
|
||||||
|
when /recent/
|
||||||
|
Account.recent
|
||||||
|
when /suspended/
|
||||||
|
Account.suspended
|
||||||
|
else
|
||||||
|
raise "Unknown filter: #{key}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,13 +2,43 @@
|
||||||
require 'csv'
|
require 'csv'
|
||||||
|
|
||||||
class Export
|
class Export
|
||||||
attr_reader :accounts
|
attr_reader :account
|
||||||
|
|
||||||
def initialize(accounts)
|
def initialize(account)
|
||||||
@accounts = accounts
|
@account = account
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_csv
|
def to_blocked_accounts_csv
|
||||||
|
to_csv account.blocking
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_muted_accounts_csv
|
||||||
|
to_csv account.muting
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_following_accounts_csv
|
||||||
|
to_csv account.following
|
||||||
|
end
|
||||||
|
|
||||||
|
def total_storage
|
||||||
|
account.media_attachments.sum(:file_file_size)
|
||||||
|
end
|
||||||
|
|
||||||
|
def total_follows
|
||||||
|
account.following.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def total_blocks
|
||||||
|
account.blocking.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def total_mutes
|
||||||
|
account.muting.count
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def to_csv(accounts)
|
||||||
CSV.generate do |csv|
|
CSV.generate do |csv|
|
||||||
accounts.each do |account|
|
accounts.each do |account|
|
||||||
csv << [(account.local? ? account.local_username_and_domain : account.acct)]
|
csv << [(account.local? ? account.local_username_and_domain : account.acct)]
|
||||||
|
|
|
@ -62,11 +62,11 @@
|
||||||
= number_to_human_size @account.media_attachments.sum('file_file_size')
|
= number_to_human_size @account.media_attachments.sum('file_file_size')
|
||||||
|
|
||||||
- if @account.silenced?
|
- if @account.silenced?
|
||||||
= link_to 'Undo silence', unsilence_admin_account_path(@account.id), method: :post, class: 'button'
|
= link_to 'Undo silence', admin_account_silence_path(@account.id), method: :delete, class: 'button'
|
||||||
- else
|
- else
|
||||||
= link_to 'Silence', silence_admin_account_path(@account.id), method: :post, class: 'button'
|
= link_to 'Silence', admin_account_silence_path(@account.id), method: :post, class: 'button'
|
||||||
|
|
||||||
- if @account.suspended?
|
- if @account.suspended?
|
||||||
= link_to 'Undo suspension', unsuspend_admin_account_path(@account.id), method: :post, class: 'button'
|
= link_to 'Undo suspension', admin_account_suspension_path(@account.id), method: :delete, class: 'button'
|
||||||
- else
|
- else
|
||||||
= link_to 'Perform full suspension', suspend_admin_account_path(@account.id), method: :post, data: { confirm: 'Are you sure?' }, class: 'button'
|
= link_to 'Perform full suspension', admin_account_suspension_path(@account.id), method: :post, data: { confirm: 'Are you sure?' }, class: 'button'
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
= t('auth.login')
|
= t('auth.login')
|
||||||
|
|
||||||
= simple_form_for(resource, as: resource_name, url: session_path(resource_name), method: :post) do |f|
|
= simple_form_for(resource, as: resource_name, url: session_path(resource_name), method: :post) do |f|
|
||||||
= f.input :otp_attempt, placeholder: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt') }, required: true, autofocus: true, autocomplete: 'off'
|
= f.input :otp_attempt, type: :number, placeholder: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt') }, required: true, autofocus: true, autocomplete: 'off'
|
||||||
|
|
||||||
.actions
|
.actions
|
||||||
= f.button :button, t('auth.login'), type: :submit
|
= f.button :button, t('auth.login'), type: :submit
|
||||||
|
|
|
@ -5,17 +5,17 @@
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%th= t('exports.storage')
|
%th= t('exports.storage')
|
||||||
%td= number_to_human_size @total_storage
|
%td= number_to_human_size @export.total_storage
|
||||||
%td
|
%td
|
||||||
%tr
|
%tr
|
||||||
%th= t('exports.follows')
|
%th= t('exports.follows')
|
||||||
%td= @total_follows
|
%td= @export.total_follows
|
||||||
%td= table_link_to 'download', t('exports.csv'), settings_exports_follows_path(format: :csv)
|
%td= table_link_to 'download', t('exports.csv'), settings_exports_follows_path(format: :csv)
|
||||||
%tr
|
%tr
|
||||||
%th= t('exports.blocks')
|
%th= t('exports.blocks')
|
||||||
%td= @total_blocks
|
%td= @export.total_blocks
|
||||||
%td= table_link_to 'download', t('exports.csv'), settings_exports_blocks_path(format: :csv)
|
%td= table_link_to 'download', t('exports.csv'), settings_exports_blocks_path(format: :csv)
|
||||||
%tr
|
%tr
|
||||||
%th= t('exports.mutes')
|
%th= t('exports.mutes')
|
||||||
%td= @total_mutes
|
%td= @export.total_mutes
|
||||||
%td= table_link_to 'download', t('exports.csv'), settings_exports_mutes_path(format: :csv)
|
%td= table_link_to 'download', t('exports.csv'), settings_exports_mutes_path(format: :csv)
|
||||||
|
|
|
@ -27,6 +27,7 @@ module Mastodon
|
||||||
|
|
||||||
config.i18n.available_locales = [
|
config.i18n.available_locales = [
|
||||||
:en,
|
:en,
|
||||||
|
:bg,
|
||||||
:de,
|
:de,
|
||||||
:eo,
|
:eo,
|
||||||
:es,
|
:es,
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
---
|
||||||
|
bg:
|
||||||
|
about:
|
||||||
|
about_mastodon: Mastodon е <em>безплатен</em> сървър с <em>отворен код</em> за социални мрежи. Като <em>децентрализирана</em> алтернатива на комерсиалните платформи, той позволява избягването на риска от монополизация на твоята комуникация от единични компании. Изберете си сървър, на който се доверявате, и ще можете да контактувате с всички останали. Всеки може да пусне Mastodon и лесно да вземе участие в <em>социалната мрежа</em>.
|
||||||
|
about_this: За тази инстанция
|
||||||
|
apps: Приложения
|
||||||
|
business_email: 'Служебен e-mail:'
|
||||||
|
closed_registrations: В момента регистрациите за тази инстанция са затворени.
|
||||||
|
contact: За контакти
|
||||||
|
description_headline: Какво е %{domain}?
|
||||||
|
domain_count_after: други инстанции
|
||||||
|
domain_count_before: Свързани към
|
||||||
|
features:
|
||||||
|
api: Отворено API за приложения и услуги
|
||||||
|
blocks: Богат на инструменти за блокиране и заглушаване
|
||||||
|
characters: Публикации от 500 символа
|
||||||
|
chronology: Публикациите се показват хронологично
|
||||||
|
ethics: 'Етичен дизайн: без реклами и проследяване'
|
||||||
|
gifv: GIFV комплекти и кратки видео клипове
|
||||||
|
privacy: Настройване на поверителността за всяка публикация
|
||||||
|
public: Публични канали
|
||||||
|
features_headline: Какво откроява Mastodon
|
||||||
|
get_started: Първи стъпки
|
||||||
|
links: Връзки
|
||||||
|
other_instances: Други инстанции
|
||||||
|
source_code: Програмен код
|
||||||
|
status_count_after: публикации
|
||||||
|
status_count_before: Написали
|
||||||
|
terms: Условия
|
||||||
|
user_count_after: потребители
|
||||||
|
user_count_before: Дом на
|
||||||
|
accounts:
|
||||||
|
follow: Последвай
|
||||||
|
followers: Последователи
|
||||||
|
following: Следва
|
||||||
|
nothing_here: Тук няма никого!
|
||||||
|
people_followed_by: Хора, които %{name} следва
|
||||||
|
people_who_follow: Хора, които следват %{name}
|
||||||
|
posts: Публикации
|
||||||
|
remote_follow: Последвай
|
||||||
|
unfollow: Не следвай
|
||||||
|
application_mailer:
|
||||||
|
settings: 'Промяна на предпочитанията за e-mail: %{link}'
|
||||||
|
signature: Mastodon известия от %{instance}
|
||||||
|
view: 'Преглед:'
|
||||||
|
applications:
|
||||||
|
invalid_url: Предоставеният URL е невалиден
|
||||||
|
auth:
|
||||||
|
change_password: Идентификационни данни
|
||||||
|
didnt_get_confirmation: Не получих инструкции за потвърждение
|
||||||
|
forgot_password: Забравих си паролата
|
||||||
|
login: Влизане
|
||||||
|
logout: Излизане
|
||||||
|
register: Регистрация
|
||||||
|
resend_confirmation: Изпрати отново инструкции за потвърждение
|
||||||
|
reset_password: Подновяване на паролата
|
||||||
|
set_new_password: Задай нова парола
|
||||||
|
authorize_follow:
|
||||||
|
error: Възникна грешка в откриването на потребителя
|
||||||
|
follow: Последвай
|
||||||
|
prompt_html: '(<strong>%{self}</strong>), молбата ти беше изпратена до:'
|
||||||
|
title: Последвай %{acct}
|
||||||
|
datetime:
|
||||||
|
distance_in_words:
|
||||||
|
about_x_hours: "%{count} ч."
|
||||||
|
about_x_months: "%{count} м."
|
||||||
|
about_x_years: "%{count} г."
|
||||||
|
almost_x_years: "%{count} г."
|
||||||
|
half_a_minute: Току-що
|
||||||
|
less_than_x_minutes: "%{count} мин."
|
||||||
|
less_than_x_seconds: Току-що
|
||||||
|
over_x_years: "%{count} г."
|
||||||
|
x_days: "%{count} дни"
|
||||||
|
x_minutes: "%{count} мин."
|
||||||
|
x_months: "%{count} м."
|
||||||
|
x_seconds: "%{count} сек."
|
||||||
|
exports:
|
||||||
|
blocks: Вашите блокирания
|
||||||
|
csv: CSV
|
||||||
|
follows: Вашите следвания
|
||||||
|
storage: Съхранение на мултимедия
|
||||||
|
generic:
|
||||||
|
changes_saved_msg: Успешно запазване на промените!
|
||||||
|
powered_by: поддържано от %{link}
|
||||||
|
save_changes: Запази промените
|
||||||
|
validation_errors:
|
||||||
|
one: Нещо все още не е наред! Моля, прегледай грешката по-долу
|
||||||
|
other: Нещо все още не е наред! Моля, прегледай грешките по-долу
|
||||||
|
imports:
|
||||||
|
preface: Можеш да импортираш някои данни, като например всички хора, които следваш или блокираш в акаунта си на тази инстанция, от файлове, създадени чрез експорт в друга инстанция.
|
||||||
|
success: Твоите данни бяха успешно качени и ще бъдат обработени впоследствие.
|
||||||
|
types:
|
||||||
|
blocking: Списък на блокираните
|
||||||
|
following: Списък на последователите
|
||||||
|
upload: Качване
|
||||||
|
landing_strip_html: <strong>%{name}</strong> е потребител от <strong>%{domain}</strong>. Можеш да ги следваш, или да контактуваш с тях, ако имаш акаунт където и да е из федерираната вселена на Mastodon. Ако нямаш акаунт, можеш да си <a href="%{sign_up_path}">създадеш ето тук</a>.
|
||||||
|
notification_mailer:
|
||||||
|
digest:
|
||||||
|
body: 'Ето кратко резюме на нещата, които се случиха от последното ти посещение в %{instance} на %{since}:'
|
||||||
|
mention: "%{name} те спомена в:"
|
||||||
|
new_followers_summary:
|
||||||
|
one: Имаш един нов последовател! Ура!
|
||||||
|
other: Имаш %{count} нови последователи! Изумително!
|
||||||
|
subject:
|
||||||
|
one: "1 ново известие от последното ти посещение \U0001F418"
|
||||||
|
other: "%{count} нови известия от последното ти посещение \U0001F418"
|
||||||
|
favourite:
|
||||||
|
body: 'Публикацията ти беше харесана от %{name}:'
|
||||||
|
subject: "%{name} хареса твоята публикация"
|
||||||
|
follow:
|
||||||
|
body: "%{name} те последва!"
|
||||||
|
subject: "%{name} те последва"
|
||||||
|
follow_request:
|
||||||
|
body: "%{name} помоли за разрешение да те последва"
|
||||||
|
subject: 'Чакащ последовател: %{name}'
|
||||||
|
mention:
|
||||||
|
body: '%{name} те спомена в:'
|
||||||
|
subject: '%{name} те спомена'
|
||||||
|
reblog:
|
||||||
|
body: 'Твоята публикация беше споделена от %{name}:'
|
||||||
|
subject: "%{name} сподели публикацията ти"
|
||||||
|
pagination:
|
||||||
|
next: Напред
|
||||||
|
prev: Назад
|
||||||
|
remote_follow:
|
||||||
|
acct: Въведи потребителско_име@домейн, от които искаш да следваш
|
||||||
|
missing_resource: Неуспешно търсене на нужния URL за пренасочване за твоя акаунт
|
||||||
|
proceed: Започни следване
|
||||||
|
prompt: 'Ще последваш:'
|
||||||
|
settings:
|
||||||
|
authorized_apps: Упълномощени приложения
|
||||||
|
back: Обратно към Mastodon
|
||||||
|
edit_profile: Редактирай профила си
|
||||||
|
export: Експортиране на данни
|
||||||
|
import: Импортиране
|
||||||
|
preferences: Предпочитания
|
||||||
|
settings: Настройки
|
||||||
|
two_factor_auth: Двустепенно удостоверяване
|
||||||
|
statuses:
|
||||||
|
open_in_web: Отвори в уеб
|
||||||
|
over_character_limit: прехвърлен лимит от %{max} символа
|
||||||
|
show_more: Покажи повече
|
||||||
|
visibilities:
|
||||||
|
private: Покажи само на последователите си
|
||||||
|
public: Публично
|
||||||
|
unlisted: Публично, но не показвай в публичния канал
|
||||||
|
stream_entries:
|
||||||
|
click_to_show: Покажи
|
||||||
|
reblogged: споделено
|
||||||
|
sensitive_content: Деликатно съдържание
|
||||||
|
time:
|
||||||
|
formats:
|
||||||
|
default: "%d %b, %Y, %H:%M"
|
||||||
|
two_factor_auth:
|
||||||
|
description_html: При активация на <strong>двустепенно удостоверяване</strong>, за да влезеш в приложението, ще трябва да използваш телефона си. През него ще се генерира код, който да въвеждаш при влизане.
|
||||||
|
disable: Деактивирай
|
||||||
|
enable: Активирай
|
||||||
|
instructions_html: "<strong>Сканирай този QR код с Google Authenticator или подобно приложение от своя телефон</strong>. Oтсега нататък, това приложение ще генерира код, който ще трябва да въвеждаш при всяко влизане."
|
||||||
|
plaintext_secret_html: "Тайна в обикновен текст: <samp>%{secret}</samp>"
|
||||||
|
warning: Ако не можеш да настроиш приложението за удостверяване сега, избери "Деактивирай". В противен случай, няма да можеш да влезеш в акаунта си.
|
||||||
|
users:
|
||||||
|
invalid_email: E-mail адресът е невалиден
|
||||||
|
invalid_otp_token: Невалиден код
|
||||||
|
will_paginate:
|
||||||
|
page_gap: "…"
|
||||||
|
media_attachments:
|
||||||
|
validations:
|
||||||
|
too_many: Не мога да прикача повече от 4 файла
|
||||||
|
images_and_video: Не мога да прикача видеоклип към публикация, която вече съдържа изображения
|
|
@ -0,0 +1,61 @@
|
||||||
|
---
|
||||||
|
bg:
|
||||||
|
devise:
|
||||||
|
confirmations:
|
||||||
|
confirmed: Твоят профил беше успешно потвърден. Влизането в профила е успешно.
|
||||||
|
send_instructions: Ще получиш писмо с инструкции как да потвърдиш своя профил до няколко минути.
|
||||||
|
send_paranoid_instructions: Ако твоят имейл адрес съществува в базата ни, ще получиш там инструкции как да потвърдиш своя профил.
|
||||||
|
failure:
|
||||||
|
already_authenticated: Вече си вътре в профила си.
|
||||||
|
inactive: Профилът ти все още не е активиран.
|
||||||
|
invalid: Невалиден имейл адрес или парола.
|
||||||
|
last_attempt: Разполагаш с още един опит преди профилът ти да бъде заключен.
|
||||||
|
locked: Профилът ти е заключен.
|
||||||
|
not_found_in_database: "Невалидни стойности за %{authentication_keys} или парола."
|
||||||
|
timeout: Сесията ти изтече, моля влез отново, за да продължиш.
|
||||||
|
unauthenticated: Преди да продължиш, трябва да влезеш в профила си или да се регистрираш.
|
||||||
|
unconfirmed: Преди да продължиш, трябва да потвърдиш регистрацията си.
|
||||||
|
mailer:
|
||||||
|
confirmation_instructions:
|
||||||
|
subject: 'Mastodon: Инструкции за потвърждаване'
|
||||||
|
password_change:
|
||||||
|
subject: 'Mastodon: Паролата е променена'
|
||||||
|
reset_password_instructions:
|
||||||
|
subject: 'Инструкции за смяна на паролата'
|
||||||
|
unlock_instructions:
|
||||||
|
subject: 'Инструкции за отключване'
|
||||||
|
omniauth_callbacks:
|
||||||
|
failure: "Не успяхме да те упълномощим чрез %{kind}, защото \"%{reason}\"."
|
||||||
|
success: "Успешно упълномощаване чрез %{kind} профил."
|
||||||
|
passwords:
|
||||||
|
no_token: Може да достъпваш тази страница само от имейл за промяна на паролата. Ако тази страница е отворена от такъв имейл, увери се, че използваш целия URL-адрес, който сме ти изпратили.
|
||||||
|
send_instructions: Ще получиш писмо с инструкции как да промениш паролата си до няколко минути.
|
||||||
|
send_paranoid_instructions: Ако твоят имейл адрес съществува в базата ни, ще получиш там инструкции за промяна на своята парола.
|
||||||
|
updated: Паролата ти беше променена успешно. Влизането в профила е успешно.
|
||||||
|
updated_not_active: Паролата ти беше променена успешно.
|
||||||
|
registrations:
|
||||||
|
destroyed: Довиждане! Твоят профил беше успешно изтрит. Надяваме се скоро да те видим отново.
|
||||||
|
signed_up: Привет! Регистрирацията ти е успешна.
|
||||||
|
signed_up_but_inactive: Регистрирацията ти е успешна. Въпреки това, не можеш да влезеш в профила си, защото той все още не е потвърден.
|
||||||
|
signed_up_but_locked: Регистрирацията ти е успешна. Въпреки това, не можеш да влезеш в профила си, защото той е заключен.
|
||||||
|
signed_up_but_unconfirmed: Писмо с връзка за потвърждаване на профила ти беше изпратено на твоя имейл адрес. Моля, отвори връзката, за да активираш своя профил.
|
||||||
|
update_needs_confirmation: Профилът ти е успешно променен, но ние трябва да проверим твоя нов имейл адрес. Моля, провери пощата си и отвори връзката за потвърждаване на новия адрес.
|
||||||
|
updated: Профилът ти е успешно променен.
|
||||||
|
sessions:
|
||||||
|
already_signed_out: Успешно излизане от профила.
|
||||||
|
signed_in: Успешно влизане.
|
||||||
|
signed_out: Успешно излизане.
|
||||||
|
unlocks:
|
||||||
|
send_instructions: Ще получиш писмо с инструкции как да отключиш профила си до няколко минути.
|
||||||
|
send_paranoid_instructions: Ако твоят профил съществува в базата ни, на своя имейл адрес ще получиш инструкции за отключването му до няколко минути.
|
||||||
|
unlocked: Твоят профил беше отключен успешно. За да продължиш, влез в него.
|
||||||
|
errors:
|
||||||
|
messages:
|
||||||
|
already_confirmed: е вече потвърден, моля опитай да влезеш в профила си с него
|
||||||
|
confirmation_period_expired: "трябва да се потвърди в рамките на %{period}, моля направи нова заявка за потвърждение"
|
||||||
|
expired: е изтекъл, моля заяви нов
|
||||||
|
not_found: не е намерен
|
||||||
|
not_locked: не бе заключен
|
||||||
|
not_saved:
|
||||||
|
one: "Една грешка попречи този %{resource} да бъде записан:"
|
||||||
|
other: "%{count} грешки попречиха този %{resource} да бъде записан:"
|
|
@ -0,0 +1,113 @@
|
||||||
|
---
|
||||||
|
bg:
|
||||||
|
activerecord:
|
||||||
|
attributes:
|
||||||
|
doorkeeper/application:
|
||||||
|
name: Име
|
||||||
|
redirect_uri: URI за пренасочване
|
||||||
|
errors:
|
||||||
|
models:
|
||||||
|
doorkeeper/application:
|
||||||
|
attributes:
|
||||||
|
redirect_uri:
|
||||||
|
fragment_present: не може да съдържа фрагмент.
|
||||||
|
invalid_uri: трябва да е валидно URI.
|
||||||
|
relative_uri: трябва да е абсолютно URI.
|
||||||
|
secured_uri: трябва да е HTTPS/SSL URI.
|
||||||
|
doorkeeper:
|
||||||
|
applications:
|
||||||
|
buttons:
|
||||||
|
authorize: Упълномощаване
|
||||||
|
cancel: Отказ
|
||||||
|
destroy: Унищожаване
|
||||||
|
edit: Редакция
|
||||||
|
submit: Изпращане
|
||||||
|
confirmations:
|
||||||
|
destroy: Потвърждаваш ли изтриването?
|
||||||
|
edit:
|
||||||
|
title: Редактиране на приложението
|
||||||
|
form:
|
||||||
|
error: О, не! Провери формата за възможни грешки
|
||||||
|
help:
|
||||||
|
native_redirect_uri: Изполвай %{native_redirect_uri} за локални тестове
|
||||||
|
redirect_uri: Използвай един ред за всяко URI
|
||||||
|
scopes: Разделяй диапазоните с интервал. Остави празно, за да използваш диапазона по подразбиране.
|
||||||
|
index:
|
||||||
|
callback_url: URL за обратно повикване
|
||||||
|
name: Име
|
||||||
|
new: Ново приложение
|
||||||
|
title: Твоите приложения
|
||||||
|
new:
|
||||||
|
title: Ново приложение
|
||||||
|
show:
|
||||||
|
actions: Действия
|
||||||
|
application_id: Идентификатор на приложението
|
||||||
|
callback_urls: URL-и за обратно повикване
|
||||||
|
scopes: Диапазони
|
||||||
|
secret: Тайна
|
||||||
|
title: 'Приложение: %{name}'
|
||||||
|
authorizations:
|
||||||
|
buttons:
|
||||||
|
authorize: Упълномощаване
|
||||||
|
deny: Отказ
|
||||||
|
error:
|
||||||
|
title: Възникна грешка
|
||||||
|
new:
|
||||||
|
able_to: Ще е възможно
|
||||||
|
prompt: Приложението %{client_name} заявява достъп до твоя акаунт
|
||||||
|
title: Изисква се упълномощаване
|
||||||
|
show:
|
||||||
|
title: Код за упълномощаване
|
||||||
|
authorized_applications:
|
||||||
|
buttons:
|
||||||
|
revoke: Отмяна
|
||||||
|
confirmations:
|
||||||
|
revoke: Потвърждаваш ли отмяната?
|
||||||
|
index:
|
||||||
|
application: Приложение
|
||||||
|
created_at: Създадено на
|
||||||
|
date_format: "%Y-%m-%d %H:%M:%S"
|
||||||
|
scopes: Диапазони
|
||||||
|
title: Твоите упълномощени приложения
|
||||||
|
errors:
|
||||||
|
messages:
|
||||||
|
access_denied: Заявката беше отказана от собственика на ресурса или от сървъра за упълномощаване.
|
||||||
|
credential_flow_not_configured: Resource Owner Password Credentials предизвика грешка, заради това, че настройките за Doorkeeper.configure.resource_owner_from_credentials липсват.
|
||||||
|
invalid_client: Удостоверяването на клиента предизвика грешка, поради непознат клиент, липсващо клиентско удостоверяване, или заради това, че методът на удостоверяване не се поддържа.
|
||||||
|
invalid_grant: Предоставеното удостоверение за достъп е невалидно, изтекло, отхвърлено, не съвпада с пренасочващото URI, използвано в заявката за удостоверение, или е бил издадено от друг клиент.
|
||||||
|
invalid_redirect_uri: Наличното пренасочващо URI е невалидно.
|
||||||
|
invalid_request: Заявката е с липсващ задължителен параметър, включва стойност на параметъра, която не се поддържа, или е изкривена по друг начин.
|
||||||
|
invalid_resource_owner: Предоставените идентификационни данни на притежателя на ресурса са невалидни, или притежателят не може да бъде намерен.
|
||||||
|
invalid_scope: Заявеният диапазон е невалиден, неизвестен или изкривен.
|
||||||
|
invalid_token:
|
||||||
|
expired: Маркерът за достъп изтече
|
||||||
|
revoked: Маркерът за достъп беше отхвърлен
|
||||||
|
unknown: Маркерът за достъп е невалиден
|
||||||
|
resource_owner_authenticator_not_configured: Намирането на Resource Owner се провали поради липса на конфигурация на Doorkeeper.configure.resource_owner_authenticator.
|
||||||
|
server_error: Сървърът за удостоверяване попадна на неочаквано условие, което предотврати изпълнението на заявката.
|
||||||
|
temporarily_unavailable: Сървърът за удостоверяване не може да се справи със заявката в момента поради временно претоварване или профилактика на сървъра.
|
||||||
|
unauthorized_client: Клиентът не е удостоверен да изпълни заявката по този начин.
|
||||||
|
unsupported_grant_type: Типът на удостоврението за достъп не се поддържа от сървъра за удостоверяване.
|
||||||
|
unsupported_response_type: Удостоверяващият сървър не поддържа този тип отговор.
|
||||||
|
flash:
|
||||||
|
applications:
|
||||||
|
create:
|
||||||
|
notice: Приложението е създадено.
|
||||||
|
destroy:
|
||||||
|
notice: Приложението е изтрито.
|
||||||
|
update:
|
||||||
|
notice: Приложението е обновено.
|
||||||
|
authorized_applications:
|
||||||
|
destroy:
|
||||||
|
notice: Приложението е отказано.
|
||||||
|
layouts:
|
||||||
|
admin:
|
||||||
|
nav:
|
||||||
|
applications: Приложения
|
||||||
|
oauth2_provider: OAuth2 доставчик
|
||||||
|
application:
|
||||||
|
title: Нужно е упълномощаване по OAuth
|
||||||
|
scopes:
|
||||||
|
follow: следването, блокирането, деблокирането и отмяната на следването на акаунтите
|
||||||
|
read: четенето на данните от твоя акаунт
|
||||||
|
write: публикуването от твое име
|
|
@ -25,7 +25,7 @@ ja:
|
||||||
confirmations:
|
confirmations:
|
||||||
destroy: 本当に削除しますか?
|
destroy: 本当に削除しますか?
|
||||||
edit:
|
edit:
|
||||||
title: アプリケーションの編集
|
title: アプリの編集
|
||||||
form:
|
form:
|
||||||
error: フォームにエラーが無いか確認してください。
|
error: フォームにエラーが無いか確認してください。
|
||||||
help:
|
help:
|
||||||
|
@ -35,17 +35,17 @@ ja:
|
||||||
index:
|
index:
|
||||||
callback_url: コールバックURL
|
callback_url: コールバックURL
|
||||||
name: 名前
|
name: 名前
|
||||||
new: 新規アプリケーション
|
new: 新規アプリ
|
||||||
title: あなたのアプリケーション
|
title: アプリ
|
||||||
new:
|
new:
|
||||||
title: 新規アプリケーション
|
title: 新規アプリ
|
||||||
show:
|
show:
|
||||||
actions: アクション
|
actions: アクション
|
||||||
application_id: アクションId
|
application_id: アクションId
|
||||||
callback_urls: コールバックurl
|
callback_urls: コールバックurl
|
||||||
scopes: アクセス権
|
scopes: アクセス権
|
||||||
secret: 非公開
|
secret: 非公開
|
||||||
title: 'アプリケーション: %{name}'
|
title: 'アプリ: %{name}'
|
||||||
authorizations:
|
authorizations:
|
||||||
buttons:
|
buttons:
|
||||||
authorize: 承認
|
authorize: 承認
|
||||||
|
@ -53,8 +53,8 @@ ja:
|
||||||
error:
|
error:
|
||||||
title: エラーが発生しました。
|
title: エラーが発生しました。
|
||||||
new:
|
new:
|
||||||
able_to: このアプリケーションは以下のことができます
|
able_to: このアプリは以下のことができます
|
||||||
prompt: アプリケーション %{client_name} があなたのアカウントへのアクセスを要求しています。
|
prompt: アプリ %{client_name} があなたのアカウントへのアクセスを要求しています。
|
||||||
title: 認証が必要です。
|
title: 認証が必要です。
|
||||||
show:
|
show:
|
||||||
title: 認証コード
|
title: 認証コード
|
||||||
|
@ -68,7 +68,7 @@ ja:
|
||||||
created_at: 許可した日時
|
created_at: 許可した日時
|
||||||
date_format: "%Y年%m月%d日 %H時%M分%S秒"
|
date_format: "%Y年%m月%d日 %H時%M分%S秒"
|
||||||
scopes: アクセス権
|
scopes: アクセス権
|
||||||
title: 認証済みアプリケーション
|
title: 認証済みアプリ
|
||||||
errors:
|
errors:
|
||||||
messages:
|
messages:
|
||||||
access_denied: リソースの所有者または認証サーバーが要求を拒否しました。
|
access_denied: リソースの所有者または認証サーバーが要求を拒否しました。
|
||||||
|
@ -92,22 +92,22 @@ ja:
|
||||||
flash:
|
flash:
|
||||||
applications:
|
applications:
|
||||||
create:
|
create:
|
||||||
notice: アプリケーションが作成されました。
|
notice: アプリが作成されました。
|
||||||
destroy:
|
destroy:
|
||||||
notice: アプリケーションが削除されました。
|
notice: アプリが削除されました。
|
||||||
update:
|
update:
|
||||||
notice: アプリケーションが更新されました。
|
notice: アプリが更新されました。
|
||||||
authorized_applications:
|
authorized_applications:
|
||||||
destroy:
|
destroy:
|
||||||
notice: アプリケーションが取り消されました。
|
notice: アプリが取り消されました。
|
||||||
layouts:
|
layouts:
|
||||||
admin:
|
admin:
|
||||||
nav:
|
nav:
|
||||||
applications: アプリケーション
|
applications: アプリ
|
||||||
oauth2_provider: OAuth2プロバイダー
|
oauth2_provider: OAuth2プロバイダー
|
||||||
application:
|
application:
|
||||||
title: OAuth認証が必要です。
|
title: OAuth認証
|
||||||
scopes:
|
scopes:
|
||||||
follow: アカウントのフォロー, ブロック, ブロック解除, フォロー解除
|
follow: アカウントのフォロー, ブロック, ブロック解除, フォロー解除
|
||||||
read: アカウントへのデータの読み取り
|
read: アカウントからのデータの読み取り
|
||||||
write: アカウントからの投稿の書き込み
|
write: アカウントへのデータの書き込み
|
||||||
|
|
|
@ -46,7 +46,7 @@ ja:
|
||||||
applications:
|
applications:
|
||||||
invalid_url: URLが無効です
|
invalid_url: URLが無効です
|
||||||
auth:
|
auth:
|
||||||
change_password: 資格情報
|
change_password: ログイン情報
|
||||||
didnt_get_confirmation: 確認メールを受信できませんか?
|
didnt_get_confirmation: 確認メールを受信できませんか?
|
||||||
forgot_password: パスワードをお忘れですか?
|
forgot_password: パスワードをお忘れですか?
|
||||||
login: ログイン
|
login: ログイン
|
||||||
|
|
|
@ -9,7 +9,7 @@ ru:
|
||||||
contact: Связаться
|
contact: Связаться
|
||||||
description_headline: Что такое %{domain}?
|
description_headline: Что такое %{domain}?
|
||||||
domain_count_after: другими узлами
|
domain_count_after: другими узлами
|
||||||
domain_count_before: Связывается с
|
domain_count_before: Связан с
|
||||||
features:
|
features:
|
||||||
api: Открытый API для приложений и сервисов
|
api: Открытый API для приложений и сервисов
|
||||||
blocks: Продвинутые инструменты блокирования и глушения
|
blocks: Продвинутые инструменты блокирования и глушения
|
||||||
|
@ -25,7 +25,7 @@ ru:
|
||||||
other_instances: Другие узлы
|
other_instances: Другие узлы
|
||||||
source_code: Исходный код
|
source_code: Исходный код
|
||||||
status_count_after: статусов
|
status_count_after: статусов
|
||||||
status_count_before: Автор
|
status_count_before: Опубликовано
|
||||||
terms: Условия
|
terms: Условия
|
||||||
user_count_after: пользователей
|
user_count_after: пользователей
|
||||||
user_count_before: Здесь живет
|
user_count_before: Здесь живет
|
||||||
|
@ -42,7 +42,7 @@ ru:
|
||||||
application_mailer:
|
application_mailer:
|
||||||
settings: 'Изменить настройки e-mail: %{link}'
|
settings: 'Изменить настройки e-mail: %{link}'
|
||||||
signature: Уведомления Mastodon от %{instance}
|
signature: Уведомления Mastodon от %{instance}
|
||||||
view: 'View:'
|
view: 'Просмотр:'
|
||||||
applications:
|
applications:
|
||||||
invalid_url: Введенный URL неверен
|
invalid_url: Введенный URL неверен
|
||||||
auth:
|
auth:
|
||||||
|
@ -126,7 +126,7 @@ ru:
|
||||||
acct: Введите username@domain, откуда Вы хотите подписаться
|
acct: Введите username@domain, откуда Вы хотите подписаться
|
||||||
missing_resource: Поиск требуемого перенаправления URL для Вашего аккаунта завершился неудачей
|
missing_resource: Поиск требуемого перенаправления URL для Вашего аккаунта завершился неудачей
|
||||||
proceed: Продолжить подписку
|
proceed: Продолжить подписку
|
||||||
prompt: 'Вы ходите подписаться на:'
|
prompt: 'Вы хотите подписаться на:'
|
||||||
settings:
|
settings:
|
||||||
authorized_apps: Авторизованные приложения
|
authorized_apps: Авторизованные приложения
|
||||||
back: Назад в Mastodon
|
back: Назад в Mastodon
|
||||||
|
@ -142,8 +142,8 @@ ru:
|
||||||
show_more: Подробнее
|
show_more: Подробнее
|
||||||
visibilities:
|
visibilities:
|
||||||
private: Показывать только подписчикам
|
private: Показывать только подписчикам
|
||||||
public: Публичный
|
public: Показывать всем
|
||||||
unlisted: Публичный, но без отображения в публичных лентах
|
unlisted: Показывать всем, но не отображать в публичных лентах
|
||||||
stream_entries:
|
stream_entries:
|
||||||
click_to_show: Показать
|
click_to_show: Показать
|
||||||
reblogged: продвинул(а)
|
reblogged: продвинул(а)
|
||||||
|
@ -156,8 +156,13 @@ ru:
|
||||||
disable: Отключить
|
disable: Отключить
|
||||||
enable: Включить
|
enable: Включить
|
||||||
instructions_html: "<strong>Отсканируйте этот QR-код с помощью Google Authenticator или другого подобного приложения на Вашем телефоне</strong>. С этого момента приложение будет генерировать токены, которые будет необходимо ввести для входа."
|
instructions_html: "<strong>Отсканируйте этот QR-код с помощью Google Authenticator или другого подобного приложения на Вашем телефоне</strong>. С этого момента приложение будет генерировать токены, которые будет необходимо ввести для входа."
|
||||||
|
manual_instructions: 'Если Вы не можете отсканировать QR-код и хотите ввести его вручную, секрет представлен здесь открытым текстом:'
|
||||||
plaintext_secret_html: 'Секрет открытым текстом: <samp>%{secret}</samp>'
|
plaintext_secret_html: 'Секрет открытым текстом: <samp>%{secret}</samp>'
|
||||||
warning: Если сейчас у Вас не получается настроить аутентификатор, нажмите "отключить", иначе Вы не сможете войти!
|
code_hint: 'Для подтверждения введите код, сгенерированный приложением аутентификатора'
|
||||||
|
setup: Настроить
|
||||||
|
warning: 'Если сейчас у Вас не получается настроить аутентификатор, нажмите "отключить", иначе Вы не сможете войти!'
|
||||||
users:
|
users:
|
||||||
invalid_email: Введенный e-mail неверен
|
invalid_email: Введенный e-mail неверен
|
||||||
invalid_otp_token: Введен неверный код
|
invalid_otp_token: Введен неверный код
|
||||||
|
will_paginate:
|
||||||
|
page_gap: "…"
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
---
|
||||||
|
bg:
|
||||||
|
simple_form:
|
||||||
|
hints:
|
||||||
|
defaults:
|
||||||
|
avatar: PNG, GIF или JPG. До 2MB. Ще бъде смалена до 120x120 пиксела
|
||||||
|
display_name: До 30 символа
|
||||||
|
header: PNG, GIF или JPG. До 2MB. Ще бъде смалена до 700x335 пиксела
|
||||||
|
locked: Изисква ръчно одобрение на последователите. По подразбиране, публикациите са достъпни само до последователи.
|
||||||
|
note: До 160 символа
|
||||||
|
imports:
|
||||||
|
data: CSV файл, експортиран от друга инстанция на Mastodon
|
||||||
|
labels:
|
||||||
|
defaults:
|
||||||
|
avatar: Аватар
|
||||||
|
confirm_new_password: Потвърди новата парола
|
||||||
|
confirm_password: Потвърди паролата
|
||||||
|
current_password: Текуща парола
|
||||||
|
data: Данни
|
||||||
|
display_name: Показвано име
|
||||||
|
email: E-mail адрес
|
||||||
|
header: Заглавен ред
|
||||||
|
locale: Език
|
||||||
|
locked: Направи акаунта поверителен
|
||||||
|
new_password: Нова парола
|
||||||
|
note: Био
|
||||||
|
otp_attempt: Двустепенен код
|
||||||
|
password: Парола
|
||||||
|
setting_default_privacy: Поверителност на публикациите
|
||||||
|
type: Тип на импортиране
|
||||||
|
username: Потребителско име
|
||||||
|
interactions:
|
||||||
|
must_be_follower: Блокирай известия от не-последователи
|
||||||
|
must_be_following: Блокирай известия от хора, които не следваш
|
||||||
|
notification_emails:
|
||||||
|
digest: Изпращай извлечения на съобщенията
|
||||||
|
favourite: Изпращай e-mail, когато някой хареса твоя публикация
|
||||||
|
follow: Изпращай e-mail, когато някой те последва
|
||||||
|
follow_request: Изпращай e-mail, когато някой пожелае да те последва
|
||||||
|
mention: Изпращай e-mail, когато някой те спомене
|
||||||
|
reblog: Изпращай e-mail, когато някой сподели твоя публикация
|
||||||
|
'no': 'Не'
|
||||||
|
required:
|
||||||
|
mark: "*"
|
||||||
|
text: задължително
|
||||||
|
'yes': 'Да'
|
|
@ -26,7 +26,7 @@ ru:
|
||||||
note: О Вас
|
note: О Вас
|
||||||
otp_attempt: Двухфакторный код
|
otp_attempt: Двухфакторный код
|
||||||
password: Пароль
|
password: Пароль
|
||||||
setting_default_privacy: Приватность постов
|
setting_default_privacy: Видимость постов
|
||||||
type: Тип импорта
|
type: Тип импорта
|
||||||
username: Имя пользователя
|
username: Имя пользователя
|
||||||
interactions:
|
interactions:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'sidekiq/web'
|
require 'sidekiq/web'
|
||||||
|
@ -14,8 +15,8 @@ Rails.application.routes.draw do
|
||||||
controllers authorizations: 'oauth/authorizations', authorized_applications: 'oauth/authorized_applications'
|
controllers authorizations: 'oauth/authorizations', authorized_applications: 'oauth/authorized_applications'
|
||||||
end
|
end
|
||||||
|
|
||||||
get '.well-known/host-meta', to: 'xrd#host_meta', as: :host_meta
|
get '.well-known/host-meta', to: 'well_known/host_meta#show', as: :host_meta, defaults: { format: 'xml' }
|
||||||
get '.well-known/webfinger', to: 'xrd#webfinger', as: :webfinger, defaults: { format: 'json' }
|
get '.well-known/webfinger', to: 'well_known/webfinger#show', as: :webfinger, defaults: { format: 'json' }
|
||||||
|
|
||||||
devise_for :users, path: 'auth', controllers: {
|
devise_for :users, path: 'auth', controllers: {
|
||||||
sessions: 'auth/sessions',
|
sessions: 'auth/sessions',
|
||||||
|
@ -89,12 +90,8 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :accounts, only: [:index, :show] do
|
resources :accounts, only: [:index, :show] do
|
||||||
member do
|
resource :silence, only: [:create, :destroy]
|
||||||
post :silence
|
resource :suspension, only: [:create, :destroy]
|
||||||
post :unsilence
|
|
||||||
post :suspend
|
|
||||||
post :unsuspend
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe Admin::SilencesController do
|
||||||
|
let(:account) { Fabricate(:account) }
|
||||||
|
before do
|
||||||
|
sign_in Fabricate(:user, admin: true), scope: :user
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'POST #create' do
|
||||||
|
it 'redirects to admin accounts page' do
|
||||||
|
post :create, params: { account_id: account.id }
|
||||||
|
|
||||||
|
expect(response).to redirect_to(admin_accounts_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'DELETE #destroy' do
|
||||||
|
it 'redirects to admin accounts page' do
|
||||||
|
delete :destroy, params: { account_id: account.id }
|
||||||
|
|
||||||
|
expect(response).to redirect_to(admin_accounts_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,24 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe Admin::SuspensionsController do
|
||||||
|
let(:account) { Fabricate(:account) }
|
||||||
|
before do
|
||||||
|
sign_in Fabricate(:user, admin: true), scope: :user
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'POST #create' do
|
||||||
|
it 'redirects to admin accounts page' do
|
||||||
|
post :create, params: { account_id: account.id }
|
||||||
|
|
||||||
|
expect(response).to redirect_to(admin_accounts_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'DELETE #destroy' do
|
||||||
|
it 'redirects to admin accounts page' do
|
||||||
|
delete :destroy, params: { account_id: account.id }
|
||||||
|
|
||||||
|
expect(response).to redirect_to(admin_accounts_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,8 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe Settings::ExportsController do
|
describe Settings::ExportsController do
|
||||||
|
render_views
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in Fabricate(:user), scope: :user
|
sign_in Fabricate(:user), scope: :user
|
||||||
end
|
end
|
||||||
|
@ -8,6 +10,7 @@ describe Settings::ExportsController do
|
||||||
describe 'GET #show' do
|
describe 'GET #show' do
|
||||||
it 'returns http success' do
|
it 'returns http success' do
|
||||||
get :show
|
get :show
|
||||||
|
|
||||||
expect(response).to have_http_status(:success)
|
expect(response).to have_http_status(:success)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe WellKnown::HostMetaController, type: :controller do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
describe 'GET #show' do
|
||||||
|
it 'returns http success' do
|
||||||
|
get :show, format: :xml
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,21 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe WellKnown::WebfingerController, type: :controller do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
describe 'GET #show' do
|
||||||
|
let(:alice) { Fabricate(:account, username: 'alice') }
|
||||||
|
|
||||||
|
it 'returns http success when account can be found' do
|
||||||
|
get :show, params: { resource: alice.to_webfinger_s }, format: :json
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns http not found when account cannot be found' do
|
||||||
|
get :show, params: { resource: 'acct:not@existing.com' }, format: :json
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:not_found)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,26 +0,0 @@
|
||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
RSpec.describe XrdController, type: :controller do
|
|
||||||
render_views
|
|
||||||
|
|
||||||
describe 'GET #host_meta' do
|
|
||||||
it 'returns http success' do
|
|
||||||
get :host_meta
|
|
||||||
expect(response).to have_http_status(:success)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'GET #webfinger' do
|
|
||||||
let(:alice) { Fabricate(:account, username: 'alice') }
|
|
||||||
|
|
||||||
it 'returns http success when account can be found' do
|
|
||||||
get :webfinger, params: { resource: alice.to_webfinger_s }, format: :json
|
|
||||||
expect(response).to have_http_status(:success)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns http not found when account cannot be found' do
|
|
||||||
get :webfinger, params: { resource: 'acct:not@existing.com' }, format: :json
|
|
||||||
expect(response).to have_http_status(:not_found)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe AccountFilter do
|
||||||
|
describe 'with empty params' do
|
||||||
|
it 'defaults to alphabetic account list' do
|
||||||
|
filter = AccountFilter.new({})
|
||||||
|
|
||||||
|
expect(filter.results).to eq Account.alphabetic
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'with invalid params' do
|
||||||
|
it 'raises with key error' do
|
||||||
|
filter = AccountFilter.new(wrong: true)
|
||||||
|
|
||||||
|
expect { filter.results }.to raise_error(/wrong/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'with valid params' do
|
||||||
|
it 'combines filters on Account' do
|
||||||
|
filter = AccountFilter.new(by_domain: 'test.com', silenced: true)
|
||||||
|
|
||||||
|
allow(Account).to receive(:where).and_return(Account.none)
|
||||||
|
allow(Account).to receive(:silenced).and_return(Account.none)
|
||||||
|
filter.results
|
||||||
|
expect(Account).to have_received(:where).with(domain: 'test.com')
|
||||||
|
expect(Account).to have_received(:silenced)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,12 @@
|
||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe "The host_meta route" do
|
||||||
|
describe "requested without accepts headers" do
|
||||||
|
it "returns an xml response" do
|
||||||
|
get host_meta_url
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
expect(response.content_type).to eq "application/xrd+xml"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,15 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe 'the host-meta route' do
|
||||||
|
it 'routes to correct place with xml format' do
|
||||||
|
expect(get('/.well-known/host-meta')).
|
||||||
|
to route_to('well_known/host_meta#show', format: 'xml')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'the webfinger route' do
|
||||||
|
it 'routes to correct place with json format' do
|
||||||
|
expect(get('/.well-known/webfinger')).
|
||||||
|
to route_to('well_known/webfinger#show', format: 'json')
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue