+
-
-
+
-
+
diff --git a/src/components/settings_modal/tabs/version_tab.js b/src/components/settings_modal/tabs/version_tab.js
new file mode 100644
index 00000000..616bdadf
--- /dev/null
+++ b/src/components/settings_modal/tabs/version_tab.js
@@ -0,0 +1,24 @@
+import { extractCommit } from 'src/services/version/version.service'
+
+const pleromaFeCommitUrl = 'https://git.pleroma.social/pleroma/pleroma-fe/commit/'
+const pleromaBeCommitUrl = 'https://git.pleroma.social/pleroma/pleroma/commit/'
+
+const VersionTab = {
+ data () {
+ const instance = this.$store.state.instance
+ return {
+ backendVersion: instance.backendVersion,
+ frontendVersion: instance.frontendVersion
+ }
+ },
+ computed: {
+ frontendVersionLink () {
+ return pleromaFeCommitUrl + this.frontendVersion
+ },
+ backendVersionLink () {
+ return pleromaBeCommitUrl + extractCommit(this.backendVersion)
+ }
+ }
+}
+
+export default VersionTab
diff --git a/src/components/settings_modal/tabs/version_tab.vue b/src/components/settings_modal/tabs/version_tab.vue
new file mode 100644
index 00000000..d35ff25e
--- /dev/null
+++ b/src/components/settings_modal/tabs/version_tab.vue
@@ -0,0 +1,31 @@
+
+
-
+
+
+
+
+
-
-
-
-
+
+
@@ -29,50 +38,25 @@
diff --git a/src/i18n/ar.json b/src/i18n/ar.json
index 72e3010f..8bba2b97 100644
--- a/src/i18n/ar.json
+++ b/src/i18n/ar.json
@@ -1,206 +1,206 @@
{
- "chat": {
- "title": "الدردشة"
+ "chat": {
+ "title": "الدردشة"
+ },
+ "features_panel": {
+ "chat": "الدردشة",
+ "gopher": "غوفر",
+ "media_proxy": "بروكسي الوسائط",
+ "scope_options": "",
+ "text_limit": "الحد الأقصى للنص",
+ "title": "الميّزات",
+ "who_to_follow": "للمتابعة"
+ },
+ "finder": {
+ "error_fetching_user": "خطأ أثناء جلب صفحة المستخدم",
+ "find_user": "البحث عن مستخدِم"
+ },
+ "general": {
+ "apply": "تطبيق",
+ "submit": "إرسال"
+ },
+ "login": {
+ "login": "تسجيل الدخول",
+ "logout": "الخروج",
+ "password": "الكلمة السرية",
+ "placeholder": "مثال lain",
+ "register": "انشاء حساب",
+ "username": "إسم المستخدم"
+ },
+ "nav": {
+ "chat": "الدردشة المحلية",
+ "friend_requests": "طلبات المتابَعة",
+ "mentions": "الإشارات",
+ "public_tl": "الخيط الزمني العام",
+ "timeline": "الخيط الزمني",
+ "twkn": "كافة الشبكة المعروفة"
+ },
+ "notifications": {
+ "broken_favorite": "منشور مجهول، جارٍ البحث عنه…",
+ "favorited_you": "أعجِب بمنشورك",
+ "followed_you": "يُتابعك",
+ "load_older": "تحميل الإشعارات الأقدم",
+ "notifications": "الإخطارات",
+ "read": "مقروء!",
+ "repeated_you": "شارَك منشورك"
+ },
+ "post_status": {
+ "account_not_locked_warning": "",
+ "account_not_locked_warning_link": "مقفل",
+ "attachments_sensitive": "اعتبر المرفقات كلها كمحتوى حساس",
+ "content_type": {
+ "text/plain": "نص صافٍ"
},
- "features_panel": {
- "chat": "الدردشة",
- "gopher": "غوفر",
- "media_proxy": "بروكسي الوسائط",
- "scope_options": "",
- "text_limit": "الحد الأقصى للنص",
- "title": "الميّزات",
- "who_to_follow": "للمتابعة"
- },
- "finder": {
- "error_fetching_user": "خطأ أثناء جلب صفحة المستخدم",
- "find_user": "البحث عن مستخدِم"
- },
- "general": {
- "apply": "تطبيق",
- "submit": "إرسال"
- },
- "login": {
- "login": "تسجيل الدخول",
- "logout": "الخروج",
- "password": "الكلمة السرية",
- "placeholder": "مثال lain",
- "register": "انشاء حساب",
- "username": "إسم المستخدم"
- },
- "nav": {
- "chat": "الدردشة المحلية",
- "friend_requests": "طلبات المتابَعة",
- "mentions": "الإشارات",
- "public_tl": "الخيط الزمني العام",
- "timeline": "الخيط الزمني",
- "twkn": "كافة الشبكة المعروفة"
- },
- "notifications": {
- "broken_favorite": "منشور مجهول، جارٍ البحث عنه…",
- "favorited_you": "أعجِب بمنشورك",
- "followed_you": "يُتابعك",
- "load_older": "تحميل الإشعارات الأقدم",
- "notifications": "الإخطارات",
- "read": "مقروء!",
- "repeated_you": "شارَك منشورك"
- },
- "post_status": {
- "account_not_locked_warning": "",
- "account_not_locked_warning_link": "مقفل",
- "attachments_sensitive": "اعتبر المرفقات كلها كمحتوى حساس",
- "content_type": {
- "text/plain": "نص صافٍ"
- },
- "content_warning": "الموضوع (اختياري)",
- "default": "وصلت للتوّ إلى لوس أنجلس.",
- "direct_warning": "",
- "posting": "النشر",
- "scope": {
- "direct": "",
- "private": "",
- "public": "علني - يُنشر على الخيوط الزمنية العمومية",
- "unlisted": "غير مُدرَج - لا يُنشَر على الخيوط الزمنية العمومية"
- }
- },
- "registration": {
- "bio": "السيرة الذاتية",
- "email": "عنوان البريد الإلكتروني",
- "fullname": "الإسم المعروض",
- "password_confirm": "تأكيد الكلمة السرية",
- "registration": "التسجيل",
- "token": "رمز الدعوة"
- },
- "settings": {
- "attachmentRadius": "المُرفَقات",
- "attachments": "المُرفَقات",
- "autoload": "",
- "avatar": "الصورة الرمزية",
- "avatarAltRadius": "الصور الرمزية (الإشعارات)",
- "avatarRadius": "الصور الرمزية",
- "background": "الخلفية",
- "bio": "السيرة الذاتية",
- "btnRadius": "الأزرار",
- "cBlue": "أزرق (الرد، المتابَعة)",
- "cGreen": "أخضر (إعادة النشر)",
- "cOrange": "برتقالي (مفضلة)",
- "cRed": "أحمر (إلغاء)",
- "change_password": "تغيير كلمة السر",
- "change_password_error": "وقع هناك خلل أثناء تعديل كلمتك السرية.",
- "changed_password": "تم تغيير كلمة المرور بنجاح!",
- "collapse_subject": "",
- "confirm_new_password": "تأكيد كلمة السر الجديدة",
- "current_avatar": "صورتك الرمزية الحالية",
- "current_password": "كلمة السر الحالية",
- "current_profile_banner": "الرأسية الحالية لصفحتك الشخصية",
- "data_import_export_tab": "تصدير واستيراد البيانات",
- "default_vis": "أسلوب العرض الافتراضي",
- "delete_account": "حذف الحساب",
- "delete_account_description": "حذف حسابك و كافة منشوراتك نهائيًا.",
- "delete_account_error": "",
- "delete_account_instructions": "يُرجى إدخال كلمتك السرية أدناه لتأكيد عملية حذف الحساب.",
- "export_theme": "حفظ النموذج",
- "filtering": "التصفية",
- "filtering_explanation": "سيتم إخفاء كافة المنشورات التي تحتوي على هذه الكلمات، كلمة واحدة في كل سطر",
- "follow_export": "تصدير الاشتراكات",
- "follow_export_button": "تصدير الاشتراكات كملف csv",
- "follow_export_processing": "التصدير جارٍ، سوف يُطلَب منك تنزيل ملفك بعد حين",
- "follow_import": "استيراد الاشتراكات",
- "follow_import_error": "خطأ أثناء استيراد المتابِعين",
- "follows_imported": "",
- "foreground": "الأمامية",
- "general": "الإعدادات العامة",
- "hide_attachments_in_convo": "إخفاء المرفقات على المحادثات",
- "hide_attachments_in_tl": "إخفاء المرفقات على الخيط الزمني",
- "hide_post_stats": "",
- "hide_user_stats": "",
- "import_followers_from_a_csv_file": "",
- "import_theme": "تحميل نموذج",
- "inputRadius": "",
- "instance_default": "",
- "interfaceLanguage": "لغة الواجهة",
- "invalid_theme_imported": "",
- "limited_availability": "غير متوفر على متصفحك",
- "links": "الروابط",
- "lock_account_description": "",
- "loop_video": "",
- "loop_video_silent_only": "",
- "name": "الاسم",
- "name_bio": "الاسم والسيرة الذاتية",
- "new_password": "كلمة السر الجديدة",
- "no_rich_text_description": "",
- "notification_visibility": "نوع الإشعارات التي تريد عرضها",
- "notification_visibility_follows": "يتابع",
- "notification_visibility_likes": "الإعجابات",
- "notification_visibility_mentions": "الإشارات",
- "notification_visibility_repeats": "",
- "nsfw_clickthrough": "",
- "oauth_tokens": "رموز OAuth",
- "token": "رمز",
- "refresh_token": "رمز التحديث",
- "valid_until": "صالح حتى",
- "revoke_token": "سحب",
- "panelRadius": "",
- "pause_on_unfocused": "",
- "presets": "النماذج",
- "profile_background": "خلفية الصفحة الشخصية",
- "profile_banner": "رأسية الصفحة الشخصية",
- "profile_tab": "الملف الشخصي",
- "radii_help": "",
- "replies_in_timeline": "الردود على الخيط الزمني",
- "reply_link_preview": "",
- "reply_visibility_all": "عرض كافة الردود",
- "reply_visibility_following": "",
- "reply_visibility_self": "",
- "saving_err": "خطأ أثناء حفظ الإعدادات",
- "saving_ok": "تم حفظ الإعدادات",
- "security_tab": "الأمان",
- "set_new_avatar": "اختيار صورة رمزية جديدة",
- "set_new_profile_background": "اختيار خلفية جديدة للملف الشخصي",
- "set_new_profile_banner": "اختيار رأسية جديدة للصفحة الشخصية",
- "settings": "الإعدادات",
- "stop_gifs": "",
- "streaming": "",
- "text": "النص",
- "theme": "المظهر",
- "theme_help": "",
- "tooltipRadius": "",
- "user_settings": "إعدادات المستخدم",
- "values": {
- "false": "لا",
- "true": "نعم"
- }
- },
- "timeline": {
- "collapse": "",
- "conversation": "محادثة",
- "error_fetching": "خطأ أثناء جلب التحديثات",
- "load_older": "تحميل المنشورات القديمة",
- "no_retweet_hint": "",
- "repeated": "",
- "show_new": "عرض الجديد",
- "up_to_date": "تم تحديثه"
- },
- "user_card": {
- "approve": "قبول",
- "block": "حظر",
- "blocked": "تم حظره!",
- "deny": "رفض",
- "follow": "اتبع",
- "followees": "",
- "followers": "مُتابِعون",
- "following": "",
- "follows_you": "يتابعك!",
- "mute": "كتم",
- "muted": "تم كتمه",
- "per_day": "في اليوم",
- "remote_follow": "مُتابَعة عن بُعد",
- "statuses": "المنشورات"
- },
- "user_profile": {
- "timeline_title": "الخيط الزمني للمستخدم"
- },
- "who_to_follow": {
- "more": "المزيد",
- "who_to_follow": "للمتابعة"
+ "content_warning": "الموضوع (اختياري)",
+ "default": "وصلت للتوّ إلى لوس أنجلس.",
+ "direct_warning": "",
+ "posting": "النشر",
+ "scope": {
+ "direct": "",
+ "private": "",
+ "public": "علني - يُنشر على الخيوط الزمنية العمومية",
+ "unlisted": "غير مُدرَج - لا يُنشَر على الخيوط الزمنية العمومية"
}
-}
\ No newline at end of file
+ },
+ "registration": {
+ "bio": "السيرة الذاتية",
+ "email": "عنوان البريد الإلكتروني",
+ "fullname": "الإسم المعروض",
+ "password_confirm": "تأكيد الكلمة السرية",
+ "registration": "التسجيل",
+ "token": "رمز الدعوة"
+ },
+ "settings": {
+ "attachmentRadius": "المُرفَقات",
+ "attachments": "المُرفَقات",
+ "autoload": "",
+ "avatar": "الصورة الرمزية",
+ "avatarAltRadius": "الصور الرمزية (الإشعارات)",
+ "avatarRadius": "الصور الرمزية",
+ "background": "الخلفية",
+ "bio": "السيرة الذاتية",
+ "btnRadius": "الأزرار",
+ "cBlue": "أزرق (الرد، المتابَعة)",
+ "cGreen": "أخضر (إعادة النشر)",
+ "cOrange": "برتقالي (مفضلة)",
+ "cRed": "أحمر (إلغاء)",
+ "change_password": "تغيير كلمة السر",
+ "change_password_error": "وقع هناك خلل أثناء تعديل كلمتك السرية.",
+ "changed_password": "تم تغيير كلمة المرور بنجاح!",
+ "collapse_subject": "",
+ "confirm_new_password": "تأكيد كلمة السر الجديدة",
+ "current_avatar": "صورتك الرمزية الحالية",
+ "current_password": "كلمة السر الحالية",
+ "current_profile_banner": "الرأسية الحالية لصفحتك الشخصية",
+ "data_import_export_tab": "تصدير واستيراد البيانات",
+ "default_vis": "أسلوب العرض الافتراضي",
+ "delete_account": "حذف الحساب",
+ "delete_account_description": "حذف حسابك و كافة منشوراتك نهائيًا.",
+ "delete_account_error": "",
+ "delete_account_instructions": "يُرجى إدخال كلمتك السرية أدناه لتأكيد عملية حذف الحساب.",
+ "export_theme": "حفظ النموذج",
+ "filtering": "التصفية",
+ "filtering_explanation": "سيتم إخفاء كافة المنشورات التي تحتوي على هذه الكلمات، كلمة واحدة في كل سطر",
+ "follow_export": "تصدير الاشتراكات",
+ "follow_export_button": "تصدير الاشتراكات كملف csv",
+ "follow_export_processing": "التصدير جارٍ، سوف يُطلَب منك تنزيل ملفك بعد حين",
+ "follow_import": "استيراد الاشتراكات",
+ "follow_import_error": "خطأ أثناء استيراد المتابِعين",
+ "follows_imported": "",
+ "foreground": "الأمامية",
+ "general": "الإعدادات العامة",
+ "hide_attachments_in_convo": "إخفاء المرفقات على المحادثات",
+ "hide_attachments_in_tl": "إخفاء المرفقات على الخيط الزمني",
+ "hide_post_stats": "",
+ "hide_user_stats": "",
+ "import_followers_from_a_csv_file": "",
+ "import_theme": "تحميل نموذج",
+ "inputRadius": "",
+ "instance_default": "",
+ "interfaceLanguage": "لغة الواجهة",
+ "invalid_theme_imported": "",
+ "limited_availability": "غير متوفر على متصفحك",
+ "links": "الروابط",
+ "lock_account_description": "",
+ "loop_video": "",
+ "loop_video_silent_only": "",
+ "name": "الاسم",
+ "name_bio": "الاسم والسيرة الذاتية",
+ "new_password": "كلمة السر الجديدة",
+ "no_rich_text_description": "",
+ "notification_visibility": "نوع الإشعارات التي تريد عرضها",
+ "notification_visibility_follows": "يتابع",
+ "notification_visibility_likes": "الإعجابات",
+ "notification_visibility_mentions": "الإشارات",
+ "notification_visibility_repeats": "",
+ "nsfw_clickthrough": "",
+ "oauth_tokens": "رموز OAuth",
+ "token": "رمز",
+ "refresh_token": "رمز التحديث",
+ "valid_until": "صالح حتى",
+ "revoke_token": "سحب",
+ "panelRadius": "",
+ "pause_on_unfocused": "",
+ "presets": "النماذج",
+ "profile_background": "خلفية الصفحة الشخصية",
+ "profile_banner": "رأسية الصفحة الشخصية",
+ "profile_tab": "الملف الشخصي",
+ "radii_help": "",
+ "replies_in_timeline": "الردود على الخيط الزمني",
+ "reply_link_preview": "",
+ "reply_visibility_all": "عرض كافة الردود",
+ "reply_visibility_following": "",
+ "reply_visibility_self": "",
+ "saving_err": "خطأ أثناء حفظ الإعدادات",
+ "saving_ok": "تم حفظ الإعدادات",
+ "security_tab": "الأمان",
+ "set_new_avatar": "اختيار صورة رمزية جديدة",
+ "set_new_profile_background": "اختيار خلفية جديدة للملف الشخصي",
+ "set_new_profile_banner": "اختيار رأسية جديدة للصفحة الشخصية",
+ "settings": "الإعدادات",
+ "stop_gifs": "",
+ "streaming": "",
+ "text": "النص",
+ "theme": "المظهر",
+ "theme_help": "",
+ "tooltipRadius": "",
+ "user_settings": "إعدادات المستخدم",
+ "values": {
+ "false": "لا",
+ "true": "نعم"
+ }
+ },
+ "timeline": {
+ "collapse": "",
+ "conversation": "محادثة",
+ "error_fetching": "خطأ أثناء جلب التحديثات",
+ "load_older": "تحميل المنشورات القديمة",
+ "no_retweet_hint": "",
+ "repeated": "",
+ "show_new": "عرض الجديد",
+ "up_to_date": "تم تحديثه"
+ },
+ "user_card": {
+ "approve": "قبول",
+ "block": "حظر",
+ "blocked": "تم حظره!",
+ "deny": "رفض",
+ "follow": "اتبع",
+ "followees": "",
+ "followers": "مُتابِعون",
+ "following": "",
+ "follows_you": "يتابعك!",
+ "mute": "كتم",
+ "muted": "تم كتمه",
+ "per_day": "في اليوم",
+ "remote_follow": "مُتابَعة عن بُعد",
+ "statuses": "المنشورات"
+ },
+ "user_profile": {
+ "timeline_title": "الخيط الزمني للمستخدم"
+ },
+ "who_to_follow": {
+ "more": "المزيد",
+ "who_to_follow": "للمتابعة"
+ }
+}
diff --git a/src/i18n/de.json b/src/i18n/de.json
index a4b4c16f..a44e58cb 100644
--- a/src/i18n/de.json
+++ b/src/i18n/de.json
@@ -7,8 +7,8 @@
"gopher": "Gopher",
"media_proxy": "Medienproxy",
"scope_options": "Reichweitenoptionen",
- "text_limit": "Textlimit",
- "title": "Features",
+ "text_limit": "Zeichenlimit",
+ "title": "Funktionen",
"who_to_follow": "Wem folgen?"
},
"finder": {
@@ -17,7 +17,18 @@
},
"general": {
"apply": "Anwenden",
- "submit": "Absenden"
+ "submit": "Absenden",
+ "more": "Mehr",
+ "generic_error": "Ein Fehler ist aufgetreten",
+ "optional": "Optional",
+ "show_more": "Zeige mehr",
+ "show_less": "Zeige weniger",
+ "dismiss": "Ablehnen",
+ "cancel": "Abbrechen",
+ "disable": "Deaktivieren",
+ "enable": "Aktivieren",
+ "confirm": "Bestätigen",
+ "verify": "Verifizieren"
},
"login": {
"login": "Anmelden",
@@ -26,7 +37,16 @@
"password": "Passwort",
"placeholder": "z.B. lain",
"register": "Registrieren",
- "username": "Benutzername"
+ "username": "Benutzername",
+ "authentication_code": "Authentifizierungscode",
+ "enter_recovery_code": "Gebe einen Wiederherstellungscode ein",
+ "recovery_code": "Wiederherstellungscode",
+ "heading": {
+ "totp": "Zwei-Faktor Authentifizierung",
+ "recovery": "Zwei-Faktor Wiederherstellung"
+ },
+ "hint": "Anmelden um an der Diskussion teilzunehmen",
+ "enter_two_factor_code": "Gebe einen Zwei-Faktor-Code ein"
},
"nav": {
"about": "Über",
@@ -41,7 +61,9 @@
"twkn": "Das gesamte bekannte Netzwerk",
"user_search": "Benutzersuche",
"search": "Suche",
- "preferences": "Voreinstellungen"
+ "preferences": "Voreinstellungen",
+ "administration": "Administration",
+ "who_to_follow": "Wem folgen"
},
"notifications": {
"broken_favorite": "Unbekannte Nachricht, suche danach...",
@@ -50,7 +72,11 @@
"load_older": "Ältere Benachrichtigungen laden",
"notifications": "Benachrichtigungen",
"read": "Gelesen!",
- "repeated_you": "wiederholte deine Nachricht"
+ "repeated_you": "wiederholte deine Nachricht",
+ "follow_request": "möchte dir folgen",
+ "migrated_to": "migrierte zu",
+ "reacted_with": "reagierte mit {0}",
+ "no_more_notifications": "Keine Benachrichtigungen mehr"
},
"post_status": {
"new_status": "Neuen Status veröffentlichen",
@@ -58,7 +84,10 @@
"account_not_locked_warning_link": "gesperrt",
"attachments_sensitive": "Anhänge als heikel markieren",
"content_type": {
- "text/plain": "Nur Text"
+ "text/plain": "Nur Text",
+ "text/bbcode": "BBCode",
+ "text/markdown": "Markdown",
+ "text/html": "HTML"
},
"content_warning": "Betreff (optional)",
"default": "Sitze gerade im Hofbräuhaus.",
@@ -69,6 +98,13 @@
"private": "Nur Follower - Beitrag nur für Follower sichtbar",
"public": "Öffentlich - Beitrag an öffentliche Zeitleisten",
"unlisted": "Nicht gelistet - Nicht in öffentlichen Zeitleisten anzeigen"
+ },
+ "direct_warning_to_all": "Dieser Beitrag wird für alle erwähnten Benutzer sichtbar sein.",
+ "direct_warning_to_first_only": "Dieser Beitrag wird für alle Benutzer, die am Anfang der Nachricht erwähnt wurden, sichtbar sein.",
+ "scope_notice": {
+ "public": "Dieser Beitrag wird für alle sichtbar sein",
+ "private": "Dieser Beitrag wird nur für deine Follower sichtbar sein",
+ "unlisted": "Dieser Beitrag wird weder in der öffentlichen Zeitleiste noch im gesamten bekannten Netzwerk sichtbar sein"
}
},
"registration": {
@@ -86,8 +122,11 @@
"email_required": "darf nicht leer sein",
"password_required": "darf nicht leer sein",
"password_confirmation_required": "darf nicht leer sein",
- "password_confirmation_match": "sollte mit dem Passwort identisch sein."
- }
+ "password_confirmation_match": "sollte mit dem Passwort identisch sein"
+ },
+ "bio_placeholder": "z.B.\nHallo, ich bin Lain.\nIch bin ein Anime Mödchen aus dem vorstädtischen Japan. Du kennst mich vielleicht vom Wired.",
+ "fullname_placeholder": "z.B. Lain Iwakura",
+ "username_placeholder": "z.B. lain"
},
"settings": {
"attachmentRadius": "Anhänge",
@@ -99,7 +138,7 @@
"background": "Hintergrund",
"bio": "Bio",
"btnRadius": "Buttons",
- "cBlue": "Blau (Antworten, Folgt dir)",
+ "cBlue": "Blau (Antworten, folgt dir)",
"cGreen": "Grün (Retweet)",
"cOrange": "Orange (Favorisieren)",
"cRed": "Rot (Abbrechen)",
@@ -115,21 +154,21 @@
"data_import_export_tab": "Datenimport/-export",
"default_vis": "Standard-Sichtbarkeitsumfang",
"delete_account": "Account löschen",
- "delete_account_description": "Lösche deinen Account und alle deine Nachrichten unwiderruflich.",
+ "delete_account_description": "Lösche deine Daten und deaktiviere deinen Account unwiderruflich.",
"delete_account_error": "Es ist ein Fehler beim Löschen deines Accounts aufgetreten. Tritt dies weiterhin auf, wende dich an den Administrator der Instanz.",
"delete_account_instructions": "Tippe dein Passwort unten in das Feld ein, um die Löschung deines Accounts zu bestätigen.",
- "discoverable": "Erlaubnis für automatisches Suchen nach diesem Account",
+ "discoverable": "Erlaube, dass dieser Account in Suchergebnissen auftaucht",
"avatar_size_instruction": "Die empfohlene minimale Größe für Avatare ist 150x150 Pixel.",
"pad_emoji": "Emojis mit Leerzeichen umrahmen",
"export_theme": "Farbschema speichern",
"filtering": "Filtern",
- "filtering_explanation": "Alle Beiträge die diese Wörter enthalten werden ausgeblendet. Ein Wort pro Zeile.",
+ "filtering_explanation": "Alle Beiträge, welche diese Wörter enthalten, werden ausgeblendet. Ein Wort pro Zeile.",
"follow_export": "Follower exportieren",
"follow_export_button": "Exportiere deine Follows in eine csv-Datei",
"follow_export_processing": "In Bearbeitung. Die Liste steht gleich zum herunterladen bereit.",
- "follow_import": "Followers importieren",
- "follow_import_error": "Fehler beim importieren der Follower",
- "follows_imported": "Followers importiert! Die Bearbeitung kann eine Zeit lang dauern.",
+ "follow_import": "Follower importieren",
+ "follow_import_error": "Fehler beim Importieren der Follower",
+ "follows_imported": "Follower importiert! Die Bearbeitung kann einen Moment dauern.",
"foreground": "Vordergrund",
"general": "Allgemein",
"hide_attachments_in_convo": "Anhänge in Unterhaltungen ausblenden",
@@ -142,7 +181,7 @@
"hide_post_stats": "Beitragsstatistiken verbergen (z.B. die Anzahl der Favoriten)",
"hide_user_stats": "Benutzerstatistiken verbergen (z.B. die Anzahl der Follower)",
"hide_filtered_statuses": "Gefilterte Beiträge verbergen",
- "import_followers_from_a_csv_file": "Importiere Follower, denen du folgen möchtest, aus einer CSV-Datei",
+ "import_followers_from_a_csv_file": "Importiere Follower aus einer CSV-Datei",
"import_theme": "Farbschema laden",
"inputRadius": "Eingabefelder",
"checkboxRadius": "Auswahlfelder",
@@ -156,7 +195,7 @@
"lock_account_description": "Sperre deinen Account, um neue Follower zu genehmigen oder abzulehnen",
"loop_video": "Videos wiederholen",
"loop_video_silent_only": "Nur Videos ohne Ton wiederholen (z.B. Mastodons \"gifs\")",
- "mutes_tab": "Mutes",
+ "mutes_tab": "Stummschaltungen",
"play_videos_in_modal": "Videos in größerem Medienfenster abspielen",
"use_contain_fit": "Vorschaubilder nicht zuschneiden",
"name": "Name",
@@ -221,7 +260,7 @@
},
"notifications": "Benachrichtigungen",
"enable_web_push_notifications": "Web-Pushbenachrichtigungen aktivieren",
- "style": {
+ "style": {
"switcher": {
"keep_color": "Farben beibehalten",
"keep_shadows": "Schatten beibehalten",
@@ -329,7 +368,43 @@
"checkbox": "Ich habe die Allgemeinen Geschäftsbedingungen überflogen",
"link": "ein netter kleiner Link"
}
- }
+ },
+ "app_name": "Anwendungsname",
+ "mfa": {
+ "otp": "OTP",
+ "recovery_codes_warning": "Schreibe dir die Codes auf oder speichere sie an einem sicheren Ort - ansonsten wirst du sie nicht wiederfinden. Wenn du den Zugriff zu deiner 2FA App und die Wiederherstellungs-Codes verlierst, wirst du aus deinem Account ausgeschlossen sein.",
+ "recovery_codes": "Wiederherstellungs-Codes.",
+ "warning_of_generate_new_codes": "Wenn du neue Wiederherstellungs-Codes generierst, werden die alten Codes nicht mehr funktionieren.",
+ "generate_new_recovery_codes": "Generiere neue Wiederherstellungs-Codes",
+ "title": "Zwei-Faktor Authentifizierung",
+ "waiting_a_recovery_codes": "Erhalte Wiederherstellungscodes...",
+ "authentication_methods": "Authentifizierungsmethoden",
+ "scan": {
+ "title": "Scan",
+ "secret_code": "Schlüssel",
+ "desc": "Wenn du deine 2FA App verwendest, scanne diesen QR Code oder gebe den Schlüssel ein:"
+ },
+ "verify": {
+ "desc": "Um 2FA zu aktivieren, gib den Code von deiner 2FA-App ein:"
+ }
+ },
+ "enter_current_password_to_confirm": "Gib dein aktuelles Passwort ein, um deine Identität zu bestätigen",
+ "security": "Sicherheit",
+ "allow_following_move": "Erlaube automatisches Folgen, sobald ein gefolgter Nutzer umzieht",
+ "blocks_imported": "Blocks importiert! Die Verarbeitung wird einen Moment brauchen.",
+ "block_import_error": "Fehler beim Importieren der Blocks",
+ "block_import": "Block Import",
+ "block_export_button": "Exportiere deine Blocks in eine csv Datei",
+ "block_export": "Block Export",
+ "emoji_reactions_on_timeline": "Zeige Emoji-Reaktionen auf der Zeitleiste",
+ "domain_mutes": "Domains",
+ "changed_email": "Email Adresse erfolgreich geändert!",
+ "change_email_error": "Es trat ein Problem auf beim Versuch, deine Email Adresse zu ändern.",
+ "change_email": "Ändere Email",
+ "notification_setting_non_followers": "Nutzer, die dir nicht folgen",
+ "notification_setting_followers": "Nutzer, die dir folgen",
+ "import_blocks_from_a_csv_file": "Importiere Blocks von einer CSV Datei",
+ "accent": "Akzent"
},
"timeline": {
"collapse": "Einklappen",
@@ -352,7 +427,7 @@
"follow_again": "Anfrage erneut senden?",
"follow_unfollow": "Folgen beenden",
"followees": "Folgt",
- "followers": "Followers",
+ "followers": "Folgende",
"following": "Folgst du!",
"follows_you": "Folgt dir!",
"its_you": "Das bist du!",
@@ -360,7 +435,10 @@
"muted": "Stummgeschaltet",
"per_day": "pro Tag",
"remote_follow": "Folgen",
- "statuses": "Beiträge"
+ "statuses": "Beiträge",
+ "admin_menu": {
+ "sandbox": "Erzwinge Beiträge nur für Follower sichtbar zu sein"
+ }
},
"user_profile": {
"timeline_title": "Beiträge"
@@ -376,11 +454,11 @@
"favorite": "Favorisieren",
"user_settings": "Benutzereinstellungen"
},
- "upload":{
+ "upload": {
"error": {
- "base": "Hochladen fehlgeschlagen.",
- "file_too_big": "Datei ist zu groß [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
- "default": "Bitte versuche es später erneut"
+ "base": "Hochladen fehlgeschlagen.",
+ "file_too_big": "Datei ist zu groß [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
+ "default": "Bitte versuche es später erneut"
},
"file_size_units": {
"B": "B",
@@ -409,5 +487,98 @@
"password_reset_disabled": "Passwortzurücksetzen deaktiviert. Bitte Administrator kontaktieren.",
"password_reset_required": "Passwortzurücksetzen erforderlich",
"password_reset_required_but_mailer_is_disabled": "Passwortzurücksetzen wäre erforderlich, ist aber deaktiviert. Bitte Administrator kontaktieren."
+ },
+ "about": {
+ "mrf": {
+ "federation": "Föderation",
+ "mrf_policies": "Aktivierte MRF Richtlinien",
+ "simple": {
+ "simple_policies": "Instanzspezifische Richtlinien",
+ "accept": "Akzeptieren",
+ "reject": "Ablehnen",
+ "reject_desc": "Diese Instanz akzeptiert keine Nachrichten der folgenden Instanzen:",
+ "quarantine": "Quarantäne",
+ "ftl_removal": "Von der Zeitleiste \"Das gesamte bekannte Netzwerk\" entfernen",
+ "media_removal": "Medienentfernung",
+ "media_removal_desc": "Diese Instanz entfernt Medien von den Beiträgen der folgenden Instanzen:",
+ "media_nsfw": "Erzwingen Medien als heikel zu makieren",
+ "media_nsfw_desc": "Diese Instanz makiert die Medien in Beiträgen der folgenden Instanzen als heikel:",
+ "accept_desc": "Diese Instanz akzeptiert nur Nachrichten von den folgenden Instanzen:",
+ "quarantine_desc": "Diese Instanz sendet nur öffentliche Beiträge zu den folgenden Instanzen:",
+ "ftl_removal_desc": "Dieser Instanz entfernt folgende Instanzen von der \"Das gesamte bekannte Netzwerk\" Zeitleiste:"
+ },
+ "keyword": {
+ "keyword_policies": "Keyword Richtlinien",
+ "reject": "Ablehnen",
+ "replace": "Ersetzen",
+ "is_replaced_by": "→",
+ "ftl_removal": "Von der Zeitleiste \"Das gesamte bekannte Netzwerk\" entfernen"
+ },
+ "mrf_policies_desc": "MRF Richtlinien manipulieren das Föderationsverhalten dieser Instanz. Die folgenden Richtlinien sind aktiv:"
+ },
+ "staff": "Mitarbeiter"
+ },
+ "domain_mute_card": {
+ "mute": "Stummschalten",
+ "mute_progress": "Wird stummgeschaltet..",
+ "unmute": "Stummschaltung aufheben",
+ "unmute_progress": "Stummschaltung wird aufgehoben.."
+ },
+ "exporter": {
+ "export": "Exportieren",
+ "processing": "Verarbeitung läuft, bald wird Du dazu aufgefordert, deine Datei herunterzuladen"
+ },
+ "image_cropper": {
+ "crop_picture": "Bild zuschneiden",
+ "save": "Speichern",
+ "cancel": "Abbrechen",
+ "save_without_cropping": "Ohne Zuschneiden speichern"
+ },
+ "importer": {
+ "submit": "Absenden",
+ "success": "Erfolgreich importiert.",
+ "error": "Ein Fehler ist beim Verabeiten der Datei aufgetreten."
+ },
+ "media_modal": {
+ "previous": "Zurück",
+ "next": "Weiter"
+ },
+ "polls": {
+ "add_poll": "Umfrage hinzufügen",
+ "add_option": "Option hinzufügen",
+ "option": "Option",
+ "votes": "Stimmen",
+ "vote": "Abstimmen",
+ "type": "Umfragetyp",
+ "multiple_choices": "Mehrere Auswahlmöglichkeiten",
+ "single_choice": "Eine Auswahlmöglichkeit",
+ "expiry": "Alter der Umfrage",
+ "expired": "Die Umfrage endete vor {0}",
+ "not_enough_options": "Zu wenig einzigartige Auswahlmöglichkeiten in der Umfrage",
+ "expires_in": "Die Umfrage endet in {0}"
+ },
+ "emoji": {
+ "stickers": "Sticker",
+ "emoji": "Emoji",
+ "search_emoji": "Nach einem Emoji suchen",
+ "custom": "Benutzerdefinierter Emoji",
+ "keep_open": "Auswahlfenster offen halten",
+ "add_emoji": "Emoji einfügen",
+ "load_all": "Lade alle {emojiAmount} Emoji",
+ "load_all_hint": "Erfolgreich erste {saneAmount} Emoji geladen, alle Emojis zu laden würde Leistungsprobleme hervorrufen.",
+ "unicode": "Unicode Emoji"
+ },
+ "interactions": {
+ "load_older": "Lade ältere Interaktionen",
+ "follows": "Neue Follows",
+ "favs_repeats": "Wiederholungen und Favoriten",
+ "moves": "Benutzer migriert zu"
+ },
+ "selectable_list": {
+ "select_all": "Wähle alle"
+ },
+ "remote_user_resolver": {
+ "searching_for": "Suche nach",
+ "error": "Nicht gefunden."
}
}
diff --git a/src/i18n/en.json b/src/i18n/en.json
index d0d654d3..eefe10e5 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -1,40 +1,42 @@
{
"about": {
- "staff": "Staff",
- "federation": "Federation",
- "mrf_policies": "Enabled MRF Policies",
- "mrf_policies_desc": "MRF policies manipulate the federation behaviour of the instance. The following policies are enabled:",
- "mrf_policy_simple": "Instance-specific Policies",
- "mrf_policy_simple_accept": "Accept",
- "mrf_policy_simple_accept_desc": "This instance only accepts messages from the following instances:",
- "mrf_policy_simple_reject": "Reject",
- "mrf_policy_simple_reject_desc": "This instance will not accept messages from the following instances:",
- "mrf_policy_simple_quarantine": "Quarantine",
- "mrf_policy_simple_quarantine_desc": "This instance will send only public posts to the following instances:",
- "mrf_policy_simple_ftl_removal": "Removal from \"The Whole Known Network\" Timeline",
- "mrf_policy_simple_ftl_removal_desc": "This instance removes these instances from \"The Whole Known Network\" timeline:",
- "mrf_policy_simple_media_removal": "Media Removal",
- "mrf_policy_simple_media_removal_desc": "This instance removes media from posts on the following instances:",
- "mrf_policy_simple_media_nsfw": "Media Force-set As Sensitive",
- "mrf_policy_simple_media_nsfw_desc": "This instance forces media to be set sensitive in posts on the following instances:",
"mrf": {
+ "federation": "Federation",
"keyword": {
"keyword_policies": "Keyword Policies",
"ftl_removal": "Removal from \"The Whole Known Network\" Timeline",
"reject": "Reject",
"replace": "Replace",
"is_replaced_by": "→"
+ },
+ "mrf_policies": "Enabled MRF Policies",
+ "mrf_policies_desc": "MRF policies manipulate the federation behaviour of the instance. The following policies are enabled:",
+ "simple": {
+ "simple_policies": "Instance-specific Policies",
+ "accept": "Accept",
+ "accept_desc": "This instance only accepts messages from the following instances:",
+ "reject": "Reject",
+ "reject_desc": "This instance will not accept messages from the following instances:",
+ "quarantine": "Quarantine",
+ "quarantine_desc": "This instance will send only public posts to the following instances:",
+ "ftl_removal": "Removal from \"The Whole Known Network\" Timeline",
+ "ftl_removal_desc": "This instance removes these instances from \"The Whole Known Network\" timeline:",
+ "media_removal": "Media Removal",
+ "media_removal_desc": "This instance removes media from posts on the following instances:",
+ "media_nsfw": "Media Force-set As Sensitive",
+ "media_nsfw_desc": "This instance forces media to be set sensitive in posts on the following instances:"
}
- }
+ },
+ "staff": "Staff"
},
"chat": {
"title": "Chat"
},
"domain_mute_card": {
"mute": "Mute",
- "mute_progress": "Muting...",
+ "mute_progress": "Muting…",
"unmute": "Unmute",
- "unmute_progress": "Unmuting..."
+ "unmute_progress": "Unmuting…"
},
"exporter": {
"export": "Export",
@@ -57,15 +59,21 @@
"apply": "Apply",
"submit": "Submit",
"more": "More",
+ "loading": "Loading…",
"generic_error": "An error occured",
+ "error_retry": "Please try again",
+ "retry": "Try again",
"optional": "optional",
"show_more": "Show more",
"show_less": "Show less",
+ "dismiss": "Dismiss",
"cancel": "Cancel",
"disable": "Disable",
"enable": "Enable",
"confirm": "Confirm",
- "verify": "Verify"
+ "verify": "Verify",
+ "close": "Close",
+ "peek": "Peek"
},
"image_cropper": {
"crop_picture": "Crop picture",
@@ -91,9 +99,9 @@
"enter_recovery_code": "Enter a recovery code",
"enter_two_factor_code": "Enter a two-factor code",
"recovery_code": "Recovery code",
- "heading" : {
- "totp" : "Two-factor authentication",
- "recovery" : "Two-factor recovery"
+ "heading": {
+ "totp": "Two-factor authentication",
+ "recovery": "Two-factor recovery"
}
},
"media_modal": {
@@ -118,9 +126,10 @@
"preferences": "Preferences"
},
"notifications": {
- "broken_favorite": "Unknown status, searching for it...",
+ "broken_favorite": "Unknown status, searching for it…",
"favorited_you": "favorited your status",
"followed_you": "followed you",
+ "follow_request": "wants to follow you",
"load_older": "Load older notifications",
"notifications": "Notifications",
"read": "Read!",
@@ -222,17 +231,17 @@
"security": "Security",
"enter_current_password_to_confirm": "Enter your current password to confirm your identity",
"mfa": {
- "otp" : "OTP",
- "setup_otp" : "Setup OTP",
- "wait_pre_setup_otp" : "presetting OTP",
- "confirm_and_enable" : "Confirm & enable OTP",
+ "otp": "OTP",
+ "setup_otp": "Setup OTP",
+ "wait_pre_setup_otp": "presetting OTP",
+ "confirm_and_enable": "Confirm & enable OTP",
"title": "Two-factor Authentication",
- "generate_new_recovery_codes" : "Generate new recovery codes",
- "warning_of_generate_new_codes" : "When you generate new recovery codes, your old codes won’t work anymore.",
- "recovery_codes" : "Recovery codes.",
- "waiting_a_recovery_codes": "Receiving backup codes...",
- "recovery_codes_warning" : "Write the codes down or save them somewhere secure - otherwise you won't see them again. If you lose access to your 2FA app and recovery codes you'll be locked out of your account.",
- "authentication_methods" : "Authentication methods",
+ "generate_new_recovery_codes": "Generate new recovery codes",
+ "warning_of_generate_new_codes": "When you generate new recovery codes, your old codes won’t work anymore.",
+ "recovery_codes": "Recovery codes.",
+ "waiting_a_recovery_codes": "Receiving backup codes…",
+ "recovery_codes_warning": "Write the codes down or save them somewhere secure - otherwise you won't see them again. If you lose access to your 2FA app and recovery codes you'll be locked out of your account.",
+ "authentication_methods": "Authentication methods",
"scan": {
"title": "Scan",
"desc": "Using your two-factor app, scan this QR code or enter text key:",
@@ -274,10 +283,11 @@
"current_avatar": "Your current avatar",
"current_password": "Current password",
"current_profile_banner": "Your current profile banner",
+ "mutes_and_blocks": "Mutes and Blocks",
"data_import_export_tab": "Data Import / Export",
"default_vis": "Default visibility scope",
"delete_account": "Delete Account",
- "delete_account_description": "Permanently delete your account and all your messages.",
+ "delete_account_description": "Permanently delete your data and deactivate your account.",
"delete_account_error": "There was an issue deleting your account. If this persists please contact your instance administrator.",
"delete_account_instructions": "Type your password in the input below to confirm account deletion.",
"discoverable": "Allow discovery of this account in search results and other services",
@@ -293,6 +303,7 @@
"follow_import": "Follow import",
"follow_import_error": "Error importing followers",
"follows_imported": "Follows imported! Processing them will take a while.",
+ "accent": "Accent",
"foreground": "Foreground",
"general": "General",
"hide_attachments_in_convo": "Hide attachments in conversations",
@@ -390,7 +401,7 @@
"theme_help_v2_1": "You can also override certain component's colors and opacity by toggling the checkbox, use \"Clear all\" button to clear all overrides.",
"theme_help_v2_2": "Icons underneath some entries are background/text contrast indicators, hover over for detailed info. Please keep in mind that when using transparency contrast indicators show the worst possible case.",
"tooltipRadius": "Tooltips/alerts",
- "type_domains_to_mute": "Type in domains to mute",
+ "type_domains_to_mute": "Search domains to mute",
"upload_a_photo": "Upload a photo",
"user_settings": "User Settings",
"values": {
@@ -400,11 +411,14 @@
"fun": "Fun",
"greentext": "Meme arrows",
"notifications": "Notifications",
+ "notification_setting_filters": "Filters",
"notification_setting": "Receive notifications from:",
"notification_setting_follows": "Users you follow",
"notification_setting_non_follows": "Users you do not follow",
"notification_setting_followers": "Users who follow you",
"notification_setting_non_followers": "Users who do not follow you",
+ "notification_setting_privacy": "Privacy",
+ "notification_setting_privacy_option": "Hide the sender and contents of push notifications",
"notification_mutes": "To stop receiving notifications from a specific user, use a mute.",
"notification_blocks": "Blocking a user stops all notifications as well as unsubscribes them.",
"enable_web_push_notifications": "Enable web push notifications",
@@ -418,7 +432,24 @@
"save_load_hint": "\"Keep\" options preserve currently set options when selecting or loading themes, it also stores said options when exporting a theme. When all checkboxes unset, exporting theme will save everything.",
"reset": "Reset",
"clear_all": "Clear all",
- "clear_opacity": "Clear opacity"
+ "clear_opacity": "Clear opacity",
+ "load_theme": "Load theme",
+ "keep_as_is": "Keep as is",
+ "use_snapshot": "Old version",
+ "use_source": "New version",
+ "help": {
+ "upgraded_from_v2": "PleromaFE has been upgraded, theme could look a little bit different than you remember.",
+ "v2_imported": "File you imported was made for older FE. We try to maximize compatibility but there still could be inconsistencies.",
+ "future_version_imported": "File you imported was made in newer version of FE.",
+ "older_version_imported": "File you imported was made in older version of FE.",
+ "snapshot_present": "Theme snapshot is loaded, so all values are overriden. You can load theme's actual data instead.",
+ "snapshot_missing": "No theme snapshot was in the file so it could look different than originally envisioned.",
+ "fe_upgraded": "PleromaFE's theme engine upgraded after version update.",
+ "fe_downgraded": "PleromaFE's version rolled back.",
+ "migration_snapshot_ok": "Just to be safe, theme snapshot loaded. You can try loading theme data.",
+ "migration_napshot_gone": "For whatever reason snapshot was missing, some stuff could look different than you remember.",
+ "snapshot_source_mismatch": "Versions conflict: most likely FE was rolled back and updated again, if you changed theme using older version of FE you most likely want to use old version, otherwise use new version."
+ }
},
"common": {
"color": "Color",
@@ -447,14 +478,27 @@
"alert": "Alert background",
"alert_error": "Error",
"alert_warning": "Warning",
+ "alert_neutral": "Neutral",
+ "post": "Posts/User bios",
"badge": "Badge background",
+ "popover": "Tooltips, menus, popovers",
"badge_notification": "Notification",
"panel_header": "Panel header",
"top_bar": "Top bar",
"borders": "Borders",
"buttons": "Buttons",
"inputs": "Input fields",
- "faint_text": "Faded text"
+ "faint_text": "Faded text",
+ "underlay": "Underlay",
+ "poll": "Poll graph",
+ "icons": "Icons",
+ "highlight": "Highlighted elements",
+ "pressed": "Pressed",
+ "selectedPost": "Selected post",
+ "selectedMenu": "Selected menu item",
+ "disabled": "Disabled",
+ "toggled": "Toggled",
+ "tabs": "Tabs"
},
"radii": {
"_tab_label": "Roundness"
@@ -467,7 +511,7 @@
"blur": "Blur",
"spread": "Spread",
"inset": "Inset",
- "hint": "For shadows you can also use --variable as a color value to use CSS3 variables. Please note that setting opacity won't work in this case.",
+ "hintV3": "For shadows you can also use the {0} notation to use other color slot.",
"filter_hint": {
"always_drop_shadow": "Warning, this shadow always uses {0} when browser supports it.",
"drop_shadow_syntax": "{0} does not support {1} parameter and {2} keyword.",
@@ -581,7 +625,11 @@
"reply_to": "Reply to",
"replies_list": "Replies:",
"mute_conversation": "Mute conversation",
- "unmute_conversation": "Unmute conversation"
+ "unmute_conversation": "Unmute conversation",
+ "status_unavailable": "Status unavailable",
+ "copy_link": "Copy link to status",
+ "thread_muted": "Thread muted",
+ "thread_muted_and_words": ", has words:"
},
"user_card": {
"approve": "Approve",
@@ -611,11 +659,11 @@
"subscribe": "Subscribe",
"unsubscribe": "Unsubscribe",
"unblock": "Unblock",
- "unblock_progress": "Unblocking...",
- "block_progress": "Blocking...",
+ "unblock_progress": "Unblocking…",
+ "block_progress": "Blocking…",
"unmute": "Unmute",
- "unmute_progress": "Unmuting...",
- "mute_progress": "Muting...",
+ "unmute_progress": "Unmuting…",
+ "mute_progress": "Muting…",
"hide_repeats": "Hide repeats",
"show_repeats": "Show repeats",
"admin_menu": {
@@ -662,9 +710,11 @@
"reply": "Reply",
"favorite": "Favorite",
"add_reaction": "Add Reaction",
- "user_settings": "User Settings"
+ "user_settings": "User Settings",
+ "accept_follow_request": "Accept follow request",
+ "reject_follow_request": "Reject follow request"
},
- "upload":{
+ "upload": {
"error": {
"base": "Upload failed.",
"file_too_big": "File too big [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
diff --git a/src/i18n/es.json b/src/i18n/es.json
index 163eb707..931d4c64 100644
--- a/src/i18n/es.json
+++ b/src/i18n/es.json
@@ -57,12 +57,12 @@
"enter_recovery_code": "Inserta el código de recuperación",
"enter_two_factor_code": "Inserta el código de dos factores",
"recovery_code": "Código de recuperación",
- "heading" : {
- "totp" : "Autenticación de dos factores",
- "recovery" : "Recuperación de dos factores"
+ "heading": {
+ "totp": "Autenticación de dos factores",
+ "recovery": "Recuperación de dos factores"
}
},
- "media_modal": {
+ "media_modal": {
"previous": "Anterior",
"next": "Siguiente"
},
@@ -103,7 +103,7 @@
"single_choice": "Elección única",
"multiple_choices": "Elección múltiple",
"expiry": "Tiempo de vida de la encuesta",
- "expires_in": "La encuensta termina en {0}",
+ "expires_in": "La encuesta termina en {0}",
"expired": "La encuesta terminó hace {0}",
"not_enough_options": "Muy pocas opciones únicas en la encuesta"
},
@@ -137,7 +137,7 @@
},
"content_warning": "Tema (opcional)",
"default": "Acabo de aterrizar en L.A.",
- "direct_warning_to_all": "Esta publicación será visible para todos los usarios mencionados.",
+ "direct_warning_to_all": "Esta publicación será visible para todos los usuarios mencionados.",
"direct_warning_to_first_only": "Esta publicación solo será visible para los usuarios mencionados al comienzo del mensaje.",
"posting": "Publicando",
"scope_notice": {
@@ -146,7 +146,7 @@
"unlisted": "Esta publicación no será visible en la Línea Temporal Pública ni en Toda La Red Conocida"
},
"scope": {
- "direct": "Directo - Solo para los usuarios mencionados.",
+ "direct": "Directo - Solo para los usuarios mencionados",
"private": "Solo-seguidores - Solo tus seguidores leerán la publicación",
"public": "Público - Entradas visibles en las Líneas Temporales Públicas",
"unlisted": "Sin listar - Entradas no visibles en las Líneas Temporales Públicas"
@@ -173,7 +173,7 @@
"password_confirmation_match": "la contraseña no coincide"
}
},
- "selectable_list": {
+ "selectable_list": {
"select_all": "Seleccionar todo"
},
"settings": {
@@ -181,17 +181,17 @@
"security": "Seguridad",
"enter_current_password_to_confirm": "Introduce la contraseña actual para confirmar tu identidad",
"mfa": {
- "otp" : "OTP",
- "setup_otp" : "Configurar OTP",
- "wait_pre_setup_otp" : "preconfiguración OTP",
- "confirm_and_enable" : "Confirmar y habilitar OTP",
+ "otp": "OTP",
+ "setup_otp": "Configurar OTP",
+ "wait_pre_setup_otp": "preconfiguración OTP",
+ "confirm_and_enable": "Confirmar y habilitar OTP",
"title": "Autentificación de dos factores",
- "generate_new_recovery_codes" : "Generar códigos de recuperación nuevos",
- "warning_of_generate_new_codes" : "Cuando generas nuevos códigos de recuperación, los antiguos dejarán de funcionar.",
- "recovery_codes" : "Códigos de recuperación.",
+ "generate_new_recovery_codes": "Generar códigos de recuperación nuevos",
+ "warning_of_generate_new_codes": "Cuando generas nuevos códigos de recuperación, los antiguos dejarán de funcionar.",
+ "recovery_codes": "Códigos de recuperación.",
"waiting_a_recovery_codes": "Recibiendo códigos de respaldo",
- "recovery_codes_warning" : "Anote los códigos o guárdelos en un lugar seguro, de lo contrario no los volverá a ver. Si pierde el acceso a su aplicación 2FA y los códigos de recuperación, su cuenta quedará bloqueada.",
- "authentication_methods" : "Métodos de autentificación",
+ "recovery_codes_warning": "Anote los códigos o guárdelos en un lugar seguro, de lo contrario no los volverá a ver. Si pierde el acceso a su aplicación 2FA y los códigos de recuperación, su cuenta quedará bloqueada.",
+ "authentication_methods": "Métodos de autentificación",
"scan": {
"title": "Escanear",
"desc": "Usando su aplicación de dos factores, escanee este código QR o ingrese la clave de texto:",
@@ -210,7 +210,7 @@
"background": "Fondo",
"bio": "Biografía",
"block_export": "Exportar usuarios bloqueados",
- "block_export_button": "Exporta la lista de tus usarios bloqueados a un archivo csv",
+ "block_export_button": "Exporta la lista de tus usuarios bloqueados a un archivo csv",
"block_import": "Importar usuarios bloqueados",
"block_import_error": "Error importando la lista de usuarios bloqueados",
"blocks_imported": "¡Lista de usuarios bloqueados importada! El procesado puede tardar un poco.",
@@ -222,7 +222,7 @@
"cRed": "Rojo (Cancelar)",
"change_password": "Cambiar contraseña",
"change_password_error": "Hubo un problema cambiando la contraseña.",
- "changed_password": "Contraseña cambiada correctamente!",
+ "changed_password": "¡Contraseña cambiada correctamente!",
"collapse_subject": "Colapsar entradas con tema",
"composing": "Redactando",
"confirm_new_password": "Confirmar la nueva contraseña",
@@ -286,7 +286,7 @@
"notification_visibility_repeats": "Repeticiones (Repeats)",
"no_rich_text_description": "Eliminar el formato de texto enriquecido de todas las entradas",
"no_blocks": "No hay usuarios bloqueados",
- "no_mutes": "No hay usuarios sinlenciados",
+ "no_mutes": "No hay usuarios silenciados",
"hide_follows_description": "No mostrar a quién sigo",
"hide_followers_description": "No mostrar quién me sigue",
"hide_follows_count_description": "No mostrar el número de cuentas que sigo",
@@ -305,7 +305,7 @@
"profile_background": "Fondo del Perfil",
"profile_banner": "Cabecera del Perfil",
"profile_tab": "Perfil",
- "radii_help": "Estable el redondeo de las esquinas de la interfaz (en píxeles)",
+ "radii_help": "Establezca el redondeo de las esquinas de la interfaz (en píxeles)",
"replies_in_timeline": "Réplicas en la línea temporal",
"reply_link_preview": "Activar la previsualización del enlace de responder al pasar el ratón por encima",
"reply_visibility_all": "Mostrar todas las réplicas",
@@ -337,7 +337,7 @@
"theme_help_v2_1": "También puede invalidar los colores y la opacidad de ciertos componentes si activa la casilla de verificación. Use el botón \"Borrar todo\" para deshacer los cambios.",
"theme_help_v2_2": "Los iconos debajo de algunas entradas son indicadores de contraste de fondo/texto, desplace el ratón por encima para obtener información más detallada. Tenga en cuenta que cuando se utilizan indicadores de contraste de transparencia se muestra el peor caso posible.",
"tooltipRadius": "Información/alertas",
- "upload_a_photo": "Subir una foto",
+ "upload_a_photo": "Subir una foto",
"user_settings": "Ajustes del Usuario",
"values": {
"false": "no",
@@ -583,7 +583,7 @@
"profile_does_not_exist": "Lo sentimos, este perfil no existe.",
"profile_loading_error": "Lo sentimos, hubo un error al cargar este perfil."
},
- "user_reporting": {
+ "user_reporting": {
"title": "Reportando a {0}",
"add_comment_description": "El informe será enviado a los moderadores de su instancia. Puedes proporcionar una explicación de por qué estás reportando esta cuenta a continuación:",
"additional_comments": "Comentarios adicionales",
@@ -603,7 +603,7 @@
"favorite": "Favorito",
"user_settings": "Ajustes de usuario"
},
- "upload":{
+ "upload": {
"error": {
"base": "Subida fallida.",
"file_too_big": "Archivo demasiado grande [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
@@ -635,4 +635,4 @@
"too_many_requests": "Has alcanzado el límite de intentos, vuelve a intentarlo más tarde.",
"password_reset_disabled": "El restablecimiento de contraseñas está deshabilitado. Póngase en contacto con el administrador de su instancia."
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/et.json b/src/i18n/et.json
index 5262b2a4..b5ae4275 100644
--- a/src/i18n/et.json
+++ b/src/i18n/et.json
@@ -4,7 +4,19 @@
"find_user": "Otsi kasutajaid"
},
"general": {
- "submit": "Postita"
+ "submit": "Postita",
+ "verify": "Kinnita",
+ "confirm": "Kinnita",
+ "enable": "Luba",
+ "disable": "Keela",
+ "cancel": "Tühista",
+ "dismiss": "Olgu",
+ "show_less": "Kuva vähem",
+ "show_more": "Kuva rohkem",
+ "optional": "valikuline",
+ "generic_error": "Esines viga",
+ "more": "Rohkem",
+ "apply": "Rakenda"
},
"login": {
"login": "Logi sisse",
@@ -12,29 +24,95 @@
"password": "Parool",
"placeholder": "nt lain",
"register": "Registreeru",
- "username": "Kasutajanimi"
+ "username": "Kasutajanimi",
+ "heading": {
+ "recovery": "Kaheastmelise autentimise taaste",
+ "totp": "Kaheastmeline autentimine"
+ },
+ "recovery_code": "Taastekood",
+ "enter_two_factor_code": "Sisesta kaheastmelise autentimise kood",
+ "enter_recovery_code": "Sisesta taastekood",
+ "authentication_code": "Autentimiskood",
+ "hint": "Logi sisse, et liituda vestlusega",
+ "description": "Logi sisse OAuthiga"
},
"nav": {
"mentions": "Mainimised",
"public_tl": "Avalik Ajajoon",
"timeline": "Ajajoon",
- "twkn": "Kogu Teadaolev Võrgustik"
+ "twkn": "Kogu Teadaolev Võrgustik",
+ "preferences": "Eelistused",
+ "who_to_follow": "Keda jälgida",
+ "search": "Otsing",
+ "user_search": "Kasutajaotsing",
+ "dms": "Privaatsõnumid",
+ "interactions": "Interaktsioonid",
+ "friend_requests": "Jägimistaotlused",
+ "chat": "Kohalik vestlus",
+ "back": "Tagasi",
+ "administration": "Administreerimine",
+ "about": "Meist"
},
"notifications": {
"followed_you": "alustas sinu jälgimist",
- "notifications": "Teavitused",
- "read": "Loe!"
+ "notifications": "Teated",
+ "read": "Loe!",
+ "reacted_with": "reageeris {0}",
+ "migrated_to": "kolis",
+ "no_more_notifications": "Rohkem teateid ei ole",
+ "repeated_you": "taaspostitas su staatuse",
+ "load_older": "Laadi vanemad teated",
+ "follow_request": "soovib Teid jälgida",
+ "favorited_you": "lisas su staatuse lemmikuks",
+ "broken_favorite": "Tundmatu staatus, otsin…"
},
"post_status": {
"default": "Just sõitsin elektrirongiga Tallinnast Pääskülla.",
- "posting": "Postitan"
+ "posting": "Postitan",
+ "scope": {
+ "unlisted": "Peidetud - Ära postita avalikele ajajoontele",
+ "public": "Avalil - Postita avalikele ajajoontele",
+ "private": "Jälgijatele - Postita ainult jälgijatele",
+ "direct": "Privaatne - Postita ainult mainitud kasutajatele"
+ },
+ "scope_notice": {
+ "unlisted": "See postitus ei ole nähtav avalikul ega kogu võrgu ajajoonel",
+ "private": "See postitus on nähtav ainult Teie jälgijatele",
+ "public": "See postitus on nähtav kõigile"
+ },
+ "direct_warning_to_first_only": "See postitus on nähtav ainult kirja alguses mainitud kasutajatele.",
+ "direct_warning_to_all": "See postitus on nähtav kõikidele mainitud kasutajatele.",
+ "content_warning": "Pealkiri (valikuline)",
+ "content_type": {
+ "text/bbcode": "BBCode",
+ "text/markdown": "Markdown",
+ "text/html": "HTML",
+ "text/plain": "Lihttekst"
+ },
+ "attachments_sensitive": "Märgi manused sensitiivseks",
+ "account_not_locked_warning_link": "lukus",
+ "account_not_locked_warning": "Teie konto ei ole {0}. Kõik võivad Teid jälgida, et näha Teie ainult-jälgijatele postitusi.",
+ "new_status": "Postita uus staatus"
},
"registration": {
"bio": "Bio",
"email": "E-post",
"fullname": "Kuvatav nimi",
"password_confirm": "Parooli kinnitamine",
- "registration": "Registreerimine"
+ "registration": "Registreerimine",
+ "validations": {
+ "password_confirmation_match": "peaks olema sama kui salasõna",
+ "password_confirmation_required": "ei saa jätta tühjaks",
+ "password_required": "ei saa jätta tühjaks",
+ "email_required": "ei saa jätta tühjaks",
+ "fullname_required": "ei saa jätta tühjaks",
+ "username_required": "ei saa jätta tühjaks"
+ },
+ "fullname_placeholder": "Näiteks Lain Iwakura",
+ "username_placeholder": "Näiteks lain",
+ "new_captcha": "Vajuta pildile, et saada uus captcha",
+ "captcha": "CAPTCHA",
+ "token": "Kutse võti"
},
"settings": {
"attachments": "Manused",
@@ -44,7 +122,7 @@
"current_avatar": "Sinu praegune profiilipilt",
"current_profile_banner": "Praegune profiilibänner",
"filtering": "Sisu filtreerimine",
- "filtering_explanation": "Kõiki staatuseid, mis sisaldavad neid sõnu, ei kuvata. Üks sõna reale.",
+ "filtering_explanation": "Kõiki staatuseid, mis sisaldavad neid sõnu, ei kuvata. Üks sõna reale",
"hide_attachments_in_convo": "Peida manused vastlustes",
"hide_attachments_in_tl": "Peida manused ajajoonel",
"name": "Nimi",
@@ -58,7 +136,201 @@
"set_new_profile_banner": "Vali uus profiilibänner",
"settings": "Sätted",
"theme": "Teema",
- "user_settings": "Kasutaja sätted"
+ "user_settings": "Kasutaja sätted",
+ "subject_line_noop": "Ära kopeeri",
+ "subject_line_mastodon": "Nagu mastodon: kopeeri nagu on",
+ "subject_line_email": "Nagu e-post: \"vs: pealkiri\"",
+ "subject_line_behavior": "Kopeeri pealkiri vastamisel",
+ "subject_input_always_show": "Alati kuva pealkirja välja",
+ "minimal_scopes_mode": "Peida postituse nähtavussätted",
+ "scope_copy": "Kopeeri nähtavussätted vastamisel (Privaatsed on alati kopeeritud)",
+ "security_tab": "Turvalisus",
+ "search_user_to_mute": "Otsi, keda soovid vaigistada",
+ "search_user_to_block": "Otsi, keda soovid blokeerida",
+ "saving_ok": "Sätted salvestatud",
+ "saving_err": "Sätete salvestamine ebaõnnestus",
+ "autohide_floating_post_button": "Automaatselt peida uue postituse nupp (mobiilil)",
+ "reply_visibility_self": "Näita ainult vastuseid, mis on suunatud mulle",
+ "reply_visibility_following": "Näita ainult vastuseid, mis on suunatud mulle või kasutajatele, keda jälgin",
+ "reply_visibility_all": "Näita kõiki vastuseid",
+ "replies_in_timeline": "Vastused ajajoonel",
+ "radii_help": "Liidese ümardamine (pikslites)",
+ "profile_tab": "Profiil",
+ "presets": "Salvestatud sätted",
+ "pause_on_unfocused": "Peata reaalajas voog kui leht pole fookuses",
+ "panelRadius": "Paneelid",
+ "revoke_token": "Keela",
+ "valid_until": "Kehtiv kuni",
+ "refresh_token": "Värskendustoken",
+ "token": "Token",
+ "oauth_tokens": "OAuth tokenid",
+ "show_moderator_badge": "Näita Moderaator silti mu profiilil",
+ "show_admin_badge": "Näita Admin silti mu profiilil",
+ "hide_followers_count_description": "Ära näita minu jälgijate arvu",
+ "hide_follows_count_description": "Ära näita minu jälgimiste arvu",
+ "hide_followers_description": "Ära näita minu jälgijaid",
+ "hide_follows_description": "Ära näita minu jälgimisi",
+ "no_mutes": "Vaigistusi pole",
+ "no_blocks": "Blokeeringuid pole",
+ "no_rich_text_description": "Muuda kõik postitused lihttekstiks",
+ "notification_visibility_emoji_reactions": "Reaktsioonid",
+ "notification_visibility_moves": "Kasutaja kolimised",
+ "notification_visibility_repeats": "Taaspostitused",
+ "notification_visibility_mentions": "Mainimised",
+ "notification_visibility_likes": "Lemmikud",
+ "notification_visibility_follows": "Jälgimised",
+ "notification_visibility": "Milliseid teateid kuvatakse",
+ "new_password": "Uus salasõna",
+ "new_email": "Uus e-post",
+ "use_contain_fit": "Näita eelvaadetes täis suuruses pilte",
+ "play_videos_in_modal": "Näita videoid eraldi raamis",
+ "mutes_tab": "Vaigistused",
+ "loop_video_silent_only": "Loop videod, millel pole heli (nt. Mastodoni \"gifid\")",
+ "loop_video": "Loop videod",
+ "lock_account_description": "Piira oma konto ainult lubatud jälgijatele",
+ "links": "Lingid",
+ "limited_availability": "Pole Teie veebilehitsejas saadaval",
+ "invalid_theme_imported": "Valitud fail ei ole Pleroma kujundus. Kujundusele muudatusi ei tehtud.",
+ "interfaceLanguage": "Liidese keel",
+ "interface": "Liides",
+ "instance_default_simple": "(vaikimisi)",
+ "instance_default": "(vaikimisi: {value})",
+ "checkboxRadius": "Märkeruudud",
+ "inputRadius": "Sisestuskastid",
+ "import_theme": "Lae sätted",
+ "import_followers_from_a_csv_file": "Impordi jälgimised csv failist",
+ "import_blocks_from_a_csv_file": "Impordi blokeeringud csv failist",
+ "hide_filtered_statuses": "Peida filtreeritud staatused",
+ "hide_user_stats": "Peida kasutaja statistika (nt. jälgijate arv)",
+ "hide_post_stats": "Peida postituse statistika (nt. lemmikute arv)",
+ "use_one_click_nsfw": "Ava NSFW manused ühe klikiga",
+ "preload_images": "Piltide eellaadimine",
+ "hide_isp": "Peida instantsipõhine paneel",
+ "max_thumbnails": "Maksimaalne lubatud eelvaadete arv postituste kohta",
+ "hide_muted_posts": "Peida vaigistatud kasutajate postitused",
+ "general": "Üldine",
+ "foreground": "Esiplaan",
+ "accent": "Rõhk",
+ "follows_imported": "Jälgimised imporditud! Nende töötlemine võtab natuke aega.",
+ "follow_import_error": "Jälgimiste importimisel tekkis viga",
+ "follow_import": "Impordi jälgimised",
+ "follow_export_button": "Ekspordi oma jälgimised csv failiks",
+ "follow_export": "Ekspordi jälgimised",
+ "export_theme": "Salvesta sätted",
+ "emoji_reactions_on_timeline": "Näita reaktsioone ajajoonel",
+ "pad_emoji": "Lisa emotikonidele tühikud ette ja järgi neid menüüst valides",
+ "avatar_size_instruction": "Profiilipildi soovitatud minimaalne suurus on 150x150 pikslit.",
+ "domain_mutes": "Domeenid",
+ "discoverable": "Luba selle konto ilmumine otsingutulemustes ning muudes teenustes",
+ "delete_account_instructions": "Konto kustutamise kinnitamiseks sisestage oma salasõna.",
+ "delete_account_error": "Teie konto kustutamisel tekkis viga. Kui see jätkub, palun võtke kontakti administraatoriga.",
+ "delete_account_description": "Jäädavalt kustuta oma andmed ja konto.",
+ "delete_account": "Kustuta konto",
+ "default_vis": "Vaikimisi nähtavus",
+ "data_import_export_tab": "Andmete import / eksport",
+ "current_password": "Praegune salasõna",
+ "confirm_new_password": "Kinnita uus salasõna",
+ "composing": "Koostamine",
+ "collapse_subject": "Peida postituste pealkirjad",
+ "changed_password": "Salasõna edukalt muudetud!",
+ "change_password_error": "Esines viga salasõna muutmisel.",
+ "change_password": "Muuda salasõna",
+ "changed_email": "E-post edukalt muudetud!",
+ "change_email_error": "Esines viga e-posti muutmisel.",
+ "change_email": "Muuda e-posti",
+ "cRed": "Punane (Tühista)",
+ "cOrange": "Oranž (Lisa lemmikuks)",
+ "cGreen": "Roheline (Taaspostita)",
+ "cBlue": "Sinine (Vasta, jälgi)",
+ "btnRadius": "Nupud",
+ "blocks_tab": "Blokeeringud",
+ "blocks_imported": "Blokeeringud imporditud! Nende töötlemine võtab natuke aega.",
+ "block_import_error": "Blokeeringute importimisel esines viga",
+ "block_import": "Blokeeringute import",
+ "block_export_button": "Ekspordi oma blokeeringud csv failiks",
+ "block_export": "Blokeeringute eksport",
+ "background": "Taust",
+ "avatarRadius": "Profiilipildid",
+ "avatarAltRadius": "Profiilipildid (Teated)",
+ "attachmentRadius": "Manused",
+ "allow_following_move": "Luba automaatjälgimine kui jälgitav konto kolib",
+ "mfa": {
+ "verify": {
+ "desc": "Et lubada kaheastmelist autentimist, sisestage kood oma äpist:"
+ },
+ "scan": {
+ "desc": "Kasutades oma kaheastmelise autentimise äppi, skännige see QR kood või sisestage tekstiline võti:",
+ "secret_code": "Võti",
+ "title": "Skänni"
+ },
+ "authentication_methods": "Autentimismeetodid",
+ "recovery_codes_warning": "Kirjutage need koodid üles ning hoidke need kindlas kohas. Kui Te kaotate ligipääsu oma kaheastmelise autentimise äppile ning nendele koodidele, ei ole Teil võimalik oma kontosse sisse logida.",
+ "waiting_a_recovery_codes": "Laen taastekoode…",
+ "recovery_codes": "Taastekoodid.",
+ "warning_of_generate_new_codes": "Kui Te loote uued taastekoodid, Teie vanad koodid ei tööta enam.",
+ "generate_new_recovery_codes": "Loo uued taastekoodid",
+ "title": "Kaheastmeline autentimine",
+ "confirm_and_enable": "Kinnita & luba OTP",
+ "wait_pre_setup_otp": "sean üles OTP",
+ "setup_otp": "Sea üles OTP",
+ "otp": "OTP"
+ },
+ "enter_current_password_to_confirm": "Sisetage isiku tõestamiseks oma salasõna",
+ "security": "Turvalisus",
+ "app_name": "Rakenduse nimi",
+ "style": {
+ "switcher": {
+ "help": {
+ "snapshot_present": "Kujunduse eelvaade on laetud, nii et kõik väärtused on üle kirjutatud. Te saate laadida ka kujunduse päris sisu.",
+ "older_version_imported": "Teie imporditud fail oli loodud vanemas versioonis.",
+ "future_version_imported": "Teie imporditud fail oli loodud uuemas versioonis.",
+ "v2_imported": "Teie imporditud fail oli vanema versiooni jaoks. Me üritame hoida ühilduvust, kuid ikkagi võib esineda erinevusi.",
+ "upgraded_from_v2": "PleromaFE-d uuendati, teie kujundus võib välja näha natuke erinev, kui mäletate."
+ },
+ "use_source": "Uus versioon",
+ "use_snapshot": "Vana versioon",
+ "keep_as_is": "Jäta nii, nagu on",
+ "load_theme": "Lae kujundus",
+ "clear_opacity": "Tühista läbipaistvus",
+ "clear_all": "Tühista kõik",
+ "reset": "Taasta algne",
+ "keep_fonts": "Jäta fondid",
+ "keep_roundness": "Jäta ümarus",
+ "keep_opacity": "Jäta läbipaistvus",
+ "keep_shadows": "Jäta varjud",
+ "keep_color": "Jäta värvid"
+ }
+ },
+ "enable_web_push_notifications": "Luba veebipõhised push-teated",
+ "notification_blocks": "Kasutaja blokeerimisel ei tule neilt enam teateid ning nendele teilt ka mitte.",
+ "notification_setting_privacy_option": "Peida saatja ning sisu push-teadetelt",
+ "notification_setting": "Saa teateid nendelt:",
+ "notifications": "Teated",
+ "notification_mutes": "Kui soovid mõnelt kasutajalt mitte teateid saada, kasuta vaigistust.",
+ "notification_setting_privacy": "Privaatsus",
+ "notification_setting_non_followers": "Kasutajatelt, kes sind ei jälgi",
+ "notification_setting_followers": "Kasutajatelt, kes jälgivad sind",
+ "notification_setting_non_follows": "Kasutajatelt, keda sa ei jälgi",
+ "notification_setting_follows": "Kasutajatelt, keda jälgid",
+ "notification_setting_filters": "Filtrid",
+ "greentext": "Meemi nooled",
+ "fun": "Naljad",
+ "values": {
+ "true": "jah",
+ "false": "ei"
+ },
+ "upload_a_photo": "Lae üles foto",
+ "type_domains_to_mute": "Trüki siia domeene, mida vaigistada",
+ "tooltipRadius": "Vihjed/hoiatused",
+ "theme_help_v2_1": "Te saate ka mõndade komponentide värvust ning läbipaistvust üle kirjutada vajutades ruudule. Kasuta \"Tühista kõik\" nuppu, et need tühistada.",
+ "theme_help": "Kasuta hex värvikoode (#rrggbb) oma kujunduse isikupärastamiseks.",
+ "text": "Tekst",
+ "useStreamingApiWarning": "(Pole soovituslik, eksperimentaalne, on teada, et jätab postitusi vahele)",
+ "useStreamingApi": "Saa postitusi ning teateid reaalajas",
+ "user_mutes": "Kasutajad",
+ "streaming": "Luba uute postituste automaatvoog kui oled lehekülje alguses",
+ "stop_gifs": "Mängi GIFid hiirega ületades",
+ "post_status_content_type": "Postituse sisutüüp"
},
"timeline": {
"conversation": "Vestlus",
@@ -79,5 +351,111 @@
"muted": "Vaigistatud",
"per_day": "päevas",
"statuses": "Staatuseid"
+ },
+ "about": {
+ "mrf": {
+ "mrf_policies_desc": "MRF poliitikad mõjutavad selle instansi föderatsiooni käitumist. Järgmised poliitikad on lubatud:",
+ "simple": {
+ "media_nsfw_desc": "See instants määrab nendest instantsidest postituste meedia sensitiivseks:",
+ "media_nsfw": "Meedia määratakse sensitiivseks",
+ "media_removal_desc": "See instants eemaldab meedia postitustelt nendest instantsidest:",
+ "media_removal": "Meedia eemaldamine",
+ "ftl_removal_desc": "See instants eemaldab postitused nendelt instantsidest \"Kogu teatud võrgu\" ajajoonelt:",
+ "ftl_removal": "\"Kogu teatud võrgu\" ajajoonelt eemaldamine",
+ "quarantine_desc": "See instants saadab ainult avalikke postitusi järgmistele instantsidele:",
+ "quarantine": "Karantiini",
+ "reject_desc": "See instants ei luba sõnumeid nendest instantsidest:",
+ "reject": "Keela",
+ "accept_desc": "See instants lubab sõnumeid ainult nendest instantsidest:",
+ "accept": "Luba",
+ "simple_policies": "Instansi-omased poliitikad"
+ },
+ "mrf_policies": "Lubatud MRF poliitikad",
+ "keyword": {
+ "is_replaced_by": "→",
+ "replace": "Vaheta",
+ "reject": "Lükka tagasi",
+ "ftl_removal": "\"Kogu teatud võrgu\" ajajoonelt eemaldamine",
+ "keyword_policies": "Võtmesõna poliitikad"
+ },
+ "federation": "Föderatsioon"
+ },
+ "staff": "Personal"
+ },
+ "selectable_list": {
+ "select_all": "Vali kõik"
+ },
+ "remote_user_resolver": {
+ "error": "Ei leitud.",
+ "searching_for": "Otsin",
+ "remote_user_resolver": "Kaugkasutaja leidja"
+ },
+ "interactions": {
+ "load_older": "Laadi vanemad interaktsioonid",
+ "moves": "Kasutaja kolimised",
+ "follows": "Uued jälgimised",
+ "favs_repeats": "Taaspostitused ja lemmikud"
+ },
+ "emoji": {
+ "load_all": "Laen kõik {emojiAmount} emotikoni",
+ "load_all_hint": "Laadisin esimesed {saneAmount} emotikoni, kõike laadides võib esineda probleeme jõudlusega.",
+ "unicode": "Unicode emotikonid",
+ "custom": "Kohandatud emotikonid",
+ "add_emoji": "Lisa emotikon",
+ "search_emoji": "Otsi emotikone",
+ "keep_open": "Hoia valija lahti",
+ "emoji": "Emotikonid",
+ "stickers": "Kleepsud"
+ },
+ "polls": {
+ "not_enough_options": "Liiga vähe unikaalseid valikuid hääletuses",
+ "expired": "Hääletus lõppes {0} tagasi",
+ "expires_in": "Hääletus lõppeb {0}",
+ "expiry": "Hääletuse vanus",
+ "multiple_choices": "Mitu vastust",
+ "single_choice": "Üks vastus",
+ "type": "Hääletuse tüüp",
+ "vote": "Hääleta",
+ "votes": "häält",
+ "option": "Valik",
+ "add_option": "Lisa valik",
+ "add_poll": "Lisa küsitlus"
+ },
+ "media_modal": {
+ "next": "Järgmine",
+ "previous": "Eelmine"
+ },
+ "importer": {
+ "error": "Faili importimisel tekkis viga.",
+ "success": "Import õnnestus.",
+ "submit": "Esita"
+ },
+ "image_cropper": {
+ "cancel": "Tühista",
+ "save_without_cropping": "Salvesta muudatusteta",
+ "save": "Salvesta",
+ "crop_picture": "Modifitseeri pilti"
+ },
+ "features_panel": {
+ "who_to_follow": "Keda jälgida",
+ "title": "Featuurid",
+ "text_limit": "Tekstilimiit",
+ "scope_options": "Ulatuse valikud",
+ "media_proxy": "Meedia proksi",
+ "gopher": "Gopher",
+ "chat": "Vestlus"
+ },
+ "exporter": {
+ "processing": "Töötlemine, Teilt küsitakse varsti faili allalaadimist",
+ "export": "Ekspordi"
+ },
+ "domain_mute_card": {
+ "unmute_progress": "Eemaldan vaigistuse…",
+ "unmute": "Ära vaigista",
+ "mute_progress": "Vaigistan…",
+ "mute": "Vaigista"
+ },
+ "chat": {
+ "title": "Vestlus"
}
}
diff --git a/src/i18n/fi.json b/src/i18n/fi.json
index ac8b2ac9..99a1b53a 100644
--- a/src/i18n/fi.json
+++ b/src/i18n/fi.json
@@ -19,7 +19,16 @@
"apply": "Aseta",
"submit": "Lähetä",
"more": "Lisää",
- "generic_error": "Virhe tapahtui"
+ "generic_error": "Virhe tapahtui",
+ "optional": "valinnainen",
+ "show_more": "Näytä lisää",
+ "show_less": "Näytä vähemmän",
+ "dismiss": "Sulje",
+ "cancel": "Peruuta",
+ "disable": "Poista käytöstä",
+ "confirm": "Hyväksy",
+ "verify": "Varmenna",
+ "enable": "Ota käyttöön"
},
"login": {
"login": "Kirjaudu sisään",
@@ -28,7 +37,16 @@
"password": "Salasana",
"placeholder": "esim. Seppo",
"register": "Rekisteröidy",
- "username": "Käyttäjänimi"
+ "username": "Käyttäjänimi",
+ "hint": "Kirjaudu sisään liittyäksesi keskusteluun",
+ "authentication_code": "Todennuskoodi",
+ "enter_recovery_code": "Syötä palautuskoodi",
+ "recovery_code": "Palautuskoodi",
+ "heading": {
+ "totp": "Monivaihetodennus",
+ "recovery": "Monivaihepalautus"
+ },
+ "enter_two_factor_code": "Syötä monivaihetodennuskoodi"
},
"nav": {
"about": "Tietoja",
@@ -43,7 +61,9 @@
"twkn": "Koko Tunnettu Verkosto",
"user_search": "Käyttäjähaku",
"who_to_follow": "Seurausehdotukset",
- "preferences": "Asetukset"
+ "preferences": "Asetukset",
+ "administration": "Ylläpito",
+ "search": "Haku"
},
"notifications": {
"broken_favorite": "Viestiä ei löydetty...",
@@ -54,7 +74,9 @@
"read": "Lue!",
"repeated_you": "toisti viestisi",
"no_more_notifications": "Ei enempää ilmoituksia",
- "reacted_with": "lisäsi reaktion {0}"
+ "reacted_with": "lisäsi reaktion {0}",
+ "migrated_to": "siirtyi sivulle",
+ "follow_request": "haluaa seurata sinua"
},
"polls": {
"add_poll": "Lisää äänestys",
@@ -68,12 +90,14 @@
"expiry": "Äänestyksen kesto",
"expires_in": "Päättyy {0} päästä",
"expired": "Päättyi {0} sitten",
- "not_enough_option": "Liian vähän uniikkeja vaihtoehtoja äänestyksessä"
+ "not_enough_option": "Liian vähän uniikkeja vaihtoehtoja äänestyksessä",
+ "not_enough_options": "Liian vähän ainutkertaisia vaihtoehtoja"
},
"interactions": {
"favs_repeats": "Toistot ja tykkäykset",
"follows": "Uudet seuraukset",
- "load_older": "Lataa vanhempia interaktioita"
+ "load_older": "Lataa vanhempia interaktioita",
+ "moves": "Käyttäjien siirtymiset"
},
"post_status": {
"new_status": "Uusi viesti",
@@ -81,7 +105,10 @@
"account_not_locked_warning_link": "lukittu",
"attachments_sensitive": "Merkkaa liitteet arkaluonteisiksi",
"content_type": {
- "text/plain": "Tavallinen teksti"
+ "text/plain": "Tavallinen teksti",
+ "text/html": "HTML",
+ "text/markdown": "Markdown",
+ "text/bbcode": "BBCode"
},
"content_warning": "Aihe (valinnainen)",
"default": "Tulin juuri saunasta.",
@@ -92,6 +119,13 @@
"private": "Vain-seuraajille - Näkyy vain seuraajillesi",
"public": "Julkinen - Näkyy julkisilla aikajanoilla",
"unlisted": "Listaamaton - Ei näy julkisilla aikajanoilla"
+ },
+ "direct_warning_to_all": "Tämä viesti näkyy vain viestissä mainituille käyttäjille.",
+ "direct_warning_to_first_only": "Tämä viesti näkyy vain viestin alussa mainituille käyttäjille.",
+ "scope_notice": {
+ "public": "Tämä viesti näkyy kaikille",
+ "private": "Tämä viesti näkyy vain sinun seuraajillesi",
+ "unlisted": "Tämä viesti ei näy Julkisella Aikajanalla tai Koko Tunnettu Verkosto -aikajanalla"
}
},
"registration": {
@@ -110,7 +144,10 @@
"password_required": "ei voi olla tyhjä",
"password_confirmation_required": "ei voi olla tyhjä",
"password_confirmation_match": "pitää vastata salasanaa"
- }
+ },
+ "username_placeholder": "esim. peke",
+ "fullname_placeholder": "esim. Pekka Postaaja",
+ "bio_placeholder": "esim.\nHei, olen Pekka.\nOlen esimerkkikäyttäjä tässä verkostossa."
},
"settings": {
"attachmentRadius": "Liitteet",
@@ -151,7 +188,7 @@
"follow_import": "Seurausten tuonti",
"follow_import_error": "Virhe tuodessa seuraksia",
"follows_imported": "Seuraukset tuotu! Niiden käsittely vie hetken.",
- "foreground": "Korostus",
+ "foreground": "Etuala",
"general": "Yleinen",
"hide_attachments_in_convo": "Piilota liitteet keskusteluissa",
"hide_attachments_in_tl": "Piilota liitteet aikajanalla",
@@ -186,14 +223,14 @@
"notification_visibility_mentions": "Maininnat",
"notification_visibility_repeats": "Toistot",
"notification_visibility_emoji_reactions": "Reaktiot",
- "no_rich_text_description": "Älä näytä tekstin muotoilua.",
+ "no_rich_text_description": "Älä näytä tekstin muotoilua",
"hide_network_description": "Älä näytä seurauksiani tai seuraajiani",
"nsfw_clickthrough": "Piilota NSFW liitteet klikkauksen taakse",
"oauth_tokens": "OAuth-merkit",
"token": "Token",
"refresh_token": "Päivitä token",
"valid_until": "Voimassa asti",
- "revoke_token": "Peruuttaa",
+ "revoke_token": "Peruuta",
"panelRadius": "Ruudut",
"pause_on_unfocused": "Pysäytä automaattinen viestien näyttö välilehden ollessa pois fokuksesta",
"presets": "Valmiit teemat",
@@ -231,6 +268,228 @@
"values": {
"false": "pois päältä",
"true": "päällä"
+ },
+ "hide_follows_description": "Älä näytä ketä seuraan",
+ "show_moderator_badge": "Näytä Moderaattori-merkki profiilissani",
+ "useStreamingApi": "Vastaanota viestiejä ja ilmoituksia reaaliajassa",
+ "notification_setting_filters": "Suodattimet",
+ "notification_setting": "Vastaanota ilmoituksia seuraavista:",
+ "notification_setting_privacy_option": "Piilota lähettäjä ja sisältö sovelluksen ulkopuolisista ilmoituksista",
+ "enable_web_push_notifications": "Ota käyttöön sovelluksen ulkopuoliset ilmoitukset",
+ "app_name": "Sovelluksen nimi",
+ "security": "Turvallisuus",
+ "mfa": {
+ "otp": "OTP",
+ "setup_otp": "OTP-asetukset",
+ "wait_pre_setup_otp": "esiasetetaan OTP:ta",
+ "confirm_and_enable": "Hyväksy ja käytä OTP",
+ "title": "Monivaihetodennus",
+ "generate_new_recovery_codes": "Luo uudet palautuskoodit",
+ "authentication_methods": "Todennus",
+ "warning_of_generate_new_codes": "Luodessasi uudet palautuskoodit, vanhat koodisi lakkaavat toimimasta.",
+ "recovery_codes": "Palautuskoodit.",
+ "waiting_a_recovery_codes": "Odotetaan palautuskoodeja...",
+ "recovery_codes_warning": "Kirjoita koodit ylös tai tallenna ne turvallisesti, muuten et näe niitä uudestaan. Jos et voi käyttää monivaihetodennusta ja sinulla ei ole palautuskoodeja, et voi enää kirjautua sisään tilillesi.",
+ "scan": {
+ "title": "Skannaa",
+ "secret_code": "Avain",
+ "desc": "Käytä monivaihetodennus-sovellusta skannakksesi tämän QR-kooding, tai syötä avain:"
+ },
+ "verify": {
+ "desc": "Kytkeäksesi päälle monivaihetodennuksen, syötä koodi monivaihetodennussovellksesta:"
+ }
+ },
+ "allow_following_move": "Salli automaattinen seuraaminen kun käyttäjä siirtää tilinsä",
+ "block_export": "Estojen vienti",
+ "block_export_button": "Vie estosi CSV-tiedostoon",
+ "block_import": "Estojen tuonti",
+ "block_import_error": "Virhe tuodessa estoja",
+ "blocks_imported": "Estot tuotu! Käsittely vie hetken.",
+ "blocks_tab": "Estot",
+ "change_email": "Vaihda sähköpostiosoite",
+ "change_email_error": "Virhe vaihtaessa sähköpostiosoitetta.",
+ "changed_email": "Sähköpostiosoite vaihdettu!",
+ "domain_mutes": "Sivut",
+ "avatar_size_instruction": "Suositeltu vähimmäiskoko profiilikuville on 150x150 pikseliä.",
+ "accent": "Korostus",
+ "hide_muted_posts": "Piilota mykistettyjen käyttäjien viestit",
+ "hide_filtered_statuses": "Piilota mykistetyt viestit",
+ "import_blocks_from_a_csv_file": "Tuo estot CSV-tiedostosta",
+ "no_blocks": "Ei estoja",
+ "no_mutes": "Ei mykistyksiä",
+ "notification_visibility_moves": "Käyttäjien siirtymiset",
+ "hide_followers_description": "Älä näytä ketkä seuraavat minua",
+ "hide_follows_count_description": "Älä näytä seurauksien määrää",
+ "hide_followers_count_description": "Älä näytä seuraajien määrää",
+ "show_admin_badge": "Näytä Ylläpitäjä-merkki proofilissani",
+ "autohide_floating_post_button": "Piilota Uusi Viesti -nappi automaattisesti (mobiili)",
+ "search_user_to_block": "Hae estettäviä käyttäjiä",
+ "search_user_to_mute": "Hae mykistettäviä käyttäjiä",
+ "minimal_scopes_mode": "Yksinkertaista näkyvyydenrajauksen vaihtoehdot",
+ "post_status_content_type": "Uuden viestin sisällön muoto",
+ "user_mutes": "Käyttäjät",
+ "useStreamingApiWarning": "(Kokeellinen)",
+ "type_domains_to_mute": "Syötä mykistettäviä sivustoja",
+ "upload_a_photo": "Lataa kuva",
+ "fun": "Hupi",
+ "greentext": "Meeminuolet",
+ "notifications": "Ilmoitukset",
+ "style": {
+ "switcher": {
+ "save_load_hint": "\"Säilytä\" asetukset säilyttävät tällä hetkellä asetetut asetukset valittaessa tai ladatessa teemaa, se myös tallentaa kyseiset asetukset viedessä teemaa. Kun kaikki laatikot ovat tyhjänä, viety teema tallentaa kaiken.",
+ "help": {
+ "older_version_imported": "Tuomasi tiedosto on luotu vanhemmalla versiolla.",
+ "fe_upgraded": "PleromaFE:n teemaus päivitetty versiopäivityksen yhteydessä.",
+ "migration_snapshot_ok": "Varmuuden vuoksi teeman kaappaus ladattu. Voit koittaa ladata teeman sisällön.",
+ "migration_napshot_gone": "Jostain syystä teeman kaappaus puuttuu, kaikki asiat eivät välttämättä näytä oikealta.",
+ "snapshot_source_mismatch": "Versiot eivät täsmää: todennäköisesti versio vaihdettu vanhempaan ja päivitetty uudestaan, jos vaihdoit teemaa vanhalla versiolla, sinun tulisi käyttää vanhaa versiota, muutoin uutta.",
+ "upgraded_from_v2": "PleromaFE on päivitetty, teemasi saattaa näyttää erilaiselta kuin muistat.",
+ "v2_imported": "Tuomasi tiedosto on luotu vanhemmalla versiolla. Yhteensopivuus ei välttämättä ole täydellinen.",
+ "future_version_imported": "Tuomasi tiedosto on luotu uudemmalla versiolla.",
+ "snapshot_present": "Teeman kaappaus ladattu, joten kaikki arvot ovat ylikirjoitettu. Voit sen sijaan ladata teeman sisällön.",
+ "snapshot_missing": "Teeman kaappausta ei tiedostossa, joten se voi näyttää erilaiselta kuin suunniteltu.",
+ "fe_downgraded": "PleromaFE:n versio vaihtunut vanhempaan."
+ },
+ "keep_color": "Säilytä värit",
+ "keep_shadows": "Säilytä varjot",
+ "keep_opacity": "Säilytä läpinäkyvyys",
+ "keep_roundness": "Säilytä pyöristys",
+ "keep_fonts": "Säilytä fontit",
+ "reset": "Palauta",
+ "clear_all": "Tyhjennä kaikki",
+ "clear_opacity": "Tyhjennä läpinäkyvyys",
+ "load_theme": "Lataa teema",
+ "keep_as_is": "Pidä sellaisenaan",
+ "use_snapshot": "Vanha",
+ "use_source": "Uusi"
+ },
+ "advanced_colors": {
+ "selectedPost": "Valittu viesti",
+ "_tab_label": "Edistynyt",
+ "alert": "Varoituksen tausta",
+ "alert_error": "Virhe",
+ "alert_warning": "Varoitus",
+ "alert_neutral": "Neutraali",
+ "post": "Viestit/Käyttäjien kuvaukset",
+ "badge": "Merkin tausta",
+ "badge_notification": "Ilmoitus",
+ "panel_header": "Ruudun otsikko",
+ "top_bar": "Yläpalkki",
+ "borders": "Reunat",
+ "buttons": "Napit",
+ "inputs": "Syöttökentät",
+ "faint_text": "Häivytetty teksti",
+ "underlay": "Taustapeite",
+ "poll": "Äänestyksen kuvaaja",
+ "icons": "Ikonit",
+ "highlight": "Korostetut elementit",
+ "pressed": "Painettu",
+ "selectedMenu": "Valikon valinta",
+ "disabled": "Pois käytöstä",
+ "toggled": "Kytketty",
+ "tabs": "Välilehdet",
+ "popover": "Työkaluvinkit, valikot, ponnahdusviestit"
+ },
+ "common": {
+ "color": "Väri",
+ "opacity": "Läpinäkyvyys",
+ "contrast": {
+ "level": {
+ "aaa": "saavuttaa AAA-tason (suositeltu)",
+ "aa": "saavuttaa AA-tason (minimi)",
+ "bad": "ei saavuta mitään helppokäyttöisyyssuosituksia"
+ },
+ "hint": "Kontrastisuhde on {ratio}, se {level} {context}",
+ "context": {
+ "18pt": "suurella (18pt+) tekstillä",
+ "text": "tekstillä"
+ }
+ }
+ },
+ "common_colors": {
+ "_tab_label": "Yleinen",
+ "main": "Yleiset värit",
+ "foreground_hint": "Löydät \"Edistynyt\"-välilehdeltä tarkemmat asetukset",
+ "rgbo": "Ikonit, korostukset, merkit"
+ },
+ "shadows": {
+ "filter_hint": {
+ "always_drop_shadow": "Varoitus, tämä varjo käyttää aina {0} kun selain tukee sitä.",
+ "avatar_inset": "Huom. sisennettyjen ja ei-sisennettyjen varjojen yhdistelmät saattavat luoda ei-odotettuja lopputuloksia läpinäkyvillä profiilikuvilla.",
+ "drop_shadow_syntax": "{0} ei tue {1} parametria ja {2} avainsanaa.",
+ "spread_zero": "Varjot joiden levitys > 0 näyttävät samalta kuin se olisi nolla",
+ "inset_classic": "Sisennetyt varjot käyttävät {0}"
+ },
+ "components": {
+ "buttonPressedHover": "Nappi (painettu ja kohdistettu)",
+ "panel": "Ruutu",
+ "panelHeader": "Ruudun otsikko",
+ "topBar": "Yläpalkki",
+ "avatar": "Profiilikuva (profiilinäkymässä)",
+ "avatarStatus": "Profiilikuva (viestin yhtyedessä)",
+ "popup": "Ponnahdusviestit ja työkaluvinkit",
+ "button": "Nappi",
+ "buttonHover": "Nappi (kohdistus)",
+ "buttonPressed": "Nappi (painettu)",
+ "input": "Syöttökenttä"
+ },
+ "hintV3": "Voit käyttää {0} merkintää varjoille käyttääksesi väriä toisesta asetuksesta.",
+ "_tab_label": "Valo ja varjostus",
+ "component": "Komponentti",
+ "override": "Ylikirjoita",
+ "shadow_id": "Varjo #{value}",
+ "blur": "Sumennus",
+ "spread": "Levitys",
+ "inset": "Sisennys"
+ },
+ "fonts": {
+ "help": "Valitse fontti käyttöliittymälle. \"Oma\"-vaihtohdolle on syötettävä fontin nimi tarkalleen samana kuin se on järjestelmässäsi.",
+ "_tab_label": "Fontit",
+ "components": {
+ "interface": "Käyttöliittymä",
+ "input": "Syöttökentät",
+ "post": "Viestin teksti",
+ "postCode": "Tasavälistetty teksti viestissä"
+ },
+ "family": "Fontin nimi",
+ "size": "Koko (pikseleissä)",
+ "weight": "Painostus (paksuus)",
+ "custom": "Oma"
+ },
+ "preview": {
+ "input": "Tulin juuri saunasta.",
+ "header": "Esikatselu",
+ "content": "Sisältö",
+ "error": "Esimerkkivirhe",
+ "button": "Nappi",
+ "text": "Vähän lisää {0} ja {1}",
+ "mono": "sisältöä",
+ "faint_link": "manuaali",
+ "fine_print": "Lue meidän {0} vaikka huvin vuoksi!",
+ "header_faint": "Tämä on OK",
+ "checkbox": "Olen silmäillyt käyttöehdot",
+ "link": "kiva linkki"
+ },
+ "radii": {
+ "_tab_label": "Pyöristys"
+ }
+ },
+ "enter_current_password_to_confirm": "Syötä nykyinen salasanasi todentaaksesi henkilöllisyytesi",
+ "discoverable": "Salli tilisi näkyvyys hakukoneisiin ja muihin palveluihin",
+ "pad_emoji": "Välistä emojit välilyönneillä lisätessäsi niitä valitsimesta",
+ "mutes_tab": "Mykistykset",
+ "new_email": "Uusi sähköpostiosoite",
+ "notification_setting_follows": "Käyttäjät joita seuraat",
+ "notification_setting_non_follows": "Käyttäjät joita et seuraa",
+ "notification_setting_followers": "Käyttäjät jotka seuraavat sinua",
+ "notification_setting_non_followers": "Käyttäjät jotka eivät seuraa sinua",
+ "notification_setting_privacy": "Yksityisyys",
+ "notification_mutes": "Jos et halua ilmoituksia joltain käyttäjältä, käytä mykistystä.",
+ "notification_blocks": "Estäminen pysäyttää kaikki ilmoitukset käyttäjältä ja poistaa seurauksen.",
+ "version": {
+ "title": "Versio",
+ "backend_version": "Palvelimen versio",
+ "frontend_version": "Käyttöliittymän versio"
}
},
"time": {
@@ -252,8 +511,8 @@
"months": "{0} kuukautta",
"month_short": "{0}kk",
"months_short": "{0}kk",
- "now": "nyt",
- "now_short": "juuri nyt",
+ "now": "juuri nyt",
+ "now_short": "nyt",
"second": "{0} sekunti",
"seconds": "{0} sekuntia",
"second_short": "{0}s",
@@ -276,7 +535,8 @@
"repeated": "toisti",
"show_new": "Näytä uudet",
"up_to_date": "Ajantasalla",
- "no_more_statuses": "Ei enempää viestejä"
+ "no_more_statuses": "Ei enempää viestejä",
+ "no_statuses": "Ei viestejä"
},
"status": {
"favorites": "Tykkäykset",
@@ -288,8 +548,10 @@
"delete_confirm": "Haluatko varmasti postaa viestin?",
"reply_to": "Vastaus",
"replies_list": "Vastaukset:",
- "mute_conversation": "Hiljennä keskustelu",
- "unmute_conversation": "Poista hiljennys"
+ "mute_conversation": "Mykistä keskustelu",
+ "unmute_conversation": "Poista mykistys",
+ "status_unavailable": "Viesti ei saatavissa",
+ "copy_link": "Kopioi linkki"
},
"user_card": {
"approve": "Hyväksy",
@@ -298,7 +560,7 @@
"deny": "Älä hyväksy",
"follow": "Seuraa",
"follow_sent": "Pyyntö lähetetty!",
- "follow_progress": "Pyydetään...",
+ "follow_progress": "Pyydetään…",
"follow_again": "Lähetä pyyntö uudestaan",
"follow_unfollow": "Älä seuraa",
"followees": "Seuraa",
@@ -306,14 +568,50 @@
"following": "Seuraat!",
"follows_you": "Seuraa sinua!",
"its_you": "Sinun tili!",
- "mute": "Hiljennä",
- "muted": "Hiljennetty",
+ "mute": "Mykistä",
+ "muted": "Mykistetty",
"per_day": "päivässä",
"remote_follow": "Seuraa muualta",
- "statuses": "Viestit"
+ "statuses": "Viestit",
+ "hidden": "Piilotettu",
+ "media": "Media",
+ "block_progress": "Estetään...",
+ "admin_menu": {
+ "grant_admin": "Anna Ylläpitöoikeudet",
+ "force_nsfw": "Merkitse kaikki viestit NSFW:nä",
+ "disable_any_subscription": "Estä käyttäjän seuraaminen",
+ "moderation": "Moderaatio",
+ "revoke_admin": "Poista Ylläpitöoikeudet",
+ "grant_moderator": "Anna Moderaattorioikeudet",
+ "revoke_moderator": "Poista Moderaattorioikeudet",
+ "activate_account": "Aktivoi tili",
+ "deactivate_account": "Deaktivoi tili",
+ "delete_account": "Poista tili",
+ "strip_media": "Poista media viesteistä",
+ "force_unlisted": "Pakota viestit listaamattomiksi",
+ "sandbox": "Pakota viestit vain seuraajille",
+ "disable_remote_subscription": "Estä seuraaminen ulkopuolisilta sivuilta",
+ "quarantine": "Estä käyttäjän viestin federoituminen",
+ "delete_user": "Poista käyttäjä",
+ "delete_user_confirmation": "Oletko aivan varma? Tätä ei voi kumota."
+ },
+ "favorites": "Tykkäykset",
+ "mention": "Mainitse",
+ "report": "Ilmianna",
+ "subscribe": "Tilaa",
+ "unsubscribe": "Poista tilaus",
+ "unblock": "Poista esto",
+ "unblock_progress": "Postetaan estoa...",
+ "unmute": "Poista mykistys",
+ "unmute_progress": "Poistetaan mykistystä...",
+ "mute_progress": "Mykistetään...",
+ "hide_repeats": "Piilota toistot",
+ "show_repeats": "Näytä toistot"
},
"user_profile": {
- "timeline_title": "Käyttäjän aikajana"
+ "timeline_title": "Käyttäjän aikajana",
+ "profile_does_not_exist": "Tätä profiilia ei ole.",
+ "profile_loading_error": "Virhe ladatessa profiilia."
},
"who_to_follow": {
"more": "Lisää",
@@ -324,9 +622,12 @@
"repeat": "Toista",
"reply": "Vastaa",
"favorite": "Tykkää",
- "user_settings": "Käyttäjäasetukset"
+ "user_settings": "Käyttäjäasetukset",
+ "add_reaction": "Lisää Reaktio",
+ "accept_follow_request": "Hyväksy seurauspyyntö",
+ "reject_follow_request": "Hylkää seurauspyyntö"
},
- "upload":{
+ "upload": {
"error": {
"base": "Lataus epäonnistui.",
"file_too_big": "Tiedosto liian suuri [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
@@ -339,5 +640,108 @@
"GiB": "Gt",
"TiB": "Tt"
}
+ },
+ "about": {
+ "mrf": {
+ "keyword": {
+ "keyword_policies": "Avainsanasäännöt",
+ "ftl_removal": "Poistettu \"Koko Tunnettu Verkosto\" -aikajanalta",
+ "reject": "Hylkää",
+ "replace": "Korvaa",
+ "is_replaced_by": "→"
+ },
+ "simple": {
+ "accept": "Hyväksy",
+ "reject": "Hylkää",
+ "quarantine": "Karanteeni",
+ "ftl_removal": "Poisto \"Koko Tunnettu Verkosto\" -aikajanalta",
+ "media_removal": "Media-tiedostojen poisto",
+ "simple_policies": "Palvelinkohtaiset Säännöt",
+ "accept_desc": "Tämä palvelin hyväksyy viestit vain seuraavilta palvelimilta:",
+ "reject_desc": "Tämä palvelin ei hyväksy viestejä seuraavilta palvelimilta:",
+ "quarantine_desc": "Tämä palvelin lähettää vain julkisia viestejä seuraaville palvelimille:",
+ "ftl_removal_desc": "Tämä palvelin poistaa nämä palvelimet \"Koko Tunnettu Verkosto\"-aikajanalta:",
+ "media_removal_desc": "Tämä palvelin postaa mediatiedostot viesteistä seuraavilta palvelimilta:",
+ "media_nsfw": "Pakota Media Arkaluontoiseksi",
+ "media_nsfw_desc": "Tämä palvelin pakottaa mediatiedostot arkaluonteisiksi seuraavilta palvelimilta:"
+ },
+ "federation": "Federaatio",
+ "mrf_policies": "Aktivoidut MRF-säännöt",
+ "mrf_policies_desc": "MRF-säännöt muuttavat federaation toimintaa sivulla. Seuraavat säännöt ovat kytketty päälle:"
+ },
+ "staff": "Henkilökunta"
+ },
+ "domain_mute_card": {
+ "mute": "Mykistä",
+ "unmute": "Poista mykistys",
+ "mute_progress": "Mykistetään...",
+ "unmute_progress": "Poistetaan mykistyst..."
+ },
+ "exporter": {
+ "export": "Vie",
+ "processing": "Käsitellään, hetken päästä voit tallentaa tiedoston"
+ },
+ "image_cropper": {
+ "crop_picture": "Rajaa kuva",
+ "save": "Tallenna",
+ "save_without_cropping": "Tallenna rajaamatta",
+ "cancel": "Peruuta"
+ },
+ "importer": {
+ "submit": "Hyväksy",
+ "error": "Virhe tapahtui tietoja tuodessa.",
+ "success": "Tuonti onnistui."
+ },
+ "media_modal": {
+ "previous": "Edellinen",
+ "next": "Seuraava"
+ },
+ "emoji": {
+ "stickers": "Tarrat",
+ "emoji": "Emoji",
+ "keep_open": "Pidä valitsin auki",
+ "search_emoji": "Hae emojia",
+ "add_emoji": "Lisää emoji",
+ "custom": "Custom-emoji",
+ "load_all": "Ladataan kaikkia {emojiAmount} emojia",
+ "unicode": "Unicode-emoji",
+ "load_all_hint": "Ensimmäiset {saneAmount} emojia ladattu, kaikkien emojien lataaminen voi aiheuttaa hidastelua."
+ },
+ "remote_user_resolver": {
+ "remote_user_resolver": "Ulkopuolinen käyttäjä",
+ "searching_for": "Etsitään käyttäjää",
+ "error": "Ei löytynyt."
+ },
+ "selectable_list": {
+ "select_all": "Valitse kaikki"
+ },
+ "password_reset": {
+ "check_email": "Tarkista sähköpostisi salasanannollausta varten.",
+ "instruction": "Syötä sähköpostiosoite tai käyttäjänimi. Lähetämme linkin salasanan nollausta varten.",
+ "password_reset_disabled": "Salasanan nollaus ei käytössä. Ota yhteyttä sivun ylläpitäjään.",
+ "password_reset_required_but_mailer_is_disabled": "Sinun täytyy vaihtaa salasana, mutta salasanan nollaus on pois käytöstä. Ota yhteyttä sivun ylläpitäjään.",
+ "forgot_password": "Unohditko salasanan?",
+ "password_reset": "Salasanan nollaus",
+ "placeholder": "Sähköpostiosoite tai käyttäjänimi",
+ "return_home": "Palaa etusivulle",
+ "not_found": "Sähköpostiosoitetta tai käyttäjänimeä ei löytynyt.",
+ "too_many_requests": "Olet käyttänyt kaikki yritykset, yritä uudelleen myöhemmin.",
+ "password_reset_required": "Sinun täytyy vaihtaa salasana kirjautuaksesi."
+ },
+ "user_reporting": {
+ "add_comment_description": "Tämä raportti lähetetään sivun moderaattoreille. Voit antaa selityksen miksi ilmiannoit tilin:",
+ "title": "Ilmiannetaan {0}",
+ "additional_comments": "Lisäkommentit",
+ "forward_description": "Tämä tili on toiselta palvelimelta. Lähetä kopio ilmiannosta sinnekin?",
+ "forward_to": "Lähetä eteenpäin: {0}",
+ "submit": "Lähetä",
+ "generic_error": "Virhe käsitellessä pyyntöä."
+ },
+ "search": {
+ "people": "Käyttäjät",
+ "hashtags": "Aihetunnisteet",
+ "people_talking": "{0} käyttäjää puhuvat",
+ "person_talking": "{0} käyttäjä puhuu",
+ "no_results": "Ei tuloksia"
}
}
diff --git a/src/i18n/fr.json b/src/i18n/fr.json
index 5f0053d5..31b69a0f 100644
--- a/src/i18n/fr.json
+++ b/src/i18n/fr.json
@@ -1,549 +1,743 @@
{
- "chat": {
- "title": "Chat"
- },
- "exporter": {
- "export": "Exporter",
- "processing": "En cours de traitement, vous pourrez bientôt télécharger votre fichier"
- },
- "features_panel": {
- "chat": "Chat",
- "gopher": "Gopher",
- "media_proxy": "Proxy média",
- "scope_options": "Options de visibilité",
- "text_limit": "Limite de texte",
- "title": "Caractéristiques",
- "who_to_follow": "Personnes à suivre"
- },
- "finder": {
- "error_fetching_user": "Erreur lors de la recherche de l'utilisateur·ice",
- "find_user": "Chercher un-e utilisateur·ice"
- },
- "general": {
- "apply": "Appliquer",
- "submit": "Envoyer",
- "more": "Plus",
- "generic_error": "Une erreur s'est produite",
- "optional": "optionnel",
- "show_more": "Montrer plus",
- "show_less": "Montrer moins",
- "cancel": "Annuler",
- "disable": "Désactiver",
- "enable": "Activer",
- "confirm": "Confirmer",
- "verify": "Vérifier"
- },
- "image_cropper": {
- "crop_picture": "Rogner l'image",
- "save": "Sauvegarder",
- "save_without_cropping": "Sauvegarder sans rogner",
- "cancel": "Annuler"
- },
- "importer": {
- "submit": "Soumettre",
- "success": "Importé avec succès.",
- "error": "Une erreur est survenue pendant l'import de ce fichier."
- },
- "login": {
- "login": "Connexion",
- "description": "Connexion avec OAuth",
- "logout": "Déconnexion",
- "password": "Mot de passe",
- "placeholder": "p.e. lain",
- "register": "S'inscrire",
- "username": "Identifiant",
- "hint": "Connectez-vous pour rejoindre la discussion",
- "authentication_code": "Code d'authentification",
- "enter_recovery_code": "Entrez un code de récupération",
- "enter_two_factor_code": "Entrez un code à double authentification",
- "recovery_code": "Code de récupération",
- "heading": {
- "totp": "Authentification à double authentification",
- "recovery": "Récuperation de la double authentification"
- }
- },
- "media_modal": {
- "previous": "Précédent",
- "next": "Suivant"
- },
- "nav": {
- "about": "À propos",
- "back": "Retour",
- "chat": "Chat local",
- "friend_requests": "Demandes de suivi",
- "mentions": "Notifications",
- "interactions": "Interactions",
- "dms": "Messages directs",
- "public_tl": "Fil d'actualité public",
- "timeline": "Fil d'actualité",
- "twkn": "Ensemble du réseau connu",
- "user_search": "Recherche d'utilisateur·ice",
- "who_to_follow": "Qui suivre",
- "preferences": "Préférences"
- },
- "notifications": {
- "broken_favorite": "Chargement d'un message inconnu…",
- "favorited_you": "a aimé votre statut",
- "followed_you": "a commencé à vous suivre",
- "load_older": "Charger les notifications précédentes",
- "notifications": "Notifications",
- "read": "Lu !",
- "repeated_you": "a partagé votre statut",
- "no_more_notifications": "Aucune notification supplémentaire"
- },
- "interactions": {
- "favs_repeats": "Partages et favoris",
- "follows": "Nouveaux⋅elles abonné⋅e⋅s ?",
- "load_older": "Chargez d'anciennes interactions"
- },
- "post_status": {
- "new_status": "Poster un nouveau statut",
- "account_not_locked_warning": "Votre compte n'est pas {0}. N'importe qui peut vous suivre pour voir vos billets en Abonné·e·s uniquement.",
- "account_not_locked_warning_link": "verrouillé",
- "attachments_sensitive": "Marquer le média comme sensible",
- "content_type": {
- "text/plain": "Texte brut",
- "text/html": "HTML",
- "text/markdown": "Markdown",
- "text/bbcode": "BBCode"
- },
- "content_warning": "Sujet (optionnel)",
- "default": "Écrivez ici votre prochain statut.",
- "direct_warning_to_all": "Ce message sera visible pour toutes les personnes mentionnées.",
- "direct_warning_to_first_only": "Ce message sera visible uniquement pour personnes mentionnées au début du message.",
- "posting": "Envoi en cours",
- "scope_notice": {
- "public": "Ce statut sera visible par tout le monde",
- "private": "Ce statut sera visible par seulement vos abonné⋅e⋅s",
- "unlisted": "Ce statut ne sera pas visible dans le Fil d'actualité public et l'Ensemble du réseau connu"
- },
- "scope": {
- "direct": "Direct - N'envoyer qu'aux personnes mentionnées",
- "private": "Abonné·e·s uniquement - Seul·e·s vos abonné·e·s verront vos billets",
- "public": "Publique - Afficher dans les fils publics",
- "unlisted": "Non-Listé - Ne pas afficher dans les fils publics"
- }
- },
- "registration": {
- "bio": "Biographie",
- "email": "Adresse mail",
- "fullname": "Pseudonyme",
- "password_confirm": "Confirmation du mot de passe",
- "registration": "Inscription",
- "token": "Jeton d'invitation",
- "captcha": "CAPTCHA",
- "new_captcha": "Cliquez sur l'image pour avoir un nouveau captcha",
- "username_placeholder": "p.e. lain",
- "fullname_placeholder": "p.e. Lain Iwakura",
- "bio_placeholder": "p.e.\nSalut, je suis Lain\nJe suis une héroïne d'animé qui vit dans une banlieue japonaise. Vous me connaissez peut-être du Wired.",
- "validations": {
- "username_required": "ne peut pas être laissé vide",
- "fullname_required": "ne peut pas être laissé vide",
- "email_required": "ne peut pas être laissé vide",
- "password_required": "ne peut pas être laissé vide",
- "password_confirmation_required": "ne peut pas être laissé vide",
- "password_confirmation_match": "doit être identique au mot de passe"
- }
- },
- "selectable_list": {
- "select_all": "Tout selectionner"
- },
- "settings": {
- "app_name": "Nom de l'application",
- "security": "Sécurité",
- "enter_current_password_to_confirm": "Entrez votre mot de passe actuel pour confirmer votre identité",
- "mfa": {
- "otp": "OTP",
- "setup_otp": "Configurer OTP",
- "wait_pre_setup_otp": "préconfiguration OTP",
- "confirm_and_enable": "Confirmer & activer OTP",
- "title": "Double authentification",
- "generate_new_recovery_codes": "Générer de nouveaux codes de récupération",
- "warning_of_generate_new_codes": "Quand vous générez de nouveauc codes de récupération, vos anciens codes ne fonctionnerons plus.",
- "recovery_codes": "Codes de récupération.",
- "waiting_a_recovery_codes": "Récéption des codes de récupération…",
- "recovery_codes_warning": "Écrivez les codes ou sauvez les quelquepart sécurisé - sinon vous ne les verrez plus jamais. Si vous perdez l'accès à votre application de double authentification et codes de récupération vous serez vérouillé en dehors de votre compte.",
- "authentication_methods": "Methodes d'authentification",
- "scan": {
- "title": "Scanner",
- "desc": "En utilisant votre application de double authentification, scannez ce QR code ou entrez la clé textuelle :",
- "secret_code": "Clé"
- },
- "verify": {
- "desc": "Pour activer la double authentification, entrez le code depuis votre application:"
- }
- },
- "attachmentRadius": "Pièces jointes",
- "attachments": "Pièces jointes",
- "autoload": "Charger la suite automatiquement une fois le bas de la page atteint",
- "avatar": "Avatar",
- "avatarAltRadius": "Avatars (Notifications)",
- "avatarRadius": "Avatars",
- "background": "Arrière-plan",
- "bio": "Biographie",
- "block_export": "Export des comptes bloqués",
- "block_export_button": "Export des comptes bloqués vers un fichier csv",
- "block_import": "Import des comptes bloqués",
- "block_import_error": "Erreur lors de l'import des comptes bloqués",
- "blocks_imported": "Blocks importés! Le traitement va prendre un moment.",
- "blocks_tab": "Bloqué·e·s",
- "btnRadius": "Boutons",
- "cBlue": "Bleu (répondre, suivre)",
- "cGreen": "Vert (partager)",
- "cOrange": "Orange (aimer)",
- "cRed": "Rouge (annuler)",
- "change_password": "Changez votre mot de passe",
- "change_password_error": "Il y a eu un problème pour changer votre mot de passe.",
- "changed_password": "Mot de passe modifié avec succès !",
- "collapse_subject": "Réduire les messages avec des sujets",
- "composing": "Composition",
- "confirm_new_password": "Confirmation du nouveau mot de passe",
- "current_avatar": "Avatar actuel",
- "current_password": "Mot de passe actuel",
- "current_profile_banner": "Bannière de profil actuelle",
- "data_import_export_tab": "Import / Export des Données",
- "default_vis": "Visibilité par défaut",
- "delete_account": "Supprimer le compte",
- "delete_account_description": "Supprimer définitivement votre compte et tous vos statuts.",
- "delete_account_error": "Il y a eu un problème lors de la tentative de suppression de votre compte. Si le problème persiste, contactez l'administrateur⋅ice de cette instance.",
- "delete_account_instructions": "Indiquez votre mot de passe ci-dessous pour confirmer la suppression de votre compte.",
- "avatar_size_instruction": "La taille minimale recommandée pour l'image de l'avatar est de 150x150 pixels.",
- "export_theme": "Enregistrer le thème",
- "filtering": "Filtre",
- "filtering_explanation": "Tous les statuts contenant ces mots seront masqués. Un mot par ligne",
- "follow_export": "Exporter les abonnements",
- "follow_export_button": "Exporter les abonnements en csv",
- "follow_import": "Importer des abonnements",
- "follow_import_error": "Erreur lors de l'importation des abonnements",
- "follows_imported": "Abonnements importés ! Le traitement peut prendre un moment.",
- "foreground": "Premier plan",
- "general": "Général",
- "hide_attachments_in_convo": "Masquer les pièces jointes dans les conversations",
- "hide_attachments_in_tl": "Masquer les pièces jointes dans le journal",
- "hide_muted_posts": "Masquer les statuts des utilisateurs masqués",
- "max_thumbnails": "Nombre maximum de miniatures par statuts",
- "hide_isp": "Masquer le panneau spécifique a l'instance",
- "preload_images": "Précharger les images",
- "use_one_click_nsfw": "Ouvrir les pièces-jointes NSFW avec un seul clic",
- "hide_post_stats": "Masquer les statistiques de publication (le nombre de favoris)",
- "hide_user_stats": "Masquer les statistiques de profil (le nombre d'amis)",
- "hide_filtered_statuses": "Masquer les statuts filtrés",
- "import_blocks_from_a_csv_file": "Importer les blocages depuis un fichier csv",
- "import_followers_from_a_csv_file": "Importer des abonnements depuis un fichier csv",
- "import_theme": "Charger le thème",
- "inputRadius": "Champs de texte",
- "checkboxRadius": "Cases à cocher",
- "instance_default": "(default: {value})",
- "instance_default_simple": "(default)",
- "interface": "Interface",
- "interfaceLanguage": "Langue de l'interface",
- "invalid_theme_imported": "Le fichier sélectionné n'est pas un thème Pleroma pris en charge. Aucun changement n'a été apporté à votre thème.",
- "limited_availability": "Non disponible dans votre navigateur",
- "links": "Liens",
- "lock_account_description": "Limitez votre compte aux abonnés acceptés uniquement",
- "loop_video": "Vidéos en boucle",
- "loop_video_silent_only": "Boucle uniquement les vidéos sans le son (les « gifs » de Mastodon)",
- "mutes_tab": "Comptes silenciés",
- "play_videos_in_modal": "Jouer les vidéos directement dans le visionneur de médias",
- "use_contain_fit": "Ne pas rogner les miniatures des pièces-jointes",
- "name": "Nom",
- "name_bio": "Nom & Bio",
- "new_password": "Nouveau mot de passe",
- "notification_visibility": "Types de notifications à afficher",
- "notification_visibility_follows": "Abonnements",
- "notification_visibility_likes": "J'aime",
- "notification_visibility_mentions": "Mentionnés",
- "notification_visibility_repeats": "Partages",
- "no_rich_text_description": "Ne formatez pas le texte",
- "no_blocks": "Aucun bloqués",
- "no_mutes": "Aucun masqués",
- "hide_follows_description": "Ne pas afficher à qui je suis abonné",
- "hide_followers_description": "Ne pas afficher qui est abonné à moi",
- "show_admin_badge": "Afficher le badge d'Administrateur⋅ice sur mon profil",
- "show_moderator_badge": "Afficher le badge de Modérateur⋅ice sur mon profil",
- "nsfw_clickthrough": "Masquer les images marquées comme contenu adulte ou sensible",
- "oauth_tokens": "Jetons OAuth",
- "token": "Jeton",
- "refresh_token": "Refresh Token",
- "valid_until": "Valable jusque",
- "revoke_token": "Révoquer",
- "panelRadius": "Fenêtres",
- "pause_on_unfocused": "Suspendre le streaming lorsque l'onglet n'est pas actif",
- "presets": "Thèmes prédéfinis",
- "profile_background": "Image de fond",
- "profile_banner": "Bannière de profil",
- "profile_tab": "Profil",
- "radii_help": "Vous pouvez ici choisir le niveau d'arrondi des angles de l'interface (en pixels)",
- "replies_in_timeline": "Réponses au journal",
- "reply_link_preview": "Afficher un aperçu lors du survol de liens vers une réponse",
- "reply_visibility_all": "Montrer toutes les réponses",
- "reply_visibility_following": "Afficher uniquement les réponses adressées à moi ou aux personnes que je suis",
- "reply_visibility_self": "Afficher uniquement les réponses adressées à moi",
- "autohide_floating_post_button": "Automatiquement cacher le bouton de Nouveau Statut (sur mobile)",
- "saving_err": "Erreur lors de l'enregistrement des paramètres",
- "saving_ok": "Paramètres enregistrés",
- "search_user_to_block": "Rechercher qui vous voulez bloquer",
- "search_user_to_mute": "Rechercher qui vous voulez masquer",
- "security_tab": "Sécurité",
- "scope_copy": "Garder la même visibilité en répondant (les DMs restent toujours des DMs)",
- "minimal_scopes_mode": "Rétrécir les options de séléction de la portée",
- "set_new_avatar": "Changer d'avatar",
- "set_new_profile_background": "Changer d'image de fond",
- "set_new_profile_banner": "Changer de bannière",
- "settings": "Paramètres",
- "subject_input_always_show": "Toujours copier le champ de sujet",
- "subject_line_behavior": "Copier le sujet en répondant",
- "subject_line_email": "Comme les mails: « re: sujet »",
- "subject_line_mastodon": "Comme mastodon: copier tel quel",
- "subject_line_noop": "Ne pas copier",
- "post_status_content_type": "Type de contenu du statuts",
- "stop_gifs": "N'animer les GIFS que lors du survol du curseur de la souris",
- "streaming": "Charger automatiquement les nouveaux statuts lorsque vous êtes au haut de la page",
- "text": "Texte",
- "theme": "Thème",
- "theme_help": "Spécifiez des codes couleur hexadécimaux (#rrvvbb) pour personnaliser les couleurs du thème.",
- "theme_help_v2_1": "Vous pouvez aussi surcharger certaines couleurs de composants et transparence via la case à cocher, utilisez le bouton « Vider tout » pour effacer toutes les surcharges.",
- "theme_help_v2_2": "Les icônes sous certaines des entrées ont un indicateur de contraste du fond/texte, survolez les pour plus d'informations détailles. Veuillez garder a l'esprit que lors de l'utilisation de transparence l'indicateur de contraste indique le pire des cas.",
- "tooltipRadius": "Info-bulles/alertes",
- "upload_a_photo": "Envoyer une photo",
- "user_settings": "Paramètres utilisateur",
- "values": {
- "false": "non",
- "true": "oui"
- },
- "notifications": "Notifications",
- "notification_setting": "Reçevoir les notifications de:",
- "notification_setting_follows": "Utilisateurs que vous suivez",
- "notification_setting_non_follows": "Utilisateurs que vous ne suivez pas",
- "notification_setting_followers": "Utilisateurs qui vous suivent",
- "notification_setting_non_followers": "Utilisateurs qui ne vous suivent pas",
- "notification_mutes": "Pour stopper la récéption de notifications d'un utilisateur particulier, utilisez un masquage.",
- "notification_blocks": "Bloquer un utilisateur stoppe toute notification et se désabonne de lui.",
- "enable_web_push_notifications": "Activer les notifications de push web",
- "style": {
- "switcher": {
- "keep_color": "Garder les couleurs",
- "keep_shadows": "Garder les ombres",
- "keep_opacity": "Garder la transparence",
- "keep_roundness": "Garder la rondeur",
- "keep_fonts": "Garder les polices",
- "save_load_hint": "L'option « Garder » préserve les options activés en cours lors de la séléction ou chargement des thèmes, il sauve aussi les dites options lors de l'export d'un thème. Quand toutes les cases sont décochés, exporter un thème sauvera tout.",
- "reset": "Remise à zéro",
- "clear_all": "Tout vider",
- "clear_opacity": "Vider la transparence"
- },
- "common": {
- "color": "Couleur",
- "opacity": "Transparence",
- "contrast": {
- "hint": "Le ratio de contraste est {ratio}, il {level} {context}",
- "level": {
- "aa": "répond aux directives de niveau AA (minimum)",
- "aaa": "répond aux directives de niveau AAA (recommandé)",
- "bad": "ne réponds à aucune directive d'accessibilité"
- },
- "context": {
- "18pt": "pour texte large (19pt+)",
- "text": "pour texte"
- }
- }
- },
- "common_colors": {
- "_tab_label": "Commun",
- "main": "Couleurs communes",
- "foreground_hint": "Voir l'onglet « Avancé » pour plus de contrôle détaillé",
- "rgbo": "Icônes, accents, badges"
- },
- "advanced_colors": {
- "_tab_label": "Avancé",
- "alert": "Fond d'alerte",
- "alert_error": "Erreur",
- "badge": "Fond de badge",
- "badge_notification": "Notification",
- "panel_header": "Entête de panneau",
- "top_bar": "Barre du haut",
- "borders": "Bordures",
- "buttons": "Boutons",
- "inputs": "Champs de saisie",
- "faint_text": "Texte en fondu"
- },
- "radii": {
- "_tab_label": "Rondeur"
- },
- "shadows": {
- "_tab_label": "Ombres et éclairage",
- "component": "Composant",
- "override": "Surcharger",
- "shadow_id": "Ombre #{value}",
- "blur": "Flou",
- "spread": "Dispersion",
- "inset": "Interne",
- "hint": "Pour les ombres, vous pouvez aussi utiliser --variable comme valeur de couleur en CSS3. Veuillez noter que spécifier la transparence ne fonctionnera pas dans ce cas.",
- "filter_hint": {
- "always_drop_shadow": "Attention, cette ombre utilise toujours {0} quand le navigateur le supporte.",
- "drop_shadow_syntax": "{0} ne supporte pas le paramètre {1} et mot-clé {2}.",
- "avatar_inset": "Veuillez noter que combiner a la fois les ombres internes et non-internes sur les avatars peut fournir des résultats innatendus avec la transparence des avatars.",
- "spread_zero": "Les ombres avec une dispersion > 0 apparaitrons comme si ils étaient à zéro",
- "inset_classic": "L'ombre interne utilisera toujours {0}"
- },
- "components": {
- "panel": "Panneau",
- "panelHeader": "En-tête de panneau",
- "topBar": "Barre du haut",
- "avatar": "Avatar utilisateur⋅ice (dans la vue de profil)",
- "avatarStatus": "Avatar utilisateur⋅ice (dans la vue de statuts)",
- "popup": "Popups et infobulles",
- "button": "Bouton",
- "buttonHover": "Bouton (survol)",
- "buttonPressed": "Bouton (cliqué)",
- "buttonPressedHover": "Bouton (cliqué+survol)",
- "input": "Champ de saisie"
- }
- },
- "fonts": {
- "_tab_label": "Polices",
- "help": "Sélectionnez la police à utiliser pour les éléments de l'UI. Pour « personnalisé » vous avez à entrer le nom exact de la police comme il apparaît dans le système.",
- "components": {
- "interface": "Interface",
- "input": "Champs de saisie",
- "post": "Post text",
- "postCode": "Texte à taille fixe dans un article (texte enrichi)"
- },
- "family": "Nom de la police",
- "size": "Taille (en px)",
- "weight": "Poid (gras)",
- "custom": "Personnalisé"
- },
- "preview": {
- "header": "Prévisualisation",
- "content": "Contenu",
- "error": "Exemple d'erreur",
- "button": "Bouton",
- "text": "Un certain nombre de {0} et {1}",
- "mono": "contenu",
- "input": "Je viens juste d’atterrir à L.A.",
- "faint_link": "manuel utile",
- "fine_print": "Lisez notre {0} pour n'apprendre rien d'utile !",
- "header_faint": "Tout va bien",
- "checkbox": "J'ai survolé les conditions d'utilisation",
- "link": "un petit lien sympa"
- }
- },
- "version": {
- "title": "Version",
- "backend_version": "Version du Backend",
- "frontend_version": "Version du Frontend"
- }
- },
- "timeline": {
- "collapse": "Fermer",
- "conversation": "Conversation",
- "error_fetching": "Erreur en cherchant les mises à jour",
- "load_older": "Afficher plus",
- "no_retweet_hint": "Le message est marqué en abonnés-seulement ou direct et ne peut pas être partagé",
- "repeated": "a partagé",
- "show_new": "Afficher plus",
- "up_to_date": "À jour",
- "no_more_statuses": "Pas plus de statuts",
- "no_statuses": "Aucun statuts"
- },
- "status": {
- "favorites": "Favoris",
- "repeats": "Partages",
- "delete": "Supprimer statuts",
- "pin": "Agraffer sur le profil",
- "unpin": "Dégraffer du profil",
- "pinned": "Agraffé",
- "delete_confirm": "Voulez-vous vraiment supprimer ce statuts ?",
- "reply_to": "Réponse à",
- "replies_list": "Réponses:"
- },
- "user_card": {
- "approve": "Accepter",
- "block": "Bloquer",
- "blocked": "Bloqué !",
- "deny": "Rejeter",
- "favorites": "Favoris",
- "follow": "Suivre",
- "follow_sent": "Demande envoyée !",
- "follow_progress": "Demande en cours…",
- "follow_again": "Renvoyer la demande ?",
- "follow_unfollow": "Désabonner",
- "followees": "Suivis",
- "followers": "Vous suivent",
- "following": "Suivi !",
- "follows_you": "Vous suit !",
- "its_you": "C'est vous !",
- "media": "Media",
- "mute": "Masquer",
- "muted": "Masqué",
- "per_day": "par jour",
- "remote_follow": "Suivre d'une autre instance",
- "report": "Signalement",
- "statuses": "Statuts",
- "unblock": "Débloquer",
- "unblock_progress": "Déblocage…",
- "block_progress": "Blocage…",
- "unmute": "Démasquer",
- "unmute_progress": "Démasquage…",
- "mute_progress": "Masquage…",
- "admin_menu": {
- "moderation": "Moderation",
- "grant_admin": "Promouvoir Administrateur⋅ice",
- "revoke_admin": "Dégrader Administrateur⋅ice",
- "grant_moderator": "Promouvoir Modérateur⋅ice",
- "revoke_moderator": "Dégrader Modérateur⋅ice",
- "activate_account": "Activer le compte",
- "deactivate_account": "Désactiver le compte",
- "delete_account": "Supprimer le compte",
- "force_nsfw": "Marquer tous les statuts comme NSFW",
- "strip_media": "Supprimer les medias des statuts",
- "force_unlisted": "Forcer les statuts à être délistés",
- "sandbox": "Forcer les statuts à être visibles seuleument pour les abonné⋅e⋅s",
- "disable_remote_subscription": "Interdir de s'abonner a l'utilisateur depuis l'instance distante",
- "disable_any_subscription": "Interdir de s'abonner à l'utilisateur tout court",
- "quarantine": "Interdir les statuts de l'utilisateur à fédérer",
- "delete_user": "Supprimer l'utilisateur",
- "delete_user_confirmation": "Êtes-vous absolument-sûr⋅e ? Cette action ne peut être annulée."
- }
- },
- "user_profile": {
- "timeline_title": "Journal de l'utilisateur⋅ice",
- "profile_does_not_exist": "Désolé, ce profil n'existe pas.",
- "profile_loading_error": "Désolé, il y a eu une erreur au chargement du profil."
- },
- "user_reporting": {
- "title": "Signaler {0}",
- "add_comment_description": "Ce signalement sera envoyé aux modérateur⋅ice⋅s de votre instance. Vous pouvez fournir une explication de pourquoi vous signalez ce compte ci-dessous :",
- "additional_comments": "Commentaires additionnels",
- "forward_description": "Le compte vient d'un autre serveur. Envoyer une copie du signalement à celui-ci aussi ?",
- "forward_to": "Transmettre à {0}",
- "submit": "Envoyer",
- "generic_error": "Une erreur est survenue lors du traitement de votre requête."
- },
- "who_to_follow": {
- "more": "Plus",
- "who_to_follow": "À qui s'abonner"
- },
- "tool_tip": {
- "media_upload": "Envoyer un media",
- "repeat": "Répéter",
- "reply": "Répondre",
- "favorite": "Favoriser",
- "user_settings": "Paramètres utilisateur"
- },
- "upload": {
- "error": {
- "base": "L'envoi a échoué.",
- "file_too_big": "Fichier trop gros [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
- "default": "Réessayez plus tard"
- },
- "file_size_units": {
- "B": "O",
- "KiB": "KiO",
- "MiB": "MiO",
- "GiB": "GiO",
- "TiB": "TiO"
- }
+ "chat": {
+ "title": "Chat"
+ },
+ "exporter": {
+ "export": "Exporter",
+ "processing": "En cours de traitement, vous pourrez bientôt télécharger votre fichier"
+ },
+ "features_panel": {
+ "chat": "Chat",
+ "gopher": "Gopher",
+ "media_proxy": "Proxy média",
+ "scope_options": "Options de visibilité",
+ "text_limit": "Limite de texte",
+ "title": "Caractéristiques",
+ "who_to_follow": "Personnes à suivre"
+ },
+ "finder": {
+ "error_fetching_user": "Erreur lors de la recherche de l'utilisateur·ice",
+ "find_user": "Chercher un-e utilisateur·ice"
+ },
+ "general": {
+ "apply": "Appliquer",
+ "submit": "Envoyer",
+ "more": "Plus",
+ "generic_error": "Une erreur s'est produite",
+ "optional": "optionnel",
+ "show_more": "Montrer plus",
+ "show_less": "Montrer moins",
+ "cancel": "Annuler",
+ "disable": "Désactiver",
+ "enable": "Activer",
+ "confirm": "Confirmer",
+ "verify": "Vérifier",
+ "dismiss": "Rejeter"
+ },
+ "image_cropper": {
+ "crop_picture": "Rogner l'image",
+ "save": "Sauvegarder",
+ "save_without_cropping": "Sauvegarder sans rogner",
+ "cancel": "Annuler"
+ },
+ "importer": {
+ "submit": "Soumettre",
+ "success": "Importé avec succès.",
+ "error": "Une erreur est survenue pendant l'import de ce fichier."
+ },
+ "login": {
+ "login": "Connexion",
+ "description": "Connexion avec OAuth",
+ "logout": "Déconnexion",
+ "password": "Mot de passe",
+ "placeholder": "p.e. lain",
+ "register": "S'inscrire",
+ "username": "Identifiant",
+ "hint": "Connectez-vous pour rejoindre la discussion",
+ "authentication_code": "Code d'authentification",
+ "enter_recovery_code": "Entrez un code de récupération",
+ "enter_two_factor_code": "Entrez un code à double authentification",
+ "recovery_code": "Code de récupération",
+ "heading": {
+ "totp": "Authentification à double authentification",
+ "recovery": "Récuperation de la double authentification"
}
+ },
+ "media_modal": {
+ "previous": "Précédent",
+ "next": "Suivant"
+ },
+ "nav": {
+ "about": "À propos",
+ "back": "Retour",
+ "chat": "Chat local",
+ "friend_requests": "Demandes de suivi",
+ "mentions": "Notifications",
+ "interactions": "Interactions",
+ "dms": "Messages directs",
+ "public_tl": "Fil d'actualité public",
+ "timeline": "Fil d'actualité",
+ "twkn": "Ensemble du réseau connu",
+ "user_search": "Recherche d'utilisateur·ice",
+ "who_to_follow": "Qui suivre",
+ "preferences": "Préférences",
+ "search": "Recherche",
+ "administration": "Administration"
+ },
+ "notifications": {
+ "broken_favorite": "Chargement d'un message inconnu…",
+ "favorited_you": "a aimé votre statut",
+ "followed_you": "a commencé à vous suivre",
+ "load_older": "Charger les notifications précédentes",
+ "notifications": "Notifications",
+ "read": "Lu !",
+ "repeated_you": "a partagé votre statut",
+ "no_more_notifications": "Aucune notification supplémentaire",
+ "migrated_to": "a migré à",
+ "reacted_with": "a réagi avec {0}",
+ "follow_request": "veut vous suivre"
+ },
+ "interactions": {
+ "favs_repeats": "Partages et favoris",
+ "follows": "Nouveaux suivis",
+ "load_older": "Chargez d'anciennes interactions",
+ "moves": "Migrations de comptes"
+ },
+ "post_status": {
+ "new_status": "Poster un nouveau statut",
+ "account_not_locked_warning": "Votre compte n'est pas {0}. N'importe qui peut vous suivre pour voir vos billets en Abonné·e·s uniquement.",
+ "account_not_locked_warning_link": "verrouillé",
+ "attachments_sensitive": "Marquer le média comme sensible",
+ "content_type": {
+ "text/plain": "Texte brut",
+ "text/html": "HTML",
+ "text/markdown": "Markdown",
+ "text/bbcode": "BBCode"
+ },
+ "content_warning": "Sujet (optionnel)",
+ "default": "Écrivez ici votre prochain statut.",
+ "direct_warning_to_all": "Ce message sera visible pour toutes les personnes mentionnées.",
+ "direct_warning_to_first_only": "Ce message sera visible uniquement pour personnes mentionnées au début du message.",
+ "posting": "Envoi en cours",
+ "scope_notice": {
+ "public": "Ce statut sera visible par tout le monde",
+ "private": "Ce statut sera visible par seulement vos abonné⋅e⋅s",
+ "unlisted": "Ce statut ne sera pas visible dans le Fil d'actualité public et l'Ensemble du réseau connu"
+ },
+ "scope": {
+ "direct": "Direct - N'envoyer qu'aux personnes mentionnées",
+ "private": "Abonné·e·s uniquement - Seul·e·s vos abonné·e·s verront vos billets",
+ "public": "Publique - Afficher dans les fils publics",
+ "unlisted": "Non-Listé - Ne pas afficher dans les fils publics"
+ }
+ },
+ "registration": {
+ "bio": "Biographie",
+ "email": "Adresse mail",
+ "fullname": "Pseudonyme",
+ "password_confirm": "Confirmation du mot de passe",
+ "registration": "Inscription",
+ "token": "Jeton d'invitation",
+ "captcha": "CAPTCHA",
+ "new_captcha": "Cliquez sur l'image pour avoir un nouveau captcha",
+ "username_placeholder": "p.e. lain",
+ "fullname_placeholder": "p.e. Lain Iwakura",
+ "bio_placeholder": "p.e.\nSalut, je suis Lain\nJe suis une héroïne d'animé qui vit dans une banlieue japonaise. Vous me connaissez peut-être du Wired.",
+ "validations": {
+ "username_required": "ne peut pas être laissé vide",
+ "fullname_required": "ne peut pas être laissé vide",
+ "email_required": "ne peut pas être laissé vide",
+ "password_required": "ne peut pas être laissé vide",
+ "password_confirmation_required": "ne peut pas être laissé vide",
+ "password_confirmation_match": "doit être identique au mot de passe"
+ }
+ },
+ "selectable_list": {
+ "select_all": "Tout selectionner"
+ },
+ "settings": {
+ "app_name": "Nom de l'application",
+ "security": "Sécurité",
+ "enter_current_password_to_confirm": "Entrez votre mot de passe actuel pour confirmer votre identité",
+ "mfa": {
+ "otp": "OTP",
+ "setup_otp": "Configurer OTP",
+ "wait_pre_setup_otp": "préconfiguration OTP",
+ "confirm_and_enable": "Confirmer & activer OTP",
+ "title": "Double authentification",
+ "generate_new_recovery_codes": "Générer de nouveaux codes de récupération",
+ "warning_of_generate_new_codes": "Quand vous générez de nouveauc codes de récupération, vos anciens codes ne fonctionnerons plus.",
+ "recovery_codes": "Codes de récupération.",
+ "waiting_a_recovery_codes": "Réception des codes de récupération…",
+ "recovery_codes_warning": "Écrivez les codes ou sauvez les quelquepart sécurisé - sinon vous ne les verrez plus jamais. Si vous perdez l'accès à votre application de double authentification et codes de récupération vous serez vérouillé en dehors de votre compte.",
+ "authentication_methods": "Methodes d'authentification",
+ "scan": {
+ "title": "Scanner",
+ "desc": "En utilisant votre application de double authentification, scannez ce QR code ou entrez la clé textuelle :",
+ "secret_code": "Clé"
+ },
+ "verify": {
+ "desc": "Pour activer la double authentification, entrez le code depuis votre application :"
+ }
+ },
+ "attachmentRadius": "Pièces jointes",
+ "attachments": "Pièces jointes",
+ "autoload": "Charger la suite automatiquement une fois le bas de la page atteint",
+ "avatar": "Avatar",
+ "avatarAltRadius": "Avatars (Notifications)",
+ "avatarRadius": "Avatars",
+ "background": "Arrière-plan",
+ "bio": "Biographie",
+ "block_export": "Export des comptes bloqués",
+ "block_export_button": "Export des comptes bloqués vers un fichier csv",
+ "block_import": "Import des comptes bloqués",
+ "block_import_error": "Erreur lors de l'import des comptes bloqués",
+ "blocks_imported": "Blocks importés ! Le traitement va prendre un moment.",
+ "blocks_tab": "Bloqué·e·s",
+ "btnRadius": "Boutons",
+ "cBlue": "Bleu (répondre, suivre)",
+ "cGreen": "Vert (partager)",
+ "cOrange": "Orange (aimer)",
+ "cRed": "Rouge (annuler)",
+ "change_password": "Changez votre mot de passe",
+ "change_password_error": "Il y a eu un problème pour changer votre mot de passe.",
+ "changed_password": "Mot de passe modifié avec succès !",
+ "collapse_subject": "Réduire les messages avec des sujets",
+ "composing": "Composition",
+ "confirm_new_password": "Confirmation du nouveau mot de passe",
+ "current_avatar": "Avatar actuel",
+ "current_password": "Mot de passe actuel",
+ "current_profile_banner": "Bannière de profil actuelle",
+ "data_import_export_tab": "Import / Export des Données",
+ "default_vis": "Visibilité par défaut",
+ "delete_account": "Supprimer le compte",
+ "delete_account_description": "Supprimer définitivement vos données et désactiver votre compte.",
+ "delete_account_error": "Il y a eu un problème lors de la tentative de suppression de votre compte. Si le problème persiste, contactez l'administrateur⋅ice de cette instance.",
+ "delete_account_instructions": "Indiquez votre mot de passe ci-dessous pour confirmer la suppression de votre compte.",
+ "avatar_size_instruction": "La taille minimale recommandée pour l'image de l'avatar est de 150x150 pixels.",
+ "export_theme": "Enregistrer le thème",
+ "filtering": "Filtre",
+ "filtering_explanation": "Tous les statuts contenant ces mots seront masqués. Un mot par ligne",
+ "follow_export": "Exporter les abonnements",
+ "follow_export_button": "Exporter les abonnements en csv",
+ "follow_import": "Importer des abonnements",
+ "follow_import_error": "Erreur lors de l'importation des abonnements",
+ "follows_imported": "Abonnements importés ! Le traitement peut prendre un moment.",
+ "foreground": "Premier plan",
+ "general": "Général",
+ "hide_attachments_in_convo": "Masquer les pièces jointes dans les conversations",
+ "hide_attachments_in_tl": "Masquer les pièces jointes dans le journal",
+ "hide_muted_posts": "Masquer les statuts des utilisateurs masqués",
+ "max_thumbnails": "Nombre maximum de miniatures par statuts",
+ "hide_isp": "Masquer le panneau spécifique a l'instance",
+ "preload_images": "Précharger les images",
+ "use_one_click_nsfw": "Ouvrir les pièces-jointes NSFW avec un seul clic",
+ "hide_post_stats": "Masquer les statistiques de publication (le nombre de favoris)",
+ "hide_user_stats": "Masquer les statistiques de profil (le nombre d'amis)",
+ "hide_filtered_statuses": "Masquer les statuts filtrés",
+ "import_blocks_from_a_csv_file": "Importer les blocages depuis un fichier csv",
+ "import_followers_from_a_csv_file": "Importer des abonnements depuis un fichier csv",
+ "import_theme": "Charger le thème",
+ "inputRadius": "Champs de texte",
+ "checkboxRadius": "Cases à cocher",
+ "instance_default": "(default : {value})",
+ "instance_default_simple": "(default)",
+ "interface": "Interface",
+ "interfaceLanguage": "Langue de l'interface",
+ "invalid_theme_imported": "Le fichier sélectionné n'est pas un thème Pleroma pris en charge. Aucun changement n'a été apporté à votre thème.",
+ "limited_availability": "Non disponible dans votre navigateur",
+ "links": "Liens",
+ "lock_account_description": "Limitez votre compte aux abonnés acceptés uniquement",
+ "loop_video": "Vidéos en boucle",
+ "loop_video_silent_only": "Boucle uniquement les vidéos sans le son (les « gifs » de Mastodon)",
+ "mutes_tab": "Comptes silenciés",
+ "play_videos_in_modal": "Jouer les vidéos directement dans le visionneur de médias",
+ "use_contain_fit": "Ne pas rogner les miniatures des pièces-jointes",
+ "name": "Nom",
+ "name_bio": "Nom & Bio",
+ "new_password": "Nouveau mot de passe",
+ "notification_visibility": "Types de notifications à afficher",
+ "notification_visibility_follows": "Abonnements",
+ "notification_visibility_likes": "J'aime",
+ "notification_visibility_mentions": "Mentionnés",
+ "notification_visibility_repeats": "Partages",
+ "no_rich_text_description": "Ne formatez pas le texte",
+ "no_blocks": "Aucun bloqués",
+ "no_mutes": "Aucun masqués",
+ "hide_follows_description": "Ne pas afficher à qui je suis abonné",
+ "hide_followers_description": "Ne pas afficher qui est abonné à moi",
+ "show_admin_badge": "Afficher le badge d'Administrateur⋅ice sur mon profil",
+ "show_moderator_badge": "Afficher le badge de Modérateur⋅ice sur mon profil",
+ "nsfw_clickthrough": "Masquer les images marquées comme contenu adulte ou sensible",
+ "oauth_tokens": "Jetons OAuth",
+ "token": "Jeton",
+ "refresh_token": "Rafraichir le jeton",
+ "valid_until": "Valable jusque",
+ "revoke_token": "Révoquer",
+ "panelRadius": "Fenêtres",
+ "pause_on_unfocused": "Suspendre le streaming lorsque l'onglet n'est pas actif",
+ "presets": "Thèmes prédéfinis",
+ "profile_background": "Image de fond",
+ "profile_banner": "Bannière de profil",
+ "profile_tab": "Profil",
+ "radii_help": "Vous pouvez ici choisir le niveau d'arrondi des angles de l'interface (en pixels)",
+ "replies_in_timeline": "Réponses au journal",
+ "reply_link_preview": "Afficher un aperçu lors du survol de liens vers une réponse",
+ "reply_visibility_all": "Montrer toutes les réponses",
+ "reply_visibility_following": "Afficher uniquement les réponses adressées à moi ou aux personnes que je suis",
+ "reply_visibility_self": "Afficher uniquement les réponses adressées à moi",
+ "autohide_floating_post_button": "Automatiquement cacher le bouton de Nouveau Statut (sur mobile)",
+ "saving_err": "Erreur lors de l'enregistrement des paramètres",
+ "saving_ok": "Paramètres enregistrés",
+ "search_user_to_block": "Rechercher qui vous voulez bloquer",
+ "search_user_to_mute": "Rechercher qui vous voulez masquer",
+ "security_tab": "Sécurité",
+ "scope_copy": "Garder la même visibilité en répondant (les DMs restent toujours des DMs)",
+ "minimal_scopes_mode": "Rétrécir les options de séléction de la portée",
+ "set_new_avatar": "Changer d'avatar",
+ "set_new_profile_background": "Changer d'image de fond",
+ "set_new_profile_banner": "Changer de bannière",
+ "settings": "Paramètres",
+ "subject_input_always_show": "Toujours copier le champ de sujet",
+ "subject_line_behavior": "Copier le sujet en répondant",
+ "subject_line_email": "Similaire au courriel : « re : sujet »",
+ "subject_line_mastodon": "Comme mastodon : copier tel quel",
+ "subject_line_noop": "Ne pas copier",
+ "post_status_content_type": "Type de contenu du statuts",
+ "stop_gifs": "N'animer les GIFS que lors du survol du curseur de la souris",
+ "streaming": "Charger automatiquement les nouveaux statuts lorsque vous êtes au haut de la page",
+ "text": "Texte",
+ "theme": "Thème",
+ "theme_help": "Spécifiez des codes couleur hexadécimaux (#rrvvbb) pour personnaliser les couleurs du thème.",
+ "theme_help_v2_1": "Vous pouvez aussi surcharger certaines couleurs de composants et transparence via la case à cocher, utilisez le bouton « Vider tout » pour effacer toutes les surcharges.",
+ "theme_help_v2_2": "Les icônes sous certaines des entrées ont un indicateur de contraste du fond/texte, survolez les pour plus d'informations détailles. Veuillez garder a l'esprit que lors de l'utilisation de transparence l'indicateur de contraste indique le pire des cas.",
+ "tooltipRadius": "Info-bulles/alertes",
+ "upload_a_photo": "Envoyer une photo",
+ "user_settings": "Paramètres utilisateur",
+ "values": {
+ "false": "non",
+ "true": "oui"
+ },
+ "notifications": "Notifications",
+ "notification_setting": "Reçevoir les notifications de :",
+ "notification_setting_follows": "Utilisateurs que vous suivez",
+ "notification_setting_non_follows": "Utilisateurs que vous ne suivez pas",
+ "notification_setting_followers": "Utilisateurs qui vous suivent",
+ "notification_setting_non_followers": "Utilisateurs qui ne vous suivent pas",
+ "notification_mutes": "Pour stopper la récéption de notifications d'un utilisateur particulier, utilisez un masquage.",
+ "notification_blocks": "Bloquer un utilisateur stoppe toute notification et se désabonne de lui.",
+ "enable_web_push_notifications": "Activer les notifications de push web",
+ "style": {
+ "switcher": {
+ "keep_color": "Garder les couleurs",
+ "keep_shadows": "Garder les ombres",
+ "keep_opacity": "Garder la transparence",
+ "keep_roundness": "Garder la rondeur",
+ "keep_fonts": "Garder les polices",
+ "save_load_hint": "L'option « Garder » préserve les options activés en cours lors de la séléction ou chargement des thèmes, il sauve aussi les dites options lors de l'export d'un thème. Quand toutes les cases sont décochés, exporter un thème sauvera tout.",
+ "reset": "Remise à zéro",
+ "clear_all": "Tout vider",
+ "clear_opacity": "Vider la transparence",
+ "load_theme": "Charger le thème",
+ "use_snapshot": "Ancienne version",
+ "help": {
+ "upgraded_from_v2": "PleromaFE à été mis à jour, le thème peut être un peu différent que dans vos souvenirs.",
+ "v2_imported": "Le fichier que vous avez importé vient d'un version antérieure. Nous essayons de maximizer la compatibilité mais il peu y avoir quelques incohérences.",
+ "future_version_imported": "Le fichier importé viens d'une version postérieure de PleromaFE.",
+ "older_version_imported": "Le fichier importé viens d'une version antérieure de PleromaFE.",
+ "snapshot_source_mismatch": "Conflict de version : Probablement due à un retour arrière puis remise à jour de la version de PleromaFE, si vous avez charger le thème en utilisant une version antérieure vous voulez probablement utiliser la version antérieure, autrement utiliser la version postérieure.",
+ "migration_napshot_gone": "Pour une raison inconnue l'instantané est manquant, des parties peuvent rendre différentes que dans vos souvenirs.",
+ "migration_snapshot_ok": "Pour être sûr un instantanée du thème à été chargé. Vos pouvez essayer de charger ses données.",
+ "fe_downgraded": "Retour en arrière de la version de PleromaFE.",
+ "fe_upgraded": "Le moteur de thème PleromaFE à été mis à jour après un changement de version.",
+ "snapshot_missing": "Aucun instantané du thème à été trouvé dans le fichier, il peut y avoir un rendu différent à la vision originelle."
+ },
+ "keep_as_is": "Garder tel-quel",
+ "use_source": "Nouvelle version"
+ },
+ "common": {
+ "color": "Couleur",
+ "opacity": "Transparence",
+ "contrast": {
+ "hint": "Le ratio de contraste est {ratio}, il {level} {context}",
+ "level": {
+ "aa": "répond aux directives de niveau AA (minimum)",
+ "aaa": "répond aux directives de niveau AAA (recommandé)",
+ "bad": "ne réponds à aucune directive d'accessibilité"
+ },
+ "context": {
+ "18pt": "pour texte large (19pt+)",
+ "text": "pour texte"
+ }
+ }
+ },
+ "common_colors": {
+ "_tab_label": "Commun",
+ "main": "Couleurs communes",
+ "foreground_hint": "Voir l'onglet « Avancé » pour plus de contrôle détaillé",
+ "rgbo": "Icônes, accents, badges"
+ },
+ "advanced_colors": {
+ "_tab_label": "Avancé",
+ "alert": "Fond d'alerte",
+ "alert_error": "Erreur",
+ "badge": "Fond de badge",
+ "badge_notification": "Notification",
+ "panel_header": "Entête de panneau",
+ "top_bar": "Barre du haut",
+ "borders": "Bordures",
+ "buttons": "Boutons",
+ "inputs": "Champs de saisie",
+ "faint_text": "Texte en fondu",
+ "underlay": "sous-calque",
+ "pressed": "Appuyé",
+ "alert_warning": "Avertissement",
+ "alert_neutral": "Neutre",
+ "post": "Messages/Bios des comptes",
+ "poll": "Graphique de Sondage",
+ "icons": "Icônes",
+ "selectedPost": "Message sélectionné",
+ "selectedMenu": "Objet sélectionné du menu",
+ "disabled": "Désactivé",
+ "tabs": "Onglets",
+ "toggled": "(Dés)activé",
+ "highlight": "Éléments mis en valeur",
+ "popover": "Infobulles, menus"
+ },
+ "radii": {
+ "_tab_label": "Rondeur"
+ },
+ "shadows": {
+ "_tab_label": "Ombres et éclairage",
+ "component": "Composant",
+ "override": "Surcharger",
+ "shadow_id": "Ombre #{value}",
+ "blur": "Flou",
+ "spread": "Dispersion",
+ "inset": "Interne",
+ "hint": "Pour les ombres, vous pouvez aussi utiliser --variable comme valeur de couleur en CSS3. Veuillez noter que spécifier la transparence ne fonctionnera pas dans ce cas.",
+ "filter_hint": {
+ "always_drop_shadow": "Attention, cette ombre utilise toujours {0} quand le navigateur le supporte.",
+ "drop_shadow_syntax": "{0} ne supporte pas le paramètre {1} et mot-clé {2}.",
+ "avatar_inset": "Veuillez noter que combiner a la fois les ombres internes et non-internes sur les avatars peut fournir des résultats innatendus avec la transparence des avatars.",
+ "spread_zero": "Les ombres avec une dispersion > 0 apparaitrons comme si ils étaient à zéro",
+ "inset_classic": "L'ombre interne utilisera toujours {0}"
+ },
+ "components": {
+ "panel": "Panneau",
+ "panelHeader": "En-tête de panneau",
+ "topBar": "Barre du haut",
+ "avatar": "Avatar utilisateur⋅ice (dans la vue de profil)",
+ "avatarStatus": "Avatar utilisateur⋅ice (dans la vue de statuts)",
+ "popup": "Popups et infobulles",
+ "button": "Bouton",
+ "buttonHover": "Bouton (survol)",
+ "buttonPressed": "Bouton (cliqué)",
+ "buttonPressedHover": "Bouton (cliqué+survol)",
+ "input": "Champ de saisie"
+ },
+ "hintV3": "Pour les ombres vous pouvez aussi utiliser la notation {0} pour utiliser un autre emplacement de couleur."
+ },
+ "fonts": {
+ "_tab_label": "Polices",
+ "help": "Sélectionnez la police à utiliser pour les éléments de l'UI. Pour « personnalisé » vous avez à entrer le nom exact de la police comme il apparaît dans le système.",
+ "components": {
+ "interface": "Interface",
+ "input": "Champs de saisie",
+ "post": "Post text",
+ "postCode": "Texte à taille fixe dans un article (texte enrichi)"
+ },
+ "family": "Nom de la police",
+ "size": "Taille (en px)",
+ "weight": "Poid (gras)",
+ "custom": "Personnalisé"
+ },
+ "preview": {
+ "header": "Prévisualisation",
+ "content": "Contenu",
+ "error": "Exemple d'erreur",
+ "button": "Bouton",
+ "text": "Un certain nombre de {0} et {1}",
+ "mono": "contenu",
+ "input": "Je viens juste d’atterrir à L.A.",
+ "faint_link": "manuel utile",
+ "fine_print": "Lisez notre {0} pour n'apprendre rien d'utile !",
+ "header_faint": "Tout va bien",
+ "checkbox": "J'ai survolé les conditions d'utilisation",
+ "link": "un petit lien sympa"
+ }
+ },
+ "version": {
+ "title": "Version",
+ "backend_version": "Version du Backend",
+ "frontend_version": "Version du Frontend"
+ },
+ "change_email": "Changer de courriel",
+ "domain_mutes": "Domaines",
+ "pad_emoji": "Rajouter un espace autour de l'émoji après l’avoir choisit",
+ "notification_visibility_emoji_reactions": "Réactions",
+ "hide_follows_count_description": "Masquer le nombre de suivis",
+ "useStreamingApiWarning": "(Non recommandé, expérimental, connu pour rater des messages)",
+ "type_domains_to_mute": "Écrire les domaines à masquer",
+ "fun": "Rigolo",
+ "greentext": "greentexting",
+ "allow_following_move": "Suivre automatiquement quand ce compte migre",
+ "change_email_error": "Il y a eu un problème pour charger votre courriel.",
+ "changed_email": "Courriel changé avec succès !",
+ "discoverable": "Permettre de découvrir ce compte dans les résultats de recherche web et autres services",
+ "emoji_reactions_on_timeline": "Montrer les émojis-réactions dans le flux",
+ "new_email": "Nouveau courriel",
+ "notification_visibility_moves": "Migrations de compte",
+ "user_mutes": "Comptes",
+ "useStreamingApi": "Recevoir les messages et notifications en temps réel",
+ "notification_setting_filters": "Filtres",
+ "notification_setting_privacy_option": "Masquer l'expéditeur et le contenu des notifications push",
+ "notification_setting_privacy": "Intimité",
+ "hide_followers_count_description": "Masquer le nombre d'abonnés",
+ "accent": "Accent"
+ },
+ "timeline": {
+ "collapse": "Fermer",
+ "conversation": "Conversation",
+ "error_fetching": "Erreur en cherchant les mises à jour",
+ "load_older": "Afficher plus",
+ "no_retweet_hint": "Le message est marqué en abonnés-seulement ou direct et ne peut pas être partagé",
+ "repeated": "a partagé",
+ "show_new": "Afficher plus",
+ "up_to_date": "À jour",
+ "no_more_statuses": "Pas plus de statuts",
+ "no_statuses": "Aucun statuts"
+ },
+ "status": {
+ "favorites": "Favoris",
+ "repeats": "Partages",
+ "delete": "Supprimer statuts",
+ "pin": "Agraffer sur le profil",
+ "unpin": "Dégraffer du profil",
+ "pinned": "Agraffé",
+ "delete_confirm": "Voulez-vous vraiment supprimer ce statuts ?",
+ "reply_to": "Réponse à",
+ "replies_list": "Réponses :",
+ "mute_conversation": "Masquer la conversation",
+ "unmute_conversation": "Démasquer la conversation",
+ "status_unavailable": "Status indisponible",
+ "copy_link": "Copier le lien au status"
+ },
+ "user_card": {
+ "approve": "Accepter",
+ "block": "Bloquer",
+ "blocked": "Bloqué !",
+ "deny": "Rejeter",
+ "favorites": "Favoris",
+ "follow": "Suivre",
+ "follow_sent": "Demande envoyée !",
+ "follow_progress": "Demande en cours…",
+ "follow_again": "Renvoyer la demande ?",
+ "follow_unfollow": "Désabonner",
+ "followees": "Suivis",
+ "followers": "Vous suivent",
+ "following": "Suivi !",
+ "follows_you": "Vous suit !",
+ "its_you": "C'est vous !",
+ "media": "Media",
+ "mute": "Masquer",
+ "muted": "Masqué",
+ "per_day": "par jour",
+ "remote_follow": "Suivre d'une autre instance",
+ "report": "Signalement",
+ "statuses": "Statuts",
+ "unblock": "Débloquer",
+ "unblock_progress": "Déblocage…",
+ "block_progress": "Blocage…",
+ "unmute": "Démasquer",
+ "unmute_progress": "Démasquage…",
+ "mute_progress": "Masquage…",
+ "admin_menu": {
+ "moderation": "Moderation",
+ "grant_admin": "Promouvoir Administrateur⋅ice",
+ "revoke_admin": "Dégrader Administrateur⋅ice",
+ "grant_moderator": "Promouvoir Modérateur⋅ice",
+ "revoke_moderator": "Dégrader Modérateur⋅ice",
+ "activate_account": "Activer le compte",
+ "deactivate_account": "Désactiver le compte",
+ "delete_account": "Supprimer le compte",
+ "force_nsfw": "Marquer tous les statuts comme NSFW",
+ "strip_media": "Supprimer les medias des statuts",
+ "force_unlisted": "Forcer les statuts à être délistés",
+ "sandbox": "Forcer les statuts à être visibles seuleument pour les abonné⋅e⋅s",
+ "disable_remote_subscription": "Interdir de s'abonner a l'utilisateur depuis l'instance distante",
+ "disable_any_subscription": "Interdir de s'abonner à l'utilisateur tout court",
+ "quarantine": "Interdir les statuts de l'utilisateur à fédérer",
+ "delete_user": "Supprimer l'utilisateur",
+ "delete_user_confirmation": "Êtes-vous absolument-sûr⋅e ? Cette action ne peut être annulée."
+ },
+ "mention": "Mention",
+ "hidden": "Caché",
+ "subscribe": "Abonner",
+ "unsubscribe": "Désabonner",
+ "hide_repeats": "Cacher les partages",
+ "show_repeats": "Montrer les partages"
+ },
+ "user_profile": {
+ "timeline_title": "Journal de l'utilisateur⋅ice",
+ "profile_does_not_exist": "Désolé, ce profil n'existe pas.",
+ "profile_loading_error": "Désolé, il y a eu une erreur au chargement du profil."
+ },
+ "user_reporting": {
+ "title": "Signaler {0}",
+ "add_comment_description": "Ce signalement sera envoyé aux modérateur⋅ice⋅s de votre instance. Vous pouvez fournir une explication de pourquoi vous signalez ce compte ci-dessous :",
+ "additional_comments": "Commentaires additionnels",
+ "forward_description": "Le compte vient d'un autre serveur. Envoyer une copie du signalement à celui-ci aussi ?",
+ "forward_to": "Transmettre à {0}",
+ "submit": "Envoyer",
+ "generic_error": "Une erreur est survenue lors du traitement de votre requête."
+ },
+ "who_to_follow": {
+ "more": "Plus",
+ "who_to_follow": "À qui s'abonner"
+ },
+ "tool_tip": {
+ "media_upload": "Envoyer un media",
+ "repeat": "Répéter",
+ "reply": "Répondre",
+ "favorite": "Favoriser",
+ "user_settings": "Paramètres utilisateur",
+ "add_reaction": "Ajouter une réaction",
+ "accept_follow_request": "Accepter la demande de suivit",
+ "reject_follow_request": "Rejeter la demande de suivit"
+ },
+ "upload": {
+ "error": {
+ "base": "L'envoi a échoué.",
+ "file_too_big": "Fichier trop gros [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
+ "default": "Réessayez plus tard"
+ },
+ "file_size_units": {
+ "B": "O",
+ "KiB": "KiO",
+ "MiB": "MiO",
+ "GiB": "GiO",
+ "TiB": "TiO"
+ }
+ },
+ "about": {
+ "mrf": {
+ "keyword": {
+ "reject": "Rejeté",
+ "replace": "Remplacer",
+ "keyword_policies": "Politiques par mot-clés",
+ "ftl_removal": "Suppression du flux \"Ensemble du réseau connu\"",
+ "is_replaced_by": "→"
+ },
+ "simple": {
+ "simple_policies": "Politiques par instances",
+ "accept": "Accepter",
+ "accept_desc": "Cette instance accepte des messages seulement depuis ces instances :",
+ "reject": "Rejeter",
+ "reject_desc": "Cette instance n'acceptera pas de message de ces instances :",
+ "quarantine": "Quarantaine",
+ "quarantine_desc": "Cette instance enverras seulement des messages publics à ces instances :",
+ "ftl_removal_desc": "Cette instance supprime ces instance du flux fédéré :",
+ "media_removal": "Suppression multimédia",
+ "media_removal_desc": "Cette instance supprime le contenu multimédia des instances suivantes :",
+ "media_nsfw": "Force le contenu multimédia comme sensible",
+ "ftl_removal": "Suppression du flux fédéré",
+ "media_nsfw_desc": "Cette instance force le contenu multimédia comme sensible pour les messages des instances suivantes :"
+ },
+ "federation": "Fédération",
+ "mrf_policies": "Politiques MRF activées",
+ "mrf_policies_desc": "Les politiques MRF modifient la fédération entre les instances. Les politiques suivantes sont activées :"
+ },
+ "staff": "Staff"
+ },
+ "domain_mute_card": {
+ "mute": "Muet",
+ "mute_progress": "Masquage…",
+ "unmute": "Démasquer",
+ "unmute_progress": "Démasquage…"
+ },
+ "polls": {
+ "add_poll": "Ajouter un Sondage",
+ "add_option": "Ajouter une option",
+ "option": "Option",
+ "votes": "votes",
+ "type": "Type de Sondage",
+ "single_choice": "Choix unique",
+ "multiple_choices": "Choix multiples",
+ "expiry": "Age du sondage",
+ "expires_in": "Fin du sondage dans {0}",
+ "not_enough_options": "Trop peu d'options unique au sondage",
+ "vote": "Voter",
+ "expired": "Sondage terminé il y a {0}"
+ },
+ "emoji": {
+ "emoji": "Émoji",
+ "search_emoji": "Rechercher un émoji",
+ "add_emoji": "Insérer un émoji",
+ "custom": "émoji personnalisé",
+ "unicode": "émoji unicode",
+ "load_all": "Charger tout les {emojiAmount} émojis",
+ "load_all_hint": "{saneAmount} émojis chargé, charger tout les émojis peuvent causer des problèmes de performances.",
+ "stickers": "Stickers",
+ "keep_open": "Garder le sélecteur ouvert"
+ },
+ "remote_user_resolver": {
+ "error": "Non trouvé.",
+ "searching_for": "Rechercher",
+ "remote_user_resolver": "Résolution de compte distant"
+ },
+ "time": {
+ "minutes_short": "{0}min",
+ "second_short": "{0}s",
+ "day": "{0} jour",
+ "days": "{0} jours",
+ "months": "{0} mois",
+ "month_short": "{0}m",
+ "months_short": "{0}m",
+ "now": "tout de suite",
+ "now_short": "maintenant",
+ "second": "{0} seconde",
+ "seconds": "{0} secondes",
+ "seconds_short": "{0}s",
+ "day_short": "{0}j",
+ "days_short": "{0}j",
+ "hour": "{0} heure",
+ "hours": "{0} heures",
+ "hour_short": "{0}h",
+ "hours_short": "{0}h",
+ "in_future": "dans {0}",
+ "in_past": "il y a {0}",
+ "minute": "{0} minute",
+ "minutes": "{0} minutes",
+ "minute_short": "{0}min",
+ "month": "{0} mois",
+ "week": "{0} semaine",
+ "weeks": "{0} semaines",
+ "week_short": "{0}s",
+ "weeks_short": "{0}s",
+ "year": "{0} année",
+ "years": "{0} années",
+ "year_short": "{0}a",
+ "years_short": "{0}a"
+ },
+ "search": {
+ "people": "Comptes",
+ "person_talking": "{count} personnes discutant",
+ "hashtags": "Mot-dièses",
+ "people_talking": "{count} personnes discutant",
+ "no_results": "Aucun résultats"
+ },
+ "password_reset": {
+ "forgot_password": "Mot de passe oublié ?",
+ "check_email": "Vérifiez vos courriels pour le lien permettant de changer votre mot de passe.",
+ "password_reset_disabled": "Le changement de mot de passe est désactivé. Veuillez contacter l'administration de votre instance.",
+ "password_reset_required_but_mailer_is_disabled": "Vous devez changer votre mot de passe mais sont changement est désactivé. Veuillez contacter l’administration de votre instance.",
+ "password_reset": "Nouveau mot de passe",
+ "instruction": "Entrer votre address de courriel ou votre nom utilisateur. Nous enverrons un lien pour changer votre mot de passe.",
+ "placeholder": "Votre email ou nom d'utilisateur",
+ "return_home": "Retourner à la page d'accueil",
+ "not_found": "Email ou nom d'utilisateur inconnu.",
+ "too_many_requests": "Vos avez atteint la limite d'essais, essayez plus tard.",
+ "password_reset_required": "Vous devez changer votre mot de passe pour vous authentifier."
+ }
}
diff --git a/src/i18n/it.json b/src/i18n/it.json
index f441292e..6c8be351 100644
--- a/src/i18n/it.json
+++ b/src/i18n/it.json
@@ -1,140 +1,357 @@
{
"general": {
"submit": "Invia",
- "apply": "Applica"
+ "apply": "Applica",
+ "more": "Altro",
+ "generic_error": "Errore",
+ "optional": "facoltativo",
+ "show_more": "Mostra tutto",
+ "show_less": "Ripiega",
+ "dismiss": "Chiudi",
+ "cancel": "Annulla",
+ "disable": "Disabilita",
+ "enable": "Abilita",
+ "confirm": "Conferma",
+ "verify": "Verifica",
+ "peek": "Anteprima",
+ "close": "Chiudi",
+ "retry": "Riprova",
+ "error_retry": "Per favore, riprova",
+ "loading": "Carico…"
},
"nav": {
"mentions": "Menzioni",
- "public_tl": "Sequenza temporale pubblica",
- "timeline": "Sequenza temporale",
- "twkn": "L'intera rete conosciuta",
- "chat": "Chat Locale",
- "friend_requests": "Richieste di Seguirti"
+ "public_tl": "Sequenza pubblica",
+ "timeline": "Sequenza personale",
+ "twkn": "Sequenza globale",
+ "chat": "Chat della stanza",
+ "friend_requests": "Vogliono seguirti",
+ "about": "Informazioni",
+ "administration": "Amministrazione",
+ "back": "Indietro",
+ "interactions": "Interazioni",
+ "dms": "Messaggi diretti",
+ "user_search": "Ricerca utenti",
+ "search": "Ricerca",
+ "who_to_follow": "Chi seguire",
+ "preferences": "Preferenze"
},
"notifications": {
"followed_you": "ti segue",
"notifications": "Notifiche",
- "read": "Leggi!",
- "broken_favorite": "Stato sconosciuto, lo sto cercando...",
- "favorited_you": "ha messo mi piace al tuo stato",
- "load_older": "Carica notifiche più vecchie",
- "repeated_you": "ha condiviso il tuo stato"
+ "read": "Letto!",
+ "broken_favorite": "Stato sconosciuto, lo sto cercando…",
+ "favorited_you": "ha gradito il tuo messaggio",
+ "load_older": "Carica notifiche precedenti",
+ "repeated_you": "ha condiviso il tuo messaggio",
+ "follow_request": "vuole seguirti",
+ "no_more_notifications": "Fine delle notifiche",
+ "migrated_to": "è migrato verso",
+ "reacted_with": "ha reagito con {0}"
},
"settings": {
"attachments": "Allegati",
- "autoload": "Abilita caricamento automatico quando si raggiunge fondo pagina",
- "avatar": "Avatar",
+ "autoload": "Abilita caricamento automatico quando raggiungi il fondo pagina",
+ "avatar": "Icona utente",
"bio": "Introduzione",
- "current_avatar": "Il tuo avatar attuale",
- "current_profile_banner": "Il tuo banner attuale",
+ "current_avatar": "La tua icona attuale",
+ "current_profile_banner": "Il tuo stendardo attuale",
"filtering": "Filtri",
- "filtering_explanation": "Tutti i post contenenti queste parole saranno silenziati, uno per linea",
+ "filtering_explanation": "Tutti i post contenenti queste parole saranno silenziati, una per riga",
"hide_attachments_in_convo": "Nascondi gli allegati presenti nelle conversazioni",
- "hide_attachments_in_tl": "Nascondi gli allegati presenti nella sequenza temporale",
+ "hide_attachments_in_tl": "Nascondi gli allegati presenti nelle sequenze",
"name": "Nome",
- "name_bio": "Nome & Introduzione",
- "nsfw_clickthrough": "Abilita il click per visualizzare gli allegati segnati come NSFW",
+ "name_bio": "Nome ed introduzione",
+ "nsfw_clickthrough": "Fai click per visualizzare gli allegati offuscati",
"profile_background": "Sfondo della tua pagina",
- "profile_banner": "Banner del tuo profilo",
- "reply_link_preview": "Abilita il link per la risposta al passaggio del mouse",
- "set_new_avatar": "Scegli un nuovo avatar",
+ "profile_banner": "Stendardo del tuo profilo",
+ "reply_link_preview": "Visualizza le risposte al passaggio del cursore",
+ "set_new_avatar": "Scegli una nuova icona",
"set_new_profile_background": "Scegli un nuovo sfondo per la tua pagina",
- "set_new_profile_banner": "Scegli un nuovo banner per il tuo profilo",
+ "set_new_profile_banner": "Scegli un nuovo stendardo per il tuo profilo",
"settings": "Impostazioni",
"theme": "Tema",
"user_settings": "Impostazioni Utente",
"attachmentRadius": "Allegati",
- "avatarAltRadius": "Avatar (Notifiche)",
- "avatarRadius": "Avatar",
+ "avatarAltRadius": "Icone utente (Notifiche)",
+ "avatarRadius": "Icone utente",
"background": "Sfondo",
"btnRadius": "Pulsanti",
- "cBlue": "Blu (Rispondere, seguire)",
- "cGreen": "Verde (Condividi)",
- "cOrange": "Arancio (Mi piace)",
- "cRed": "Rosso (Annulla)",
- "change_password": "Cambia Password",
+ "cBlue": "Blu (risposte, seguire)",
+ "cGreen": "Verde (ripeti)",
+ "cOrange": "Arancione (gradire)",
+ "cRed": "Rosso (annulla)",
+ "change_password": "Cambia password",
"change_password_error": "C'è stato un problema durante il cambiamento della password.",
"changed_password": "Password cambiata correttamente!",
- "collapse_subject": "Riduci post che hanno un oggetto",
+ "collapse_subject": "Ripiega messaggi con Oggetto",
"confirm_new_password": "Conferma la nuova password",
- "current_password": "Password attuale",
- "data_import_export_tab": "Importa / Esporta Dati",
- "default_vis": "Visibilità predefinita dei post",
- "delete_account": "Elimina Account",
- "delete_account_description": "Elimina definitivamente il tuo account e tutti i tuoi messaggi.",
- "delete_account_error": "C'è stato un problema durante l'eliminazione del tuo account. Se il problema persiste contatta l'amministratore della tua istanza.",
- "delete_account_instructions": "Digita la tua password nel campo sottostante per confermare l'eliminazione dell'account.",
- "export_theme": "Salva settaggi",
+ "current_password": "La tua password attuale",
+ "data_import_export_tab": "Importa o esporta dati",
+ "default_vis": "Visibilità predefinita dei messaggi",
+ "delete_account": "Elimina profilo",
+ "delete_account_description": "Elimina definitivamente i tuoi dati e disattiva il tuo profilo.",
+ "delete_account_error": "C'è stato un problema durante l'eliminazione del tuo profilo. Se il problema persiste contatta l'amministratore della tua stanza.",
+ "delete_account_instructions": "Digita la tua password nel campo sottostante per confermare l'eliminazione del tuo profilo.",
+ "export_theme": "Salva impostazioni",
"follow_export": "Esporta la lista di chi segui",
- "follow_export_button": "Esporta la lista di chi segui in un file csv",
+ "follow_export_button": "Esporta la lista di chi segui in un file CSV",
"follow_export_processing": "Sto elaborando, presto ti sarà chiesto di scaricare il tuo file",
"follow_import": "Importa la lista di chi segui",
"follow_import_error": "Errore nell'importazione della lista di chi segui",
"follows_imported": "Importazione riuscita! L'elaborazione richiederà un po' di tempo.",
- "foreground": "In primo piano",
+ "foreground": "Primo piano",
"general": "Generale",
- "hide_post_stats": "Nascondi statistiche dei post (es. il numero di mi piace)",
- "hide_user_stats": "Nascondi statistiche dell'utente (es. il numero di chi ti segue)",
- "import_followers_from_a_csv_file": "Importa una lista di chi segui da un file csv",
- "import_theme": "Carica settaggi",
+ "hide_post_stats": "Nascondi statistiche dei messaggi (es. il numero di preferenze)",
+ "hide_user_stats": "Nascondi statistiche dell'utente (es. il numero dei tuoi seguaci)",
+ "import_followers_from_a_csv_file": "Importa una lista di chi segui da un file CSV",
+ "import_theme": "Carica impostazioni",
"inputRadius": "Campi di testo",
"instance_default": "(predefinito: {value})",
- "interfaceLanguage": "Linguaggio dell'interfaccia",
- "invalid_theme_imported": "Il file selezionato non è un file di tema per Pleroma supportato. Il tuo tema non è stato modificato.",
+ "interfaceLanguage": "Lingua dell'interfaccia",
+ "invalid_theme_imported": "Il file selezionato non è un tema supportato da Pleroma. Il tuo tema non è stato modificato.",
"limited_availability": "Non disponibile nel tuo browser",
"links": "Collegamenti",
- "lock_account_description": "Limita il tuo account solo per contatti approvati",
+ "lock_account_description": "Limita il tuo account solo a seguaci approvati",
"loop_video": "Riproduci video in ciclo continuo",
- "loop_video_silent_only": "Riproduci solo video senza audio in ciclo continuo (es. le gif di Mastodon)",
+ "loop_video_silent_only": "Riproduci solo video senza audio in ciclo continuo (es. le \"gif\" di Mastodon)",
"new_password": "Nuova password",
"notification_visibility": "Tipi di notifiche da mostrare",
"notification_visibility_follows": "Nuove persone ti seguono",
- "notification_visibility_likes": "Mi piace",
+ "notification_visibility_likes": "Preferiti",
"notification_visibility_mentions": "Menzioni",
"notification_visibility_repeats": "Condivisioni",
- "no_rich_text_description": "Togli la formattazione del testo da tutti i post",
+ "no_rich_text_description": "Togli la formattazione del testo da tutti i messaggi",
"oauth_tokens": "Token OAuth",
"token": "Token",
"refresh_token": "Aggiorna token",
"valid_until": "Valido fino a",
- "revoke_token": "Revocare",
+ "revoke_token": "Revoca",
"panelRadius": "Pannelli",
- "pause_on_unfocused": "Metti in pausa l'aggiornamento continuo quando la scheda non è in primo piano",
+ "pause_on_unfocused": "Interrompi l'aggiornamento continuo mentre la scheda è in secondo piano",
"presets": "Valori predefiniti",
"profile_tab": "Profilo",
- "radii_help": "Imposta l'arrotondamento dei bordi (in pixel)",
- "replies_in_timeline": "Risposte nella sequenza temporale",
+ "radii_help": "Imposta il raggio degli angoli (in pixel)",
+ "replies_in_timeline": "Risposte nella sequenza personale",
"reply_visibility_all": "Mostra tutte le risposte",
- "reply_visibility_following": "Mostra solo le risposte dirette a me o agli utenti che seguo",
- "reply_visibility_self": "Mostra solo risposte dirette a me",
+ "reply_visibility_following": "Mostra solo le risposte rivolte a me o agli utenti che seguo",
+ "reply_visibility_self": "Mostra solo risposte rivolte a me",
"saving_err": "Errore nel salvataggio delle impostazioni",
"saving_ok": "Impostazioni salvate",
"security_tab": "Sicurezza",
- "stop_gifs": "Riproduci GIF al passaggio del cursore del mouse",
- "streaming": "Abilita aggiornamento automatico dei nuovi post quando si è in alto alla pagina",
+ "stop_gifs": "Riproduci GIF al passaggio del cursore",
+ "streaming": "Mostra automaticamente i nuovi messaggi quando sei in cima alla pagina",
"text": "Testo",
"theme_help": "Usa codici colore esadecimali (#rrggbb) per personalizzare il tuo schema di colori.",
- "tooltipRadius": "Descrizioni/avvisi",
+ "tooltipRadius": "Suggerimenti/avvisi",
"values": {
"false": "no",
- "true": "si"
- }
+ "true": "sì"
+ },
+ "avatar_size_instruction": "La taglia minima per l'icona personale è 150x150 pixel.",
+ "domain_mutes": "Domini",
+ "discoverable": "Permetti la scoperta di questo profilo da servizi di ricerca ed altro",
+ "composing": "Composizione",
+ "changed_email": "Email cambiata con successo!",
+ "change_email_error": "C'è stato un problema nel cambiare la tua email.",
+ "change_email": "Cambia email",
+ "blocks_tab": "Bloccati",
+ "blocks_imported": "Blocchi importati! Saranno elaborati a breve.",
+ "block_import_error": "Errore nell'importazione",
+ "block_import": "Importa blocchi",
+ "block_export_button": "Esporta i tuoi blocchi in un file CSV",
+ "block_export": "Esporta blocchi",
+ "allow_following_move": "Consenti",
+ "mfa": {
+ "verify": {
+ "desc": "Per abilitare l'autenticazione bifattoriale, inserisci il codice fornito dalla tua applicazione:"
+ },
+ "scan": {
+ "secret_code": "Codice",
+ "desc": "Con la tua applicazione bifattoriale, acquisisci questo QR o inserisci il codice manualmente:",
+ "title": "Acquisisci"
+ },
+ "authentication_methods": "Metodi di accesso",
+ "recovery_codes_warning": "Appuntati i codici o salvali in un posto sicuro, altrimenti rischi di non rivederli mai più. Se perderai l'accesso sia alla tua applicazione bifattoriale che ai codici di recupero non potrai più accedere al tuo profilo.",
+ "waiting_a_recovery_codes": "Ricevo codici di recupero…",
+ "recovery_codes": "Codici di recupero.",
+ "warning_of_generate_new_codes": "Alla generazione di nuovi codici di recupero, quelli vecchi saranno disattivati.",
+ "generate_new_recovery_codes": "Genera nuovi codici di recupero",
+ "title": "Accesso bifattoriale",
+ "confirm_and_enable": "Conferma ed abilita OTP",
+ "wait_pre_setup_otp": "preimposto OTP",
+ "setup_otp": "Imposta OTP",
+ "otp": "OTP"
+ },
+ "enter_current_password_to_confirm": "Inserisci la tua password per identificarti",
+ "security": "Sicurezza",
+ "app_name": "Nome applicazione",
+ "style": {
+ "switcher": {
+ "help": {
+ "older_version_imported": "Il tema importato è stato creato per una versione precedente dell'interfaccia.",
+ "future_version_imported": "Il tema importato è stato creato per una versione più recente dell'interfaccia.",
+ "v2_imported": "Il tema importato è stato creato per una vecchia interfaccia. Non tutto potrebbe essere come prima.",
+ "upgraded_from_v2": "L'interfaccia è stata aggiornata, il tema potrebbe essere diverso da come lo intendevi.",
+ "migration_snapshot_ok": "Ho caricato l'anteprima del tema. Puoi provare a caricarne i contenuti.",
+ "fe_downgraded": "L'interfaccia è stata portata ad una versione precedente.",
+ "fe_upgraded": "Lo schema dei temi è stato aggiornato insieme all'interfaccia.",
+ "snapshot_missing": "Il tema non è provvisto di anteprima, quindi potrebbe essere diverso da come appare.",
+ "snapshot_present": "Tutti i valori sono sostituiti dall'anteprima del tema. Puoi invece caricare i suoi contenuti.",
+ "snapshot_source_mismatch": "Conflitto di versione: probabilmente l'interfaccia è stata portata ad una versione precedente e poi aggiornata di nuovo. Se hai modificato il tema con una versione precedente dell'interfaccia, usa la vecchia versione del tema, altrimenti puoi usare la nuova.",
+ "migration_napshot_gone": "Anteprima del tema non trovata, non tutto potrebbe essere come ricordi."
+ },
+ "use_source": "Nuova versione",
+ "use_snapshot": "Versione precedente",
+ "keep_as_is": "Mantieni tal quale",
+ "load_theme": "Carica tema",
+ "clear_opacity": "Rimuovi opacità",
+ "clear_all": "Azzera tutto",
+ "reset": "Reimposta",
+ "save_load_hint": "Le opzioni \"mantieni\" conservano le impostazioni correnti quando selezioni o carichi un tema, e le salvano quando ne esporti uno. Quando nessuna casella è selezionata, tutte le impostazioni correnti saranno salvate nel tema.",
+ "keep_fonts": "Mantieni font",
+ "keep_roundness": "Mantieni vertici",
+ "keep_opacity": "Mantieni opacità",
+ "keep_shadows": "Mantieni ombre",
+ "keep_color": "Mantieni colori"
+ },
+ "common": {
+ "opacity": "Opacità",
+ "color": "Colore",
+ "contrast": {
+ "context": {
+ "text": "per il testo",
+ "18pt": "per il testo grande (oltre 17pt)"
+ },
+ "level": {
+ "bad": "non soddisfa le linee guida di alcun livello",
+ "aaa": "soddisfa le linee guida di livello AAA (ottimo)",
+ "aa": "soddisfa le linee guida di livello AA (sufficiente)"
+ },
+ "hint": "Il rapporto di contrasto è {ratio}, e {level} {context}"
+ }
+ },
+ "advanced_colors": {
+ "badge": "Sfondo medaglie",
+ "post": "Messaggi / Biografie",
+ "alert_neutral": "Neutro",
+ "alert_warning": "Attenzione",
+ "alert_error": "Errore",
+ "alert": "Sfondo degli avvertimenti",
+ "_tab_label": "Avanzate",
+ "tabs": "Etichette",
+ "disabled": "Disabilitato",
+ "selectedMenu": "Voce menù selezionata",
+ "selectedPost": "Messaggio selezionato",
+ "pressed": "Premuto",
+ "highlight": "Elementi evidenziati",
+ "icons": "Icone",
+ "poll": "Grafico sondaggi",
+ "underlay": "Sottostante",
+ "faint_text": "Testo sbiadito",
+ "inputs": "Campi d'immissione",
+ "buttons": "Pulsanti",
+ "borders": "Bordi",
+ "top_bar": "Barra superiore",
+ "panel_header": "Titolo pannello",
+ "badge_notification": "Notifica",
+ "popover": "Suggerimenti, menù, sbalzi"
+ },
+ "common_colors": {
+ "rgbo": "Icone, accenti, medaglie",
+ "foreground_hint": "Seleziona l'etichetta \"Avanzate\" per controlli più fini",
+ "main": "Colori comuni",
+ "_tab_label": "Comuni"
+ },
+ "shadows": {
+ "inset": "Includi",
+ "spread": "Spandi",
+ "blur": "Sfoca",
+ "shadow_id": "Ombra numero {value}",
+ "override": "Sostituisci",
+ "component": "Componente",
+ "_tab_label": "Luci ed ombre"
+ },
+ "radii": {
+ "_tab_label": "Raggio"
+ }
+ },
+ "enable_web_push_notifications": "Abilita notifiche web push",
+ "fun": "Divertimento",
+ "notification_mutes": "Per non ricevere notifiche da uno specifico utente, zittiscilo.",
+ "notification_setting_privacy_option": "Nascondi mittente e contenuti delle notifiche push",
+ "notification_setting_privacy": "Privacy",
+ "notification_setting_followers": "Utenti che ti seguono",
+ "notification_setting_non_followers": "Utenti che non ti seguono",
+ "notification_setting_non_follows": "Utenti che non segui",
+ "notification_setting_follows": "Utenti che segui",
+ "notification_setting": "Ricevi notifiche da:",
+ "notification_setting_filters": "Filtri",
+ "notifications": "Notifiche",
+ "greentext": "Frecce da meme",
+ "upload_a_photo": "Carica un'immagine",
+ "type_domains_to_mute": "Cerca domini da zittire",
+ "theme_help_v2_2": "Le icone dietro alcuni elementi sono indicatori del contrasto fra testo e sfondo, passaci sopra col puntatore per ulteriori informazioni. Se si usano delle trasparenze, questi indicatori mostrano il peggior caso possibile.",
+ "theme_help_v2_1": "Puoi anche forzare colore ed opacità di alcuni elementi selezionando la casella. Usa il pulsante \"Azzera\" per azzerare tutte le forzature.",
+ "useStreamingApiWarning": "(Sconsigliato, sperimentale, può saltare messaggi)",
+ "useStreamingApi": "Ricevi messaggi e notifiche in tempo reale",
+ "user_mutes": "Utenti",
+ "post_status_content_type": "Tipo di contenuto dei messaggi",
+ "subject_line_noop": "Non copiare",
+ "subject_line_mastodon": "Come in Mastodon: copia tal quale",
+ "subject_line_email": "Come nelle email: \"re: oggetto\"",
+ "subject_line_behavior": "Copia oggetto quando rispondi",
+ "subject_input_always_show": "Mostra sempre il campo Oggetto",
+ "minimal_scopes_mode": "Riduci opzioni di visibilità",
+ "scope_copy": "Risposte ereditano la visibilità (messaggi privati lo fanno sempre)",
+ "search_user_to_mute": "Cerca utente da zittire",
+ "search_user_to_block": "Cerca utente da bloccare",
+ "autohide_floating_post_button": "Nascondi automaticamente il pulsante di composizione (mobile)",
+ "show_moderator_badge": "Mostra l'insegna di moderatore sulla mia pagina",
+ "show_admin_badge": "Mostra l'insegna di amministratore sulla mia pagina",
+ "hide_followers_count_description": "Non mostrare quanti seguaci ho",
+ "hide_follows_count_description": "Non mostrare quanti utenti seguo",
+ "hide_followers_description": "Non mostrare i miei seguaci",
+ "hide_follows_description": "Non mostrare chi seguo",
+ "no_mutes": "Nessun utente zittito",
+ "no_blocks": "Nessun utente bloccato",
+ "notification_visibility_emoji_reactions": "Reazioni",
+ "notification_visibility_moves": "Migrazioni utenti",
+ "new_email": "Nuova email",
+ "use_contain_fit": "Non ritagliare le anteprime degli allegati",
+ "play_videos_in_modal": "Riproduci video in un riquadro a sbalzo",
+ "mutes_tab": "Zittiti",
+ "interface": "Interfaccia",
+ "instance_default_simple": "(predefinito)",
+ "checkboxRadius": "Caselle di selezione",
+ "import_blocks_from_a_csv_file": "Importa blocchi da un file CSV",
+ "hide_filtered_statuses": "Nascondi messaggi filtrati",
+ "use_one_click_nsfw": "Apri media offuscati con un solo click",
+ "preload_images": "Precarica immagini",
+ "hide_isp": "Nascondi pannello della stanza",
+ "max_thumbnails": "Numero massimo di anteprime per messaggio",
+ "hide_muted_posts": "Nascondi messaggi degli utenti zittiti",
+ "accent": "Accento",
+ "emoji_reactions_on_timeline": "Mostra emoji di reazione sulle sequenze",
+ "pad_emoji": "Affianca spazi agli emoji inseriti tramite selettore",
+ "notification_blocks": "Bloccando un utente non riceverai più le sue notifiche né lo seguirai più.",
+ "mutes_and_blocks": "Zittiti e bloccati"
},
"timeline": {
- "error_fetching": "Errore nel prelievo aggiornamenti",
+ "error_fetching": "Errore nell'aggiornamento",
"load_older": "Carica messaggi più vecchi",
"show_new": "Mostra nuovi",
"up_to_date": "Aggiornato",
"collapse": "Riduci",
"conversation": "Conversazione",
- "no_retweet_hint": "La visibilità del post è impostata solo per chi ti segue o messaggio diretto e non può essere condiviso",
+ "no_retweet_hint": "Il messaggio è diretto o solo per seguaci e non può essere condiviso",
"repeated": "condiviso"
},
"user_card": {
"follow": "Segui",
"followees": "Chi stai seguendo",
- "followers": "Chi ti segue",
- "following": "Lo stai seguendo!",
+ "followers": "Seguaci",
+ "following": "Seguìto!",
"follows_you": "Ti segue!",
"mute": "Silenzia",
"muted": "Silenziato",
@@ -152,9 +369,9 @@
"features_panel": {
"chat": "Chat",
"gopher": "Gopher",
- "media_proxy": "Media proxy",
- "scope_options": "Opzioni di visibilità",
- "text_limit": "Lunghezza limite",
+ "media_proxy": "Proxy multimedia",
+ "scope_options": "Opzioni visibilità",
+ "text_limit": "Lunghezza massima",
"title": "Caratteristiche",
"who_to_follow": "Chi seguire"
},
@@ -166,27 +383,48 @@
"login": "Accedi",
"logout": "Disconnettiti",
"password": "Password",
- "placeholder": "es. lain",
+ "placeholder": "es. Lupo Lucio",
"register": "Registrati",
- "username": "Nome utente"
+ "username": "Nome utente",
+ "description": "Accedi con OAuth",
+ "hint": "Accedi per partecipare alla discussione",
+ "authentication_code": "Codice di autenticazione",
+ "enter_recovery_code": "Inserisci un codice di recupero",
+ "enter_two_factor_code": "Inserisci un codice two-factor",
+ "recovery_code": "Codice di recupero",
+ "heading": {
+ "totp": "Autenticazione two-factor",
+ "recovery": "Recupero two-factor"
+ }
},
"post_status": {
- "account_not_locked_warning": "Il tuo account non è {0}. Chiunque può seguirti e vedere i tuoi post riservati a chi ti segue.",
- "account_not_locked_warning_link": "bloccato",
- "attachments_sensitive": "Segna allegati come sensibili",
+ "account_not_locked_warning": "Il tuo profilo non è {0}. Chiunque può seguirti e vedere i tuoi messaggi riservati ai tuoi seguaci.",
+ "account_not_locked_warning_link": "protetto",
+ "attachments_sensitive": "Nascondi gli allegati",
"content_type": {
- "text/plain": "Testo normale"
+ "text/plain": "Testo normale",
+ "text/bbcode": "BBCode",
+ "text/markdown": "Markdown",
+ "text/html": "HTML"
},
"content_warning": "Oggetto (facoltativo)",
- "default": "Appena atterrato in L.A.",
+ "default": "Sono appena atterrato a Fiumicino.",
"direct_warning": "Questo post sarà visibile solo dagli utenti menzionati.",
- "posting": "Pubblica",
+ "posting": "Sto pubblicando",
"scope": {
- "direct": "Diretto - Pubblicato solo per gli utenti menzionati",
- "private": "Solo per chi ti segue - Visibile solo da chi ti segue",
- "public": "Pubblico - Visibile sulla sequenza temporale pubblica",
- "unlisted": "Non elencato - Non visibile sulla sequenza temporale pubblica"
- }
+ "direct": "Diretto - Visibile solo agli utenti menzionati",
+ "private": "Solo per seguaci - Visibile solo dai tuoi seguaci",
+ "public": "Pubblico - Visibile sulla sequenza pubblica",
+ "unlisted": "Non elencato - Non visibile sulla sequenza pubblica"
+ },
+ "scope_notice": {
+ "unlisted": "Questo messaggio non sarà visibile sulla sequenza locale né su quella pubblica",
+ "private": "Questo messaggio sarà visibile solo ai tuoi seguaci",
+ "public": "Questo messaggio sarà visibile a tutti"
+ },
+ "direct_warning_to_first_only": "Questo messaggio sarà visibile solo agli utenti menzionati all'inizio.",
+ "direct_warning_to_all": "Questo messaggio sarà visibile a tutti i menzionati.",
+ "new_status": "Nuovo messaggio"
},
"registration": {
"bio": "Introduzione",
@@ -194,13 +432,120 @@
"fullname": "Nome visualizzato",
"password_confirm": "Conferma password",
"registration": "Registrazione",
- "token": "Codice d'invito"
+ "token": "Codice d'invito",
+ "validations": {
+ "password_confirmation_match": "dovrebbe essere uguale alla password",
+ "password_confirmation_required": "non può essere vuoto",
+ "password_required": "non può essere vuoto",
+ "email_required": "non può essere vuoto",
+ "fullname_required": "non può essere vuoto",
+ "username_required": "non può essere vuoto"
+ },
+ "bio_placeholder": "es.\nCiao, sono Lupo Lucio.\nSono un lupo fantastico che vive nel Fantabosco. Forse mi hai visto alla Melevisione.",
+ "fullname_placeholder": "es. Lupo Lucio",
+ "username_placeholder": "es. mister_wolf",
+ "new_captcha": "Clicca l'immagine per avere un altro captcha",
+ "captcha": "CAPTCHA"
},
"user_profile": {
- "timeline_title": "Sequenza Temporale dell'Utente"
+ "timeline_title": "Sequenza dell'Utente"
},
"who_to_follow": {
- "more": "Più",
+ "more": "Altro",
"who_to_follow": "Chi seguire"
+ },
+ "about": {
+ "mrf": {
+ "federation": "Federazione",
+ "keyword": {
+ "reject": "Rifiuta",
+ "replace": "Sostituisci",
+ "is_replaced_by": "→",
+ "keyword_policies": "Regole per parole chiave",
+ "ftl_removal": "Rimozione dalla sequenza globale"
+ },
+ "simple": {
+ "reject": "Rifiuta",
+ "accept": "Accetta",
+ "simple_policies": "Regole specifiche alla stanza",
+ "accept_desc": "Questa stanza accetta messaggi solo dalle seguenti stanze:",
+ "reject_desc": "Questa stanza non accetterà messaggi dalle stanze seguenti:",
+ "quarantine": "Quarantena",
+ "quarantine_desc": "Questa stanza inoltrerà solo messaggi pubblici alle seguenti stanze:",
+ "ftl_removal": "Rimozione dalla sequenza globale",
+ "ftl_removal_desc": "Questa stanza rimuove le seguenti stanze dalla sequenza globale:",
+ "media_removal": "Rimozione multimedia",
+ "media_removal_desc": "Questa istanza rimuove gli allegati dalle seguenti stanze:",
+ "media_nsfw": "Allegati oscurati forzatamente",
+ "media_nsfw_desc": "Questa stanza oscura gli allegati dei messaggi provenienti da queste stanze:"
+ },
+ "mrf_policies": "Regole RM abilitate",
+ "mrf_policies_desc": "Le regole RM cambiano il comportamento federativo della stanza. Vigono le seguenti regole:"
+ },
+ "staff": "Equipaggio"
+ },
+ "domain_mute_card": {
+ "mute": "Zittisci",
+ "mute_progress": "Zittisco…",
+ "unmute": "Ascolta",
+ "unmute_progress": "Procedo…"
+ },
+ "exporter": {
+ "export": "Esporta",
+ "processing": "In elaborazione, il tuo file sarà scaricabile a breve"
+ },
+ "image_cropper": {
+ "crop_picture": "Ritaglia immagine",
+ "save": "Salva",
+ "save_without_cropping": "Salva senza ritagliare",
+ "cancel": "Annulla"
+ },
+ "importer": {
+ "submit": "Invia",
+ "success": "Importato.",
+ "error": "L'importazione non è andata a buon fine."
+ },
+ "media_modal": {
+ "previous": "Precedente",
+ "next": "Prossimo"
+ },
+ "polls": {
+ "add_poll": "Sondaggio",
+ "add_option": "Alternativa",
+ "option": "Opzione",
+ "votes": "voti",
+ "vote": "Vota",
+ "type": "Tipo di sondaggio",
+ "single_choice": "Scelta singola",
+ "multiple_choices": "Scelta multipla",
+ "expiry": "Scadenza",
+ "expires_in": "Scade fra {0}",
+ "expired": "Scaduto {0} fa",
+ "not_enough_options": "Aggiungi altre risposte"
+ },
+ "interactions": {
+ "favs_repeats": "Condivisi e preferiti",
+ "load_older": "Carica vecchie interazioni",
+ "moves": "Utenti migrati",
+ "follows": "Nuovi seguìti"
+ },
+ "emoji": {
+ "load_all": "Carico tutti i {emojiAmount} emoji",
+ "load_all_hint": "Primi {saneAmount} emoji caricati, caricarli tutti potrebbe causare rallentamenti.",
+ "unicode": "Emoji Unicode",
+ "custom": "Emoji personale",
+ "add_emoji": "Inserisci Emoji",
+ "search_emoji": "Cerca un emoji",
+ "keep_open": "Tieni aperto il menù",
+ "emoji": "Emoji",
+ "stickers": "Adesivi"
+ },
+ "selectable_list": {
+ "select_all": "Seleziona tutto"
+ },
+ "remote_user_resolver": {
+ "error": "Non trovato.",
+ "searching_for": "Cerco",
+ "remote_user_resolver": "Cerca utenti remoti"
}
}
diff --git a/src/i18n/ja_easy.json b/src/i18n/ja_easy.json
index be447f1c..978e43b3 100644
--- a/src/i18n/ja_easy.json
+++ b/src/i18n/ja_easy.json
@@ -1,22 +1,26 @@
{
"about": {
- "staff": "スタッフ",
- "federation": "フェデレーション",
- "mrf_policies": "ゆうこうなMRFポリシー",
- "mrf_policies_desc": "MRFポリシーは、このインスタンスのフェデレーションのふるまいを、いじります。これらのMRFポリシーがゆうこうになっています:",
- "mrf_policy_simple": "インスタンスのポリシー",
- "mrf_policy_simple_accept": "うけいれ",
- "mrf_policy_simple_accept_desc": "このインスンスは、これらのインスタンスからのメッセージのみをうけいれます:",
- "mrf_policy_simple_reject": "おことわり",
- "mrf_policy_simple_reject_desc": "このインスタンスは、これらのインスタンスからのメッセージをうけいれません:",
- "mrf_policy_simple_quarantine": "けんえき",
- "mrf_policy_simple_quarantine_desc": "このインスタンスは、これらのインスタンスに、パブリックなとうこうのみを、おくります:",
- "mrf_policy_simple_ftl_removal": "「つながっているすべてのネットワーク」タイムラインからのぞく",
- "mrf_policy_simple_ftl_removal_desc": "このインスタンスは、つながっているすべてのネットワーク」タイムラインから、これらのインスタンスを、とりのぞきます:",
- "mrf_policy_simple_media_removal": "メディアをのぞく",
- "mrf_policy_simple_media_removal_desc": "このインスタンスは、これらのインスタンスからおくられてきたメディアを、とりのぞきます:",
- "mrf_policy_simple_media_nsfw": "メディアをすべてセンシティブにする",
- "mrf_policy_simple_media_nsfw_desc": "このインスタンスは、これらのインスタンスからおくられてきたメディアを、すべて、センシティブにマークします:"
+ "mrf": {
+ "federation": "フェデレーション",
+ "mrf_policies": "ゆうこうなMRFポリシー",
+ "mrf_policies_desc": "MRFポリシーは、このインスタンスのフェデレーションのふるまいを、いじります。これらのMRFポリシーがゆうこうになっています:",
+ "simple": {
+ "simple_policies": "インスタンスのポリシー",
+ "accept": "うけいれ",
+ "accept_desc": "このインスンスは、これらのインスタンスからのメッセージのみをうけいれます:",
+ "reject": "おことわり",
+ "reject_desc": "このインスタンスは、これらのインスタンスからのメッセージをうけいれません:",
+ "quarantine": "けんえき",
+ "quarantine_desc": "このインスタンスは、これらのインスタンスに、パブリックなとうこうのみを、おくります:",
+ "ftl_removal": "「つながっているすべてのネットワーク」タイムラインからのぞく",
+ "ftl_removal_desc": "このインスタンスは、つながっているすべてのネットワーク」タイムラインから、これらのインスタンスを、とりのぞきます:",
+ "media_removal": "メディアをのぞく",
+ "media_removal_desc": "このインスタンスは、これらのインスタンスからおくられてきたメディアを、とりのぞきます:",
+ "media_nsfw": "メディアをすべてセンシティブにする",
+ "media_nsfw_desc": "このインスタンスは、これらのインスタンスからおくられてきたメディアを、すべて、センシティブにマークします:"
+ }
+ },
+ "staff": "スタッフ"
},
"chat": {
"title": "チャット"
diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index c56ae205..c3195f10 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -7,34 +7,47 @@
// sed -i -e "s/'//gm" -e 's/"/\\"/gm' -re 's/^( +)(.+?): ((.+?))?(,?)(\{?)$/\1"\2": "\4"/gm' -e 's/\"\{\"/{/g' -e 's/,"$/",/g' file.json
// There's only problem that apostrophe character ' gets replaced by \\ so you have to fix it manually, sorry.
+const loaders = {
+ ar: () => import('./ar.json'),
+ ca: () => import('./ca.json'),
+ cs: () => import('./cs.json'),
+ de: () => import('./de.json'),
+ eo: () => import('./eo.json'),
+ es: () => import('./es.json'),
+ et: () => import('./et.json'),
+ eu: () => import('./eu.json'),
+ fi: () => import('./fi.json'),
+ fr: () => import('./fr.json'),
+ ga: () => import('./ga.json'),
+ he: () => import('./he.json'),
+ hu: () => import('./hu.json'),
+ it: () => import('./it.json'),
+ ja: () => import('./ja_pedantic.json'),
+ ja_easy: () => import('./ja_easy.json'),
+ ko: () => import('./ko.json'),
+ nb: () => import('./nb.json'),
+ nl: () => import('./nl.json'),
+ oc: () => import('./oc.json'),
+ pl: () => import('./pl.json'),
+ pt: () => import('./pt.json'),
+ ro: () => import('./ro.json'),
+ ru: () => import('./ru.json'),
+ te: () => import('./te.json'),
+ zh: () => import('./zh.json')
+}
+
const messages = {
- ar: require('./ar.json'),
- ca: require('./ca.json'),
- cs: require('./cs.json'),
- de: require('./de.json'),
- en: require('./en.json'),
- eo: require('./eo.json'),
- es: require('./es.json'),
- et: require('./et.json'),
- eu: require('./eu.json'),
- fi: require('./fi.json'),
- fr: require('./fr.json'),
- ga: require('./ga.json'),
- he: require('./he.json'),
- hu: require('./hu.json'),
- it: require('./it.json'),
- ja: require('./ja_pedantic.json'),
- ja_easy: require('./ja_easy.json'),
- ko: require('./ko.json'),
- nb: require('./nb.json'),
- nl: require('./nl.json'),
- oc: require('./oc.json'),
- pl: require('./pl.json'),
- pt: require('./pt.json'),
- ro: require('./ro.json'),
- ru: require('./ru.json'),
- te: require('./te.json'),
- zh: require('./zh.json')
+ languages: ['en', ...Object.keys(loaders)],
+ default: {
+ en: require('./en.json')
+ },
+ setLanguage: async (i18n, language) => {
+ if (loaders[language]) {
+ let messages = await loaders[language]()
+ i18n.setLocaleMessage(language, messages)
+ }
+ i18n.locale = language
+ }
}
export default messages
diff --git a/src/i18n/nl.json b/src/i18n/nl.json
index 7e2f0604..af728b6e 100644
--- a/src/i18n/nl.json
+++ b/src/i18n/nl.json
@@ -8,7 +8,7 @@
"media_proxy": "Media proxy",
"scope_options": "Zichtbaarheidsopties",
"text_limit": "Tekst limiet",
- "title": "Features",
+ "title": "Kenmerken",
"who_to_follow": "Wie te volgen"
},
"finder": {
@@ -16,58 +16,95 @@
"find_user": "Gebruiker zoeken"
},
"general": {
- "apply": "toepassen",
- "submit": "Verzend"
+ "apply": "Toepassen",
+ "submit": "Verzend",
+ "more": "Meer",
+ "optional": "optioneel",
+ "show_more": "Bekijk meer",
+ "show_less": "Bekijk minder",
+ "dismiss": "Opheffen",
+ "cancel": "Annuleren",
+ "disable": "Uitschakelen",
+ "enable": "Inschakelen",
+ "confirm": "Bevestigen",
+ "verify": "Verifiëren",
+ "generic_error": "Er is een fout opgetreden"
},
"login": {
"login": "Log in",
"description": "Log in met OAuth",
- "logout": "Log uit",
+ "logout": "Uitloggen",
"password": "Wachtwoord",
- "placeholder": "bv. lain",
- "register": "Registreer",
- "username": "Gebruikersnaam"
+ "placeholder": "bijv. lain",
+ "register": "Registreren",
+ "username": "Gebruikersnaam",
+ "hint": "Log in om deel te nemen aan de discussie",
+ "authentication_code": "Authenticatie code",
+ "enter_recovery_code": "Voer een herstelcode in",
+ "enter_two_factor_code": "Voer een twee-factor code in",
+ "recovery_code": "Herstelcode",
+ "heading": {
+ "totp": "Twee-factor authenticatie",
+ "recovery": "Twee-factor herstelling"
+ }
},
"nav": {
"about": "Over",
"back": "Terug",
- "chat": "Locale Chat",
- "friend_requests": "Volgverzoek",
+ "chat": "Lokale Chat",
+ "friend_requests": "Volgverzoeken",
"mentions": "Vermeldingen",
"dms": "Directe Berichten",
"public_tl": "Publieke Tijdlijn",
"timeline": "Tijdlijn",
- "twkn": "Het Geheel Gekende Netwerk",
- "user_search": "Zoek Gebruiker",
+ "twkn": "Het Geheel Bekende Netwerk",
+ "user_search": "Gebruiker Zoeken",
"who_to_follow": "Wie te volgen",
- "preferences": "Voorkeuren"
+ "preferences": "Voorkeuren",
+ "administration": "Administratie",
+ "search": "Zoeken",
+ "interactions": "Interacties"
},
"notifications": {
- "broken_favorite": "Onbekende status, aan het zoeken...",
+ "broken_favorite": "Onbekende status, aan het zoeken…",
"favorited_you": "vond je status leuk",
"followed_you": "volgt jou",
"load_older": "Laad oudere meldingen",
"notifications": "Meldingen",
"read": "Gelezen!",
- "repeated_you": "Herhaalde je status"
+ "repeated_you": "Herhaalde je status",
+ "no_more_notifications": "Geen meldingen meer",
+ "migrated_to": "is gemigreerd naar",
+ "follow_request": "wil je volgen",
+ "reacted_with": "reageerde met {0}"
},
"post_status": {
- "new_status": "Post nieuwe status",
- "account_not_locked_warning": "Je account is niet {0}. Iedereen die je volgt kan enkel-volgers posts lezen.",
+ "new_status": "Nieuwe status plaatsen",
+ "account_not_locked_warning": "Je account is niet {0}. Iedereen kan je volgen om je alleen-volgers berichten te lezen.",
"account_not_locked_warning_link": "gesloten",
- "attachments_sensitive": "Markeer bijlage als gevoelig",
+ "attachments_sensitive": "Markeer bijlagen als gevoelig",
"content_type": {
- "text/plain": "Gewone tekst"
+ "text/plain": "Platte tekst",
+ "text/html": "HTML",
+ "text/markdown": "Markdown",
+ "text/bbcode": "BBCode"
},
"content_warning": "Onderwerp (optioneel)",
- "default": "Tijd voor een pauze!",
+ "default": "Zojuist geland in L.A.",
"direct_warning": "Deze post zal enkel zichtbaar zijn voor de personen die genoemd zijn.",
"posting": "Plaatsen",
"scope": {
- "direct": "Direct - Post enkel naar genoemde gebruikers",
+ "direct": "Direct - Post enkel naar vermelde gebruikers",
"private": "Enkel volgers - Post enkel naar volgers",
"public": "Publiek - Post op publieke tijdlijnen",
- "unlisted": "Unlisted - Toon niet op publieke tijdlijnen"
+ "unlisted": "Niet Vermelden - Niet tonen op publieke tijdlijnen"
+ },
+ "direct_warning_to_all": "Dit bericht zal zichtbaar zijn voor alle vermelde gebruikers.",
+ "direct_warning_to_first_only": "Dit bericht zal alleen zichtbaar zijn voor de vermelde gebruikers aan het begin van het bericht.",
+ "scope_notice": {
+ "public": "Dit bericht zal voor iedereen zichtbaar zijn",
+ "unlisted": "Dit bericht zal niet zichtbaar zijn in de Publieke Tijdlijn en Het Geheel Bekende Netwerk",
+ "private": "Dit bericht zal voor alleen je volgers zichtbaar zijn"
}
},
"registration": {
@@ -76,7 +113,7 @@
"fullname": "Weergave naam",
"password_confirm": "Wachtwoord bevestiging",
"registration": "Registratie",
- "token": "Uitnodigingstoken",
+ "token": "Uitnodigings-token",
"captcha": "CAPTCHA",
"new_captcha": "Klik op de afbeelding voor een nieuwe captcha",
"validations": {
@@ -86,141 +123,161 @@
"password_required": "moet ingevuld zijn",
"password_confirmation_required": "moet ingevuld zijn",
"password_confirmation_match": "komt niet overeen met het wachtwoord"
- }
+ },
+ "username_placeholder": "bijv. lain",
+ "fullname_placeholder": "bijv. Lain Iwakura",
+ "bio_placeholder": "bijv.\nHallo, ik ben Lain.\nIk ben een anime meisje woonachtig in een buitenwijk in Japan. Je kent me misschien van the Wired."
},
"settings": {
"attachmentRadius": "Bijlages",
"attachments": "Bijlages",
- "autoload": "Automatisch laden wanneer tot de bodem gescrold inschakelen",
+ "autoload": "Automatisch laden inschakelen wanneer tot de bodem gescrold wordt",
"avatar": "Avatar",
"avatarAltRadius": "Avatars (Meldingen)",
"avatarRadius": "Avatars",
"background": "Achtergrond",
"bio": "Bio",
"btnRadius": "Knoppen",
- "cBlue": "Blauw (Antwoord, volgen)",
- "cGreen": "Groen (Herhaal)",
- "cOrange": "Oranje (Vind ik leuk)",
- "cRed": "Rood (Annuleer)",
- "change_password": "Verander Wachtwoord",
- "change_password_error": "Er was een probleem bij het aanpassen van je wachtwoord.",
- "changed_password": "Wachtwoord succesvol aangepast!",
- "collapse_subject": "Klap posts met onderwerp in",
- "composing": "Samenstellen",
- "confirm_new_password": "Bevestig nieuw wachtwoord",
+ "cBlue": "Blauw (Beantwoorden, volgen)",
+ "cGreen": "Groen (Herhalen)",
+ "cOrange": "Oranje (Favoriet)",
+ "cRed": "Rood (Annuleren)",
+ "change_password": "Wachtwoord Wijzigen",
+ "change_password_error": "Er is een fout opgetreden bij het wijzigen van je wachtwoord.",
+ "changed_password": "Wachtwoord succesvol gewijzigd!",
+ "collapse_subject": "Klap berichten met een onderwerp in",
+ "composing": "Opstellen",
+ "confirm_new_password": "Nieuw wachtwoord bevestigen",
"current_avatar": "Je huidige avatar",
"current_password": "Huidig wachtwoord",
"current_profile_banner": "Je huidige profiel banner",
"data_import_export_tab": "Data Import / Export",
- "default_vis": "Standaard zichtbaarheidsscope",
- "delete_account": "Verwijder Account",
- "delete_account_description": "Verwijder je account en berichten permanent.",
- "delete_account_error": "Er was een probleem bij het verwijderen van je account. Indien dit probleem blijft, gelieve de administratie van deze instantie te verwittigen.",
- "delete_account_instructions": "Typ je wachtwoord in de input hieronder om het verwijderen van je account te bevestigen.",
- "export_theme": "Sla preset op",
+ "default_vis": "Standaard zichtbaarheidsbereik",
+ "delete_account": "Account Verwijderen",
+ "delete_account_description": "Permanent je gegevens verwijderen en account deactiveren.",
+ "delete_account_error": "Er is een fout opgetreden bij het verwijderen van je account. Indien dit probleem zich voor blijft doen, neem dan contact op met de beheerder van deze instantie.",
+ "delete_account_instructions": "Voer je wachtwoord in het onderstaande invoerveld in om het verwijderen van je account te bevestigen.",
+ "export_theme": "Preset opslaan",
"filtering": "Filtering",
- "filtering_explanation": "Alle statussen die deze woorden bevatten worden genegeerd, één filter per lijn.",
- "follow_export": "Volgers export",
- "follow_export_button": "Exporteer je volgers naar een csv file",
+ "filtering_explanation": "Alle statussen die deze woorden bevatten worden genegeerd, één filter per lijn",
+ "follow_export": "Volgers exporteren",
+ "follow_export_button": "Exporteer je volgers naar een csv bestand",
"follow_export_processing": "Aan het verwerken, binnen enkele ogenblikken wordt je gevraagd je bestand te downloaden",
- "follow_import": "Volgers import",
+ "follow_import": "Volgers importeren",
"follow_import_error": "Fout bij importeren volgers",
- "follows_imported": "Volgers geïmporteerd! Het kan even duren om ze allemaal te verwerken.",
+ "follows_imported": "Volgers geïmporteerd! Het kan even duren voordat deze verwerkt zijn.",
"foreground": "Voorgrond",
"general": "Algemeen",
"hide_attachments_in_convo": "Verberg bijlages in conversaties",
"hide_attachments_in_tl": "Verberg bijlages in de tijdlijn",
"hide_isp": "Verberg instantie-specifiek paneel",
- "preload_images": "Afbeeldingen voorladen",
- "hide_post_stats": "Verberg post statistieken (bv. het aantal vind-ik-leuks)",
- "hide_user_stats": "Verberg post statistieken (bv. het aantal volgers)",
- "import_followers_from_a_csv_file": "Importeer volgers uit een csv file",
- "import_theme": "Laad preset",
- "inputRadius": "Invoer velden",
+ "preload_images": "Afbeeldingen vooraf laden",
+ "hide_post_stats": "Verberg bericht statistieken (bijv. het aantal favorieten)",
+ "hide_user_stats": "Verberg bericht statistieken (bijv. het aantal volgers)",
+ "import_followers_from_a_csv_file": "Importeer volgers uit een csv bestand",
+ "import_theme": "Preset laden",
+ "inputRadius": "Invoervelden",
"checkboxRadius": "Checkboxen",
"instance_default": "(standaard: {value})",
"instance_default_simple": "(standaard)",
"interface": "Interface",
"interfaceLanguage": "Interface taal",
- "invalid_theme_imported": "Het geselecteerde thema is geen door Pleroma ondersteund thema. Er zijn geen aanpassingen gedaan.",
- "limited_availability": "Onbeschikbaar in je browser",
+ "invalid_theme_imported": "Het geselecteerde bestand is geen door Pleroma ondersteund thema. Er zijn geen aanpassingen gedaan.",
+ "limited_availability": "Niet beschikbaar in je browser",
"links": "Links",
"lock_account_description": "Laat volgers enkel toe na expliciete toestemming",
- "loop_video": "Speel videos af in een lus",
- "loop_video_silent_only": "Speel enkel videos zonder geluid af in een lus (bv. Mastodon's \"gifs\")",
+ "loop_video": "Herhaal video's",
+ "loop_video_silent_only": "Herhaal enkel video's zonder geluid (bijv. Mastodon's \"gifs\")",
"name": "Naam",
"name_bio": "Naam & Bio",
"new_password": "Nieuw wachtwoord",
"notification_visibility": "Type meldingen die getoond worden",
- "notification_visibility_follows": "Volgers",
+ "notification_visibility_follows": "Volgingen",
"notification_visibility_likes": "Vind-ik-leuks",
"notification_visibility_mentions": "Vermeldingen",
"notification_visibility_repeats": "Herhalingen",
- "no_rich_text_description": "Strip rich text formattering van alle posts",
+ "no_rich_text_description": "Verwijder rich text formattering van alle berichten",
"hide_network_description": "Toon niet wie mij volgt en wie ik volg.",
- "nsfw_clickthrough": "Schakel doorklikbaar verbergen van NSFW bijlages in",
+ "nsfw_clickthrough": "Doorklikbaar verbergen van gevoelige bijlages inschakelen",
"oauth_tokens": "OAuth-tokens",
"token": "Token",
- "refresh_token": "Token vernieuwen",
+ "refresh_token": "Token Vernieuwen",
"valid_until": "Geldig tot",
"revoke_token": "Intrekken",
"panelRadius": "Panelen",
- "pause_on_unfocused": "Pauzeer streamen wanneer de tab niet gefocused is",
+ "pause_on_unfocused": "Streamen pauzeren wanneer de tab niet in focus is",
"presets": "Presets",
"profile_background": "Profiel Achtergrond",
"profile_banner": "Profiel Banner",
"profile_tab": "Profiel",
"radii_help": "Stel afronding van hoeken in de interface in (in pixels)",
"replies_in_timeline": "Antwoorden in tijdlijn",
- "reply_link_preview": "Schakel antwoordlink preview in bij over zweven met muisaanwijzer",
- "reply_visibility_all": "Toon alle antwoorden",
- "reply_visibility_following": "Toon enkel antwoorden naar mij of andere gebruikers gericht",
- "reply_visibility_self": "Toon enkel antwoorden naar mij gericht",
+ "reply_link_preview": "Antwoord-link weergave inschakelen bij aanwijzen met muisaanwijzer",
+ "reply_visibility_all": "Alle antwoorden tonen",
+ "reply_visibility_following": "Enkel antwoorden tonen die aan mij of gevolgde gebruikers gericht zijn",
+ "reply_visibility_self": "Enkel antwoorden tonen die aan mij gericht zijn",
"saving_err": "Fout tijdens opslaan van instellingen",
"saving_ok": "Instellingen opgeslagen",
- "security_tab": "Veiligheid",
- "scope_copy": "Neem scope over bij antwoorden (Directe Berichten blijven altijd Direct)",
- "set_new_avatar": "Zet nieuwe avatar",
- "set_new_profile_background": "Zet nieuwe profiel achtergrond",
- "set_new_profile_banner": "Zet nieuwe profiel banner",
+ "security_tab": "Beveiliging",
+ "scope_copy": "Neem bereik over bij beantwoorden (Directe Berichten blijven altijd Direct)",
+ "set_new_avatar": "Nieuwe avatar instellen",
+ "set_new_profile_background": "Nieuwe profiel achtergrond instellen",
+ "set_new_profile_banner": "Nieuwe profiel banner instellen",
"settings": "Instellingen",
- "subject_input_always_show": "Maak onderwerpveld altijd zichtbaar",
- "subject_line_behavior": "Kopieer onderwerp bij antwoorden",
+ "subject_input_always_show": "Altijd onderwerpveld tonen",
+ "subject_line_behavior": "Onderwerp kopiëren bij antwoorden",
"subject_line_email": "Zoals email: \"re: onderwerp\"",
- "subject_line_mastodon": "Zoals Mastodon: kopieer zoals het is",
- "subject_line_noop": "Kopieer niet",
- "stop_gifs": "Speel GIFs af bij zweven",
- "streaming": "Schakel automatisch streamen van posts in wanneer tot boven gescrold.",
+ "subject_line_mastodon": "Zoals mastodon: kopieer zoals het is",
+ "subject_line_noop": "Niet kopiëren",
+ "stop_gifs": "GIFs afspelen bij zweven",
+ "streaming": "Automatisch streamen van nieuwe berichten inschakelen wanneer tot boven gescrold is",
"text": "Tekst",
"theme": "Thema",
"theme_help": "Gebruik hex color codes (#rrggbb) om je kleurschema te wijzigen.",
- "theme_help_v2_1": "Je kan ook de kleur en transparantie van bepaalde componenten overschrijven door de checkbox aan te vinken, gebruik de \"Wis alles\" knop om alle overschrijvingen te annuleren.",
- "theme_help_v2_2": "Iconen onder sommige items zijn achtergrond/tekst contrast indicators, zweef er over voor gedetailleerde info. Hou er rekening mee dat bij doorzichtigheid de ergst mogelijke situatie wordt weer gegeven.",
- "tooltipRadius": "Gereedschapstips/alarmen",
- "user_settings": "Gebruikers Instellingen",
+ "theme_help_v2_1": "Je kan ook de kleur en transparantie van bepaalde componenten overschrijven door de checkbox aan te vinken, gebruik de \"Alles wissen\" knop om alle overschrijvingen te annuleren.",
+ "theme_help_v2_2": "Iconen onder sommige onderdelen zijn achtergrond/tekst contrast indicatoren, zweef er over voor gedetailleerde info. Hou er rekening mee dat bij doorzichtigheid de ergst mogelijke situatie wordt weer gegeven.",
+ "tooltipRadius": "Tooltips/alarmen",
+ "user_settings": "Gebruikersinstellingen",
"values": {
"false": "nee",
"true": "ja"
},
"notifications": "Meldingen",
- "enable_web_push_notifications": "Schakel web push meldingen in",
+ "enable_web_push_notifications": "Web push meldingen inschakelen",
"style": {
"switcher": {
- "keep_color": "Behoud kleuren",
- "keep_shadows": "Behoud schaduwen",
- "keep_opacity": "Behoud transparantie",
- "keep_roundness": "Behoud afrondingen",
- "keep_fonts": "Behoud lettertypes",
+ "keep_color": "Kleuren behouden",
+ "keep_shadows": "Schaduwen behouden",
+ "keep_opacity": "Transparantie behouden",
+ "keep_roundness": "Rondingen behouden",
+ "keep_fonts": "Lettertypes behouden",
"save_load_hint": "\"Behoud\" opties behouden de momenteel ingestelde opties bij het selecteren of laden van thema's, maar slaan ook de genoemde opties op bij het exporteren van een thema. Wanneer alle selectievakjes zijn uitgeschakeld, zal het exporteren van thema's alles opslaan.",
"reset": "Reset",
- "clear_all": "Wis alles",
- "clear_opacity": "Wis transparantie"
+ "clear_all": "Alles wissen",
+ "clear_opacity": "Transparantie wissen",
+ "keep_as_is": "Hou zoals het is",
+ "use_snapshot": "Oude versie",
+ "use_source": "Nieuwe versie",
+ "help": {
+ "future_version_imported": "Het geïmporteerde bestand is gemaakt voor een nieuwere versie van FE.",
+ "older_version_imported": "Het geïmporteerde bestand is gemaakt voor een oudere versie van FE.",
+ "upgraded_from_v2": "PleromaFE is bijgewerkt, het thema kan iets anders uitzien dan dat je gewend bent.",
+ "v2_imported": "Het geïmporteerde bestand is gemaakt voor een oudere FE. We proberen compatibiliteit te maximaliseren, maar het kan toch voorkomen dat er inconsistenties zijn.",
+ "snapshot_source_mismatch": "Versie conflict: waarschijnlijk was FE terug gerold en opnieuw bijgewerkt, indien je het thema aangepast hebt met de oudere versie van FE wil je waarschijnlijk de oude versie gebruiken, gebruik anders de nieuwe versie.",
+ "migration_napshot_gone": "Voor een onduidelijke reden mist de momentopname, dus sommige dingen kunnen anders uitzien dan je gewend bent.",
+ "migration_snapshot_ok": "Voor de zekerheid is een momentopname van het thema geladen. Je kunt proberen om de thema gegevens te laden.",
+ "fe_downgraded": "PleromaFE's versie is terug gerold.",
+ "fe_upgraded": "De thema-engine van PleromaFE is bijgewerkt na de versie update.",
+ "snapshot_missing": "Het bestand bevat geen thema momentopname, dus het thema kan anders uitzien dan je oorspronkelijk bedacht had.",
+ "snapshot_present": "Thema momentopname is geladen, alle waarden zijn overschreven. Je kunt in plaats daarvan ook de daadwerkelijke data van het thema laden."
+ },
+ "load_theme": "Thema laden"
},
"common": {
"color": "Kleur",
"opacity": "Transparantie",
"contrast": {
- "hint": "Contrast ratio is {ratio}, {level} {context}",
+ "hint": "Contrast verhouding is {ratio}, {level} {context}",
"level": {
"aa": "voldoet aan de richtlijn van niveau AA (minimum)",
"aaa": "voldoet aan de richtlijn van niveau AAA (aangeraden)",
@@ -233,8 +290,8 @@
}
},
"common_colors": {
- "_tab_label": "Gemeenschappelijk",
- "main": "Gemeenschappelijke kleuren",
+ "_tab_label": "Algemeen",
+ "main": "Algemene kleuren",
"foreground_hint": "Zie \"Geavanceerd\" tab voor meer gedetailleerde controle",
"rgbo": "Iconen, accenten, badges"
},
@@ -244,58 +301,73 @@
"alert_error": "Fout",
"badge": "Badge achtergrond",
"badge_notification": "Meldingen",
- "panel_header": "Paneel hoofding",
- "top_bar": "Top bar",
+ "panel_header": "Paneel koptekst",
+ "top_bar": "Top balk",
"borders": "Randen",
"buttons": "Knoppen",
"inputs": "Invoervelden",
- "faint_text": "Vervaagde tekst"
+ "faint_text": "Vervaagde tekst",
+ "tabs": "Tabbladen",
+ "toggled": "Geschakeld",
+ "disabled": "Uitgeschakeld",
+ "selectedMenu": "Geselecteerd menu item",
+ "selectedPost": "Geselecteerd bericht",
+ "pressed": "Ingedrukt",
+ "highlight": "Gemarkeerde elementen",
+ "icons": "Iconen",
+ "poll": "Poll grafiek",
+ "underlay": "Onderlaag",
+ "popover": "Tooltips, menu's, popovers",
+ "post": "Berichten / Gebruiker bios",
+ "alert_neutral": "Neutraal",
+ "alert_warning": "Waarschuwing"
},
"radii": {
"_tab_label": "Rondheid"
},
"shadows": {
"_tab_label": "Schaduw en belichting",
- "component": "Component",
+ "component": "Onderdeel",
"override": "Overschrijven",
"shadow_id": "Schaduw #{value}",
"blur": "Vervagen",
- "spread": "Spreid",
+ "spread": "Spreiding",
"inset": "Inzet",
"hint": "Voor schaduw kan je ook --variable gebruiken als een kleur waarde om CSS3 variabelen te gebruiken. Houd er rekening mee dat het instellen van opaciteit in dit geval niet werkt.",
"filter_hint": {
"always_drop_shadow": "Waarschuwing, deze schaduw gebruikt altijd {0} als de browser dit ondersteund.",
"drop_shadow_syntax": "{0} ondersteund niet de {1} parameter en {2} sleutelwoord.",
- "avatar_inset": "Houd er rekening mee dat het combineren van zowel inzet and niet-inzet schaduwen op transparante avatars onverwachte resultaten kan opleveren.",
+ "avatar_inset": "Houdt er rekening mee dat het combineren van zowel inzet and niet-inzet schaduwen op transparante avatars onverwachte resultaten kan opleveren.",
"spread_zero": "Schaduw met spreiding > 0 worden weergegeven alsof ze op nul staan",
"inset_classic": "Inzet schaduw zal {0} gebruiken"
},
"components": {
"panel": "Paneel",
- "panelHeader": "Paneel hoofding",
- "topBar": "Top bar",
- "avatar": "Gebruiker avatar (in profiel weergave)",
- "avatarStatus": "Gebruiker avatar (in post weergave)",
- "popup": "Popups en gereedschapstips",
+ "panelHeader": "Paneel koptekst",
+ "topBar": "Top balk",
+ "avatar": "Gebruikers avatar (in profiel weergave)",
+ "avatarStatus": "Gebruikers avatar (in bericht weergave)",
+ "popup": "Popups en tooltips",
"button": "Knop",
"buttonHover": "Knop (zweven)",
"buttonPressed": "Knop (ingedrukt)",
"buttonPressedHover": "Knop (ingedrukt+zweven)",
"input": "Invoerveld"
- }
+ },
+ "hintV3": "Voor schaduwen kun je ook de {0} notatie gebruiken om de andere kleur invoer te gebruiken."
},
"fonts": {
"_tab_label": "Lettertypes",
- "help": "Selecteer het lettertype om te gebruiken voor elementen van de UI.Voor \"aangepast\" moet je de exacte naam van het lettertype invoeren zoals die in het systeem wordt weergegeven.",
+ "help": "Selecteer het lettertype om te gebruiken voor elementen van de UI. Voor \"aangepast\" dien je de exacte naam van het lettertype in te voeren zoals die in het systeem wordt weergegeven.",
"components": {
"interface": "Interface",
"input": "Invoervelden",
- "post": "Post tekst",
- "postCode": "Monospaced tekst in een post (rich text)"
+ "post": "Bericht tekst",
+ "postCode": "Monospaced tekst in een bericht (rich text)"
},
- "family": "Naam lettertype",
+ "family": "Lettertype naam",
"size": "Grootte (in px)",
- "weight": "Gewicht (vetheid)",
+ "weight": "Gewicht (dikgedruktheid)",
"custom": "Aangepast"
},
"preview": {
@@ -305,31 +377,119 @@
"button": "Knop",
"text": "Nog een boel andere {0} en {1}",
"mono": "inhoud",
- "input": "Tijd voor een pauze!",
+ "input": "Zojuist geland in L.A.",
"faint_link": "handige gebruikershandleiding",
"fine_print": "Lees onze {0} om niets nuttig te leren!",
"header_faint": "Alles komt goed",
- "checkbox": "Ik heb de gebruikersvoorwaarden eens van ver bekeken",
- "link": "een link"
+ "checkbox": "Ik heb de gebruikersvoorwaarden gelezen",
+ "link": "een leuke kleine link"
}
+ },
+ "notification_setting_follows": "Gebruikers die je volgt",
+ "notification_setting_non_follows": "Gebruikers die je niet volgt",
+ "notification_setting_followers": "Gebruikers die je volgen",
+ "notification_setting_privacy": "Privacy",
+ "notification_setting_privacy_option": "Verberg de afzender en inhoud van push meldingen",
+ "notification_mutes": "Om niet langer meldingen te ontvangen van een specifieke gebruiker, kun je deze negeren.",
+ "app_name": "App naam",
+ "security": "Beveiliging",
+ "enter_current_password_to_confirm": "Voer je huidige wachtwoord in om je identiteit te bevestigen",
+ "mfa": {
+ "otp": "OTP",
+ "setup_otp": "OTP instellen",
+ "wait_pre_setup_otp": "OTP voorinstellen",
+ "confirm_and_enable": "Bevestig en schakel OTP in",
+ "title": "Twee-factor Authenticatie",
+ "generate_new_recovery_codes": "Genereer nieuwe herstelcodes",
+ "recovery_codes": "Herstelcodes.",
+ "waiting_a_recovery_codes": "Backup codes ontvangen…",
+ "authentication_methods": "Authenticatie methodes",
+ "scan": {
+ "title": "Scannen",
+ "desc": "Scan de QR code of voer een sleutel in met je twee-factor applicatie:",
+ "secret_code": "Sleutel"
+ },
+ "verify": {
+ "desc": "Voer de code van je twee-factor applicatie in om twee-factor authenticatie in te schakelen:"
+ },
+ "warning_of_generate_new_codes": "Wanneer je nieuwe herstelcodes genereert, zullen je oude code niet langer werken.",
+ "recovery_codes_warning": "Schrijf de codes op of sla ze op een veilige locatie op - anders kun je ze niet meer inzien. Als je toegang tot je 2FA app en herstelcodes verliest, zal je buitengesloten zijn uit je account."
+ },
+ "allow_following_move": "Automatisch volgen toestaan wanneer een gevolgd account migreert",
+ "block_export": "Blokkades exporteren",
+ "block_import": "Blokkades importeren",
+ "blocks_imported": "Blokkades geïmporteerd! Het kan even duren voordat deze verwerkt zijn.",
+ "blocks_tab": "Blokkades",
+ "change_email": "Email wijzigen",
+ "change_email_error": "Er is een fout opgetreden tijdens het wijzigen van je email.",
+ "changed_email": "Email succesvol gewijzigd!",
+ "domain_mutes": "Domeinen",
+ "avatar_size_instruction": "De aangeraden minimale afmeting voor avatar afbeeldingen is 150x150 pixels.",
+ "pad_emoji": "Vul emoji aan met spaties wanneer deze met de picker ingevoegd worden",
+ "emoji_reactions_on_timeline": "Toon emoji reacties op de tijdlijn",
+ "accent": "Accent",
+ "hide_muted_posts": "Verberg berichten van genegeerde gebruikers",
+ "max_thumbnails": "Maximaal aantal miniaturen per bericht",
+ "use_one_click_nsfw": "Open gevoelige bijlagen met slechts één klik",
+ "hide_filtered_statuses": "Gefilterde statussen verbergen",
+ "import_blocks_from_a_csv_file": "Importeer blokkades van een csv bestand",
+ "mutes_tab": "Negeringen",
+ "play_videos_in_modal": "Speel video's af in een popup frame",
+ "new_email": "Nieuwe Email",
+ "notification_visibility_emoji_reactions": "Reacties",
+ "no_blocks": "Geen blokkades",
+ "no_mutes": "Geen negeringen",
+ "hide_followers_description": "Niet tonen wie mij volgt",
+ "hide_followers_count_description": "Niet mijn volgers aantal tonen",
+ "hide_follows_count_description": "Niet mijn gevolgde aantal tonen",
+ "show_admin_badge": "Beheerders badge tonen in mijn profiel",
+ "autohide_floating_post_button": "Nieuw Bericht knop automatisch verbergen (mobiel)",
+ "search_user_to_block": "Zoek wie je wilt blokkeren",
+ "search_user_to_mute": "Zoek wie je wilt negeren",
+ "minimal_scopes_mode": "Bericht bereik-opties minimaliseren",
+ "post_status_content_type": "Bericht status content type",
+ "user_mutes": "Gebruikers",
+ "useStreamingApi": "Berichten en meldingen in real-time ontvangen",
+ "useStreamingApiWarning": "(Afgeraden, experimenteel, kan berichten overslaan)",
+ "type_domains_to_mute": "Voer domeinen in om te negeren",
+ "upload_a_photo": "Upload een foto",
+ "fun": "Plezier",
+ "greentext": "Meme pijlen",
+ "notification_setting": "Ontvang meldingen van:",
+ "block_export_button": "Exporteer je geblokkeerde gebruikers naar een csv bestand",
+ "block_import_error": "Fout bij importeren blokkades",
+ "discoverable": "Sta toe dat dit account ontdekt kan worden in zoekresultaten en andere diensten",
+ "use_contain_fit": "Snij bijlage in miniaturen niet bij",
+ "notification_visibility_moves": "Gebruiker Migraties",
+ "hide_follows_description": "Niet tonen wie ik volg",
+ "show_moderator_badge": "Moderators badge tonen in mijn profiel",
+ "notification_setting_filters": "Filters",
+ "notification_setting_non_followers": "Gebruikers die je niet volgen",
+ "notification_blocks": "Door een gebruiker te blokkeren, ontvang je geen meldingen meer van de gebruiker en wordt je abonnement op de gebruiker opgeheven.",
+ "version": {
+ "frontend_version": "Frontend Versie",
+ "backend_version": "Backend Versie",
+ "title": "Versie"
}
},
"timeline": {
"collapse": "Inklappen",
"conversation": "Conversatie",
"error_fetching": "Fout bij ophalen van updates",
- "load_older": "Laad oudere Statussen",
- "no_retweet_hint": "Post is gemarkeerd als enkel volgers of direct en kan niet worden herhaald",
+ "load_older": "Oudere statussen laden",
+ "no_retweet_hint": "Bericht is gemarkeerd als enkel volgers of direct en kan niet worden herhaald",
"repeated": "herhaalde",
- "show_new": "Toon nieuwe",
- "up_to_date": "Up-to-date"
+ "show_new": "Nieuwe tonen",
+ "up_to_date": "Up-to-date",
+ "no_statuses": "Geen statussen",
+ "no_more_statuses": "Geen statussen meer"
},
"user_card": {
"approve": "Goedkeuren",
"block": "Blokkeren",
"blocked": "Geblokkeerd!",
- "deny": "Ontzeggen",
- "favorites": "Vind-ik-leuks",
+ "deny": "Weigeren",
+ "favorites": "Favorieten",
"follow": "Volgen",
"follow_sent": "Aanvraag verzonden!",
"follow_progress": "Aanvragen…",
@@ -340,31 +500,69 @@
"following": "Aan het volgen!",
"follows_you": "Volgt jou!",
"its_you": "'t is jij!",
- "mute": "Dempen",
- "muted": "Gedempt",
+ "mute": "Negeren",
+ "muted": "Genegeerd",
"per_day": "per dag",
"remote_follow": "Volg vanop afstand",
- "statuses": "Statussen"
+ "statuses": "Statussen",
+ "admin_menu": {
+ "delete_user_confirmation": "Weet je het heel zeker? Deze uitvoering kan niet ongedaan worden gemaakt.",
+ "delete_user": "Gebruiker verwijderen",
+ "quarantine": "Federeren van gebruikers berichten verbieden",
+ "disable_any_subscription": "Volgen van gebruiker in zijn geheel verbieden",
+ "disable_remote_subscription": "Volgen van gebruiker vanaf andere instanties verbieden",
+ "sandbox": "Berichten forceren om alleen voor volgers zichtbaar te zijn",
+ "force_unlisted": "Berichten forceren om niet publiekelijk getoond te worden",
+ "strip_media": "Media van berichten verwijderen",
+ "force_nsfw": "Alle berichten als gevoelig markeren",
+ "delete_account": "Account verwijderen",
+ "deactivate_account": "Account deactiveren",
+ "activate_account": "Account activeren",
+ "revoke_moderator": "Moderatorsrechten intrekken",
+ "grant_moderator": "Moderatorsrechten toekennen",
+ "revoke_admin": "Beheerdersrechten intrekken",
+ "grant_admin": "Beheerdersrechten toekennen",
+ "moderation": "Moderatie"
+ },
+ "show_repeats": "Herhalingen tonen",
+ "hide_repeats": "Herhalingen verbergen",
+ "mute_progress": "Negeren…",
+ "unmute_progress": "Negering opheffen…",
+ "unmute": "Negering opheffen",
+ "block_progress": "Blokkeren…",
+ "unblock_progress": "Blokkade opheffen…",
+ "unblock": "Blokkade opheffen",
+ "unsubscribe": "Abonnement opzeggen",
+ "subscribe": "Abonneren",
+ "report": "Aangeven",
+ "mention": "Vermelding",
+ "media": "Media",
+ "hidden": "Verborgen"
},
"user_profile": {
- "timeline_title": "Gebruikers Tijdlijn"
+ "timeline_title": "Gebruikers Tijdlijn",
+ "profile_loading_error": "Sorry, er is een fout opgetreden bij het laden van dit profiel.",
+ "profile_does_not_exist": "Sorry, dit profiel bestaat niet."
},
"who_to_follow": {
"more": "Meer",
"who_to_follow": "Wie te volgen"
},
"tool_tip": {
- "media_upload": "Upload Media",
- "repeat": "Herhaal",
- "reply": "Antwoord",
- "favorite": "Vind-ik-leuk",
- "user_settings": "Gebruikers Instellingen"
+ "media_upload": "Media Uploaden",
+ "repeat": "Herhalen",
+ "reply": "Beantwoorden",
+ "favorite": "Favoriet maken",
+ "user_settings": "Gebruikers Instellingen",
+ "reject_follow_request": "Volg-verzoek afwijzen",
+ "accept_follow_request": "Volg-aanvraag accepteren",
+ "add_reaction": "Reactie toevoegen"
},
- "upload":{
+ "upload": {
"error": {
- "base": "Upload gefaald.",
- "file_too_big": "Bestand is te groot [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
- "default": "Probeer later opnieuw"
+ "base": "Upload mislukt.",
+ "file_too_big": "Bestand is te groot [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
+ "default": "Probeer het later opnieuw"
},
"file_size_units": {
"B": "B",
@@ -373,5 +571,177 @@
"GiB": "GiB",
"TiB": "TiB"
}
+ },
+ "about": {
+ "mrf": {
+ "federation": "Federatie",
+ "keyword": {
+ "reject": "Afwijzen",
+ "replace": "Vervangen",
+ "is_replaced_by": "→",
+ "keyword_policies": "Zoekwoord Beleid",
+ "ftl_removal": "Verwijdering van \"Het Geheel Bekende Netwerk\" Tijdlijn"
+ },
+ "mrf_policies_desc": "MRF regels beïnvloeden het federatie gedrag van de instantie. De volgende regels zijn ingeschakeld:",
+ "mrf_policies": "Ingeschakelde MRF Regels",
+ "simple": {
+ "simple_policies": "Instantie-specifieke Regels",
+ "accept": "Accepteren",
+ "accept_desc": "Deze instantie accepteert alleen berichten van de volgende instanties:",
+ "reject": "Afwijzen",
+ "reject_desc": "Deze instantie zal geen berichten accepteren van de volgende instanties:",
+ "quarantine": "Quarantaine",
+ "quarantine_desc": "Deze instantie zal alleen publieke berichten sturen naar de volgende instanties:",
+ "ftl_removal_desc": "Deze instantie verwijdert de volgende instanties van \"Het Geheel Bekende Netwerk\" tijdlijn:",
+ "media_removal_desc": "Deze instantie verwijdert media van berichten van de volgende instanties:",
+ "media_nsfw_desc": "Deze instantie stelt media in als gevoelig in berichten van de volgende instanties:",
+ "ftl_removal": "Verwijderen van \"Het Geheel Bekende Netwerk\" Tijdlijn",
+ "media_removal": "Media Verwijdering",
+ "media_nsfw": "Forceer Media als Gevoelig"
+ }
+ },
+ "staff": "Personeel"
+ },
+ "domain_mute_card": {
+ "mute": "Negeren",
+ "mute_progress": "Negeren…",
+ "unmute": "Negering opheffen",
+ "unmute_progress": "Negering wordt opgeheven…"
+ },
+ "exporter": {
+ "export": "Exporteren",
+ "processing": "Verwerken, er wordt zo gevraagd om je bestand te downloaden"
+ },
+ "image_cropper": {
+ "save": "Opslaan",
+ "save_without_cropping": "Opslaan zonder bijsnijden",
+ "cancel": "Annuleren",
+ "crop_picture": "Afbeelding bijsnijden"
+ },
+ "importer": {
+ "submit": "Verzenden",
+ "success": "Succesvol geïmporteerd.",
+ "error": "Er is een fout opgetreden bij het importeren van dit bestand."
+ },
+ "media_modal": {
+ "previous": "Vorige",
+ "next": "Volgende"
+ },
+ "polls": {
+ "add_poll": "Poll Toevoegen",
+ "add_option": "Optie Toevoegen",
+ "option": "Optie",
+ "votes": "stemmen",
+ "vote": "Stem",
+ "single_choice": "Enkele keuze",
+ "multiple_choices": "Meerkeuze",
+ "expiry": "Poll leeftijd",
+ "expires_in": "Poll eindigt in {0}",
+ "expired": "Poll is {0} geleden beëindigd",
+ "not_enough_options": "Te weinig opties in poll",
+ "type": "Poll type"
+ },
+ "emoji": {
+ "emoji": "Emoji",
+ "keep_open": "Picker openhouden",
+ "search_emoji": "Zoek voor een emoji",
+ "add_emoji": "Emoji invoegen",
+ "unicode": "Unicode emoji",
+ "load_all": "Alle {emojiAmount} emoji worden geladen",
+ "stickers": "Stickers",
+ "load_all_hint": "Eerste {saneAmount} emoji geladen, alle emoji tegelijk laden kan problemen veroorzaken met prestaties.",
+ "custom": "Gepersonaliseerde emoji"
+ },
+ "interactions": {
+ "favs_repeats": "Herhalingen en Favorieten",
+ "follows": "Nieuwe volgingen",
+ "moves": "Gebruiker migreert",
+ "load_older": "Oudere interacties laden"
+ },
+ "remote_user_resolver": {
+ "searching_for": "Zoeken naar",
+ "error": "Niet gevonden.",
+ "remote_user_resolver": "Externe gebruikers zoeker"
+ },
+ "selectable_list": {
+ "select_all": "Alles selecteren"
+ },
+ "password_reset": {
+ "password_reset_required_but_mailer_is_disabled": "Je dient je wachtwoord opnieuw in te stellen, maar wachtwoord reset is uitgeschakeld. Neem contact op met de beheerder van deze instantie.",
+ "password_reset_required": "Je dient je wachtwoord opnieuw in te stellen om in te kunnen loggen.",
+ "password_reset_disabled": "Wachtwoord reset is uitgeschakeld. Neem contact op met de beheerder van deze instantie.",
+ "too_many_requests": "Je hebt het maximaal aantal pogingen bereikt, probeer het later opnieuw.",
+ "not_found": "We kunnen die email of gebruikersnaam niet vinden.",
+ "return_home": "Terugkeren naar de home pagina",
+ "check_email": "Controleer je email inbox voor een link om je wachtwoord opnieuw in te stellen.",
+ "placeholder": "Je email of gebruikersnaam",
+ "instruction": "Voer je email adres of gebruikersnaam in. We sturen je een link om je wachtwoord opnieuw in te stellen.",
+ "password_reset": "Wachtwoord opnieuw instellen",
+ "forgot_password": "Wachtwoord vergeten?"
+ },
+ "search": {
+ "no_results": "Geen resultaten",
+ "people_talking": "{count} personen aan het praten",
+ "person_talking": "{count} persoon aan het praten",
+ "hashtags": "Hashtags",
+ "people": "Personen"
+ },
+ "user_reporting": {
+ "generic_error": "Er is een fout opgetreden tijdens het verwerken van je verzoek.",
+ "submit": "Verzenden",
+ "forward_to": "Doorsturen naar {0}",
+ "forward_description": "Dit account hoort bij een andere server. Wil je een kopie van het rapport ook daarheen sturen?",
+ "additional_comments": "Aanvullende opmerkingen",
+ "add_comment_description": "Het rapport zal naar de moderators van de instantie worden verstuurd. Je kunt hieronder uitleg bijvoegen waarom je dit account wilt aangeven:",
+ "title": "{0} aangeven"
+ },
+ "status": {
+ "copy_link": "Link naar status kopiëren",
+ "status_unavailable": "Status niet beschikbaar",
+ "unmute_conversation": "Conversatie niet meer negeren",
+ "mute_conversation": "Conversatie negeren",
+ "replies_list": "Antwoorden:",
+ "reply_to": "Antwoorden aan",
+ "delete_confirm": "Wil je echt deze status verwijderen?",
+ "pin": "Aan profiel vastmaken",
+ "pinned": "Vastgezet",
+ "unpin": "Van profiel losmaken",
+ "delete": "Status verwijderen",
+ "repeats": "Herhalingen",
+ "favorites": "Favorieten"
+ },
+ "time": {
+ "years_short": "{0}j",
+ "year_short": "{0}j",
+ "years": "{0} jaren",
+ "year": "{0} jaar",
+ "weeks_short": "{0}w",
+ "week_short": "{0}w",
+ "weeks": "{0} weken",
+ "week": "{0} week",
+ "seconds_short": "{0}s",
+ "second_short": "{0}s",
+ "seconds": "{0} seconden",
+ "second": "{0} seconde",
+ "now_short": "nu",
+ "now": "zojuist",
+ "months_short": "{0}ma",
+ "month_short": "{0}ma",
+ "months": "{0} maanden",
+ "month": "{0} maand",
+ "minutes_short": "{0}min",
+ "minute_short": "{0}min",
+ "minutes": "{0} minuten",
+ "minute": "{0} minuut",
+ "in_past": "{0} geleden",
+ "in_future": "over {0}",
+ "hours_short": "{0}u",
+ "hour_short": "{0}u",
+ "hours": "{0} uren",
+ "hour": "{0} uur",
+ "days_short": "{0}d",
+ "day_short": "{0}d",
+ "days": "{0} dagen",
+ "day": "{0} dag"
}
}
diff --git a/src/i18n/pl.json b/src/i18n/pl.json
index 51cadfb6..61e09318 100644
--- a/src/i18n/pl.json
+++ b/src/i18n/pl.json
@@ -1,7 +1,47 @@
{
+ "about": {
+ "mrf": {
+ "federation": "Federacja",
+ "keyword": {
+ "keyword_policies": "Zasady słów kluczowych",
+ "ftl_removal": "Usunięcie z \"Całej znanej sieci\"",
+ "reject": "Odrzucanie",
+ "replace": "Zastąpienie",
+ "is_replaced_by": "→"
+ },
+ "mrf_policies": "Włączone zasady MRF",
+ "mrf_policies_desc": "Zasady MRF zmieniają zachowanie federowania instancji. Następujące zasady są włączone:",
+ "simple": {
+ "simple_policies": "Zasady specyficzne dla instancji",
+ "accept": "Akceptowanie",
+ "accept_desc": "Ta instancja akceptuje tylko posty z wymienionych instancji:",
+ "reject": "Odrzucanie",
+ "reject_desc": "Ta instancja odrzuca posty z wymienionych instancji:",
+ "quarantine": "Kwarantanna",
+ "quarantine_desc": "Ta instancja wysyła tylko publiczne posty do wymienionych instancji:",
+ "ftl_removal": "Usunięcie z \"Całej znanej sieci\"",
+ "ftl_removal_desc": "Ta instancja usuwa wymienionych instancje z \"Całej znanej sieci\":",
+ "media_removal": "Usuwanie multimediów",
+ "media_removal_desc": "Ta instancja usuwa multimedia z postów od wymienionych instancji:",
+ "media_nsfw": "Multimedia ustawione jako wrażliwe",
+ "media_nsfw_desc": "Ta instancja wymusza, by multimedia z wymienionych instancji były ustawione jako wrażliwe:"
+ }
+ },
+ "staff": "Administracja"
+ },
"chat": {
"title": "Czat"
},
+ "domain_mute_card": {
+ "mute": "Wycisz",
+ "mute_progress": "Wyciszam...",
+ "unmute": "Odcisz",
+ "unmute_progress": "Odciszam..."
+ },
+ "exporter": {
+ "export": "Eksportuj",
+ "processing": "Przetwarzam, za chwilę zostaniesz zapytany(-na) o ściągnięcie pliku"
+ },
"features_panel": {
"chat": "Czat",
"gopher": "Gopher",
@@ -20,7 +60,15 @@
"submit": "Wyślij",
"more": "Więcej",
"generic_error": "Wystąpił błąd",
- "optional": "nieobowiązkowe"
+ "optional": "nieobowiązkowe",
+ "show_more": "Pokaż więcej",
+ "show_less": "Pokaż mniej",
+ "dismiss": "Odrzuć",
+ "cancel": "Anuluj",
+ "disable": "Wyłącz",
+ "enable": "Włącz",
+ "confirm": "Potwierdź",
+ "verify": "Zweryfikuj"
},
"image_cropper": {
"crop_picture": "Przytnij obrazek",
@@ -28,6 +76,11 @@
"save_without_cropping": "Zapisz bez przycinania",
"cancel": "Anuluj"
},
+ "importer": {
+ "submit": "Wyślij",
+ "success": "Zaimportowano pomyślnie.",
+ "error": "Wystąpił błąd podczas importowania pliku."
+ },
"login": {
"login": "Zaloguj",
"description": "Zaloguj używając OAuth",
@@ -36,7 +89,15 @@
"placeholder": "n.p. lain",
"register": "Zarejestruj",
"username": "Użytkownik",
- "hint": "Zaloguj się, aby dołączyć do dyskusji"
+ "hint": "Zaloguj się, aby dołączyć do dyskusji",
+ "authentication_code": "Kod weryfikacyjny",
+ "enter_recovery_code": "Wprowadź kod zapasowy",
+ "enter_two_factor_code": "Wprowadź kod weryfikacyjny",
+ "recovery_code": "Kod zapasowy",
+ "heading": {
+ "totp": "Weryfikacja dwuetapowa",
+ "recovery": "Zapasowa weryfikacja dwuetapowa"
+ }
},
"media_modal": {
"previous": "Poprzednie",
@@ -44,15 +105,18 @@
},
"nav": {
"about": "O nas",
+ "administration": "Administracja",
"back": "Wróć",
"chat": "Lokalny czat",
"friend_requests": "Prośby o możliwość obserwacji",
"mentions": "Wzmianki",
+ "interactions": "Interakcje",
"dms": "Wiadomości prywatne",
"public_tl": "Publiczna oś czasu",
"timeline": "Oś czasu",
"twkn": "Cała znana sieć",
"user_search": "Wyszukiwanie użytkowników",
+ "search": "Wyszukiwanie",
"who_to_follow": "Sugestie obserwacji",
"preferences": "Preferencje"
},
@@ -64,7 +128,41 @@
"notifications": "Powiadomienia",
"read": "Przeczytane!",
"repeated_you": "powtórzył(-a) twój status",
- "no_more_notifications": "Nie masz więcej powiadomień"
+ "no_more_notifications": "Nie masz więcej powiadomień",
+ "migrated_to": "wyemigrował do",
+ "reacted_with": "zareagował z {0}",
+ "follow_request": "chce ciebie obserwować"
+ },
+ "polls": {
+ "add_poll": "Dodaj ankietę",
+ "add_option": "Dodaj opcję",
+ "option": "Opcja",
+ "votes": "głosów",
+ "vote": "Głosuj",
+ "type": "Typ ankiety",
+ "single_choice": "jednokrotnego wyboru",
+ "multiple_choices": "wielokrotnego wyboru",
+ "expiry": "Czas trwania ankiety",
+ "expires_in": "Ankieta kończy się za {0}",
+ "expired": "Ankieta skończyła się {0} temu",
+ "not_enough_options": "Zbyt mało unikalnych opcji w ankiecie"
+ },
+ "emoji": {
+ "stickers": "Naklejki",
+ "emoji": "Emoji",
+ "keep_open": "Zostaw selektor otwarty",
+ "search_emoji": "Wyszukaj emoji",
+ "add_emoji": "Wstaw emoji",
+ "custom": "Niestandardowe emoji",
+ "unicode": "Emoji unicode",
+ "load_all_hint": "Załadowano pierwsze {saneAmount} emoji, Załadowanie wszystkich emoji może spowodować problemy z wydajnością.",
+ "load_all": "Ładuję wszystkie {emojiAmount} emoji"
+ },
+ "interactions": {
+ "favs_repeats": "Powtórzenia i ulubione",
+ "follows": "Nowi obserwujący",
+ "moves": "Użytkownik migruje",
+ "load_older": "Załaduj starsze interakcje"
},
"post_status": {
"new_status": "Dodaj nowy status",
@@ -79,8 +177,14 @@
},
"content_warning": "Temat (nieobowiązkowy)",
"default": "Właśnie wróciłem z kościoła",
- "direct_warning": "Ten wpis zobaczą tylko osoby, o których wspomniałeś(-aś).",
+ "direct_warning_to_all": "Ten wpis zobaczą wszystkie osoby, o których wspomniałeś(-aś).",
+ "direct_warning_to_first_only": "Ten wpis zobaczą tylko te osoby, o których wspomniałeś(-aś) na początku wiadomości.",
"posting": "Wysyłanie",
+ "scope_notice": {
+ "public": "Ten post będzie widoczny dla każdego",
+ "private": "Ten post będzie widoczny tylko dla twoich obserwujących",
+ "unlisted": "Ten post nie będzie widoczny na publicznej osi czasu i całej znanej sieci"
+ },
"scope": {
"direct": "Bezpośredni – Tylko dla wspomnianych użytkowników",
"private": "Tylko dla obserwujących – Umieść dla osób, które cię obserwują",
@@ -109,8 +213,40 @@
"password_confirmation_match": "musi być takie jak hasło"
}
},
+ "remote_user_resolver": {
+ "remote_user_resolver": "Wyszukiwarka użytkowników nietutejszych",
+ "searching_for": "Szukam",
+ "error": "Nie znaleziono."
+ },
+ "selectable_list": {
+ "select_all": "Zaznacz wszystko"
+ },
"settings": {
"app_name": "Nazwa aplikacji",
+ "security": "Bezpieczeństwo",
+ "enter_current_password_to_confirm": "Wprowadź obecne hasło, by potwierdzić twoją tożsamość",
+ "mfa": {
+ "otp": "OTP",
+ "setup_otp": "Ustaw OTP",
+ "wait_pre_setup_otp": "początkowe ustawianie OTP",
+ "confirm_and_enable": "Potwierdź i włącz OTP",
+ "title": "Weryfikacja dwuetapowa",
+ "generate_new_recovery_codes": "Wygeneruj nowe kody zapasowe",
+ "warning_of_generate_new_codes": "Po tym gdy wygenerujesz nowe kody zapasowe, stare przestaną działać.",
+ "recovery_codes": "Kody zapasowe.",
+ "waiting_a_recovery_codes": "Otrzymuję kody zapasowe...",
+ "recovery_codes_warning": "Spisz kody na kartce papieru, albo zapisz je w bezpiecznym miejscu - inaczej nie zobaczysz ich już nigdy. Jeśli stracisz dostęp do twojej aplikacji 2FA i kodów zapasowych, nie będziesz miał(-a) dostępu do swojego konta.",
+ "authentication_methods": "Metody weryfikacji",
+ "scan": {
+ "title": "Skanuj",
+ "desc": "Zeskanuj ten kod QR używając twojej aplikacji 2FA albo wpisz ten klucz:",
+ "secret_code": "Klucz"
+ },
+ "verify": {
+ "desc": "By włączyć weryfikację dwuetapową, wpisz kod z twojej aplikacji 2FA:"
+ }
+ },
+ "allow_following_move": "Zezwalaj na automatyczną obserwację gdy obserwowane konto migruje",
"attachmentRadius": "Załączniki",
"attachments": "Załączniki",
"autoload": "Włącz automatyczne ładowanie po przewinięciu do końca strony",
@@ -119,12 +255,20 @@
"avatarRadius": "Awatary",
"background": "Tło",
"bio": "Bio",
+ "block_export": "Eksport blokad",
+ "block_export_button": "Eksportuj twoje blokady do pliku .csv",
+ "block_import": "Import blokad",
+ "block_import_error": "Wystąpił błąd podczas importowania blokad",
+ "blocks_imported": "Zaimportowano blokady, przetwarzanie może zająć trochę czasu.",
"blocks_tab": "Bloki",
"btnRadius": "Przyciski",
"cBlue": "Niebieski (odpowiedz, obserwuj)",
"cGreen": "Zielony (powtórzenia)",
"cOrange": "Pomarańczowy (ulubione)",
"cRed": "Czerwony (anuluj)",
+ "change_email": "Zmień email",
+ "change_email_error": "Wystąpił problem podczas zmiany emaila.",
+ "changed_email": "Pomyślnie zmieniono email!",
"change_password": "Zmień hasło",
"change_password_error": "Podczas zmiany hasła wystąpił problem.",
"changed_password": "Pomyślnie zmieniono hasło!",
@@ -137,19 +281,23 @@
"data_import_export_tab": "Import/eksport danych",
"default_vis": "Domyślny zakres widoczności",
"delete_account": "Usuń konto",
- "delete_account_description": "Trwale usuń konto i wszystkie posty.",
+ "delete_account_description": "Trwale usuń dane i zdezaktywuj konto.",
"delete_account_error": "Wystąpił problem z usuwaniem twojego konta. Jeżeli problem powtarza się, poinformuj administratora swojej instancji.",
"delete_account_instructions": "Wprowadź swoje hasło w poniższe pole aby potwierdzić usunięcie konta.",
+ "discoverable": "Zezwól na odkrywanie tego konta w wynikach wyszukiwania i innych usługach",
+ "domain_mutes": "Domeny",
"avatar_size_instruction": "Zalecany minimalny rozmiar awatarów to 150x150 pikseli.",
+ "pad_emoji": "Dodaj odstęp z obu stron emoji podczas dodawania selektorem",
+ "emoji_reactions_on_timeline": "Pokaż reakcje emoji na osi czasu",
"export_theme": "Zapisz motyw",
"filtering": "Filtrowanie",
"filtering_explanation": "Wszystkie statusy zawierające te słowa będą wyciszone. Jedno słowo na linijkę.",
"follow_export": "Eksport obserwowanych",
"follow_export_button": "Eksportuj swoją listę obserwowanych do pliku CSV",
- "follow_export_processing": "Przetwarzanie, wkrótce twój plik zacznie się ściągać.",
"follow_import": "Import obserwowanych",
"follow_import_error": "Błąd przy importowaniu obserwowanych",
"follows_imported": "Obserwowani zaimportowani! Przetwarzanie może trochę potrwać.",
+ "accent": "Akcent",
"foreground": "Pierwszy plan",
"general": "Ogólne",
"hide_attachments_in_convo": "Ukrywaj załączniki w rozmowach",
@@ -162,18 +310,19 @@
"hide_post_stats": "Ukrywaj statysyki postów (np. liczbę polubień)",
"hide_user_stats": "Ukrywaj statysyki użytkowników (np. liczbę obserwujących)",
"hide_filtered_statuses": "Ukrywaj filtrowane statusy",
+ "import_blocks_from_a_csv_file": "Importuj blokady z pliku CSV",
"import_followers_from_a_csv_file": "Importuj obserwowanych z pliku CSV",
"import_theme": "Załaduj motyw",
"inputRadius": "Pola tekstowe",
"checkboxRadius": "Pola wyboru",
- "instance_default": "(domyślny: {value})",
- "instance_default_simple": "(domyślny)",
+ "instance_default": "(domyślnie: {value})",
+ "instance_default_simple": "(domyślne)",
"interface": "Interfejs",
"interfaceLanguage": "Język interfejsu",
"invalid_theme_imported": "Wybrany plik nie jest obsługiwanym motywem Pleromy. Nie dokonano zmian w twoim motywie.",
"limited_availability": "Niedostępne w twojej przeglądarce",
"links": "Łącza",
- "lock_account_description": "Ogranicz swoje konto dla zatwierdzonych obserwowanych",
+ "lock_account_description": "Spraw, by konto mogli wyświetlać tylko zatwierdzeni obserwujący",
"loop_video": "Zapętlaj filmy",
"loop_video_silent_only": "Zapętlaj tylko filmy bez dźwięku (np. mastodonowe „gify”)",
"mutes_tab": "Wyciszenia",
@@ -181,17 +330,22 @@
"use_contain_fit": "Nie przycinaj załączników na miniaturach",
"name": "Imię",
"name_bio": "Imię i bio",
+ "new_email": "Nowy email",
"new_password": "Nowe hasło",
"notification_visibility": "Rodzaje powiadomień do wyświetlania",
"notification_visibility_follows": "Obserwacje",
"notification_visibility_likes": "Ulubione",
"notification_visibility_mentions": "Wzmianki",
"notification_visibility_repeats": "Powtórzenia",
+ "notification_visibility_moves": "Użytkownik migruje",
+ "notification_visibility_emoji_reactions": "Reakcje",
"no_rich_text_description": "Usuwaj formatowanie ze wszystkich postów",
"no_blocks": "Bez blokad",
"no_mutes": "Bez wyciszeń",
"hide_follows_description": "Nie pokazuj kogo obserwuję",
"hide_followers_description": "Nie pokazuj kto mnie obserwuje",
+ "hide_follows_count_description": "Nie pokazuj licznika obserwowanych",
+ "hide_followers_count_description": "Nie pokazuj licznika obserwujących",
"show_admin_badge": "Pokazuj odznakę Administrator na moim profilu",
"show_moderator_badge": "Pokazuj odznakę Moderator na moim profilu",
"nsfw_clickthrough": "Włącz domyślne ukrywanie załączników o treści nieprzyzwoitej (NSFW)",
@@ -212,10 +366,14 @@
"reply_visibility_all": "Pokazuj wszystkie odpowiedzi",
"reply_visibility_following": "Pokazuj tylko odpowiedzi skierowane do mnie i osób które obserwuję",
"reply_visibility_self": "Pokazuj tylko odpowiedzi skierowane do mnie",
+ "autohide_floating_post_button": "Ukryj automatycznie przycisk \"Nowy post\" (mobile)",
"saving_err": "Nie udało się zapisać ustawień",
"saving_ok": "Zapisano ustawienia",
+ "search_user_to_block": "Wyszukaj kogo chcesz zablokować",
+ "search_user_to_mute": "Wyszukaj kogo chcesz wyciszyć",
"security_tab": "Bezpieczeństwo",
"scope_copy": "Kopiuj zakres podczas odpowiadania (DM-y zawsze są kopiowane)",
+ "minimal_scopes_mode": "Zminimalizuj opcje wyboru zakresu postów",
"set_new_avatar": "Ustaw nowy awatar",
"set_new_profile_background": "Ustaw nowe tło profilu",
"set_new_profile_banner": "Ustaw nowy banner profilu",
@@ -228,19 +386,32 @@
"post_status_content_type": "Post status content type",
"stop_gifs": "Odtwarzaj GIFy po najechaniu kursorem",
"streaming": "Włącz automatycznie strumieniowanie nowych postów gdy jesteś na początku strony",
+ "user_mutes": "Użytkownicy",
+ "useStreamingApi": "Otrzymuj posty i powiadomienia w czasie rzeczywistym",
+ "useStreamingApiWarning": "(Niezalecane, eksperymentalne, pomija posty)",
"text": "Tekst",
"theme": "Motyw",
"theme_help": "Użyj kolorów w notacji szesnastkowej (#rrggbb), by stworzyć swój motyw.",
"theme_help_v2_1": "Możesz też zastąpić kolory i widoczność poszczególnych komponentów przełączając pola wyboru, użyj „Wyczyść wszystko” aby usunąć wszystkie zastąpienia.",
"theme_help_v2_2": "Ikony pod niektórych wpisami są wskaźnikami kontrastu pomiędzy tłem a tekstem, po najechaniu na nie otrzymasz szczegółowe informacje. Zapamiętaj, że jeżeli używasz przezroczystości, wskaźniki pokazują najgorszy możliwy przypadek.",
"tooltipRadius": "Etykiety/alerty",
+ "type_domains_to_mute": "Wpisz domeny, które chcesz wyciszyć",
"upload_a_photo": "Wyślij zdjęcie",
"user_settings": "Ustawienia użytkownika",
"values": {
"false": "nie",
"true": "tak"
},
+ "fun": "Zabawa",
+ "greentext": "Memiczne strzałki",
"notifications": "Powiadomienia",
+ "notification_setting": "Otrzymuj powiadomienia od:",
+ "notification_setting_follows": "Ludzi których obserwujesz",
+ "notification_setting_non_follows": "Ludzi których nie obserwujesz",
+ "notification_setting_followers": "Ludzi którzy obserwują ciebie",
+ "notification_setting_non_followers": "Ludzi którzy nie obserwują ciebie",
+ "notification_mutes": "By przestać otrzymywać powiadomienia od jednego użytkownika, wycisz go.",
+ "notification_blocks": "Blokowanie uzytkownika zatrzymuje wszystkie powiadomienia i odsubskrybowuje go.",
"enable_web_push_notifications": "Włącz powiadomienia push",
"style": {
"switcher": {
@@ -249,10 +420,27 @@
"keep_opacity": "Zachowaj widoczność",
"keep_roundness": "Zachowaj zaokrąglenie",
"keep_fonts": "Zachowaj czcionki",
- "save_load_hint": "Opcje „zachowaj” pozwalają na pozostanie przy obecnych opcjach po wybraniu lub załadowaniu motywu, jak i przechowywanie ich podczas eksportowania motywu. Jeżeli wszystkie są odznaczone, eksportowanie motywu spowoduje zapisanie wszystkiego.",
+ "save_load_hint": "Opcje „zachowaj” pozwalają na pozostanie przy obecnych opcjach po wybraniu lub załadowaniu motywu, jak i przechowywanie ich podczas eksportowania motywu. Jeżeli wszystkie opcje są odznaczone, eksportowanie motywu spowoduje zapisanie wszystkiego.",
"reset": "Wyzeruj",
"clear_all": "Wyczyść wszystko",
- "clear_opacity": "Wyczyść widoczność"
+ "clear_opacity": "Wyczyść widoczność",
+ "load_theme": "Załaduj motyw",
+ "keep_as_is": "Zostaw po staremu",
+ "use_snapshot": "Stara wersja",
+ "use_source": "Nowa wersja",
+ "help": {
+ "upgraded_from_v2": "PleromaFE zostało zaaktualizowane, motyw może wyglądać nieco inaczej niż zapamiętałeś(-aś).",
+ "v2_imported": "Plik który zaimportowałeś(-aś) został stworzony dla starszego FE. Próbujemy zwiększyć kompatybilność, lecz wciąż mogą występować rozbieżności.",
+ "future_version_imported": "Plik który zaimportowałeś(-aś) został stworzony w nowszej wersji FE.",
+ "older_version_imported": "Plik który zaimportowałeś(-aś) został stworzony w starszej wersji FE.",
+ "snapshot_present": "Migawka motywu jest załadowana, więc wszystkie wartości zostały nadpisane. Zamiast tego możesz załadować właściwe dane motywu.",
+ "snapshot_missing": "Nie znaleziono migawki motywu w pliku, więc motyw może wyglądać inaczej niż pierwotnie zaplanowano.",
+ "fe_upgraded": "Silnik motywów PleromaFE został zaaktualizowany.",
+ "fe_downgraded": "Wersja PleromaFE została cofnięta.",
+ "migration_snapshot_ok": "Żeby być bezpiecznym, migawka motywu została załadowana. Możesz spróbować załadować dane motywu.",
+ "migration_napshot_gone": "Z jakiegoś powodu migawka zniknęła, niektóre rzeczy mogą wyglądać inaczej niż zapamiętałeś(-aś).",
+ "snapshot_source_mismatch": "Konflikt wersji: najprawdopodobniej FE zostało cofnięte do poprzedniej wersji i zaktualizowane ponownie, jeśli zmieniłeś(-aś) motyw używając starszej wersji FE, najprawdopodobniej chcesz używać starszej wersji, w przeciwnym razie użyj nowej wersji."
+ }
},
"common": {
"color": "Kolor",
@@ -280,14 +468,28 @@
"_tab_label": "Zaawansowane",
"alert": "Tło alertu",
"alert_error": "Błąd",
+ "alert_warning": "Ostrzeżenie",
+ "alert_neutral": "Neutralne",
+ "post": "Posty/Bio użytkowników",
"badge": "Tło odznaki",
+ "popover": "Etykiety, menu, popovery",
"badge_notification": "Powiadomienie",
"panel_header": "Nagłówek panelu",
"top_bar": "Górny pasek",
"borders": "Granice",
"buttons": "Przyciski",
"inputs": "Pola wejścia",
- "faint_text": "Zanikający tekst"
+ "faint_text": "Zanikający tekst",
+ "underlay": "Podkład",
+ "poll": "Wykres ankiety",
+ "icons": "Ikony",
+ "highlight": "Podświetlone elementy",
+ "pressed": "Naciśnięte",
+ "selectedPost": "Wybrany post",
+ "selectedMenu": "Wybrany element menu",
+ "disabled": "Wyłączone",
+ "toggled": "Przełączone",
+ "tabs": "Karty"
},
"radii": {
"_tab_label": "Zaokrąglenie"
@@ -300,11 +502,11 @@
"blur": "Rozmycie",
"spread": "Szerokość",
"inset": "Inset",
- "hint": "Możesz też używać --zmiennych jako kolorów, aby wykorzystać zmienne CSS3. Pamiętaj, że ustawienie widoczności nie będzie wtedy działać.",
+ "hintV3": "Dla cieni możesz również użyć notacji {0} by użyć inny slot koloru.",
"filter_hint": {
"always_drop_shadow": "Ostrzeżenie, ten cień zawsze używa {0} jeżeli to obsługiwane przez przeglądarkę.",
"drop_shadow_syntax": "{0} nie obsługuje parametru {1} i słowa kluczowego {2}.",
- "avatar_inset": "Pamiętaj że użycie jednocześnie cieni inset i nie inset na awatarach może daćnieoczekiwane wyniki z przezroczystymi awatarami.",
+ "avatar_inset": "Pamiętaj że użycie jednocześnie cieni inset i nie inset na awatarach może dać nieoczekiwane wyniki z przezroczystymi awatarami.",
"spread_zero": "Cienie o ujemnej szerokości będą widoczne tak, jakby wynosiła ona zero",
"inset_classic": "Cienie inset będą używały {0}"
},
@@ -347,7 +549,7 @@
"faint_link": "pomocny podręcznik",
"fine_print": "Przeczytaj nasz {0}, aby nie nauczyć się niczego przydatnego!",
"header_faint": "W porządku",
- "checkbox": "Przeleciałem przez zasady użytkowania",
+ "checkbox": "Przeleciałem(-am) przez zasady użytkowania",
"link": "i fajny mały odnośnik"
}
},
@@ -355,7 +557,44 @@
"title": "Wersja",
"backend_version": "Wersja back-endu",
"frontend_version": "Wersja front-endu"
- }
+ },
+ "notification_setting_privacy": "Prywatność",
+ "notification_setting_filters": "Filtry",
+ "notification_setting_privacy_option": "Ukryj nadawcę i zawartość powiadomień push"
+ },
+ "time": {
+ "day": "{0} dzień",
+ "days": "{0} dni",
+ "day_short": "{0} d",
+ "days_short": "{0} d",
+ "hour": "{0} godzina",
+ "hours": "{0} godzin",
+ "hour_short": "{0} godz.",
+ "hours_short": "{0} godz.",
+ "in_future": "za {0}",
+ "in_past": "{0} temu",
+ "minute": "{0} minuta",
+ "minutes": "{0} minut",
+ "minute_short": "{0} min",
+ "minutes_short": "{0} min",
+ "month": "{0} miesiąc",
+ "months": "{0} miesięcy",
+ "month_short": "{0} mies.",
+ "months_short": "{0} mies.",
+ "now": "teraz",
+ "now_short": "teraz",
+ "second": "{0} sekunda",
+ "seconds": "{0} sekund",
+ "second_short": "{0} s",
+ "seconds_short": "{0} s",
+ "week": "{0} tydzień",
+ "weeks": "{0} tygodni",
+ "week_short": "{0} tydz.",
+ "weeks_short": "{0} tyg.",
+ "year": "{0} rok",
+ "years": "{0} lata",
+ "year_short": "{0} r.",
+ "years_short": "{0} lata"
},
"timeline": {
"collapse": "Zwiń",
@@ -370,8 +609,19 @@
"no_statuses": "Brak statusów"
},
"status": {
+ "favorites": "Ulubione",
+ "repeats": "Powtórzenia",
+ "delete": "Usuń status",
+ "pin": "Przypnij na profilu",
+ "unpin": "Odepnij z profilu",
+ "pinned": "Przypnięte",
+ "delete_confirm": "Czy naprawdę chcesz usunąć ten status?",
"reply_to": "Odpowiedź dla",
- "replies_list": "Odpowiedzi:"
+ "replies_list": "Odpowiedzi:",
+ "mute_conversation": "Wycisz konwersację",
+ "unmute_conversation": "Odcisz konwersację",
+ "status_unavailable": "Status niedostępny",
+ "copy_link": "Kopiuj link do statusu"
},
"user_card": {
"approve": "Przyjmij",
@@ -388,25 +638,60 @@
"followers": "Obserwujący",
"following": "Obserwowany!",
"follows_you": "Obserwuje cię!",
+ "hidden": "Ukryte",
"its_you": "To ty!",
"media": "Media",
+ "mention": "Wspomnienie",
"mute": "Wycisz",
"muted": "Wyciszony(-a)",
"per_day": "dziennie",
"remote_follow": "Zdalna obserwacja",
+ "report": "Zgłoś",
"statuses": "Statusy",
+ "subscribe": "Subskrybuj",
+ "unsubscribe": "Odsubskrybuj",
"unblock": "Odblokuj",
"unblock_progress": "Odblokowuję…",
"block_progress": "Blokuję…",
"unmute": "Cofnij wyciszenie",
"unmute_progress": "Cofam wyciszenie…",
- "mute_progress": "Wyciszam…"
+ "mute_progress": "Wyciszam…",
+ "hide_repeats": "Ukryj powtórzenia",
+ "show_repeats": "Pokaż powtórzenia",
+ "admin_menu": {
+ "moderation": "Moderacja",
+ "grant_admin": "Przyznaj admina",
+ "revoke_admin": "Odwołaj admina",
+ "grant_moderator": "Przyznaj moderatora",
+ "revoke_moderator": "Odwołaj moderatora",
+ "activate_account": "Aktywuj konto",
+ "deactivate_account": "Dezaktywuj konto",
+ "delete_account": "Usuń konto",
+ "force_nsfw": "Oznacz wszystkie posty jako NSFW",
+ "strip_media": "Usuń multimedia z postów",
+ "force_unlisted": "Wymuś posty na niepubliczne",
+ "sandbox": "Wymuś by posty były tylko dla obserwujących",
+ "disable_remote_subscription": "Zakaż obserwowania użytkownika ze zdalnych instancji",
+ "disable_any_subscription": "Zakaż całkowicie obserwowania użytkownika",
+ "quarantine": "Zakaż federowania postów od tego użytkownika",
+ "delete_user": "Usuń użytkownika",
+ "delete_user_confirmation": "Czy jesteś absolutnie pewny(-a)? Ta operacja nie może być cofnięta."
+ }
},
"user_profile": {
"timeline_title": "Oś czasu użytkownika",
"profile_does_not_exist": "Przepraszamy, ten profil nie istnieje.",
"profile_loading_error": "Przepraszamy, wystąpił błąd podczas ładowania tego profilu."
},
+ "user_reporting": {
+ "title": "Raportowanie {0}",
+ "add_comment_description": "Zgłoszenie zostanie wysłane do moderatorów instancji. Możesz dodać powód dlaczego zgłaszasz owe konto poniżej:",
+ "additional_comments": "Dodatkowe komentarze",
+ "forward_description": "To konto jest z innego serwera. Wysłać również tam kopię zgłoszenia?",
+ "forward_to": "Przekaż do {0}",
+ "submit": "Wyślij",
+ "generic_error": "Wystąpił błąd podczas przetwarzania twojej prośby."
+ },
"who_to_follow": {
"more": "Więcej",
"who_to_follow": "Propozycje obserwacji"
@@ -416,9 +701,12 @@
"repeat": "Powtórz",
"reply": "Odpowiedz",
"favorite": "Dodaj do ulubionych",
- "user_settings": "Ustawienia użytkownika"
+ "add_reaction": "Dodaj reakcję",
+ "user_settings": "Ustawienia użytkownika",
+ "accept_follow_request": "Akceptuj prośbę o możliwość obserwacji",
+ "reject_follow_request": "Odrzuć prośbę o możliwość obserwacji"
},
- "upload":{
+ "upload": {
"error": {
"base": "Wysyłanie nie powiodło się.",
"file_too_big": "Zbyt duży plik [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
@@ -431,5 +719,25 @@
"GiB": "GiB",
"TiB": "TiB"
}
+ },
+ "search": {
+ "people": "Ludzie",
+ "hashtags": "Hasztagi",
+ "person_talking": "{count} osoba rozmawia o tym",
+ "people_talking": "{count} osób rozmawia o tym",
+ "no_results": "Brak wyników"
+ },
+ "password_reset": {
+ "forgot_password": "Zapomniałeś(-aś) hasła?",
+ "password_reset": "Reset hasła",
+ "instruction": "Wprowadź swój adres email lub nazwę użytkownika. Wyślemy ci link z którym możesz zresetować hasło.",
+ "placeholder": "Twój email lub nazwa użytkownika",
+ "check_email": "Sprawdź pocztę, aby uzyskać link do zresetowania hasła.",
+ "return_home": "Wróć do strony głównej",
+ "not_found": "Nie mogliśmy znaleźć tego emaila lub nazwy użytkownika.",
+ "too_many_requests": "Przekroczyłeś(-aś) limit prób, spróbuj ponownie później.",
+ "password_reset_disabled": "Resetowanie hasła jest wyłączone. Proszę skontaktuj się z administratorem tej instancji.",
+ "password_reset_required": "Musisz zresetować hasło, by się zalogować.",
+ "password_reset_required_but_mailer_is_disabled": "Musisz zresetować hasło, ale resetowanie hasła jest wyłączone. Proszę skontaktuj się z administratorem tej instancji."
}
}
diff --git a/src/i18n/ru.json b/src/i18n/ru.json
index 4cb2d497..f9a72954 100644
--- a/src/i18n/ru.json
+++ b/src/i18n/ru.json
@@ -13,7 +13,12 @@
"disable": "Оключить",
"enable": "Включить",
"confirm": "Подтвердить",
- "verify": "Проверить"
+ "verify": "Проверить",
+ "more": "Больше",
+ "generic_error": "Произошла ошибка",
+ "optional": "не обязательно",
+ "show_less": "Показать меньше",
+ "show_more": "Показать больше"
},
"login": {
"login": "Войти",
@@ -26,9 +31,9 @@
"enter_recovery_code": "Ввести код восстановления",
"enter_two_factor_code": "Ввести код аутентификации",
"recovery_code": "Код восстановления",
- "heading" : {
- "TotpForm" : "Двухфакторная аутентификация",
- "RecoveryForm" : "Two-factor recovery"
+ "heading": {
+ "TotpForm": "Двухфакторная аутентификация",
+ "RecoveryForm": "Two-factor recovery"
}
},
"nav": {
@@ -39,7 +44,8 @@
"public_tl": "Публичная лента",
"timeline": "Лента",
"twkn": "Федеративная лента",
- "search": "Поиск"
+ "search": "Поиск",
+ "friend_requests": "Запросы на чтение"
},
"notifications": {
"broken_favorite": "Неизвестный статус, ищем...",
@@ -48,7 +54,8 @@
"load_older": "Загрузить старые уведомления",
"notifications": "Уведомления",
"read": "Прочесть",
- "repeated_you": "повторил(а) ваш статус"
+ "repeated_you": "повторил(а) ваш статус",
+ "follow_request": "хочет читать вас"
},
"interactions": {
"favs_repeats": "Повторы и фавориты",
@@ -56,7 +63,7 @@
"load_older": "Загрузить старые взаимодействия"
},
"post_status": {
- "account_not_locked_warning": "Ваш аккаунт не {0}. Кто угодно может зафоловить вас чтобы прочитать посты только для подписчиков",
+ "account_not_locked_warning": "Ваш аккаунт не {0}. Кто угодно может начать читать вас чтобы видеть посты только для подписчиков.",
"account_not_locked_warning_link": "залочен",
"attachments_sensitive": "Вложения содержат чувствительный контент",
"content_warning": "Тема (не обязательно)",
@@ -94,17 +101,17 @@
"settings": {
"enter_current_password_to_confirm": "Введите свой текущий пароль",
"mfa": {
- "otp" : "OTP",
- "setup_otp" : "Настройка OTP",
- "wait_pre_setup_otp" : "предварительная настройка OTP",
- "confirm_and_enable" : "Подтвердить и включить OTP",
+ "otp": "OTP",
+ "setup_otp": "Настройка OTP",
+ "wait_pre_setup_otp": "предварительная настройка OTP",
+ "confirm_and_enable": "Подтвердить и включить OTP",
"title": "Двухфакторная аутентификация",
- "generate_new_recovery_codes" : "Получить новые коды востановления",
- "warning_of_generate_new_codes" : "После получения новых кодов восстановления, старые больше не будут работать.",
- "recovery_codes" : "Коды восстановления.",
+ "generate_new_recovery_codes": "Получить новые коды востановления",
+ "warning_of_generate_new_codes": "После получения новых кодов восстановления, старые больше не будут работать.",
+ "recovery_codes": "Коды восстановления.",
"waiting_a_recovery_codes": "Получение кодов восстановления ...",
- "recovery_codes_warning" : "Запишите эти коды и держите в безопасном месте - иначе вы их больше не увидите. Если вы потеряете доступ к OTP приложению - без резервных кодов вы больше не сможете залогиниться.",
- "authentication_methods" : "Методы аутентификации",
+ "recovery_codes_warning": "Запишите эти коды и держите в безопасном месте - иначе вы их больше не увидите. Если вы потеряете доступ к OTP приложению - без резервных кодов вы больше не сможете залогиниться.",
+ "authentication_methods": "Методы аутентификации",
"scan": {
"title": "Сканирование",
"desc": "Используйте приложение для двухэтапной аутентификации для сканирования этого QR-код или введите текстовый ключ:",
@@ -129,10 +136,10 @@
"cRed": "Отменить",
"change_email": "Сменить email",
"change_email_error": "Произошла ошибка при попытке изменить email.",
- "changed_email": "Email изменён успешно.",
+ "changed_email": "Email изменён успешно!",
"change_password": "Сменить пароль",
"change_password_error": "Произошла ошибка при попытке изменить пароль.",
- "changed_password": "Пароль изменён успешно.",
+ "changed_password": "Пароль изменён успешно!",
"collapse_subject": "Сворачивать посты с темой",
"confirm_new_password": "Подтверждение нового пароля",
"current_avatar": "Текущий аватар",
@@ -150,7 +157,7 @@
"follow_export_button": "Экспортировать читаемых в файл .csv",
"follow_export_processing": "Ведётся обработка, скоро вам будет предложено загрузить файл",
"follow_import": "Импортировать читаемых",
- "follow_import_error": "Ошибка при импортировании читаемых.",
+ "follow_import_error": "Ошибка при импортировании читаемых",
"follows_imported": "Список читаемых импортирован. Обработка займёт некоторое время..",
"foreground": "Передний план",
"general": "Общие",
@@ -204,7 +211,7 @@
"replies_in_timeline": "Ответы в ленте",
"reply_link_preview": "Включить предварительный просмотр ответа при наведении мыши",
"reply_visibility_all": "Показывать все ответы",
- "reply_visibility_following": "Показывать только ответы мне и тех на кого я подписан",
+ "reply_visibility_following": "Показывать только ответы мне или тех на кого я подписан",
"reply_visibility_self": "Показывать только ответы мне",
"autohide_floating_post_button": "Автоматически скрывать кнопку постинга (в мобильной версии)",
"saving_err": "Не удалось сохранить настройки",
@@ -224,7 +231,7 @@
"text": "Текст",
"theme": "Тема",
"theme_help": "Используйте шестнадцатеричные коды цветов (#rrggbb) для настройки темы.",
- "theme_help_v2_1": "Вы так же можете перепоределить цвета определенных компонентов нажав соотв. галочку. Используйте кнопку \"Очистить всё\" чтобы снять все переопределения",
+ "theme_help_v2_1": "Вы так же можете перепоределить цвета определенных компонентов нажав соотв. галочку. Используйте кнопку \"Очистить всё\" чтобы снять все переопределения.",
"theme_help_v2_2": "Под некоторыми полями ввода это идикаторы контрастности, наведите на них мышью чтобы узнать больше. Приспользовании прозрачности контраст расчитывается для наихудшего варианта.",
"tooltipRadius": "Всплывающие подсказки/уведомления",
"user_settings": "Настройки пользователя",
@@ -292,9 +299,9 @@
"inset": "Внутренняя",
"hint": "Для теней вы так же можете использовать --variable в качестве цвета чтобы использовать CSS3-переменные. В таком случае прозрачность работать не будет.",
"filter_hint": {
- "always_drop_shadow": "Внимание, эта тень всегда использует {0} когда браузер поддерживает это",
- "drop_shadow_syntax": "{0} не поддерживает параметр {1} и ключевое слово {2}",
- "avatar_inset": "Одновременное использование внутренних и внешних теней на (прозрачных) аватарках может дать не те результаты что вы ожидаете",
+ "always_drop_shadow": "Внимание, эта тень всегда использует {0} когда браузер поддерживает это.",
+ "drop_shadow_syntax": "{0} не поддерживает параметр {1} и ключевое слово {2}.",
+ "avatar_inset": "Одновременное использование внутренних и внешних теней на (прозрачных) аватарках может дать не те результаты что вы ожидаете.",
"spread_zero": "Тени с разбросом > 0 будут выглядеть как если бы разброс установлен в 0",
"inset_classic": "Внутренние тени будут использовать {0}"
},
@@ -340,7 +347,13 @@
"checkbox": "Я подтверждаю что не было ни единого разрыва",
"link": "ссылка"
}
- }
+ },
+ "notification_setting_non_followers": "Не читающие вас",
+ "allow_following_move": "Разрешить автоматически читать новый аккаунт при перемещении на другой сервер",
+ "hide_user_stats": "Не показывать статистику пользователей (например количество читателей)",
+ "notification_setting_followers": "Читающие вас",
+ "notification_setting_follows": "Читаемые вами",
+ "notification_setting_non_follows": "Не читаемые вами"
},
"timeline": {
"collapse": "Свернуть",
@@ -359,12 +372,12 @@
"follow": "Читать",
"follow_sent": "Запрос отправлен!",
"follow_progress": "Запрашиваем…",
- "follow_again": "Запросить еще заново?",
+ "follow_again": "Запросить еще раз?",
"follow_unfollow": "Перестать читать",
"followees": "Читаемые",
"followers": "Читатели",
- "following": "Читаю",
- "follows_you": "Читает вас",
+ "following": "Читаю!",
+ "follows_you": "Читает вас!",
"mute": "Игнорировать",
"muted": "Игнорирую",
"per_day": "в день",
@@ -382,9 +395,9 @@
"force_nsfw": "Отмечать посты пользователя как NSFW",
"strip_media": "Убирать вложения из постов пользователя",
"force_unlisted": "Не добавлять посты в публичные ленты",
- "sandbox": "Посты доступны только для подписчиков",
- "disable_remote_subscription": "Запретить подписываться с удаленных серверов",
- "disable_any_subscription": "Запретить подписываться на пользователя",
+ "sandbox": "Принудить видимость постов только читателям",
+ "disable_remote_subscription": "Запретить читать с удаленных серверов",
+ "disable_any_subscription": "Запретить читать пользователя",
"quarantine": "Не федерировать посты пользователя",
"delete_user": "Удалить пользователя",
"delete_user_confirmation": "Вы уверены? Это действие нельзя отменить."
@@ -410,5 +423,56 @@
"not_found": "Мы не смогли найти аккаунт с таким email-ом или именем пользователя.",
"too_many_requests": "Вы исчерпали допустимое количество попыток, попробуйте позже.",
"password_reset_disabled": "Сброс пароля отключен. Cвяжитесь с администратором вашего сервера."
+ },
+ "about": {
+ "mrf": {
+ "federation": "Федерация",
+ "simple": {
+ "accept_desc": "Данный сервер принимает сообщения только со следующих серверов:",
+ "ftl_removal_desc": "Данный сервер скрывает следующие сервера с федеративной ленты:",
+ "media_nsfw_desc": "Данный сервер принужденно помечает вложения со следущих серверов как NSFW:",
+ "simple_policies": "Правила для определенных серверов",
+ "accept": "Принимаемые сообщения",
+ "reject": "Отклоняемые сообщения",
+ "reject_desc": "Данный сервер не принимает сообщения со следующих серверов:",
+ "quarantine": "Зона карантина",
+ "quarantine_desc": "Данный сервер отправляет только публичные посты следующим серверам:",
+ "ftl_removal": "Скрытие с федеративной ленты",
+ "media_removal": "Удаление вложений",
+ "media_removal_desc": "Данный сервер удаляет вложения со следующих серверов:",
+ "media_nsfw": "Принужденно помеченно как NSFW"
+ },
+ "keyword": {
+ "ftl_removal": "Убрать из федеративной ленты",
+ "reject": "Отклонить",
+ "keyword_policies": "Действия на ключевые слова",
+ "replace": "Заменить",
+ "is_replaced_by": "→"
+ },
+ "mrf_policies": "Активные правила MRF (модуль переписывания сообщений)",
+ "mrf_policies_desc": "Правила MRF (модуль переписывания сообщений) влияют на федерацию данного сервера. Следующие правила активны:"
+ },
+ "staff": "Администрация"
+ },
+ "domain_mute_card": {
+ "mute": "Игнорировать",
+ "mute_progress": "В процессе…",
+ "unmute": "Прекратить игнорирование",
+ "unmute_progress": "В процессе…"
+ },
+ "exporter": {
+ "export": "Экспорт",
+ "processing": "Запрос в обработке, вам скоро будет предложено загрузить файл"
+ },
+ "features_panel": {
+ "chat": "Чат",
+ "media_proxy": "Прокси для внешних вложений",
+ "text_limit": "Лимит символов",
+ "title": "Особенности",
+ "gopher": "Gopher"
+ },
+ "tool_tip": {
+ "accept_follow_request": "Принять запрос на чтение",
+ "reject_follow_request": "Отклонить запрос на чтение"
}
}
diff --git a/src/i18n/te.json b/src/i18n/te.json
index f0953d97..6022349d 100644
--- a/src/i18n/te.json
+++ b/src/i18n/te.json
@@ -1,352 +1,352 @@
{
- "chat.title": "చాట్",
- "features_panel.chat": "చాట్",
- "features_panel.gopher": "గోఫర్",
- "features_panel.media_proxy": "మీడియా ప్రాక్సీ",
- "features_panel.scope_options": "స్కోప్ ఎంపికలు",
- "features_panel.text_limit": "వచన పరిమితి",
- "features_panel.title": "లక్షణాలు",
- "features_panel.who_to_follow": "ఎవరిని అనుసరించాలి",
- "finder.error_fetching_user": "వినియోగదారుని పొందడంలో లోపం",
- "finder.find_user": "వినియోగదారుని కనుగొనండి",
- "general.apply": "వర్తించు",
- "general.submit": "సమర్పించు",
- "general.more": "మరిన్ని",
- "general.generic_error": "ఒక తప్పిదం సంభవించినది",
- "general.optional": "ఐచ్చికం",
- "image_cropper.crop_picture": "చిత్రాన్ని కత్తిరించండి",
- "image_cropper.save": "దాచు",
- "image_cropper.save_without_cropping": "కత్తిరించకుండా సేవ్ చేయి",
- "image_cropper.cancel": "రద్దుచేయి",
- "login.login": "లాగిన్",
- "login.description": "OAuth తో లాగిన్ అవ్వండి",
- "login.logout": "లాగౌట్",
- "login.password": "సంకేతపదము",
- "login.placeholder": "ఉదా. lain",
- "login.register": "నమోదు చేసుకోండి",
- "login.username": "వాడుకరి పేరు",
- "login.hint": "చర్చలో చేరడానికి లాగిన్ అవ్వండి",
- "media_modal.previous": "ముందరి పుట",
- "media_modal.next": "తరువాత",
- "nav.about": "గురించి",
- "nav.back": "వెనక్కి",
- "nav.chat": "స్థానిక చాట్",
- "nav.friend_requests": "అనుసరించడానికి అభ్యర్థనలు",
- "nav.mentions": "ప్రస్తావనలు",
- "nav.dms": "నేరుగా పంపిన సందేశాలు",
- "nav.public_tl": "ప్రజా కాలక్రమం",
- "nav.timeline": "కాలక్రమం",
- "nav.twkn": "మొత్తం తెలిసిన నెట్వర్క్",
- "nav.user_search": "వాడుకరి శోధన",
- "nav.who_to_follow": "ఎవరిని అనుసరించాలి",
- "nav.preferences": "ప్రాధాన్యతలు",
- "notifications.broken_favorite": "తెలియని స్థితి, దాని కోసం శోధిస్తోంది...",
- "notifications.favorited_you": "మీ స్థితిని ఇష్టపడ్డారు",
- "notifications.followed_you": "మిమ్మల్ని అనుసరించారు",
- "notifications.load_older": "పాత నోటిఫికేషన్లను లోడ్ చేయండి",
- "notifications.notifications": "ప్రకటనలు",
- "notifications.read": "చదివాను!",
- "notifications.repeated_you": "మీ స్థితిని పునరావృతం చేసారు",
- "notifications.no_more_notifications": "ఇక నోటిఫికేషన్లు లేవు",
- "post_status.new_status": "క్రొత్త స్థితిని పోస్ట్ చేయండి",
- "post_status.account_not_locked_warning": "మీ ఖాతా {౦} కాదు. ఎవరైనా మిమ్మల్ని అనుసరించి అనుచరులకు మాత్రమే ఉద్దేశించిన పోస్టులను చూడవచ్చు.",
- "post_status.account_not_locked_warning_link": "తాళం వేయబడినది",
- "post_status.attachments_sensitive": "జోడింపులను సున్నితమైనవిగా గుర్తించండి",
- "post_status.content_type.text/plain": "సాధారణ అక్షరాలు",
- "post_status.content_type.text/html": "హెచ్టిఎమ్ఎల్",
- "post_status.content_type.text/markdown": "మార్క్డౌన్",
- "post_status.content_warning": "విషయం (ఐచ్ఛికం)",
- "post_status.default": "ఇప్పుడే విజయవాడలో దిగాను.",
- "post_status.direct_warning": "ఈ పోస్ట్ మాత్రమే పేర్కొన్న వినియోగదారులకు మాత్రమే కనిపిస్తుంది.",
- "post_status.posting": "పోస్ట్ చేస్తున్నా",
- "post_status.scope.direct": "ప్రత్యక్ష - పేర్కొన్న వినియోగదారులకు మాత్రమే పోస్ట్ చేయబడుతుంది",
- "post_status.scope.private": "అనుచరులకు మాత్రమే - అనుచరులకు మాత్రమే పోస్ట్ చేయబడుతుంది",
- "post_status.scope.public": "పబ్లిక్ - ప్రజా కాలక్రమాలకు పోస్ట్ చేయబడుతుంది",
- "post_status.scope.unlisted": "జాబితా చేయబడనిది - ప్రజా కాలక్రమాలకు పోస్ట్ చేయవద్దు",
- "registration.bio": "బయో",
- "registration.email": "ఈ మెయిల్",
- "registration.fullname": "ప్రదర్శన పేరు",
- "registration.password_confirm": "పాస్వర్డ్ నిర్ధారణ",
- "registration.registration": "నమోదు",
- "registration.token": "ఆహ్వాన టోకెన్",
- "registration.captcha": "కాప్చా",
- "registration.new_captcha": "కొత్త కాప్చా పొందుటకు చిత్రం మీద క్లిక్ చేయండి",
- "registration.username_placeholder": "ఉదా. lain",
- "registration.fullname_placeholder": "ఉదా. Lain Iwakura",
- "registration.bio_placeholder": "e.g.\nHi, I'm Lain.\nI’m an anime girl living in suburban Japan. You may know me from the Wired.",
- "registration.validations.username_required": "ఖాళీగా విడిచిపెట్టరాదు",
- "registration.validations.fullname_required": "ఖాళీగా విడిచిపెట్టరాదు",
- "registration.validations.email_required": "ఖాళీగా విడిచిపెట్టరాదు",
- "registration.validations.password_required": "ఖాళీగా విడిచిపెట్టరాదు",
- "registration.validations.password_confirmation_required": "ఖాళీగా విడిచిపెట్టరాదు",
- "registration.validations.password_confirmation_match": "సంకేతపదం వలె ఉండాలి",
- "settings.app_name": "అనువర్తన పేరు",
- "settings.attachmentRadius": "జోడింపులు",
- "settings.attachments": "జోడింపులు",
- "settings.autoload": "క్రిందికి స్క్రోల్ చేయబడినప్పుడు స్వయంచాలక లోడింగ్ని ప్రారంభించు",
- "settings.avatar": "అవతారం",
- "settings.avatarAltRadius": "అవతారాలు (ప్రకటనలు)",
- "settings.avatarRadius": "అవతారాలు",
- "settings.background": "బ్యాక్గ్రౌండు",
- "settings.bio": "బయో",
- "settings.blocks_tab": "బ్లాక్లు",
- "settings.btnRadius": "బటన్లు",
- "settings.cBlue": "నీలం (ప్రత్యుత్తరం, అనుసరించండి)",
- "settings.cGreen": "Green (Retweet)",
- "settings.cOrange": "ఆరెంజ్ (ఇష్టపడు)",
- "settings.cRed": "Red (Cancel)",
- "settings.change_password": "పాస్వర్డ్ మార్చండి",
- "settings.change_password_error": "మీ పాస్వర్డ్ను మార్చడంలో సమస్య ఉంది.",
- "settings.changed_password": "పాస్వర్డ్ విజయవంతంగా మార్చబడింది!",
- "settings.collapse_subject": "Collapse posts with subjects",
- "settings.composing": "Composing",
- "settings.confirm_new_password": "కొత్త పాస్వర్డ్ను నిర్ధారించండి",
- "settings.current_avatar": "మీ ప్రస్తుత అవతారం",
- "settings.current_password": "ప్రస్తుత పాస్వర్డ్",
- "settings.current_profile_banner": "మీ ప్రస్తుత ప్రొఫైల్ బ్యానర్",
- "settings.data_import_export_tab": "Data Import / Export",
- "settings.default_vis": "Default visibility scope",
- "settings.delete_account": "Delete Account",
- "settings.delete_account_description": "మీ ఖాతా మరియు మీ అన్ని సందేశాలను శాశ్వతంగా తొలగించండి.",
- "settings.delete_account_error": "There was an issue deleting your account. If this persists please contact your instance administrator.",
- "settings.delete_account_instructions": "ఖాతా తొలగింపును నిర్ధారించడానికి దిగువ ఇన్పుట్లో మీ పాస్వర్డ్ను టైప్ చేయండి.",
- "settings.avatar_size_instruction": "అవతార్ చిత్రాలకు సిఫార్సు చేసిన కనీస పరిమాణం 150x150 పిక్సెల్స్.",
- "settings.export_theme": "Save preset",
- "settings.filtering": "వడపోత",
- "settings.filtering_explanation": "All statuses containing these words will be muted, one per line",
- "settings.follow_export": "Follow export",
- "settings.follow_export_button": "Export your follows to a csv file",
- "settings.follow_export_processing": "Processing, you'll soon be asked to download your file",
- "settings.follow_import": "Follow import",
- "settings.follow_import_error": "అనుచరులను దిగుమతి చేయడంలో లోపం",
- "settings.follows_imported": "Follows imported! Processing them will take a while.",
- "settings.foreground": "Foreground",
- "settings.general": "General",
- "settings.hide_attachments_in_convo": "సంభాషణలలో జోడింపులను దాచు",
- "settings.hide_attachments_in_tl": "కాలక్రమంలో జోడింపులను దాచు",
- "settings.hide_muted_posts": "మ్యూట్ చేసిన వినియోగదారుల యొక్క పోస్ట్లను దాచిపెట్టు",
- "settings.max_thumbnails": "Maximum amount of thumbnails per post",
- "settings.hide_isp": "Hide instance-specific panel",
- "settings.preload_images": "Preload images",
- "settings.use_one_click_nsfw": "కేవలం ఒక క్లిక్ తో NSFW జోడింపులను తెరవండి",
- "settings.hide_post_stats": "Hide post statistics (e.g. the number of favorites)",
- "settings.hide_user_stats": "Hide user statistics (e.g. the number of followers)",
- "settings.hide_filtered_statuses": "Hide filtered statuses",
- "settings.import_followers_from_a_csv_file": "Import follows from a csv file",
- "settings.import_theme": "Load preset",
- "settings.inputRadius": "Input fields",
- "settings.checkboxRadius": "Checkboxes",
- "settings.instance_default": "(default: {value})",
- "settings.instance_default_simple": "(default)",
- "settings.interface": "Interface",
- "settings.interfaceLanguage": "Interface language",
- "settings.invalid_theme_imported": "The selected file is not a supported Pleroma theme. No changes to your theme were made.",
- "settings.limited_availability": "మీ బ్రౌజర్లో అందుబాటులో లేదు",
- "settings.links": "Links",
- "settings.lock_account_description": "మీ ఖాతాను ఆమోదించిన అనుచరులకు మాత్రమే పరిమితం చేయండి",
- "settings.loop_video": "Loop videos",
- "settings.loop_video_silent_only": "Loop only videos without sound (i.e. Mastodon's \"gifs\")",
- "settings.mutes_tab": "మ్యూట్ చేయబడినవి",
- "settings.play_videos_in_modal": "మీడియా వీక్షికలో నేరుగా వీడియోలను ప్లే చేయి",
- "settings.use_contain_fit": "అటాచ్మెంట్ సూక్ష్మచిత్రాలను కత్తిరించవద్దు",
- "settings.name": "Name",
- "settings.name_bio": "పేరు & బయో",
- "settings.new_password": "కొత్త సంకేతపదం",
- "settings.notification_visibility": "చూపించవలసిన నోటిఫికేషన్ రకాలు",
- "settings.notification_visibility_follows": "Follows",
- "settings.notification_visibility_likes": "ఇష్టాలు",
- "settings.notification_visibility_mentions": "ప్రస్తావనలు",
- "settings.notification_visibility_repeats": "పునఃప్రసారాలు",
- "settings.no_rich_text_description": "అన్ని పోస్ట్ల నుండి రిచ్ టెక్స్ట్ ఫార్మాటింగ్ను స్ట్రిప్ చేయండి",
- "settings.no_blocks": "బ్లాక్స్ లేవు",
- "settings.no_mutes": "మ్యూట్లు లేవు",
- "settings.hide_follows_description": "నేను ఎవరిని అనుసరిస్తున్నానో చూపించవద్దు",
- "settings.hide_followers_description": "నన్ను ఎవరు అనుసరిస్తున్నారో చూపవద్దు",
- "settings.show_admin_badge": "నా ప్రొఫైల్ లో అడ్మిన్ బ్యాడ్జ్ చూపించు",
- "settings.show_moderator_badge": "నా ప్రొఫైల్లో మోడరేటర్ బ్యాడ్జ్ని చూపించు",
- "settings.nsfw_clickthrough": "Enable clickthrough NSFW attachment hiding",
- "settings.oauth_tokens": "OAuth tokens",
- "settings.token": "Token",
- "settings.refresh_token": "Refresh Token",
- "settings.valid_until": "Valid Until",
- "settings.revoke_token": "Revoke",
- "settings.panelRadius": "Panels",
- "settings.pause_on_unfocused": "Pause streaming when tab is not focused",
- "settings.presets": "Presets",
- "settings.profile_background": "Profile Background",
- "settings.profile_banner": "Profile Banner",
- "settings.profile_tab": "Profile",
- "settings.radii_help": "Set up interface edge rounding (in pixels)",
- "settings.replies_in_timeline": "Replies in timeline",
- "settings.reply_link_preview": "Enable reply-link preview on mouse hover",
- "settings.reply_visibility_all": "Show all replies",
- "settings.reply_visibility_following": "Only show replies directed at me or users I'm following",
- "settings.reply_visibility_self": "Only show replies directed at me",
- "settings.saving_err": "Error saving settings",
- "settings.saving_ok": "Settings saved",
- "settings.security_tab": "Security",
- "settings.scope_copy": "Copy scope when replying (DMs are always copied)",
- "settings.set_new_avatar": "Set new avatar",
- "settings.set_new_profile_background": "Set new profile background",
- "settings.set_new_profile_banner": "Set new profile banner",
- "settings.settings": "Settings",
- "settings.subject_input_always_show": "Always show subject field",
- "settings.subject_line_behavior": "Copy subject when replying",
- "settings.subject_line_email": "Like email: \"re: subject\"",
- "settings.subject_line_mastodon": "Like mastodon: copy as is",
- "settings.subject_line_noop": "Do not copy",
- "settings.post_status_content_type": "Post status content type",
- "settings.stop_gifs": "Play-on-hover GIFs",
- "settings.streaming": "Enable automatic streaming of new posts when scrolled to the top",
- "settings.text": "Text",
- "settings.theme": "Theme",
- "settings.theme_help": "Use hex color codes (#rrggbb) to customize your color theme.",
- "settings.theme_help_v2_1": "You can also override certain component's colors and opacity by toggling the checkbox, use \"Clear all\" button to clear all overrides.",
- "settings.theme_help_v2_2": "Icons underneath some entries are background/text contrast indicators, hover over for detailed info. Please keep in mind that when using transparency contrast indicators show the worst possible case.",
- "settings.tooltipRadius": "Tooltips/alerts",
- "settings.upload_a_photo": "Upload a photo",
- "settings.user_settings": "User Settings",
- "settings.values.false": "no",
- "settings.values.true": "yes",
- "settings.notifications": "Notifications",
- "settings.enable_web_push_notifications": "Enable web push notifications",
- "settings.style.switcher.keep_color": "Keep colors",
- "settings.style.switcher.keep_shadows": "Keep shadows",
- "settings.style.switcher.keep_opacity": "Keep opacity",
- "settings.style.switcher.keep_roundness": "Keep roundness",
- "settings.style.switcher.keep_fonts": "Keep fonts",
- "settings.style.switcher.save_load_hint": "\"Keep\" options preserve currently set options when selecting or loading themes, it also stores said options when exporting a theme. When all checkboxes unset, exporting theme will save everything.",
- "settings.style.switcher.reset": "Reset",
- "settings.style.switcher.clear_all": "Clear all",
- "settings.style.switcher.clear_opacity": "Clear opacity",
- "settings.style.common.color": "Color",
- "settings.style.common.opacity": "Opacity",
- "settings.style.common.contrast.hint": "Contrast ratio is {ratio}, it {level} {context}",
- "settings.style.common.contrast.level.aa": "meets Level AA guideline (minimal)",
- "settings.style.common.contrast.level.aaa": "meets Level AAA guideline (recommended)",
- "settings.style.common.contrast.level.bad": "doesn't meet any accessibility guidelines",
- "settings.style.common.contrast.context.18pt": "for large (18pt+) text",
- "settings.style.common.contrast.context.text": "for text",
- "settings.style.common_colors._tab_label": "Common",
- "settings.style.common_colors.main": "Common colors",
- "settings.style.common_colors.foreground_hint": "See \"Advanced\" tab for more detailed control",
- "settings.style.common_colors.rgbo": "Icons, accents, badges",
- "settings.style.advanced_colors._tab_label": "Advanced",
- "settings.style.advanced_colors.alert": "Alert background",
- "settings.style.advanced_colors.alert_error": "Error",
- "settings.style.advanced_colors.badge": "Badge background",
- "settings.style.advanced_colors.badge_notification": "Notification",
- "settings.style.advanced_colors.panel_header": "Panel header",
- "settings.style.advanced_colors.top_bar": "Top bar",
- "settings.style.advanced_colors.borders": "Borders",
- "settings.style.advanced_colors.buttons": "Buttons",
- "settings.style.advanced_colors.inputs": "Input fields",
- "settings.style.advanced_colors.faint_text": "Faded text",
- "settings.style.radii._tab_label": "Roundness",
- "settings.style.shadows._tab_label": "Shadow and lighting",
- "settings.style.shadows.component": "Component",
- "settings.style.shadows.override": "Override",
- "settings.style.shadows.shadow_id": "Shadow #{value}",
- "settings.style.shadows.blur": "Blur",
- "settings.style.shadows.spread": "Spread",
- "settings.style.shadows.inset": "Inset",
- "settings.style.shadows.hint": "For shadows you can also use --variable as a color value to use CSS3 variables. Please note that setting opacity won't work in this case.",
- "settings.style.shadows.filter_hint.always_drop_shadow": "Warning, this shadow always uses {0} when browser supports it.",
- "settings.style.shadows.filter_hint.drop_shadow_syntax": "{0} does not support {1} parameter and {2} keyword.",
- "settings.style.shadows.filter_hint.avatar_inset": "Please note that combining both inset and non-inset shadows on avatars might give unexpected results with transparent avatars.",
- "settings.style.shadows.filter_hint.spread_zero": "Shadows with spread > 0 will appear as if it was set to zero",
- "settings.style.shadows.filter_hint.inset_classic": "Inset shadows will be using {0}",
- "settings.style.shadows.components.panel": "Panel",
- "settings.style.shadows.components.panelHeader": "Panel header",
- "settings.style.shadows.components.topBar": "Top bar",
- "settings.style.shadows.components.avatar": "User avatar (in profile view)",
- "settings.style.shadows.components.avatarStatus": "User avatar (in post display)",
- "settings.style.shadows.components.popup": "Popups and tooltips",
- "settings.style.shadows.components.button": "Button",
- "settings.style.shadows.components.buttonHover": "Button (hover)",
- "settings.style.shadows.components.buttonPressed": "Button (pressed)",
- "settings.style.shadows.components.buttonPressedHover": "Button (pressed+hover)",
- "settings.style.shadows.components.input": "Input field",
- "settings.style.fonts._tab_label": "Fonts",
- "settings.style.fonts.help": "Select font to use for elements of UI. For \"custom\" you have to enter exact font name as it appears in system.",
- "settings.style.fonts.components.interface": "Interface",
- "settings.style.fonts.components.input": "Input fields",
- "settings.style.fonts.components.post": "Post text",
- "settings.style.fonts.components.postCode": "Monospaced text in a post (rich text)",
- "settings.style.fonts.family": "Font name",
- "settings.style.fonts.size": "Size (in px)",
- "settings.style.fonts.weight": "Weight (boldness)",
- "settings.style.fonts.custom": "Custom",
- "settings.style.preview.header": "Preview",
- "settings.style.preview.content": "Content",
- "settings.style.preview.error": "Example error",
- "settings.style.preview.button": "Button",
- "settings.style.preview.text": "A bunch of more {0} and {1}",
- "settings.style.preview.mono": "content",
- "settings.style.preview.input": "Just landed in L.A.",
- "settings.style.preview.faint_link": "helpful manual",
- "settings.style.preview.fine_print": "Read our {0} to learn nothing useful!",
- "settings.style.preview.header_faint": "This is fine",
- "settings.style.preview.checkbox": "I have skimmed over terms and conditions",
- "settings.style.preview.link": "a nice lil' link",
- "settings.version.title": "Version",
- "settings.version.backend_version": "Backend Version",
- "settings.version.frontend_version": "Frontend Version",
- "timeline.collapse": "Collapse",
- "timeline.conversation": "Conversation",
- "timeline.error_fetching": "Error fetching updates",
- "timeline.load_older": "Load older statuses",
- "timeline.no_retweet_hint": "Post is marked as followers-only or direct and cannot be repeated",
- "timeline.repeated": "repeated",
- "timeline.show_new": "Show new",
- "timeline.up_to_date": "Up-to-date",
- "timeline.no_more_statuses": "No more statuses",
- "timeline.no_statuses": "No statuses",
- "status.reply_to": "Reply to",
- "status.replies_list": "Replies:",
- "user_card.approve": "Approve",
- "user_card.block": "Block",
- "user_card.blocked": "Blocked!",
- "user_card.deny": "Deny",
- "user_card.favorites": "Favorites",
- "user_card.follow": "Follow",
- "user_card.follow_sent": "Request sent!",
- "user_card.follow_progress": "Requesting…",
- "user_card.follow_again": "Send request again?",
- "user_card.follow_unfollow": "Unfollow",
- "user_card.followees": "Following",
- "user_card.followers": "Followers",
- "user_card.following": "Following!",
- "user_card.follows_you": "Follows you!",
- "user_card.its_you": "It's you!",
- "user_card.media": "Media",
- "user_card.mute": "Mute",
- "user_card.muted": "Muted",
- "user_card.per_day": "per day",
- "user_card.remote_follow": "Remote follow",
- "user_card.statuses": "Statuses",
- "user_card.unblock": "Unblock",
- "user_card.unblock_progress": "Unblocking...",
- "user_card.block_progress": "Blocking...",
- "user_card.unmute": "Unmute",
- "user_card.unmute_progress": "Unmuting...",
- "user_card.mute_progress": "Muting...",
- "user_profile.timeline_title": "User Timeline",
- "user_profile.profile_does_not_exist": "Sorry, this profile does not exist.",
- "user_profile.profile_loading_error": "Sorry, there was an error loading this profile.",
- "who_to_follow.more": "More",
- "who_to_follow.who_to_follow": "Who to follow",
- "tool_tip.media_upload": "Upload Media",
- "tool_tip.repeat": "Repeat",
- "tool_tip.reply": "Reply",
- "tool_tip.favorite": "Favorite",
- "tool_tip.user_settings": "User Settings",
- "upload.error.base": "Upload failed.",
- "upload.error.file_too_big": "File too big [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
- "upload.error.default": "Try again later",
- "upload.file_size_units.B": "B",
- "upload.file_size_units.KiB": "KiB",
- "upload.file_size_units.MiB": "MiB",
- "upload.file_size_units.GiB": "GiB",
- "upload.file_size_units.TiB": "TiB"
+ "chat.title": "చాట్",
+ "features_panel.chat": "చాట్",
+ "features_panel.gopher": "గోఫర్",
+ "features_panel.media_proxy": "మీడియా ప్రాక్సీ",
+ "features_panel.scope_options": "స్కోప్ ఎంపికలు",
+ "features_panel.text_limit": "వచన పరిమితి",
+ "features_panel.title": "లక్షణాలు",
+ "features_panel.who_to_follow": "ఎవరిని అనుసరించాలి",
+ "finder.error_fetching_user": "వినియోగదారుని పొందడంలో లోపం",
+ "finder.find_user": "వినియోగదారుని కనుగొనండి",
+ "general.apply": "వర్తించు",
+ "general.submit": "సమర్పించు",
+ "general.more": "మరిన్ని",
+ "general.generic_error": "ఒక తప్పిదం సంభవించినది",
+ "general.optional": "ఐచ్చికం",
+ "image_cropper.crop_picture": "చిత్రాన్ని కత్తిరించండి",
+ "image_cropper.save": "దాచు",
+ "image_cropper.save_without_cropping": "కత్తిరించకుండా సేవ్ చేయి",
+ "image_cropper.cancel": "రద్దుచేయి",
+ "login.login": "లాగిన్",
+ "login.description": "OAuth తో లాగిన్ అవ్వండి",
+ "login.logout": "లాగౌట్",
+ "login.password": "సంకేతపదము",
+ "login.placeholder": "ఉదా. lain",
+ "login.register": "నమోదు చేసుకోండి",
+ "login.username": "వాడుకరి పేరు",
+ "login.hint": "చర్చలో చేరడానికి లాగిన్ అవ్వండి",
+ "media_modal.previous": "ముందరి పుట",
+ "media_modal.next": "తరువాత",
+ "nav.about": "గురించి",
+ "nav.back": "వెనక్కి",
+ "nav.chat": "స్థానిక చాట్",
+ "nav.friend_requests": "అనుసరించడానికి అభ్యర్థనలు",
+ "nav.mentions": "ప్రస్తావనలు",
+ "nav.dms": "నేరుగా పంపిన సందేశాలు",
+ "nav.public_tl": "ప్రజా కాలక్రమం",
+ "nav.timeline": "కాలక్రమం",
+ "nav.twkn": "మొత్తం తెలిసిన నెట్వర్క్",
+ "nav.user_search": "వాడుకరి శోధన",
+ "nav.who_to_follow": "ఎవరిని అనుసరించాలి",
+ "nav.preferences": "ప్రాధాన్యతలు",
+ "notifications.broken_favorite": "తెలియని స్థితి, దాని కోసం శోధిస్తోంది...",
+ "notifications.favorited_you": "మీ స్థితిని ఇష్టపడ్డారు",
+ "notifications.followed_you": "మిమ్మల్ని అనుసరించారు",
+ "notifications.load_older": "పాత నోటిఫికేషన్లను లోడ్ చేయండి",
+ "notifications.notifications": "ప్రకటనలు",
+ "notifications.read": "చదివాను!",
+ "notifications.repeated_you": "మీ స్థితిని పునరావృతం చేసారు",
+ "notifications.no_more_notifications": "ఇక నోటిఫికేషన్లు లేవు",
+ "post_status.new_status": "క్రొత్త స్థితిని పోస్ట్ చేయండి",
+ "post_status.account_not_locked_warning": "మీ ఖాతా {౦} కాదు. ఎవరైనా మిమ్మల్ని అనుసరించి అనుచరులకు మాత్రమే ఉద్దేశించిన పోస్టులను చూడవచ్చు.",
+ "post_status.account_not_locked_warning_link": "తాళం వేయబడినది",
+ "post_status.attachments_sensitive": "జోడింపులను సున్నితమైనవిగా గుర్తించండి",
+ "post_status.content_type.text/plain": "సాధారణ అక్షరాలు",
+ "post_status.content_type.text/html": "హెచ్టిఎమ్ఎల్",
+ "post_status.content_type.text/markdown": "మార్క్డౌన్",
+ "post_status.content_warning": "విషయం (ఐచ్ఛికం)",
+ "post_status.default": "ఇప్పుడే విజయవాడలో దిగాను.",
+ "post_status.direct_warning": "ఈ పోస్ట్ మాత్రమే పేర్కొన్న వినియోగదారులకు మాత్రమే కనిపిస్తుంది.",
+ "post_status.posting": "పోస్ట్ చేస్తున్నా",
+ "post_status.scope.direct": "ప్రత్యక్ష - పేర్కొన్న వినియోగదారులకు మాత్రమే పోస్ట్ చేయబడుతుంది",
+ "post_status.scope.private": "అనుచరులకు మాత్రమే - అనుచరులకు మాత్రమే పోస్ట్ చేయబడుతుంది",
+ "post_status.scope.public": "పబ్లిక్ - ప్రజా కాలక్రమాలకు పోస్ట్ చేయబడుతుంది",
+ "post_status.scope.unlisted": "జాబితా చేయబడనిది - ప్రజా కాలక్రమాలకు పోస్ట్ చేయవద్దు",
+ "registration.bio": "బయో",
+ "registration.email": "ఈ మెయిల్",
+ "registration.fullname": "ప్రదర్శన పేరు",
+ "registration.password_confirm": "పాస్వర్డ్ నిర్ధారణ",
+ "registration.registration": "నమోదు",
+ "registration.token": "ఆహ్వాన టోకెన్",
+ "registration.captcha": "కాప్చా",
+ "registration.new_captcha": "కొత్త కాప్చా పొందుటకు చిత్రం మీద క్లిక్ చేయండి",
+ "registration.username_placeholder": "ఉదా. lain",
+ "registration.fullname_placeholder": "ఉదా. Lain Iwakura",
+ "registration.bio_placeholder": "e.g.\nHi, I'm Lain.\nI’m an anime girl living in suburban Japan. You may know me from the Wired.",
+ "registration.validations.username_required": "ఖాళీగా విడిచిపెట్టరాదు",
+ "registration.validations.fullname_required": "ఖాళీగా విడిచిపెట్టరాదు",
+ "registration.validations.email_required": "ఖాళీగా విడిచిపెట్టరాదు",
+ "registration.validations.password_required": "ఖాళీగా విడిచిపెట్టరాదు",
+ "registration.validations.password_confirmation_required": "ఖాళీగా విడిచిపెట్టరాదు",
+ "registration.validations.password_confirmation_match": "సంకేతపదం వలె ఉండాలి",
+ "settings.app_name": "అనువర్తన పేరు",
+ "settings.attachmentRadius": "జోడింపులు",
+ "settings.attachments": "జోడింపులు",
+ "settings.autoload": "క్రిందికి స్క్రోల్ చేయబడినప్పుడు స్వయంచాలక లోడింగ్ని ప్రారంభించు",
+ "settings.avatar": "అవతారం",
+ "settings.avatarAltRadius": "అవతారాలు (ప్రకటనలు)",
+ "settings.avatarRadius": "అవతారాలు",
+ "settings.background": "బ్యాక్గ్రౌండు",
+ "settings.bio": "బయో",
+ "settings.blocks_tab": "బ్లాక్లు",
+ "settings.btnRadius": "బటన్లు",
+ "settings.cBlue": "నీలం (ప్రత్యుత్తరం, అనుసరించండి)",
+ "settings.cGreen": "Green (Retweet)",
+ "settings.cOrange": "ఆరెంజ్ (ఇష్టపడు)",
+ "settings.cRed": "Red (Cancel)",
+ "settings.change_password": "పాస్వర్డ్ మార్చండి",
+ "settings.change_password_error": "మీ పాస్వర్డ్ను మార్చడంలో సమస్య ఉంది.",
+ "settings.changed_password": "పాస్వర్డ్ విజయవంతంగా మార్చబడింది!",
+ "settings.collapse_subject": "Collapse posts with subjects",
+ "settings.composing": "Composing",
+ "settings.confirm_new_password": "కొత్త పాస్వర్డ్ను నిర్ధారించండి",
+ "settings.current_avatar": "మీ ప్రస్తుత అవతారం",
+ "settings.current_password": "ప్రస్తుత పాస్వర్డ్",
+ "settings.current_profile_banner": "మీ ప్రస్తుత ప్రొఫైల్ బ్యానర్",
+ "settings.data_import_export_tab": "Data Import / Export",
+ "settings.default_vis": "Default visibility scope",
+ "settings.delete_account": "Delete Account",
+ "settings.delete_account_description": "మీ ఖాతా మరియు మీ అన్ని సందేశాలను శాశ్వతంగా తొలగించండి.",
+ "settings.delete_account_error": "There was an issue deleting your account. If this persists please contact your instance administrator.",
+ "settings.delete_account_instructions": "ఖాతా తొలగింపును నిర్ధారించడానికి దిగువ ఇన్పుట్లో మీ పాస్వర్డ్ను టైప్ చేయండి.",
+ "settings.avatar_size_instruction": "అవతార్ చిత్రాలకు సిఫార్సు చేసిన కనీస పరిమాణం 150x150 పిక్సెల్స్.",
+ "settings.export_theme": "Save preset",
+ "settings.filtering": "వడపోత",
+ "settings.filtering_explanation": "All statuses containing these words will be muted, one per line",
+ "settings.follow_export": "Follow export",
+ "settings.follow_export_button": "Export your follows to a csv file",
+ "settings.follow_export_processing": "Processing, you'll soon be asked to download your file",
+ "settings.follow_import": "Follow import",
+ "settings.follow_import_error": "అనుచరులను దిగుమతి చేయడంలో లోపం",
+ "settings.follows_imported": "Follows imported! Processing them will take a while.",
+ "settings.foreground": "Foreground",
+ "settings.general": "General",
+ "settings.hide_attachments_in_convo": "సంభాషణలలో జోడింపులను దాచు",
+ "settings.hide_attachments_in_tl": "కాలక్రమంలో జోడింపులను దాచు",
+ "settings.hide_muted_posts": "మ్యూట్ చేసిన వినియోగదారుల యొక్క పోస్ట్లను దాచిపెట్టు",
+ "settings.max_thumbnails": "Maximum amount of thumbnails per post",
+ "settings.hide_isp": "Hide instance-specific panel",
+ "settings.preload_images": "Preload images",
+ "settings.use_one_click_nsfw": "కేవలం ఒక క్లిక్ తో NSFW జోడింపులను తెరవండి",
+ "settings.hide_post_stats": "Hide post statistics (e.g. the number of favorites)",
+ "settings.hide_user_stats": "Hide user statistics (e.g. the number of followers)",
+ "settings.hide_filtered_statuses": "Hide filtered statuses",
+ "settings.import_followers_from_a_csv_file": "Import follows from a csv file",
+ "settings.import_theme": "Load preset",
+ "settings.inputRadius": "Input fields",
+ "settings.checkboxRadius": "Checkboxes",
+ "settings.instance_default": "(default: {value})",
+ "settings.instance_default_simple": "(default)",
+ "settings.interface": "Interface",
+ "settings.interfaceLanguage": "Interface language",
+ "settings.invalid_theme_imported": "The selected file is not a supported Pleroma theme. No changes to your theme were made.",
+ "settings.limited_availability": "మీ బ్రౌజర్లో అందుబాటులో లేదు",
+ "settings.links": "Links",
+ "settings.lock_account_description": "మీ ఖాతాను ఆమోదించిన అనుచరులకు మాత్రమే పరిమితం చేయండి",
+ "settings.loop_video": "Loop videos",
+ "settings.loop_video_silent_only": "Loop only videos without sound (i.e. Mastodon's \"gifs\")",
+ "settings.mutes_tab": "మ్యూట్ చేయబడినవి",
+ "settings.play_videos_in_modal": "మీడియా వీక్షికలో నేరుగా వీడియోలను ప్లే చేయి",
+ "settings.use_contain_fit": "అటాచ్మెంట్ సూక్ష్మచిత్రాలను కత్తిరించవద్దు",
+ "settings.name": "Name",
+ "settings.name_bio": "పేరు & బయో",
+ "settings.new_password": "కొత్త సంకేతపదం",
+ "settings.notification_visibility": "చూపించవలసిన నోటిఫికేషన్ రకాలు",
+ "settings.notification_visibility_follows": "Follows",
+ "settings.notification_visibility_likes": "ఇష్టాలు",
+ "settings.notification_visibility_mentions": "ప్రస్తావనలు",
+ "settings.notification_visibility_repeats": "పునఃప్రసారాలు",
+ "settings.no_rich_text_description": "అన్ని పోస్ట్ల నుండి రిచ్ టెక్స్ట్ ఫార్మాటింగ్ను స్ట్రిప్ చేయండి",
+ "settings.no_blocks": "బ్లాక్స్ లేవు",
+ "settings.no_mutes": "మ్యూట్లు లేవు",
+ "settings.hide_follows_description": "నేను ఎవరిని అనుసరిస్తున్నానో చూపించవద్దు",
+ "settings.hide_followers_description": "నన్ను ఎవరు అనుసరిస్తున్నారో చూపవద్దు",
+ "settings.show_admin_badge": "నా ప్రొఫైల్ లో అడ్మిన్ బ్యాడ్జ్ చూపించు",
+ "settings.show_moderator_badge": "నా ప్రొఫైల్లో మోడరేటర్ బ్యాడ్జ్ని చూపించు",
+ "settings.nsfw_clickthrough": "Enable clickthrough NSFW attachment hiding",
+ "settings.oauth_tokens": "OAuth tokens",
+ "settings.token": "Token",
+ "settings.refresh_token": "Refresh Token",
+ "settings.valid_until": "Valid Until",
+ "settings.revoke_token": "Revoke",
+ "settings.panelRadius": "Panels",
+ "settings.pause_on_unfocused": "Pause streaming when tab is not focused",
+ "settings.presets": "Presets",
+ "settings.profile_background": "Profile Background",
+ "settings.profile_banner": "Profile Banner",
+ "settings.profile_tab": "Profile",
+ "settings.radii_help": "Set up interface edge rounding (in pixels)",
+ "settings.replies_in_timeline": "Replies in timeline",
+ "settings.reply_link_preview": "Enable reply-link preview on mouse hover",
+ "settings.reply_visibility_all": "Show all replies",
+ "settings.reply_visibility_following": "Only show replies directed at me or users I'm following",
+ "settings.reply_visibility_self": "Only show replies directed at me",
+ "settings.saving_err": "Error saving settings",
+ "settings.saving_ok": "Settings saved",
+ "settings.security_tab": "Security",
+ "settings.scope_copy": "Copy scope when replying (DMs are always copied)",
+ "settings.set_new_avatar": "Set new avatar",
+ "settings.set_new_profile_background": "Set new profile background",
+ "settings.set_new_profile_banner": "Set new profile banner",
+ "settings.settings": "Settings",
+ "settings.subject_input_always_show": "Always show subject field",
+ "settings.subject_line_behavior": "Copy subject when replying",
+ "settings.subject_line_email": "Like email: \"re: subject\"",
+ "settings.subject_line_mastodon": "Like mastodon: copy as is",
+ "settings.subject_line_noop": "Do not copy",
+ "settings.post_status_content_type": "Post status content type",
+ "settings.stop_gifs": "Play-on-hover GIFs",
+ "settings.streaming": "Enable automatic streaming of new posts when scrolled to the top",
+ "settings.text": "Text",
+ "settings.theme": "Theme",
+ "settings.theme_help": "Use hex color codes (#rrggbb) to customize your color theme.",
+ "settings.theme_help_v2_1": "You can also override certain component's colors and opacity by toggling the checkbox, use \"Clear all\" button to clear all overrides.",
+ "settings.theme_help_v2_2": "Icons underneath some entries are background/text contrast indicators, hover over for detailed info. Please keep in mind that when using transparency contrast indicators show the worst possible case.",
+ "settings.tooltipRadius": "Tooltips/alerts",
+ "settings.upload_a_photo": "Upload a photo",
+ "settings.user_settings": "User Settings",
+ "settings.values.false": "no",
+ "settings.values.true": "yes",
+ "settings.notifications": "Notifications",
+ "settings.enable_web_push_notifications": "Enable web push notifications",
+ "settings.style.switcher.keep_color": "Keep colors",
+ "settings.style.switcher.keep_shadows": "Keep shadows",
+ "settings.style.switcher.keep_opacity": "Keep opacity",
+ "settings.style.switcher.keep_roundness": "Keep roundness",
+ "settings.style.switcher.keep_fonts": "Keep fonts",
+ "settings.style.switcher.save_load_hint": "\"Keep\" options preserve currently set options when selecting or loading themes, it also stores said options when exporting a theme. When all checkboxes unset, exporting theme will save everything.",
+ "settings.style.switcher.reset": "Reset",
+ "settings.style.switcher.clear_all": "Clear all",
+ "settings.style.switcher.clear_opacity": "Clear opacity",
+ "settings.style.common.color": "Color",
+ "settings.style.common.opacity": "Opacity",
+ "settings.style.common.contrast.hint": "Contrast ratio is {ratio}, it {level} {context}",
+ "settings.style.common.contrast.level.aa": "meets Level AA guideline (minimal)",
+ "settings.style.common.contrast.level.aaa": "meets Level AAA guideline (recommended)",
+ "settings.style.common.contrast.level.bad": "doesn't meet any accessibility guidelines",
+ "settings.style.common.contrast.context.18pt": "for large (18pt+) text",
+ "settings.style.common.contrast.context.text": "for text",
+ "settings.style.common_colors._tab_label": "Common",
+ "settings.style.common_colors.main": "Common colors",
+ "settings.style.common_colors.foreground_hint": "See \"Advanced\" tab for more detailed control",
+ "settings.style.common_colors.rgbo": "Icons, accents, badges",
+ "settings.style.advanced_colors._tab_label": "Advanced",
+ "settings.style.advanced_colors.alert": "Alert background",
+ "settings.style.advanced_colors.alert_error": "Error",
+ "settings.style.advanced_colors.badge": "Badge background",
+ "settings.style.advanced_colors.badge_notification": "Notification",
+ "settings.style.advanced_colors.panel_header": "Panel header",
+ "settings.style.advanced_colors.top_bar": "Top bar",
+ "settings.style.advanced_colors.borders": "Borders",
+ "settings.style.advanced_colors.buttons": "Buttons",
+ "settings.style.advanced_colors.inputs": "Input fields",
+ "settings.style.advanced_colors.faint_text": "Faded text",
+ "settings.style.radii._tab_label": "Roundness",
+ "settings.style.shadows._tab_label": "Shadow and lighting",
+ "settings.style.shadows.component": "Component",
+ "settings.style.shadows.override": "Override",
+ "settings.style.shadows.shadow_id": "Shadow #{value}",
+ "settings.style.shadows.blur": "Blur",
+ "settings.style.shadows.spread": "Spread",
+ "settings.style.shadows.inset": "Inset",
+ "settings.style.shadows.hint": "For shadows you can also use --variable as a color value to use CSS3 variables. Please note that setting opacity won't work in this case.",
+ "settings.style.shadows.filter_hint.always_drop_shadow": "Warning, this shadow always uses {0} when browser supports it.",
+ "settings.style.shadows.filter_hint.drop_shadow_syntax": "{0} does not support {1} parameter and {2} keyword.",
+ "settings.style.shadows.filter_hint.avatar_inset": "Please note that combining both inset and non-inset shadows on avatars might give unexpected results with transparent avatars.",
+ "settings.style.shadows.filter_hint.spread_zero": "Shadows with spread > 0 will appear as if it was set to zero",
+ "settings.style.shadows.filter_hint.inset_classic": "Inset shadows will be using {0}",
+ "settings.style.shadows.components.panel": "Panel",
+ "settings.style.shadows.components.panelHeader": "Panel header",
+ "settings.style.shadows.components.topBar": "Top bar",
+ "settings.style.shadows.components.avatar": "User avatar (in profile view)",
+ "settings.style.shadows.components.avatarStatus": "User avatar (in post display)",
+ "settings.style.shadows.components.popup": "Popups and tooltips",
+ "settings.style.shadows.components.button": "Button",
+ "settings.style.shadows.components.buttonHover": "Button (hover)",
+ "settings.style.shadows.components.buttonPressed": "Button (pressed)",
+ "settings.style.shadows.components.buttonPressedHover": "Button (pressed+hover)",
+ "settings.style.shadows.components.input": "Input field",
+ "settings.style.fonts._tab_label": "Fonts",
+ "settings.style.fonts.help": "Select font to use for elements of UI. For \"custom\" you have to enter exact font name as it appears in system.",
+ "settings.style.fonts.components.interface": "Interface",
+ "settings.style.fonts.components.input": "Input fields",
+ "settings.style.fonts.components.post": "Post text",
+ "settings.style.fonts.components.postCode": "Monospaced text in a post (rich text)",
+ "settings.style.fonts.family": "Font name",
+ "settings.style.fonts.size": "Size (in px)",
+ "settings.style.fonts.weight": "Weight (boldness)",
+ "settings.style.fonts.custom": "Custom",
+ "settings.style.preview.header": "Preview",
+ "settings.style.preview.content": "Content",
+ "settings.style.preview.error": "Example error",
+ "settings.style.preview.button": "Button",
+ "settings.style.preview.text": "A bunch of more {0} and {1}",
+ "settings.style.preview.mono": "content",
+ "settings.style.preview.input": "Just landed in L.A.",
+ "settings.style.preview.faint_link": "helpful manual",
+ "settings.style.preview.fine_print": "Read our {0} to learn nothing useful!",
+ "settings.style.preview.header_faint": "This is fine",
+ "settings.style.preview.checkbox": "I have skimmed over terms and conditions",
+ "settings.style.preview.link": "a nice lil' link",
+ "settings.version.title": "Version",
+ "settings.version.backend_version": "Backend Version",
+ "settings.version.frontend_version": "Frontend Version",
+ "timeline.collapse": "Collapse",
+ "timeline.conversation": "Conversation",
+ "timeline.error_fetching": "Error fetching updates",
+ "timeline.load_older": "Load older statuses",
+ "timeline.no_retweet_hint": "Post is marked as followers-only or direct and cannot be repeated",
+ "timeline.repeated": "repeated",
+ "timeline.show_new": "Show new",
+ "timeline.up_to_date": "Up-to-date",
+ "timeline.no_more_statuses": "No more statuses",
+ "timeline.no_statuses": "No statuses",
+ "status.reply_to": "Reply to",
+ "status.replies_list": "Replies:",
+ "user_card.approve": "Approve",
+ "user_card.block": "Block",
+ "user_card.blocked": "Blocked!",
+ "user_card.deny": "Deny",
+ "user_card.favorites": "Favorites",
+ "user_card.follow": "Follow",
+ "user_card.follow_sent": "Request sent!",
+ "user_card.follow_progress": "Requesting…",
+ "user_card.follow_again": "Send request again?",
+ "user_card.follow_unfollow": "Unfollow",
+ "user_card.followees": "Following",
+ "user_card.followers": "Followers",
+ "user_card.following": "Following!",
+ "user_card.follows_you": "Follows you!",
+ "user_card.its_you": "It's you!",
+ "user_card.media": "Media",
+ "user_card.mute": "Mute",
+ "user_card.muted": "Muted",
+ "user_card.per_day": "per day",
+ "user_card.remote_follow": "Remote follow",
+ "user_card.statuses": "Statuses",
+ "user_card.unblock": "Unblock",
+ "user_card.unblock_progress": "Unblocking...",
+ "user_card.block_progress": "Blocking...",
+ "user_card.unmute": "Unmute",
+ "user_card.unmute_progress": "Unmuting...",
+ "user_card.mute_progress": "Muting...",
+ "user_profile.timeline_title": "User Timeline",
+ "user_profile.profile_does_not_exist": "Sorry, this profile does not exist.",
+ "user_profile.profile_loading_error": "Sorry, there was an error loading this profile.",
+ "who_to_follow.more": "More",
+ "who_to_follow.who_to_follow": "Who to follow",
+ "tool_tip.media_upload": "Upload Media",
+ "tool_tip.repeat": "Repeat",
+ "tool_tip.reply": "Reply",
+ "tool_tip.favorite": "Favorite",
+ "tool_tip.user_settings": "User Settings",
+ "upload.error.base": "Upload failed.",
+ "upload.error.file_too_big": "File too big [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
+ "upload.error.default": "Try again later",
+ "upload.file_size_units.B": "B",
+ "upload.file_size_units.KiB": "KiB",
+ "upload.file_size_units.MiB": "MiB",
+ "upload.file_size_units.GiB": "GiB",
+ "upload.file_size_units.TiB": "TiB"
}
diff --git a/src/i18n/zh.json b/src/i18n/zh.json
index 8d9462ab..f95dc498 100644
--- a/src/i18n/zh.json
+++ b/src/i18n/zh.json
@@ -25,13 +25,14 @@
"more": "更多",
"generic_error": "发生一个错误",
"optional": "可选项",
- "show_more": "显示更多",
- "show_less": "显示更少",
+ "show_more": "展开",
+ "show_less": "收起",
"cancel": "取消",
"disable": "禁用",
"enable": "启用",
"confirm": "确认",
- "verify": "验证"
+ "verify": "验证",
+ "dismiss": "忽略"
},
"image_cropper": {
"crop_picture": "裁剪图片",
@@ -57,9 +58,9 @@
"enter_recovery_code": "输入一个恢复码",
"enter_two_factor_code": "输入一个双重因素验证码",
"recovery_code": "恢复码",
- "heading" : {
- "totp" : "双重因素验证",
- "recovery" : "双重因素恢复"
+ "heading": {
+ "totp": "双重因素验证",
+ "recovery": "双重因素恢复"
}
},
"media_modal": {
@@ -68,8 +69,8 @@
},
"nav": {
"about": "关于",
- "back": "Back",
- "chat": "本地聊天",
+ "back": "后退",
+ "chat": "本站聊天",
"friend_requests": "关注请求",
"mentions": "提及",
"interactions": "互动",
@@ -80,7 +81,8 @@
"user_search": "用户搜索",
"search": "搜索",
"who_to_follow": "推荐关注",
- "preferences": "偏好设置"
+ "preferences": "偏好设置",
+ "administration": "管理员"
},
"notifications": {
"broken_favorite": "未知的状态,正在搜索中...",
@@ -90,7 +92,10 @@
"notifications": "通知",
"read": "阅读!",
"repeated_you": "转发了你的状态",
- "no_more_notifications": "没有更多的通知"
+ "no_more_notifications": "没有更多的通知",
+ "reacted_with": "和 {0} 互动过",
+ "migrated_to": "迁移到",
+ "follow_request": "想要关注你"
},
"polls": {
"add_poll": "增加问卷调查",
@@ -112,7 +117,8 @@
"interactions": {
"favs_repeats": "转发和收藏",
"follows": "新的关注者",
- "load_older": "加载更早的互动"
+ "load_older": "加载更早的互动",
+ "moves": "用户迁移"
},
"post_status": {
"new_status": "发布新状态",
@@ -151,9 +157,9 @@
"token": "邀请码",
"captcha": "CAPTCHA",
"new_captcha": "点击图片获取新的验证码",
- "username_placeholder": "例如: lain",
- "fullname_placeholder": "例如: Lain Iwakura",
- "bio_placeholder": "例如:\n你好, 我是 Lain.\n我是一个住在上海的宅男。你可能在某处见过我。",
+ "username_placeholder": "例如:lain",
+ "fullname_placeholder": "例如:岩仓玲音",
+ "bio_placeholder": "例如:\n你好,我是玲音。\n我是一个住在日本郊区的动画少女。你可能在 Wired 见过我。",
"validations": {
"username_required": "不能留空",
"fullname_required": "不能留空",
@@ -171,17 +177,17 @@
"security": "安全",
"enter_current_password_to_confirm": "输入你当前密码来确认你的身份",
"mfa": {
- "otp" : "OTP",
- "setup_otp" : "设置 OTP",
- "wait_pre_setup_otp" : "预设 OTP",
- "confirm_and_enable" : "确认并启用 OTP",
+ "otp": "OTP",
+ "setup_otp": "设置 OTP",
+ "wait_pre_setup_otp": "预设 OTP",
+ "confirm_and_enable": "确认并启用 OTP",
"title": "双因素验证",
- "generate_new_recovery_codes" : "生成新的恢复码",
- "warning_of_generate_new_codes" : "当你生成新的恢复码时,你的就恢复码就失效了。",
- "recovery_codes" : "恢复码。",
- "waiting_a_recovery_codes": "接受备份码。。。",
- "recovery_codes_warning" : "抄写这些号码,或者保存在安全的地方。这些号码不会再次显示。如果你无法访问你的 2FA app,也丢失了你的恢复码,你的账号就再也无法登录了。",
- "authentication_methods" : "身份验证方法",
+ "generate_new_recovery_codes": "生成新的恢复码",
+ "warning_of_generate_new_codes": "当你生成新的恢复码时,你的旧恢复码就失效了。",
+ "recovery_codes": "恢复码。",
+ "waiting_a_recovery_codes": "正在接收备份码……",
+ "recovery_codes_warning": "抄写这些号码,或者保存在安全的地方。这些号码不会再次显示。如果你无法访问你的 2FA app,也丢失了你的恢复码,你的账号就再也无法登录了。",
+ "authentication_methods": "身份验证方法",
"scan": {
"title": "扫一下",
"desc": "使用你的双因素验证 app,扫描这个二维码,或者输入这些文字密钥:",
@@ -222,7 +228,7 @@
"data_import_export_tab": "数据导入/导出",
"default_vis": "默认可见范围",
"delete_account": "删除账户",
- "delete_account_description": "永久删除你的帐号和所有消息。",
+ "delete_account_description": "永久删除你的帐号和所有数据。",
"delete_account_error": "删除账户时发生错误,如果一直删除不了,请联系实例管理员。",
"delete_account_instructions": "在下面输入你的密码来确认删除账户",
"avatar_size_instruction": "推荐的头像图片最小的尺寸是 150x150 像素。",
@@ -263,7 +269,7 @@
"loop_video_silent_only": "只循环没有声音的视频(例如:Mastodon 里的“GIF”)",
"mutes_tab": "隐藏",
"play_videos_in_modal": "在弹出框内播放视频",
- "use_contain_fit": "生成缩略图时不要裁剪附件。",
+ "use_contain_fit": "生成缩略图时不要裁剪附件",
"name": "名字",
"name_bio": "名字及简介",
"new_password": "新密码",
@@ -348,7 +354,14 @@
"save_load_hint": "\"保留\" 选项在选择或加载主题时保留当前设置的选项,在导出主题时还会存储上述选项。当所有复选框未设置时,导出主题将保存所有内容。",
"reset": "重置",
"clear_all": "清除全部",
- "clear_opacity": "清除透明度"
+ "clear_opacity": "清除透明度",
+ "load_theme": "加载主题",
+ "help": {
+ "upgraded_from_v2": "PleromaFE 已升级,主题会和你记忆中的不太一样。"
+ },
+ "use_source": "新版本",
+ "use_snapshot": "老版本",
+ "keep_as_is": "保持原状"
},
"common": {
"color": "颜色",
@@ -441,7 +454,7 @@
"mono": "内容",
"input": "刚刚抵达上海",
"faint_link": "帮助菜单",
- "fine_print": "阅读我们的 {0} 学不到什么东东!",
+ "fine_print": "阅读我们的 {0} ,然而什么也学不到!",
"header_faint": "这很正常",
"checkbox": "我已经浏览了 TOC",
"link": "一个很棒的摇滚链接"
@@ -451,7 +464,20 @@
"title": "版本",
"backend_version": "后端版本",
"frontend_version": "前端版本"
- }
+ },
+ "notification_setting_filters": "过滤器",
+ "domain_mutes": "域名",
+ "changed_email": "邮箱修改成功!",
+ "change_email_error": "修改你的电子邮箱时发生错误",
+ "change_email": "修改电子邮箱",
+ "allow_following_move": "正在关注的账号迁移时自动重新关注",
+ "notification_setting_privacy_option": "在通知推送中隐藏发送者和内容",
+ "notification_setting_privacy": "隐私",
+ "hide_follows_count_description": "不显示关注数",
+ "notification_visibility_emoji_reactions": "互动",
+ "notification_visibility_moves": "用户迁移",
+ "new_email": "新邮箱",
+ "emoji_reactions_on_timeline": "在时间线上显示表情符号互动"
},
"time": {
"day": "{0} 天",
@@ -533,7 +559,7 @@
"muted": "已隐藏",
"per_day": "每天",
"remote_follow": "跨站关注",
- "report": "报告",
+ "report": "报告",
"statuses": "状态",
"subscribe": "订阅",
"unsubscribe": "退订",
@@ -561,7 +587,10 @@
"quarantine": "从联合实例中禁止用户帖子",
"delete_user": "删除用户",
"delete_user_confirmation": "你确认吗?此操作无法撤销。"
- }
+ },
+ "hidden": "已隐藏",
+ "show_repeats": "显示转发",
+ "hide_repeats": "隐藏转发"
},
"user_profile": {
"timeline_title": "用户时间线",
@@ -586,9 +615,11 @@
"repeat": "转发",
"reply": "回复",
"favorite": "收藏",
- "user_settings": "用户设置"
+ "user_settings": "用户设置",
+ "reject_follow_request": "拒绝关注请求",
+ "add_reaction": "添加互动"
},
- "upload":{
+ "upload": {
"error": {
"base": "上传不成功。",
"file_too_big": "文件太大了 [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
@@ -605,8 +636,8 @@
"search": {
"people": "人",
"hashtags": "Hashtags",
- "person_talking": "{count} 人谈论",
- "people_talking": "{count} 人谈论",
+ "person_talking": "{count} 人正在讨论",
+ "people_talking": "{count} 人正在讨论",
"no_results": "没有搜索结果"
},
"password_reset": {
@@ -619,5 +650,49 @@
"not_found": "我们无法找到匹配的邮箱地址或者用户名。",
"too_many_requests": "你触发了尝试的限制,请稍后再试。",
"password_reset_disabled": "密码重置已经被禁用。请联系你的实例管理员。"
+ },
+ "remote_user_resolver": {
+ "error": "未找到。",
+ "searching_for": "搜索",
+ "remote_user_resolver": "远程用户解析器"
+ },
+ "emoji": {
+ "keep_open": "选择器保持打开",
+ "stickers": "贴图",
+ "unicode": "Unicode 表情符号",
+ "custom": "自定义表情符号",
+ "add_emoji": "插入表情符号",
+ "search_emoji": "搜索表情符号",
+ "emoji": "表情符号"
+ },
+ "about": {
+ "mrf": {
+ "simple": {
+ "quarantine_desc": "本实例只会把公开状态发送非下列实例:",
+ "quarantine": "隔离",
+ "reject_desc": "本实例不会接收来自下列实例的消息:",
+ "reject": "拒绝",
+ "accept_desc": "本实例只接收来自下列实例的消息:",
+ "simple_policies": "站规",
+ "accept": "接受",
+ "media_removal": "移除媒体"
+ },
+ "mrf_policies_desc": "MRF 策略会影响本实例的互通行为。以下策略已启用:",
+ "mrf_policies": "已启动 MRF 策略",
+ "keyword": {
+ "ftl_removal": "从“全部已知网络”时间线上移除",
+ "keyword_policies": "关键词策略",
+ "is_replaced_by": "→",
+ "replace": "替换",
+ "reject": "拒绝"
+ },
+ "federation": "联邦"
+ }
+ },
+ "domain_mute_card": {
+ "unmute_progress": "正在取消隐藏……",
+ "unmute": "取消隐藏",
+ "mute_progress": "隐藏中……",
+ "mute": "隐藏"
}
}
diff --git a/src/lib/persisted_state.js b/src/lib/persisted_state.js
index cad7ea25..8ecb66a8 100644
--- a/src/lib/persisted_state.js
+++ b/src/lib/persisted_state.js
@@ -1,13 +1,12 @@
import merge from 'lodash.merge'
-import objectPath from 'object-path'
import localforage from 'localforage'
-import { each } from 'lodash'
+import { each, get, set } from 'lodash'
let loaded = false
const defaultReducer = (state, paths) => (
paths.length === 0 ? state : paths.reduce((substate, path) => {
- objectPath.set(substate, path, objectPath.get(state, path))
+ set(substate, path, get(state, path))
return substate
}, {})
)
diff --git a/src/main.js b/src/main.js
index baf73ac8..9a201e4f 100644
--- a/src/main.js
+++ b/src/main.js
@@ -31,7 +31,6 @@ import VueChatScroll from 'vue-chat-scroll'
import VueClickOutside from 'v-click-outside'
import PortalVue from 'portal-vue'
import VBodyScrollLock from './directives/body_scroll_lock'
-import VTooltip from 'v-tooltip'
import afterStoreSetup from './boot/after_store.js'
@@ -44,21 +43,16 @@ Vue.use(VueChatScroll)
Vue.use(VueClickOutside)
Vue.use(PortalVue)
Vue.use(VBodyScrollLock)
-Vue.use(VTooltip, {
- popover: {
- defaultTrigger: 'hover click',
- defaultContainer: false,
- defaultOffset: 5
- }
-})
const i18n = new VueI18n({
// By default, use the browser locale, we will update it if neccessary
- locale: currentLocale,
+ locale: 'en',
fallbackLocale: 'en',
- messages
+ messages: messages.default
})
+messages.setLanguage(i18n, currentLocale)
+
const persistedStateOptions = {
paths: [
'config',
diff --git a/src/modules/config.js b/src/modules/config.js
index 8381fa53..47b24d77 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -1,10 +1,24 @@
import { set, delete as del } from 'vue'
import { setPreset, applyTheme } from '../services/style_setter/style_setter.js'
+import messages from '../i18n/messages'
const browserLocale = (window.navigator.language || 'en').split('-')[0]
+/* TODO this is a bit messy.
+ * We need to declare settings with their types and also deal with
+ * instance-default settings in some way, hopefully try to avoid copy-pasta
+ * in general.
+ */
+export const multiChoiceProperties = [
+ 'postContentType',
+ 'subjectLineBehavior'
+]
+
export const defaultState = {
colors: {},
+ theme: undefined,
+ customTheme: undefined,
+ customThemeSource: undefined,
hideISP: false,
// bad name: actually hides posts of muted USERS
hideMutedPosts: undefined, // instance default
@@ -31,7 +45,8 @@ export const defaultState = {
likes: true,
repeats: true,
moves: true,
- emojiReactions: false
+ emojiReactions: false,
+ followRequest: true
},
webPushNotifications: false,
muteWords: [],
@@ -96,10 +111,15 @@ const config = {
commit('setOption', { name, value })
switch (name) {
case 'theme':
- setPreset(value, commit)
+ setPreset(value)
break
case 'customTheme':
- applyTheme(value, commit)
+ case 'customThemeSource':
+ applyTheme(value)
+ break
+ case 'interfaceLanguage':
+ messages.setLanguage(this.getters.i18n, value)
+ break
}
}
}
diff --git a/src/modules/instance.js b/src/modules/instance.js
index 625323b9..ec5f4e54 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -1,53 +1,60 @@
import { set } from 'vue'
-import { setPreset } from '../services/style_setter/style_setter.js'
+import { getPreset, applyTheme } from '../services/style_setter/style_setter.js'
+import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js'
+import apiService from '../services/api/api.service.js'
import { instanceDefaultProperties } from './config.js'
const defaultState = {
- // Stuff from static/config.json and apiConfig
+ // Stuff from apiConfig
name: 'Pleroma FE',
registrationOpen: true,
- safeDM: true,
- textlimit: 5000,
server: 'http://localhost:4040/',
- theme: 'pleroma-dark',
- background: '/static/aurora_borealis.jpg',
- logo: '/static/logo.png',
- logoMask: true,
- logoMargin: '.2em',
- redirectRootNoLogin: '/main/all',
- redirectRootLogin: '/main/friends',
- showInstanceSpecificPanel: false,
- alwaysShowSubjectInput: true,
- hideMutedPosts: false,
- collapseMessageWithSubject: false,
- hidePostStats: false,
- hideUserStats: false,
- hideFilteredStatuses: false,
- disableChat: false,
- scopeCopy: true,
- subjectLineBehavior: 'email',
- postContentType: 'text/plain',
- hideSitename: false,
- nsfwCensorImage: undefined,
+ textlimit: 5000,
+ themeData: undefined,
vapidPublicKey: undefined,
- noAttachmentLinks: false,
- showFeaturesPanel: true,
- minimalScopesMode: false,
+
+ // Stuff from static/config.json
+ alwaysShowSubjectInput: true,
+ background: '/static/aurora_borealis.jpg',
+ collapseMessageWithSubject: false,
+ disableChat: false,
greentext: false,
+ hideFilteredStatuses: false,
+ hideMutedPosts: false,
+ hidePostStats: false,
+ hideSitename: false,
+ hideUserStats: false,
+ loginMethod: 'password',
+ logo: '/static/logo.png',
+ logoMargin: '.2em',
+ logoMask: true,
+ minimalScopesMode: false,
+ nsfwCensorImage: undefined,
+ postContentType: 'text/plain',
+ redirectRootLogin: '/main/friends',
+ redirectRootNoLogin: '/main/all',
+ scopeCopy: true,
+ showFeaturesPanel: true,
+ showInstanceSpecificPanel: false,
+ sidebarRight: false,
+ subjectLineBehavior: 'email',
+ theme: 'pleroma-dark',
// Nasty stuff
- pleromaBackend: true,
- emoji: [],
- emojiFetched: false,
customEmoji: [],
customEmojiFetched: false,
- restrictedNicknames: [],
+ emoji: [],
+ emojiFetched: false,
+ pleromaBackend: true,
postFormats: [],
+ restrictedNicknames: [],
+ safeDM: true,
+ knownDomains: [],
// Feature-set, apparently, not everything here is reported...
- mediaProxyAvailable: false,
chatAvailable: false,
gopherAvailable: false,
+ mediaProxyAvailable: false,
suggestionsEnabled: false,
suggestionsWeb: '',
@@ -75,6 +82,9 @@ const instance = {
if (typeof value !== 'undefined') {
set(state, name, value)
}
+ },
+ setKnownDomains (state, domains) {
+ state.knownDomains = domains
}
},
getters: {
@@ -96,6 +106,9 @@ const instance = {
dispatch('initializeSocket')
}
break
+ case 'theme':
+ dispatch('setTheme', value)
+ break
}
},
async getStaticEmoji ({ commit }) {
@@ -147,9 +160,23 @@ const instance = {
}
},
- setTheme ({ commit }, themeName) {
+ setTheme ({ commit, rootState }, themeName) {
commit('setInstanceOption', { name: 'theme', value: themeName })
- return setPreset(themeName, commit)
+ getPreset(themeName)
+ .then(themeData => {
+ commit('setInstanceOption', { name: 'themeData', value: themeData })
+ // No need to apply theme if there's user theme already
+ const { customTheme } = rootState.config
+ if (customTheme) return
+
+ // New theme presets don't have 'theme' property, they use 'source'
+ const themeSource = themeData.source
+ if (!themeData.theme || (themeSource && themeSource.themeEngineVersion === CURRENT_VERSION)) {
+ applyTheme(themeSource)
+ } else {
+ applyTheme(themeData.theme)
+ }
+ })
},
fetchEmoji ({ dispatch, state }) {
if (!state.customEmojiFetched) {
@@ -160,6 +187,18 @@ const instance = {
state.emojiFetched = true
dispatch('getStaticEmoji')
}
+ },
+
+ async getKnownDomains ({ commit, rootState }) {
+ try {
+ const result = await apiService.fetchKnownDomains({
+ credentials: rootState.users.currentUser.credentials
+ })
+ commit('setKnownDomains', result)
+ } catch (e) {
+ console.warn("Can't load known domains")
+ console.warn(e)
+ }
}
}
}
diff --git a/src/modules/interface.js b/src/modules/interface.js
index 5b2762e5..eeebd65e 100644
--- a/src/modules/interface.js
+++ b/src/modules/interface.js
@@ -1,6 +1,8 @@
import { set, delete as del } from 'vue'
const defaultState = {
+ settingsModalState: 'hidden',
+ settingsModalLoaded: false,
settings: {
currentSaveStateNotice: null,
noticeClearTimeout: null,
@@ -35,6 +37,27 @@ const interfaceMod = {
},
setMobileLayout (state, value) {
state.mobileLayout = value
+ },
+ closeSettingsModal (state) {
+ state.settingsModalState = 'hidden'
+ },
+ togglePeekSettingsModal (state) {
+ switch (state.settingsModalState) {
+ case 'minimized':
+ state.settingsModalState = 'visible'
+ return
+ case 'visible':
+ state.settingsModalState = 'minimized'
+ return
+ default:
+ throw new Error('Illegal minimization state of settings modal')
+ }
+ },
+ openSettingsModal (state) {
+ state.settingsModalState = 'visible'
+ if (!state.settingsModalLoaded) {
+ state.settingsModalLoaded = true
+ }
}
},
actions: {
@@ -49,6 +72,15 @@ const interfaceMod = {
},
setMobileLayout ({ commit }, value) {
commit('setMobileLayout', value)
+ },
+ closeSettingsModal ({ commit }) {
+ commit('closeSettingsModal')
+ },
+ openSettingsModal ({ commit }) {
+ commit('openSettingsModal')
+ },
+ togglePeekSettingsModal ({ commit }) {
+ commit('togglePeekSettingsModal')
}
}
}
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 25b62ac7..9a2e0df1 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -13,8 +13,9 @@ import {
omitBy
} from 'lodash'
import { set } from 'vue'
+import { isStatusNotification } from '../services/notification_utils/notification_utils.js'
import apiService from '../services/api/api.service.js'
-// import parse from '../services/status_parser/status_parser.js'
+import { muteWordHits } from '../services/status_parser/status_parser.js'
const emptyTl = (userId = 0) => ({
statuses: [],
@@ -321,7 +322,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
const addNewNotifications = (state, { dispatch, notifications, older, visibleNotificationTypes, rootGetters }) => {
each(notifications, (notification) => {
- if (notification.type !== 'follow' && notification.type !== 'move') {
+ if (isStatusNotification(notification.type)) {
notification.action = addStatusToGlobalStorage(state, notification.action).item
notification.status = notification.status && addStatusToGlobalStorage(state, notification.status).item
}
@@ -361,13 +362,16 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot
case 'move':
i18nString = 'migrated_to'
break
+ case 'follow_request':
+ i18nString = 'follow_request'
+ break
}
if (notification.type === 'pleroma:emoji_reaction') {
notifObj.body = rootGetters.i18n.t('notifications.reacted_with', [notification.emoji])
} else if (i18nString) {
notifObj.body = rootGetters.i18n.t('notifications.' + i18nString)
- } else {
+ } else if (isStatusNotification(notification.type)) {
notifObj.body = notification.status.text
}
@@ -377,7 +381,18 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot
notifObj.image = status.attachments[0].url
}
- if (!notification.seen && !state.notifications.desktopNotificationSilence && visibleNotificationTypes.includes(notification.type)) {
+ const reasonsToMuteNotif = (
+ notification.seen ||
+ state.notifications.desktopNotificationSilence ||
+ !visibleNotificationTypes.includes(notification.type) ||
+ (
+ notification.type === 'mention' && status && (
+ status.muted ||
+ muteWordHits(status, rootGetters.mergedConfig.muteWords).length === 0
+ )
+ )
+ )
+ if (!reasonsToMuteNotif) {
let desktopNotification = new window.Notification(title, notifObj)
// Chrome is known for not closing notifications automatically
// according to MDN, anyway.
@@ -521,6 +536,17 @@ export const mutations = {
notification.seen = true
})
},
+ markSingleNotificationAsSeen (state, { id }) {
+ const notification = find(state.notifications.data, n => n.id === id)
+ if (notification) notification.seen = true
+ },
+ dismissNotification (state, { id }) {
+ state.notifications.data = state.notifications.data.filter(n => n.id !== id)
+ },
+ updateNotification (state, { id, updater }) {
+ const notification = find(state.notifications.data, n => n.id === id)
+ notification && updater(notification)
+ },
queueFlush (state, { timeline, id }) {
state.timelines[timeline].flushMarker = id
},
@@ -616,7 +642,7 @@ const statuses = {
commit('setNotificationsSilence', { value })
},
fetchStatus ({ rootState, dispatch }, id) {
- rootState.api.backendInteractor.fetchStatus({ id })
+ return rootState.api.backendInteractor.fetchStatus({ id })
.then((status) => dispatch('addNewStatuses', { statuses: [status] }))
},
deleteStatus ({ rootState, commit }, status) {
@@ -680,6 +706,24 @@ const statuses = {
credentials: rootState.users.currentUser.credentials
})
},
+ markSingleNotificationAsSeen ({ rootState, commit }, { id }) {
+ commit('markSingleNotificationAsSeen', { id })
+ apiService.markNotificationsAsSeen({
+ single: true,
+ id,
+ credentials: rootState.users.currentUser.credentials
+ })
+ },
+ dismissNotificationLocal ({ rootState, commit }, { id }) {
+ commit('dismissNotification', { id })
+ },
+ dismissNotification ({ rootState, commit }, { id }) {
+ commit('dismissNotification', { id })
+ rootState.api.backendInteractor.dismissNotification({ id })
+ },
+ updateNotification ({ rootState, commit }, { id, updater }) {
+ commit('updateNotification', { id, updater })
+ },
fetchFavsAndRepeats ({ rootState, commit }, id) {
Promise.all([
rootState.api.backendInteractor.fetchFavoritedByUsers({ id }),
diff --git a/src/modules/users.js b/src/modules/users.js
index ce3e595d..f9329f2a 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -48,6 +48,11 @@ const unblockUser = (store, id) => {
}
const muteUser = (store, id) => {
+ const predictedRelationship = store.state.relationships[id] || { id }
+ predictedRelationship.muting = true
+ store.commit('updateUserRelationship', [predictedRelationship])
+ store.commit('addMuteId', id)
+
return store.rootState.api.backendInteractor.muteUser({ id })
.then((relationship) => {
store.commit('updateUserRelationship', [relationship])
@@ -56,6 +61,10 @@ const muteUser = (store, id) => {
}
const unmuteUser = (store, id) => {
+ const predictedRelationship = store.state.relationships[id] || { id }
+ predictedRelationship.muting = false
+ store.commit('updateUserRelationship', [predictedRelationship])
+
return store.rootState.api.backendInteractor.unmuteUser({ id })
.then((relationship) => store.commit('updateUserRelationship', [relationship]))
}
@@ -83,10 +92,6 @@ const unmuteDomain = (store, domain) => {
}
export const mutations = {
- setMuted (state, { user: { id }, muted }) {
- const user = state.usersObject[id]
- set(user, 'muted', muted)
- },
tagUser (state, { user: { id }, tag }) {
const user = state.usersObject[id]
const tags = user.tags || []
@@ -146,26 +151,18 @@ export const mutations = {
}
},
addNewUsers (state, users) {
- each(users, (user) => mergeOrAdd(state.users, state.usersObject, user))
+ each(users, (user) => {
+ if (user.relationship) {
+ set(state.relationships, user.relationship.id, user.relationship)
+ }
+ mergeOrAdd(state.users, state.usersObject, user)
+ })
},
updateUserRelationship (state, relationships) {
relationships.forEach((relationship) => {
- const user = state.usersObject[relationship.id]
- if (user) {
- user.follows_you = relationship.followed_by
- user.following = relationship.following
- user.muted = relationship.muting
- user.statusnet_blocking = relationship.blocking
- user.subscribed = relationship.subscribing
- user.showing_reblogs = relationship.showing_reblogs
- }
+ set(state.relationships, relationship.id, relationship)
})
},
- updateBlocks (state, blockedUsers) {
- // Reset statusnet_blocking of all fetched users
- each(state.users, (user) => { user.statusnet_blocking = false })
- each(blockedUsers, (user) => mergeOrAdd(state.users, state.usersObject, user))
- },
saveBlockIds (state, blockIds) {
state.currentUser.blockIds = blockIds
},
@@ -174,11 +171,6 @@ export const mutations = {
state.currentUser.blockIds.push(blockId)
}
},
- updateMutes (state, mutedUsers) {
- // Reset muted of all fetched users
- each(state.users, (user) => { user.muted = false })
- each(mutedUsers, (user) => mergeOrAdd(state.users, state.usersObject, user))
- },
saveMuteIds (state, muteIds) {
state.currentUser.muteIds = muteIds
},
@@ -244,6 +236,10 @@ export const getters = {
return state.usersObject[query.toLowerCase()]
}
return result
+ },
+ relationship: state => id => {
+ const rel = id && state.relationships[id]
+ return rel || { id, loading: true }
}
}
@@ -254,7 +250,8 @@ export const defaultState = {
users: [],
usersObject: {},
signUpPending: false,
- signUpErrors: []
+ signUpErrors: [],
+ relationships: {}
}
const users = {
@@ -279,7 +276,7 @@ const users = {
return store.rootState.api.backendInteractor.fetchBlocks()
.then((blocks) => {
store.commit('saveBlockIds', map(blocks, 'id'))
- store.commit('updateBlocks', blocks)
+ store.commit('addNewUsers', blocks)
return blocks
})
},
@@ -298,8 +295,8 @@ const users = {
fetchMutes (store) {
return store.rootState.api.backendInteractor.fetchMutes()
.then((mutes) => {
- store.commit('updateMutes', mutes)
store.commit('saveMuteIds', map(mutes, 'id'))
+ store.commit('addNewUsers', mutes)
return mutes
})
},
@@ -374,9 +371,9 @@ const users = {
return rootState.api.backendInteractor.unsubscribeUser({ id })
.then((relationship) => commit('updateUserRelationship', [relationship]))
},
- toggleActivationStatus ({ rootState, commit }, user) {
+ toggleActivationStatus ({ rootState, commit }, { user }) {
const api = user.deactivated ? rootState.api.backendInteractor.activateUser : rootState.api.backendInteractor.deactivateUser
- api(user)
+ api({ user })
.then(({ deactivated }) => commit('updateActivationStatus', { user, deactivated }))
},
registerPushNotifications (store) {
@@ -416,7 +413,7 @@ const users = {
},
addNewNotifications (store, { notifications }) {
const users = map(notifications, 'from_profile')
- const targetUsers = map(notifications, 'target')
+ const targetUsers = map(notifications, 'target').filter(_ => _)
const notificationIds = notifications.map(_ => _.id)
store.commit('addNewUsers', users)
store.commit('addNewUsers', targetUsers)
@@ -431,7 +428,7 @@ const users = {
store.commit('setUserForNotification', notification)
})
},
- searchUsers (store, query) {
+ searchUsers (store, { query }) {
return store.rootState.api.backendInteractor.searchUsers({ query })
.then((users) => {
store.commit('addNewUsers', users)
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 20eaa9a0..dfffc291 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -1,10 +1,8 @@
import { each, map, concat, last, get } from 'lodash'
import { parseStatus, parseUser, parseNotification, parseAttachment } from '../entity_normalizer/entity_normalizer.service.js'
-import 'whatwg-fetch'
import { RegistrationError, StatusCodeError } from '../errors/errors'
/* eslint-env browser */
-const QVITTER_USER_NOTIFICATIONS_READ_URL = '/api/qvitter/statuses/notifications/read.json'
const BLOCKS_IMPORT_URL = '/api/pleroma/blocks_import'
const FOLLOW_IMPORT_URL = '/api/pleroma/follow_import'
const DELETE_ACCOUNT_URL = '/api/pleroma/delete_account'
@@ -17,6 +15,7 @@ const DEACTIVATE_USER_URL = '/api/pleroma/admin/users/deactivate'
const ADMIN_USERS_URL = '/api/pleroma/admin/users'
const SUGGESTIONS_URL = '/api/v1/suggestions'
const NOTIFICATION_SETTINGS_URL = '/api/pleroma/notification_settings'
+const NOTIFICATION_READ_URL = '/api/v1/pleroma/notifications/read'
const MFA_SETTINGS_URL = '/api/pleroma/accounts/mfa'
const MFA_BACKUP_CODES_URL = '/api/pleroma/accounts/mfa/backup_codes'
@@ -29,6 +28,7 @@ const MASTODON_LOGIN_URL = '/api/v1/accounts/verify_credentials'
const MASTODON_REGISTRATION_URL = '/api/v1/accounts'
const MASTODON_USER_FAVORITES_TIMELINE_URL = '/api/v1/favourites'
const MASTODON_USER_NOTIFICATIONS_URL = '/api/v1/notifications'
+const MASTODON_DISMISS_NOTIFICATION_URL = id => `/api/v1/notifications/${id}/dismiss`
const MASTODON_FAVORITE_URL = id => `/api/v1/statuses/${id}/favourite`
const MASTODON_UNFAVORITE_URL = id => `/api/v1/statuses/${id}/unfavourite`
const MASTODON_RETWEET_URL = id => `/api/v1/statuses/${id}/reblog`
@@ -74,6 +74,7 @@ const MASTODON_SEARCH_2 = `/api/v2/search`
const MASTODON_USER_SEARCH_URL = '/api/v1/accounts/search'
const MASTODON_DOMAIN_BLOCKS_URL = '/api/v1/domain_blocks'
const MASTODON_STREAMING = '/api/v1/streaming'
+const MASTODON_KNOWN_DOMAIN_LIST_URL = '/api/v1/instance/peers'
const PLEROMA_EMOJI_REACTIONS_URL = id => `/api/v1/pleroma/statuses/${id}/reactions`
const PLEROMA_EMOJI_REACT_URL = (id, emoji) => `/api/v1/pleroma/statuses/${id}/reactions/${emoji}`
const PLEROMA_EMOJI_UNREACT_URL = (id, emoji) => `/api/v1/pleroma/statuses/${id}/reactions/${emoji}`
@@ -323,7 +324,8 @@ const fetchFriends = ({ id, maxId, sinceId, limit = 20, credentials }) => {
const args = [
maxId && `max_id=${maxId}`,
sinceId && `since_id=${sinceId}`,
- limit && `limit=${limit}`
+ limit && `limit=${limit}`,
+ `with_relationships=true`
].filter(_ => _).join('&')
url = url + (args ? '?' + args : '')
@@ -357,7 +359,8 @@ const fetchFollowers = ({ id, maxId, sinceId, limit = 20, credentials }) => {
const args = [
maxId && `max_id=${maxId}`,
sinceId && `since_id=${sinceId}`,
- limit && `limit=${limit}`
+ limit && `limit=${limit}`,
+ `with_relationships=true`
].filter(_ => _).join('&')
url += args ? '?' + args : ''
@@ -402,8 +405,8 @@ const fetchStatus = ({ id, credentials }) => {
.then((data) => parseStatus(data))
}
-const tagUser = ({ tag, credentials, ...options }) => {
- const screenName = options.screen_name
+const tagUser = ({ tag, credentials, user }) => {
+ const screenName = user.screen_name
const form = {
nicknames: [screenName],
tags: [tag]
@@ -419,8 +422,8 @@ const tagUser = ({ tag, credentials, ...options }) => {
})
}
-const untagUser = ({ tag, credentials, ...options }) => {
- const screenName = options.screen_name
+const untagUser = ({ tag, credentials, user }) => {
+ const screenName = user.screen_name
const body = {
nicknames: [screenName],
tags: [tag]
@@ -436,7 +439,7 @@ const untagUser = ({ tag, credentials, ...options }) => {
})
}
-const addRight = ({ right, credentials, ...user }) => {
+const addRight = ({ right, credentials, user }) => {
const screenName = user.screen_name
return fetch(PERMISSION_GROUP_URL(screenName, right), {
@@ -446,7 +449,7 @@ const addRight = ({ right, credentials, ...user }) => {
})
}
-const deleteRight = ({ right, credentials, ...user }) => {
+const deleteRight = ({ right, credentials, user }) => {
const screenName = user.screen_name
return fetch(PERMISSION_GROUP_URL(screenName, right), {
@@ -478,7 +481,7 @@ const deactivateUser = ({ credentials, user: { screen_name: nickname } }) => {
}).then(response => get(response, 'users.0'))
}
-const deleteUser = ({ credentials, ...user }) => {
+const deleteUser = ({ credentials, user }) => {
const screenName = user.screen_name
const headers = authHeaders(credentials)
@@ -495,8 +498,7 @@ const fetchTimeline = ({
until = false,
userId = false,
tag = false,
- withMuted = false,
- withMove = false
+ withMuted = false
}) => {
const timelineUrls = {
public: MASTODON_PUBLIC_TIMELINE,
@@ -536,12 +538,11 @@ const fetchTimeline = ({
if (timeline === 'public' || timeline === 'publicAndExternal') {
params.push(['only_media', false])
}
- if (timeline === 'notifications') {
- params.push(['with_move', withMove])
+ if (timeline !== 'favorites') {
+ params.push(['with_muted', withMuted])
}
- params.push(['count', 20])
- params.push(['with_muted', withMuted])
+ params.push(['limit', 20])
const queryString = map(params, (param) => `${param[0]}=${param[1]}`).join('&')
url += `?${queryString}`
@@ -844,12 +845,16 @@ const suggestions = ({ credentials }) => {
}).then((data) => data.json())
}
-const markNotificationsAsSeen = ({ id, credentials }) => {
+const markNotificationsAsSeen = ({ id, credentials, single = false }) => {
const body = new FormData()
- body.append('latest_id', id)
+ if (single) {
+ body.append('id', id)
+ } else {
+ body.append('max_id', id)
+ }
- return fetch(QVITTER_USER_NOTIFICATIONS_READ_URL, {
+ return fetch(NOTIFICATION_READ_URL, {
body,
headers: authHeaders(credentials),
method: 'POST'
@@ -880,12 +885,20 @@ const fetchPoll = ({ pollId, credentials }) => {
)
}
-const fetchFavoritedByUsers = ({ id }) => {
- return promisedRequest({ url: MASTODON_STATUS_FAVORITEDBY_URL(id) }).then((users) => users.map(parseUser))
+const fetchFavoritedByUsers = ({ id, credentials }) => {
+ return promisedRequest({
+ url: MASTODON_STATUS_FAVORITEDBY_URL(id),
+ method: 'GET',
+ credentials
+ }).then((users) => users.map(parseUser))
}
-const fetchRebloggedByUsers = ({ id }) => {
- return promisedRequest({ url: MASTODON_STATUS_REBLOGGEDBY_URL(id) }).then((users) => users.map(parseUser))
+const fetchRebloggedByUsers = ({ id, credentials }) => {
+ return promisedRequest({
+ url: MASTODON_STATUS_REBLOGGEDBY_URL(id),
+ method: 'GET',
+ credentials
+ }).then((users) => users.map(parseUser))
}
const fetchEmojiReactions = ({ id, credentials }) => {
@@ -962,6 +975,8 @@ const search2 = ({ credentials, q, resolve, limit, offset, following }) => {
params.push(['following', true])
}
+ params.push(['with_relationships', true])
+
let queryString = map(params, (param) => `${param[0]}=${param[1]}`).join('&')
url += `?${queryString}`
@@ -980,6 +995,10 @@ const search2 = ({ credentials, q, resolve, limit, offset, following }) => {
})
}
+const fetchKnownDomains = ({ credentials }) => {
+ return promisedRequest({ url: MASTODON_KNOWN_DOMAIN_LIST_URL, credentials })
+}
+
const fetchDomainMutes = ({ credentials }) => {
return promisedRequest({ url: MASTODON_DOMAIN_BLOCKS_URL, credentials })
}
@@ -1002,6 +1021,15 @@ const unmuteDomain = ({ domain, credentials }) => {
})
}
+const dismissNotification = ({ credentials, id }) => {
+ return promisedRequest({
+ url: MASTODON_DISMISS_NOTIFICATION_URL(id),
+ method: 'POST',
+ payload: { id },
+ credentials
+ })
+}
+
export const getMastodonSocketURI = ({ credentials, stream, args = {} }) => {
return Object.entries({
...(credentials
@@ -1157,6 +1185,7 @@ const apiService = {
denyUser,
suggestions,
markNotificationsAsSeen,
+ dismissNotification,
vote,
fetchPoll,
fetchFavoritedByUsers,
@@ -1168,6 +1197,7 @@ const apiService = {
updateNotificationSettings,
search2,
searchUsers,
+ fetchKnownDomains,
fetchDomainMutes,
muteDomain,
unmuteDomain
diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js
index d1b17c61..ec104269 100644
--- a/src/services/color_convert/color_convert.js
+++ b/src/services/color_convert/color_convert.js
@@ -1,16 +1,27 @@
-import { map } from 'lodash'
+import { invertLightness, contrastRatio } from 'chromatism'
-const rgb2hex = (r, g, b) => {
+// useful for visualizing color when debugging
+export const consoleColor = (color) => console.log('%c##########', 'background: ' + color + '; color: ' + color)
+
+/**
+ * Convert r, g, b values into hex notation. All components are [0-255]
+ *
+ * @param {Number|String|Object} r - Either red component, {r,g,b} object, or hex string
+ * @param {Number} [g] - Green component
+ * @param {Number} [b] - Blue component
+ */
+export const rgb2hex = (r, g, b) => {
if (r === null || typeof r === 'undefined') {
return undefined
}
- if (r[0] === '#') {
+ // TODO: clean up this mess
+ if (r[0] === '#' || r === 'transparent') {
return r
}
if (typeof r === 'object') {
({ r, g, b } = r)
}
- [r, g, b] = map([r, g, b], (val) => {
+ [r, g, b] = [r, g, b].map(val => {
val = Math.ceil(val)
val = val < 0 ? 0 : val
val = val > 255 ? 255 : val
@@ -58,7 +69,7 @@ const srgbToLinear = (srgb) => {
* @param {Object} srgb - sRGB color
* @returns {Number} relative luminance
*/
-const relativeLuminance = (srgb) => {
+export const relativeLuminance = (srgb) => {
const { r, g, b } = srgbToLinear(srgb)
return 0.2126 * r + 0.7152 * g + 0.0722 * b
}
@@ -71,7 +82,7 @@ const relativeLuminance = (srgb) => {
* @param {Object} b - sRGB color
* @returns {Number} color ratio
*/
-const getContrastRatio = (a, b) => {
+export const getContrastRatio = (a, b) => {
const la = relativeLuminance(a)
const lb = relativeLuminance(b)
const [l1, l2] = la > lb ? [la, lb] : [lb, la]
@@ -79,6 +90,17 @@ const getContrastRatio = (a, b) => {
return (l1 + 0.05) / (l2 + 0.05)
}
+/**
+ * Same as `getContrastRatio` but for multiple layers in-between
+ *
+ * @param {Object} text - text color (topmost layer)
+ * @param {[Object, Number]} layers[] - layers between text and bedrock
+ * @param {Object} bedrock - layer at the very bottom
+ */
+export const getContrastRatioLayers = (text, layers, bedrock) => {
+ return getContrastRatio(alphaBlendLayers(bedrock, layers), text)
+}
+
/**
* This performs alpha blending between solid background and semi-transparent foreground
*
@@ -87,7 +109,7 @@ const getContrastRatio = (a, b) => {
* @param {Object} bg - bottom layer color
* @returns {Object} sRGB of resulting color
*/
-const alphaBlend = (fg, fga, bg) => {
+export const alphaBlend = (fg, fga, bg) => {
if (fga === 1 || typeof fga === 'undefined') return fg
return 'rgb'.split('').reduce((acc, c) => {
// Simplified https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
@@ -97,14 +119,30 @@ const alphaBlend = (fg, fga, bg) => {
}, {})
}
-const invert = (rgb) => {
+/**
+ * Same as `alphaBlend` but for multiple layers in-between
+ *
+ * @param {Object} bedrock - layer at the very bottom
+ * @param {[Object, Number]} layers[] - layers between text and bedrock
+ */
+export const alphaBlendLayers = (bedrock, layers) => layers.reduce((acc, [color, opacity]) => {
+ return alphaBlend(color, opacity, acc)
+}, bedrock)
+
+export const invert = (rgb) => {
return 'rgb'.split('').reduce((acc, c) => {
acc[c] = 255 - rgb[c]
return acc
}, {})
}
-const hex2rgb = (hex) => {
+/**
+ * Converts #rrggbb hex notation into an {r, g, b} object
+ *
+ * @param {String} hex - #rrggbb string
+ * @returns {Object} rgb representation of the color, values are 0-255
+ */
+export const hex2rgb = (hex) => {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
return result ? {
r: parseInt(result[1], 16),
@@ -113,18 +151,72 @@ const hex2rgb = (hex) => {
} : null
}
-const mixrgb = (a, b) => {
- return Object.keys(a).reduce((acc, k) => {
+/**
+ * Old somewhat weird function for mixing two colors together
+ *
+ * @param {Object} a - one color (rgb)
+ * @param {Object} b - other color (rgb)
+ * @returns {Object} result
+ */
+export const mixrgb = (a, b) => {
+ return 'rgb'.split('').reduce((acc, k) => {
acc[k] = (a[k] + b[k]) / 2
return acc
}, {})
}
-
-export {
- rgb2hex,
- hex2rgb,
- mixrgb,
- invert,
- getContrastRatio,
- alphaBlend
+/**
+ * Converts rgb object into a CSS rgba() color
+ *
+ * @param {Object} color - rgb
+ * @returns {String} CSS rgba() color
+ */
+export const rgba2css = function (rgba) {
+ return `rgba(${Math.floor(rgba.r)}, ${Math.floor(rgba.g)}, ${Math.floor(rgba.b)}, ${rgba.a})`
+}
+
+/**
+ * Get text color for given background color and intended text color
+ * This checks if text and background don't have enough color and inverts
+ * text color's lightness if needed. If text color is still not enough it
+ * will fall back to black or white
+ *
+ * @param {Object} bg - background color
+ * @param {Object} text - intended text color
+ * @param {Boolean} preserve - try to preserve intended text color's hue/saturation (i.e. no BW)
+ */
+export const getTextColor = function (bg, text, preserve) {
+ const contrast = getContrastRatio(bg, text)
+
+ if (contrast < 4.5) {
+ const base = typeof text.a !== 'undefined' ? { a: text.a } : {}
+ const result = Object.assign(base, invertLightness(text).rgb)
+ if (!preserve && getContrastRatio(bg, result) < 4.5) {
+ // B&W
+ return contrastRatio(bg, text).rgb
+ }
+ // Inverted color
+ return result
+ }
+ return text
+}
+
+/**
+ * Converts color to CSS Color value
+ *
+ * @param {Object|String} input - color
+ * @param {Number} [a] - alpha value
+ * @returns {String} a CSS Color value
+ */
+export const getCssColor = (input, a) => {
+ let rgb = {}
+ if (typeof input === 'object') {
+ rgb = input
+ } else if (typeof input === 'string') {
+ if (input.startsWith('#')) {
+ rgb = hex2rgb(input)
+ } else {
+ return input
+ }
+ }
+ return rgba2css({ ...rgb, a })
}
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index 84169a7b..c7ed65a4 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -1,4 +1,5 @@
import escape from 'escape-html'
+import { isStatusNotification } from '../notification_utils/notification_utils.js'
const qvitterStatusType = (status) => {
if (status.is_post_verb) {
@@ -74,13 +75,7 @@ export const parseUser = (data) => {
output.token = data.pleroma.chat_token
if (relationship) {
- output.follows_you = relationship.followed_by
- output.requested = relationship.requested
- output.following = relationship.following
- output.statusnet_blocking = relationship.blocking
- output.muted = relationship.muting
- output.showing_reblogs = relationship.showing_reblogs
- output.subscribed = relationship.subscribing
+ output.relationship = relationship
}
output.allow_following_move = data.pleroma.allow_following_move
@@ -137,16 +132,10 @@ export const parseUser = (data) => {
output.statusnet_profile_url = data.statusnet_profile_url
- output.statusnet_blocking = data.statusnet_blocking
-
output.is_local = data.is_local
output.role = data.role
output.show_role = data.show_role
- output.follows_you = data.follows_you
-
- output.muted = data.muted
-
if (data.rights) {
output.rights = {
moderator: data.rights.delete_others_notice,
@@ -160,10 +149,16 @@ export const parseUser = (data) => {
output.hide_follows_count = data.hide_follows_count
output.hide_followers_count = data.hide_followers_count
output.background_image = data.background_image
- // on mastoapi this info is contained in a "relationship"
- output.following = data.following
// Websocket token
output.token = data.token
+
+ // Convert relationsip data to expected format
+ output.relationship = {
+ muting: data.muted,
+ blocking: data.statusnet_blocking,
+ followed_by: data.follows_you,
+ following: data.following
+ }
}
output.created_at = new Date(data.created_at)
@@ -215,7 +210,7 @@ export const addEmojis = (string, emojis) => {
const regexSafeShortCode = emoji.shortcode.replace(matchOperatorsRegex, '\\$&')
return acc.replace(
new RegExp(`:${regexSafeShortCode}:`, 'g'),
- ``
+ ``
)
}, string)
}
@@ -346,9 +341,7 @@ export const parseNotification = (data) => {
if (masto) {
output.type = mastoDict[data.type] || data.type
output.seen = data.pleroma.is_seen
- output.status = output.type === 'follow' || output.type === 'move'
- ? null
- : parseStatus(data.status)
+ output.status = isStatusNotification(output.type) ? parseStatus(data.status) : null
output.action = output.status // TODO: Refactor, this is unneeded
output.target = output.type !== 'move'
? null
diff --git a/src/services/follow_manipulate/follow_manipulate.js b/src/services/follow_manipulate/follow_manipulate.js
index 29b38a0f..08f4c4d6 100644
--- a/src/services/follow_manipulate/follow_manipulate.js
+++ b/src/services/follow_manipulate/follow_manipulate.js
@@ -1,24 +1,27 @@
-const fetchUser = (attempt, user, store) => new Promise((resolve, reject) => {
+const fetchRelationship = (attempt, userId, store) => new Promise((resolve, reject) => {
setTimeout(() => {
- store.state.api.backendInteractor.fetchUser({ id: user.id })
- .then((user) => store.commit('addNewUsers', [user]))
- .then(() => resolve([user.following, user.requested, user.locked, attempt]))
+ store.state.api.backendInteractor.fetchUserRelationship({ id: userId })
+ .then((relationship) => {
+ store.commit('updateUserRelationship', [relationship])
+ return relationship
+ })
+ .then((relationship) => resolve([relationship.following, relationship.requested, relationship.locked, attempt]))
.catch((e) => reject(e))
}, 500)
}).then(([following, sent, locked, attempt]) => {
if (!following && !(locked && sent) && attempt <= 3) {
// If we BE reports that we still not following that user - retry,
// increment attempts by one
- fetchUser(++attempt, user, store)
+ fetchRelationship(++attempt, userId, store)
}
})
-export const requestFollow = (user, store) => new Promise((resolve, reject) => {
- store.state.api.backendInteractor.followUser({ id: user.id })
+export const requestFollow = (userId, store) => new Promise((resolve, reject) => {
+ store.state.api.backendInteractor.followUser({ id: userId })
.then((updated) => {
store.commit('updateUserRelationship', [updated])
- if (updated.following || (user.locked && user.requested)) {
+ if (updated.following || (updated.locked && updated.requested)) {
// If we get result immediately or the account is locked, just stop.
resolve()
return
@@ -31,15 +34,15 @@ export const requestFollow = (user, store) => new Promise((resolve, reject) => {
// don't know that yet.
// Recursive Promise, it will call itself up to 3 times.
- return fetchUser(1, user, store)
+ return fetchRelationship(1, updated, store)
.then(() => {
resolve()
})
})
})
-export const requestUnfollow = (user, store) => new Promise((resolve, reject) => {
- store.state.api.backendInteractor.unfollowUser({ id: user.id })
+export const requestUnfollow = (userId, store) => new Promise((resolve, reject) => {
+ store.state.api.backendInteractor.unfollowUser({ id: userId })
.then((updated) => {
store.commit('updateUserRelationship', [updated])
resolve({
diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js
index b17bd7bf..eb479227 100644
--- a/src/services/notification_utils/notification_utils.js
+++ b/src/services/notification_utils/notification_utils.js
@@ -1,4 +1,4 @@
-import { filter, sortBy } from 'lodash'
+import { filter, sortBy, includes } from 'lodash'
export const notificationsFromStore = store => store.state.statuses.notifications.data
@@ -7,10 +7,15 @@ export const visibleTypes = store => ([
store.state.config.notificationVisibility.mentions && 'mention',
store.state.config.notificationVisibility.repeats && 'repeat',
store.state.config.notificationVisibility.follows && 'follow',
+ store.state.config.notificationVisibility.followRequest && 'follow_request',
store.state.config.notificationVisibility.moves && 'move',
store.state.config.notificationVisibility.emojiReactions && 'pleroma:emoji_reaction'
].filter(_ => _))
+const statusNotifications = ['like', 'mention', 'repeat', 'pleroma:emoji_reaction']
+
+export const isStatusNotification = (type) => includes(statusNotifications, type)
+
const sortById = (a, b) => {
const seqA = Number(a.id)
const seqB = Number(b.id)
diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js
index 864e32f8..64499a1b 100644
--- a/src/services/notifications_fetcher/notifications_fetcher.service.js
+++ b/src/services/notifications_fetcher/notifications_fetcher.service.js
@@ -11,12 +11,9 @@ const fetchAndUpdate = ({ store, credentials, older = false }) => {
const rootState = store.rootState || store.state
const timelineData = rootState.statuses.notifications
const hideMutedPosts = getters.mergedConfig.hideMutedPosts
- const allowFollowingMove = rootState.users.currentUser.allow_following_move
args['withMuted'] = !hideMutedPosts
- args['withMove'] = !allowFollowingMove
-
args['timeline'] = 'notifications'
if (older) {
if (timelineData.minId !== Number.POSITIVE_INFINITY) {
diff --git a/src/services/resettable_async_component.js b/src/services/resettable_async_component.js
new file mode 100644
index 00000000..517bbd88
--- /dev/null
+++ b/src/services/resettable_async_component.js
@@ -0,0 +1,32 @@
+import Vue from 'vue'
+
+/* By default async components don't have any way to recover, if component is
+ * failed, it is failed forever. This helper tries to remedy that by recreating
+ * async component when retry is requested (by user). You need to emit the
+ * `resetAsyncComponent` event from child to reset the component. Generally,
+ * this should be done from error component but could be done from loading or
+ * actual target component itself if needs to be.
+ */
+function getResettableAsyncComponent (asyncComponent, options) {
+ const asyncComponentFactory = () => () => ({
+ component: asyncComponent(),
+ ...options
+ })
+
+ const observe = Vue.observable({ c: asyncComponentFactory() })
+
+ return {
+ functional: true,
+ render (createElement, { data, children }) {
+ // emit event resetAsyncComponent to reloading
+ data.on = {}
+ data.on.resetAsyncComponent = () => {
+ observe.c = asyncComponentFactory()
+ // parent.$forceUpdate()
+ }
+ return createElement(observe.c, data, children)
+ }
+ }
+}
+
+export default getResettableAsyncComponent
diff --git a/src/services/status_parser/status_parser.js b/src/services/status_parser/status_parser.js
index 900cd56e..ed0f6d57 100644
--- a/src/services/status_parser/status_parser.js
+++ b/src/services/status_parser/status_parser.js
@@ -1,15 +1,11 @@
-import sanitize from 'sanitize-html'
+import { filter } from 'lodash'
-export const removeAttachmentLinks = (html) => {
- return sanitize(html, {
- allowedTags: false,
- allowedAttributes: false,
- exclusiveFilter: ({ tag, attribs }) => tag === 'a' && typeof attribs.class === 'string' && attribs.class.match(/attachment/)
+export const muteWordHits = (status, muteWords) => {
+ const statusText = status.text.toLowerCase()
+ const statusSummary = status.summary.toLowerCase()
+ const hits = filter(muteWords, (muteWord) => {
+ return statusText.includes(muteWord.toLowerCase()) || statusSummary.includes(muteWord.toLowerCase())
})
-}
-export const parse = (html) => {
- return removeAttachmentLinks(html)
+ return hits
}
-
-export default parse
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index eaa495c4..fbdcf562 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -1,78 +1,9 @@
-import { times } from 'lodash'
-import { brightness, invertLightness, convert, contrastRatio } from 'chromatism'
-import { rgb2hex, hex2rgb, mixrgb, getContrastRatio, alphaBlend } from '../color_convert/color_convert.js'
+import { convert } from 'chromatism'
+import { rgb2hex, hex2rgb, rgba2css, getCssColor, relativeLuminance } from '../color_convert/color_convert.js'
+import { getColors, computeDynamicColor, getOpacitySlot } from '../theme_data/theme_data.service.js'
-// While this is not used anymore right now, I left it in if we want to do custom
-// styles that aren't just colors, so user can pick from a few different distinct
-// styles as well as set their own colors in the future.
-
-const setStyle = (href, commit) => {
- /***
- What's going on here?
- I want to make it easy for admins to style this application. To have
- a good set of default themes, I chose the system from base16
- (https://chriskempson.github.io/base16/) to style all elements. They
- all have the base00..0F classes. So the only thing an admin needs to
- do to style Pleroma is to change these colors in that one css file.
- Some default things (body text color, link color) need to be set dy-
- namically, so this is done here by waiting for the stylesheet to be
- loaded and then creating an element with the respective classes.
-
- It is a bit weird, but should make life for admins somewhat easier.
- ***/
- const head = document.head
- const body = document.body
- body.classList.add('hidden')
- const cssEl = document.createElement('link')
- cssEl.setAttribute('rel', 'stylesheet')
- cssEl.setAttribute('href', href)
- head.appendChild(cssEl)
-
- const setDynamic = () => {
- const baseEl = document.createElement('div')
- body.appendChild(baseEl)
-
- let colors = {}
- times(16, (n) => {
- const name = `base0${n.toString(16).toUpperCase()}`
- baseEl.setAttribute('class', name)
- const color = window.getComputedStyle(baseEl).getPropertyValue('color')
- colors[name] = color
- })
-
- body.removeChild(baseEl)
-
- const styleEl = document.createElement('style')
- head.appendChild(styleEl)
- // const styleSheet = styleEl.sheet
-
- body.classList.remove('hidden')
- }
-
- cssEl.addEventListener('load', setDynamic)
-}
-
-const rgb2rgba = function (rgba) {
- return `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`
-}
-
-const getTextColor = function (bg, text, preserve) {
- const bgIsLight = convert(bg).hsl.l > 50
- const textIsLight = convert(text).hsl.l > 50
-
- if ((bgIsLight && textIsLight) || (!bgIsLight && !textIsLight)) {
- const base = typeof text.a !== 'undefined' ? { a: text.a } : {}
- const result = Object.assign(base, invertLightness(text).rgb)
- if (!preserve && getContrastRatio(bg, result) < 4.5) {
- return contrastRatio(bg, text).rgb
- }
- return result
- }
- return text
-}
-
-const applyTheme = (input, commit) => {
- const { rules, theme } = generatePreset(input)
+export const applyTheme = (input) => {
+ const { rules } = generatePreset(input)
const head = document.head
const body = document.body
body.classList.add('hidden')
@@ -87,14 +18,9 @@ const applyTheme = (input, commit) => {
styleSheet.insertRule(`body { ${rules.shadows} }`, 'index-max')
styleSheet.insertRule(`body { ${rules.fonts} }`, 'index-max')
body.classList.remove('hidden')
-
- // commit('setOption', { name: 'colors', value: htmlColors })
- // commit('setOption', { name: 'radii', value: radii })
- commit('setOption', { name: 'customTheme', value: input })
- commit('setOption', { name: 'colors', value: theme.colors })
}
-const getCssShadow = (input, usesDropShadow) => {
+export const getCssShadow = (input, usesDropShadow) => {
if (input.length === 0) {
return 'none'
}
@@ -132,122 +58,18 @@ const getCssShadowFilter = (input) => {
.join(' ')
}
-const getCssColor = (input, a) => {
- let rgb = {}
- if (typeof input === 'object') {
- rgb = input
- } else if (typeof input === 'string') {
- if (input.startsWith('#')) {
- rgb = hex2rgb(input)
- } else if (input.startsWith('--')) {
- return `var(${input})`
- } else {
- return input
- }
- }
- return rgb2rgba({ ...rgb, a })
-}
+export const generateColors = (themeData) => {
+ const sourceColors = !themeData.themeEngineVersion
+ ? colors2to3(themeData.colors || themeData)
+ : themeData.colors || themeData
-const generateColors = (input) => {
- const colors = {}
- const opacity = Object.assign({
- alert: 0.5,
- input: 0.5,
- faint: 0.5
- }, Object.entries(input.opacity || {}).reduce((acc, [k, v]) => {
- if (typeof v !== 'undefined') {
- acc[k] = v
- }
- return acc
- }, {}))
- const col = Object.entries(input.colors || input).reduce((acc, [k, v]) => {
- if (typeof v === 'object') {
- acc[k] = v
- } else {
- acc[k] = hex2rgb(v)
- }
- return acc
- }, {})
-
- const isLightOnDark = convert(col.bg).hsl.l < convert(col.text).hsl.l
- const mod = isLightOnDark ? 1 : -1
-
- colors.text = col.text
- colors.lightText = brightness(20 * mod, colors.text).rgb
- colors.link = col.link
- colors.faint = col.faint || Object.assign({}, col.text)
-
- colors.bg = col.bg
- colors.lightBg = col.lightBg || brightness(5, colors.bg).rgb
-
- colors.fg = col.fg
- colors.fgText = col.fgText || getTextColor(colors.fg, colors.text)
- colors.fgLink = col.fgLink || getTextColor(colors.fg, colors.link, true)
-
- colors.border = col.border || brightness(2 * mod, colors.fg).rgb
-
- colors.btn = col.btn || Object.assign({}, col.fg)
- colors.btnText = col.btnText || getTextColor(colors.btn, colors.fgText)
-
- colors.input = col.input || Object.assign({}, col.fg)
- colors.inputText = col.inputText || getTextColor(colors.input, colors.lightText)
-
- colors.panel = col.panel || Object.assign({}, col.fg)
- colors.panelText = col.panelText || getTextColor(colors.panel, colors.fgText)
- colors.panelLink = col.panelLink || getTextColor(colors.panel, colors.fgLink)
- colors.panelFaint = col.panelFaint || getTextColor(colors.panel, colors.faint)
-
- colors.topBar = col.topBar || Object.assign({}, col.fg)
- colors.topBarText = col.topBarText || getTextColor(colors.topBar, colors.fgText)
- colors.topBarLink = col.topBarLink || getTextColor(colors.topBar, colors.fgLink)
-
- colors.faintLink = col.faintLink || Object.assign({}, col.link)
- colors.linkBg = alphaBlend(colors.link, 0.4, colors.bg)
-
- colors.icon = mixrgb(colors.bg, colors.text)
-
- colors.cBlue = col.cBlue || hex2rgb('#0000FF')
- colors.cRed = col.cRed || hex2rgb('#FF0000')
- colors.cGreen = col.cGreen || hex2rgb('#00FF00')
- colors.cOrange = col.cOrange || hex2rgb('#E3FF00')
-
- colors.alertError = col.alertError || Object.assign({}, colors.cRed)
- colors.alertErrorText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.bg), colors.text)
- colors.alertErrorPanelText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.panel), colors.panelText)
-
- colors.alertWarning = col.alertWarning || Object.assign({}, colors.cOrange)
- colors.alertWarningText = getTextColor(alphaBlend(colors.alertWarning, opacity.alert, colors.bg), colors.text)
- colors.alertWarningPanelText = getTextColor(alphaBlend(colors.alertWarning, opacity.alert, colors.panel), colors.panelText)
-
- colors.badgeNotification = col.badgeNotification || Object.assign({}, colors.cRed)
- colors.badgeNotificationText = contrastRatio(colors.badgeNotification).rgb
-
- Object.entries(opacity).forEach(([ k, v ]) => {
- if (typeof v === 'undefined') return
- if (k === 'alert') {
- colors.alertError.a = v
- colors.alertWarning.a = v
- return
- }
- if (k === 'faint') {
- colors[k + 'Link'].a = v
- colors['panelFaint'].a = v
- }
- if (k === 'bg') {
- colors['lightBg'].a = v
- }
- if (colors[k]) {
- colors[k].a = v
- } else {
- console.error('Wrong key ' + k)
- }
- })
+ const { colors, opacity } = getColors(sourceColors, themeData.opacity || {})
const htmlColors = Object.entries(colors)
.reduce((acc, [k, v]) => {
if (!v) return acc
acc.solid[k] = rgb2hex(v)
- acc.complete[k] = typeof v.a === 'undefined' ? rgb2hex(v) : rgb2rgba(v)
+ acc.complete[k] = typeof v.a === 'undefined' ? rgb2hex(v) : rgba2css(v)
return acc
}, { complete: {}, solid: {} })
return {
@@ -264,7 +86,7 @@ const generateColors = (input) => {
}
}
-const generateRadii = (input) => {
+export const generateRadii = (input) => {
let inputRadii = input.radii || {}
// v1 -> v2
if (typeof input.btnRadius !== 'undefined') {
@@ -297,7 +119,7 @@ const generateRadii = (input) => {
}
}
-const generateFonts = (input) => {
+export const generateFonts = (input) => {
const fonts = Object.entries(input.fonts || {}).filter(([k, v]) => v).reduce((acc, [k, v]) => {
acc[k] = Object.entries(v).filter(([k, v]) => v).reduce((acc, [k, v]) => {
acc[k] = v
@@ -332,89 +154,123 @@ const generateFonts = (input) => {
}
}
-const generateShadows = (input) => {
- const border = (top, shadow) => ({
- x: 0,
- y: top ? 1 : -1,
- blur: 0,
+const border = (top, shadow) => ({
+ x: 0,
+ y: top ? 1 : -1,
+ blur: 0,
+ spread: 0,
+ color: shadow ? '#000000' : '#FFFFFF',
+ alpha: 0.2,
+ inset: true
+})
+const buttonInsetFakeBorders = [border(true, false), border(false, true)]
+const inputInsetFakeBorders = [border(true, true), border(false, false)]
+const hoverGlow = {
+ x: 0,
+ y: 0,
+ blur: 4,
+ spread: 0,
+ color: '--faint',
+ alpha: 1
+}
+
+export const DEFAULT_SHADOWS = {
+ panel: [{
+ x: 1,
+ y: 1,
+ blur: 4,
spread: 0,
- color: shadow ? '#000000' : '#FFFFFF',
- alpha: 0.2,
- inset: true
- })
- const buttonInsetFakeBorders = [border(true, false), border(false, true)]
- const inputInsetFakeBorders = [border(true, true), border(false, false)]
- const hoverGlow = {
+ color: '#000000',
+ alpha: 0.6
+ }],
+ topBar: [{
x: 0,
y: 0,
blur: 4,
spread: 0,
- color: '--faint',
+ color: '#000000',
+ alpha: 0.6
+ }],
+ popup: [{
+ x: 2,
+ y: 2,
+ blur: 3,
+ spread: 0,
+ color: '#000000',
+ alpha: 0.5
+ }],
+ avatar: [{
+ x: 0,
+ y: 1,
+ blur: 8,
+ spread: 0,
+ color: '#000000',
+ alpha: 0.7
+ }],
+ avatarStatus: [],
+ panelHeader: [],
+ button: [{
+ x: 0,
+ y: 0,
+ blur: 2,
+ spread: 0,
+ color: '#000000',
alpha: 1
+ }, ...buttonInsetFakeBorders],
+ buttonHover: [hoverGlow, ...buttonInsetFakeBorders],
+ buttonPressed: [hoverGlow, ...inputInsetFakeBorders],
+ input: [...inputInsetFakeBorders, {
+ x: 0,
+ y: 0,
+ blur: 2,
+ inset: true,
+ spread: 0,
+ color: '#000000',
+ alpha: 1
+ }]
+}
+export const generateShadows = (input, colors) => {
+ // TODO this is a small hack for `mod` to work with shadows
+ // this is used to get the "context" of shadow, i.e. for `mod` properly depend on background color of element
+ const hackContextDict = {
+ button: 'btn',
+ panel: 'bg',
+ top: 'topBar',
+ popup: 'popover',
+ avatar: 'bg',
+ panelHeader: 'panel',
+ input: 'input'
}
-
- const shadows = {
- panel: [{
- x: 1,
- y: 1,
- blur: 4,
- spread: 0,
- color: '#000000',
- alpha: 0.6
- }],
- topBar: [{
- x: 0,
- y: 0,
- blur: 4,
- spread: 0,
- color: '#000000',
- alpha: 0.6
- }],
- popup: [{
- x: 2,
- y: 2,
- blur: 3,
- spread: 0,
- color: '#000000',
- alpha: 0.5
- }],
- avatar: [{
- x: 0,
- y: 1,
- blur: 8,
- spread: 0,
- color: '#000000',
- alpha: 0.7
- }],
- avatarStatus: [],
- panelHeader: [],
- button: [{
- x: 0,
- y: 0,
- blur: 2,
- spread: 0,
- color: '#000000',
- alpha: 1
- }, ...buttonInsetFakeBorders],
- buttonHover: [hoverGlow, ...buttonInsetFakeBorders],
- buttonPressed: [hoverGlow, ...inputInsetFakeBorders],
- input: [...inputInsetFakeBorders, {
- x: 0,
- y: 0,
- blur: 2,
- inset: true,
- spread: 0,
- color: '#000000',
- alpha: 1
- }],
- ...(input.shadows || {})
- }
+ const inputShadows = input.shadows && !input.themeEngineVersion
+ ? shadows2to3(input.shadows, input.opacity)
+ : input.shadows || {}
+ const shadows = Object.entries({
+ ...DEFAULT_SHADOWS,
+ ...inputShadows
+ }).reduce((shadowsAcc, [slotName, shadowDefs]) => {
+ const slotFirstWord = slotName.replace(/[A-Z].*$/, '')
+ const colorSlotName = hackContextDict[slotFirstWord]
+ const isLightOnDark = relativeLuminance(convert(colors[colorSlotName]).rgb) < 0.5
+ const mod = isLightOnDark ? 1 : -1
+ const newShadow = shadowDefs.reduce((shadowAcc, def) => [
+ ...shadowAcc,
+ {
+ ...def,
+ color: rgb2hex(computeDynamicColor(
+ def.color,
+ (variableSlot) => convert(colors[variableSlot]).rgb,
+ mod
+ ))
+ }
+ ], [])
+ return { ...shadowsAcc, [slotName]: newShadow }
+ }, {})
return {
rules: {
shadows: Object
.entries(shadows)
- // TODO for v2.1: if shadow doesn't have non-inset shadows with spread > 0 - optionally
+ // TODO for v2.2: if shadow doesn't have non-inset shadows with spread > 0 - optionally
// convert all non-inset shadows into filter: drop-shadow() to boost performance
.map(([k, v]) => [
`--${k}Shadow: ${getCssShadow(v)}`,
@@ -429,7 +285,7 @@ const generateShadows = (input) => {
}
}
-const composePreset = (colors, radii, shadows, fonts) => {
+export const composePreset = (colors, radii, shadows, fonts) => {
return {
rules: {
...shadows.rules,
@@ -446,98 +302,110 @@ const composePreset = (colors, radii, shadows, fonts) => {
}
}
-const generatePreset = (input) => {
- const shadows = generateShadows(input)
+export const generatePreset = (input) => {
const colors = generateColors(input)
- const radii = generateRadii(input)
- const fonts = generateFonts(input)
-
- return composePreset(colors, radii, shadows, fonts)
+ return composePreset(
+ colors,
+ generateRadii(input),
+ generateShadows(input, colors.theme.colors, colors.mod),
+ generateFonts(input)
+ )
}
-const getThemes = () => {
- return window.fetch('/static/styles.json')
+export const getThemes = () => {
+ const cache = 'no-store'
+
+ return window.fetch('/static/styles.json', { cache })
.then((data) => data.json())
.then((themes) => {
- return Promise.all(Object.entries(themes).map(([k, v]) => {
+ return Object.entries(themes).map(([k, v]) => {
+ let promise = null
if (typeof v === 'object') {
- return Promise.resolve([k, v])
+ promise = Promise.resolve(v)
} else if (typeof v === 'string') {
- return window.fetch(v)
+ promise = window.fetch(v, { cache })
.then((data) => data.json())
- .then((theme) => {
- return [k, theme]
- })
.catch((e) => {
console.error(e)
- return []
+ return null
})
}
- }))
+ return [k, promise]
+ })
})
.then((promises) => {
return promises
- .filter(([k, v]) => v)
.reduce((acc, [k, v]) => {
acc[k] = v
return acc
}, {})
})
}
+export const colors2to3 = (colors) => {
+ return Object.entries(colors).reduce((acc, [slotName, color]) => {
+ const btnPositions = ['', 'Panel', 'TopBar']
+ switch (slotName) {
+ case 'lightBg':
+ return { ...acc, highlight: color }
+ case 'btnText':
+ return {
+ ...acc,
+ ...btnPositions
+ .reduce(
+ (statePositionAcc, position) =>
+ ({ ...statePositionAcc, ['btn' + position + 'Text']: color })
+ , {}
+ )
+ }
+ default:
+ return { ...acc, [slotName]: color }
+ }
+ }, {})
+}
-const setPreset = (val, commit) => {
- return getThemes().then((themes) => {
- const theme = themes[val] ? themes[val] : themes['pleroma-dark']
- const isV1 = Array.isArray(theme)
- const data = isV1 ? {} : theme.theme
-
- if (isV1) {
- const bgRgb = hex2rgb(theme[1])
- const fgRgb = hex2rgb(theme[2])
- const textRgb = hex2rgb(theme[3])
- const linkRgb = hex2rgb(theme[4])
-
- const cRedRgb = hex2rgb(theme[5] || '#FF0000')
- const cGreenRgb = hex2rgb(theme[6] || '#00FF00')
- const cBlueRgb = hex2rgb(theme[7] || '#0000FF')
- const cOrangeRgb = hex2rgb(theme[8] || '#E3FF00')
-
- data.colors = {
- bg: bgRgb,
- fg: fgRgb,
- text: textRgb,
- link: linkRgb,
- cRed: cRedRgb,
- cBlue: cBlueRgb,
- cGreen: cGreenRgb,
- cOrange: cOrangeRgb
+/**
+ * This handles compatibility issues when importing v2 theme's shadows to current format
+ *
+ * Back in v2 shadows allowed you to use dynamic colors however those used pure CSS3 variables
+ */
+export const shadows2to3 = (shadows, opacity) => {
+ return Object.entries(shadows).reduce((shadowsAcc, [slotName, shadowDefs]) => {
+ const isDynamic = ({ color }) => color.startsWith('--')
+ const getOpacity = ({ color }) => opacity[getOpacitySlot(color.substring(2).split(',')[0])]
+ const newShadow = shadowDefs.reduce((shadowAcc, def) => [
+ ...shadowAcc,
+ {
+ ...def,
+ alpha: isDynamic(def) ? getOpacity(def) || 1 : def.alpha
}
- }
-
- // This is a hack, this function is only called during initial load.
- // We want to cancel loading the theme from config.json if we're already
- // loading a theme from the persisted state.
- // Needed some way of dealing with the async way of things.
- // load config -> set preset -> wait for styles.json to load ->
- // load persisted state -> set colors -> styles.json loaded -> set colors
- if (!window.themeLoaded) {
- applyTheme(data, commit)
- }
- })
+ ], [])
+ return { ...shadowsAcc, [slotName]: newShadow }
+ }, {})
}
-export {
- setStyle,
- setPreset,
- applyTheme,
- getTextColor,
- generateColors,
- generateRadii,
- generateShadows,
- generateFonts,
- generatePreset,
- getThemes,
- composePreset,
- getCssShadow,
- getCssShadowFilter
+export const getPreset = (val) => {
+ return getThemes()
+ .then((themes) => themes[val] ? themes[val] : themes['pleroma-dark'])
+ .then((theme) => {
+ const isV1 = Array.isArray(theme)
+ const data = isV1 ? {} : theme.theme
+
+ if (isV1) {
+ const bg = hex2rgb(theme[1])
+ const fg = hex2rgb(theme[2])
+ const text = hex2rgb(theme[3])
+ const link = hex2rgb(theme[4])
+
+ const cRed = hex2rgb(theme[5] || '#FF0000')
+ const cGreen = hex2rgb(theme[6] || '#00FF00')
+ const cBlue = hex2rgb(theme[7] || '#0000FF')
+ const cOrange = hex2rgb(theme[8] || '#E3FF00')
+
+ data.colors = { bg, fg, text, link, cRed, cBlue, cGreen, cOrange }
+ }
+
+ return { theme: data, source: theme.source }
+ })
}
+
+export const setPreset = (val) => getPreset(val).then(data => applyTheme(data.theme))
diff --git a/src/services/theme_data/pleromafe.js b/src/services/theme_data/pleromafe.js
new file mode 100644
index 00000000..b577cfab
--- /dev/null
+++ b/src/services/theme_data/pleromafe.js
@@ -0,0 +1,637 @@
+import { invertLightness, brightness } from 'chromatism'
+import { alphaBlend, mixrgb } from '../color_convert/color_convert.js'
+/* This is a definition of all layer combinations
+ * each key is a topmost layer, each value represents layer underneath
+ * this is essentially a simplified tree
+ */
+export const LAYERS = {
+ undelay: null, // root
+ topBar: null, // no transparency support
+ badge: null, // no transparency support
+ profileTint: null, // doesn't matter
+ fg: null,
+ bg: 'underlay',
+ highlight: 'bg',
+ panel: 'bg',
+ popover: 'bg',
+ selectedMenu: 'popover',
+ btn: 'bg',
+ btnPanel: 'panel',
+ btnTopBar: 'topBar',
+ input: 'bg',
+ inputPanel: 'panel',
+ inputTopBar: 'topBar',
+ alert: 'bg',
+ alertPanel: 'panel',
+ poll: 'bg'
+}
+
+/* By default opacity slots have 1 as default opacity
+ * this allows redefining it to something else
+ */
+export const DEFAULT_OPACITY = {
+ profileTint: 0.5,
+ alert: 0.5,
+ input: 0.5,
+ faint: 0.5,
+ underlay: 0.15
+}
+
+/** SUBJECT TO CHANGE IN THE FUTURE, this is all beta
+ * Color and opacity slots definitions. Each key represents a slot.
+ *
+ * Short-hands:
+ * String beginning with `--` - value after dashes treated as sole
+ * dependency - i.e. `--value` equivalent to { depends: ['value']}
+ * String beginning with `#` - value would be treated as solid color
+ * defined in hexadecimal representation (i.e. #FFFFFF) and will be
+ * used as default. `#FFFFFF` is equivalent to { default: '#FFFFFF'}
+ *
+ * Full definition:
+ * @property {String[]} depends - color slot names this color depends ones.
+ * cyclic dependencies are supported to some extent but not recommended.
+ * @property {String} [opacity] - opacity slot used by this color slot.
+ * opacity is inherited from parents. To break inheritance graph use null
+ * @property {Number} [priority] - EXPERIMENTAL. used to pre-sort slots so
+ * that slots with higher priority come earlier
+ * @property {Function(mod, ...colors)} [color] - function that will be
+ * used to determine the color. By default it just copies first color in
+ * dependency list.
+ * @argument {Number} mod - `1` (light-on-dark) or `-1` (dark-on-light)
+ * depending on background color (for textColor)/given color.
+ * @argument {...Object} deps - each argument after mod represents each
+ * color from `depends` array. All colors take user customizations into
+ * account and represented by { r, g, b } objects.
+ * @returns {Object} resulting color, should be in { r, g, b } form
+ *
+ * @property {Boolean|String} [textColor] - true to mark color slot as text
+ * color. This enables automatic text color generation for the slot. Use
+ * 'preserve' string if you don't want text color to fall back to
+ * black/white. Use 'bw' to only ever use black or white. This also makes
+ * following properties required:
+ * @property {String} [layer] - which layer the text sit on top on - used
+ * to account for transparency in text color calculation
+ * layer is inherited from parents. To break inheritance graph use null
+ * @property {String} [variant] - which color slot is background (same as
+ * above, used to account for transparency)
+ */
+export const SLOT_INHERITANCE = {
+ bg: {
+ depends: [],
+ opacity: 'bg',
+ priority: 1
+ },
+ fg: {
+ depends: [],
+ priority: 1
+ },
+ text: {
+ depends: [],
+ layer: 'bg',
+ opacity: null,
+ priority: 1
+ },
+ underlay: {
+ default: '#000000',
+ opacity: 'underlay'
+ },
+ link: {
+ depends: ['accent'],
+ priority: 1
+ },
+ accent: {
+ depends: ['link'],
+ priority: 1
+ },
+ faint: {
+ depends: ['text'],
+ opacity: 'faint'
+ },
+ faintLink: {
+ depends: ['link'],
+ opacity: 'faint'
+ },
+ postFaintLink: {
+ depends: ['postLink'],
+ opacity: 'faint'
+ },
+
+ cBlue: '#0000ff',
+ cRed: '#FF0000',
+ cGreen: '#00FF00',
+ cOrange: '#E3FF00',
+
+ profileBg: {
+ depends: ['bg'],
+ color: (mod, bg) => ({
+ r: Math.floor(bg.r * 0.53),
+ g: Math.floor(bg.g * 0.56),
+ b: Math.floor(bg.b * 0.59)
+ })
+ },
+ profileTint: {
+ depends: ['bg'],
+ layer: 'profileTint',
+ opacity: 'profileTint'
+ },
+
+ highlight: {
+ depends: ['bg'],
+ color: (mod, bg) => brightness(5 * mod, bg).rgb
+ },
+ highlightLightText: {
+ depends: ['lightText'],
+ layer: 'highlight',
+ textColor: true
+ },
+ highlightPostLink: {
+ depends: ['postLink'],
+ layer: 'highlight',
+ textColor: 'preserve'
+ },
+ highlightFaintText: {
+ depends: ['faint'],
+ layer: 'highlight',
+ textColor: true
+ },
+ highlightFaintLink: {
+ depends: ['faintLink'],
+ layer: 'highlight',
+ textColor: 'preserve'
+ },
+ highlightPostFaintLink: {
+ depends: ['postFaintLink'],
+ layer: 'highlight',
+ textColor: 'preserve'
+ },
+ highlightText: {
+ depends: ['text'],
+ layer: 'highlight',
+ textColor: true
+ },
+ highlightLink: {
+ depends: ['link'],
+ layer: 'highlight',
+ textColor: 'preserve'
+ },
+ highlightIcon: {
+ depends: ['highlight', 'highlightText'],
+ color: (mod, bg, text) => mixrgb(bg, text)
+ },
+
+ popover: {
+ depends: ['bg'],
+ opacity: 'popover'
+ },
+ popoverLightText: {
+ depends: ['lightText'],
+ layer: 'popover',
+ textColor: true
+ },
+ popoverPostLink: {
+ depends: ['postLink'],
+ layer: 'popover',
+ textColor: 'preserve'
+ },
+ popoverFaintText: {
+ depends: ['faint'],
+ layer: 'popover',
+ textColor: true
+ },
+ popoverFaintLink: {
+ depends: ['faintLink'],
+ layer: 'popover',
+ textColor: 'preserve'
+ },
+ popoverPostFaintLink: {
+ depends: ['postFaintLink'],
+ layer: 'popover',
+ textColor: 'preserve'
+ },
+ popoverText: {
+ depends: ['text'],
+ layer: 'popover',
+ textColor: true
+ },
+ popoverLink: {
+ depends: ['link'],
+ layer: 'popover',
+ textColor: 'preserve'
+ },
+ popoverIcon: {
+ depends: ['popover', 'popoverText'],
+ color: (mod, bg, text) => mixrgb(bg, text)
+ },
+
+ selectedPost: '--highlight',
+ selectedPostFaintText: {
+ depends: ['highlightFaintText'],
+ layer: 'highlight',
+ variant: 'selectedPost',
+ textColor: true
+ },
+ selectedPostLightText: {
+ depends: ['highlightLightText'],
+ layer: 'highlight',
+ variant: 'selectedPost',
+ textColor: true
+ },
+ selectedPostPostLink: {
+ depends: ['highlightPostLink'],
+ layer: 'highlight',
+ variant: 'selectedPost',
+ textColor: 'preserve'
+ },
+ selectedPostFaintLink: {
+ depends: ['highlightFaintLink'],
+ layer: 'highlight',
+ variant: 'selectedPost',
+ textColor: 'preserve'
+ },
+ selectedPostText: {
+ depends: ['highlightText'],
+ layer: 'highlight',
+ variant: 'selectedPost',
+ textColor: true
+ },
+ selectedPostLink: {
+ depends: ['highlightLink'],
+ layer: 'highlight',
+ variant: 'selectedPost',
+ textColor: 'preserve'
+ },
+ selectedPostIcon: {
+ depends: ['selectedPost', 'selectedPostText'],
+ color: (mod, bg, text) => mixrgb(bg, text)
+ },
+
+ selectedMenu: {
+ depends: ['bg'],
+ color: (mod, bg) => brightness(5 * mod, bg).rgb
+ },
+ selectedMenuLightText: {
+ depends: ['highlightLightText'],
+ layer: 'selectedMenu',
+ variant: 'selectedMenu',
+ textColor: true
+ },
+ selectedMenuFaintText: {
+ depends: ['highlightFaintText'],
+ layer: 'selectedMenu',
+ variant: 'selectedMenu',
+ textColor: true
+ },
+ selectedMenuFaintLink: {
+ depends: ['highlightFaintLink'],
+ layer: 'selectedMenu',
+ variant: 'selectedMenu',
+ textColor: 'preserve'
+ },
+ selectedMenuText: {
+ depends: ['highlightText'],
+ layer: 'selectedMenu',
+ variant: 'selectedMenu',
+ textColor: true
+ },
+ selectedMenuLink: {
+ depends: ['highlightLink'],
+ layer: 'selectedMenu',
+ variant: 'selectedMenu',
+ textColor: 'preserve'
+ },
+ selectedMenuIcon: {
+ depends: ['selectedMenu', 'selectedMenuText'],
+ color: (mod, bg, text) => mixrgb(bg, text)
+ },
+
+ selectedMenuPopover: {
+ depends: ['popover'],
+ color: (mod, bg) => brightness(5 * mod, bg).rgb
+ },
+ selectedMenuPopoverLightText: {
+ depends: ['selectedMenuLightText'],
+ layer: 'selectedMenuPopover',
+ variant: 'selectedMenuPopover',
+ textColor: true
+ },
+ selectedMenuPopoverFaintText: {
+ depends: ['selectedMenuFaintText'],
+ layer: 'selectedMenuPopover',
+ variant: 'selectedMenuPopover',
+ textColor: true
+ },
+ selectedMenuPopoverFaintLink: {
+ depends: ['selectedMenuFaintLink'],
+ layer: 'selectedMenuPopover',
+ variant: 'selectedMenuPopover',
+ textColor: 'preserve'
+ },
+ selectedMenuPopoverText: {
+ depends: ['selectedMenuText'],
+ layer: 'selectedMenuPopover',
+ variant: 'selectedMenuPopover',
+ textColor: true
+ },
+ selectedMenuPopoverLink: {
+ depends: ['selectedMenuLink'],
+ layer: 'selectedMenuPopover',
+ variant: 'selectedMenuPopover',
+ textColor: 'preserve'
+ },
+ selectedMenuPopoverIcon: {
+ depends: ['selectedMenuPopover', 'selectedMenuText'],
+ color: (mod, bg, text) => mixrgb(bg, text)
+ },
+
+ lightText: {
+ depends: ['text'],
+ layer: 'bg',
+ textColor: 'preserve',
+ color: (mod, text) => brightness(20 * mod, text).rgb
+ },
+
+ postLink: {
+ depends: ['link'],
+ layer: 'bg',
+ textColor: 'preserve'
+ },
+
+ postGreentext: {
+ depends: ['cGreen'],
+ layer: 'bg',
+ textColor: 'preserve'
+ },
+
+ border: {
+ depends: ['fg'],
+ opacity: 'border',
+ color: (mod, fg) => brightness(2 * mod, fg).rgb
+ },
+
+ poll: {
+ depends: ['accent', 'bg'],
+ copacity: 'poll',
+ color: (mod, accent, bg) => alphaBlend(accent, 0.4, bg)
+ },
+ pollText: {
+ depends: ['text'],
+ layer: 'poll',
+ textColor: true
+ },
+
+ icon: {
+ depends: ['bg', 'text'],
+ inheritsOpacity: false,
+ color: (mod, bg, text) => mixrgb(bg, text)
+ },
+
+ // Foreground
+ fgText: {
+ depends: ['text'],
+ layer: 'fg',
+ textColor: true
+ },
+ fgLink: {
+ depends: ['link'],
+ layer: 'fg',
+ textColor: 'preserve'
+ },
+
+ // Panel header
+ panel: {
+ depends: ['fg'],
+ opacity: 'panel'
+ },
+ panelText: {
+ depends: ['text'],
+ layer: 'panel',
+ textColor: true
+ },
+ panelFaint: {
+ depends: ['fgText'],
+ layer: 'panel',
+ opacity: 'faint',
+ textColor: true
+ },
+ panelLink: {
+ depends: ['fgLink'],
+ layer: 'panel',
+ textColor: 'preserve'
+ },
+
+ // Top bar
+ topBar: '--fg',
+ topBarText: {
+ depends: ['fgText'],
+ layer: 'topBar',
+ textColor: true
+ },
+ topBarLink: {
+ depends: ['fgLink'],
+ layer: 'topBar',
+ textColor: 'preserve'
+ },
+
+ // Tabs
+ tab: {
+ depends: ['btn']
+ },
+ tabText: {
+ depends: ['btnText'],
+ layer: 'btn',
+ textColor: true
+ },
+ tabActiveText: {
+ depends: ['text'],
+ layer: 'bg',
+ textColor: true
+ },
+
+ // Buttons
+ btn: {
+ depends: ['fg'],
+ variant: 'btn',
+ opacity: 'btn'
+ },
+ btnText: {
+ depends: ['fgText'],
+ layer: 'btn',
+ textColor: true
+ },
+ btnPanelText: {
+ depends: ['btnText'],
+ layer: 'btnPanel',
+ variant: 'btn',
+ textColor: true
+ },
+ btnTopBarText: {
+ depends: ['btnText'],
+ layer: 'btnTopBar',
+ variant: 'btn',
+ textColor: true
+ },
+
+ // Buttons: pressed
+ btnPressed: {
+ depends: ['btn'],
+ layer: 'btn'
+ },
+ btnPressedText: {
+ depends: ['btnText'],
+ layer: 'btn',
+ variant: 'btnPressed',
+ textColor: true
+ },
+ btnPressedPanel: {
+ depends: ['btnPressed'],
+ layer: 'btn'
+ },
+ btnPressedPanelText: {
+ depends: ['btnPanelText'],
+ layer: 'btnPanel',
+ variant: 'btnPressed',
+ textColor: true
+ },
+ btnPressedTopBar: {
+ depends: ['btnPressed'],
+ layer: 'btn'
+ },
+ btnPressedTopBarText: {
+ depends: ['btnTopBarText'],
+ layer: 'btnTopBar',
+ variant: 'btnPressed',
+ textColor: true
+ },
+
+ // Buttons: toggled
+ btnToggled: {
+ depends: ['btn'],
+ layer: 'btn',
+ color: (mod, btn) => brightness(mod * 20, btn).rgb
+ },
+ btnToggledText: {
+ depends: ['btnText'],
+ layer: 'btn',
+ variant: 'btnToggled',
+ textColor: true
+ },
+ btnToggledPanelText: {
+ depends: ['btnPanelText'],
+ layer: 'btnPanel',
+ variant: 'btnToggled',
+ textColor: true
+ },
+ btnToggledTopBarText: {
+ depends: ['btnTopBarText'],
+ layer: 'btnTopBar',
+ variant: 'btnToggled',
+ textColor: true
+ },
+
+ // Buttons: disabled
+ btnDisabled: {
+ depends: ['btn', 'bg'],
+ color: (mod, btn, bg) => alphaBlend(btn, 0.25, bg)
+ },
+ btnDisabledText: {
+ depends: ['btnText', 'btnDisabled'],
+ layer: 'btn',
+ variant: 'btnDisabled',
+ color: (mod, text, btn) => alphaBlend(text, 0.25, btn)
+ },
+ btnDisabledPanelText: {
+ depends: ['btnPanelText', 'btnDisabled'],
+ layer: 'btnPanel',
+ variant: 'btnDisabled',
+ color: (mod, text, btn) => alphaBlend(text, 0.25, btn)
+ },
+ btnDisabledTopBarText: {
+ depends: ['btnTopBarText', 'btnDisabled'],
+ layer: 'btnTopBar',
+ variant: 'btnDisabled',
+ color: (mod, text, btn) => alphaBlend(text, 0.25, btn)
+ },
+
+ // Input fields
+ input: {
+ depends: ['fg'],
+ opacity: 'input'
+ },
+ inputText: {
+ depends: ['text'],
+ layer: 'input',
+ textColor: true
+ },
+ inputPanelText: {
+ depends: ['panelText'],
+ layer: 'inputPanel',
+ variant: 'input',
+ textColor: true
+ },
+ inputTopbarText: {
+ depends: ['topBarText'],
+ layer: 'inputTopBar',
+ variant: 'input',
+ textColor: true
+ },
+
+ alertError: {
+ depends: ['cRed'],
+ opacity: 'alert'
+ },
+ alertErrorText: {
+ depends: ['text'],
+ layer: 'alert',
+ variant: 'alertError',
+ textColor: true
+ },
+ alertErrorPanelText: {
+ depends: ['panelText'],
+ layer: 'alertPanel',
+ variant: 'alertError',
+ textColor: true
+ },
+
+ alertWarning: {
+ depends: ['cOrange'],
+ opacity: 'alert'
+ },
+ alertWarningText: {
+ depends: ['text'],
+ layer: 'alert',
+ variant: 'alertWarning',
+ textColor: true
+ },
+ alertWarningPanelText: {
+ depends: ['panelText'],
+ layer: 'alertPanel',
+ variant: 'alertWarning',
+ textColor: true
+ },
+
+ alertNeutral: {
+ depends: ['text'],
+ opacity: 'alert'
+ },
+ alertNeutralText: {
+ depends: ['text'],
+ layer: 'alert',
+ variant: 'alertNeutral',
+ color: (mod, text) => invertLightness(text).rgb,
+ textColor: true
+ },
+ alertNeutralPanelText: {
+ depends: ['panelText'],
+ layer: 'alertPanel',
+ variant: 'alertNeutral',
+ textColor: true
+ },
+
+ badgeNotification: '--cRed',
+ badgeNotificationText: {
+ depends: ['text', 'badgeNotification'],
+ layer: 'badge',
+ variant: 'badgeNotification',
+ textColor: 'bw'
+ }
+}
diff --git a/src/services/theme_data/theme_data.service.js b/src/services/theme_data/theme_data.service.js
new file mode 100644
index 00000000..dd87e3cf
--- /dev/null
+++ b/src/services/theme_data/theme_data.service.js
@@ -0,0 +1,405 @@
+import { convert, brightness, contrastRatio } from 'chromatism'
+import { alphaBlendLayers, getTextColor, relativeLuminance } from '../color_convert/color_convert.js'
+import { LAYERS, DEFAULT_OPACITY, SLOT_INHERITANCE } from './pleromafe.js'
+
+/*
+ * # What's all this?
+ * Here be theme engine for pleromafe. All of this supposed to ease look
+ * and feel customization, making widget styles and make developer's life
+ * easier when it comes to supporting themes. Like many other theme systems
+ * it operates on color definitions, or "slots" - for example you define
+ * "button" color slot and then in UI component Button's CSS you refer to
+ * it as a CSS3 Variable.
+ *
+ * Some applications allow you to customize colors for certain things.
+ * Some UI toolkits allow you to define colors for each type of widget.
+ * Most of them are pretty barebones and have no assistance for common
+ * problems and cases, and in general themes themselves are very hard to
+ * maintain in all aspects. This theme engine tries to solve all of the
+ * common problems with themes.
+ *
+ * You don't have redefine several similar colors if you just want to
+ * change one color - all color slots are derived from other ones, so you
+ * can have at least one or two "basic" colors defined and have all other
+ * components inherit and modify basic ones.
+ *
+ * You don't have to test contrast ratio for colors or pick text color for
+ * each element even if you have light-on-dark elements in dark-on-light
+ * theme.
+ *
+ * You don't have to maintain order of code for inheriting slots from othet
+ * slots - dependency graph resolving does it for you.
+ */
+
+/* This indicates that this version of code outputs similar theme data and
+ * should be incremented if output changes - for instance if getTextColor
+ * function changes and older themes no longer render text colors as
+ * author intended previously.
+ */
+export const CURRENT_VERSION = 3
+
+export const getLayersArray = (layer, data = LAYERS) => {
+ let array = [layer]
+ let parent = data[layer]
+ while (parent) {
+ array.unshift(parent)
+ parent = data[parent]
+ }
+ return array
+}
+
+export const getLayers = (layer, variant = layer, opacitySlot, colors, opacity) => {
+ return getLayersArray(layer).map((currentLayer) => ([
+ currentLayer === layer
+ ? colors[variant]
+ : colors[currentLayer],
+ currentLayer === layer
+ ? opacity[opacitySlot] || 1
+ : opacity[currentLayer]
+ ]))
+}
+
+const getDependencies = (key, inheritance) => {
+ const data = inheritance[key]
+ if (typeof data === 'string' && data.startsWith('--')) {
+ return [data.substring(2)]
+ } else {
+ if (data === null) return []
+ const { depends, layer, variant } = data
+ const layerDeps = layer
+ ? getLayersArray(layer).map(currentLayer => {
+ return currentLayer === layer
+ ? variant || layer
+ : currentLayer
+ })
+ : []
+ if (Array.isArray(depends)) {
+ return [...depends, ...layerDeps]
+ } else {
+ return [...layerDeps]
+ }
+ }
+}
+
+/**
+ * Sorts inheritance object topologically - dependant slots come after
+ * dependencies
+ *
+ * @property {Object} inheritance - object defining the nodes
+ * @property {Function} getDeps - function that returns dependencies for
+ * given value and inheritance object.
+ * @returns {String[]} keys of inheritance object, sorted in topological
+ * order. Additionally, dependency-less nodes will always be first in line
+ */
+export const topoSort = (
+ inheritance = SLOT_INHERITANCE,
+ getDeps = getDependencies
+) => {
+ // This is an implementation of https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
+
+ const allKeys = Object.keys(inheritance)
+ const whites = new Set(allKeys)
+ const grays = new Set()
+ const blacks = new Set()
+ const unprocessed = [...allKeys]
+ const output = []
+
+ const step = (node) => {
+ if (whites.has(node)) {
+ // Make node "gray"
+ whites.delete(node)
+ grays.add(node)
+ // Do step for each node connected to it (one way)
+ getDeps(node, inheritance).forEach(step)
+ // Make node "black"
+ grays.delete(node)
+ blacks.add(node)
+ // Put it into the output list
+ output.push(node)
+ } else if (grays.has(node)) {
+ console.debug('Cyclic depenency in topoSort, ignoring')
+ output.push(node)
+ } else if (blacks.has(node)) {
+ // do nothing
+ } else {
+ throw new Error('Unintended condition in topoSort!')
+ }
+ }
+ while (unprocessed.length > 0) {
+ step(unprocessed.pop())
+ }
+ return output.sort((a, b) => {
+ const depsA = getDeps(a, inheritance).length
+ const depsB = getDeps(b, inheritance).length
+
+ if (depsA === depsB || (depsB !== 0 && depsA !== 0)) return 0
+ if (depsA === 0 && depsB !== 0) return -1
+ if (depsB === 0 && depsA !== 0) return 1
+ })
+}
+
+const expandSlotValue = (value) => {
+ if (typeof value === 'object') return value
+ return {
+ depends: value.startsWith('--') ? [value.substring(2)] : [],
+ default: value.startsWith('#') ? value : undefined
+ }
+}
+/**
+ * retrieves opacity slot for given slot. This goes up the depenency graph
+ * to find which parent has opacity slot defined for it.
+ * TODO refactor this
+ */
+export const getOpacitySlot = (
+ k,
+ inheritance = SLOT_INHERITANCE,
+ getDeps = getDependencies
+) => {
+ const value = expandSlotValue(inheritance[k])
+ if (value.opacity === null) return
+ if (value.opacity) return value.opacity
+ const findInheritedOpacity = (key, visited = [k]) => {
+ const depSlot = getDeps(key, inheritance)[0]
+ if (depSlot === undefined) return
+ const dependency = inheritance[depSlot]
+ if (dependency === undefined) return
+ if (dependency.opacity || dependency === null) {
+ return dependency.opacity
+ } else if (dependency.depends && visited.includes(depSlot)) {
+ return findInheritedOpacity(depSlot, [...visited, depSlot])
+ } else {
+ return null
+ }
+ }
+ if (value.depends) {
+ return findInheritedOpacity(k)
+ }
+}
+
+/**
+ * retrieves layer slot for given slot. This goes up the depenency graph
+ * to find which parent has opacity slot defined for it.
+ * this is basically copypaste of getOpacitySlot except it checks if key is
+ * in LAYERS
+ * TODO refactor this
+ */
+export const getLayerSlot = (
+ k,
+ inheritance = SLOT_INHERITANCE,
+ getDeps = getDependencies
+) => {
+ const value = expandSlotValue(inheritance[k])
+ if (LAYERS[k]) return k
+ if (value.layer === null) return
+ if (value.layer) return value.layer
+ const findInheritedLayer = (key, visited = [k]) => {
+ const depSlot = getDeps(key, inheritance)[0]
+ if (depSlot === undefined) return
+ const dependency = inheritance[depSlot]
+ if (dependency === undefined) return
+ if (dependency.layer || dependency === null) {
+ return dependency.layer
+ } else if (dependency.depends) {
+ return findInheritedLayer(dependency, [...visited, depSlot])
+ } else {
+ return null
+ }
+ }
+ if (value.depends) {
+ return findInheritedLayer(k)
+ }
+}
+
+/**
+ * topologically sorted SLOT_INHERITANCE
+ */
+export const SLOT_ORDERED = topoSort(
+ Object.entries(SLOT_INHERITANCE)
+ .sort(([aK, aV], [bK, bV]) => ((aV && aV.priority) || 0) - ((bV && bV.priority) || 0))
+ .reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {})
+)
+
+/**
+ * All opacity slots used in color slots, their default values and affected
+ * color slots.
+ */
+export const OPACITIES = Object.entries(SLOT_INHERITANCE).reduce((acc, [k, v]) => {
+ const opacity = getOpacitySlot(k, SLOT_INHERITANCE, getDependencies)
+ if (opacity) {
+ return {
+ ...acc,
+ [opacity]: {
+ defaultValue: DEFAULT_OPACITY[opacity] || 1,
+ affectedSlots: [...((acc[opacity] && acc[opacity].affectedSlots) || []), k]
+ }
+ }
+ } else {
+ return acc
+ }
+}, {})
+
+/**
+ * Handle dynamic color
+ */
+export const computeDynamicColor = (sourceColor, getColor, mod) => {
+ if (typeof sourceColor !== 'string' || !sourceColor.startsWith('--')) return sourceColor
+ let targetColor = null
+ // Color references other color
+ const [variable, modifier] = sourceColor.split(/,/g).map(str => str.trim())
+ const variableSlot = variable.substring(2)
+ targetColor = getColor(variableSlot)
+ if (modifier) {
+ targetColor = brightness(Number.parseFloat(modifier) * mod, targetColor).rgb
+ }
+ return targetColor
+}
+
+/**
+ * THE function you want to use. Takes provided colors and opacities
+ * value and uses inheritance data to figure out color needed for the slot.
+ */
+export const getColors = (sourceColors, sourceOpacity) => SLOT_ORDERED.reduce(({ colors, opacity }, key) => {
+ const sourceColor = sourceColors[key]
+ const value = expandSlotValue(SLOT_INHERITANCE[key])
+ const deps = getDependencies(key, SLOT_INHERITANCE)
+ const isTextColor = !!value.textColor
+ const variant = value.variant || value.layer
+
+ let backgroundColor = null
+
+ if (isTextColor) {
+ backgroundColor = alphaBlendLayers(
+ { ...(colors[deps[0]] || convert(sourceColors[key] || '#FF00FF').rgb) },
+ getLayers(
+ getLayerSlot(key) || 'bg',
+ variant || 'bg',
+ getOpacitySlot(variant),
+ colors,
+ opacity
+ )
+ )
+ } else if (variant && variant !== key) {
+ backgroundColor = colors[variant] || convert(sourceColors[variant]).rgb
+ } else {
+ backgroundColor = colors.bg || convert(sourceColors.bg)
+ }
+
+ const isLightOnDark = relativeLuminance(backgroundColor) < 0.5
+ const mod = isLightOnDark ? 1 : -1
+
+ let outputColor = null
+ if (sourceColor) {
+ // Color is defined in source color
+ let targetColor = sourceColor
+ if (targetColor === 'transparent') {
+ // We take only layers below current one
+ const layers = getLayers(
+ getLayerSlot(key),
+ key,
+ getOpacitySlot(key) || key,
+ colors,
+ opacity
+ ).slice(0, -1)
+ targetColor = {
+ ...alphaBlendLayers(
+ convert('#FF00FF').rgb,
+ layers
+ ),
+ a: 0
+ }
+ } else if (typeof sourceColor === 'string' && sourceColor.startsWith('--')) {
+ targetColor = computeDynamicColor(
+ sourceColor,
+ variableSlot => colors[variableSlot] || sourceColors[variableSlot],
+ mod
+ )
+ } else if (typeof sourceColor === 'string' && sourceColor.startsWith('#')) {
+ targetColor = convert(targetColor).rgb
+ }
+ outputColor = { ...targetColor }
+ } else if (value.default) {
+ // same as above except in object form
+ outputColor = convert(value.default).rgb
+ } else {
+ // calculate color
+ const defaultColorFunc = (mod, dep) => ({ ...dep })
+ const colorFunc = value.color || defaultColorFunc
+
+ if (value.textColor) {
+ if (value.textColor === 'bw') {
+ outputColor = contrastRatio(backgroundColor).rgb
+ } else {
+ let color = { ...colors[deps[0]] }
+ if (value.color) {
+ color = colorFunc(mod, ...deps.map((dep) => ({ ...colors[dep] })))
+ }
+ outputColor = getTextColor(
+ backgroundColor,
+ { ...color },
+ value.textColor === 'preserve'
+ )
+ }
+ } else {
+ // background color case
+ outputColor = colorFunc(
+ mod,
+ ...deps.map((dep) => ({ ...colors[dep] }))
+ )
+ }
+ }
+ if (!outputColor) {
+ throw new Error('Couldn\'t generate color for ' + key)
+ }
+
+ const opacitySlot = value.opacity || getOpacitySlot(key)
+ const ownOpacitySlot = value.opacity
+
+ if (ownOpacitySlot === null) {
+ outputColor.a = 1
+ } else if (sourceColor === 'transparent') {
+ outputColor.a = 0
+ } else {
+ const opacityOverriden = ownOpacitySlot && sourceOpacity[opacitySlot] !== undefined
+
+ const dependencySlot = deps[0]
+ const dependencyColor = dependencySlot && colors[dependencySlot]
+
+ if (!ownOpacitySlot && dependencyColor && !value.textColor && ownOpacitySlot !== null) {
+ // Inheriting color from dependency (weird, i know)
+ // except if it's a text color or opacity slot is set to 'null'
+ outputColor.a = dependencyColor.a
+ } else if (!dependencyColor && !opacitySlot) {
+ // Remove any alpha channel if no dependency and no opacitySlot found
+ delete outputColor.a
+ } else {
+ // Otherwise try to assign opacity
+ if (dependencyColor && dependencyColor.a === 0) {
+ // transparent dependency shall make dependents transparent too
+ outputColor.a = 0
+ } else {
+ // Otherwise check if opacity is overriden and use that or default value instead
+ outputColor.a = Number(
+ opacityOverriden
+ ? sourceOpacity[opacitySlot]
+ : (OPACITIES[opacitySlot] || {}).defaultValue
+ )
+ }
+ }
+ }
+
+ if (Number.isNaN(outputColor.a) || outputColor.a === undefined) {
+ outputColor.a = 1
+ }
+
+ if (opacitySlot) {
+ return {
+ colors: { ...colors, [key]: outputColor },
+ opacity: { ...opacity, [opacitySlot]: outputColor.a }
+ }
+ } else {
+ return {
+ colors: { ...colors, [key]: outputColor },
+ opacity
+ }
+ }
+}, { colors: {}, opacity: {} })
diff --git a/static/config.json b/static/config.json
index c8267869..0030f78f 100644
--- a/static/config.json
+++ b/static/config.json
@@ -1,23 +1,28 @@
{
- "theme": "pleroma-dark",
- "background": "/static/aurora_borealis.jpg",
- "logo": "/static/logo.png",
- "logoMask": true,
- "logoMargin": ".1em",
- "redirectRootNoLogin": "/main/all",
- "redirectRootLogin": "/main/friends",
- "showInstanceSpecificPanel": false,
- "collapseMessageWithSubject": false,
- "scopeCopy": true,
- "subjectLineBehavior": "email",
- "postContentType": "text/plain",
"alwaysShowSubjectInput": true,
+ "background": "/static/aurora_borealis.jpg",
+ "collapseMessageWithSubject": false,
+ "disableChat": false,
+ "greentext": false,
+ "hideFilteredStatuses": false,
+ "hideMutedPosts": false,
"hidePostStats": false,
+ "hideSitename": false,
"hideUserStats": false,
"loginMethod": "password",
- "webPushNotifications": false,
- "noAttachmentLinks": false,
+ "logo": "/static/logo.png",
+ "logoMargin": ".1em",
+ "logoMask": true,
+ "minimalScopesMode": false,
"nsfwCensorImage": "",
+ "postContentType": "text/plain",
+ "redirectRootLogin": "/main/friends",
+ "redirectRootNoLogin": "/main/all",
+ "scopeCopy": true,
"showFeaturesPanel": true,
- "minimalScopesMode": false
+ "showInstanceSpecificPanel": false,
+ "sidebarRight": false,
+ "subjectLineBehavior": "email",
+ "theme": "pleroma-dark",
+ "webPushNotifications": false
}
diff --git a/static/css/base16-3024.css b/static/css/base16-3024.css
deleted file mode 100644
index 91859e27..00000000
--- a/static/css/base16-3024.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #090300; }
-.base01-background { background-color: #3a3432; }
-.base02-background { background-color: #4a4543; }
-.base03-background { background-color: #5c5855; }
-.base04-background { background-color: #807d7c; }
-.base05-background { background-color: #a5a2a2; }
-.base06-background { background-color: #d6d5d4; }
-.base07-background { background-color: #f7f7f7; }
-.base08-background { background-color: #db2d20; }
-.base09-background { background-color: #e8bbd0; }
-.base0A-background { background-color: #fded02; }
-.base0B-background { background-color: #01a252; }
-.base0C-background { background-color: #b5e4f4; }
-.base0D-background { background-color: #01a0e4; }
-.base0E-background { background-color: #a16a94; }
-.base0F-background { background-color: #cdab53; }
-
-.base00 { color: #090300; }
-.base01 { color: #3a3432; }
-.base02 { color: #4a4543; }
-.base03 { color: #5c5855; }
-.base04 { color: #807d7c; }
-.base05 { color: #a5a2a2; }
-.base06 { color: #d6d5d4; }
-.base07 { color: #f7f7f7; }
-.base08 { color: #db2d20; }
-.base09 { color: #e8bbd0; }
-.base0A { color: #fded02; }
-.base0B { color: #01a252; }
-.base0C { color: #b5e4f4; }
-.base0D { color: #01a0e4; }
-.base0E { color: #a16a94; }
-.base0F { color: #cdab53; }
diff --git a/static/css/base16-apathy.css b/static/css/base16-apathy.css
deleted file mode 100644
index 2e99ba1f..00000000
--- a/static/css/base16-apathy.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #031A16; }
-.base01-background { background-color: #0B342D; }
-.base02-background { background-color: #184E45; }
-.base03-background { background-color: #2B685E; }
-.base04-background { background-color: #5F9C92; }
-.base05-background { background-color: #81B5AC; }
-.base06-background { background-color: #A7CEC8; }
-.base07-background { background-color: #D2E7E4; }
-.base08-background { background-color: #3E9688; }
-.base09-background { background-color: #3E7996; }
-.base0A-background { background-color: #3E4C96; }
-.base0B-background { background-color: #883E96; }
-.base0C-background { background-color: #963E4C; }
-.base0D-background { background-color: #96883E; }
-.base0E-background { background-color: #4C963E; }
-.base0F-background { background-color: #3E965B; }
-
-.base00 { color: #031A16; }
-.base01 { color: #0B342D; }
-.base02 { color: #184E45; }
-.base03 { color: #2B685E; }
-.base04 { color: #5F9C92; }
-.base05 { color: #81B5AC; }
-.base06 { color: #A7CEC8; }
-.base07 { color: #D2E7E4; }
-.base08 { color: #3E9688; }
-.base09 { color: #3E7996; }
-.base0A { color: #3E4C96; }
-.base0B { color: #883E96; }
-.base0C { color: #963E4C; }
-.base0D { color: #96883E; }
-.base0E { color: #4C963E; }
-.base0F { color: #3E965B; }
diff --git a/static/css/base16-ashes.css b/static/css/base16-ashes.css
deleted file mode 100644
index d10e1918..00000000
--- a/static/css/base16-ashes.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #1C2023; }
-.base01-background { background-color: #393F45; }
-.base02-background { background-color: #565E65; }
-.base03-background { background-color: #747C84; }
-.base04-background { background-color: #ADB3BA; }
-.base05-background { background-color: #C7CCD1; }
-.base06-background { background-color: #DFE2E5; }
-.base07-background { background-color: #F3F4F5; }
-.base08-background { background-color: #C7AE95; }
-.base09-background { background-color: #C7C795; }
-.base0A-background { background-color: #AEC795; }
-.base0B-background { background-color: #95C7AE; }
-.base0C-background { background-color: #95AEC7; }
-.base0D-background { background-color: #AE95C7; }
-.base0E-background { background-color: #C795AE; }
-.base0F-background { background-color: #C79595; }
-
-.base00 { color: #1C2023; }
-.base01 { color: #393F45; }
-.base02 { color: #565E65; }
-.base03 { color: #747C84; }
-.base04 { color: #ADB3BA; }
-.base05 { color: #C7CCD1; }
-.base06 { color: #DFE2E5; }
-.base07 { color: #F3F4F5; }
-.base08 { color: #C7AE95; }
-.base09 { color: #C7C795; }
-.base0A { color: #AEC795; }
-.base0B { color: #95C7AE; }
-.base0C { color: #95AEC7; }
-.base0D { color: #AE95C7; }
-.base0E { color: #C795AE; }
-.base0F { color: #C79595; }
diff --git a/static/css/base16-atelier-cave.css b/static/css/base16-atelier-cave.css
deleted file mode 100644
index 5ac17f97..00000000
--- a/static/css/base16-atelier-cave.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #19171c; }
-.base01-background { background-color: #26232a; }
-.base02-background { background-color: #585260; }
-.base03-background { background-color: #655f6d; }
-.base04-background { background-color: #7e7887; }
-.base05-background { background-color: #8b8792; }
-.base06-background { background-color: #e2dfe7; }
-.base07-background { background-color: #efecf4; }
-.base08-background { background-color: #be4678; }
-.base09-background { background-color: #aa573c; }
-.base0A-background { background-color: #a06e3b; }
-.base0B-background { background-color: #2a9292; }
-.base0C-background { background-color: #398bc6; }
-.base0D-background { background-color: #576ddb; }
-.base0E-background { background-color: #955ae7; }
-.base0F-background { background-color: #bf40bf; }
-
-.base00 { color: #19171c; }
-.base01 { color: #26232a; }
-.base02 { color: #585260; }
-.base03 { color: #655f6d; }
-.base04 { color: #7e7887; }
-.base05 { color: #8b8792; }
-.base06 { color: #e2dfe7; }
-.base07 { color: #efecf4; }
-.base08 { color: #be4678; }
-.base09 { color: #aa573c; }
-.base0A { color: #a06e3b; }
-.base0B { color: #2a9292; }
-.base0C { color: #398bc6; }
-.base0D { color: #576ddb; }
-.base0E { color: #955ae7; }
-.base0F { color: #bf40bf; }
diff --git a/static/css/base16-atelier-dune.css b/static/css/base16-atelier-dune.css
deleted file mode 100644
index cfb2d9a1..00000000
--- a/static/css/base16-atelier-dune.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #20201d; }
-.base01-background { background-color: #292824; }
-.base02-background { background-color: #6e6b5e; }
-.base03-background { background-color: #7d7a68; }
-.base04-background { background-color: #999580; }
-.base05-background { background-color: #a6a28c; }
-.base06-background { background-color: #e8e4cf; }
-.base07-background { background-color: #fefbec; }
-.base08-background { background-color: #d73737; }
-.base09-background { background-color: #b65611; }
-.base0A-background { background-color: #ae9513; }
-.base0B-background { background-color: #60ac39; }
-.base0C-background { background-color: #1fad83; }
-.base0D-background { background-color: #6684e1; }
-.base0E-background { background-color: #b854d4; }
-.base0F-background { background-color: #d43552; }
-
-.base00 { color: #20201d; }
-.base01 { color: #292824; }
-.base02 { color: #6e6b5e; }
-.base03 { color: #7d7a68; }
-.base04 { color: #999580; }
-.base05 { color: #a6a28c; }
-.base06 { color: #e8e4cf; }
-.base07 { color: #fefbec; }
-.base08 { color: #d73737; }
-.base09 { color: #b65611; }
-.base0A { color: #ae9513; }
-.base0B { color: #60ac39; }
-.base0C { color: #1fad83; }
-.base0D { color: #6684e1; }
-.base0E { color: #b854d4; }
-.base0F { color: #d43552; }
diff --git a/static/css/base16-atelier-estuary.css b/static/css/base16-atelier-estuary.css
deleted file mode 100644
index 76d82c75..00000000
--- a/static/css/base16-atelier-estuary.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #22221b; }
-.base01-background { background-color: #302f27; }
-.base02-background { background-color: #5f5e4e; }
-.base03-background { background-color: #6c6b5a; }
-.base04-background { background-color: #878573; }
-.base05-background { background-color: #929181; }
-.base06-background { background-color: #e7e6df; }
-.base07-background { background-color: #f4f3ec; }
-.base08-background { background-color: #ba6236; }
-.base09-background { background-color: #ae7313; }
-.base0A-background { background-color: #a5980d; }
-.base0B-background { background-color: #7d9726; }
-.base0C-background { background-color: #5b9d48; }
-.base0D-background { background-color: #36a166; }
-.base0E-background { background-color: #5f9182; }
-.base0F-background { background-color: #9d6c7c; }
-
-.base00 { color: #22221b; }
-.base01 { color: #302f27; }
-.base02 { color: #5f5e4e; }
-.base03 { color: #6c6b5a; }
-.base04 { color: #878573; }
-.base05 { color: #929181; }
-.base06 { color: #e7e6df; }
-.base07 { color: #f4f3ec; }
-.base08 { color: #ba6236; }
-.base09 { color: #ae7313; }
-.base0A { color: #a5980d; }
-.base0B { color: #7d9726; }
-.base0C { color: #5b9d48; }
-.base0D { color: #36a166; }
-.base0E { color: #5f9182; }
-.base0F { color: #9d6c7c; }
diff --git a/static/css/base16-atelier-forest.css b/static/css/base16-atelier-forest.css
deleted file mode 100644
index 8108ed8f..00000000
--- a/static/css/base16-atelier-forest.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #1b1918; }
-.base01-background { background-color: #2c2421; }
-.base02-background { background-color: #68615e; }
-.base03-background { background-color: #766e6b; }
-.base04-background { background-color: #9c9491; }
-.base05-background { background-color: #a8a19f; }
-.base06-background { background-color: #e6e2e0; }
-.base07-background { background-color: #f1efee; }
-.base08-background { background-color: #f22c40; }
-.base09-background { background-color: #df5320; }
-.base0A-background { background-color: #c38418; }
-.base0B-background { background-color: #7b9726; }
-.base0C-background { background-color: #3d97b8; }
-.base0D-background { background-color: #407ee7; }
-.base0E-background { background-color: #6666ea; }
-.base0F-background { background-color: #c33ff3; }
-
-.base00 { color: #1b1918; }
-.base01 { color: #2c2421; }
-.base02 { color: #68615e; }
-.base03 { color: #766e6b; }
-.base04 { color: #9c9491; }
-.base05 { color: #a8a19f; }
-.base06 { color: #e6e2e0; }
-.base07 { color: #f1efee; }
-.base08 { color: #f22c40; }
-.base09 { color: #df5320; }
-.base0A { color: #c38418; }
-.base0B { color: #7b9726; }
-.base0C { color: #3d97b8; }
-.base0D { color: #407ee7; }
-.base0E { color: #6666ea; }
-.base0F { color: #c33ff3; }
diff --git a/static/css/base16-atelier-heath.css b/static/css/base16-atelier-heath.css
deleted file mode 100644
index 8858cb80..00000000
--- a/static/css/base16-atelier-heath.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #1b181b; }
-.base01-background { background-color: #292329; }
-.base02-background { background-color: #695d69; }
-.base03-background { background-color: #776977; }
-.base04-background { background-color: #9e8f9e; }
-.base05-background { background-color: #ab9bab; }
-.base06-background { background-color: #d8cad8; }
-.base07-background { background-color: #f7f3f7; }
-.base08-background { background-color: #ca402b; }
-.base09-background { background-color: #a65926; }
-.base0A-background { background-color: #bb8a35; }
-.base0B-background { background-color: #918b3b; }
-.base0C-background { background-color: #159393; }
-.base0D-background { background-color: #516aec; }
-.base0E-background { background-color: #7b59c0; }
-.base0F-background { background-color: #cc33cc; }
-
-.base00 { color: #1b181b; }
-.base01 { color: #292329; }
-.base02 { color: #695d69; }
-.base03 { color: #776977; }
-.base04 { color: #9e8f9e; }
-.base05 { color: #ab9bab; }
-.base06 { color: #d8cad8; }
-.base07 { color: #f7f3f7; }
-.base08 { color: #ca402b; }
-.base09 { color: #a65926; }
-.base0A { color: #bb8a35; }
-.base0B { color: #918b3b; }
-.base0C { color: #159393; }
-.base0D { color: #516aec; }
-.base0E { color: #7b59c0; }
-.base0F { color: #cc33cc; }
diff --git a/static/css/base16-atelier-lakeside.css b/static/css/base16-atelier-lakeside.css
deleted file mode 100644
index 77d44c5f..00000000
--- a/static/css/base16-atelier-lakeside.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #161b1d; }
-.base01-background { background-color: #1f292e; }
-.base02-background { background-color: #516d7b; }
-.base03-background { background-color: #5a7b8c; }
-.base04-background { background-color: #7195a8; }
-.base05-background { background-color: #7ea2b4; }
-.base06-background { background-color: #c1e4f6; }
-.base07-background { background-color: #ebf8ff; }
-.base08-background { background-color: #d22d72; }
-.base09-background { background-color: #935c25; }
-.base0A-background { background-color: #8a8a0f; }
-.base0B-background { background-color: #568c3b; }
-.base0C-background { background-color: #2d8f6f; }
-.base0D-background { background-color: #257fad; }
-.base0E-background { background-color: #6b6bb8; }
-.base0F-background { background-color: #b72dd2; }
-
-.base00 { color: #161b1d; }
-.base01 { color: #1f292e; }
-.base02 { color: #516d7b; }
-.base03 { color: #5a7b8c; }
-.base04 { color: #7195a8; }
-.base05 { color: #7ea2b4; }
-.base06 { color: #c1e4f6; }
-.base07 { color: #ebf8ff; }
-.base08 { color: #d22d72; }
-.base09 { color: #935c25; }
-.base0A { color: #8a8a0f; }
-.base0B { color: #568c3b; }
-.base0C { color: #2d8f6f; }
-.base0D { color: #257fad; }
-.base0E { color: #6b6bb8; }
-.base0F { color: #b72dd2; }
diff --git a/static/css/base16-atelier-plateau.css b/static/css/base16-atelier-plateau.css
deleted file mode 100644
index a7445030..00000000
--- a/static/css/base16-atelier-plateau.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #1b1818; }
-.base01-background { background-color: #292424; }
-.base02-background { background-color: #585050; }
-.base03-background { background-color: #655d5d; }
-.base04-background { background-color: #7e7777; }
-.base05-background { background-color: #8a8585; }
-.base06-background { background-color: #e7dfdf; }
-.base07-background { background-color: #f4ecec; }
-.base08-background { background-color: #ca4949; }
-.base09-background { background-color: #b45a3c; }
-.base0A-background { background-color: #a06e3b; }
-.base0B-background { background-color: #4b8b8b; }
-.base0C-background { background-color: #5485b6; }
-.base0D-background { background-color: #7272ca; }
-.base0E-background { background-color: #8464c4; }
-.base0F-background { background-color: #bd5187; }
-
-.base00 { color: #1b1818; }
-.base01 { color: #292424; }
-.base02 { color: #585050; }
-.base03 { color: #655d5d; }
-.base04 { color: #7e7777; }
-.base05 { color: #8a8585; }
-.base06 { color: #e7dfdf; }
-.base07 { color: #f4ecec; }
-.base08 { color: #ca4949; }
-.base09 { color: #b45a3c; }
-.base0A { color: #a06e3b; }
-.base0B { color: #4b8b8b; }
-.base0C { color: #5485b6; }
-.base0D { color: #7272ca; }
-.base0E { color: #8464c4; }
-.base0F { color: #bd5187; }
diff --git a/static/css/base16-atelier-savanna.css b/static/css/base16-atelier-savanna.css
deleted file mode 100644
index be728d07..00000000
--- a/static/css/base16-atelier-savanna.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #171c19; }
-.base01-background { background-color: #232a25; }
-.base02-background { background-color: #526057; }
-.base03-background { background-color: #5f6d64; }
-.base04-background { background-color: #78877d; }
-.base05-background { background-color: #87928a; }
-.base06-background { background-color: #dfe7e2; }
-.base07-background { background-color: #ecf4ee; }
-.base08-background { background-color: #b16139; }
-.base09-background { background-color: #9f713c; }
-.base0A-background { background-color: #a07e3b; }
-.base0B-background { background-color: #489963; }
-.base0C-background { background-color: #1c9aa0; }
-.base0D-background { background-color: #478c90; }
-.base0E-background { background-color: #55859b; }
-.base0F-background { background-color: #867469; }
-
-.base00 { color: #171c19; }
-.base01 { color: #232a25; }
-.base02 { color: #526057; }
-.base03 { color: #5f6d64; }
-.base04 { color: #78877d; }
-.base05 { color: #87928a; }
-.base06 { color: #dfe7e2; }
-.base07 { color: #ecf4ee; }
-.base08 { color: #b16139; }
-.base09 { color: #9f713c; }
-.base0A { color: #a07e3b; }
-.base0B { color: #489963; }
-.base0C { color: #1c9aa0; }
-.base0D { color: #478c90; }
-.base0E { color: #55859b; }
-.base0F { color: #867469; }
diff --git a/static/css/base16-atelier-seaside.css b/static/css/base16-atelier-seaside.css
deleted file mode 100644
index 8b391466..00000000
--- a/static/css/base16-atelier-seaside.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #131513; }
-.base01-background { background-color: #242924; }
-.base02-background { background-color: #5e6e5e; }
-.base03-background { background-color: #687d68; }
-.base04-background { background-color: #809980; }
-.base05-background { background-color: #8ca68c; }
-.base06-background { background-color: #cfe8cf; }
-.base07-background { background-color: #f4fbf4; }
-.base08-background { background-color: #e6193c; }
-.base09-background { background-color: #87711d; }
-.base0A-background { background-color: #98981b; }
-.base0B-background { background-color: #29a329; }
-.base0C-background { background-color: #1999b3; }
-.base0D-background { background-color: #3d62f5; }
-.base0E-background { background-color: #ad2bee; }
-.base0F-background { background-color: #e619c3; }
-
-.base00 { color: #131513; }
-.base01 { color: #242924; }
-.base02 { color: #5e6e5e; }
-.base03 { color: #687d68; }
-.base04 { color: #809980; }
-.base05 { color: #8ca68c; }
-.base06 { color: #cfe8cf; }
-.base07 { color: #f4fbf4; }
-.base08 { color: #e6193c; }
-.base09 { color: #87711d; }
-.base0A { color: #98981b; }
-.base0B { color: #29a329; }
-.base0C { color: #1999b3; }
-.base0D { color: #3d62f5; }
-.base0E { color: #ad2bee; }
-.base0F { color: #e619c3; }
diff --git a/static/css/base16-atelier-sulphurpool.css b/static/css/base16-atelier-sulphurpool.css
deleted file mode 100644
index fb44d6e0..00000000
--- a/static/css/base16-atelier-sulphurpool.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #202746; }
-.base01-background { background-color: #293256; }
-.base02-background { background-color: #5e6687; }
-.base03-background { background-color: #6b7394; }
-.base04-background { background-color: #898ea4; }
-.base05-background { background-color: #979db4; }
-.base06-background { background-color: #dfe2f1; }
-.base07-background { background-color: #f5f7ff; }
-.base08-background { background-color: #c94922; }
-.base09-background { background-color: #c76b29; }
-.base0A-background { background-color: #c08b30; }
-.base0B-background { background-color: #ac9739; }
-.base0C-background { background-color: #22a2c9; }
-.base0D-background { background-color: #3d8fd1; }
-.base0E-background { background-color: #6679cc; }
-.base0F-background { background-color: #9c637a; }
-
-.base00 { color: #202746; }
-.base01 { color: #293256; }
-.base02 { color: #5e6687; }
-.base03 { color: #6b7394; }
-.base04 { color: #898ea4; }
-.base05 { color: #979db4; }
-.base06 { color: #dfe2f1; }
-.base07 { color: #f5f7ff; }
-.base08 { color: #c94922; }
-.base09 { color: #c76b29; }
-.base0A { color: #c08b30; }
-.base0B { color: #ac9739; }
-.base0C { color: #22a2c9; }
-.base0D { color: #3d8fd1; }
-.base0E { color: #6679cc; }
-.base0F { color: #9c637a; }
diff --git a/static/css/base16-bespin.css b/static/css/base16-bespin.css
deleted file mode 100644
index 48a9dcf7..00000000
--- a/static/css/base16-bespin.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #28211c; }
-.base01-background { background-color: #36312e; }
-.base02-background { background-color: #5e5d5c; }
-.base03-background { background-color: #666666; }
-.base04-background { background-color: #797977; }
-.base05-background { background-color: #8a8986; }
-.base06-background { background-color: #9d9b97; }
-.base07-background { background-color: #baae9e; }
-.base08-background { background-color: #cf6a4c; }
-.base09-background { background-color: #cf7d34; }
-.base0A-background { background-color: #f9ee98; }
-.base0B-background { background-color: #54be0d; }
-.base0C-background { background-color: #afc4db; }
-.base0D-background { background-color: #5ea6ea; }
-.base0E-background { background-color: #9b859d; }
-.base0F-background { background-color: #937121; }
-
-.base00 { color: #28211c; }
-.base01 { color: #36312e; }
-.base02 { color: #5e5d5c; }
-.base03 { color: #666666; }
-.base04 { color: #797977; }
-.base05 { color: #8a8986; }
-.base06 { color: #9d9b97; }
-.base07 { color: #baae9e; }
-.base08 { color: #cf6a4c; }
-.base09 { color: #cf7d34; }
-.base0A { color: #f9ee98; }
-.base0B { color: #54be0d; }
-.base0C { color: #afc4db; }
-.base0D { color: #5ea6ea; }
-.base0E { color: #9b859d; }
-.base0F { color: #937121; }
diff --git a/static/css/base16-brewer.css b/static/css/base16-brewer.css
deleted file mode 100644
index c88f219b..00000000
--- a/static/css/base16-brewer.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #0c0d0e; }
-.base01-background { background-color: #2e2f30; }
-.base02-background { background-color: #515253; }
-.base03-background { background-color: #737475; }
-.base04-background { background-color: #959697; }
-.base05-background { background-color: #b7b8b9; }
-.base06-background { background-color: #dadbdc; }
-.base07-background { background-color: #fcfdfe; }
-.base08-background { background-color: #e31a1c; }
-.base09-background { background-color: #e6550d; }
-.base0A-background { background-color: #dca060; }
-.base0B-background { background-color: #31a354; }
-.base0C-background { background-color: #80b1d3; }
-.base0D-background { background-color: #3182bd; }
-.base0E-background { background-color: #756bb1; }
-.base0F-background { background-color: #b15928; }
-
-.base00 { color: #0c0d0e; }
-.base01 { color: #2e2f30; }
-.base02 { color: #515253; }
-.base03 { color: #737475; }
-.base04 { color: #959697; }
-.base05 { color: #b7b8b9; }
-.base06 { color: #dadbdc; }
-.base07 { color: #fcfdfe; }
-.base08 { color: #e31a1c; }
-.base09 { color: #e6550d; }
-.base0A { color: #dca060; }
-.base0B { color: #31a354; }
-.base0C { color: #80b1d3; }
-.base0D { color: #3182bd; }
-.base0E { color: #756bb1; }
-.base0F { color: #b15928; }
diff --git a/static/css/base16-bright.css b/static/css/base16-bright.css
deleted file mode 100644
index c2333b8d..00000000
--- a/static/css/base16-bright.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #000000; }
-.base01-background { background-color: #303030; }
-.base02-background { background-color: #505050; }
-.base03-background { background-color: #b0b0b0; }
-.base04-background { background-color: #d0d0d0; }
-.base05-background { background-color: #e0e0e0; }
-.base06-background { background-color: #f5f5f5; }
-.base07-background { background-color: #ffffff; }
-.base08-background { background-color: #fb0120; }
-.base09-background { background-color: #fc6d24; }
-.base0A-background { background-color: #fda331; }
-.base0B-background { background-color: #a1c659; }
-.base0C-background { background-color: #76c7b7; }
-.base0D-background { background-color: #6fb3d2; }
-.base0E-background { background-color: #d381c3; }
-.base0F-background { background-color: #be643c; }
-
-.base00 { color: #000000; }
-.base01 { color: #303030; }
-.base02 { color: #505050; }
-.base03 { color: #b0b0b0; }
-.base04 { color: #d0d0d0; }
-.base05 { color: #e0e0e0; }
-.base06 { color: #f5f5f5; }
-.base07 { color: #ffffff; }
-.base08 { color: #fb0120; }
-.base09 { color: #fc6d24; }
-.base0A { color: #fda331; }
-.base0B { color: #a1c659; }
-.base0C { color: #76c7b7; }
-.base0D { color: #6fb3d2; }
-.base0E { color: #d381c3; }
-.base0F { color: #be643c; }
diff --git a/static/css/base16-chalk.css b/static/css/base16-chalk.css
deleted file mode 100644
index e3cb3c20..00000000
--- a/static/css/base16-chalk.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #151515; }
-.base01-background { background-color: #202020; }
-.base02-background { background-color: #303030; }
-.base03-background { background-color: #505050; }
-.base04-background { background-color: #b0b0b0; }
-.base05-background { background-color: #d0d0d0; }
-.base06-background { background-color: #e0e0e0; }
-.base07-background { background-color: #f5f5f5; }
-.base08-background { background-color: #fb9fb1; }
-.base09-background { background-color: #eda987; }
-.base0A-background { background-color: #ddb26f; }
-.base0B-background { background-color: #acc267; }
-.base0C-background { background-color: #12cfc0; }
-.base0D-background { background-color: #6fc2ef; }
-.base0E-background { background-color: #e1a3ee; }
-.base0F-background { background-color: #deaf8f; }
-
-.base00 { color: #151515; }
-.base01 { color: #202020; }
-.base02 { color: #303030; }
-.base03 { color: #505050; }
-.base04 { color: #b0b0b0; }
-.base05 { color: #d0d0d0; }
-.base06 { color: #e0e0e0; }
-.base07 { color: #f5f5f5; }
-.base08 { color: #fb9fb1; }
-.base09 { color: #eda987; }
-.base0A { color: #ddb26f; }
-.base0B { color: #acc267; }
-.base0C { color: #12cfc0; }
-.base0D { color: #6fc2ef; }
-.base0E { color: #e1a3ee; }
-.base0F { color: #deaf8f; }
diff --git a/static/css/base16-codeschool.css b/static/css/base16-codeschool.css
deleted file mode 100644
index 00194bbf..00000000
--- a/static/css/base16-codeschool.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #232c31; }
-.base01-background { background-color: #1c3657; }
-.base02-background { background-color: #2a343a; }
-.base03-background { background-color: #3f4944; }
-.base04-background { background-color: #84898c; }
-.base05-background { background-color: #9ea7a6; }
-.base06-background { background-color: #a7cfa3; }
-.base07-background { background-color: #b5d8f6; }
-.base08-background { background-color: #2a5491; }
-.base09-background { background-color: #43820d; }
-.base0A-background { background-color: #a03b1e; }
-.base0B-background { background-color: #237986; }
-.base0C-background { background-color: #b02f30; }
-.base0D-background { background-color: #484d79; }
-.base0E-background { background-color: #c59820; }
-.base0F-background { background-color: #c98344; }
-
-.base00 { color: #232c31; }
-.base01 { color: #1c3657; }
-.base02 { color: #2a343a; }
-.base03 { color: #3f4944; }
-.base04 { color: #84898c; }
-.base05 { color: #9ea7a6; }
-.base06 { color: #a7cfa3; }
-.base07 { color: #b5d8f6; }
-.base08 { color: #2a5491; }
-.base09 { color: #43820d; }
-.base0A { color: #a03b1e; }
-.base0B { color: #237986; }
-.base0C { color: #b02f30; }
-.base0D { color: #484d79; }
-.base0E { color: #c59820; }
-.base0F { color: #c98344; }
diff --git a/static/css/base16-darktooth.css b/static/css/base16-darktooth.css
deleted file mode 100644
index 53448706..00000000
--- a/static/css/base16-darktooth.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #1D2021; }
-.base01-background { background-color: #32302F; }
-.base02-background { background-color: #504945; }
-.base03-background { background-color: #665C54; }
-.base04-background { background-color: #928374; }
-.base05-background { background-color: #A89984; }
-.base06-background { background-color: #D5C4A1; }
-.base07-background { background-color: #FDF4C1; }
-.base08-background { background-color: #FB543F; }
-.base09-background { background-color: #FE8625; }
-.base0A-background { background-color: #FAC03B; }
-.base0B-background { background-color: #95C085; }
-.base0C-background { background-color: #8BA59B; }
-.base0D-background { background-color: #0D6678; }
-.base0E-background { background-color: #8F4673; }
-.base0F-background { background-color: #A87322; }
-
-.base00 { color: #1D2021; }
-.base01 { color: #32302F; }
-.base02 { color: #504945; }
-.base03 { color: #665C54; }
-.base04 { color: #928374; }
-.base05 { color: #A89984; }
-.base06 { color: #D5C4A1; }
-.base07 { color: #FDF4C1; }
-.base08 { color: #FB543F; }
-.base09 { color: #FE8625; }
-.base0A { color: #FAC03B; }
-.base0B { color: #95C085; }
-.base0C { color: #8BA59B; }
-.base0D { color: #0D6678; }
-.base0E { color: #8F4673; }
-.base0F { color: #A87322; }
diff --git a/static/css/base16-default-dark.css b/static/css/base16-default-dark.css
deleted file mode 100644
index 3cd7e860..00000000
--- a/static/css/base16-default-dark.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #181818; }
-.base01-background { background-color: #282828; }
-.base02-background { background-color: #383838; }
-.base03-background { background-color: #585858; }
-.base04-background { background-color: #b8b8b8; }
-.base05-background { background-color: #d8d8d8; }
-.base06-background { background-color: #e8e8e8; }
-.base07-background { background-color: #f8f8f8; }
-.base08-background { background-color: #ab4642; }
-.base09-background { background-color: #dc9656; }
-.base0A-background { background-color: #f7ca88; }
-.base0B-background { background-color: #a1b56c; }
-.base0C-background { background-color: #86c1b9; }
-.base0D-background { background-color: #7cafc2; }
-.base0E-background { background-color: #ba8baf; }
-.base0F-background { background-color: #a16946; }
-
-.base00 { color: #181818; }
-.base01 { color: #282828; }
-.base02 { color: #383838; }
-.base03 { color: #585858; }
-.base04 { color: #b8b8b8; }
-.base05 { color: #d8d8d8; }
-.base06 { color: #e8e8e8; }
-.base07 { color: #f8f8f8; }
-.base08 { color: #ab4642; }
-.base09 { color: #dc9656; }
-.base0A { color: #f7ca88; }
-.base0B { color: #a1b56c; }
-.base0C { color: #86c1b9; }
-.base0D { color: #7cafc2; }
-.base0E { color: #ba8baf; }
-.base0F { color: #a16946; }
diff --git a/static/css/base16-default-light.css b/static/css/base16-default-light.css
deleted file mode 100644
index 7e660c30..00000000
--- a/static/css/base16-default-light.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #f8f8f8; }
-.base01-background { background-color: #e8e8e8; }
-.base02-background { background-color: #d8d8d8; }
-.base03-background { background-color: #b8b8b8; }
-.base04-background { background-color: #585858; }
-.base05-background { background-color: #383838; }
-.base06-background { background-color: #282828; }
-.base07-background { background-color: #181818; }
-.base08-background { background-color: #ab4642; }
-.base09-background { background-color: #dc9656; }
-.base0A-background { background-color: #f7ca88; }
-.base0B-background { background-color: #a1b56c; }
-.base0C-background { background-color: #86c1b9; }
-.base0D-background { background-color: #7cafc2; }
-.base0E-background { background-color: #ba8baf; }
-.base0F-background { background-color: #a16946; }
-
-.base00 { color: #f8f8f8; }
-.base01 { color: #e8e8e8; }
-.base02 { color: #d8d8d8; }
-.base03 { color: #b8b8b8; }
-.base04 { color: #585858; }
-.base05 { color: #383838; }
-.base06 { color: #282828; }
-.base07 { color: #181818; }
-.base08 { color: #ab4642; }
-.base09 { color: #dc9656; }
-.base0A { color: #f7ca88; }
-.base0B { color: #a1b56c; }
-.base0C { color: #86c1b9; }
-.base0D { color: #7cafc2; }
-.base0E { color: #ba8baf; }
-.base0F { color: #a16946; }
diff --git a/static/css/base16-eighties.css b/static/css/base16-eighties.css
deleted file mode 100644
index 8ffcf04d..00000000
--- a/static/css/base16-eighties.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #2d2d2d; }
-.base01-background { background-color: #393939; }
-.base02-background { background-color: #515151; }
-.base03-background { background-color: #747369; }
-.base04-background { background-color: #a09f93; }
-.base05-background { background-color: #d3d0c8; }
-.base06-background { background-color: #e8e6df; }
-.base07-background { background-color: #f2f0ec; }
-.base08-background { background-color: #f2777a; }
-.base09-background { background-color: #f99157; }
-.base0A-background { background-color: #ffcc66; }
-.base0B-background { background-color: #99cc99; }
-.base0C-background { background-color: #66cccc; }
-.base0D-background { background-color: #6699cc; }
-.base0E-background { background-color: #cc99cc; }
-.base0F-background { background-color: #d27b53; }
-
-.base00 { color: #2d2d2d; }
-.base01 { color: #393939; }
-.base02 { color: #515151; }
-.base03 { color: #747369; }
-.base04 { color: #a09f93; }
-.base05 { color: #d3d0c8; }
-.base06 { color: #e8e6df; }
-.base07 { color: #f2f0ec; }
-.base08 { color: #f2777a; }
-.base09 { color: #f99157; }
-.base0A { color: #ffcc66; }
-.base0B { color: #99cc99; }
-.base0C { color: #66cccc; }
-.base0D { color: #6699cc; }
-.base0E { color: #cc99cc; }
-.base0F { color: #d27b53; }
diff --git a/static/css/base16-embers.css b/static/css/base16-embers.css
deleted file mode 100644
index 74e9b769..00000000
--- a/static/css/base16-embers.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #16130F; }
-.base01-background { background-color: #2C2620; }
-.base02-background { background-color: #433B32; }
-.base03-background { background-color: #5A5047; }
-.base04-background { background-color: #8A8075; }
-.base05-background { background-color: #A39A90; }
-.base06-background { background-color: #BEB6AE; }
-.base07-background { background-color: #DBD6D1; }
-.base08-background { background-color: #826D57; }
-.base09-background { background-color: #828257; }
-.base0A-background { background-color: #6D8257; }
-.base0B-background { background-color: #57826D; }
-.base0C-background { background-color: #576D82; }
-.base0D-background { background-color: #6D5782; }
-.base0E-background { background-color: #82576D; }
-.base0F-background { background-color: #825757; }
-
-.base00 { color: #16130F; }
-.base01 { color: #2C2620; }
-.base02 { color: #433B32; }
-.base03 { color: #5A5047; }
-.base04 { color: #8A8075; }
-.base05 { color: #A39A90; }
-.base06 { color: #BEB6AE; }
-.base07 { color: #DBD6D1; }
-.base08 { color: #826D57; }
-.base09 { color: #828257; }
-.base0A { color: #6D8257; }
-.base0B { color: #57826D; }
-.base0C { color: #576D82; }
-.base0D { color: #6D5782; }
-.base0E { color: #82576D; }
-.base0F { color: #825757; }
diff --git a/static/css/base16-flat.css b/static/css/base16-flat.css
deleted file mode 100644
index 72918a5d..00000000
--- a/static/css/base16-flat.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #2C3E50; }
-.base01-background { background-color: #34495E; }
-.base02-background { background-color: #7F8C8D; }
-.base03-background { background-color: #95A5A6; }
-.base04-background { background-color: #BDC3C7; }
-.base05-background { background-color: #e0e0e0; }
-.base06-background { background-color: #f5f5f5; }
-.base07-background { background-color: #ECF0F1; }
-.base08-background { background-color: #E74C3C; }
-.base09-background { background-color: #E67E22; }
-.base0A-background { background-color: #F1C40F; }
-.base0B-background { background-color: #2ECC71; }
-.base0C-background { background-color: #1ABC9C; }
-.base0D-background { background-color: #3498DB; }
-.base0E-background { background-color: #9B59B6; }
-.base0F-background { background-color: #be643c; }
-
-.base00 { color: #2C3E50; }
-.base01 { color: #34495E; }
-.base02 { color: #7F8C8D; }
-.base03 { color: #95A5A6; }
-.base04 { color: #BDC3C7; }
-.base05 { color: #e0e0e0; }
-.base06 { color: #f5f5f5; }
-.base07 { color: #ECF0F1; }
-.base08 { color: #E74C3C; }
-.base09 { color: #E67E22; }
-.base0A { color: #F1C40F; }
-.base0B { color: #2ECC71; }
-.base0C { color: #1ABC9C; }
-.base0D { color: #3498DB; }
-.base0E { color: #9B59B6; }
-.base0F { color: #be643c; }
diff --git a/static/css/base16-github.css b/static/css/base16-github.css
deleted file mode 100644
index 080ed34c..00000000
--- a/static/css/base16-github.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #ffffff; }
-.base01-background { background-color: #f5f5f5; }
-.base02-background { background-color: #c8c8fa; }
-.base03-background { background-color: #969896; }
-.base04-background { background-color: #e8e8e8; }
-.base05-background { background-color: #333333; }
-.base06-background { background-color: #ffffff; }
-.base07-background { background-color: #ffffff; }
-.base08-background { background-color: #ed6a43; }
-.base09-background { background-color: #0086b3; }
-.base0A-background { background-color: #795da3; }
-.base0B-background { background-color: #183691; }
-.base0C-background { background-color: #183691; }
-.base0D-background { background-color: #795da3; }
-.base0E-background { background-color: #a71d5d; }
-.base0F-background { background-color: #333333; }
-
-.base00 { color: #ffffff; }
-.base01 { color: #f5f5f5; }
-.base02 { color: #c8c8fa; }
-.base03 { color: #969896; }
-.base04 { color: #e8e8e8; }
-.base05 { color: #333333; }
-.base06 { color: #ffffff; }
-.base07 { color: #ffffff; }
-.base08 { color: #ed6a43; }
-.base09 { color: #0086b3; }
-.base0A { color: #795da3; }
-.base0B { color: #183691; }
-.base0C { color: #183691; }
-.base0D { color: #795da3; }
-.base0E { color: #a71d5d; }
-.base0F { color: #333333; }
diff --git a/static/css/base16-google-dark.css b/static/css/base16-google-dark.css
deleted file mode 100644
index 988eac51..00000000
--- a/static/css/base16-google-dark.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #1d1f21; }
-.base01-background { background-color: #282a2e; }
-.base02-background { background-color: #373b41; }
-.base03-background { background-color: #969896; }
-.base04-background { background-color: #b4b7b4; }
-.base05-background { background-color: #c5c8c6; }
-.base06-background { background-color: #e0e0e0; }
-.base07-background { background-color: #ffffff; }
-.base08-background { background-color: #CC342B; }
-.base09-background { background-color: #F96A38; }
-.base0A-background { background-color: #FBA922; }
-.base0B-background { background-color: #198844; }
-.base0C-background { background-color: #3971ED; }
-.base0D-background { background-color: #3971ED; }
-.base0E-background { background-color: #A36AC7; }
-.base0F-background { background-color: #3971ED; }
-
-.base00 { color: #1d1f21; }
-.base01 { color: #282a2e; }
-.base02 { color: #373b41; }
-.base03 { color: #969896; }
-.base04 { color: #b4b7b4; }
-.base05 { color: #c5c8c6; }
-.base06 { color: #e0e0e0; }
-.base07 { color: #ffffff; }
-.base08 { color: #CC342B; }
-.base09 { color: #F96A38; }
-.base0A { color: #FBA922; }
-.base0B { color: #198844; }
-.base0C { color: #3971ED; }
-.base0D { color: #3971ED; }
-.base0E { color: #A36AC7; }
-.base0F { color: #3971ED; }
diff --git a/static/css/base16-google-light.css b/static/css/base16-google-light.css
deleted file mode 100644
index 2ee2a606..00000000
--- a/static/css/base16-google-light.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #ffffff; }
-.base01-background { background-color: #e0e0e0; }
-.base02-background { background-color: #c5c8c6; }
-.base03-background { background-color: #b4b7b4; }
-.base04-background { background-color: #969896; }
-.base05-background { background-color: #373b41; }
-.base06-background { background-color: #282a2e; }
-.base07-background { background-color: #1d1f21; }
-.base08-background { background-color: #CC342B; }
-.base09-background { background-color: #F96A38; }
-.base0A-background { background-color: #FBA922; }
-.base0B-background { background-color: #198844; }
-.base0C-background { background-color: #3971ED; }
-.base0D-background { background-color: #3971ED; }
-.base0E-background { background-color: #A36AC7; }
-.base0F-background { background-color: #3971ED; }
-
-.base00 { color: #ffffff; }
-.base01 { color: #e0e0e0; }
-.base02 { color: #c5c8c6; }
-.base03 { color: #b4b7b4; }
-.base04 { color: #969896; }
-.base05 { color: #373b41; }
-.base06 { color: #282a2e; }
-.base07 { color: #1d1f21; }
-.base08 { color: #CC342B; }
-.base09 { color: #F96A38; }
-.base0A { color: #FBA922; }
-.base0B { color: #198844; }
-.base0C { color: #3971ED; }
-.base0D { color: #3971ED; }
-.base0E { color: #A36AC7; }
-.base0F { color: #3971ED; }
diff --git a/static/css/base16-grayscale-dark.css b/static/css/base16-grayscale-dark.css
deleted file mode 100644
index dc0dd03a..00000000
--- a/static/css/base16-grayscale-dark.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #101010; }
-.base01-background { background-color: #252525; }
-.base02-background { background-color: #464646; }
-.base03-background { background-color: #525252; }
-.base04-background { background-color: #ababab; }
-.base05-background { background-color: #b9b9b9; }
-.base06-background { background-color: #e3e3e3; }
-.base07-background { background-color: #f7f7f7; }
-.base08-background { background-color: #7c7c7c; }
-.base09-background { background-color: #999999; }
-.base0A-background { background-color: #a0a0a0; }
-.base0B-background { background-color: #8e8e8e; }
-.base0C-background { background-color: #868686; }
-.base0D-background { background-color: #686868; }
-.base0E-background { background-color: #747474; }
-.base0F-background { background-color: #5e5e5e; }
-
-.base00 { color: #101010; }
-.base01 { color: #252525; }
-.base02 { color: #464646; }
-.base03 { color: #525252; }
-.base04 { color: #ababab; }
-.base05 { color: #b9b9b9; }
-.base06 { color: #e3e3e3; }
-.base07 { color: #f7f7f7; }
-.base08 { color: #7c7c7c; }
-.base09 { color: #999999; }
-.base0A { color: #a0a0a0; }
-.base0B { color: #8e8e8e; }
-.base0C { color: #868686; }
-.base0D { color: #686868; }
-.base0E { color: #747474; }
-.base0F { color: #5e5e5e; }
diff --git a/static/css/base16-grayscale-light.css b/static/css/base16-grayscale-light.css
deleted file mode 100644
index f9fd213a..00000000
--- a/static/css/base16-grayscale-light.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #f7f7f7; }
-.base01-background { background-color: #e3e3e3; }
-.base02-background { background-color: #b9b9b9; }
-.base03-background { background-color: #ababab; }
-.base04-background { background-color: #525252; }
-.base05-background { background-color: #464646; }
-.base06-background { background-color: #252525; }
-.base07-background { background-color: #101010; }
-.base08-background { background-color: #7c7c7c; }
-.base09-background { background-color: #999999; }
-.base0A-background { background-color: #a0a0a0; }
-.base0B-background { background-color: #8e8e8e; }
-.base0C-background { background-color: #868686; }
-.base0D-background { background-color: #686868; }
-.base0E-background { background-color: #747474; }
-.base0F-background { background-color: #5e5e5e; }
-
-.base00 { color: #f7f7f7; }
-.base01 { color: #e3e3e3; }
-.base02 { color: #b9b9b9; }
-.base03 { color: #ababab; }
-.base04 { color: #525252; }
-.base05 { color: #464646; }
-.base06 { color: #252525; }
-.base07 { color: #101010; }
-.base08 { color: #7c7c7c; }
-.base09 { color: #999999; }
-.base0A { color: #a0a0a0; }
-.base0B { color: #8e8e8e; }
-.base0C { color: #868686; }
-.base0D { color: #686868; }
-.base0E { color: #747474; }
-.base0F { color: #5e5e5e; }
diff --git a/static/css/base16-green-screen.css b/static/css/base16-green-screen.css
deleted file mode 100644
index 205efeae..00000000
--- a/static/css/base16-green-screen.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #001100; }
-.base01-background { background-color: #003300; }
-.base02-background { background-color: #005500; }
-.base03-background { background-color: #007700; }
-.base04-background { background-color: #009900; }
-.base05-background { background-color: #00bb00; }
-.base06-background { background-color: #00dd00; }
-.base07-background { background-color: #00ff00; }
-.base08-background { background-color: #007700; }
-.base09-background { background-color: #009900; }
-.base0A-background { background-color: #007700; }
-.base0B-background { background-color: #00bb00; }
-.base0C-background { background-color: #005500; }
-.base0D-background { background-color: #009900; }
-.base0E-background { background-color: #00bb00; }
-.base0F-background { background-color: #005500; }
-
-.base00 { color: #001100; }
-.base01 { color: #003300; }
-.base02 { color: #005500; }
-.base03 { color: #007700; }
-.base04 { color: #009900; }
-.base05 { color: #00bb00; }
-.base06 { color: #00dd00; }
-.base07 { color: #00ff00; }
-.base08 { color: #007700; }
-.base09 { color: #009900; }
-.base0A { color: #007700; }
-.base0B { color: #00bb00; }
-.base0C { color: #005500; }
-.base0D { color: #009900; }
-.base0E { color: #00bb00; }
-.base0F { color: #005500; }
diff --git a/static/css/base16-harmonic16-dark.css b/static/css/base16-harmonic16-dark.css
deleted file mode 100644
index 0c2c7ce4..00000000
--- a/static/css/base16-harmonic16-dark.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #0b1c2c; }
-.base01-background { background-color: #223b54; }
-.base02-background { background-color: #405c79; }
-.base03-background { background-color: #627e99; }
-.base04-background { background-color: #aabcce; }
-.base05-background { background-color: #cbd6e2; }
-.base06-background { background-color: #e5ebf1; }
-.base07-background { background-color: #f7f9fb; }
-.base08-background { background-color: #bf8b56; }
-.base09-background { background-color: #bfbf56; }
-.base0A-background { background-color: #8bbf56; }
-.base0B-background { background-color: #56bf8b; }
-.base0C-background { background-color: #568bbf; }
-.base0D-background { background-color: #8b56bf; }
-.base0E-background { background-color: #bf568b; }
-.base0F-background { background-color: #bf5656; }
-
-.base00 { color: #0b1c2c; }
-.base01 { color: #223b54; }
-.base02 { color: #405c79; }
-.base03 { color: #627e99; }
-.base04 { color: #aabcce; }
-.base05 { color: #cbd6e2; }
-.base06 { color: #e5ebf1; }
-.base07 { color: #f7f9fb; }
-.base08 { color: #bf8b56; }
-.base09 { color: #bfbf56; }
-.base0A { color: #8bbf56; }
-.base0B { color: #56bf8b; }
-.base0C { color: #568bbf; }
-.base0D { color: #8b56bf; }
-.base0E { color: #bf568b; }
-.base0F { color: #bf5656; }
diff --git a/static/css/base16-harmonic16-light.css b/static/css/base16-harmonic16-light.css
deleted file mode 100644
index 37bb7679..00000000
--- a/static/css/base16-harmonic16-light.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #f7f9fb; }
-.base01-background { background-color: #e5ebf1; }
-.base02-background { background-color: #cbd6e2; }
-.base03-background { background-color: #aabcce; }
-.base04-background { background-color: #627e99; }
-.base05-background { background-color: #405c79; }
-.base06-background { background-color: #223b54; }
-.base07-background { background-color: #0b1c2c; }
-.base08-background { background-color: #bf8b56; }
-.base09-background { background-color: #bfbf56; }
-.base0A-background { background-color: #8bbf56; }
-.base0B-background { background-color: #56bf8b; }
-.base0C-background { background-color: #568bbf; }
-.base0D-background { background-color: #8b56bf; }
-.base0E-background { background-color: #bf568b; }
-.base0F-background { background-color: #bf5656; }
-
-.base00 { color: #f7f9fb; }
-.base01 { color: #e5ebf1; }
-.base02 { color: #cbd6e2; }
-.base03 { color: #aabcce; }
-.base04 { color: #627e99; }
-.base05 { color: #405c79; }
-.base06 { color: #223b54; }
-.base07 { color: #0b1c2c; }
-.base08 { color: #bf8b56; }
-.base09 { color: #bfbf56; }
-.base0A { color: #8bbf56; }
-.base0B { color: #56bf8b; }
-.base0C { color: #568bbf; }
-.base0D { color: #8b56bf; }
-.base0E { color: #bf568b; }
-.base0F { color: #bf5656; }
diff --git a/static/css/base16-hopscotch.css b/static/css/base16-hopscotch.css
deleted file mode 100644
index f2ad232c..00000000
--- a/static/css/base16-hopscotch.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #322931; }
-.base01-background { background-color: #433b42; }
-.base02-background { background-color: #5c545b; }
-.base03-background { background-color: #797379; }
-.base04-background { background-color: #989498; }
-.base05-background { background-color: #b9b5b8; }
-.base06-background { background-color: #d5d3d5; }
-.base07-background { background-color: #ffffff; }
-.base08-background { background-color: #dd464c; }
-.base09-background { background-color: #fd8b19; }
-.base0A-background { background-color: #fdcc59; }
-.base0B-background { background-color: #8fc13e; }
-.base0C-background { background-color: #149b93; }
-.base0D-background { background-color: #1290bf; }
-.base0E-background { background-color: #c85e7c; }
-.base0F-background { background-color: #b33508; }
-
-.base00 { color: #322931; }
-.base01 { color: #433b42; }
-.base02 { color: #5c545b; }
-.base03 { color: #797379; }
-.base04 { color: #989498; }
-.base05 { color: #b9b5b8; }
-.base06 { color: #d5d3d5; }
-.base07 { color: #ffffff; }
-.base08 { color: #dd464c; }
-.base09 { color: #fd8b19; }
-.base0A { color: #fdcc59; }
-.base0B { color: #8fc13e; }
-.base0C { color: #149b93; }
-.base0D { color: #1290bf; }
-.base0E { color: #c85e7c; }
-.base0F { color: #b33508; }
diff --git a/static/css/base16-ir-black.css b/static/css/base16-ir-black.css
deleted file mode 100644
index 8d14ab9b..00000000
--- a/static/css/base16-ir-black.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #000000; }
-.base01-background { background-color: #242422; }
-.base02-background { background-color: #484844; }
-.base03-background { background-color: #6c6c66; }
-.base04-background { background-color: #918f88; }
-.base05-background { background-color: #b5b3aa; }
-.base06-background { background-color: #d9d7cc; }
-.base07-background { background-color: #fdfbee; }
-.base08-background { background-color: #ff6c60; }
-.base09-background { background-color: #e9c062; }
-.base0A-background { background-color: #ffffb6; }
-.base0B-background { background-color: #a8ff60; }
-.base0C-background { background-color: #c6c5fe; }
-.base0D-background { background-color: #96cbfe; }
-.base0E-background { background-color: #ff73fd; }
-.base0F-background { background-color: #b18a3d; }
-
-.base00 { color: #000000; }
-.base01 { color: #242422; }
-.base02 { color: #484844; }
-.base03 { color: #6c6c66; }
-.base04 { color: #918f88; }
-.base05 { color: #b5b3aa; }
-.base06 { color: #d9d7cc; }
-.base07 { color: #fdfbee; }
-.base08 { color: #ff6c60; }
-.base09 { color: #e9c062; }
-.base0A { color: #ffffb6; }
-.base0B { color: #a8ff60; }
-.base0C { color: #c6c5fe; }
-.base0D { color: #96cbfe; }
-.base0E { color: #ff73fd; }
-.base0F { color: #b18a3d; }
diff --git a/static/css/base16-isotope.css b/static/css/base16-isotope.css
deleted file mode 100644
index f7a4a0b4..00000000
--- a/static/css/base16-isotope.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #000000; }
-.base01-background { background-color: #404040; }
-.base02-background { background-color: #606060; }
-.base03-background { background-color: #808080; }
-.base04-background { background-color: #c0c0c0; }
-.base05-background { background-color: #d0d0d0; }
-.base06-background { background-color: #e0e0e0; }
-.base07-background { background-color: #ffffff; }
-.base08-background { background-color: #ff0000; }
-.base09-background { background-color: #ff9900; }
-.base0A-background { background-color: #ff0099; }
-.base0B-background { background-color: #33ff00; }
-.base0C-background { background-color: #00ffff; }
-.base0D-background { background-color: #0066ff; }
-.base0E-background { background-color: #cc00ff; }
-.base0F-background { background-color: #3300ff; }
-
-.base00 { color: #000000; }
-.base01 { color: #404040; }
-.base02 { color: #606060; }
-.base03 { color: #808080; }
-.base04 { color: #c0c0c0; }
-.base05 { color: #d0d0d0; }
-.base06 { color: #e0e0e0; }
-.base07 { color: #ffffff; }
-.base08 { color: #ff0000; }
-.base09 { color: #ff9900; }
-.base0A { color: #ff0099; }
-.base0B { color: #33ff00; }
-.base0C { color: #00ffff; }
-.base0D { color: #0066ff; }
-.base0E { color: #cc00ff; }
-.base0F { color: #3300ff; }
diff --git a/static/css/base16-london-tube.css b/static/css/base16-london-tube.css
deleted file mode 100644
index 0537d1ad..00000000
--- a/static/css/base16-london-tube.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #231f20; }
-.base01-background { background-color: #1c3f95; }
-.base02-background { background-color: #5a5758; }
-.base03-background { background-color: #737171; }
-.base04-background { background-color: #959ca1; }
-.base05-background { background-color: #d9d8d8; }
-.base06-background { background-color: #e7e7e8; }
-.base07-background { background-color: #ffffff; }
-.base08-background { background-color: #ee2e24; }
-.base09-background { background-color: #f386a1; }
-.base0A-background { background-color: #ffd204; }
-.base0B-background { background-color: #00853e; }
-.base0C-background { background-color: #85cebc; }
-.base0D-background { background-color: #009ddc; }
-.base0E-background { background-color: #98005d; }
-.base0F-background { background-color: #b06110; }
-
-.base00 { color: #231f20; }
-.base01 { color: #1c3f95; }
-.base02 { color: #5a5758; }
-.base03 { color: #737171; }
-.base04 { color: #959ca1; }
-.base05 { color: #d9d8d8; }
-.base06 { color: #e7e7e8; }
-.base07 { color: #ffffff; }
-.base08 { color: #ee2e24; }
-.base09 { color: #f386a1; }
-.base0A { color: #ffd204; }
-.base0B { color: #00853e; }
-.base0C { color: #85cebc; }
-.base0D { color: #009ddc; }
-.base0E { color: #98005d; }
-.base0F { color: #b06110; }
diff --git a/static/css/base16-macintosh.css b/static/css/base16-macintosh.css
deleted file mode 100644
index d5969fec..00000000
--- a/static/css/base16-macintosh.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #000000; }
-.base01-background { background-color: #404040; }
-.base02-background { background-color: #404040; }
-.base03-background { background-color: #808080; }
-.base04-background { background-color: #808080; }
-.base05-background { background-color: #c0c0c0; }
-.base06-background { background-color: #c0c0c0; }
-.base07-background { background-color: #ffffff; }
-.base08-background { background-color: #dd0907; }
-.base09-background { background-color: #ff6403; }
-.base0A-background { background-color: #fbf305; }
-.base0B-background { background-color: #1fb714; }
-.base0C-background { background-color: #02abea; }
-.base0D-background { background-color: #0000d3; }
-.base0E-background { background-color: #4700a5; }
-.base0F-background { background-color: #90713a; }
-
-.base00 { color: #000000; }
-.base01 { color: #404040; }
-.base02 { color: #404040; }
-.base03 { color: #808080; }
-.base04 { color: #808080; }
-.base05 { color: #c0c0c0; }
-.base06 { color: #c0c0c0; }
-.base07 { color: #ffffff; }
-.base08 { color: #dd0907; }
-.base09 { color: #ff6403; }
-.base0A { color: #fbf305; }
-.base0B { color: #1fb714; }
-.base0C { color: #02abea; }
-.base0D { color: #0000d3; }
-.base0E { color: #4700a5; }
-.base0F { color: #90713a; }
diff --git a/static/css/base16-marrakesh.css b/static/css/base16-marrakesh.css
deleted file mode 100644
index 91f0471f..00000000
--- a/static/css/base16-marrakesh.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #201602; }
-.base01-background { background-color: #302e00; }
-.base02-background { background-color: #5f5b17; }
-.base03-background { background-color: #6c6823; }
-.base04-background { background-color: #86813b; }
-.base05-background { background-color: #948e48; }
-.base06-background { background-color: #ccc37a; }
-.base07-background { background-color: #faf0a5; }
-.base08-background { background-color: #c35359; }
-.base09-background { background-color: #b36144; }
-.base0A-background { background-color: #a88339; }
-.base0B-background { background-color: #18974e; }
-.base0C-background { background-color: #75a738; }
-.base0D-background { background-color: #477ca1; }
-.base0E-background { background-color: #8868b3; }
-.base0F-background { background-color: #b3588e; }
-
-.base00 { color: #201602; }
-.base01 { color: #302e00; }
-.base02 { color: #5f5b17; }
-.base03 { color: #6c6823; }
-.base04 { color: #86813b; }
-.base05 { color: #948e48; }
-.base06 { color: #ccc37a; }
-.base07 { color: #faf0a5; }
-.base08 { color: #c35359; }
-.base09 { color: #b36144; }
-.base0A { color: #a88339; }
-.base0B { color: #18974e; }
-.base0C { color: #75a738; }
-.base0D { color: #477ca1; }
-.base0E { color: #8868b3; }
-.base0F { color: #b3588e; }
diff --git a/static/css/base16-materia.css b/static/css/base16-materia.css
deleted file mode 100644
index 41d935dd..00000000
--- a/static/css/base16-materia.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #263238; }
-.base01-background { background-color: #2C393F; }
-.base02-background { background-color: #37474F; }
-.base03-background { background-color: #707880; }
-.base04-background { background-color: #C9CCD3; }
-.base05-background { background-color: #CDD3DE; }
-.base06-background { background-color: #D5DBE5; }
-.base07-background { background-color: #FFFFFF; }
-.base08-background { background-color: #EC5F67; }
-.base09-background { background-color: #EA9560; }
-.base0A-background { background-color: #FFCC00; }
-.base0B-background { background-color: #8BD649; }
-.base0C-background { background-color: #80CBC4; }
-.base0D-background { background-color: #89DDFF; }
-.base0E-background { background-color: #82AAFF; }
-.base0F-background { background-color: #EC5F67; }
-
-.base00 { color: #263238; }
-.base01 { color: #2C393F; }
-.base02 { color: #37474F; }
-.base03 { color: #707880; }
-.base04 { color: #C9CCD3; }
-.base05 { color: #CDD3DE; }
-.base06 { color: #D5DBE5; }
-.base07 { color: #FFFFFF; }
-.base08 { color: #EC5F67; }
-.base09 { color: #EA9560; }
-.base0A { color: #FFCC00; }
-.base0B { color: #8BD649; }
-.base0C { color: #80CBC4; }
-.base0D { color: #89DDFF; }
-.base0E { color: #82AAFF; }
-.base0F { color: #EC5F67; }
diff --git a/static/css/base16-mexico-light.css b/static/css/base16-mexico-light.css
deleted file mode 100644
index 1916c67b..00000000
--- a/static/css/base16-mexico-light.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #f8f8f8; }
-.base01-background { background-color: #e8e8e8; }
-.base02-background { background-color: #d8d8d8; }
-.base03-background { background-color: #b8b8b8; }
-.base04-background { background-color: #585858; }
-.base05-background { background-color: #383838; }
-.base06-background { background-color: #282828; }
-.base07-background { background-color: #181818; }
-.base08-background { background-color: #ab4642; }
-.base09-background { background-color: #dc9656; }
-.base0A-background { background-color: #f79a0e; }
-.base0B-background { background-color: #538947; }
-.base0C-background { background-color: #4b8093; }
-.base0D-background { background-color: #7cafc2; }
-.base0E-background { background-color: #96609e; }
-.base0F-background { background-color: #a16946; }
-
-.base00 { color: #f8f8f8; }
-.base01 { color: #e8e8e8; }
-.base02 { color: #d8d8d8; }
-.base03 { color: #b8b8b8; }
-.base04 { color: #585858; }
-.base05 { color: #383838; }
-.base06 { color: #282828; }
-.base07 { color: #181818; }
-.base08 { color: #ab4642; }
-.base09 { color: #dc9656; }
-.base0A { color: #f79a0e; }
-.base0B { color: #538947; }
-.base0C { color: #4b8093; }
-.base0D { color: #7cafc2; }
-.base0E { color: #96609e; }
-.base0F { color: #a16946; }
diff --git a/static/css/base16-mocha.css b/static/css/base16-mocha.css
deleted file mode 100644
index 6cb2fb58..00000000
--- a/static/css/base16-mocha.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #3B3228; }
-.base01-background { background-color: #534636; }
-.base02-background { background-color: #645240; }
-.base03-background { background-color: #7e705a; }
-.base04-background { background-color: #b8afad; }
-.base05-background { background-color: #d0c8c6; }
-.base06-background { background-color: #e9e1dd; }
-.base07-background { background-color: #f5eeeb; }
-.base08-background { background-color: #cb6077; }
-.base09-background { background-color: #d28b71; }
-.base0A-background { background-color: #f4bc87; }
-.base0B-background { background-color: #beb55b; }
-.base0C-background { background-color: #7bbda4; }
-.base0D-background { background-color: #8ab3b5; }
-.base0E-background { background-color: #a89bb9; }
-.base0F-background { background-color: #bb9584; }
-
-.base00 { color: #3B3228; }
-.base01 { color: #534636; }
-.base02 { color: #645240; }
-.base03 { color: #7e705a; }
-.base04 { color: #b8afad; }
-.base05 { color: #d0c8c6; }
-.base06 { color: #e9e1dd; }
-.base07 { color: #f5eeeb; }
-.base08 { color: #cb6077; }
-.base09 { color: #d28b71; }
-.base0A { color: #f4bc87; }
-.base0B { color: #beb55b; }
-.base0C { color: #7bbda4; }
-.base0D { color: #8ab3b5; }
-.base0E { color: #a89bb9; }
-.base0F { color: #bb9584; }
diff --git a/static/css/base16-monokai.css b/static/css/base16-monokai.css
deleted file mode 100644
index fc7ccf47..00000000
--- a/static/css/base16-monokai.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #272822; }
-.base01-background { background-color: #383830; }
-.base02-background { background-color: #49483e; }
-.base03-background { background-color: #75715e; }
-.base04-background { background-color: #a59f85; }
-.base05-background { background-color: #f8f8f2; }
-.base06-background { background-color: #f5f4f1; }
-.base07-background { background-color: #f9f8f5; }
-.base08-background { background-color: #f92672; }
-.base09-background { background-color: #fd971f; }
-.base0A-background { background-color: #f4bf75; }
-.base0B-background { background-color: #a6e22e; }
-.base0C-background { background-color: #a1efe4; }
-.base0D-background { background-color: #66d9ef; }
-.base0E-background { background-color: #ae81ff; }
-.base0F-background { background-color: #cc6633; }
-
-.base00 { color: #272822; }
-.base01 { color: #383830; }
-.base02 { color: #49483e; }
-.base03 { color: #75715e; }
-.base04 { color: #a59f85; }
-.base05 { color: #f8f8f2; }
-.base06 { color: #f5f4f1; }
-.base07 { color: #f9f8f5; }
-.base08 { color: #f92672; }
-.base09 { color: #fd971f; }
-.base0A { color: #f4bf75; }
-.base0B { color: #a6e22e; }
-.base0C { color: #a1efe4; }
-.base0D { color: #66d9ef; }
-.base0E { color: #ae81ff; }
-.base0F { color: #cc6633; }
diff --git a/static/css/base16-ocean.css b/static/css/base16-ocean.css
deleted file mode 100644
index 8622d17e..00000000
--- a/static/css/base16-ocean.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #2b303b; }
-.base01-background { background-color: #343d46; }
-.base02-background { background-color: #4f5b66; }
-.base03-background { background-color: #65737e; }
-.base04-background { background-color: #a7adba; }
-.base05-background { background-color: #c0c5ce; }
-.base06-background { background-color: #dfe1e8; }
-.base07-background { background-color: #eff1f5; }
-.base08-background { background-color: #bf616a; }
-.base09-background { background-color: #d08770; }
-.base0A-background { background-color: #ebcb8b; }
-.base0B-background { background-color: #a3be8c; }
-.base0C-background { background-color: #96b5b4; }
-.base0D-background { background-color: #8fa1b3; }
-.base0E-background { background-color: #b48ead; }
-.base0F-background { background-color: #ab7967; }
-
-.base00 { color: #2b303b; }
-.base01 { color: #343d46; }
-.base02 { color: #4f5b66; }
-.base03 { color: #65737e; }
-.base04 { color: #a7adba; }
-.base05 { color: #c0c5ce; }
-.base06 { color: #dfe1e8; }
-.base07 { color: #eff1f5; }
-.base08 { color: #bf616a; }
-.base09 { color: #d08770; }
-.base0A { color: #ebcb8b; }
-.base0B { color: #a3be8c; }
-.base0C { color: #96b5b4; }
-.base0D { color: #8fa1b3; }
-.base0E { color: #b48ead; }
-.base0F { color: #ab7967; }
diff --git a/static/css/base16-oceanicnext.css b/static/css/base16-oceanicnext.css
deleted file mode 100644
index df4d9ef5..00000000
--- a/static/css/base16-oceanicnext.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #1B2B34; }
-.base01-background { background-color: #343D46; }
-.base02-background { background-color: #4F5B66; }
-.base03-background { background-color: #65737E; }
-.base04-background { background-color: #A7ADBA; }
-.base05-background { background-color: #C0C5CE; }
-.base06-background { background-color: #CDD3DE; }
-.base07-background { background-color: #D8DEE9; }
-.base08-background { background-color: #EC5f67; }
-.base09-background { background-color: #F99157; }
-.base0A-background { background-color: #FAC863; }
-.base0B-background { background-color: #99C794; }
-.base0C-background { background-color: #5FB3B3; }
-.base0D-background { background-color: #6699CC; }
-.base0E-background { background-color: #C594C5; }
-.base0F-background { background-color: #AB7967; }
-
-.base00 { color: #1B2B34; }
-.base01 { color: #343D46; }
-.base02 { color: #4F5B66; }
-.base03 { color: #65737E; }
-.base04 { color: #A7ADBA; }
-.base05 { color: #C0C5CE; }
-.base06 { color: #CDD3DE; }
-.base07 { color: #D8DEE9; }
-.base08 { color: #EC5f67; }
-.base09 { color: #F99157; }
-.base0A { color: #FAC863; }
-.base0B { color: #99C794; }
-.base0C { color: #5FB3B3; }
-.base0D { color: #6699CC; }
-.base0E { color: #C594C5; }
-.base0F { color: #AB7967; }
diff --git a/static/css/base16-paraiso.css b/static/css/base16-paraiso.css
deleted file mode 100644
index b68c9407..00000000
--- a/static/css/base16-paraiso.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #2f1e2e; }
-.base01-background { background-color: #41323f; }
-.base02-background { background-color: #4f424c; }
-.base03-background { background-color: #776e71; }
-.base04-background { background-color: #8d8687; }
-.base05-background { background-color: #a39e9b; }
-.base06-background { background-color: #b9b6b0; }
-.base07-background { background-color: #e7e9db; }
-.base08-background { background-color: #ef6155; }
-.base09-background { background-color: #f99b15; }
-.base0A-background { background-color: #fec418; }
-.base0B-background { background-color: #48b685; }
-.base0C-background { background-color: #5bc4bf; }
-.base0D-background { background-color: #06b6ef; }
-.base0E-background { background-color: #815ba4; }
-.base0F-background { background-color: #e96ba8; }
-
-.base00 { color: #2f1e2e; }
-.base01 { color: #41323f; }
-.base02 { color: #4f424c; }
-.base03 { color: #776e71; }
-.base04 { color: #8d8687; }
-.base05 { color: #a39e9b; }
-.base06 { color: #b9b6b0; }
-.base07 { color: #e7e9db; }
-.base08 { color: #ef6155; }
-.base09 { color: #f99b15; }
-.base0A { color: #fec418; }
-.base0B { color: #48b685; }
-.base0C { color: #5bc4bf; }
-.base0D { color: #06b6ef; }
-.base0E { color: #815ba4; }
-.base0F { color: #e96ba8; }
diff --git a/static/css/base16-phd.css b/static/css/base16-phd.css
deleted file mode 100644
index 54276ab1..00000000
--- a/static/css/base16-phd.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #061229; }
-.base01-background { background-color: #2a3448; }
-.base02-background { background-color: #4d5666; }
-.base03-background { background-color: #717885; }
-.base04-background { background-color: #9a99a3; }
-.base05-background { background-color: #b8bbc2; }
-.base06-background { background-color: #dbdde0; }
-.base07-background { background-color: #ffffff; }
-.base08-background { background-color: #d07346; }
-.base09-background { background-color: #f0a000; }
-.base0A-background { background-color: #fbd461; }
-.base0B-background { background-color: #99bf52; }
-.base0C-background { background-color: #72b9bf; }
-.base0D-background { background-color: #5299bf; }
-.base0E-background { background-color: #9989cc; }
-.base0F-background { background-color: #b08060; }
-
-.base00 { color: #061229; }
-.base01 { color: #2a3448; }
-.base02 { color: #4d5666; }
-.base03 { color: #717885; }
-.base04 { color: #9a99a3; }
-.base05 { color: #b8bbc2; }
-.base06 { color: #dbdde0; }
-.base07 { color: #ffffff; }
-.base08 { color: #d07346; }
-.base09 { color: #f0a000; }
-.base0A { color: #fbd461; }
-.base0B { color: #99bf52; }
-.base0C { color: #72b9bf; }
-.base0D { color: #5299bf; }
-.base0E { color: #9989cc; }
-.base0F { color: #b08060; }
diff --git a/static/css/base16-pico.css b/static/css/base16-pico.css
deleted file mode 100644
index 86482b72..00000000
--- a/static/css/base16-pico.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #000000; }
-.base01-background { background-color: #1d2b53; }
-.base02-background { background-color: #7e2553; }
-.base03-background { background-color: #008751; }
-.base04-background { background-color: #ab5236; }
-.base05-background { background-color: #5f574f; }
-.base06-background { background-color: #c2c3c7; }
-.base07-background { background-color: #fff1e8; }
-.base08-background { background-color: #ff004d; }
-.base09-background { background-color: #ffa300; }
-.base0A-background { background-color: #fff024; }
-.base0B-background { background-color: #00e756; }
-.base0C-background { background-color: #29adff; }
-.base0D-background { background-color: #83769c; }
-.base0E-background { background-color: #ff77a8; }
-.base0F-background { background-color: #ffccaa; }
-
-.base00 { color: #000000; }
-.base01 { color: #1d2b53; }
-.base02 { color: #7e2553; }
-.base03 { color: #008751; }
-.base04 { color: #ab5236; }
-.base05 { color: #5f574f; }
-.base06 { color: #c2c3c7; }
-.base07 { color: #fff1e8; }
-.base08 { color: #ff004d; }
-.base09 { color: #ffa300; }
-.base0A { color: #fff024; }
-.base0B { color: #00e756; }
-.base0C { color: #29adff; }
-.base0D { color: #83769c; }
-.base0E { color: #ff77a8; }
-.base0F { color: #ffccaa; }
diff --git a/static/css/base16-pleroma-dark.css b/static/css/base16-pleroma-dark.css
deleted file mode 100644
index e1d46f92..00000000
--- a/static/css/base16-pleroma-dark.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #161c20; }
-.base01-background { background-color: #282e32; }
-.base02-background { background-color: #343a3f; }
-.base03-background { background-color: #4e5256; }
-.base04-background { background-color: #ababab; }
-.base05-background { background-color: #b9b9b9; }
-.base06-background { background-color: #d0d0d0; }
-.base07-background { background-color: #e7e7e7; }
-.base08-background { background-color: #baaa9c; }
-.base09-background { background-color: #999999; }
-.base0A-background { background-color: #a0a0a0; }
-.base0B-background { background-color: #8e8e8e; }
-.base0C-background { background-color: #868686; }
-.base0D-background { background-color: #686868; }
-.base0E-background { background-color: #747474; }
-.base0F-background { background-color: #5e5e5e; }
-
-.base00 { color: #161c20; }
-.base01 { color: #282e32; }
-.base02 { color: #343a3f; }
-.base03 { color: #4e5256; }
-.base04 { color: #ababab; }
-.base05 { color: #b9b9b9; }
-.base06 { color: #d0d0d0; }
-.base07 { color: #e7e7e7; }
-.base08 { color: #baaa9c; }
-.base09 { color: #999999; }
-.base0A { color: #a0a0a0; }
-.base0B { color: #8e8e8e; }
-.base0C { color: #868686; }
-.base0D { color: #686868; }
-.base0E { color: #747474; }
-.base0F { color: #5e5e5e; }
diff --git a/static/css/base16-pleroma-light.css b/static/css/base16-pleroma-light.css
deleted file mode 100644
index 1a85689a..00000000
--- a/static/css/base16-pleroma-light.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #f2f4f6; }
-.base01-background { background-color: #dde2e6; }
-.base02-background { background-color: #c0c6cb; }
-.base03-background { background-color: #a4a4a4; }
-.base04-background { background-color: #545454; }
-.base05-background { background-color: #304055; }
-.base06-background { background-color: #040404; }
-.base07-background { background-color: #000000; }
-.base08-background { background-color: #e92f2f; }
-.base09-background { background-color: #e09448; }
-.base0A-background { background-color: #dddd13; }
-.base0B-background { background-color: #0ed839; }
-.base0C-background { background-color: #23edda; }
-.base0D-background { background-color: #3b48e3; }
-.base0E-background { background-color: #f996e2; }
-.base0F-background { background-color: #69542d; }
-
-.base00 { color: #f2f4f6; }
-.base01 { color: #dde2e6; }
-.base02 { color: #c0c6cb; }
-.base03 { color: #a4a4a4; }
-.base04 { color: #545454; }
-.base05 { color: #304055; }
-.base06 { color: #040404; }
-.base07 { color: #000000; }
-.base08 { color: #e46f0f; }
-.base09 { color: #e09448; }
-.base0A { color: #dddd13; }
-.base0B { color: #0ed839; }
-.base0C { color: #23edda; }
-.base0D { color: #3b48e3; }
-.base0E { color: #f996e2; }
-.base0F { color: #69542d; }
diff --git a/static/css/base16-pop.css b/static/css/base16-pop.css
deleted file mode 100644
index 14acac17..00000000
--- a/static/css/base16-pop.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #000000; }
-.base01-background { background-color: #202020; }
-.base02-background { background-color: #303030; }
-.base03-background { background-color: #505050; }
-.base04-background { background-color: #b0b0b0; }
-.base05-background { background-color: #d0d0d0; }
-.base06-background { background-color: #e0e0e0; }
-.base07-background { background-color: #ffffff; }
-.base08-background { background-color: #eb008a; }
-.base09-background { background-color: #f29333; }
-.base0A-background { background-color: #f8ca12; }
-.base0B-background { background-color: #37b349; }
-.base0C-background { background-color: #00aabb; }
-.base0D-background { background-color: #0e5a94; }
-.base0E-background { background-color: #b31e8d; }
-.base0F-background { background-color: #7a2d00; }
-
-.base00 { color: #000000; }
-.base01 { color: #202020; }
-.base02 { color: #303030; }
-.base03 { color: #505050; }
-.base04 { color: #b0b0b0; }
-.base05 { color: #d0d0d0; }
-.base06 { color: #e0e0e0; }
-.base07 { color: #ffffff; }
-.base08 { color: #eb008a; }
-.base09 { color: #f29333; }
-.base0A { color: #f8ca12; }
-.base0B { color: #37b349; }
-.base0C { color: #00aabb; }
-.base0D { color: #0e5a94; }
-.base0E { color: #b31e8d; }
-.base0F { color: #7a2d00; }
diff --git a/static/css/base16-railscasts.css b/static/css/base16-railscasts.css
deleted file mode 100644
index 18f43bfd..00000000
--- a/static/css/base16-railscasts.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #2b2b2b; }
-.base01-background { background-color: #272935; }
-.base02-background { background-color: #3a4055; }
-.base03-background { background-color: #5a647e; }
-.base04-background { background-color: #d4cfc9; }
-.base05-background { background-color: #e6e1dc; }
-.base06-background { background-color: #f4f1ed; }
-.base07-background { background-color: #f9f7f3; }
-.base08-background { background-color: #da4939; }
-.base09-background { background-color: #cc7833; }
-.base0A-background { background-color: #ffc66d; }
-.base0B-background { background-color: #a5c261; }
-.base0C-background { background-color: #519f50; }
-.base0D-background { background-color: #6d9cbe; }
-.base0E-background { background-color: #b6b3eb; }
-.base0F-background { background-color: #bc9458; }
-
-.base00 { color: #2b2b2b; }
-.base01 { color: #272935; }
-.base02 { color: #3a4055; }
-.base03 { color: #5a647e; }
-.base04 { color: #d4cfc9; }
-.base05 { color: #e6e1dc; }
-.base06 { color: #f4f1ed; }
-.base07 { color: #f9f7f3; }
-.base08 { color: #da4939; }
-.base09 { color: #cc7833; }
-.base0A { color: #ffc66d; }
-.base0B { color: #a5c261; }
-.base0C { color: #519f50; }
-.base0D { color: #6d9cbe; }
-.base0E { color: #b6b3eb; }
-.base0F { color: #bc9458; }
diff --git a/static/css/base16-seti-ui.css b/static/css/base16-seti-ui.css
deleted file mode 100644
index bd4f9cc4..00000000
--- a/static/css/base16-seti-ui.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #151718; }
-.base01-background { background-color: #8ec43d; }
-.base02-background { background-color: #3B758C; }
-.base03-background { background-color: #41535B; }
-.base04-background { background-color: #43a5d5; }
-.base05-background { background-color: #d6d6d6; }
-.base06-background { background-color: #eeeeee; }
-.base07-background { background-color: #ffffff; }
-.base08-background { background-color: #Cd3f45; }
-.base09-background { background-color: #db7b55; }
-.base0A-background { background-color: #e6cd69; }
-.base0B-background { background-color: #9fca56; }
-.base0C-background { background-color: #55dbbe; }
-.base0D-background { background-color: #55b5db; }
-.base0E-background { background-color: #a074c4; }
-.base0F-background { background-color: #8a553f; }
-
-.base00 { color: #151718; }
-.base01 { color: #8ec43d; }
-.base02 { color: #3B758C; }
-.base03 { color: #41535B; }
-.base04 { color: #43a5d5; }
-.base05 { color: #d6d6d6; }
-.base06 { color: #eeeeee; }
-.base07 { color: #ffffff; }
-.base08 { color: #Cd3f45; }
-.base09 { color: #db7b55; }
-.base0A { color: #e6cd69; }
-.base0B { color: #9fca56; }
-.base0C { color: #55dbbe; }
-.base0D { color: #55b5db; }
-.base0E { color: #a074c4; }
-.base0F { color: #8a553f; }
diff --git a/static/css/base16-shapeshifter.css b/static/css/base16-shapeshifter.css
deleted file mode 100644
index ded18069..00000000
--- a/static/css/base16-shapeshifter.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #f9f9f9; }
-.base01-background { background-color: #e0e0e0; }
-.base02-background { background-color: #ababab; }
-.base03-background { background-color: #555555; }
-.base04-background { background-color: #343434; }
-.base05-background { background-color: #102015; }
-.base06-background { background-color: #040404; }
-.base07-background { background-color: #000000; }
-.base08-background { background-color: #e92f2f; }
-.base09-background { background-color: #e09448; }
-.base0A-background { background-color: #dddd13; }
-.base0B-background { background-color: #0ed839; }
-.base0C-background { background-color: #23edda; }
-.base0D-background { background-color: #3b48e3; }
-.base0E-background { background-color: #f996e2; }
-.base0F-background { background-color: #69542d; }
-
-.base00 { color: #f9f9f9; }
-.base01 { color: #e0e0e0; }
-.base02 { color: #ababab; }
-.base03 { color: #555555; }
-.base04 { color: #343434; }
-.base05 { color: #102015; }
-.base06 { color: #040404; }
-.base07 { color: #000000; }
-.base08 { color: #e92f2f; }
-.base09 { color: #e09448; }
-.base0A { color: #dddd13; }
-.base0B { color: #0ed839; }
-.base0C { color: #23edda; }
-.base0D { color: #3b48e3; }
-.base0E { color: #f996e2; }
-.base0F { color: #69542d; }
diff --git a/static/css/base16-solar-flare.css b/static/css/base16-solar-flare.css
deleted file mode 100644
index 7d1d3862..00000000
--- a/static/css/base16-solar-flare.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #18262F; }
-.base01-background { background-color: #222E38; }
-.base02-background { background-color: #586875; }
-.base03-background { background-color: #667581; }
-.base04-background { background-color: #85939E; }
-.base05-background { background-color: #A6AFB8; }
-.base06-background { background-color: #E8E9ED; }
-.base07-background { background-color: #F5F7FA; }
-.base08-background { background-color: #EF5253; }
-.base09-background { background-color: #E66B2B; }
-.base0A-background { background-color: #E4B51C; }
-.base0B-background { background-color: #7CC844; }
-.base0C-background { background-color: #52CBB0; }
-.base0D-background { background-color: #33B5E1; }
-.base0E-background { background-color: #A363D5; }
-.base0F-background { background-color: #D73C9A; }
-
-.base00 { color: #18262F; }
-.base01 { color: #222E38; }
-.base02 { color: #586875; }
-.base03 { color: #667581; }
-.base04 { color: #85939E; }
-.base05 { color: #A6AFB8; }
-.base06 { color: #E8E9ED; }
-.base07 { color: #F5F7FA; }
-.base08 { color: #EF5253; }
-.base09 { color: #E66B2B; }
-.base0A { color: #E4B51C; }
-.base0B { color: #7CC844; }
-.base0C { color: #52CBB0; }
-.base0D { color: #33B5E1; }
-.base0E { color: #A363D5; }
-.base0F { color: #D73C9A; }
diff --git a/static/css/base16-solarized-dark.css b/static/css/base16-solarized-dark.css
deleted file mode 100644
index ac16f12c..00000000
--- a/static/css/base16-solarized-dark.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #002b36; }
-.base01-background { background-color: #073642; }
-.base02-background { background-color: #586e75; }
-.base03-background { background-color: #657b83; }
-.base04-background { background-color: #839496; }
-.base05-background { background-color: #93a1a1; }
-.base06-background { background-color: #eee8d5; }
-.base07-background { background-color: #fdf6e3; }
-.base08-background { background-color: #dc322f; }
-.base09-background { background-color: #cb4b16; }
-.base0A-background { background-color: #b58900; }
-.base0B-background { background-color: #859900; }
-.base0C-background { background-color: #2aa198; }
-.base0D-background { background-color: #268bd2; }
-.base0E-background { background-color: #6c71c4; }
-.base0F-background { background-color: #d33682; }
-
-.base00 { color: #002b36; }
-.base01 { color: #073642; }
-.base02 { color: #586e75; }
-.base03 { color: #657b83; }
-.base04 { color: #839496; }
-.base05 { color: #93a1a1; }
-.base06 { color: #eee8d5; }
-.base07 { color: #fdf6e3; }
-.base08 { color: #dc322f; }
-.base09 { color: #cb4b16; }
-.base0A { color: #b58900; }
-.base0B { color: #859900; }
-.base0C { color: #2aa198; }
-.base0D { color: #268bd2; }
-.base0E { color: #6c71c4; }
-.base0F { color: #d33682; }
diff --git a/static/css/base16-solarized-light.css b/static/css/base16-solarized-light.css
deleted file mode 100644
index 7164cb04..00000000
--- a/static/css/base16-solarized-light.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #fdf6e3; }
-.base01-background { background-color: #eee8d5; }
-.base02-background { background-color: #93a1a1; }
-.base03-background { background-color: #839496; }
-.base04-background { background-color: #657b83; }
-.base05-background { background-color: #586e75; }
-.base06-background { background-color: #073642; }
-.base07-background { background-color: #002b36; }
-.base08-background { background-color: #dc322f; }
-.base09-background { background-color: #cb4b16; }
-.base0A-background { background-color: #b58900; }
-.base0B-background { background-color: #859900; }
-.base0C-background { background-color: #2aa198; }
-.base0D-background { background-color: #268bd2; }
-.base0E-background { background-color: #6c71c4; }
-.base0F-background { background-color: #d33682; }
-
-.base00 { color: #fdf6e3; }
-.base01 { color: #eee8d5; }
-.base02 { color: #93a1a1; }
-.base03 { color: #839496; }
-.base04 { color: #657b83; }
-.base05 { color: #586e75; }
-.base06 { color: #073642; }
-.base07 { color: #002b36; }
-.base08 { color: #dc322f; }
-.base09 { color: #cb4b16; }
-.base0A { color: #b58900; }
-.base0B { color: #859900; }
-.base0C { color: #2aa198; }
-.base0D { color: #268bd2; }
-.base0E { color: #6c71c4; }
-.base0F { color: #d33682; }
diff --git a/static/css/base16-spacemacs.css b/static/css/base16-spacemacs.css
deleted file mode 100644
index 48737650..00000000
--- a/static/css/base16-spacemacs.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #1f2022; }
-.base01-background { background-color: #282828; }
-.base02-background { background-color: #444155; }
-.base03-background { background-color: #585858; }
-.base04-background { background-color: #b8b8b8; }
-.base05-background { background-color: #a3a3a3; }
-.base06-background { background-color: #e8e8e8; }
-.base07-background { background-color: #f8f8f8; }
-.base08-background { background-color: #f2241f; }
-.base09-background { background-color: #ffa500; }
-.base0A-background { background-color: #b1951d; }
-.base0B-background { background-color: #67b11d; }
-.base0C-background { background-color: #2d9574; }
-.base0D-background { background-color: #4f97d7; }
-.base0E-background { background-color: #a31db1; }
-.base0F-background { background-color: #b03060; }
-
-.base00 { color: #1f2022; }
-.base01 { color: #282828; }
-.base02 { color: #444155; }
-.base03 { color: #585858; }
-.base04 { color: #b8b8b8; }
-.base05 { color: #a3a3a3; }
-.base06 { color: #e8e8e8; }
-.base07 { color: #f8f8f8; }
-.base08 { color: #f2241f; }
-.base09 { color: #ffa500; }
-.base0A { color: #b1951d; }
-.base0B { color: #67b11d; }
-.base0C { color: #2d9574; }
-.base0D { color: #4f97d7; }
-.base0E { color: #a31db1; }
-.base0F { color: #b03060; }
diff --git a/static/css/base16-summerfruit-dark.css b/static/css/base16-summerfruit-dark.css
deleted file mode 100644
index 1c8f2332..00000000
--- a/static/css/base16-summerfruit-dark.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #151515; }
-.base01-background { background-color: #202020; }
-.base02-background { background-color: #303030; }
-.base03-background { background-color: #505050; }
-.base04-background { background-color: #B0B0B0; }
-.base05-background { background-color: #D0D0D0; }
-.base06-background { background-color: #E0E0E0; }
-.base07-background { background-color: #FFFFFF; }
-.base08-background { background-color: #FF0086; }
-.base09-background { background-color: #FD8900; }
-.base0A-background { background-color: #ABA800; }
-.base0B-background { background-color: #00C918; }
-.base0C-background { background-color: #1FAAAA; }
-.base0D-background { background-color: #3777E6; }
-.base0E-background { background-color: #AD00A1; }
-.base0F-background { background-color: #CC6633; }
-
-.base00 { color: #151515; }
-.base01 { color: #202020; }
-.base02 { color: #303030; }
-.base03 { color: #505050; }
-.base04 { color: #B0B0B0; }
-.base05 { color: #D0D0D0; }
-.base06 { color: #E0E0E0; }
-.base07 { color: #FFFFFF; }
-.base08 { color: #FF0086; }
-.base09 { color: #FD8900; }
-.base0A { color: #ABA800; }
-.base0B { color: #00C918; }
-.base0C { color: #1FAAAA; }
-.base0D { color: #3777E6; }
-.base0E { color: #AD00A1; }
-.base0F { color: #CC6633; }
diff --git a/static/css/base16-summerfruit-light.css b/static/css/base16-summerfruit-light.css
deleted file mode 100644
index cb54d4c5..00000000
--- a/static/css/base16-summerfruit-light.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #FFFFFF; }
-.base01-background { background-color: #E0E0E0; }
-.base02-background { background-color: #D0D0D0; }
-.base03-background { background-color: #B0B0B0; }
-.base04-background { background-color: #000000; }
-.base05-background { background-color: #101010; }
-.base06-background { background-color: #151515; }
-.base07-background { background-color: #202020; }
-.base08-background { background-color: #FF0086; }
-.base09-background { background-color: #FD8900; }
-.base0A-background { background-color: #ABA800; }
-.base0B-background { background-color: #00C918; }
-.base0C-background { background-color: #1FAAAA; }
-.base0D-background { background-color: #3777E6; }
-.base0E-background { background-color: #AD00A1; }
-.base0F-background { background-color: #CC6633; }
-
-.base00 { color: #FFFFFF; }
-.base01 { color: #E0E0E0; }
-.base02 { color: #D0D0D0; }
-.base03 { color: #B0B0B0; }
-.base04 { color: #000000; }
-.base05 { color: #101010; }
-.base06 { color: #151515; }
-.base07 { color: #202020; }
-.base08 { color: #FF0086; }
-.base09 { color: #FD8900; }
-.base0A { color: #ABA800; }
-.base0B { color: #00C918; }
-.base0C { color: #1FAAAA; }
-.base0D { color: #3777E6; }
-.base0E { color: #AD00A1; }
-.base0F { color: #CC6633; }
diff --git a/static/css/base16-tomorrow-night.css b/static/css/base16-tomorrow-night.css
deleted file mode 100644
index 09ecf08e..00000000
--- a/static/css/base16-tomorrow-night.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #1d1f21; }
-.base01-background { background-color: #282a2e; }
-.base02-background { background-color: #373b41; }
-.base03-background { background-color: #969896; }
-.base04-background { background-color: #b4b7b4; }
-.base05-background { background-color: #c5c8c6; }
-.base06-background { background-color: #e0e0e0; }
-.base07-background { background-color: #ffffff; }
-.base08-background { background-color: #cc6666; }
-.base09-background { background-color: #de935f; }
-.base0A-background { background-color: #f0c674; }
-.base0B-background { background-color: #b5bd68; }
-.base0C-background { background-color: #8abeb7; }
-.base0D-background { background-color: #81a2be; }
-.base0E-background { background-color: #b294bb; }
-.base0F-background { background-color: #a3685a; }
-
-.base00 { color: #1d1f21; }
-.base01 { color: #282a2e; }
-.base02 { color: #373b41; }
-.base03 { color: #969896; }
-.base04 { color: #b4b7b4; }
-.base05 { color: #c5c8c6; }
-.base06 { color: #e0e0e0; }
-.base07 { color: #ffffff; }
-.base08 { color: #cc6666; }
-.base09 { color: #de935f; }
-.base0A { color: #f0c674; }
-.base0B { color: #b5bd68; }
-.base0C { color: #8abeb7; }
-.base0D { color: #81a2be; }
-.base0E { color: #b294bb; }
-.base0F { color: #a3685a; }
diff --git a/static/css/base16-tomorrow.css b/static/css/base16-tomorrow.css
deleted file mode 100644
index f1486823..00000000
--- a/static/css/base16-tomorrow.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #ffffff; }
-.base01-background { background-color: #e0e0e0; }
-.base02-background { background-color: #d6d6d6; }
-.base03-background { background-color: #8e908c; }
-.base04-background { background-color: #969896; }
-.base05-background { background-color: #4d4d4c; }
-.base06-background { background-color: #282a2e; }
-.base07-background { background-color: #1d1f21; }
-.base08-background { background-color: #c82829; }
-.base09-background { background-color: #f5871f; }
-.base0A-background { background-color: #eab700; }
-.base0B-background { background-color: #718c00; }
-.base0C-background { background-color: #3e999f; }
-.base0D-background { background-color: #4271ae; }
-.base0E-background { background-color: #8959a8; }
-.base0F-background { background-color: #a3685a; }
-
-.base00 { color: #ffffff; }
-.base01 { color: #e0e0e0; }
-.base02 { color: #d6d6d6; }
-.base03 { color: #8e908c; }
-.base04 { color: #969896; }
-.base05 { color: #4d4d4c; }
-.base06 { color: #282a2e; }
-.base07 { color: #1d1f21; }
-.base08 { color: #c82829; }
-.base09 { color: #f5871f; }
-.base0A { color: #eab700; }
-.base0B { color: #718c00; }
-.base0C { color: #3e999f; }
-.base0D { color: #4271ae; }
-.base0E { color: #8959a8; }
-.base0F { color: #a3685a; }
diff --git a/static/css/base16-twilight.css b/static/css/base16-twilight.css
deleted file mode 100644
index c8dfda3f..00000000
--- a/static/css/base16-twilight.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #1e1e1e; }
-.base01-background { background-color: #323537; }
-.base02-background { background-color: #464b50; }
-.base03-background { background-color: #5f5a60; }
-.base04-background { background-color: #838184; }
-.base05-background { background-color: #a7a7a7; }
-.base06-background { background-color: #c3c3c3; }
-.base07-background { background-color: #ffffff; }
-.base08-background { background-color: #cf6a4c; }
-.base09-background { background-color: #cda869; }
-.base0A-background { background-color: #f9ee98; }
-.base0B-background { background-color: #8f9d6a; }
-.base0C-background { background-color: #afc4db; }
-.base0D-background { background-color: #7587a6; }
-.base0E-background { background-color: #9b859d; }
-.base0F-background { background-color: #9b703f; }
-
-.base00 { color: #1e1e1e; }
-.base01 { color: #323537; }
-.base02 { color: #464b50; }
-.base03 { color: #5f5a60; }
-.base04 { color: #838184; }
-.base05 { color: #a7a7a7; }
-.base06 { color: #c3c3c3; }
-.base07 { color: #ffffff; }
-.base08 { color: #cf6a4c; }
-.base09 { color: #cda869; }
-.base0A { color: #f9ee98; }
-.base0B { color: #8f9d6a; }
-.base0C { color: #afc4db; }
-.base0D { color: #7587a6; }
-.base0E { color: #9b859d; }
-.base0F { color: #9b703f; }
diff --git a/static/css/base16-unikitty-dark.css b/static/css/base16-unikitty-dark.css
deleted file mode 100644
index e6ef32e3..00000000
--- a/static/css/base16-unikitty-dark.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #2e2a31; }
-.base01-background { background-color: #4a464d; }
-.base02-background { background-color: #666369; }
-.base03-background { background-color: #838085; }
-.base04-background { background-color: #9f9da2; }
-.base05-background { background-color: #bcbabe; }
-.base06-background { background-color: #d8d7da; }
-.base07-background { background-color: #f5f4f7; }
-.base08-background { background-color: #d8137f; }
-.base09-background { background-color: #d65407; }
-.base0A-background { background-color: #dc8a0e; }
-.base0B-background { background-color: #17ad98; }
-.base0C-background { background-color: #149bda; }
-.base0D-background { background-color: #796af5; }
-.base0E-background { background-color: #bb60ea; }
-.base0F-background { background-color: #c720ca; }
-
-.base00 { color: #2e2a31; }
-.base01 { color: #4a464d; }
-.base02 { color: #666369; }
-.base03 { color: #838085; }
-.base04 { color: #9f9da2; }
-.base05 { color: #bcbabe; }
-.base06 { color: #d8d7da; }
-.base07 { color: #f5f4f7; }
-.base08 { color: #d8137f; }
-.base09 { color: #d65407; }
-.base0A { color: #dc8a0e; }
-.base0B { color: #17ad98; }
-.base0C { color: #149bda; }
-.base0D { color: #796af5; }
-.base0E { color: #bb60ea; }
-.base0F { color: #c720ca; }
diff --git a/static/css/base16-unikitty-light.css b/static/css/base16-unikitty-light.css
deleted file mode 100644
index 7e4c51b7..00000000
--- a/static/css/base16-unikitty-light.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.base00-background { background-color: #ffffff; }
-.base01-background { background-color: #e1e1e2; }
-.base02-background { background-color: #c4c3c5; }
-.base03-background { background-color: #a7a5a8; }
-.base04-background { background-color: #89878b; }
-.base05-background { background-color: #6c696e; }
-.base06-background { background-color: #4f4b51; }
-.base07-background { background-color: #322d34; }
-.base08-background { background-color: #d8137f; }
-.base09-background { background-color: #d65407; }
-.base0A-background { background-color: #dc8a0e; }
-.base0B-background { background-color: #17ad98; }
-.base0C-background { background-color: #149bda; }
-.base0D-background { background-color: #775dff; }
-.base0E-background { background-color: #aa17e6; }
-.base0F-background { background-color: #e013d0; }
-
-.base00 { color: #ffffff; }
-.base01 { color: #e1e1e2; }
-.base02 { color: #c4c3c5; }
-.base03 { color: #a7a5a8; }
-.base04 { color: #89878b; }
-.base05 { color: #6c696e; }
-.base06 { color: #4f4b51; }
-.base07 { color: #322d34; }
-.base08 { color: #d8137f; }
-.base09 { color: #d65407; }
-.base0A { color: #dc8a0e; }
-.base0B { color: #17ad98; }
-.base0C { color: #149bda; }
-.base0D { color: #775dff; }
-.base0E { color: #aa17e6; }
-.base0F { color: #e013d0; }
diff --git a/static/css/themes.json b/static/css/themes.json
deleted file mode 100644
index ea8e5a0c..00000000
--- a/static/css/themes.json
+++ /dev/null
@@ -1,66 +0,0 @@
-[
-"base16-pleroma-dark.css",
-"base16-pleroma-light.css",
-"base16-3024.css",
-"base16-apathy.css",
-"base16-ashes.css",
-"base16-atelier-cave.css",
-"base16-atelier-dune.css",
-"base16-atelier-estuary.css",
-"base16-atelier-forest.css",
-"base16-atelier-heath.css",
-"base16-atelier-lakeside.css",
-"base16-atelier-plateau.css",
-"base16-atelier-savanna.css",
-"base16-atelier-seaside.css",
-"base16-atelier-sulphurpool.css",
-"base16-bespin.css",
-"base16-brewer.css",
-"base16-bright.css",
-"base16-chalk.css",
-"base16-codeschool.css",
-"base16-darktooth.css",
-"base16-default-dark.css",
-"base16-default-light.css",
-"base16-eighties.css",
-"base16-embers.css",
-"base16-flat.css",
-"base16-github.css",
-"base16-google-dark.css",
-"base16-google-light.css",
-"base16-grayscale-dark.css",
-"base16-grayscale-light.css",
-"base16-green-screen.css",
-"base16-harmonic16-dark.css",
-"base16-harmonic16-light.css",
-"base16-hopscotch.css",
-"base16-ir-black.css",
-"base16-isotope.css",
-"base16-london-tube.css",
-"base16-macintosh.css",
-"base16-marrakesh.css",
-"base16-materia.css",
-"base16-mexico-light.css",
-"base16-mocha.css",
-"base16-monokai.css",
-"base16-ocean.css",
-"base16-oceanicnext.css",
-"base16-paraiso.css",
-"base16-phd.css",
-"base16-pico.css",
-"base16-pop.css",
-"base16-railscasts.css",
-"base16-seti-ui.css",
-"base16-shapeshifter.css",
-"base16-solar-flare.css",
-"base16-solarized-dark.css",
-"base16-solarized-light.css",
-"base16-spacemacs.css",
-"base16-summerfruit-dark.css",
-"base16-summerfruit-light.css",
-"base16-tomorrow-night.css",
-"base16-tomorrow.css",
-"base16-twilight.css",
-"base16-unikitty-dark.css",
-"base16-unikitty-light.css"
-]
diff --git a/static/fontello.json b/static/fontello.json
index 5a7086a2..ac3f0a18 100755
--- a/static/fontello.json
+++ b/static/fontello.json
@@ -345,6 +345,36 @@
"css": "link",
"code": 59427,
"src": "fontawesome"
+ },
+ {
+ "uid": "4aad6bb50b02c18508aae9cbe14e784e",
+ "css": "share",
+ "code": 61920,
+ "src": "fontawesome"
+ },
+ {
+ "uid": "8b80d36d4ef43889db10bc1f0dc9a862",
+ "css": "user",
+ "code": 59428,
+ "src": "fontawesome"
+ },
+ {
+ "uid": "12f4ece88e46abd864e40b35e05b11cd",
+ "css": "ok",
+ "code": 59431,
+ "src": "fontawesome"
+ },
+ {
+ "uid": "4109c474ff99cad28fd5a2c38af2ec6f",
+ "css": "filter",
+ "code": 61616,
+ "src": "fontawesome"
+ },
+ {
+ "uid": "9a76bc135eac17d2c8b8ad4a5774fc87",
+ "css": "download",
+ "code": 59429,
+ "src": "fontawesome"
}
]
-}
+}
\ No newline at end of file
diff --git a/static/styles.json b/static/styles.json
index 23508970..23f57c65 100644
--- a/static/styles.json
+++ b/static/styles.json
@@ -1,6 +1,6 @@
{
- "pleroma-dark": [ "Pleroma Dark", "#121a24", "#182230", "#b9b9ba", "#d8a070", "#d31014", "#0fa00f", "#0095ff", "#ffa500" ],
- "pleroma-light": [ "Pleroma Light", "#f2f4f6", "#dbe0e8", "#304055", "#f86f0f", "#d31014", "#0fa00f", "#0095ff", "#ffa500" ],
+ "pleroma-dark": "/static/themes/pleroma-dark.json",
+ "pleroma-light": "/static/themes/pleroma-light.json",
"pleroma-amoled": [ "Pleroma Dark AMOLED", "#000000", "#111111", "#b0b0b1", "#d8a070", "#aa0000", "#0fa00f", "#0095ff", "#d59500"],
"classic-dark": [ "Classic Dark", "#161c20", "#282e32", "#b9b9b9", "#baaa9c", "#d31014", "#0fa00f", "#0095ff", "#ffa500" ],
"bird": [ "Bird", "#f8fafd", "#e6ecf0", "#14171a", "#0084b8", "#e0245e", "#17bf63", "#1b95e0", "#fab81e"],
@@ -12,5 +12,6 @@
"redmond-xxi": "/static/themes/redmond-xxi.json",
"breezy-dark": "/static/themes/breezy-dark.json",
"breezy-light": "/static/themes/breezy-light.json",
- "mammal": "/static/themes/mammal.json"
+ "mammal": "/static/themes/mammal.json",
+ "paper": "/static/themes/paper.json"
}
diff --git a/static/terms-of-service.html b/static/terms-of-service.html
index c02cb719..b2c66815 100644
--- a/static/terms-of-service.html
+++ b/static/terms-of-service.html
@@ -1,7 +1,9 @@
- + diff --git a/static/themes/breezy-dark.json b/static/themes/breezy-dark.json index 6119bf88..76b962c5 100644 --- a/static/themes/breezy-dark.json +++ b/static/themes/breezy-dark.json @@ -1,7 +1,9 @@ { "_pleroma_theme_version": 2, "name": "Breezy Dark (beta)", - "theme": { + "source": { + "themeEngineVersion": 3, + "fonts": {}, "shadows": { "panel": [ { @@ -19,7 +21,7 @@ "y": "0", "blur": "0", "spread": "1", - "color": "#ffffff", + "color": "--btn,900", "alpha": "0.15", "inset": true }, @@ -40,7 +42,7 @@ "blur": "40", "spread": "-40", "inset": true, - "color": "#ffffff", + "color": "--panel,900", "alpha": "0.1" } ], @@ -50,8 +52,8 @@ "y": "0", "blur": 0, "spread": "1", - "color": "--link", - "alpha": "0.3", + "color": "--accent", + "alpha": "1", "inset": true }, { @@ -65,21 +67,12 @@ } ], "buttonPressed": [ - { - "x": 0, - "y": 0, - "blur": "0", - "spread": "50", - "color": "--faint", - "alpha": 1, - "inset": true - }, { "x": 0, "y": "0", "blur": 0, "spread": "1", - "color": "#ffffff", + "color": "--btn,900", "alpha": 0.2, "inset": true }, @@ -99,31 +92,30 @@ "y": "0", "blur": 0, "spread": "1", - "color": "#FFFFFF", + "color": "--input,900", "alpha": "0.2", "inset": true } ] }, - "fonts": {}, - "opacity": { - "input": "1", - "panel": "0" - }, + "opacity": {}, "colors": { "bg": "#31363b", "text": "#eff0f1", "link": "#3daee9", "fg": "#31363b", - "panel": "#31363b", - "input": "#232629", - "topBarLink": "#eff0f1", - "btn": "#31363b", + "panel": "transparent", + "input": "--bg,-6.47", + "topBarLink": "--topBarText", + "btn": "--bg", "border": "#4c545b", "cRed": "#da4453", "cBlue": "#3daee9", "cGreen": "#27ae60", - "cOrange": "#f67400" + "cOrange": "#f67400", + "btnPressed": "--accent", + "selectedMenu": "--accent", + "selectedMenuPopover": "--accent" }, "radii": { "btn": "2", diff --git a/static/themes/breezy-light.json b/static/themes/breezy-light.json index becf704f..0968fff0 100644 --- a/static/themes/breezy-light.json +++ b/static/themes/breezy-light.json @@ -1,7 +1,9 @@ { "_pleroma_theme_version": 2, "name": "Breezy Light (beta)", - "theme": { + "source": { + "themeEngineVersion": 3, + "fonts": {}, "shadows": { "panel": [ { @@ -19,7 +21,7 @@ "y": "0", "blur": "0", "spread": "1", - "color": "#000000", + "color": "--btn,900", "alpha": "0.3", "inset": true }, @@ -40,7 +42,7 @@ "blur": "40", "spread": "-40", "inset": true, - "color": "#ffffff", + "color": "--panel,900", "alpha": "0.1" } ], @@ -50,8 +52,8 @@ "y": "0", "blur": 0, "spread": "1", - "color": "--link", - "alpha": "0.3", + "color": "--accent", + "alpha": "1", "inset": true }, { @@ -65,21 +67,12 @@ } ], "buttonPressed": [ - { - "x": 0, - "y": 0, - "blur": "0", - "spread": "50", - "color": "--faint", - "alpha": 1, - "inset": true - }, { "x": 0, "y": "0", "blur": 0, "spread": "1", - "color": "#ffffff", + "color": "--btn,900", "alpha": 0.2, "inset": true }, @@ -99,31 +92,30 @@ "y": "0", "blur": 0, "spread": "1", - "color": "#000000", + "color": "--input,900", "alpha": "0.2", "inset": true } ] }, - "fonts": {}, "opacity": { "input": "1" }, "colors": { "bg": "#eff0f1", "text": "#232627", - "link": "#2980b9", - "fg": "#bcc2c7", - "panel": "#475057", - "panelText": "#fcfcfc", - "input": "#fcfcfc", - "topBar": "#475057", - "topBarLink": "#eff0f1", - "btn": "#eff0f1", + "fg": "#475057", + "accent": "#2980b9", + "input": "--bg,-6.47", + "topBarLink": "--topBarText", + "btn": "--bg", "cRed": "#da4453", "cBlue": "#2980b9", "cGreen": "#27ae60", - "cOrange": "#f67400" + "cOrange": "#f67400", + "btnPressed": "--accent", + "selectedMenu": "--accent", + "selectedMenuPopover": "--accent" }, "radii": { "btn": "2", diff --git a/static/themes/paper.json b/static/themes/paper.json new file mode 100644 index 00000000..a3b90a0a --- /dev/null +++ b/static/themes/paper.json @@ -0,0 +1,172 @@ +{ + "_pleroma_theme_version": 2, + "name": "Paper", + "source": { + "themeEngineVersion": 3, + "fonts": {}, + "shadows": { + "panel": [ + { + "x": "0", + "y": "2", + "blur": "9", + "spread": 0, + "inset": false, + "color": "#668bb2", + "alpha": "0.1" + }, + { + "x": "0", + "y": "1", + "blur": "2", + "spread": "-1", + "inset": false, + "color": "#668bb2", + "alpha": "0.1" + } + ], + "topBar": [ + { + "x": 0, + "y": "3", + "blur": "8", + "spread": 0, + "inset": false, + "color": "#3e618e", + "alpha": "0.1" + }, + { + "x": 0, + "y": "1", + "blur": "4", + "spread": 0, + "inset": false, + "color": "#3e618e", + "alpha": "0.1" + } + ], + "button": [ + { + "x": 0, + "y": "2", + "blur": "5", + "spread": 0, + "color": "#463f78", + "alpha": "0.1", + "inset": false + } + ], + "input": [ + { + "x": 0, + "y": "1", + "blur": "2", + "spread": 0, + "inset": true, + "color": "#6277b7", + "alpha": "0.1" + } + ], + "buttonHover": [ + { + "x": 0, + "y": "2", + "blur": "5", + "spread": 0, + "color": "#494949", + "alpha": "0.1" + }, + { + "x": 0, + "y": "2", + "blur": "0", + "spread": "20", + "color": "#ffffff", + "alpha": "1", + "inset": true + } + ], + "buttonPressed": [ + { + "x": 0, + "y": 0, + "blur": "4", + "spread": "0", + "color": "#494949", + "alpha": "0.8", + "inset": false + } + ], + "avatarStatus": [ + { + "x": "0", + "y": "2", + "blur": "4", + "spread": "0", + "inset": false, + "color": "#3e618e", + "alpha": "0.1" + } + ], + "avatar": [ + { + "x": 0, + "y": "2", + "blur": "5", + "spread": "0", + "color": "#3e618e", + "alpha": "0.9" + } + ], + "popup": [ + { + "x": "0", + "y": "3", + "blur": "11", + "spread": 0, + "color": "#668bb2", + "alpha": "0.2" + }, + { + "x": "0", + "y": "2", + "blur": "3", + "spread": "-1", + "color": "#668bb2", + "alpha": "0.2" + } + ] + }, + "opacity": { + "underlay": "1", + "border": "0" + }, + "colors": { + "bg": "#ffffff", + "fg": "#f6f6f6", + "text": "#494949", + "underlay": "#ffffff", + "link": "#788ca1", + "accent": "#97a0aa", + "cBlue": "#788ca1", + "cRed": "#eed7ce", + "cGreen": "#788ca1", + "cOrange": "#788ca1", + "postLink": "#788ca1", + "border": "#ffffff", + "icon": "#b6c9c4", + "panel": "#ffffff", + "topBarText": "#4b4b4b" + }, + "radii": { + "btn": "0", + "input": "0", + "checkbox": "0", + "panel": "0", + "avatar": "2", + "avatarAlt": "2", + "tooltip": "0", + "attachment": "0" + } + } +} diff --git a/static/themes/pleroma-dark.json b/static/themes/pleroma-dark.json new file mode 100644 index 00000000..2703fba1 --- /dev/null +++ b/static/themes/pleroma-dark.json @@ -0,0 +1,191 @@ +{ + "_pleroma_theme_version": 2, + "name": "Pleroma Dark", + "source": { + "themeEngineVersion": 3, + "fonts": {}, + "shadows": { + "buttonHover": [ + { + "x": 0, + "y": 0, + "blur": "1", + "spread": "2", + "color": "#b9b9ba", + "alpha": "0.4", + "inset": true + }, + { + "x": 0, + "y": 1, + "blur": 0, + "spread": 0, + "color": "#FFFFFF", + "alpha": 0.2, + "inset": true + }, + { + "x": 0, + "y": -1, + "blur": 0, + "spread": 0, + "color": "#000000", + "alpha": 0.2, + "inset": true + } + ], + "buttonPressed": [ + { + "x": 0, + "y": 0, + "blur": 4, + "spread": 0, + "color": "#000000", + "alpha": 1, + "inset": true + }, + { + "x": 0, + "y": 1, + "blur": 0, + "spread": 0, + "color": "#000000", + "alpha": 0.2, + "inset": true + }, + { + "x": 0, + "y": -1, + "blur": 0, + "spread": 0, + "color": "#FFFFFF", + "alpha": 0.2, + "inset": true + }, + { + "x": 0, + "y": 0, + "blur": "2", + "spread": 0, + "inset": false, + "color": "#000000", + "alpha": 1 + } + ], + "panelHeader": [ + { + "x": 0, + "y": "1", + "blur": "3", + "spread": 0, + "inset": false, + "color": "#000000", + "alpha": "0.4" + }, + { + "x": "0", + "y": "1", + "blur": "0", + "spread": 0, + "inset": true, + "color": "#ffffff", + "alpha": "0.2" + } + ], + "panel": [ + { + "x": "0", + "y": "0", + "blur": "3", + "spread": 0, + "color": "#000000", + "alpha": "0.5" + }, + { + "x": "0", + "y": "4", + "blur": "6", + "spread": "3", + "inset": false, + "color": "#000000", + "alpha": "0.3" + } + ], + "button": [ + { + "x": 0, + "y": 0, + "blur": 2, + "spread": 0, + "color": "#000000", + "alpha": 1 + }, + { + "x": 0, + "y": 1, + "blur": 0, + "spread": 0, + "color": "#FFFFFF", + "alpha": 0.2, + "inset": true + }, + { + "x": 0, + "y": -1, + "blur": 0, + "spread": 0, + "color": "#000000", + "alpha": 0.2, + "inset": true + } + ], + "topBar": [ + { + "x": 0, + "y": "1", + "blur": 4, + "spread": 0, + "color": "#000000", + "alpha": "0.4" + }, + { + "x": 0, + "y": "2", + "blur": "7", + "spread": 0, + "inset": false, + "color": "#000000", + "alpha": "0.3" + } + ] + }, + "opacity": { + "underlay": "0.6" + }, + "colors": { + "bg": "#0f161e", + "fg": "#151e2b", + "text": "#b9b9ba", + "underlay": "#090e14", + "accent": "#e2b188", + "cBlue": "#81beea", + "cRed": "#d31014", + "cGreen": "#5dc94a", + "cOrange": "#ffc459", + "border": "--fg,3", + "topBarText": "--text,-9.75", + "topBarLink": "--topBarText", + "btnToggled": "--accent,-24.2", + "alertErrorText": "--text,21.2", + "badgeNotification": "#e15932", + "badgeNotificationText": "#ffffff" + }, + "radii": { + "btn": "3", + "input": "3", + "panel": "3", + "avatar": "3", + "attachment": "3" + } + } +} diff --git a/static/themes/pleroma-light.json b/static/themes/pleroma-light.json new file mode 100644 index 00000000..05fc300a --- /dev/null +++ b/static/themes/pleroma-light.json @@ -0,0 +1,219 @@ +{ + "_pleroma_theme_version": 2, + "name": "Pleroma Light", + "source": { + "themeEngineVersion": 3, + "fonts": {}, + "shadows": { + "button": [ + { + "x": 0, + "y": 0, + "blur": 2, + "spread": 0, + "color": "#000000", + "alpha": "0.2" + }, + { + "x": 0, + "y": 1, + "blur": 0, + "spread": 0, + "color": "#FFFFFF", + "alpha": "0.5", + "inset": true + }, + { + "x": 0, + "y": -1, + "blur": 0, + "spread": 0, + "color": "#000000", + "alpha": 0.2, + "inset": true + } + ], + "buttonHover": [ + { + "x": 0, + "y": 0, + "blur": "2", + "spread": 0, + "color": "#000000", + "alpha": "0.2" + }, + { + "x": 0, + "y": "0", + "blur": "1", + "spread": "2", + "color": "#ffc39f", + "alpha": "1", + "inset": true + }, + { + "x": 0, + "y": -1, + "blur": 0, + "spread": 0, + "color": "#000000", + "alpha": 0.2, + "inset": true + } + ], + "input": [ + { + "x": 0, + "y": 1, + "blur": 0, + "spread": 0, + "color": "#000000", + "alpha": 0.2, + "inset": true + }, + { + "x": 0, + "y": -1, + "blur": 0, + "spread": 0, + "color": "#FFFFFF", + "alpha": 0.2, + "inset": true + }, + { + "x": 0, + "y": 0, + "blur": "2", + "inset": true, + "spread": 0, + "color": "#000000", + "alpha": "0.15" + } + ], + "panel": [ + { + "x": "0", + "y": 1, + "blur": "3", + "spread": 0, + "color": "#000000", + "alpha": "0.5" + }, + { + "x": "0", + "y": "3", + "blur": "6", + "spread": "1", + "inset": false, + "color": "#000000", + "alpha": "0.2" + } + ], + "panelHeader": [ + { + "x": 0, + "y": "1", + "blur": 0, + "spread": 0, + "inset": true, + "color": "#ffffff", + "alpha": "0.5" + }, + { + "x": 0, + "y": "1", + "blur": "3", + "spread": 0, + "inset": false, + "color": "#000000", + "alpha": "0.3" + } + ], + "buttonPressed": [ + { + "x": 0, + "y": 0, + "blur": 4, + "spread": 0, + "color": "#000000", + "alpha": "0.2" + }, + { + "x": 0, + "y": 1, + "blur": "1", + "spread": "2", + "color": "#000000", + "alpha": "0.3", + "inset": true + }, + { + "x": 0, + "y": -1, + "blur": 0, + "spread": 0, + "color": "#FFFFFF", + "alpha": 0.2, + "inset": true + } + ], + "popup": [ + { + "x": "1", + "y": "2", + "blur": "2", + "spread": 0, + "color": "#000000", + "alpha": "0.2" + }, + { + "x": "1", + "y": "3", + "blur": "7", + "spread": "0", + "inset": false, + "color": "#000000", + "alpha": "0.2" + } + ], + "avatarStatus": [ + { + "x": 0, + "y": "1", + "blur": "4", + "spread": "0", + "inset": false, + "color": "#000000", + "alpha": "0.2" + } + ] + }, + "opacity": { + "underlay": "0.4" + }, + "colors": { + "bg": "#f2f6f9", + "fg": "#d6dfed", + "text": "#304055", + "underlay": "#5d6086", + "accent": "#f55b1b", + "cBlue": "#0095ff", + "cRed": "#d31014", + "cGreen": "#0fa00f", + "cOrange": "#ffa500", + "border": "#d8e6f9", + "topBarText": "#304055", + "topBarLink": "--topBarText", + "btnToggled": "--accent,-24.2", + "input": "#dee3ed", + "badgeNotification": "#e83802" + }, + "radii": { + "btn": "3", + "input": "3", + "panel": "3", + "avatar": "3", + "attachment": "3" + } + } +} diff --git a/static/themes/redmond-xx-se.json b/static/themes/redmond-xx-se.json index 70ee89d1..24480d2c 100644 --- a/static/themes/redmond-xx-se.json +++ b/static/themes/redmond-xx-se.json @@ -1,7 +1,8 @@ { "_pleroma_theme_version": 2, "name": "Redmond XX SE", - "theme": { + "source": { + "themeEngineVersion": 3, "shadows": { "panel": [ { @@ -268,6 +269,7 @@ "bg": "#c0c0c0", "text": "#000000", "link": "#0000ff", + "accent": "#000080", "fg": "#c0c0c0", "panel": "#000080", "panelFaint": "#c0c0c0", @@ -275,13 +277,18 @@ "topBar": "#000080", "topBarLink": "#ffffff", "btn": "#c0c0c0", + "btnToggled": "--btn", "faint": "#3f3f3f", "faintLink": "#404080", "border": "#808080", "cRed": "#FF0000", "cBlue": "#008080", "cGreen": "#008000", - "cOrange": "#808000" + "cOrange": "#808000", + "highlight": "--accent", + "selectedPost": "--bg,-10", + "selectedMenu": "--accent", + "selectedMenuPopover": "--accent" }, "radii": { "btn": "0", diff --git a/static/themes/redmond-xx.json b/static/themes/redmond-xx.json index 4fd6a369..cf9010fe 100644 --- a/static/themes/redmond-xx.json +++ b/static/themes/redmond-xx.json @@ -1,7 +1,8 @@ { "_pleroma_theme_version": 2, "name": "Redmond XX", - "theme": { + "source": { + "themeEngineVersion": 3, "shadows": { "panel": [ { @@ -259,6 +260,7 @@ "bg": "#c0c0c0", "text": "#000000", "link": "#0000ff", + "accent": "#000080", "fg": "#c0c0c0", "panel": "#000080", "panelFaint": "#c0c0c0", @@ -266,13 +268,18 @@ "topBar": "#000080", "topBarLink": "#ffffff", "btn": "#c0c0c0", + "btnToggled": "--btn", "faint": "#3f3f3f", "faintLink": "#404080", "border": "#808080", "cRed": "#FF0000", "cBlue": "#008080", "cGreen": "#008000", - "cOrange": "#808000" + "cOrange": "#808000", + "highlight": "--accent", + "selectedPost": "--bg,-10", + "selectedMenu": "--accent", + "selectedMenuPopover": "--accent" }, "radii": { "btn": "0", diff --git a/static/themes/redmond-xxi.json b/static/themes/redmond-xxi.json index d10bf138..7fdc4a6d 100644 --- a/static/themes/redmond-xxi.json +++ b/static/themes/redmond-xxi.json @@ -1,7 +1,8 @@ { "_pleroma_theme_version": 2, "name": "Redmond XXI", - "theme": { + "source": { + "themeEngineVersion": 3, "shadows": { "panel": [ { @@ -241,6 +242,7 @@ "bg": "#d6d6ce", "text": "#000000", "link": "#0000ff", + "accent": "#0a246a", "fg": "#d6d6ce", "panel": "#042967", "panelFaint": "#FFFFFF", @@ -248,13 +250,18 @@ "topBar": "#042967", "topBarLink": "#ffffff", "btn": "#d6d6ce", + "btnToggled": "--btn", "faint": "#3f3f3f", "faintLink": "#404080", "border": "#808080", "cRed": "#c42726", "cBlue": "#6699cc", "cGreen": "#669966", - "cOrange": "#cc6633" + "cOrange": "#cc6633", + "highlight": "--accent", + "selectedPost": "--bg,-10", + "selectedMenu": "--accent", + "selectedMenuPopover": "--accent" }, "radii": { "btn": "0", diff --git a/test/unit/specs/components/emoji_input.spec.js b/test/unit/specs/components/emoji_input.spec.js index b1b98802..045b47fd 100644 --- a/test/unit/specs/components/emoji_input.spec.js +++ b/test/unit/specs/components/emoji_input.spec.js @@ -36,7 +36,8 @@ describe('EmojiInput', () => { input.setValue(initialString) wrapper.setData({ caret: initialString.length }) wrapper.vm.insert({ insertion: '(test)', keepOpen: false }) - expect(wrapper.emitted().input[0][0]).to.eql('Testing (test) ') + const inputEvents = wrapper.emitted().input + expect(inputEvents[inputEvents.length - 1][0]).to.eql('Testing (test) ') }) it('inserts string at the end with trailing space (source has a trailing space)', () => { @@ -46,7 +47,8 @@ describe('EmojiInput', () => { input.setValue(initialString) wrapper.setData({ caret: initialString.length }) wrapper.vm.insert({ insertion: '(test)', keepOpen: false }) - expect(wrapper.emitted().input[0][0]).to.eql('Testing (test) ') + const inputEvents = wrapper.emitted().input + expect(inputEvents[inputEvents.length - 1][0]).to.eql('Testing (test) ') }) it('inserts string at the begginning without leading space', () => { @@ -56,7 +58,8 @@ describe('EmojiInput', () => { input.setValue(initialString) wrapper.setData({ caret: 0 }) wrapper.vm.insert({ insertion: '(test)', keepOpen: false }) - expect(wrapper.emitted().input[0][0]).to.eql('(test) Testing') + const inputEvents = wrapper.emitted().input + expect(inputEvents[inputEvents.length - 1][0]).to.eql('(test) Testing') }) it('inserts string between words without creating extra spaces', () => { @@ -66,7 +69,8 @@ describe('EmojiInput', () => { input.setValue(initialString) wrapper.setData({ caret: 6 }) wrapper.vm.insert({ insertion: ':ebin:', keepOpen: false }) - expect(wrapper.emitted().input[0][0]).to.eql('Spurdo :ebin: Sparde') + const inputEvents = wrapper.emitted().input + expect(inputEvents[inputEvents.length - 1][0]).to.eql('Spurdo :ebin: Sparde') }) it('inserts string between words without creating extra spaces (other caret)', () => { @@ -76,7 +80,8 @@ describe('EmojiInput', () => { input.setValue(initialString) wrapper.setData({ caret: 7 }) wrapper.vm.insert({ insertion: ':ebin:', keepOpen: false }) - expect(wrapper.emitted().input[0][0]).to.eql('Spurdo :ebin: Sparde') + const inputEvents = wrapper.emitted().input + expect(inputEvents[inputEvents.length - 1][0]).to.eql('Spurdo :ebin: Sparde') }) it('inserts string without any padding if padEmoji setting is set to false', () => { @@ -86,7 +91,8 @@ describe('EmojiInput', () => { input.setValue(initialString) wrapper.setData({ caret: initialString.length, keepOpen: false }) wrapper.vm.insert({ insertion: ':spam:' }) - expect(wrapper.emitted().input[0][0]).to.eql('Eat some spam!:spam:') + const inputEvents = wrapper.emitted().input + expect(inputEvents[inputEvents.length - 1][0]).to.eql('Eat some spam!:spam:') }) it('correctly sets caret after insertion at beginning', (done) => { diff --git a/test/unit/specs/components/user_profile.spec.js b/test/unit/specs/components/user_profile.spec.js index 1b6a47d7..dcf066f9 100644 --- a/test/unit/specs/components/user_profile.spec.js +++ b/test/unit/specs/components/user_profile.spec.js @@ -19,6 +19,7 @@ const actions = { const testGetters = { findUser: state => getters.findUser(state.users), + relationship: state => getters.relationship(state.users), mergedConfig: state => ({ colors: '', highlight: {}, @@ -96,7 +97,8 @@ const externalProfileStore = new Vuex.Store({ credentials: '' }, usersObject: { 100: extUser }, - users: [extUser] + users: [extUser], + relationships: {} } } }) @@ -164,7 +166,8 @@ const localProfileStore = new Vuex.Store({ credentials: '' }, usersObject: { 100: localUser, 'testuser': localUser }, - users: [localUser] + users: [localUser], + relationships: {} } } }) diff --git a/test/unit/specs/modules/users.spec.js b/test/unit/specs/modules/users.spec.js index eeb7afef..670acfc8 100644 --- a/test/unit/specs/modules/users.spec.js +++ b/test/unit/specs/modules/users.spec.js @@ -18,20 +18,6 @@ describe('The users module', () => { expect(state.users).to.eql([user]) expect(state.users[0].name).to.eql('Dude') }) - - it('sets a mute bit on users', () => { - const state = cloneDeep(defaultState) - const user = { id: '1', name: 'Guy' } - - mutations.addNewUsers(state, [user]) - mutations.setMuted(state, { user, muted: true }) - - expect(user.muted).to.eql(true) - - mutations.setMuted(state, { user, muted: false }) - - expect(user.muted).to.eql(false) - }) }) describe('findUser', () => { diff --git a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js index cfb380ba..166fce2b 100644 --- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js +++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js @@ -338,9 +338,9 @@ describe('API Entities normalizer', () => { describe('MastoAPI emoji adder', () => { const emojis = makeMockEmojiMasto() - const imageHtml = '' + const imageHtml = '' .replace(/"/g, '\'') - const thinkHtml = '' + const thinkHtml = '' .replace(/"/g, '\'') it('correctly replaces shortcodes in supplied string', () => { @@ -366,8 +366,8 @@ describe('API Entities normalizer', () => { shortcode: '[a-z] {|}*' }]) const result = addEmojis('This post has :c++: emoji and :[a-z] {|}*: emoji', emojis) - expect(result).to.include('title=\'c++\'') - expect(result).to.include('title=\'[a-z] {|}*\'') + expect(result).to.include('title=\':c++:\'') + expect(result).to.include('title=\':[a-z] {|}*:\'') }) }) }) diff --git a/test/unit/specs/services/status_parser/status_parses.spec.js b/test/unit/specs/services/status_parser/status_parses.spec.js deleted file mode 100644 index 7afd5042..00000000 --- a/test/unit/specs/services/status_parser/status_parses.spec.js +++ /dev/null @@ -1,17 +0,0 @@ -import { removeAttachmentLinks } from '../../../../../src/services/status_parser/status_parser.js' - -const example = '' - -describe('statusParser.removeAttachmentLinks', () => { - const exampleWithoutAttachmentLinks = '' - - it('removes attachment links', () => { - const parsed = removeAttachmentLinks(example) - expect(parsed).to.eql(exampleWithoutAttachmentLinks) - }) - - it('works when the class is empty', () => { - const parsed = removeAttachmentLinks('') - expect(parsed).to.eql('') - }) -}) diff --git a/test/unit/specs/services/theme_data/sanity_checks.spec.js b/test/unit/specs/services/theme_data/sanity_checks.spec.js new file mode 100644 index 00000000..f0072e7d --- /dev/null +++ b/test/unit/specs/services/theme_data/sanity_checks.spec.js @@ -0,0 +1,28 @@ +import { getColors } from 'src/services/theme_data/theme_data.service.js' + +const checkColors = (output) => { + expect(output).to.have.property('colors') + Object.entries(output.colors).forEach(([key, v]) => { + expect(v, key).to.be.an('object') + expect(v, key).to.include.all.keys('r', 'g', 'b') + 'rgba'.split('').forEach(k => { + if ((k === 'a' && v.hasOwnProperty('a')) || k !== 'a') { + expect(v[k], key + '.' + k).to.be.a('number') + expect(v[k], key + '.' + k).to.be.least(0) + expect(v[k], key + '.' + k).to.be.most(k === 'a' ? 1 : 255) + } + }) + }) +} + +describe('Theme Data utility functions', () => { + const context = require.context('static/themes/', false, /\.json$/) + context.keys().forEach((key) => { + it(`Should render all colors for ${key} properly`, () => { + const { theme, source } = context(key) + const data = source || theme + const colors = getColors(data.colors, data.opacity, 1) + checkColors(colors) + }) + }) +}) diff --git a/test/unit/specs/services/theme_data/theme_data.spec.js b/test/unit/specs/services/theme_data/theme_data.spec.js new file mode 100644 index 00000000..c634cade --- /dev/null +++ b/test/unit/specs/services/theme_data/theme_data.spec.js @@ -0,0 +1,89 @@ +import { getLayersArray, topoSort } from 'src/services/theme_data/theme_data.service.js' + +describe('Theme Data utility functions', () => { + describe('getLayersArray', () => { + const fixture = { + layer1: null, + layer2: 'layer1', + layer3a: 'layer2', + layer3b: 'layer2' + } + + it('should expand layers properly (3b)', () => { + const out = getLayersArray('layer3b', fixture) + expect(out).to.eql(['layer1', 'layer2', 'layer3b']) + }) + + it('should expand layers properly (3a)', () => { + const out = getLayersArray('layer3a', fixture) + expect(out).to.eql(['layer1', 'layer2', 'layer3a']) + }) + + it('should expand layers properly (2)', () => { + const out = getLayersArray('layer2', fixture) + expect(out).to.eql(['layer1', 'layer2']) + }) + + it('should expand layers properly (1)', () => { + const out = getLayersArray('layer1', fixture) + expect(out).to.eql(['layer1']) + }) + }) + + describe('topoSort', () => { + const fixture1 = { + layerA: [], + layer1A: ['layerA'], + layer2A: ['layer1A'], + layerB: [], + layer1B: ['layerB'], + layer2B: ['layer1B'], + layer3AB: ['layer2B', 'layer2A'] + } + + // Same thing but messed up order + const fixture2 = { + layer1A: ['layerA'], + layer1B: ['layerB'], + layer2A: ['layer1A'], + layerB: [], + layer3AB: ['layer2B', 'layer2A'], + layer2B: ['layer1B'], + layerA: [] + } + + it('should make a topologically sorted array', () => { + const out = topoSort(fixture1, (node, inheritance) => inheritance[node]) + // This basically checks all ordering that matters + expect(out.indexOf('layerA')).to.be.below(out.indexOf('layer1A')) + expect(out.indexOf('layer1A')).to.be.below(out.indexOf('layer2A')) + expect(out.indexOf('layerB')).to.be.below(out.indexOf('layer1B')) + expect(out.indexOf('layer1B')).to.be.below(out.indexOf('layer2B')) + expect(out.indexOf('layer2A')).to.be.below(out.indexOf('layer3AB')) + expect(out.indexOf('layer2B')).to.be.below(out.indexOf('layer3AB')) + }) + + it('order in object shouldn\'t matter', () => { + const out = topoSort(fixture2, (node, inheritance) => inheritance[node]) + // This basically checks all ordering that matters + expect(out.indexOf('layerA')).to.be.below(out.indexOf('layer1A')) + expect(out.indexOf('layer1A')).to.be.below(out.indexOf('layer2A')) + expect(out.indexOf('layerB')).to.be.below(out.indexOf('layer1B')) + expect(out.indexOf('layer1B')).to.be.below(out.indexOf('layer2B')) + expect(out.indexOf('layer2A')).to.be.below(out.indexOf('layer3AB')) + expect(out.indexOf('layer2B')).to.be.below(out.indexOf('layer3AB')) + }) + + it('dependentless nodes should be first', () => { + const out = topoSort(fixture2, (node, inheritance) => inheritance[node]) + // This basically checks all ordering that matters + expect(out.indexOf('layerA')).to.eql(0) + expect(out.indexOf('layerB')).to.eql(1) + }) + + it('ignores cyclic dependencies', () => { + const out = topoSort({ a: 'b', b: 'a', c: 'a' }, (node, inheritance) => [inheritance[node]]) + expect(out.indexOf('a')).to.be.below(out.indexOf('c')) + }) + }) +}) diff --git a/yarn.lock b/yarn.lock index b794042f..f05b00b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1062,7 +1062,7 @@ array-union@^1.0.1: dependencies: array-uniq "^1.0.1" -array-uniq@^1.0.1, array-uniq@^1.0.2: +array-uniq@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" @@ -2327,6 +2327,7 @@ dateformat@^1.0.6: de-indent@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" + integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0= debug@2, debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" @@ -2544,7 +2545,7 @@ domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" -domelementtype@1, domelementtype@^1.3.0: +domelementtype@1: version "1.3.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" @@ -2558,12 +2559,6 @@ domhandler@2.1: dependencies: domelementtype "1" -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - dependencies: - domelementtype "1" - domutils@1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.1.6.tgz#bddc3de099b9a2efacc51c623f28f416ecc57485" @@ -2577,13 +2572,6 @@ domutils@1.5.1: dom-serializer "0" domelementtype "1" -domutils@^1.5.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - dependencies: - dom-serializer "0" - domelementtype "1" - duplexer2@~0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" @@ -2710,7 +2698,7 @@ ent@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" -entities@^1.1.1, entities@~1.1.1: +entities@~1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" @@ -3761,17 +3749,6 @@ html-webpack-plugin@^3.0.0, html-webpack-plugin@^3.2.0: toposort "^1.0.0" util.promisify "1.0.0" -htmlparser2@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464" - dependencies: - domelementtype "^1.3.0" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.0.6" - htmlparser2@~3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.3.0.tgz#cc70d05a59f6542e43f0e685c982e14c924a9efe" @@ -4756,10 +4733,6 @@ lodash.clone@3.0.3: lodash._bindcallback "^3.0.0" lodash._isiterateecall "^3.0.0" -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - lodash.create@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" @@ -4779,10 +4752,6 @@ lodash.defaultsdeep@4.3.2: lodash.mergewith "^4.0.0" lodash.rest "^4.0.0" -lodash.escaperegexp@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" - lodash.find@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-3.2.1.tgz#046e319f3ace912ac6c9246c7f683c5ec07b36ad" @@ -4814,14 +4783,10 @@ lodash.isplainobject@^3.0.0, lodash.isplainobject@^3.2.0: lodash.isarguments "^3.0.0" lodash.keysin "^3.0.0" -lodash.isplainobject@^4.0.0, lodash.isplainobject@^4.0.6: +lodash.isplainobject@^4.0.0: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" -lodash.isstring@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - lodash.istypedarray@^3.0.0: version "3.0.6" resolved "https://registry.yarnpkg.com/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz#c9a477498607501d8e8494d283b87c39281cef62" @@ -4870,7 +4835,7 @@ lodash.merge@^3.3.2: lodash.keysin "^3.0.0" lodash.toplainobject "^3.0.0" -lodash.mergewith@^4.0.0, lodash.mergewith@^4.6.1: +lodash.mergewith@^4.0.0: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" @@ -5537,10 +5502,6 @@ object-keys@^1.0.11, object-keys@^1.0.12: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" -object-path@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" - object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -5941,11 +5902,6 @@ pngjs@^3.3.0: version "3.3.3" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.3.3.tgz#85173703bde3edac8998757b96e5821d0966a21b" -popper.js@^1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.15.0.tgz#5560b99bbad7647e9faa475c6b8056621f5a4ff2" - integrity sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA== - portal-vue@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/portal-vue/-/portal-vue-2.1.4.tgz#1fc679d77e294dc8d026f1eb84aa467de11b392e" @@ -6249,14 +6205,6 @@ postcss@^7.0.0: source-map "^0.6.1" supports-color "^6.1.0" -postcss@^7.0.5: - version "7.0.8" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.8.tgz#2a3c5f2bdd00240cd0d0901fd998347c93d36696" - dependencies: - chalk "^2.4.2" - source-map "^0.6.1" - supports-color "^6.0.0" - prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -6525,14 +6473,6 @@ readable-stream@1.1.x: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^3.0.6: - version "3.1.1" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.1.1.tgz#ed6bbc6c5ba58b090039ff18ce670515795aeb06" - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -6843,21 +6783,6 @@ samsam@1.x, samsam@^1.1.3: version "1.3.0" resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50" -sanitize-html@^1.13.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.20.0.tgz#9a602beb1c9faf960fb31f9890f61911cc4d9156" - dependencies: - chalk "^2.4.1" - htmlparser2 "^3.10.0" - lodash.clonedeep "^4.5.0" - lodash.escaperegexp "^4.1.2" - lodash.isplainobject "^4.0.6" - lodash.isstring "^4.0.1" - lodash.mergewith "^4.6.1" - postcss "^7.0.5" - srcset "^1.0.0" - xtend "^4.0.1" - "sass-loader@git://github.com/webpack-contrib/sass-loader": version "7.1.0" resolved "git://github.com/webpack-contrib/sass-loader#e279f2a129eee0bd0b624b5acd498f23a81ee35e" @@ -7229,13 +7154,6 @@ sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" -srcset@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/srcset/-/srcset-1.0.0.tgz#a5669de12b42f3b1d5e83ed03c71046fc48f41ef" - dependencies: - array-uniq "^1.0.2" - number-is-nan "^1.0.0" - sshpk@^1.7.0: version "1.16.0" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.0.tgz#1d4963a2fbffe58050aa9084ca20be81741c07de" @@ -7335,7 +7253,7 @@ string-width@^3.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string_decoder@^1.0.0, string_decoder@^1.1.1: +string_decoder@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" dependencies: @@ -7419,7 +7337,7 @@ supports-color@^5.3.0, supports-color@^5.4.0: dependencies: has-flag "^3.0.0" -supports-color@^6.0.0, supports-color@^6.1.0: +supports-color@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" dependencies: @@ -7784,7 +7702,7 @@ useragent@2.3.0: lru-cache "4.1.x" tmp "0.0.x" -util-deprecate@^1.0.1, util-deprecate@~1.0.1: +util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -7823,15 +7741,6 @@ v-click-outside@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/v-click-outside/-/v-click-outside-2.1.3.tgz#b7297abe833a439dc0895e6418a494381e64b5e7" -v-tooltip@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/v-tooltip/-/v-tooltip-2.0.2.tgz#8610d9eece2cc44fd66c12ef2f12eec6435cab9b" - integrity sha512-xQ+qzOFfywkLdjHknRPgMMupQNS8yJtf9Utd5Dxiu/0n4HtrxqsgDtN2MLZ0LKbburtSAQgyypuE/snM8bBZhw== - dependencies: - lodash "^4.17.11" - popper.js "^1.15.0" - vue-resize "^0.4.5" - validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -7906,11 +7815,6 @@ vue-loader@^14.0.0: vue-style-loader "^4.0.1" vue-template-es2015-compiler "^1.6.0" -vue-resize@^0.4.5: - version "0.4.5" - resolved "https://registry.yarnpkg.com/vue-resize/-/vue-resize-0.4.5.tgz#4777a23042e3c05620d9cbda01c0b3cc5e32dcea" - integrity sha512-bhP7MlgJQ8TIkZJXAfDf78uJO+mEI3CaLABLjv0WNzr4CcGRGPIAItyWYnP6LsPA4Oq0WE+suidNs6dgpO4RHg== - vue-router@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.2.tgz#dedc67afe6c4e2bc25682c8b1c2a8c0d7c7e56be" @@ -7922,9 +7826,10 @@ vue-style-loader@^4.0.0, vue-style-loader@^4.0.1: hash-sum "^1.0.2" loader-utils "^1.0.2" -vue-template-compiler@^2.3.4: - version "2.5.21" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.21.tgz#a57ceb903177e8f643560a8d639a0f8db647054a" +vue-template-compiler@^2.6.11: + version "2.6.11" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080" + integrity sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA== dependencies: de-indent "^1.0.2" he "^1.1.0" @@ -7933,9 +7838,10 @@ vue-template-es2015-compiler@^1.6.0: version "1.9.1" resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" -vue@^2.5.13: - version "2.5.21" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.21.tgz#3d33dcd03bb813912ce894a8303ab553699c4a85" +vue@^2.6.11: + version "2.6.11" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5" + integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ== vuelidate@^0.7.4: version "0.7.4" @@ -8031,10 +7937,6 @@ webpack@^4.0.0: watchpack "^1.5.0" webpack-sources "^1.3.0" -whatwg-fetch@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" - whet.extend@~0.9.9: version "0.9.9" resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" @@ -8106,7 +8008,7 @@ xregexp@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: +xtend@^4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
@@ -122,6 +126,7 @@
+
diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index 0bb1b2b4..0db03547 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -5,6 +5,8 @@ import App from '../App.vue'
import { windowWidth } from '../services/window_utils/window_utils'
import { getOrCreateApp, getClientToken } from '../services/new_api/oauth.js'
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
+import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js'
+import { applyTheme } from '../services/style_setter/style_setter.js'
const getStatusnetConfig = async ({ store }) => {
try {
@@ -106,9 +108,9 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => {
copyInstanceOption('subjectLineBehavior')
copyInstanceOption('postContentType')
copyInstanceOption('alwaysShowSubjectInput')
- copyInstanceOption('noAttachmentLinks')
copyInstanceOption('showFeaturesPanel')
copyInstanceOption('hideSitename')
+ copyInstanceOption('sidebarRight')
return store.dispatch('setTheme', config['theme'])
}
@@ -221,9 +223,16 @@ const getNodeInfo = async ({ store }) => {
const frontendVersion = window.___pleromafe_commit_hash
store.dispatch('setInstanceOption', { name: 'frontendVersion', value: frontendVersion })
- store.dispatch('setInstanceOption', { name: 'tagPolicyAvailable', value: metadata.federation.mrf_policies.includes('TagPolicy') })
const federation = metadata.federation
+
+ store.dispatch('setInstanceOption', {
+ name: 'tagPolicyAvailable',
+ value: typeof federation.mrf_policies === 'undefined'
+ ? false
+ : metadata.federation.mrf_policies.includes('TagPolicy')
+ })
+
store.dispatch('setInstanceOption', { name: 'federationPolicy', value: federation })
store.dispatch('setInstanceOption', {
name: 'federating',
@@ -232,6 +241,9 @@ const getNodeInfo = async ({ store }) => {
: federation.enabled
})
+ const accountActivationRequired = metadata.accountActivationRequired
+ store.dispatch('setInstanceOption', { name: 'accountActivationRequired', value: accountActivationRequired })
+
const accounts = metadata.staffAccounts
resolveStaffAccounts({ store, accounts })
} else {
@@ -258,7 +270,7 @@ const checkOAuthToken = async ({ store }) => {
try {
await store.dispatch('loginUser', store.getters.getUserToken())
} catch (e) {
- console.log(e)
+ console.error(e)
}
}
resolve()
@@ -266,29 +278,38 @@ const checkOAuthToken = async ({ store }) => {
}
const afterStoreSetup = async ({ store, i18n }) => {
- if (store.state.config.customTheme) {
- // This is a hack to deal with async loading of config.json and themes
- // See: style_setter.js, setPreset()
- window.themeLoaded = true
- store.dispatch('setOption', {
- name: 'customTheme',
- value: store.state.config.customTheme
- })
- }
-
const width = windowWidth()
store.dispatch('setMobileLayout', width <= 800)
+ await setConfig({ store })
+
+ const { customTheme, customThemeSource } = store.state.config
+ const { theme } = store.state.instance
+ const customThemePresent = customThemeSource || customTheme
+
+ if (customThemePresent) {
+ if (customThemeSource && customThemeSource.themeEngineVersion === CURRENT_VERSION) {
+ applyTheme(customThemeSource)
+ } else {
+ applyTheme(customTheme)
+ }
+ } else if (theme) {
+ // do nothing, it will load asynchronously
+ } else {
+ console.error('Failed to load any theme!')
+ }
// Now we can try getting the server settings and logging in
await Promise.all([
checkOAuthToken({ store }),
- setConfig({ store }),
getTOS({ store }),
getInstancePanel({ store }),
getStickers({ store }),
getNodeInfo({ store })
])
+ // Start fetching things that don't need to block the UI
+ store.dispatch('fetchMutes')
+
const router = new VueRouter({
mode: 'history',
routes: routes(store),
diff --git a/src/boot/routes.js b/src/boot/routes.js
index 7400a682..d98a3b50 100644
--- a/src/boot/routes.js
+++ b/src/boot/routes.js
@@ -7,10 +7,8 @@ import Interactions from 'components/interactions/interactions.vue'
import DMs from 'components/dm_timeline/dm_timeline.vue'
import UserProfile from 'components/user_profile/user_profile.vue'
import Search from 'components/search/search.vue'
-import Settings from 'components/settings/settings.vue'
import Registration from 'components/registration/registration.vue'
import PasswordReset from 'components/password_reset/password_reset.vue'
-import UserSettings from 'components/user_settings/user_settings.vue'
import FollowRequests from 'components/follow_requests/follow_requests.vue'
import OAuthCallback from 'components/oauth_callback/oauth_callback.vue'
import Notifications from 'components/notifications/notifications.vue'
@@ -56,12 +54,10 @@ export default (store) => {
{ name: 'external-user-profile', path: '/users/:id', component: UserProfile },
{ name: 'interactions', path: '/users/:username/interactions', component: Interactions, beforeEnter: validateAuthenticatedRoute },
{ name: 'dms', path: '/users/:username/dms', component: DMs, beforeEnter: validateAuthenticatedRoute },
- { name: 'settings', path: '/settings', component: Settings },
{ name: 'registration', path: '/registration', component: Registration },
{ name: 'password-reset', path: '/password-reset', component: PasswordReset, props: true },
{ name: 'registration-token', path: '/registration/:token', component: Registration },
{ name: 'friend-requests', path: '/friend-requests', component: FollowRequests, beforeEnter: validateAuthenticatedRoute },
- { name: 'user-settings', path: '/user-settings', component: UserSettings, beforeEnter: validateAuthenticatedRoute },
{ name: 'notifications', path: '/:username/notifications', component: Notifications, beforeEnter: validateAuthenticatedRoute },
{ name: 'login', path: '/login', component: AuthForm },
{ name: 'chat', path: '/chat', component: ChatPanel, props: () => ({ floating: false }) },
diff --git a/src/components/account_actions/account_actions.js b/src/components/account_actions/account_actions.js
index d2153680..0826c275 100644
--- a/src/components/account_actions/account_actions.js
+++ b/src/components/account_actions/account_actions.js
@@ -1,14 +1,16 @@
import ProgressButton from '../progress_button/progress_button.vue'
+import Popover from '../popover/popover.vue'
const AccountActions = {
props: [
- 'user'
+ 'user', 'relationship'
],
data () {
return { }
},
components: {
- ProgressButton
+ ProgressButton,
+ Popover
},
methods: {
showRepeats () {
diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue
index d3235be1..744b77d5 100644
--- a/src/components/account_actions/account_actions.vue
+++ b/src/components/account_actions/account_actions.vue
@@ -1,24 +1,24 @@
-
-
+
+
-
diff --git a/src/components/block_card/block_card.js b/src/components/block_card/block_card.js
index c459ff1b..0bf4e37b 100644
--- a/src/components/block_card/block_card.js
+++ b/src/components/block_card/block_card.js
@@ -11,8 +11,11 @@ const BlockCard = {
user () {
return this.$store.getters.findUser(this.userId)
},
+ relationship () {
+ return this.$store.getters.relationship(this.userId)
+ },
blocked () {
- return this.user.statusnet_blocking
+ return this.relationship.blocking
}
},
components: {
diff --git a/src/components/checkbox/checkbox.vue b/src/components/checkbox/checkbox.vue
index 1113f81d..03375b2f 100644
--- a/src/components/checkbox/checkbox.vue
+++ b/src/components/checkbox/checkbox.vue
@@ -87,13 +87,13 @@ export default {
&:checked + .checkbox-indicator::before {
color: $fallback--text;
- color: var(--text, $fallback--text);
+ color: var(--inputText, $fallback--text);
}
&:indeterminate + .checkbox-indicator::before {
content: '–';
color: $fallback--text;
- color: var(--text, $fallback--text);
+ color: var(--inputText, $fallback--text);
}
}
diff --git a/src/components/color_input/color_input.scss b/src/components/color_input/color_input.scss
new file mode 100644
index 00000000..8e9923cf
--- /dev/null
+++ b/src/components/color_input/color_input.scss
@@ -0,0 +1,68 @@
+@import '../../_variables.scss';
+
+.color-input {
+ display: inline-flex;
+
+ &-field.input {
+ display: inline-flex;
+ flex: 0 0 0;
+ max-width: 9em;
+ align-items: stretch;
+ padding: .2em 8px;
+
+ input {
+ background: none;
+ color: $fallback--lightText;
+ color: var(--inputText, $fallback--lightText);
+ border: none;
+ padding: 0;
+ margin: 0;
+
+ &.textColor {
+ flex: 1 0 3em;
+ min-width: 3em;
+ padding: 0;
+ }
+
+ &.nativeColor {
+ flex: 0 0 2em;
+ min-width: 2em;
+ align-self: center;
+ height: 100%;
+ }
+ }
+ .computedIndicator,
+ .transparentIndicator {
+ flex: 0 0 2em;
+ min-width: 2em;
+ align-self: center;
+ height: 100%;
+ }
+ .transparentIndicator {
+ // forgot to install counter-strike source, ooops
+ background-color: #FF00FF;
+ position: relative;
+ &::before, &::after {
+ display: block;
+ content: '';
+ background-color: #000000;
+ position: absolute;
+ height: 50%;
+ width: 50%;
+ }
+ &::after {
+ top: 0;
+ left: 0;
+ }
+ &::before {
+ bottom: 0;
+ right: 0;
+ }
+ }
+ }
+
+ .label {
+ flex: 1 1 auto;
+ }
+
+}
diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue
index 9db62e81..8fb16113 100644
--- a/src/components/color_input/color_input.vue
+++ b/src/components/color_input/color_input.vue
@@ -1,6 +1,6 @@
-
-
+
+
-
+
@@ -62,7 +65,6 @@
diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue
index 0748b2f0..a7e217c1 100644
--- a/src/components/attachment/attachment.vue
+++ b/src/components/attachment/attachment.vue
@@ -130,6 +130,8 @@
.placeholder {
margin-right: 8px;
margin-bottom: 4px;
+ color: $fallback--link;
+ color: var(--postLink, $fallback--link);
}
.nsfw-placeholder {
diff --git a/src/components/autosuggest/autosuggest.vue b/src/components/autosuggest/autosuggest.vue
index 1f86e996..f283ab82 100644
--- a/src/components/autosuggest/autosuggest.vue
+++ b/src/components/autosuggest/autosuggest.vue
@@ -40,8 +40,8 @@
top: 100%;
right: 0;
max-height: 400px;
- background-color: $fallback--lightBg;
- background-color: var(--lightBg, $fallback--lightBg);
+ background-color: $fallback--bg;
+ background-color: var(--bg, $fallback--bg);
border-style: solid;
border-width: 1px;
border-color: $fallback--border;
diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue
index 8a02174e..9e410610 100644
--- a/src/components/basic_user_card/basic_user_card.vue
+++ b/src/components/basic_user_card/basic_user_card.vue
@@ -12,7 +12,7 @@
class="basic-user-card-expanded-content"
>
-
-
-
-
+
-
+
@@ -78,6 +82,7 @@
display: flex;
flex-direction: column;
margin-left: 0.5em;
+ min-width: 5em;
img {
width: 1em;
@@ -128,7 +133,7 @@
}
.picked-reaction {
- border: 1px solid var(--link, $fallback--link);
+ border: 1px solid var(--accent, $fallback--link);
margin-left: -1px; // offset the border, can't use inset shadows either
margin-right: calc(0.5em - 1px);
}
diff --git a/src/components/export_import/export_import.vue b/src/components/export_import/export_import.vue
index 20c6f569..ae00487f 100644
--- a/src/components/export_import/export_import.vue
+++ b/src/components/export_import/export_import.vue
@@ -42,7 +42,7 @@ export default {
},
methods: {
exportData () {
- const stringified = JSON.stringify(this.exportObject) // Pretty-print and indent with 2 spaces
+ const stringified = JSON.stringify(this.exportObject, null, 2) // Pretty-print and indent with 2 spaces
// Create an invisible link with a data url and simulate a click
const e = document.createElement('a')
diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js
index 5ac73e97..e4b19d01 100644
--- a/src/components/extra_buttons/extra_buttons.js
+++ b/src/components/extra_buttons/extra_buttons.js
@@ -1,5 +1,8 @@
+import Popover from '../popover/popover.vue'
+
const ExtraButtons = {
props: [ 'status' ],
+ components: { Popover },
methods: {
deleteStatus () {
const confirmed = window.confirm(this.$t('status.delete_confirm'))
@@ -26,6 +29,11 @@ const ExtraButtons = {
this.$store.dispatch('unmuteConversation', this.status.id)
.then(() => this.$emit('onSuccess'))
.catch(err => this.$emit('onError', err.error.error))
+ },
+ copyLink () {
+ navigator.clipboard.writeText(this.statusLink)
+ .then(() => this.$emit('onSuccess'))
+ .catch(err => this.$emit('onError', err.error.error))
}
},
computed: {
@@ -43,6 +51,9 @@ const ExtraButtons = {
},
canMute () {
return !!this.currentUser
+ },
+ statusLink () {
+ return `${this.$store.state.instance.server}${this.$router.resolve({ name: 'conversation', params: { id: this.status.id } }).href}`
}
}
}
diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue
index 746f1c91..bca93ea7 100644
--- a/src/components/extra_buttons/extra_buttons.vue
+++ b/src/components/extra_buttons/extra_buttons.vue
@@ -1,11 +1,13 @@
-
+
+
+
+
+
+
-
@@ -193,6 +248,21 @@
-
-
-
+
+
diff --git a/src/components/poll/poll.vue b/src/components/poll/poll.vue
index db8e33b3..56e91cca 100644
--- a/src/components/poll/poll.vue
+++ b/src/components/poll/poll.vue
@@ -104,8 +104,10 @@
.result-fill {
height: 100%;
position: absolute;
+ color: $fallback--text;
+ color: var(--pollText, $fallback--text);
background-color: $fallback--lightBg;
- background-color: var(--linkBg, $fallback--lightBg);
+ background-color: var(--poll, $fallback--lightBg);
border-radius: $fallback--panelRadius;
border-radius: var(--panelRadius, $fallback--panelRadius);
top: 0;
diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js
new file mode 100644
index 00000000..5881d266
--- /dev/null
+++ b/src/components/popover/popover.js
@@ -0,0 +1,156 @@
+
+const Popover = {
+ name: 'Popover',
+ props: {
+ // Action to trigger popover: either 'hover' or 'click'
+ trigger: String,
+ // Either 'top' or 'bottom'
+ placement: String,
+ // Takes object with properties 'x' and 'y', values of these can be
+ // 'container' for using offsetParent as boundaries for either axis
+ // or 'viewport'
+ boundTo: Object,
+ // Takes a top/bottom/left/right object, how much space to leave
+ // between boundary and popover element
+ margin: Object,
+ // Takes a x/y object and tells how many pixels to offset from
+ // anchor point on either axis
+ offset: Object,
+ // Additional styles you may want for the popover container
+ popoverClass: String
+ },
+ data () {
+ return {
+ hidden: true,
+ styles: { opacity: 0 },
+ oldSize: { width: 0, height: 0 }
+ }
+ },
+ methods: {
+ updateStyles () {
+ if (this.hidden) {
+ this.styles = {
+ opacity: 0
+ }
+ return
+ }
+
+ // Popover will be anchored around this element, trigger ref is the container, so
+ // its children are what are inside the slot. Expect only one slot="trigger".
+ const anchorEl = (this.$refs.trigger && this.$refs.trigger.children[0]) || this.$el
+ const screenBox = anchorEl.getBoundingClientRect()
+ // Screen position of the origin point for popover
+ const origin = { x: screenBox.left + screenBox.width * 0.5, y: screenBox.top }
+ const content = this.$refs.content
+ // Minor optimization, don't call a slow reflow call if we don't have to
+ const parentBounds = this.boundTo &&
+ (this.boundTo.x === 'container' || this.boundTo.y === 'container') &&
+ this.$el.offsetParent.getBoundingClientRect()
+ const margin = this.margin || {}
+
+ // What are the screen bounds for the popover? Viewport vs container
+ // when using viewport, using default margin values to dodge the navbar
+ const xBounds = this.boundTo && this.boundTo.x === 'container' ? {
+ min: parentBounds.left + (margin.left || 0),
+ max: parentBounds.right - (margin.right || 0)
+ } : {
+ min: 0 + (margin.left || 10),
+ max: window.innerWidth - (margin.right || 10)
+ }
+
+ const yBounds = this.boundTo && this.boundTo.y === 'container' ? {
+ min: parentBounds.top + (margin.top || 0),
+ max: parentBounds.bottom - (margin.bottom || 0)
+ } : {
+ min: 0 + (margin.top || 50),
+ max: window.innerHeight - (margin.bottom || 5)
+ }
+
+ let horizOffset = 0
+
+ // If overflowing from left, move it so that it doesn't
+ if ((origin.x - content.offsetWidth * 0.5) < xBounds.min) {
+ horizOffset += -(origin.x - content.offsetWidth * 0.5) + xBounds.min
+ }
+
+ // If overflowing from right, move it so that it doesn't
+ if ((origin.x + horizOffset + content.offsetWidth * 0.5) > xBounds.max) {
+ horizOffset -= (origin.x + horizOffset + content.offsetWidth * 0.5) - xBounds.max
+ }
+
+ // Default to whatever user wished with placement prop
+ let usingTop = this.placement !== 'bottom'
+
+ // Handle special cases, first force to displaying on top if there's not space on bottom,
+ // regardless of what placement value was. Then check if there's not space on top, and
+ // force to bottom, again regardless of what placement value was.
+ if (origin.y + content.offsetHeight > yBounds.max) usingTop = true
+ if (origin.y - content.offsetHeight < yBounds.min) usingTop = false
+
+ const yOffset = (this.offset && this.offset.y) || 0
+ const translateY = usingTop
+ ? -anchorEl.offsetHeight - yOffset - content.offsetHeight
+ : yOffset
+
+ const xOffset = (this.offset && this.offset.x) || 0
+ const translateX = (anchorEl.offsetWidth * 0.5) - content.offsetWidth * 0.5 + horizOffset + xOffset
+
+ // Note, separate translateX and translateY avoids blurry text on chromium,
+ // single translate or translate3d resulted in blurry text.
+ this.styles = {
+ opacity: 1,
+ transform: `translateX(${Math.floor(translateX)}px) translateY(${Math.floor(translateY)}px)`
+ }
+ },
+ showPopover () {
+ if (this.hidden) this.$emit('show')
+ this.hidden = false
+ this.$nextTick(this.updateStyles)
+ },
+ hidePopover () {
+ if (!this.hidden) this.$emit('close')
+ this.hidden = true
+ this.styles = { opacity: 0 }
+ },
+ onMouseenter (e) {
+ if (this.trigger === 'hover') this.showPopover()
+ },
+ onMouseleave (e) {
+ if (this.trigger === 'hover') this.hidePopover()
+ },
+ onClick (e) {
+ if (this.trigger === 'click') {
+ if (this.hidden) {
+ this.showPopover()
+ } else {
+ this.hidePopover()
+ }
+ }
+ },
+ onClickOutside (e) {
+ if (this.hidden) return
+ if (this.$el.contains(e.target)) return
+ this.hidePopover()
+ }
+ },
+ updated () {
+ // Monitor changes to content size, update styles only when content sizes have changed,
+ // that should be the only time we need to move the popover box if we don't care about scroll
+ // or resize
+ const content = this.$refs.content
+ if (!content) return
+ if (this.oldSize.width !== content.offsetWidth || this.oldSize.height !== content.offsetHeight) {
+ this.updateStyles()
+ this.oldSize = { width: content.offsetWidth, height: content.offsetHeight }
+ }
+ },
+ created () {
+ document.addEventListener('click', this.onClickOutside)
+ },
+ destroyed () {
+ document.removeEventListener('click', this.onClickOutside)
+ this.hidePopover()
+ }
+}
+
+export default Popover
diff --git a/src/components/popover/popover.vue b/src/components/popover/popover.vue
new file mode 100644
index 00000000..a271cb1b
--- /dev/null
+++ b/src/components/popover/popover.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/popper/popper.scss b/src/components/popper/popper.scss
deleted file mode 100644
index 06daa871..00000000
--- a/src/components/popper/popper.scss
+++ /dev/null
@@ -1,147 +0,0 @@
-@import '../../_variables.scss';
-
-.tooltip.popover {
- z-index: 8;
-
- .popover-inner {
- box-shadow: 1px 1px 4px rgba(0,0,0,.6);
- box-shadow: var(--panelShadow);
- border-radius: $fallback--btnRadius;
- border-radius: var(--btnRadius, $fallback--btnRadius);
- background-color: $fallback--bg;
- background-color: var(--bg, $fallback--bg);
- }
-
- .popover-arrow {
- width: 0;
- height: 0;
- border-style: solid;
- position: absolute;
- margin: 5px;
- border-color: $fallback--bg;
- border-color: var(--bg, $fallback--bg);
- }
-
- &[x-placement^="top"] {
- margin-bottom: 5px;
-
- .popover-arrow {
- border-width: 5px 5px 0 5px;
- border-left-color: transparent !important;
- border-right-color: transparent !important;
- border-bottom-color: transparent !important;
- bottom: -4px;
- left: calc(50% - 5px);
- margin-top: 0;
- margin-bottom: 0;
- }
- }
-
- &[x-placement^="bottom"] {
- margin-top: 5px;
-
- .popover-arrow {
- border-width: 0 5px 5px 5px;
- border-left-color: transparent !important;
- border-right-color: transparent !important;
- border-top-color: transparent !important;
- top: -4px;
- left: calc(50% - 5px);
- margin-top: 0;
- margin-bottom: 0;
- }
- }
-
- &[x-placement^="right"] {
- margin-left: 5px;
-
- .popover-arrow {
- border-width: 5px 5px 5px 0;
- border-left-color: transparent !important;
- border-top-color: transparent !important;
- border-bottom-color: transparent !important;
- left: -4px;
- top: calc(50% - 5px);
- margin-left: 0;
- margin-right: 0;
- }
- }
-
- &[x-placement^="left"] {
- margin-right: 5px;
-
- .popover-arrow {
- border-width: 5px 0 5px 5px;
- border-top-color: transparent !important;
- border-right-color: transparent !important;
- border-bottom-color: transparent !important;
- right: -4px;
- top: calc(50% - 5px);
- margin-left: 0;
- margin-right: 0;
- }
- }
-
- &[aria-hidden='true'] {
- visibility: hidden;
- opacity: 0;
- transition: opacity .15s, visibility .15s;
- }
-
- &[aria-hidden='false'] {
- visibility: visible;
- opacity: 1;
- transition: opacity .15s;
- }
-}
-
-.dropdown-menu {
- display: block;
- padding: .5rem 0;
- font-size: 1rem;
- text-align: left;
- list-style: none;
- max-width: 100vw;
- z-index: 10;
-
- .dropdown-divider {
- height: 0;
- margin: .5rem 0;
- overflow: hidden;
- border-top: 1px solid $fallback--border;
- border-top: 1px solid var(--border, $fallback--border);
- }
-
- .dropdown-item {
- line-height: 21px;
- margin-right: 5px;
- overflow: auto;
- display: block;
- padding: .25rem 1.0rem .25rem 1.5rem;
- clear: both;
- font-weight: 400;
- text-align: inherit;
- white-space: normal;
- border: none;
- border-radius: 0px;
- background-color: transparent;
- box-shadow: none;
- width: 100%;
- height: 100%;
-
- &-icon {
- padding-left: 0.5rem;
-
- i {
- margin-right: 0.25rem;
- }
- }
-
- &:hover {
- // TODO: improve the look on breeze themes
- background-color: $fallback--fg;
- background-color: var(--btn, $fallback--fg);
- box-shadow: none;
- }
- }
-}
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index 74067fef..9027566f 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -82,7 +82,9 @@ const PostStatusForm = {
contentType
},
caret: 0,
- pollFormVisible: false
+ pollFormVisible: false,
+ showDropIcon: 'hide',
+ dropStopTimeout: null
}
},
computed: {
@@ -102,7 +104,7 @@ const PostStatusForm = {
...this.$store.state.instance.customEmoji
],
users: this.$store.state.users.users,
- updateUsersList: (input) => this.$store.dispatch('searchUsers', input)
+ updateUsersList: (query) => this.$store.dispatch('searchUsers', { query })
})
},
emojiSuggestor () {
@@ -218,7 +220,6 @@ const PostStatusForm = {
},
addMediaFile (fileInfo) {
this.newStatus.files.push(fileInfo)
- this.enableSubmit()
},
removeMediaFile (fileInfo) {
let index = this.newStatus.files.indexOf(fileInfo)
@@ -227,7 +228,6 @@ const PostStatusForm = {
uploadFailed (errString, templateArgs) {
templateArgs = templateArgs || {}
this.error = this.$t('upload.error.base') + ' ' + this.$t('upload.error.' + errString, templateArgs)
- this.enableSubmit()
},
disableSubmit () {
this.submitDisabled = true
@@ -250,13 +250,27 @@ const PostStatusForm = {
}
},
fileDrop (e) {
- if (e.dataTransfer.files.length > 0) {
+ if (e.dataTransfer && e.dataTransfer.types.includes('Files')) {
e.preventDefault() // allow dropping text like before
this.dropFiles = e.dataTransfer.files
+ clearTimeout(this.dropStopTimeout)
+ this.showDropIcon = 'hide'
}
},
+ fileDragStop (e) {
+ // The false-setting is done with delay because just using leave-events
+ // directly caused unwanted flickering, this is not perfect either but
+ // much less noticable.
+ clearTimeout(this.dropStopTimeout)
+ this.showDropIcon = 'fade'
+ this.dropStopTimeout = setTimeout(() => (this.showDropIcon = 'hide'), 500)
+ },
fileDrag (e) {
e.dataTransfer.dropEffect = 'copy'
+ if (e.dataTransfer && e.dataTransfer.types.includes('Files')) {
+ clearTimeout(this.dropStopTimeout)
+ this.showDropIcon = 'show'
+ }
},
onEmojiInputInput (e) {
this.$nextTick(() => {
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 9789a481..e3d8d087 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -6,7 +6,15 @@
+
+
+
+
+
+
+
+
+
+
-
+
+
-
+
+
+
+
+
+
{{ $t('settings.style.advanced_colors.post') }}
+{{ $t('settings.style.advanced_colors.alert') }}
{{ $t('settings.style.advanced_colors.badge') }}
@@ -217,19 +326,30 @@ :label="$t('settings.style.advanced_colors.badge_notification')" :fallback="previewTheme.colors.badgeNotification" /> +{{ $t('settings.style.advanced_colors.panel_header') }}
@@ -257,7 +377,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('settings.style.advanced_colors.pressed') }}
+{{ $t('settings.style.advanced_colors.disabled') }}
+{{ $t('settings.style.advanced_colors.toggled') }}
+
+
+
+
+
+
{{ $t('settings.style.advanced_colors.tabs') }}
+{{ $t('settings.style.advanced_colors.borders') }}
@@ -328,7 +568,8 @@
@@ -336,7 +577,7 @@
+
+
+
+
+ {{ $t('settings.style.advanced_colors.underlay') }}
+
+
+
+
+ {{ $t('settings.style.advanced_colors.poll') }}
+
+
+
+ {{ $t('settings.style.advanced_colors.icons') }}
+
+
+
+
+
+
+
+ {{ $t('settings.style.advanced_colors.highlight') }}
+
+
+
+
+
+
+
+
+ {{ $t('settings.style.advanced_colors.popover') }}
+
+
+
+
+
+
+
+ {{ $t('settings.style.advanced_colors.selectedPost') }}
+
+
+
+
+
+
+
{{ $t('settings.style.advanced_colors.selectedMenu') }}
+
+
+
+
+
diff --git a/src/components/status_popover/status_popover.js b/src/components/status_popover/status_popover.js
index 19f16bd9..159132a9 100644
--- a/src/components/status_popover/status_popover.js
+++ b/src/components/status_popover/status_popover.js
@@ -7,11 +7,7 @@ const StatusPopover = {
],
data () {
return {
- popperOptions: {
- modifiers: {
- preventOverflow: { padding: { top: 50 }, boundariesElement: 'viewport' }
- }
- }
+ error: false
}
},
computed: {
@@ -20,12 +16,15 @@ const StatusPopover = {
}
},
components: {
- Status: () => import('../status/status.vue')
+ Status: () => import('../status/status.vue'),
+ Popover: () => import('../popover/popover.vue')
},
methods: {
enter () {
if (!this.status) {
this.$store.dispatch('fetchStatus', this.statusId)
+ .then(data => (this.error = false))
+ .catch(e => (this.error = true))
}
}
}
diff --git a/src/components/status_popover/status_popover.vue b/src/components/status_popover/status_popover.vue
index eacf4c06..f5948207 100644
--- a/src/components/status_popover/status_popover.vue
+++ b/src/components/status_popover/status_popover.vue
@@ -1,27 +1,36 @@
-
+
+ -
+
-
+
{{ $t('settings.version.backend_version') }}
+-
+
- + {{ backendVersion }} + +
+ -
+
{{ $t('settings.version.frontend_version') }}
+-
+
- + {{ frontendVersion }} + +
+
+ {{ $t('status.status_unavailable') }}
+
Terms of Service
-This is a placeholder ToS.
+This is the default placeholder ToS. You should copy it over to your static folder and edit it to fit the needs of your instance.
-Edit "/static/terms-of-service.html"
to make it fit the needs of your instance.
To do so, place a file at "/instance/static/terms-of-service.html"
in your
+ Pleroma install containing the real ToS for your instance.
See the Pleroma documentation for more information.
- + diff --git a/static/themes/breezy-dark.json b/static/themes/breezy-dark.json index 6119bf88..76b962c5 100644 --- a/static/themes/breezy-dark.json +++ b/static/themes/breezy-dark.json @@ -1,7 +1,9 @@ { "_pleroma_theme_version": 2, "name": "Breezy Dark (beta)", - "theme": { + "source": { + "themeEngineVersion": 3, + "fonts": {}, "shadows": { "panel": [ { @@ -19,7 +21,7 @@ "y": "0", "blur": "0", "spread": "1", - "color": "#ffffff", + "color": "--btn,900", "alpha": "0.15", "inset": true }, @@ -40,7 +42,7 @@ "blur": "40", "spread": "-40", "inset": true, - "color": "#ffffff", + "color": "--panel,900", "alpha": "0.1" } ], @@ -50,8 +52,8 @@ "y": "0", "blur": 0, "spread": "1", - "color": "--link", - "alpha": "0.3", + "color": "--accent", + "alpha": "1", "inset": true }, { @@ -65,21 +67,12 @@ } ], "buttonPressed": [ - { - "x": 0, - "y": 0, - "blur": "0", - "spread": "50", - "color": "--faint", - "alpha": 1, - "inset": true - }, { "x": 0, "y": "0", "blur": 0, "spread": "1", - "color": "#ffffff", + "color": "--btn,900", "alpha": 0.2, "inset": true }, @@ -99,31 +92,30 @@ "y": "0", "blur": 0, "spread": "1", - "color": "#FFFFFF", + "color": "--input,900", "alpha": "0.2", "inset": true } ] }, - "fonts": {}, - "opacity": { - "input": "1", - "panel": "0" - }, + "opacity": {}, "colors": { "bg": "#31363b", "text": "#eff0f1", "link": "#3daee9", "fg": "#31363b", - "panel": "#31363b", - "input": "#232629", - "topBarLink": "#eff0f1", - "btn": "#31363b", + "panel": "transparent", + "input": "--bg,-6.47", + "topBarLink": "--topBarText", + "btn": "--bg", "border": "#4c545b", "cRed": "#da4453", "cBlue": "#3daee9", "cGreen": "#27ae60", - "cOrange": "#f67400" + "cOrange": "#f67400", + "btnPressed": "--accent", + "selectedMenu": "--accent", + "selectedMenuPopover": "--accent" }, "radii": { "btn": "2", diff --git a/static/themes/breezy-light.json b/static/themes/breezy-light.json index becf704f..0968fff0 100644 --- a/static/themes/breezy-light.json +++ b/static/themes/breezy-light.json @@ -1,7 +1,9 @@ { "_pleroma_theme_version": 2, "name": "Breezy Light (beta)", - "theme": { + "source": { + "themeEngineVersion": 3, + "fonts": {}, "shadows": { "panel": [ { @@ -19,7 +21,7 @@ "y": "0", "blur": "0", "spread": "1", - "color": "#000000", + "color": "--btn,900", "alpha": "0.3", "inset": true }, @@ -40,7 +42,7 @@ "blur": "40", "spread": "-40", "inset": true, - "color": "#ffffff", + "color": "--panel,900", "alpha": "0.1" } ], @@ -50,8 +52,8 @@ "y": "0", "blur": 0, "spread": "1", - "color": "--link", - "alpha": "0.3", + "color": "--accent", + "alpha": "1", "inset": true }, { @@ -65,21 +67,12 @@ } ], "buttonPressed": [ - { - "x": 0, - "y": 0, - "blur": "0", - "spread": "50", - "color": "--faint", - "alpha": 1, - "inset": true - }, { "x": 0, "y": "0", "blur": 0, "spread": "1", - "color": "#ffffff", + "color": "--btn,900", "alpha": 0.2, "inset": true }, @@ -99,31 +92,30 @@ "y": "0", "blur": 0, "spread": "1", - "color": "#000000", + "color": "--input,900", "alpha": "0.2", "inset": true } ] }, - "fonts": {}, "opacity": { "input": "1" }, "colors": { "bg": "#eff0f1", "text": "#232627", - "link": "#2980b9", - "fg": "#bcc2c7", - "panel": "#475057", - "panelText": "#fcfcfc", - "input": "#fcfcfc", - "topBar": "#475057", - "topBarLink": "#eff0f1", - "btn": "#eff0f1", + "fg": "#475057", + "accent": "#2980b9", + "input": "--bg,-6.47", + "topBarLink": "--topBarText", + "btn": "--bg", "cRed": "#da4453", "cBlue": "#2980b9", "cGreen": "#27ae60", - "cOrange": "#f67400" + "cOrange": "#f67400", + "btnPressed": "--accent", + "selectedMenu": "--accent", + "selectedMenuPopover": "--accent" }, "radii": { "btn": "2", diff --git a/static/themes/paper.json b/static/themes/paper.json new file mode 100644 index 00000000..a3b90a0a --- /dev/null +++ b/static/themes/paper.json @@ -0,0 +1,172 @@ +{ + "_pleroma_theme_version": 2, + "name": "Paper", + "source": { + "themeEngineVersion": 3, + "fonts": {}, + "shadows": { + "panel": [ + { + "x": "0", + "y": "2", + "blur": "9", + "spread": 0, + "inset": false, + "color": "#668bb2", + "alpha": "0.1" + }, + { + "x": "0", + "y": "1", + "blur": "2", + "spread": "-1", + "inset": false, + "color": "#668bb2", + "alpha": "0.1" + } + ], + "topBar": [ + { + "x": 0, + "y": "3", + "blur": "8", + "spread": 0, + "inset": false, + "color": "#3e618e", + "alpha": "0.1" + }, + { + "x": 0, + "y": "1", + "blur": "4", + "spread": 0, + "inset": false, + "color": "#3e618e", + "alpha": "0.1" + } + ], + "button": [ + { + "x": 0, + "y": "2", + "blur": "5", + "spread": 0, + "color": "#463f78", + "alpha": "0.1", + "inset": false + } + ], + "input": [ + { + "x": 0, + "y": "1", + "blur": "2", + "spread": 0, + "inset": true, + "color": "#6277b7", + "alpha": "0.1" + } + ], + "buttonHover": [ + { + "x": 0, + "y": "2", + "blur": "5", + "spread": 0, + "color": "#494949", + "alpha": "0.1" + }, + { + "x": 0, + "y": "2", + "blur": "0", + "spread": "20", + "color": "#ffffff", + "alpha": "1", + "inset": true + } + ], + "buttonPressed": [ + { + "x": 0, + "y": 0, + "blur": "4", + "spread": "0", + "color": "#494949", + "alpha": "0.8", + "inset": false + } + ], + "avatarStatus": [ + { + "x": "0", + "y": "2", + "blur": "4", + "spread": "0", + "inset": false, + "color": "#3e618e", + "alpha": "0.1" + } + ], + "avatar": [ + { + "x": 0, + "y": "2", + "blur": "5", + "spread": "0", + "color": "#3e618e", + "alpha": "0.9" + } + ], + "popup": [ + { + "x": "0", + "y": "3", + "blur": "11", + "spread": 0, + "color": "#668bb2", + "alpha": "0.2" + }, + { + "x": "0", + "y": "2", + "blur": "3", + "spread": "-1", + "color": "#668bb2", + "alpha": "0.2" + } + ] + }, + "opacity": { + "underlay": "1", + "border": "0" + }, + "colors": { + "bg": "#ffffff", + "fg": "#f6f6f6", + "text": "#494949", + "underlay": "#ffffff", + "link": "#788ca1", + "accent": "#97a0aa", + "cBlue": "#788ca1", + "cRed": "#eed7ce", + "cGreen": "#788ca1", + "cOrange": "#788ca1", + "postLink": "#788ca1", + "border": "#ffffff", + "icon": "#b6c9c4", + "panel": "#ffffff", + "topBarText": "#4b4b4b" + }, + "radii": { + "btn": "0", + "input": "0", + "checkbox": "0", + "panel": "0", + "avatar": "2", + "avatarAlt": "2", + "tooltip": "0", + "attachment": "0" + } + } +} diff --git a/static/themes/pleroma-dark.json b/static/themes/pleroma-dark.json new file mode 100644 index 00000000..2703fba1 --- /dev/null +++ b/static/themes/pleroma-dark.json @@ -0,0 +1,191 @@ +{ + "_pleroma_theme_version": 2, + "name": "Pleroma Dark", + "source": { + "themeEngineVersion": 3, + "fonts": {}, + "shadows": { + "buttonHover": [ + { + "x": 0, + "y": 0, + "blur": "1", + "spread": "2", + "color": "#b9b9ba", + "alpha": "0.4", + "inset": true + }, + { + "x": 0, + "y": 1, + "blur": 0, + "spread": 0, + "color": "#FFFFFF", + "alpha": 0.2, + "inset": true + }, + { + "x": 0, + "y": -1, + "blur": 0, + "spread": 0, + "color": "#000000", + "alpha": 0.2, + "inset": true + } + ], + "buttonPressed": [ + { + "x": 0, + "y": 0, + "blur": 4, + "spread": 0, + "color": "#000000", + "alpha": 1, + "inset": true + }, + { + "x": 0, + "y": 1, + "blur": 0, + "spread": 0, + "color": "#000000", + "alpha": 0.2, + "inset": true + }, + { + "x": 0, + "y": -1, + "blur": 0, + "spread": 0, + "color": "#FFFFFF", + "alpha": 0.2, + "inset": true + }, + { + "x": 0, + "y": 0, + "blur": "2", + "spread": 0, + "inset": false, + "color": "#000000", + "alpha": 1 + } + ], + "panelHeader": [ + { + "x": 0, + "y": "1", + "blur": "3", + "spread": 0, + "inset": false, + "color": "#000000", + "alpha": "0.4" + }, + { + "x": "0", + "y": "1", + "blur": "0", + "spread": 0, + "inset": true, + "color": "#ffffff", + "alpha": "0.2" + } + ], + "panel": [ + { + "x": "0", + "y": "0", + "blur": "3", + "spread": 0, + "color": "#000000", + "alpha": "0.5" + }, + { + "x": "0", + "y": "4", + "blur": "6", + "spread": "3", + "inset": false, + "color": "#000000", + "alpha": "0.3" + } + ], + "button": [ + { + "x": 0, + "y": 0, + "blur": 2, + "spread": 0, + "color": "#000000", + "alpha": 1 + }, + { + "x": 0, + "y": 1, + "blur": 0, + "spread": 0, + "color": "#FFFFFF", + "alpha": 0.2, + "inset": true + }, + { + "x": 0, + "y": -1, + "blur": 0, + "spread": 0, + "color": "#000000", + "alpha": 0.2, + "inset": true + } + ], + "topBar": [ + { + "x": 0, + "y": "1", + "blur": 4, + "spread": 0, + "color": "#000000", + "alpha": "0.4" + }, + { + "x": 0, + "y": "2", + "blur": "7", + "spread": 0, + "inset": false, + "color": "#000000", + "alpha": "0.3" + } + ] + }, + "opacity": { + "underlay": "0.6" + }, + "colors": { + "bg": "#0f161e", + "fg": "#151e2b", + "text": "#b9b9ba", + "underlay": "#090e14", + "accent": "#e2b188", + "cBlue": "#81beea", + "cRed": "#d31014", + "cGreen": "#5dc94a", + "cOrange": "#ffc459", + "border": "--fg,3", + "topBarText": "--text,-9.75", + "topBarLink": "--topBarText", + "btnToggled": "--accent,-24.2", + "alertErrorText": "--text,21.2", + "badgeNotification": "#e15932", + "badgeNotificationText": "#ffffff" + }, + "radii": { + "btn": "3", + "input": "3", + "panel": "3", + "avatar": "3", + "attachment": "3" + } + } +} diff --git a/static/themes/pleroma-light.json b/static/themes/pleroma-light.json new file mode 100644 index 00000000..05fc300a --- /dev/null +++ b/static/themes/pleroma-light.json @@ -0,0 +1,219 @@ +{ + "_pleroma_theme_version": 2, + "name": "Pleroma Light", + "source": { + "themeEngineVersion": 3, + "fonts": {}, + "shadows": { + "button": [ + { + "x": 0, + "y": 0, + "blur": 2, + "spread": 0, + "color": "#000000", + "alpha": "0.2" + }, + { + "x": 0, + "y": 1, + "blur": 0, + "spread": 0, + "color": "#FFFFFF", + "alpha": "0.5", + "inset": true + }, + { + "x": 0, + "y": -1, + "blur": 0, + "spread": 0, + "color": "#000000", + "alpha": 0.2, + "inset": true + } + ], + "buttonHover": [ + { + "x": 0, + "y": 0, + "blur": "2", + "spread": 0, + "color": "#000000", + "alpha": "0.2" + }, + { + "x": 0, + "y": "0", + "blur": "1", + "spread": "2", + "color": "#ffc39f", + "alpha": "1", + "inset": true + }, + { + "x": 0, + "y": -1, + "blur": 0, + "spread": 0, + "color": "#000000", + "alpha": 0.2, + "inset": true + } + ], + "input": [ + { + "x": 0, + "y": 1, + "blur": 0, + "spread": 0, + "color": "#000000", + "alpha": 0.2, + "inset": true + }, + { + "x": 0, + "y": -1, + "blur": 0, + "spread": 0, + "color": "#FFFFFF", + "alpha": 0.2, + "inset": true + }, + { + "x": 0, + "y": 0, + "blur": "2", + "inset": true, + "spread": 0, + "color": "#000000", + "alpha": "0.15" + } + ], + "panel": [ + { + "x": "0", + "y": 1, + "blur": "3", + "spread": 0, + "color": "#000000", + "alpha": "0.5" + }, + { + "x": "0", + "y": "3", + "blur": "6", + "spread": "1", + "inset": false, + "color": "#000000", + "alpha": "0.2" + } + ], + "panelHeader": [ + { + "x": 0, + "y": "1", + "blur": 0, + "spread": 0, + "inset": true, + "color": "#ffffff", + "alpha": "0.5" + }, + { + "x": 0, + "y": "1", + "blur": "3", + "spread": 0, + "inset": false, + "color": "#000000", + "alpha": "0.3" + } + ], + "buttonPressed": [ + { + "x": 0, + "y": 0, + "blur": 4, + "spread": 0, + "color": "#000000", + "alpha": "0.2" + }, + { + "x": 0, + "y": 1, + "blur": "1", + "spread": "2", + "color": "#000000", + "alpha": "0.3", + "inset": true + }, + { + "x": 0, + "y": -1, + "blur": 0, + "spread": 0, + "color": "#FFFFFF", + "alpha": 0.2, + "inset": true + } + ], + "popup": [ + { + "x": "1", + "y": "2", + "blur": "2", + "spread": 0, + "color": "#000000", + "alpha": "0.2" + }, + { + "x": "1", + "y": "3", + "blur": "7", + "spread": "0", + "inset": false, + "color": "#000000", + "alpha": "0.2" + } + ], + "avatarStatus": [ + { + "x": 0, + "y": "1", + "blur": "4", + "spread": "0", + "inset": false, + "color": "#000000", + "alpha": "0.2" + } + ] + }, + "opacity": { + "underlay": "0.4" + }, + "colors": { + "bg": "#f2f6f9", + "fg": "#d6dfed", + "text": "#304055", + "underlay": "#5d6086", + "accent": "#f55b1b", + "cBlue": "#0095ff", + "cRed": "#d31014", + "cGreen": "#0fa00f", + "cOrange": "#ffa500", + "border": "#d8e6f9", + "topBarText": "#304055", + "topBarLink": "--topBarText", + "btnToggled": "--accent,-24.2", + "input": "#dee3ed", + "badgeNotification": "#e83802" + }, + "radii": { + "btn": "3", + "input": "3", + "panel": "3", + "avatar": "3", + "attachment": "3" + } + } +} diff --git a/static/themes/redmond-xx-se.json b/static/themes/redmond-xx-se.json index 70ee89d1..24480d2c 100644 --- a/static/themes/redmond-xx-se.json +++ b/static/themes/redmond-xx-se.json @@ -1,7 +1,8 @@ { "_pleroma_theme_version": 2, "name": "Redmond XX SE", - "theme": { + "source": { + "themeEngineVersion": 3, "shadows": { "panel": [ { @@ -268,6 +269,7 @@ "bg": "#c0c0c0", "text": "#000000", "link": "#0000ff", + "accent": "#000080", "fg": "#c0c0c0", "panel": "#000080", "panelFaint": "#c0c0c0", @@ -275,13 +277,18 @@ "topBar": "#000080", "topBarLink": "#ffffff", "btn": "#c0c0c0", + "btnToggled": "--btn", "faint": "#3f3f3f", "faintLink": "#404080", "border": "#808080", "cRed": "#FF0000", "cBlue": "#008080", "cGreen": "#008000", - "cOrange": "#808000" + "cOrange": "#808000", + "highlight": "--accent", + "selectedPost": "--bg,-10", + "selectedMenu": "--accent", + "selectedMenuPopover": "--accent" }, "radii": { "btn": "0", diff --git a/static/themes/redmond-xx.json b/static/themes/redmond-xx.json index 4fd6a369..cf9010fe 100644 --- a/static/themes/redmond-xx.json +++ b/static/themes/redmond-xx.json @@ -1,7 +1,8 @@ { "_pleroma_theme_version": 2, "name": "Redmond XX", - "theme": { + "source": { + "themeEngineVersion": 3, "shadows": { "panel": [ { @@ -259,6 +260,7 @@ "bg": "#c0c0c0", "text": "#000000", "link": "#0000ff", + "accent": "#000080", "fg": "#c0c0c0", "panel": "#000080", "panelFaint": "#c0c0c0", @@ -266,13 +268,18 @@ "topBar": "#000080", "topBarLink": "#ffffff", "btn": "#c0c0c0", + "btnToggled": "--btn", "faint": "#3f3f3f", "faintLink": "#404080", "border": "#808080", "cRed": "#FF0000", "cBlue": "#008080", "cGreen": "#008000", - "cOrange": "#808000" + "cOrange": "#808000", + "highlight": "--accent", + "selectedPost": "--bg,-10", + "selectedMenu": "--accent", + "selectedMenuPopover": "--accent" }, "radii": { "btn": "0", diff --git a/static/themes/redmond-xxi.json b/static/themes/redmond-xxi.json index d10bf138..7fdc4a6d 100644 --- a/static/themes/redmond-xxi.json +++ b/static/themes/redmond-xxi.json @@ -1,7 +1,8 @@ { "_pleroma_theme_version": 2, "name": "Redmond XXI", - "theme": { + "source": { + "themeEngineVersion": 3, "shadows": { "panel": [ { @@ -241,6 +242,7 @@ "bg": "#d6d6ce", "text": "#000000", "link": "#0000ff", + "accent": "#0a246a", "fg": "#d6d6ce", "panel": "#042967", "panelFaint": "#FFFFFF", @@ -248,13 +250,18 @@ "topBar": "#042967", "topBarLink": "#ffffff", "btn": "#d6d6ce", + "btnToggled": "--btn", "faint": "#3f3f3f", "faintLink": "#404080", "border": "#808080", "cRed": "#c42726", "cBlue": "#6699cc", "cGreen": "#669966", - "cOrange": "#cc6633" + "cOrange": "#cc6633", + "highlight": "--accent", + "selectedPost": "--bg,-10", + "selectedMenu": "--accent", + "selectedMenuPopover": "--accent" }, "radii": { "btn": "0", diff --git a/test/unit/specs/components/emoji_input.spec.js b/test/unit/specs/components/emoji_input.spec.js index b1b98802..045b47fd 100644 --- a/test/unit/specs/components/emoji_input.spec.js +++ b/test/unit/specs/components/emoji_input.spec.js @@ -36,7 +36,8 @@ describe('EmojiInput', () => { input.setValue(initialString) wrapper.setData({ caret: initialString.length }) wrapper.vm.insert({ insertion: '(test)', keepOpen: false }) - expect(wrapper.emitted().input[0][0]).to.eql('Testing (test) ') + const inputEvents = wrapper.emitted().input + expect(inputEvents[inputEvents.length - 1][0]).to.eql('Testing (test) ') }) it('inserts string at the end with trailing space (source has a trailing space)', () => { @@ -46,7 +47,8 @@ describe('EmojiInput', () => { input.setValue(initialString) wrapper.setData({ caret: initialString.length }) wrapper.vm.insert({ insertion: '(test)', keepOpen: false }) - expect(wrapper.emitted().input[0][0]).to.eql('Testing (test) ') + const inputEvents = wrapper.emitted().input + expect(inputEvents[inputEvents.length - 1][0]).to.eql('Testing (test) ') }) it('inserts string at the begginning without leading space', () => { @@ -56,7 +58,8 @@ describe('EmojiInput', () => { input.setValue(initialString) wrapper.setData({ caret: 0 }) wrapper.vm.insert({ insertion: '(test)', keepOpen: false }) - expect(wrapper.emitted().input[0][0]).to.eql('(test) Testing') + const inputEvents = wrapper.emitted().input + expect(inputEvents[inputEvents.length - 1][0]).to.eql('(test) Testing') }) it('inserts string between words without creating extra spaces', () => { @@ -66,7 +69,8 @@ describe('EmojiInput', () => { input.setValue(initialString) wrapper.setData({ caret: 6 }) wrapper.vm.insert({ insertion: ':ebin:', keepOpen: false }) - expect(wrapper.emitted().input[0][0]).to.eql('Spurdo :ebin: Sparde') + const inputEvents = wrapper.emitted().input + expect(inputEvents[inputEvents.length - 1][0]).to.eql('Spurdo :ebin: Sparde') }) it('inserts string between words without creating extra spaces (other caret)', () => { @@ -76,7 +80,8 @@ describe('EmojiInput', () => { input.setValue(initialString) wrapper.setData({ caret: 7 }) wrapper.vm.insert({ insertion: ':ebin:', keepOpen: false }) - expect(wrapper.emitted().input[0][0]).to.eql('Spurdo :ebin: Sparde') + const inputEvents = wrapper.emitted().input + expect(inputEvents[inputEvents.length - 1][0]).to.eql('Spurdo :ebin: Sparde') }) it('inserts string without any padding if padEmoji setting is set to false', () => { @@ -86,7 +91,8 @@ describe('EmojiInput', () => { input.setValue(initialString) wrapper.setData({ caret: initialString.length, keepOpen: false }) wrapper.vm.insert({ insertion: ':spam:' }) - expect(wrapper.emitted().input[0][0]).to.eql('Eat some spam!:spam:') + const inputEvents = wrapper.emitted().input + expect(inputEvents[inputEvents.length - 1][0]).to.eql('Eat some spam!:spam:') }) it('correctly sets caret after insertion at beginning', (done) => { diff --git a/test/unit/specs/components/user_profile.spec.js b/test/unit/specs/components/user_profile.spec.js index 1b6a47d7..dcf066f9 100644 --- a/test/unit/specs/components/user_profile.spec.js +++ b/test/unit/specs/components/user_profile.spec.js @@ -19,6 +19,7 @@ const actions = { const testGetters = { findUser: state => getters.findUser(state.users), + relationship: state => getters.relationship(state.users), mergedConfig: state => ({ colors: '', highlight: {}, @@ -96,7 +97,8 @@ const externalProfileStore = new Vuex.Store({ credentials: '' }, usersObject: { 100: extUser }, - users: [extUser] + users: [extUser], + relationships: {} } } }) @@ -164,7 +166,8 @@ const localProfileStore = new Vuex.Store({ credentials: '' }, usersObject: { 100: localUser, 'testuser': localUser }, - users: [localUser] + users: [localUser], + relationships: {} } } }) diff --git a/test/unit/specs/modules/users.spec.js b/test/unit/specs/modules/users.spec.js index eeb7afef..670acfc8 100644 --- a/test/unit/specs/modules/users.spec.js +++ b/test/unit/specs/modules/users.spec.js @@ -18,20 +18,6 @@ describe('The users module', () => { expect(state.users).to.eql([user]) expect(state.users[0].name).to.eql('Dude') }) - - it('sets a mute bit on users', () => { - const state = cloneDeep(defaultState) - const user = { id: '1', name: 'Guy' } - - mutations.addNewUsers(state, [user]) - mutations.setMuted(state, { user, muted: true }) - - expect(user.muted).to.eql(true) - - mutations.setMuted(state, { user, muted: false }) - - expect(user.muted).to.eql(false) - }) }) describe('findUser', () => { diff --git a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js index cfb380ba..166fce2b 100644 --- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js +++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js @@ -338,9 +338,9 @@ describe('API Entities normalizer', () => { describe('MastoAPI emoji adder', () => { const emojis = makeMockEmojiMasto() - const imageHtml = '' + const imageHtml = '' .replace(/"/g, '\'') - const thinkHtml = '' + const thinkHtml = '' .replace(/"/g, '\'') it('correctly replaces shortcodes in supplied string', () => { @@ -366,8 +366,8 @@ describe('API Entities normalizer', () => { shortcode: '[a-z] {|}*' }]) const result = addEmojis('This post has :c++: emoji and :[a-z] {|}*: emoji', emojis) - expect(result).to.include('title=\'c++\'') - expect(result).to.include('title=\'[a-z] {|}*\'') + expect(result).to.include('title=\':c++:\'') + expect(result).to.include('title=\':[a-z] {|}*:\'') }) }) }) diff --git a/test/unit/specs/services/status_parser/status_parses.spec.js b/test/unit/specs/services/status_parser/status_parses.spec.js deleted file mode 100644 index 7afd5042..00000000 --- a/test/unit/specs/services/status_parser/status_parses.spec.js +++ /dev/null @@ -1,17 +0,0 @@ -import { removeAttachmentLinks } from '../../../../../src/services/status_parser/status_parser.js' - -const example = '' - -describe('statusParser.removeAttachmentLinks', () => { - const exampleWithoutAttachmentLinks = '' - - it('removes attachment links', () => { - const parsed = removeAttachmentLinks(example) - expect(parsed).to.eql(exampleWithoutAttachmentLinks) - }) - - it('works when the class is empty', () => { - const parsed = removeAttachmentLinks('') - expect(parsed).to.eql('') - }) -}) diff --git a/test/unit/specs/services/theme_data/sanity_checks.spec.js b/test/unit/specs/services/theme_data/sanity_checks.spec.js new file mode 100644 index 00000000..f0072e7d --- /dev/null +++ b/test/unit/specs/services/theme_data/sanity_checks.spec.js @@ -0,0 +1,28 @@ +import { getColors } from 'src/services/theme_data/theme_data.service.js' + +const checkColors = (output) => { + expect(output).to.have.property('colors') + Object.entries(output.colors).forEach(([key, v]) => { + expect(v, key).to.be.an('object') + expect(v, key).to.include.all.keys('r', 'g', 'b') + 'rgba'.split('').forEach(k => { + if ((k === 'a' && v.hasOwnProperty('a')) || k !== 'a') { + expect(v[k], key + '.' + k).to.be.a('number') + expect(v[k], key + '.' + k).to.be.least(0) + expect(v[k], key + '.' + k).to.be.most(k === 'a' ? 1 : 255) + } + }) + }) +} + +describe('Theme Data utility functions', () => { + const context = require.context('static/themes/', false, /\.json$/) + context.keys().forEach((key) => { + it(`Should render all colors for ${key} properly`, () => { + const { theme, source } = context(key) + const data = source || theme + const colors = getColors(data.colors, data.opacity, 1) + checkColors(colors) + }) + }) +}) diff --git a/test/unit/specs/services/theme_data/theme_data.spec.js b/test/unit/specs/services/theme_data/theme_data.spec.js new file mode 100644 index 00000000..c634cade --- /dev/null +++ b/test/unit/specs/services/theme_data/theme_data.spec.js @@ -0,0 +1,89 @@ +import { getLayersArray, topoSort } from 'src/services/theme_data/theme_data.service.js' + +describe('Theme Data utility functions', () => { + describe('getLayersArray', () => { + const fixture = { + layer1: null, + layer2: 'layer1', + layer3a: 'layer2', + layer3b: 'layer2' + } + + it('should expand layers properly (3b)', () => { + const out = getLayersArray('layer3b', fixture) + expect(out).to.eql(['layer1', 'layer2', 'layer3b']) + }) + + it('should expand layers properly (3a)', () => { + const out = getLayersArray('layer3a', fixture) + expect(out).to.eql(['layer1', 'layer2', 'layer3a']) + }) + + it('should expand layers properly (2)', () => { + const out = getLayersArray('layer2', fixture) + expect(out).to.eql(['layer1', 'layer2']) + }) + + it('should expand layers properly (1)', () => { + const out = getLayersArray('layer1', fixture) + expect(out).to.eql(['layer1']) + }) + }) + + describe('topoSort', () => { + const fixture1 = { + layerA: [], + layer1A: ['layerA'], + layer2A: ['layer1A'], + layerB: [], + layer1B: ['layerB'], + layer2B: ['layer1B'], + layer3AB: ['layer2B', 'layer2A'] + } + + // Same thing but messed up order + const fixture2 = { + layer1A: ['layerA'], + layer1B: ['layerB'], + layer2A: ['layer1A'], + layerB: [], + layer3AB: ['layer2B', 'layer2A'], + layer2B: ['layer1B'], + layerA: [] + } + + it('should make a topologically sorted array', () => { + const out = topoSort(fixture1, (node, inheritance) => inheritance[node]) + // This basically checks all ordering that matters + expect(out.indexOf('layerA')).to.be.below(out.indexOf('layer1A')) + expect(out.indexOf('layer1A')).to.be.below(out.indexOf('layer2A')) + expect(out.indexOf('layerB')).to.be.below(out.indexOf('layer1B')) + expect(out.indexOf('layer1B')).to.be.below(out.indexOf('layer2B')) + expect(out.indexOf('layer2A')).to.be.below(out.indexOf('layer3AB')) + expect(out.indexOf('layer2B')).to.be.below(out.indexOf('layer3AB')) + }) + + it('order in object shouldn\'t matter', () => { + const out = topoSort(fixture2, (node, inheritance) => inheritance[node]) + // This basically checks all ordering that matters + expect(out.indexOf('layerA')).to.be.below(out.indexOf('layer1A')) + expect(out.indexOf('layer1A')).to.be.below(out.indexOf('layer2A')) + expect(out.indexOf('layerB')).to.be.below(out.indexOf('layer1B')) + expect(out.indexOf('layer1B')).to.be.below(out.indexOf('layer2B')) + expect(out.indexOf('layer2A')).to.be.below(out.indexOf('layer3AB')) + expect(out.indexOf('layer2B')).to.be.below(out.indexOf('layer3AB')) + }) + + it('dependentless nodes should be first', () => { + const out = topoSort(fixture2, (node, inheritance) => inheritance[node]) + // This basically checks all ordering that matters + expect(out.indexOf('layerA')).to.eql(0) + expect(out.indexOf('layerB')).to.eql(1) + }) + + it('ignores cyclic dependencies', () => { + const out = topoSort({ a: 'b', b: 'a', c: 'a' }, (node, inheritance) => [inheritance[node]]) + expect(out.indexOf('a')).to.be.below(out.indexOf('c')) + }) + }) +}) diff --git a/yarn.lock b/yarn.lock index b794042f..f05b00b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1062,7 +1062,7 @@ array-union@^1.0.1: dependencies: array-uniq "^1.0.1" -array-uniq@^1.0.1, array-uniq@^1.0.2: +array-uniq@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" @@ -2327,6 +2327,7 @@ dateformat@^1.0.6: de-indent@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" + integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0= debug@2, debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" @@ -2544,7 +2545,7 @@ domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" -domelementtype@1, domelementtype@^1.3.0: +domelementtype@1: version "1.3.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" @@ -2558,12 +2559,6 @@ domhandler@2.1: dependencies: domelementtype "1" -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - dependencies: - domelementtype "1" - domutils@1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.1.6.tgz#bddc3de099b9a2efacc51c623f28f416ecc57485" @@ -2577,13 +2572,6 @@ domutils@1.5.1: dom-serializer "0" domelementtype "1" -domutils@^1.5.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - dependencies: - dom-serializer "0" - domelementtype "1" - duplexer2@~0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" @@ -2710,7 +2698,7 @@ ent@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" -entities@^1.1.1, entities@~1.1.1: +entities@~1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" @@ -3761,17 +3749,6 @@ html-webpack-plugin@^3.0.0, html-webpack-plugin@^3.2.0: toposort "^1.0.0" util.promisify "1.0.0" -htmlparser2@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464" - dependencies: - domelementtype "^1.3.0" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.0.6" - htmlparser2@~3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.3.0.tgz#cc70d05a59f6542e43f0e685c982e14c924a9efe" @@ -4756,10 +4733,6 @@ lodash.clone@3.0.3: lodash._bindcallback "^3.0.0" lodash._isiterateecall "^3.0.0" -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - lodash.create@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" @@ -4779,10 +4752,6 @@ lodash.defaultsdeep@4.3.2: lodash.mergewith "^4.0.0" lodash.rest "^4.0.0" -lodash.escaperegexp@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" - lodash.find@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-3.2.1.tgz#046e319f3ace912ac6c9246c7f683c5ec07b36ad" @@ -4814,14 +4783,10 @@ lodash.isplainobject@^3.0.0, lodash.isplainobject@^3.2.0: lodash.isarguments "^3.0.0" lodash.keysin "^3.0.0" -lodash.isplainobject@^4.0.0, lodash.isplainobject@^4.0.6: +lodash.isplainobject@^4.0.0: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" -lodash.isstring@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - lodash.istypedarray@^3.0.0: version "3.0.6" resolved "https://registry.yarnpkg.com/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz#c9a477498607501d8e8494d283b87c39281cef62" @@ -4870,7 +4835,7 @@ lodash.merge@^3.3.2: lodash.keysin "^3.0.0" lodash.toplainobject "^3.0.0" -lodash.mergewith@^4.0.0, lodash.mergewith@^4.6.1: +lodash.mergewith@^4.0.0: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" @@ -5537,10 +5502,6 @@ object-keys@^1.0.11, object-keys@^1.0.12: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" -object-path@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" - object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -5941,11 +5902,6 @@ pngjs@^3.3.0: version "3.3.3" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.3.3.tgz#85173703bde3edac8998757b96e5821d0966a21b" -popper.js@^1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.15.0.tgz#5560b99bbad7647e9faa475c6b8056621f5a4ff2" - integrity sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA== - portal-vue@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/portal-vue/-/portal-vue-2.1.4.tgz#1fc679d77e294dc8d026f1eb84aa467de11b392e" @@ -6249,14 +6205,6 @@ postcss@^7.0.0: source-map "^0.6.1" supports-color "^6.1.0" -postcss@^7.0.5: - version "7.0.8" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.8.tgz#2a3c5f2bdd00240cd0d0901fd998347c93d36696" - dependencies: - chalk "^2.4.2" - source-map "^0.6.1" - supports-color "^6.0.0" - prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -6525,14 +6473,6 @@ readable-stream@1.1.x: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^3.0.6: - version "3.1.1" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.1.1.tgz#ed6bbc6c5ba58b090039ff18ce670515795aeb06" - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -6843,21 +6783,6 @@ samsam@1.x, samsam@^1.1.3: version "1.3.0" resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50" -sanitize-html@^1.13.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.20.0.tgz#9a602beb1c9faf960fb31f9890f61911cc4d9156" - dependencies: - chalk "^2.4.1" - htmlparser2 "^3.10.0" - lodash.clonedeep "^4.5.0" - lodash.escaperegexp "^4.1.2" - lodash.isplainobject "^4.0.6" - lodash.isstring "^4.0.1" - lodash.mergewith "^4.6.1" - postcss "^7.0.5" - srcset "^1.0.0" - xtend "^4.0.1" - "sass-loader@git://github.com/webpack-contrib/sass-loader": version "7.1.0" resolved "git://github.com/webpack-contrib/sass-loader#e279f2a129eee0bd0b624b5acd498f23a81ee35e" @@ -7229,13 +7154,6 @@ sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" -srcset@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/srcset/-/srcset-1.0.0.tgz#a5669de12b42f3b1d5e83ed03c71046fc48f41ef" - dependencies: - array-uniq "^1.0.2" - number-is-nan "^1.0.0" - sshpk@^1.7.0: version "1.16.0" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.0.tgz#1d4963a2fbffe58050aa9084ca20be81741c07de" @@ -7335,7 +7253,7 @@ string-width@^3.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string_decoder@^1.0.0, string_decoder@^1.1.1: +string_decoder@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" dependencies: @@ -7419,7 +7337,7 @@ supports-color@^5.3.0, supports-color@^5.4.0: dependencies: has-flag "^3.0.0" -supports-color@^6.0.0, supports-color@^6.1.0: +supports-color@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" dependencies: @@ -7784,7 +7702,7 @@ useragent@2.3.0: lru-cache "4.1.x" tmp "0.0.x" -util-deprecate@^1.0.1, util-deprecate@~1.0.1: +util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -7823,15 +7741,6 @@ v-click-outside@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/v-click-outside/-/v-click-outside-2.1.3.tgz#b7297abe833a439dc0895e6418a494381e64b5e7" -v-tooltip@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/v-tooltip/-/v-tooltip-2.0.2.tgz#8610d9eece2cc44fd66c12ef2f12eec6435cab9b" - integrity sha512-xQ+qzOFfywkLdjHknRPgMMupQNS8yJtf9Utd5Dxiu/0n4HtrxqsgDtN2MLZ0LKbburtSAQgyypuE/snM8bBZhw== - dependencies: - lodash "^4.17.11" - popper.js "^1.15.0" - vue-resize "^0.4.5" - validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -7906,11 +7815,6 @@ vue-loader@^14.0.0: vue-style-loader "^4.0.1" vue-template-es2015-compiler "^1.6.0" -vue-resize@^0.4.5: - version "0.4.5" - resolved "https://registry.yarnpkg.com/vue-resize/-/vue-resize-0.4.5.tgz#4777a23042e3c05620d9cbda01c0b3cc5e32dcea" - integrity sha512-bhP7MlgJQ8TIkZJXAfDf78uJO+mEI3CaLABLjv0WNzr4CcGRGPIAItyWYnP6LsPA4Oq0WE+suidNs6dgpO4RHg== - vue-router@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.2.tgz#dedc67afe6c4e2bc25682c8b1c2a8c0d7c7e56be" @@ -7922,9 +7826,10 @@ vue-style-loader@^4.0.0, vue-style-loader@^4.0.1: hash-sum "^1.0.2" loader-utils "^1.0.2" -vue-template-compiler@^2.3.4: - version "2.5.21" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.21.tgz#a57ceb903177e8f643560a8d639a0f8db647054a" +vue-template-compiler@^2.6.11: + version "2.6.11" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080" + integrity sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA== dependencies: de-indent "^1.0.2" he "^1.1.0" @@ -7933,9 +7838,10 @@ vue-template-es2015-compiler@^1.6.0: version "1.9.1" resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" -vue@^2.5.13: - version "2.5.21" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.21.tgz#3d33dcd03bb813912ce894a8303ab553699c4a85" +vue@^2.6.11: + version "2.6.11" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5" + integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ== vuelidate@^0.7.4: version "0.7.4" @@ -8031,10 +7937,6 @@ webpack@^4.0.0: watchpack "^1.5.0" webpack-sources "^1.3.0" -whatwg-fetch@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" - whet.extend@~0.9.9: version "0.9.9" resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" @@ -8106,7 +8008,7 @@ xregexp@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: +xtend@^4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"