Merge remote-tracking branch 'origin/master' into gs-master

Conflicts:
 	app/javascript/mastodon/locales/en.json
 	app/javascript/mastodon/locales/ja.json
 	app/javascript/mastodon/locales/pl.json
 	app/views/accounts/_header.html.haml
signup-info-prompt
David Yip 2018-04-01 20:24:50 -05:00
commit eb39db7f93
No known key found for this signature in database
GPG Key ID: 7DA0036508FCC0CC
82 changed files with 753 additions and 37 deletions

View File

@ -14,9 +14,9 @@ DB_PORT=5432
DATABASE_URL=postgresql://$DATA_DB_USER:$DATA_DB_PASS@$DATA_DB_HOST/gonano
# Optional ElasticSearch configuration
# ES_ENABLED=true
# ES_HOST=localhost
# ES_PORT=9200
ES_ENABLED=true
ES_HOST=$DATA_ELASTIC_HOST
ES_PORT=9200
# Optimizations
LD_PRELOAD=/data/lib/libjemalloc.so

View File

@ -1 +1 @@
2.5.0
2.5.1

View File

@ -35,7 +35,7 @@ addons:
- yarn
rvm:
- 2.4.2
- 2.4.3
- 2.5.0
services:

View File

@ -1,4 +1,4 @@
FROM ruby:2.4.3-alpine3.6
FROM ruby:2.4.4-alpine3.6
LABEL maintainer="https://github.com/tootsuite/mastodon" \
description="Your self-hosted, globally interconnected microblogging community"

View File

@ -63,6 +63,6 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@ -63,6 +63,6 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@ -69,7 +69,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit, :only_media, :exclude_replies).merge(core_params)
params.slice(:limit, :only_media, :exclude_replies).permit(:limit, :only_media, :exclude_replies).merge(core_params)
end
def insert_pagination_headers

View File

@ -57,6 +57,6 @@ class Api::V1::BlocksController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@ -67,7 +67,7 @@ class Api::V1::DomainBlocksController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
def domain_block_params

View File

@ -66,6 +66,6 @@ class Api::V1::FavouritesController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@ -71,6 +71,6 @@ class Api::V1::FollowRequestsController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@ -88,7 +88,7 @@ class Api::V1::Lists::AccountsController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
def unlimited?

View File

@ -76,6 +76,6 @@ class Api::V1::MutesController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@ -91,6 +91,6 @@ class Api::V1::NotificationsController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit, exclude_types: []).merge(core_params)
params.slice(:limit, :exclude_types).permit(:limit, exclude_types: []).merge(core_params)
end
end

View File

@ -77,6 +77,6 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@ -74,6 +74,6 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@ -76,7 +76,7 @@ class Api::V1::StatusesController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
def authorize_if_got_token

View File

@ -43,7 +43,7 @@ class Api::V1::Timelines::HomeController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:local, :limit).merge(core_params)
params.slice(:local, :limit).permit(:local, :limit).merge(core_params)
end
def next_path

View File

@ -45,7 +45,7 @@ class Api::V1::Timelines::ListController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
def next_path

View File

@ -45,7 +45,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:local, :limit, :only_media).merge(core_params)
params.slice(:local, :limit, :only_media).permit(:local, :limit, :only_media).merge(core_params)
end
def next_path

View File

@ -54,7 +54,7 @@ class Api::V1::Timelines::TagController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:local, :limit, :only_media).merge(core_params)
params.slice(:local, :limit, :only_media).permit(:local, :limit, :only_media).merge(core_params)
end
def next_path

View File

@ -67,6 +67,8 @@ export default class StatusActionBar extends ImmutablePureComponent {
navigator.share({
text: this.props.status.get('search_index'),
url: this.props.status.get('url'),
}).catch((e) => {
if (e.name !== 'AbortError') console.error(e);
});
}

View File

@ -74,6 +74,14 @@ export default class ComposeForm extends ImmutablePureComponent {
this.props.onChange(this.autosuggestTextarea.textarea.value);
}
// Submit disabled:
const { is_submitting, is_uploading, anyMedia } = this.props;
const fulltext = [this.props.spoiler_text, countableText(this.props.text)].join('');
if (is_submitting || is_uploading || length(fulltext) > 500 || (fulltext.length !== 0 && fulltext.trim().length === 0 && !anyMedia)) {
return;
}
this.props.onSubmit();
}

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "إعادة المحاولة",
"column.blocks": "الحسابات المحجوبة",
"column.community": "الخيط العام المحلي",
"column.domain_blocks": "Hidden domains",
"column.favourites": "المفضلة",
"column.follow_requests": "طلبات المتابعة",
"column.home": "الرئيسية",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "هل تود إخفاء الإخطارات القادمة من هذا المستخدم ؟",
"navigation_bar.blocks": "الحسابات المحجوبة",
"navigation_bar.community_timeline": "الخيط العام المحلي",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "تعديل الملف الشخصي",
"navigation_bar.favourites": "المفضلة",
"navigation_bar.follow_requests": "طلبات المتابعة",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Try again",
"column.blocks": "Blocked users",
"column.community": "Local timeline",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favourites",
"column.follow_requests": "Follow requests",
"column.home": "Начало",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Редактирай профил",
"navigation_bar.favourites": "Favourites",
"navigation_bar.follow_requests": "Follow requests",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Torna-ho a provar",
"column.blocks": "Usuaris blocats",
"column.community": "Línia de temps local",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favorits",
"column.follow_requests": "Peticions per seguir-te",
"column.home": "Inici",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Amagar notificacions d'aquest usuari?",
"navigation_bar.blocks": "Usuaris bloquejats",
"navigation_bar.community_timeline": "Línia de temps Local",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.favourites": "Favorits",
"navigation_bar.follow_requests": "Sol·licituds de seguiment",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Erneut versuchen",
"column.blocks": "Blockierte Profile",
"column.community": "Lokale Zeitleiste",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favoriten",
"column.follow_requests": "Folgeanfragen",
"column.home": "Startseite",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Benachrichtigungen von diesem Account verbergen?",
"navigation_bar.blocks": "Blockierte Profile",
"navigation_bar.community_timeline": "Lokale Zeitleiste",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Profil bearbeiten",
"navigation_bar.favourites": "Favoriten",
"navigation_bar.follow_requests": "Folgeanfragen",

View File

@ -92,6 +92,15 @@
],
"path": "app/javascript/mastodon/components/column_header.json"
},
{
"descriptors": [
{
"defaultMessage": "Unhide {domain}",
"id": "account.unblock_domain"
}
],
"path": "app/javascript/mastodon/components/domain.json"
},
{
"descriptors": [
{
@ -298,6 +307,19 @@
],
"path": "app/javascript/mastodon/containers/account_container.json"
},
{
"descriptors": [
{
"defaultMessage": "Hide entire domain",
"id": "confirmations.domain_block.confirm"
},
{
"defaultMessage": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"id": "confirmations.domain_block.message"
}
],
"path": "app/javascript/mastodon/containers/domain_container.json"
},
{
"descriptors": [
{
@ -849,6 +871,19 @@
],
"path": "app/javascript/mastodon/features/compose/index.json"
},
{
"descriptors": [
{
"defaultMessage": "Hidden domains",
"id": "column.domain_blocks"
},
{
"defaultMessage": "Unhide {domain}",
"id": "account.unblock_domain"
}
],
"path": "app/javascript/mastodon/features/domain_blocks/index.json"
},
{
"descriptors": [
{
@ -930,6 +965,10 @@
"defaultMessage": "Blocked users",
"id": "navigation_bar.blocks"
},
{
"defaultMessage": "Hidden domains",
"id": "navigation_bar.domain_blocks"
},
{
"defaultMessage": "Muted users",
"id": "navigation_bar.mutes"

View File

@ -41,6 +41,7 @@
"column.blocks": "Blocked users",
"column.community": "Local timeline",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favourites",
"column.follow_requests": "Follow requests",
"column.home": "Home",
@ -159,6 +160,7 @@
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Edit profile",
"navigation_bar.favourites": "Favourites",
"navigation_bar.follow_requests": "Follow requests",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Bonvolu reprovi",
"column.blocks": "Blokitaj uzantoj",
"column.community": "Loka tempolinio",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Stelumoj",
"column.follow_requests": "Petoj de sekvado",
"column.home": "Hejmo",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Ĉu kaŝi sciigojn el ĉi tiu uzanto?",
"navigation_bar.blocks": "Blokitaj uzantoj",
"navigation_bar.community_timeline": "Loka tempolinio",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Redakti profilon",
"navigation_bar.favourites": "Stelumoj",
"navigation_bar.follow_requests": "Petoj de sekvado",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Inténtalo de nuevo",
"column.blocks": "Usuarios bloqueados",
"column.community": "Línea de tiempo local",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favoritos",
"column.follow_requests": "Solicitudes de seguimiento",
"column.home": "Inicio",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Ocultar notificaciones de este usuario?",
"navigation_bar.blocks": "Usuarios bloqueados",
"navigation_bar.community_timeline": "Historia local",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.favourites": "Favoritos",
"navigation_bar.follow_requests": "Solicitudes para seguirte",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "تلاش دوباره",
"column.blocks": "کاربران مسدودشده",
"column.community": "نوشته‌های محلی",
"column.domain_blocks": "Hidden domains",
"column.favourites": "پسندیده‌ها",
"column.follow_requests": "درخواست‌های پیگیری",
"column.home": "خانه",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "اعلان‌های این کاربر پنهان شود؟",
"navigation_bar.blocks": "کاربران مسدودشده",
"navigation_bar.community_timeline": "نوشته‌های محلی",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "ویرایش نمایه",
"navigation_bar.favourites": "پسندیده‌ها",
"navigation_bar.follow_requests": "درخواست‌های پیگیری",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Yritä uudestaan",
"column.blocks": "Estetyt käyttäjät",
"column.community": "Paikallinen aikajana",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Suosikit",
"column.follow_requests": "Seurauspyynnöt",
"column.home": "Koti",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Piilota ilmoitukset tältä käyttäjältä?",
"navigation_bar.blocks": "Estetyt käyttäjät",
"navigation_bar.community_timeline": "Paikallinen aikajana",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Muokkaa profiilia",
"navigation_bar.favourites": "Suosikit",
"navigation_bar.follow_requests": "Seurauspyynnöt",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Réessayer",
"column.blocks": "Comptes bloqués",
"column.community": "Fil public local",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favoris",
"column.follow_requests": "Demandes de suivi",
"column.home": "Accueil",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Masquer les notifications de cet utilisateur ?",
"navigation_bar.blocks": "Comptes bloqués",
"navigation_bar.community_timeline": "Fil public local",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Modifier le profil",
"navigation_bar.favourites": "Favoris",
"navigation_bar.follow_requests": "Demandes de suivi",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Inténteo de novo",
"column.blocks": "Usuarias bloqueadas",
"column.community": "Liña temporal local",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favoritas",
"column.follow_requests": "Peticións de seguimento",
"column.home": "Inicio",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Esconder notificacións deste usuario?",
"navigation_bar.blocks": "Usuarias bloqueadas",
"navigation_bar.community_timeline": "Liña temporal local",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.favourites": "Favoritas",
"navigation_bar.follow_requests": "Peticións de seguimento",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "לנסות שוב",
"column.blocks": "חסימות",
"column.community": "ציר זמן מקומי",
"column.domain_blocks": "Hidden domains",
"column.favourites": "חיבובים",
"column.follow_requests": "בקשות מעקב",
"column.home": "בבית",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "להסתיר הודעות מחשבון זה?",
"navigation_bar.blocks": "חסימות",
"navigation_bar.community_timeline": "ציר זמן מקומי",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "עריכת פרופיל",
"navigation_bar.favourites": "חיבובים",
"navigation_bar.follow_requests": "בקשות מעקב",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Try again",
"column.blocks": "Blokirani korisnici",
"column.community": "Lokalni timeline",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favoriti",
"column.follow_requests": "Zahtjevi za slijeđenje",
"column.home": "Dom",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.blocks": "Blokirani korisnici",
"navigation_bar.community_timeline": "Lokalni timeline",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Uredi profil",
"navigation_bar.favourites": "Favoriti",
"navigation_bar.follow_requests": "Zahtjevi za slijeđenje",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Próbálja újra",
"column.blocks": "Letiltott felhasználók",
"column.community": "Helyi idővonal",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Kedvencek",
"column.follow_requests": "Követési kérések",
"column.home": "Kezdőlap",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Értesítések elrejtése ezen felhasználótól?",
"navigation_bar.blocks": "Tiltott felhasználók",
"navigation_bar.community_timeline": "Helyi idővonal",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Profil szerkesztése",
"navigation_bar.favourites": "Kedvencek",
"navigation_bar.follow_requests": "Követési kérések",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Կրկին փորձել",
"column.blocks": "Արգելափակված օգտատերեր",
"column.community": "Տեղական հոսք",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Հավանածներ",
"column.follow_requests": "Հետեւելու հայցեր",
"column.home": "Հիմնական",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Թաքցնե՞լ ցանուցումներն այս օգտատիրոջից։",
"navigation_bar.blocks": "Արգելափակված օգտատերեր",
"navigation_bar.community_timeline": "Տեղական հոսք",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Խմբագրել անձնական էջը",
"navigation_bar.favourites": "Հավանածներ",
"navigation_bar.follow_requests": "Հետեւելու հայցեր",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Coba lagi",
"column.blocks": "Pengguna diblokir",
"column.community": "Linimasa Lokal",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favorit",
"column.follow_requests": "Permintaan mengikuti",
"column.home": "Beranda",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.blocks": "Pengguna diblokir",
"navigation_bar.community_timeline": "Linimasa lokal",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Ubah profil",
"navigation_bar.favourites": "Favorit",
"navigation_bar.follow_requests": "Permintaan mengikuti",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Try again",
"column.blocks": "Blokusita uzeri",
"column.community": "Lokala tempolineo",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favorati",
"column.follow_requests": "Demandi di sequado",
"column.home": "Hemo",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.blocks": "Blokusita uzeri",
"navigation_bar.community_timeline": "Lokala tempolineo",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Modifikar profilo",
"navigation_bar.favourites": "Favorati",
"navigation_bar.follow_requests": "Demandi di sequado",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Try again",
"column.blocks": "Utenti bloccati",
"column.community": "Timeline locale",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Apprezzati",
"column.follow_requests": "Richieste di amicizia",
"column.home": "Home",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.blocks": "Utenti bloccati",
"navigation_bar.community_timeline": "Timeline locale",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Modifica profilo",
"navigation_bar.favourites": "Apprezzati",
"navigation_bar.follow_requests": "Richieste di amicizia",

View File

@ -41,6 +41,7 @@
"column.blocks": "ブロックしたユーザー",
"column.community": "ローカルタイムライン",
"column.direct": "ダイレクトメッセージ",
"column.domain_blocks": "非表示にしたドメイン",
"column.favourites": "お気に入り",
"column.follow_requests": "フォローリクエスト",
"column.home": "ホーム",
@ -159,6 +160,7 @@
"navigation_bar.blocks": "ブロックしたユーザー",
"navigation_bar.community_timeline": "ローカルタイムライン",
"navigation_bar.direct": "ダイレクトメッセージ",
"navigation_bar.domain_blocks": "非表示にしたドメイン",
"navigation_bar.edit_profile": "プロフィールを編集",
"navigation_bar.favourites": "お気に入り",
"navigation_bar.follow_requests": "フォローリクエスト",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "다시 시도",
"column.blocks": "차단 중인 사용자",
"column.community": "로컬 타임라인",
"column.domain_blocks": "Hidden domains",
"column.favourites": "즐겨찾기",
"column.follow_requests": "팔로우 요청",
"column.home": "홈",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "이 사용자로부터의 알림을 뮤트하시겠습니까?",
"navigation_bar.blocks": "차단한 사용자",
"navigation_bar.community_timeline": "로컬 타임라인",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "프로필 편집",
"navigation_bar.favourites": "즐겨찾기",
"navigation_bar.follow_requests": "팔로우 요청",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Opnieuw proberen",
"column.blocks": "Geblokkeerde gebruikers",
"column.community": "Lokale tijdlijn",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favorieten",
"column.follow_requests": "Volgverzoeken",
"column.home": "Start",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Verberg meldingen van deze persoon?",
"navigation_bar.blocks": "Geblokkeerde gebruikers",
"navigation_bar.community_timeline": "Lokale tijdlijn",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Profiel bewerken",
"navigation_bar.favourites": "Favorieten",
"navigation_bar.follow_requests": "Volgverzoeken",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Prøv igjen",
"column.blocks": "Blokkerte brukere",
"column.community": "Lokal tidslinje",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Likt",
"column.follow_requests": "Følgeforespørsler",
"column.home": "Hjem",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Skjul varslinger fra denne brukeren?",
"navigation_bar.blocks": "Blokkerte brukere",
"navigation_bar.community_timeline": "Lokal tidslinje",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Rediger profil",
"navigation_bar.favourites": "Favoritter",
"navigation_bar.follow_requests": "Følgeforespørsler",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Tornar ensajar",
"column.blocks": "Personas blocadas",
"column.community": "Flux public local",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favorits",
"column.follow_requests": "Demandas dabonament",
"column.home": "Acuèlh",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Rescondre las notificacions daquesta persona?",
"navigation_bar.blocks": "Personas blocadas",
"navigation_bar.community_timeline": "Flux public local",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Modificar lo perfil",
"navigation_bar.favourites": "Favorits",
"navigation_bar.follow_requests": "Demandas dabonament",

View File

@ -18,7 +18,7 @@
"account.mute_notifications": "Wycisz powiadomienia o @{name}",
"account.muted": "Wyciszony",
"account.posts": "Wpisy",
"account.posts_with_replies": "Wpisy z odpowiedziami",
"account.posts_with_replies": "Wpisy i odpowiedzi",
"account.report": "Zgłoś @{name}",
"account.requested": "Oczekująca prośba, kliknij aby anulować",
"account.share": "Udostępnij profil @{name}",
@ -41,6 +41,7 @@
"column.blocks": "Zablokowani użytkownicy",
"column.community": "Lokalna oś czasu",
"column.direct": "Wiadomości bezpośrednie",
"column.domain_blocks": "Ukryte domeny",
"column.favourites": "Ulubione",
"column.follow_requests": "Prośby o śledzenie",
"column.home": "Strona główna",
@ -61,7 +62,7 @@
"column_subheading.lists": "Listy",
"column_subheading.navigation": "Nawigacja",
"column_subheading.settings": "Ustawienia",
"compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
"compose_form.direct_message_warning": "Ten wpis będzie widoczny tylko dla wszystkich wspomnianych użytkowników.",
"compose_form.hashtag_warning": "Ten wpis nie będzie widoczny pod podanymi hashtagami, ponieważ jest oznaczony jako niewidoczny. Tylko publiczne wpisy mogą zostać znalezione z użyciem hashtagów.",
"compose_form.lock_disclaimer": "Twoje konto nie jest {locked}. Każdy, kto Cię śledzi, może wyświetlać Twoje wpisy przeznaczone tylko dla śledzących.",
"compose_form.lock_disclaimer.lock": "zablokowane",
@ -159,6 +160,7 @@
"navigation_bar.blocks": "Zablokowani użytkownicy",
"navigation_bar.community_timeline": "Lokalna oś czasu",
"navigation_bar.direct": "Wiadomości bezpośrednie",
"navigation_bar.domain_blocks": "Ukryte domeny",
"navigation_bar.edit_profile": "Edytuj profil",
"navigation_bar.favourites": "Ulubione",
"navigation_bar.follow_requests": "Prośby o śledzenie",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Tente novamente",
"column.blocks": "Usuários bloqueados",
"column.community": "Local",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favoritos",
"column.follow_requests": "Seguidores pendentes",
"column.home": "Página inicial",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Esconder notificações deste usuário?",
"navigation_bar.blocks": "Usuários bloqueados",
"navigation_bar.community_timeline": "Local",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.favourites": "Favoritos",
"navigation_bar.follow_requests": "Seguidores pendentes",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Tente de novo",
"column.blocks": "Utilizadores Bloqueados",
"column.community": "Local",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favoritos",
"column.follow_requests": "Seguidores Pendentes",
"column.home": "Início",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Esconder notificações deste utilizador?",
"navigation_bar.blocks": "Utilizadores bloqueados",
"navigation_bar.community_timeline": "Local",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.favourites": "Favoritos",
"navigation_bar.follow_requests": "Seguidores pendentes",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Попробовать снова",
"column.blocks": "Список блокировки",
"column.community": "Локальная лента",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Понравившееся",
"column.follow_requests": "Запросы на подписку",
"column.home": "Главная",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Убрать уведомления от этого пользователя?",
"navigation_bar.blocks": "Список блокировки",
"navigation_bar.community_timeline": "Локальная лента",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Изменить профиль",
"navigation_bar.favourites": "Понравившееся",
"navigation_bar.follow_requests": "Запросы на подписку",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Skúsiť znova",
"column.blocks": "Blokovaní užívatelia",
"column.community": "Lokálna časová os",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Obľúbené",
"column.follow_requests": "Žiadosti o sledovaní",
"column.home": "Domov",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Skryť notifikácie od tohoto užívateľa?",
"navigation_bar.blocks": "Blokovaní užívatelia",
"navigation_bar.community_timeline": "Lokálna časová os",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Upraviť profil",
"navigation_bar.favourites": "Obľúbené",
"navigation_bar.follow_requests": "Žiadosti o sledovanie",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Pokušajte ponovo",
"column.blocks": "Blokirani korisnici",
"column.community": "Lokalna lajna",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Omiljeni",
"column.follow_requests": "Zahtevi za praćenje",
"column.home": "Početna",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Sakrij obaveštenja od ovog korisnika?",
"navigation_bar.blocks": "Blokirani korisnici",
"navigation_bar.community_timeline": "Lokalna lajna",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Izmeni profil",
"navigation_bar.favourites": "Omiljeni",
"navigation_bar.follow_requests": "Zahtevi za praćenje",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Покушајте поново",
"column.blocks": "Блокирани корисници",
"column.community": "Локална лајна",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Омиљени",
"column.follow_requests": "Захтеви за праћење",
"column.home": "Почетна",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Сакриј обавештења од овог корисника?",
"navigation_bar.blocks": "Блокирани корисници",
"navigation_bar.community_timeline": "Локална лајна",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Измени профил",
"navigation_bar.favourites": "Омиљени",
"navigation_bar.follow_requests": "Захтеви за праћење",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Försök igen",
"column.blocks": "Blockerade användare",
"column.community": "Lokal tidslinje",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favoriter",
"column.follow_requests": "Följ förfrågningar",
"column.home": "Hem",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Dölj notifikationer från denna användare?",
"navigation_bar.blocks": "Blockerade användare",
"navigation_bar.community_timeline": "Lokal tidslinje",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Redigera profil",
"navigation_bar.favourites": "Favoriter",
"navigation_bar.follow_requests": "Följförfrågningar",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Try again",
"column.blocks": "Blocked users",
"column.community": "Local timeline",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favourites",
"column.follow_requests": "Follow requests",
"column.home": "Home",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Edit profile",
"navigation_bar.favourites": "Favourites",
"navigation_bar.follow_requests": "Follow requests",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Try again",
"column.blocks": "Engellenen kullanıcılar",
"column.community": "Yerel zaman tüneli",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favoriler",
"column.follow_requests": "Takip istekleri",
"column.home": "Anasayfa",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.blocks": "Engellenen kullanıcılar",
"navigation_bar.community_timeline": "Yerel zaman tüneli",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Profili düzenle",
"navigation_bar.favourites": "Favoriler",
"navigation_bar.follow_requests": "Takip istekleri",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Try again",
"column.blocks": "Заблоковані користувачі",
"column.community": "Локальна стрічка",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Вподобане",
"column.follow_requests": "Запити на підписку",
"column.home": "Головна",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.blocks": "Заблоковані користувачі",
"navigation_bar.community_timeline": "Локальна стрічка",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Редагувати профіль",
"navigation_bar.favourites": "Вподобане",
"navigation_bar.follow_requests": "Запити на підписку",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "重试",
"column.blocks": "屏蔽用户",
"column.community": "本站时间轴",
"column.domain_blocks": "Hidden domains",
"column.favourites": "收藏过的嘟文",
"column.follow_requests": "关注请求",
"column.home": "主页",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "同时隐藏来自这个用户的通知",
"navigation_bar.blocks": "被屏蔽的用户",
"navigation_bar.community_timeline": "本站时间轴",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "修改个人资料",
"navigation_bar.favourites": "收藏的内容",
"navigation_bar.follow_requests": "关注请求",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "重試",
"column.blocks": "封鎖用戶",
"column.community": "本站時間軸",
"column.domain_blocks": "Hidden domains",
"column.favourites": "最愛的文章",
"column.follow_requests": "關注請求",
"column.home": "主頁",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.blocks": "被你封鎖的用戶",
"navigation_bar.community_timeline": "本站時間軸",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "修改個人資料",
"navigation_bar.favourites": "最愛的內容",
"navigation_bar.follow_requests": "關注請求",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "重試",
"column.blocks": "封鎖的使用者",
"column.community": "本地時間軸",
"column.domain_blocks": "Hidden domains",
"column.favourites": "最愛",
"column.follow_requests": "關注請求",
"column.home": "家",
@ -153,6 +154,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.blocks": "封鎖的使用者",
"navigation_bar.community_timeline": "本地時間軸",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "編輯用者資訊",
"navigation_bar.favourites": "最愛",
"navigation_bar.follow_requests": "關注請求",

View File

@ -51,9 +51,14 @@ class Formatter
strip_tags(text)
end
def simplified_format(account)
return reformat(account.note).html_safe unless account.local? # rubocop:disable Rails/OutputSafety
linkify(account.note)
def simplified_format(account, **options)
html = if account.local?
linkify(account.note)
else
reformat(account.note)
end
html = encode_custom_emojis(html, CustomEmoji.from_text(account.note, account.domain)) if options[:custom_emojify]
html.html_safe # rubocop:disable Rails/OutputSafety
end
def sanitize(html, config)

View File

@ -26,6 +26,9 @@ class OStatus::AtomSerializer
append_element(author, 'link', nil, rel: :alternate, type: 'text/html', href: ::TagManager.instance.url_for(account))
append_element(author, 'link', nil, rel: :avatar, type: account.avatar_content_type, 'media:width': 120, 'media:height': 120, href: full_asset_url(account.avatar.url(:original))) if account.avatar?
append_element(author, 'link', nil, rel: :header, type: account.header_content_type, 'media:width': 700, 'media:height': 335, href: full_asset_url(account.header.url(:original))) if account.header?
account.emojis.each do |emoji|
append_element(author, 'link', nil, rel: :emoji, href: full_asset_url(emoji.image.url), name: emoji.shortcode)
end
append_element(author, 'poco:preferredUsername', account.username)
append_element(author, 'poco:displayName', account.display_name) if account.display_name?
append_element(author, 'poco:note', account.local? ? account.note : strip_tags(account.note)) if account.note?

View File

@ -352,6 +352,10 @@ class Account < ApplicationRecord
end
end
def emojis
CustomEmoji.from_text(note, domain)
end
before_create :generate_keys
before_validation :normalize_domain
before_validation :prepare_contents, if: :local?

View File

@ -41,6 +41,10 @@ class RemoteProfile
@header ||= link_href_from_xml(author, 'header')
end
def emojis
@emojis ||= author.xpath('./xmlns:link[@rel="emoji"]', xmlns: OStatus::TagManager::XMLNS)
end
def locked?
scope == 'private'
end

View File

@ -10,6 +10,8 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
has_one :public_key, serializer: ActivityPub::PublicKeySerializer
has_many :virtual_tags, key: :tag
attribute :moved_to, if: :moved?
class EndpointsSerializer < ActiveModel::Serializer
@ -101,7 +103,14 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
object.locked
end
def virtual_tags
object.emojis
end
def moved_to
ActivityPub::TagManager.instance.uri_for(object.moved_to_account)
end
class CustomEmojiSerializer < ActivityPub::EmojiSerializer
end
end

View File

@ -14,7 +14,7 @@ class REST::AccountSerializer < ActiveModel::Serializer
end
def note
Formatter.instance.simplified_format(object)
Formatter.instance.simplified_format(object, custom_emojify: true)
end
def url

View File

@ -3,6 +3,8 @@
class ActivityPub::FetchRemoteAccountService < BaseService
include JsonLdHelper
SUPPORTED_TYPES = %w(Application Group Organization Person Service).freeze
# Should be called when uri has already been checked for locality
# Does a WebFinger roundtrip on each call
def call(uri, id: true, prefetched_body: nil)
@ -54,6 +56,6 @@ class ActivityPub::FetchRemoteAccountService < BaseService
end
def expected_type?
@json['type'] == 'Person'
SUPPORTED_TYPES.include?(@json['type'])
end
end

View File

@ -43,7 +43,7 @@ class ActivityPub::FetchRemoteKeyService < BaseService
end
def person?
@json['type'] == 'Person'
ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES.include?(@json['type'])
end
def public_key?
@ -55,6 +55,6 @@ class ActivityPub::FetchRemoteKeyService < BaseService
end
def confirmed_owner?
@owner['type'] == 'Person' && value_or_id(@owner['publicKey']) == @json['id']
ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES.include?(@owner['type']) && value_or_id(@owner['publicKey']) == @json['id']
end
end

View File

@ -22,6 +22,7 @@ class ActivityPub::ProcessAccountService < BaseService
create_account if @account.nil?
update_account
process_tags(@account)
end
end
@ -187,4 +188,31 @@ class ActivityPub::ProcessAccountService < BaseService
def lock_options
{ redis: Redis.current, key: "process_account:#{@uri}" }
end
def process_tags(account)
return if @json['tag'].blank?
as_array(@json['tag']).each do |tag|
case tag['type']
when 'Emoji'
process_emoji tag, account
end
end
end
def process_emoji(tag, _account)
return if skip_download?
return if tag['name'].blank? || tag['icon'].blank? || tag['icon']['url'].blank?
shortcode = tag['name'].delete(':')
image_url = tag['icon']['url']
uri = tag['id']
updated = tag['updated']
emoji = CustomEmoji.find_by(shortcode: shortcode, domain: @account.domain)
return unless emoji.nil? || emoji.updated_at >= updated
emoji ||= CustomEmoji.new(domain: @account.domain, shortcode: shortcode, uri: uri)
emoji.image_remote_url = image_url
emoji.save
end
end

View File

@ -42,7 +42,7 @@ class FetchAtomService < BaseService
elsif ['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'].include?(response.mime_type)
body = response.body_with_limit
json = body_to_json(body)
if supported_context?(json) && json['type'] == 'Person' && json['inbox'].present?
if supported_context?(json) && ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES.include?(json['type']) && json['inbox'].present?
[json['id'], { prefetched_body: body, id: true }, :activitypub]
elsif supported_context?(json) && expected_type?(json)
[json['id'], { prefetched_body: body, id: true }, :activitypub]

View File

@ -189,7 +189,7 @@ class ResolveAccountService < BaseService
return @actor_json if defined?(@actor_json)
json = fetch_resource(actor_url, false)
@actor_json = supported_context?(json) && json['type'] == 'Person' ? json : nil
@actor_json = supported_context?(json) && ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES.include?(json['type']) ? json : nil
end
def atom

View File

@ -17,7 +17,7 @@ class ResolveURLService < BaseService
def process_url
case type
when 'Person'
when 'Application', 'Group', 'Organization', 'Person', 'Service'
FetchRemoteAccountService.new.call(atom_url, body, protocol)
when 'Note', 'Article', 'Image', 'Video'
FetchRemoteStatusService.new.call(atom_url, body, protocol)

View File

@ -40,6 +40,27 @@ class UpdateRemoteProfileService < BaseService
account.header_remote_url = ''
account.header.destroy
end
save_emojis(account) if remote_profile.emojis.present?
end
end
def save_emojis(parent)
do_not_download = DomainBlock.find_by(domain: parent.account.domain)&.reject_media?
return if do_not_download
remote_account.emojis.each do |link|
next unless link['href'] && link['name']
shortcode = link['name'].delete(':')
emoji = CustomEmoji.find_by(shortcode: shortcode, domain: parent.account.domain)
next unless emoji.nil?
emoji = CustomEmoji.new(shortcode: shortcode, domain: parent.account.domain)
emoji.image_remote_url = link['href']
emoji.save
end
end
end

View File

@ -1,4 +1,4 @@
- processed_bio = FrontmatterHandler.instance.process_bio Formatter.instance.simplified_format account
- processed_bio = FrontmatterHandler.instance.process_bio Formatter.instance.simplified_format(account, custom_emojify: true)
.card.h-card.p-author{ style: "background-image: url(#{account.header.url(:original)})" }
.card__illustration
= render 'accounts/follow_button', account: account

View File

@ -61,6 +61,11 @@ deploy.config:
before_live:
web.web:
- bundle exec rake db:migrate:setup
- |-
if [[ "${ES_ENABLED}" != "false" ]]
then
bundle exec rake chewy:deploy
fi
web.web:
@ -208,6 +213,32 @@ data.db:
done
data.elastic:
image: nanobox/elasticsearch:5
cron:
- id: backup
schedule: '0 3 * * *'
command: |
id=$(cat /proc/sys/kernel/random/uuid)
curl -X PUT -H "Content-Type: application/json" "127.0.0.1:9200/_snapshot/${id}" -d "{\"type\": \"fs\",\"settings\": {\"location\": \"/var/tmp/${id}\",\"compress\": true}}"
curl -X PUT -H "Content-Type: application/json" "127.0.0.1:9200/_snapshot/${id}/backup?wait_for_completion=true&pretty"
tar -cz -C "/var/tmp/${id}" . |
curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/backup-${HOSTNAME}-$(date -u +%Y-%m-%d.%H-%M-%S).tgz -X POST -T - >&2
curl -X DELETE -H "Content-Type: application/json" "127.0.0.1:9200/_snapshot/${id}"
rm -rf "/var/tmp/${id}"
curl -k -s -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/ |
sed 's/,/\n/g' |
grep ${HOSTNAME} |
sort |
head -n-${BACKUP_COUNT:-1} |
sed 's/.*: \?"\(.*\)".*/\1/' |
while read file
do
curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/${file} -X DELETE
done
data.redis:
image: nanobox/redis:4.0

View File

@ -0,0 +1,13 @@
---
zh-HK:
activerecord:
errors:
models:
account:
attributes:
username:
invalid: 只能使用字母、數字和下劃線
status:
attributes:
reblog:
taken: 已經被轉推過

View File

@ -17,11 +17,32 @@ zh-HK:
unconfirmed: 你必須先確認電郵地址,繼續使用。
mailer:
confirmation_instructions:
action: 驗證電子郵件地址
explanation: 你在 %{host} 上使用這個電子郵件地址建立了一個帳戶。只需點擊下面的連結,即可啟用帳戶。如果你並沒有建立過帳戶,請忽略此郵件。
extra_html: 請記得閱讀本服務站的<a href="%{terms_path}">相關規定</a>和<a href="%{policy_path}">使用條款</a>。
subject: 'Mastodon: 確認電郵地址'
title: 驗證電子郵件地址
email_changed:
explanation: 你的帳戶的電子郵件地址即將變更為:
extra: 如果你沒有請求更改你的電子郵件地址,則他人很有可能已經入侵你的帳戶。請立即更改你的密碼;如果你已經無法訪問你的帳戶,請聯繫服務站的管理員請求協助。
subject: Mastodon電子郵件地址已被更改
title: 新電子郵件地址
password_change:
explanation: 你的帳戶的密碼已被更改。
extra: 如果你沒有請求更改你的密碼,則他人很有可能已經入侵你的帳戶。請立即更改你的密碼;如果你已經無法訪問你的帳戶,請聯繫服務站的管理員請求協助。
subject: 'Mastodon: 更改密碼'
title: 密碼已被重設
reconfirmation_instructions:
explanation: 點擊下面的連結來確認你的新電子郵件地址。
extra: 如果你沒有請求本次變更,請忽略此郵件。 Mastodon 帳戶的電子郵件地址只有在你點擊上面的連結後才會更改。
subject: Mastodon確認 %{instance} 電子郵件地址
title: 驗證電子郵件地址
reset_password_instructions:
action: 更改密碼
explanation: 點擊下面的連結來更改帳戶的密碼。
extra: 如果你沒有請求本次變更,請忽略此郵件。你的密碼只有在你點擊上面的連結並輸入新密碼後才會更改。
subject: 'Mastodon: 重設密碼'
title: 重設密碼
unlock_instructions:
subject: 'Mastodon: 解除用戶鎖定'
omniauth_callbacks:

View File

@ -5,6 +5,8 @@ zh-HK:
doorkeeper/application:
name: 名稱
redirect_uri: 轉接 URI
scopes: 權限範圍
website: 應用網站
errors:
models:
doorkeeper/application:
@ -33,9 +35,13 @@ zh-HK:
redirect_uri: 每行輸入一個 URI
scopes: 請用半形空格分開權限範圍 (scope)。留空表示使用預設的權限範圍
index:
application: 應用
callback_url: 回傳網址
delete: 刪除
name: 名稱
new: 新增應用程式
scopes: 權限範圍
show: 顯示
title: 你的應用程式
new:
title: 新增應用程式

View File

@ -4,12 +4,17 @@ zh-HK:
hints:
defaults:
avatar: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 2MB會縮裁成 400x400px
digest: 僅在你長時間未登錄,且收到了私信時發送
display_name: 最多 30 個字元
header: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 2MB會縮裁成 700x335px
locked: 你必須人手核准每個用戶對你的關注請求,而你的文章私隱會被預設為「只有關注你的人能看」
note: 最多 160 個字元
setting_noindex: 此設定會影響到你的公開個人資料以及文章頁面
setting_theme: 此設置會影響到你從任意設備登入時 Mastodon 的顯示樣式
imports:
data: 自其他服務站匯出的 CSV 檔案
sessions:
otp: 輸入你手機上生成的雙重認證碼,或者任意一個恢復代碼。
user:
filtered_languages: 下面被選擇的語言的文章將不會出現在你的公共時間軸上。
labels:
@ -21,22 +26,33 @@ zh-HK:
data: 資料
display_name: 顯示名稱
email: 電郵地址
filtered_languages: 封鎖下面语言的文章
expires_in: 失效時間
filtered_languages: 封鎖下面語言的文章
header: 個人頁面頂部
locale: 語言
locked: 將用戶轉為「私人」
max_uses: 最大使用次數
new_password: 新密碼
note: 簡介
otp_attempt: 雙重認證碼
password: 密碼
setting_auto_play_gif: 自動播放 GIF
setting_boost_modal: 在轉推前詢問我
setting_default_privacy: 文章預設為
setting_default_sensitive: 預設我的內容為敏感內容
setting_delete_modal: 刪推前詢問我
setting_noindex: 阻止搜尋引擎檢索
setting_reduce_motion: 減低動畫效果
setting_system_font_ui: 使用系統預設字型
setting_theme: 網站主題
setting_unfollow_modal: 取消關注前跳出詢問我
severity: 等級
type: 匯入資料類型
username: 用戶名稱
interactions:
must_be_follower: 隱藏沒有關注你的用戶的通知
must_be_following: 隱藏你不關注的用戶的通知
must_be_following_dm: 隱藏你不關注的用戶的私信
notification_emails:
digest: 定期電郵摘要
favourite: 當有用戶喜歡你的文章時,發電郵通知

View File

@ -1,53 +1,98 @@
---
zh-HK:
about:
about_hashtag_html: 這些是包含「<strong>#%{hashtag}</strong>」標籤的公開文章。只要你有任何 Mastodon 服務站、或者聯盟網站的用戶,便可以與他們互動。
about_mastodon_html: Mastodon萬象是<em>自由、開源</em>的社交網絡。服務站<em>各自獨立而互連</em>,避免單一商業機構壟斷。找你所信任的服務站,建立帳號,你即可與任何服務站上的用戶溝通,享受無縫的<em>網絡交流</em>。
about_this: 關於本服務站
closed_registrations: 本服務站暫時停止接受登記。
contact: 聯絡
contact_missing: 未設定
contact_unavailable: 未公開
description_headline: 關於 %{domain}
domain_count_after: 個其他服務站
domain_count_before: 已連接至
extended_description_html: |
<h3>這裡可以寫一些網站規則</h3>
<p>本站未有詳細介紹</p>
features:
humane_approach_body: Mastodon 從其他網絡的失敗經驗中汲取教訓,以合乎道德的設計對抗社交媒體的濫用問題。
humane_approach_title: 以人為本
not_a_product_body: Mastodon 不是商業網絡。沒有廣告,沒有數據挖掘,也沒有中央機構操控。平台完全開放。
not_a_product_title: 你是用戶,不是商品
real_conversation_body: Mastodon 的字數限制高達 500 字,並支援仔細的媒體警告選項,令你暢所欲言。
real_conversation_title: 為真正的交流而生
within_reach_body: 簡易的 API 系統,令用戶可以透過不同的 iOS、Android 及其他平台的應用軟件,與朋友保持聯繫。
within_reach_title: 無處不在
generic_description: "%{domain} 是 Mastodon 網絡中其中一個服務站"
hosted_on: 在 %{domain} 運作的 Mastodon 服務站
learn_more: 了解更多
other_instances: 其他服務站
source_code: 源代碼
status_count_after: 篇文章
status_count_before: 他們共發佈了
user_count_after: 位使用者
user_count_before: 這裏共註冊有
what_is_mastodon: Mastodon 是甚麼?
accounts:
follow: 關注
followers: 關注者
following: 正在關注
media: 媒體
moved_html: "%{name} 已經轉移到 %{new_profile_link}"
nothing_here: 暫時未有內容可以顯示
people_followed_by: "%{name} 關注的人"
people_who_follow: 關注 %{name} 的人
posts: 文章
posts_with_replies: 文章和回覆
remote_follow: 跨站關注
reserved_username: 此用戶名已被保留
roles:
admin: 管理員
moderator: 監察员
unfollow: 取消關注
admin:
account_moderation_notes:
account: 管理員
create: 新增
created_at: 日期
created_msg: 管理記錄已新增
delete: 刪除
destroyed_msg: 管理記錄已被刪除
accounts:
are_you_sure: 你確定嗎?
by_domain: 域名
confirm: 確定
confirmed: 已確定
demote: 降任
disable: 停用
disable_two_factor_authentication: 停用雙重認證
disabled: 已停用
display_name: 顯示名稱
domain: 域名
edit: 編輯
email: 電郵地址
enable: 啟用
enabled: 已啟用
feed_url: Feed URL
followers: 關注者
followers_url: 關注者FollowersURL
follows: 正在關注
inbox_url: 收件箱InboxURL
ip: IP 位域
location:
all: 全部
local: 本地
remote: 遠端
title: 地點
login_status: 登入狀態
media_attachments: 媒體檔案
memorialize: 設定為追悼帳戶
moderation:
all: 全部
silenced: 被靜音的
suspended: 被停權的
title: 管理操作
moderation_notes: 管理記錄
most_recent_activity: 最新活動
most_recent_ip: 最新 IP 位域
not_subscribed: 未訂閱
@ -55,23 +100,90 @@ zh-HK:
alphabetic: 按字母
most_recent: 按時間
title: 排序
outbox_url: 寄件箱OutboxURL
perform_full_suspension: 實行完全暫停
profile_url: 個人檔案 URL
promote: 升任
protocol: 協議
public: 公共
push_subscription_expires: PuSH 訂閱過期
redownload: 更新頭像
reset: 重設
reset_password: 重設密碼
resubscribe: 重新訂閱
role: 身份
roles:
admin: 管理員
moderator: 監察员
staff: 管理人員
user: 普通用戶
salmon_url: Salmon 反饋 URL
search: 搜索
shared_inbox_url: 公共收件箱Shared InboxURL
show:
created_reports: 此用戶所提舉報的紀錄
report: 舉報
targeted_reports: 此用戶被舉報的紀錄
silence: 靜音
statuses: 文章
subscribe: 訂閱
title: 用戶
undo_silenced: 解除靜音
undo_suspension: 解除停權
unsubscribe: 取消訂閱
username: 用戶名稱
web: 用戶頁面
action_logs:
actions:
confirm_user: "%{name} 確認了用戶 %{target} 的電郵地址"
create_custom_emoji: "%{name} 加入自訂表情符號 %{target}"
create_domain_block: "%{name} 阻隔了網域 %{target}"
create_email_domain_block: "%{name} 阻隔了電郵網域 %{target}"
demote_user: "%{name} 把用戶 %{target} 降任"
destroy_domain_block: "%{name} 取消了對網域 %{target} 的阻隔"
destroy_email_domain_block: "%{name} 取消了對電郵網域 %{target} 的阻隔"
destroy_status: "%{name} 刪除了 %{target} 的文章"
disable_2fa_user: "%{name} 停用了用戶 %{target} 的雙重認證"
disable_custom_emoji: "%{name} 停用了自訂表情符號 %{target}"
disable_user: "%{name} 把用戶 %{target} 設定為禁止登入"
enable_custom_emoji: "%{name} 啟用了自訂表情符號 %{target}"
enable_user: "%{name} 把用戶 %{target} 設定為允許登入"
memorialize_account: "%{name} 把 %{target} 設定為追悼帳戶"
promote_user: "%{name} 對用戶 %{target} 进行了升任操作"
reset_password_user: "%{name} 重設了用戶 %{target} 的密碼"
resolve_report: "%{name} 處理了 %{target} 的舉報"
silence_account: "%{name} 靜音了用戶 %{target}"
suspend_account: "%{name} 停權了用戶 %{target}"
unsilence_account: "%{name} 取消了用戶 %{target} 的靜音狀態"
unsuspend_account: "%{name} 取消了用戶 %{target} 的停權狀態"
update_custom_emoji: "%{name} 更新了自訂表情符號 %{target}"
update_status: "%{name} 刷新了 %{target} 的文章"
title: 營運日誌
custom_emojis:
by_domain: 網域
copied_msg: 成功將表情複製到本地
copy: 複製
copy_failed_msg: 無法將表情複製到本地
created_msg: 已新增表情符號
delete: 刪除
destroyed_msg: 已刪除表情符號
disable: 停用
disabled_msg: 已停用表情符號
emoji: emoji
enable: 啟用
enabled_msg: 已啟用表情符號
image_hint: PNG 格式,最大 50KB
listed: 已顯示
new:
title: 加入新的自訂表情符號
overwrite: 覆蓋
shortcode: 短代碼
shortcode_hint: 至少 2 個字元,只能使用字母、數字和下劃線
title: 自訂 emoji
unlisted: 已隱藏
update_failed_msg: 無法更新表情符號
updated_msg: 已更新表情符號
upload: 上傳新的表情符號
domain_blocks:
add_new: 新增
created_msg: 正處理域名阻隔
@ -82,12 +194,14 @@ zh-HK:
hint: "「域名阻隔」不會隔絕該域名用戶的用戶進入本站資料庫,而是會在時候自動套用特定的審批操作。"
severity:
desc_html: "「<strong>自動靜音</strong>」令該域名用戶的文章,設為只對關注者顯示,沒有關注的人會看不到。 「<strong>自動刪除</strong>」會自動將該域名用戶的文章、媒體檔案、個人資料自本服務站刪除。"
noop:
silence: 自動靜音
suspend: 自動刪除
title: 新增域名阻隔
reject_media: 拒絕媒體檔案
reject_media_hint: 刪除本地緩存的媒體檔案,再也不在未來下載這個站點的檔案。和自動刪除無關。
severities:
noop:
silence: 自動靜音
suspend: 自動刪除
severity: 阻隔分級
@ -101,17 +215,41 @@ zh-HK:
undo: 撤銷
title: 域名阻隔
undo: 撤銷
email_domain_blocks:
add_new: 加入新項目
created_msg: 已新增電郵網域阻隔
delete: 刪除
destroyed_msg: 已刪除電郵網域阻隔
domain: 網域
new:
create: 新增網域
title: 新增電郵網域阻隔
title: 電郵網域阻隔
instances:
account_count: 已知帳號
domain_name: 域名
reset: 重設
search: 搜索
title: 已知服務站
invites:
filter:
all: 全部
available: 可用
expired: 已失效
title: 篩選
title: 邀請用戶
reports:
action_taken_by: 操作執行者
are_you_sure: 你確認嗎?
comment:
label: 詳細解釋
none: 沒有
delete: 刪除
id: ID
mark_as_resolved: 標示為「已處理」
nsfw:
'false': 取消 NSFW 標記
'true': 添加 NSFW 標記
report: '舉報 #%{id}'
report_contents: 舉報內容
reported_account: 舉報用戶
@ -125,23 +263,66 @@ zh-HK:
unresolved: 未處理
view: 檢視
settings:
activity_api_enabled:
desc_html: 本站用戶發佈的文章,以及本站的活躍用戶和一週內新用戶數
title: 公開用戶活躍度的統計數據
bootstrap_timeline_accounts:
desc_html: 以半形逗號分隔多個用戶名。只能加入來自本站且未開啟保護的帳號。如果留空,則默認關注本站所有管理員。
title: 新用戶默認關注
contact_information:
email: 輸入一個公開的電郵地址
username: 輸入用戶名稱
peers_api_enabled:
desc_html: 現時本服務站在網絡中已發現的域名
title: 公開已知服務站的列表
registrations:
closed_message:
desc_html: 當本站暫停接受註冊時,會顯示這個訊息。<br/> 可使用 HTML
title: 暫停註冊訊息
deletion:
desc_html: 允許所有人刪除自己的帳戶
title: 開放刪除帳戶的權限
min_invite_role:
disabled: 沒有人
title: 允許發送邀請的身份
open:
desc_html: 允許所有人建立帳戶
title: 開放註冊
show_staff_badge:
desc_html: 在個人資料頁上顯示管理人員標誌
title: 顯示管理人員標誌
site_description:
desc_html: 在首頁顯示,及在 meta 標籤使用作網站介紹。<br/> 你可以在此使用 <code>&lt;a&gt;</code> 和 <code>&lt;em&gt;</code> 等 HTML 標籤。
title: 本站介紹
site_description_extended:
desc_html: 本站詳細資訊頁的內文<br/>你可以在此使用 HTML
title: 本站詳細資訊
site_terms:
desc_html: 可以填寫自己的隱私權政策、使用條款或其他法律文本。可以使用 HTML 標籤
title: 自訂使用條款
site_title: 本站名稱
thumbnail:
desc_html: 用於在 OpenGraph 和 API 中顯示預覽圖。推薦大小 1200×630px
title: 本站縮圖
timeline_preview:
desc_html: 在主頁顯示本站時間軸
title: 時間軸預覽
title: 網站設定
statuses:
back_to_account: 返回帳戶信息頁
batch:
delete: 刪除
nsfw_off: 取消 NSFW 標記
nsfw_on: 添加 NSFW 標記
execute: 執行
failed_to_execute: 執行失敗
media:
hide: 隱藏媒體檔案
show: 顯示媒體檔案
title: 媒體檔案
no_media: 不含媒體檔案
title: 帳戶文章
with_media: 含有媒體檔案
subscriptions:
callback_url: 回傳 URL
confirmed: 確定
@ -150,16 +331,36 @@ zh-HK:
title: PuSH 訂閱
topic: 所訂閱資源
title: 管理
admin_mailer:
new_report:
body: "%{reporter} 舉報了用戶 %{target}。"
subject: 來自 %{instance} 的用戶舉報(#%{id}
application_mailer:
notification_preferences: 更改電郵首選項
salutation: "%{name}"
settings: 修改電郵設定︰%{link}
view: 進入瀏覽︰
view_profile: 檢視個人資料頁
view_status: 檢視文章
applications:
created: 已建立應用
destroyed: 已刪除應用
invalid_url: 所提供的網址不正確
regenerate_token: 重設 token
token_regenerated: 已重設 token
warning: 警告,不要把它分享給任何人!
your_token: token
auth:
agreement_html: 登記即表示你同意遵守<a href="%{rules_path}">本服務站的規則</a>和<a href="%{terms_path}">使用條款</a>。
delete_account: 刪除帳戶
delete_account_html: 如果你想刪除你的帳戶,請<a href="%{path}">點擊這裡繼續</a>。你需要確認你的操作。
didnt_get_confirmation: 沒有收到確認指示電郵?
forgot_password: 忘記了密碼?
invalid_reset_password_token: 密碼重置 token 無效或已過期。請重新重設密碼。
login: 登入
logout: 登出
migrate_account: 轉移到另一個帳號
migrate_account_html: 想要將這個帳號指向另一個帳號可<a href="%{path}">到這裡設定</a>。
register: 登記
resend_confirmation: 重發確認指示電郵
reset_password: 重設密碼
@ -168,6 +369,12 @@ zh-HK:
authorize_follow:
error: 對不起,尋找這個跨站用戶的過程發生錯誤
follow: 關注
follow_request: 關注請求已發送给:
following: 成功!你正在關注:
post_follow:
close: 你也可以直接關閉這個頁面
return: 返回至個人資料頁
web: 返回本站
title: 關注 %{acct}
datetime:
distance_in_words:
@ -183,6 +390,14 @@ zh-HK:
x_minutes: "%{count}分鐘"
x_months: "%{count}個月"
x_seconds: "%{count}秒"
deletes:
bad_password_msg: 想得美,黑客!密碼輸入錯誤
confirm_password: 輸入你現在的密碼來驗證身份
description_html: 繼續操作將會<strong>永久地、不可還原地</strong>刪除帳戶中的所有內容,然後凍結帳戶。你的用戶名將會被保留,以防有人冒用你的身份。
proceed: 刪除帳戶
success_msg: 你的帳戶已經成功刪除
warning_html: 我們只能保證本服務站上的內容將會被徹底刪除。對於已經被廣泛傳播的內容,它們在本服務站以外的某些地方可能仍然可見。此外,失去連接的服務站以及停止接收訂閱的服務站所存儲的數據亦無法刪除。
warning_title: 關於已傳播的內容的警告
errors:
'403': 你沒有觀看本頁的權限
'404': 找不到內容
@ -191,6 +406,10 @@ zh-HK:
content: 無法確認登入資訊。會不會你阻擋了本站使用 Cookies 的權限?
title: 無法確認登入資訊
'429': 伺服器繁忙
'500':
content: 抱歉,我們的後台出錯了。
title: 這個頁面有問題
noscript_html: 使用 Mastodon 網頁版應用需要啟用 JavaScript。你也可以選擇適用於你的平台的 <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">Mastodon 應用</a>。
exports:
blocks: 被你封鎖的用戶
csv: CSV
@ -224,14 +443,44 @@ zh-HK:
following: 你所關注的用戶名單
muting: 靜音名單
upload: 上載
in_memoriam_html: 謹此悼念。
invites:
delete: 停用
expired: 已失效
expires_in:
'1800': 30 分鐘後
'21600': 6 小時後
'3600': 1 小時後
'43200': 12 小時後
'86400': 1 天後
expires_in_prompt: 永不過期
generate: 生成邀請連結
max_uses: "%{count} 次"
max_uses_prompt: 無限制
prompt: 生成分享連結,邀請他人在本服務站註冊
table:
expires_at: 失效時間
uses: 已使用次數
title: 邀請用戶
landing_strip_html: "<strong>%{name}</strong> 是一個在 %{link_to_root_path} 的用戶。只要你有任何 Mastodon 服務站、或者聯盟網站的用戶,便可以跨站關注此站用戶,或者與他們互動。"
landing_strip_signup_html: 如果你沒有這類用戶,歡迎在<a href="%{sign_up_path}">此處登記</a>。
lists:
errors:
limit: 你所建立的列表數量已經達到上限
media_attachments:
validations:
images_and_video: 不能在已有圖片的文章上加入影片
too_many: 不可以加入超過 4 個檔案
migrations:
acct: 新帳戶的 用戶名@域名
currently_redirecting: 目前你的個人資料頁顯示的新帳戶是:
proceed: 保存
updated_msg: 帳戶遷移設置更新成功!
moderation:
title: 營運
notification_mailer:
digest:
action: 查看所有通知
body: 這是自從你在%{since}使用%{instance}以後,你錯失了的訊息︰
mention: "%{name} 在此提及了你︰"
new_followers_summary:
@ -240,21 +489,29 @@ zh-HK:
subject:
one: "自從上次登入以來,你收到 1 則新的通知 \U0001F418"
other: "自從上次登入以來,你收到 %{count} 則新的通知 \U0001F418"
title: 在你不在的這段時間……
favourite:
body: 你的文章是 %{name} 的最愛!
subject: "%{name} 收藏了你的文章"
title: 新的收藏
follow:
body: "%{name} 開始關注你!"
subject: "%{name} 現正關注你"
title: 新的關注者
follow_request:
action: 處理關注請求
body: "%{name} 要求關注你"
subject: 等候關注你的用戶︰ %{name}
title: 新的關注請求
mention:
action: 回覆
body: "%{name} 在文章中提及你︰"
subject: "%{name} 在文章中提及你"
title: 新的提及
reblog:
body: 你的文章得到 %{name} 的轉推
subject: "%{name} 轉推了你的文章"
title: 新的轉推
number:
human:
decimal_units:
@ -270,25 +527,94 @@ zh-HK:
next: 下一頁
prev: 上一頁
truncate: "……"
preferences:
languages: 語言
other: 其他
publishing: 發佈
web: 站内
push_notifications:
favourite:
title: "%{name} 收藏了你的文章"
follow:
title: "%{name} 關注了你"
group:
title: "%{count} 條新通知"
mention:
action_boost: 轉推
action_expand: 顯示更多
action_favourite: 收藏
title: "%{name} 提到了你"
reblog:
title: "%{name} 轉推了你的文章"
remote_follow:
acct: 請輸入你的︰用戶名稱@服務點域名
missing_resource: 無法找到你用戶的轉接網址
proceed: 下一步
prompt: 你希望關注︰
sessions:
activity: 最近活動
browser: 瀏覽器
browsers:
alipay: 支付寶
blackberry: Blackberry
chrome: Chrome
edge: Microsoft Edge
firefox: Firefox
generic: 未知的瀏覽器
ie: Internet Explorer
micro_messenger: 微信
nokia: Nokia S40 Ovi 瀏覽器
opera: Opera
phantom_js: PhantomJS
qq: QQ瀏覽器
safari: Safari
uc_browser: UC瀏覽器
weibo: 新浪微博
current_session: 目前的 session
description: "%{platform} 上的 %{browser}"
explanation: 這些是現在正登入於你的 Mastodon 帳號的瀏覽器。
ip: IP 位址
platforms:
adobe_air: Adobe Air
android: Android
blackberry: Blackberry
chrome_os: ChromeOS
firefox_os: Firefox OS
ios: iOS
linux: Linux
mac: Mac
other: 未知平台
windows: Windows
windows_mobile: Windows Mobile
windows_phone: Windows Phone
revoke: 取消
revoke_success: Session 取消成功。
title: Session
settings:
authorized_apps: 授權應用程式
back: 回到 Mastodon
delete: 刪除帳戶
development: 開發
edit_profile: 修改個人資料
export: 匯出
followers: 授權關注
import: 匯入
migrate: 帳戶遷移
notifications: 通知
preferences: 偏好設定
settings: 設定
two_factor_authentication: 雙重認證
your_apps: 你的應用程式
statuses:
open_in_web: 開啟網頁
over_character_limit: 超過了 %{max} 字的限制
pin_errors:
limit: 你所置頂的文章數量已經達到上限
ownership: 不能置頂他人的文章
private: 不能置頂非公開的文章
reblog: 不能置頂轉推
show_more: 顯示更多
title: "%{name}:「%{quote}」"
visibilities:
private: 關注者觀看
private_long: 只有關注你的人能看到
@ -298,8 +624,11 @@ zh-HK:
unlisted_long: 所有人都能看到,但不在公共時間軸(本站時間軸、跨站時間軸)顯示
stream_entries:
click_to_show: 點擊顯示
pinned: 置頂文章
reblogged: 轉推
sensitive_content: 敏感內容
terms:
title: "%{instance} 使用條款和隱私權政策"
time:
formats:
default: "%Y年%-m月%d日 %H:%M"
@ -308,15 +637,37 @@ zh-HK:
description_html: 當你啟用<strong>雙重認證</strong>後,你登入時將需要使你手機、或其他種類認證器產生的代碼。
disable: 停用
enable: 啟用
enabled: 雙重認證已啟用
enabled_success: 已成功啟用雙重認證
generate_recovery_codes: 產生備用驗證碼
instructions_html: "<strong>請用你手機的認證器應用程式(如 Google Authenticator、Authy掃描這裏的QR 圖形碼</strong>。在雙重認證啟用後,你登入時將須要使用此應用程式產生的認證碼。"
lost_recovery_codes: 讓你可以在遺失電話時,使用備用驗證碼登入。如果你遺失了備用驗證碼,可以在這裏產生一批新的,舊有的備用驗證碼將會失效。
manual_instructions: 如果你無法掃描 QR 圖形碼,請手動輸入這個文字密碼︰
recovery_codes: 備份恢復驗證碼
recovery_codes_regenerated: 成功產生新的備用驗證碼
recovery_instructions_html: 如果你遺失了安裝認證器的裝置(如︰你的電話),你可以使用備用驗證碼進行登入。請確保將備用驗證碼收藏穩當,(如列印出來,和你其他重要文件一起存放)
setup: 設定
wrong_code: 你輸入的認證碼並不正確!可能伺服器時間和你手機不一致,請檢查你手機的時鐘,或與本站管理員聯絡。
user_mailer:
welcome:
edit_profile_action: 設定個人資料
edit_profile_step: 你可以設定你的個人資料,包括上傳頭像、橫幅圖片、更改顯示名稱等等。如果你想在新的關注者關注你之前對他們進行審核,你也可以選擇為你的帳戶設為「私人」。
explanation: 下面是幾個小貼士,希望它們能幫到你
final_action: 開始發文
final_step: '開始發文吧!即使你現在沒有關注者,其他人仍然能在本站時間軸或者話題標籤等地方看到你的公開文章。試著用 #introductions 這個話題標籤介紹一下自己吧。'
full_handle: 你的完整用戶地址
full_handle_hint: 你需要把這個告訴你的朋友們,這樣他們就能從另一個實例向你發送信息或者關注你。
review_preferences_action: 更改首選項
review_preferences_step: 記得調整你的偏好設置,比如你想接收什麼類型的郵件,或者你想把你的文章可見範圍默認設定為什麼級別。如果你沒有暈車的話,考慮一下啟用「自動播放 GIF 動畫」這個選項吧。
subject: 歡迎來到 Mastodon
tip_bridge_html: 如果你剛從 Twitter 來到這裡,你可以在<a href="%{bridge_url}">橋樑站bridge app</a>上尋找你的朋友。當然,前提是他們也登錄了橋樑站!
tip_federated_timeline: 跨站公共時間軸可以讓你一窺更廣闊的 Mastodon 網絡。不過,由於它只顯示你的鄰居們所訂閱的內容,所以並不是全部。
tip_following: 默認情況下,你會自動關注你所在服務站的管理員。想結交更多有趣的人的話,記得多逛逛本站時間軸和跨站公共時間軸哦。
tip_local_timeline: 本站時間軸可以讓你一窺 %{instance} 上的用戶。他們就是離你最近的鄰居!
tip_mobile_webapp: 如果你的移動設備瀏覽器允許你將 Mastodon 添加到主屏幕,你就能夠接收推送消息。它就像本地應用一樣好使!
tips: 小貼士
title: "%{name},歡迎你的加入!"
users:
invalid_email: 電郵地址格式不正確
invalid_otp_token: 雙重認證確認碼不正確
signed_in_as: 目前登入的帳戶:

View File

@ -394,6 +394,45 @@ RSpec.describe Formatter do
end
end
context 'with custom_emojify option' do
let!(:emoji) { Fabricate(:custom_emoji) }
before { account.note = text }
subject { Formatter.instance.simplified_format(account, custom_emojify: true) }
context 'with emoji at the start' do
let(:text) { ':coolcat: Beep boop' }
it 'converts shortcode to image tag' do
is_expected.to match(/<p><img draggable="false" class="emojione" alt=":coolcat:"/)
end
end
context 'with emoji in the middle' do
let(:text) { 'Beep :coolcat: boop' }
it 'converts shortcode to image tag' do
is_expected.to match(/Beep <img draggable="false" class="emojione" alt=":coolcat:"/)
end
end
context 'with concatenated emoji' do
let(:text) { ':coolcat::coolcat:' }
it 'does not touch the shortcodes' do
is_expected.to match(/:coolcat::coolcat:/)
end
end
context 'with emoji at the end' do
let(:text) { 'Beep boop :coolcat:' }
it 'converts shortcode to image tag' do
is_expected.to match(/boop <img draggable="false" class="emojione" alt=":coolcat:"/)
end
end
end
include_examples 'encode and link URLs'
end
@ -404,6 +443,46 @@ RSpec.describe Formatter do
it 'reformats' do
is_expected.to_not include '<script>alert("Hello")</script>'
end
context 'with custom_emojify option' do
let!(:emoji) { Fabricate(:custom_emoji, domain: remote_account.domain) }
before { remote_account.note = text }
subject { Formatter.instance.simplified_format(remote_account, custom_emojify: true) }
context 'with emoji at the start' do
let(:text) { '<p>:coolcat: Beep boop<br />' }
it 'converts shortcode to image tag' do
is_expected.to match(/<p><img draggable="false" class="emojione" alt=":coolcat:"/)
end
end
context 'with emoji in the middle' do
let(:text) { '<p>Beep :coolcat: boop</p>' }
it 'converts shortcode to image tag' do
is_expected.to match(/Beep <img draggable="false" class="emojione" alt=":coolcat:"/)
end
end
context 'with concatenated emoji' do
let(:text) { '<p>:coolcat::coolcat:</p>' }
it 'does not touch the shortcodes' do
is_expected.to match(/<p>:coolcat::coolcat:<\/p>/)
end
end
context 'with emoji at the end' do
let(:text) { '<p>Beep boop<br />:coolcat:</p>' }
it 'converts shortcode to image tag' do
is_expected.to match(/<br><img draggable="false" class="emojione" alt=":coolcat:"/)
end
end
end
end
end