feat(premium): let self-hosted instances sell premium and gifts (#3025)

This commit is contained in:
Hampus
2026-09-28 21:21:51 +02:00
committed by GitHub
parent 192cec689a
commit 3736d94d73
159 changed files with 15802 additions and 9067 deletions
@@ -4,10 +4,10 @@ import {APIErrorCodes} from '@fluxer/constants/src/ApiErrorCodes';
import {BadRequestError} from '@fluxer/errors/src/domains/core/BadRequestError';
export class CannotRedeemPlutoniumWithVisionaryError extends BadRequestError {
constructor() {
constructor(premiumTierName = 'Plutonium') {
super({
code: APIErrorCodes.CANNOT_REDEEM_PLUTONIUM_WITH_VISIONARY,
messageVariables: {premium_tier_name: 'Plutonium'},
messageVariables: {premium_tier_name: premiumTierName},
});
}
}
+7 -7
View File
@@ -395,14 +395,14 @@ const ERROR_I18N_CS_MESSAGES = defineErrorI18nLocaleMessages({
"phone.verification_code_invalid": "Neplatný ověřovací kód telefonu.",
"phone.verification_needs_review": "Toto číslo se nepodařilo ověřit automaticky. Napište na [email protected] a váš účet posoudí člověk.",
"phone.verification_required": "Je vyžadováno ověření telefonu.",
"premium_and_plans.animated_avatars_require_premium": "Animované avatary vyžadují tarif Plutonium.",
"premium_and_plans.banners_require_premium": "Bannery vyžadují tarif Plutonium.",
"premium_and_plans.bio_requires_premium_for_length": "Bio delší než {maxLength} znaků vyžaduje tarif Plutonium.",
"premium_and_plans.animated_avatars_require_premium": "Animované avatary vyžadují tarif Premium.",
"premium_and_plans.banners_require_premium": "Bannery vyžadují tarif Premium.",
"premium_and_plans.bio_requires_premium_for_length": "Bio delší než {maxLength} znaků vyžaduje tarif Premium.",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "Pokud máte tarif Visionary, nemůžete uplatnit {premium_tier_name}.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Bez tarifu Plutonium nemůžete používat vlastní emoji mimo jejich zdrojové komunity.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Bez tarifu Plutonium nemůžete používat vlastní samolepky v soukromých konverzacích.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Bez tarifu Plutonium nemůžete používat vlastní samolepky mimo jejich zdrojové komunity.",
"premium_and_plans.discriminator_change_requires_premium": "Změna čtyřmístného identifikátoru vyžaduje tarif Plutonium.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Bez tarifu Premium nemůžete používat vlastní emoji mimo jejich zdrojové komunity.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Bez tarifu Premium nemůžete používat vlastní samolepky v soukromých konverzacích.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Bez tarifu Premium nemůžete používat vlastní samolepky mimo jejich zdrojové komunity.",
"premium_and_plans.discriminator_change_requires_premium": "Změna čtyřmístného identifikátoru vyžaduje tarif Premium.",
"premium_and_plans.no_active_subscription": "Žádné aktivní předplatné.",
"premium_and_plans.visionary_required_for_discriminator": "Pro použití tohoto čtyřmístného identifikátoru musíte mít doživotní tarif Visionary.",
"rate_limits.accent_color_changed_too_often": "V poslední době jste měnili svou akcentní barvu příliš často. Zkuste to znovu za {minutes, plural, one {# minutu} few {# minuty} many {# minuty} other {# minut}}.",
+7 -7
View File
@@ -395,14 +395,14 @@ const ERROR_I18N_ES_ES_MESSAGES = defineErrorI18nLocaleMessages({
"phone.verification_code_invalid": "Código de verificación del teléfono no válido.",
"phone.verification_needs_review": "No hemos podido verificar este número automáticamente. Escribe a [email protected] y una persona revisará tu cuenta.",
"phone.verification_required": "Se requiere verificación del teléfono.",
"premium_and_plans.animated_avatars_require_premium": "Los avatares animados requieren Plutonium.",
"premium_and_plans.banners_require_premium": "Los banners requieren Plutonium.",
"premium_and_plans.bio_requires_premium_for_length": "Una biografía de más de {maxLength} caracteres requiere Plutonium.",
"premium_and_plans.animated_avatars_require_premium": "Los avatares animados requieren Premium.",
"premium_and_plans.banners_require_premium": "Los banners requieren Premium.",
"premium_and_plans.bio_requires_premium_for_length": "Una biografía de más de {maxLength} caracteres requiere Premium.",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "No puedes canjear {premium_tier_name} si tienes el plan Visionary.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "No puedes usar emojis personalizados fuera de sus comunidades de origen sin Plutonium.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "No puedes usar pegatinas personalizadas en MD sin Plutonium.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "No puedes usar pegatinas personalizadas fuera de sus comunidades de origen sin Plutonium.",
"premium_and_plans.discriminator_change_requires_premium": "Cambiar tu discriminador requiere Plutonium.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "No puedes usar emojis personalizados fuera de sus comunidades de origen sin Premium.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "No puedes usar pegatinas personalizadas en MD sin Premium.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "No puedes usar pegatinas personalizadas fuera de sus comunidades de origen sin Premium.",
"premium_and_plans.discriminator_change_requires_premium": "Cambiar tu discriminador requiere Premium.",
"premium_and_plans.no_active_subscription": "No hay ninguna suscripción activa.",
"premium_and_plans.visionary_required_for_discriminator": "Necesitas el plan vitalicio de Visionary para usar ese discriminador.",
"rate_limits.accent_color_changed_too_often": "Has cambiado tu color de acento demasiadas veces últimamente. Vuelve a intentarlo en {minutes} {minutes, plural, one {minuto} other {minutos}}.",
+7 -7
View File
@@ -395,14 +395,14 @@ const ERROR_I18N_FR_MESSAGES = defineErrorI18nLocaleMessages({
"phone.verification_code_invalid": "Code de vérification téléphonique invalide.",
"phone.verification_needs_review": "Impossible de vérifier ce numéro automatiquement. Écrivez à [email protected] pour qu’une personne examine votre compte.",
"phone.verification_required": "La vérification téléphonique est requise.",
"premium_and_plans.animated_avatars_require_premium": "Les avatars animés nécessitent une formule Plutonium.",
"premium_and_plans.banners_require_premium": "Les bannières nécessitent une formule Plutonium.",
"premium_and_plans.bio_requires_premium_for_length": "Une bio de plus de {maxLength} caractères nécessite une formule Plutonium.",
"premium_and_plans.animated_avatars_require_premium": "Les avatars animés nécessitent une formule Premium.",
"premium_and_plans.banners_require_premium": "Les bannières nécessitent une formule Premium.",
"premium_and_plans.bio_requires_premium_for_length": "Une bio de plus de {maxLength} caractères nécessite une formule Premium.",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "Vous ne pouvez pas activer un cadeau {premium_tier_name} avec un abonnement Visionary.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Vous ne pouvez pas utiliser d’emojis personnalisés en dehors de leur communauté d’origine sans Plutonium.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Vous ne pouvez pas utiliser de stickers personnalisés dans les MP sans Plutonium.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Vous ne pouvez pas utiliser de stickers personnalisés en dehors de leur communauté d’origine sans Plutonium.",
"premium_and_plans.discriminator_change_requires_premium": "La modification de votre discriminateur nécessite Plutonium.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Vous ne pouvez pas utiliser d’emojis personnalisés en dehors de leur communauté d’origine sans Premium.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Vous ne pouvez pas utiliser de stickers personnalisés dans les MP sans Premium.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Vous ne pouvez pas utiliser de stickers personnalisés en dehors de leur communauté d’origine sans Premium.",
"premium_and_plans.discriminator_change_requires_premium": "La modification de votre discriminateur nécessite Premium.",
"premium_and_plans.no_active_subscription": "Aucun abonnement actif.",
"premium_and_plans.visionary_required_for_discriminator": "L’abonnement à vie Visionary est nécessaire pour utiliser ce discriminateur.",
"rate_limits.accent_color_changed_too_often": "Vous avez changé votre couleur d’accentuation trop souvent récemment. Réessayez dans {minutes, plural, =1 {# minute} other {# minutes}}.",
+7 -7
View File
@@ -395,14 +395,14 @@ const ERROR_I18N_HR_MESSAGES = defineErrorI18nLocaleMessages({
"phone.verification_code_invalid": "Nevažeći kod za provjeru telefona.",
"phone.verification_needs_review": "Ovaj broj nismo mogli automatski provjeriti. Piši na [email protected] i netko iz našeg tima pregledat će tvoj račun.",
"phone.verification_required": "Potrebna je provjera telefona.",
"premium_and_plans.animated_avatars_require_premium": "Animirani avatari zahtijevaju pretplatu na Plutonium.",
"premium_and_plans.banners_require_premium": "Banneri zahtijevaju pretplatu na Plutonium.",
"premium_and_plans.bio_requires_premium_for_length": "Opis profila duži od {maxLength} znakova zahtijeva pretplatu na Plutonium.",
"premium_and_plans.animated_avatars_require_premium": "Animirani avatari zahtijevaju Premium pretplatu.",
"premium_and_plans.banners_require_premium": "Banneri zahtijevaju Premium pretplatu.",
"premium_and_plans.bio_requires_premium_for_length": "Opis profila duži od {maxLength} znakova zahtijeva Premium pretplatu.",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "Ne možeš iskoristiti {premium_tier_name} uz Visionary.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Ne možeš koristiti prilagođene emojije izvan njihovih izvornih zajednica bez pretplate na Plutonium.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Ne možeš koristiti prilagođene naljepnice u izravnim porukama bez pretplate na Plutonium.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Ne možeš koristiti prilagođene naljepnice izvan njihovih izvornih zajednica bez pretplate na Plutonium.",
"premium_and_plans.discriminator_change_requires_premium": "Promjena diskriminatora zahtijeva pretplatu na Plutonium.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Ne možeš koristiti prilagođene emojije izvan njihovih izvornih zajednica bez Premium pretplate.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Ne možeš koristiti prilagođene naljepnice u izravnim porukama bez Premium pretplate.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Ne možeš koristiti prilagođene naljepnice izvan njihovih izvornih zajednica bez Premium pretplate.",
"premium_and_plans.discriminator_change_requires_premium": "Promjena diskriminatora zahtijeva Premium pretplatu.",
"premium_and_plans.no_active_subscription": "Nema aktivne pretplate.",
"premium_and_plans.visionary_required_for_discriminator": "Za taj diskriminator moraš biti na doživotnom planu Visionary.",
"rate_limits.accent_color_changed_too_often": "U zadnje vrijeme prečesto mijenjaš boju naglaska. Pokušaj ponovno za {minutes, plural, one {# minutu} few {# minute} other {# minuta}}.",
+7 -7
View File
@@ -395,14 +395,14 @@ const ERROR_I18N_JA_MESSAGES = defineErrorI18nLocaleMessages({
"phone.verification_code_invalid": "電話認証コードが無効です。",
"phone.verification_needs_review": "この番号を自動で認証できませんでした。[email protected]にメールしていただければ、担当者がアカウントを確認します。",
"phone.verification_required": "電話認証が必要です。",
"premium_and_plans.animated_avatars_require_premium": "アニメーションアバターにはPlutoniumが必要です。",
"premium_and_plans.banners_require_premium": "バナーにはPlutoniumが必要です。",
"premium_and_plans.bio_requires_premium_for_length": "{maxLength}文字を超える自己紹介にはPlutoniumが必要です。",
"premium_and_plans.animated_avatars_require_premium": "アニメーションアバターにはプレミアムが必要です。",
"premium_and_plans.banners_require_premium": "バナーにはプレミアムが必要です。",
"premium_and_plans.bio_requires_premium_for_length": "{maxLength}文字を超える自己紹介にはプレミアムが必要です。",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "Visionaryでは{premium_tier_name}を引き換えられません。",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Plutoniumをお持ちでない場合は、元のコミュニティ以外でカスタム絵文字を使えません。",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Plutoniumをお持ちでない場合は、DMでカスタムスタンプを使えません。",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Plutoniumをお持ちでない場合は、元のコミュニティ以外でカスタムスタンプを使えません。",
"premium_and_plans.discriminator_change_requires_premium": "識別子の変更にはPlutoniumが必要です。",
"premium_and_plans.custom_emojis_outside_source_require_premium": "プレミアムをお持ちでない場合は、元のコミュニティ以外でカスタム絵文字を使えません。",
"premium_and_plans.custom_stickers_in_dms_require_premium": "プレミアムをお持ちでない場合は、DMでカスタムスタンプを使えません。",
"premium_and_plans.custom_stickers_outside_source_require_premium": "プレミアムをお持ちでない場合は、元のコミュニティ以外でカスタムスタンプを使えません。",
"premium_and_plans.discriminator_change_requires_premium": "識別子の変更にはプレミアムが必要です。",
"premium_and_plans.no_active_subscription": "有効なサブスクリプションがありません。",
"premium_and_plans.visionary_required_for_discriminator": "その識別子を使うには、Visionaryライフタイムプランに加入している必要があります。",
"rate_limits.accent_color_changed_too_often": "アクセントカラーの変更回数が多すぎます。{minutes, plural, other {#分}}後にもう一度お試しください。",
+7 -7
View File
@@ -395,14 +395,14 @@ const ERROR_I18N_KO_MESSAGES = defineErrorI18nLocaleMessages({
"phone.verification_code_invalid": "전화 인증 코드가 올바르지 않아요.",
"phone.verification_needs_review": "이 번호를 자동으로 인증하지 못했어요. [email protected]으로 메일을 보내면 담당자가 회원님 계정을 검토해 드려요.",
"phone.verification_required": "전화 인증이 필요해요.",
"premium_and_plans.animated_avatars_require_premium": "움직이는 아바타는 Plutonium이 필요해요.",
"premium_and_plans.banners_require_premium": "배너는 Plutonium이 필요해요.",
"premium_and_plans.bio_requires_premium_for_length": "{maxLength}자가 넘는 소개글을 쓰려면 Plutonium이 필요해요.",
"premium_and_plans.animated_avatars_require_premium": "움직이는 아바타는 프리미엄이 필요해요.",
"premium_and_plans.banners_require_premium": "배너는 프리미엄이 필요해요.",
"premium_and_plans.bio_requires_premium_for_length": "{maxLength}자가 넘는 소개글을 쓰려면 프리미엄이 필요해요.",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "Visionary 이용 중에는 {premium_tier_name}을 사용할 수 없어요.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Plutonium 없이는 원본 커뮤니티 외부에서 커스텀 이모지를 사용할 수 없어요.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Plutonium 없이는 DM에서 커스텀 스티커를 사용할 수 없어요.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Plutonium 없이는 원본 커뮤니티 외부에서 커스텀 스티커를 사용할 수 없어요.",
"premium_and_plans.discriminator_change_requires_premium": "식별자를 변경하려면 Plutonium이 필요해요.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "프리미엄 없이는 원본 커뮤니티 외부에서 커스텀 이모지를 사용할 수 없어요.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "프리미엄 없이는 DM에서 커스텀 스티커를 사용할 수 없어요.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "프리미엄 없이는 원본 커뮤니티 외부에서 커스텀 스티커를 사용할 수 없어요.",
"premium_and_plans.discriminator_change_requires_premium": "식별자를 변경하려면 프리미엄이 필요해요.",
"premium_and_plans.no_active_subscription": "활성화된 구독이 없어요.",
"premium_and_plans.visionary_required_for_discriminator": "해당 식별자를 사용하려면 Visionary 평생 요금제를 이용해야 해요.",
"rate_limits.accent_color_changed_too_often": "최근에 강조 색상을 너무 자주 변경했어요. {minutes, plural, other {#분}} 후에 다시 시도해 주세요.",
+7 -7
View File
@@ -395,14 +395,14 @@ const ERROR_I18N_RO_MESSAGES = defineErrorI18nLocaleMessages({
"phone.verification_code_invalid": "Cod de verificare telefonică invalid.",
"phone.verification_needs_review": "Nu am putut verifica automat acest număr. Scrie la [email protected] și o persoană îți va examina contul.",
"phone.verification_required": "Este necesară verificarea telefonului.",
"premium_and_plans.animated_avatars_require_premium": "Avatarele animate necesită Plutonium.",
"premium_and_plans.banners_require_premium": "Bannerele necesită Plutonium.",
"premium_and_plans.bio_requires_premium_for_length": "O biografie mai lungă de {maxLength} caractere necesită Plutonium.",
"premium_and_plans.animated_avatars_require_premium": "Avatarele animate necesită Premium.",
"premium_and_plans.banners_require_premium": "Bannerele necesită Premium.",
"premium_and_plans.bio_requires_premium_for_length": "O biografie mai lungă de {maxLength} caractere necesită Premium.",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "Nu poți revendica {premium_tier_name} cu Visionary.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Nu poți folosi emoji personalizate din afara comunităților sursă fără Plutonium.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Nu poți folosi stickere personalizate în DM-uri fără Plutonium.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Nu poți folosi stickere personalizate din afara comunităților sursă fără Plutonium.",
"premium_and_plans.discriminator_change_requires_premium": "Schimbarea discriminatorului necesită Plutonium.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Nu poți folosi emoji personalizate din afara comunităților sursă fără Premium.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Nu poți folosi stickere personalizate în DM-uri fără Premium.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Nu poți folosi stickere personalizate din afara comunităților sursă fără Premium.",
"premium_and_plans.discriminator_change_requires_premium": "Schimbarea discriminatorului necesită Premium.",
"premium_and_plans.no_active_subscription": "Niciun abonament activ.",
"premium_and_plans.visionary_required_for_discriminator": "Trebuie să ai abonamentul Visionary pe viață pentru a folosi acel discriminator.",
"rate_limits.accent_color_changed_too_often": "Ți-ai schimbat culoarea de accent prea des recent. Încearcă din nou peste {minutes, plural, one {# minut} few {# minute} other {# de minute}}.",
+7 -7
View File
@@ -395,14 +395,14 @@ const ERROR_I18N_RU_MESSAGES = defineErrorI18nLocaleMessages({
"phone.verification_code_invalid": "Неверный код подтверждения телефона.",
"phone.verification_needs_review": "Нам не удалось подтвердить этот номер автоматически. Напиши на [email protected], и твой аккаунт проверит человек.",
"phone.verification_required": "Требуется подтверждение телефона.",
"premium_and_plans.animated_avatars_require_premium": "Для анимированных аватаров нужен Plutonium.",
"premium_and_plans.banners_require_premium": "Для баннеров нужен Plutonium.",
"premium_and_plans.bio_requires_premium_for_length": "Для биографии длиннее {maxLength} символов нужен Plutonium.",
"premium_and_plans.animated_avatars_require_premium": "Для анимированных аватаров нужен Премиум.",
"premium_and_plans.banners_require_premium": "Для баннеров нужен Премиум.",
"premium_and_plans.bio_requires_premium_for_length": "Для биографии длиннее {maxLength} символов нужен Премиум.",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "Нельзя активировать {premium_tier_name}, если у тебя уже есть Visionary.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Без Plutonium нельзя использовать пользовательские эмодзи за пределами исходных сообществ.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Без Plutonium нельзя использовать пользовательские стикеры в ЛС.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Без Plutonium нельзя использовать пользовательские стикеры за пределами исходных сообществ.",
"premium_and_plans.discriminator_change_requires_premium": "Для смены дискриминатора нужен Plutonium.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Без Премиума нельзя использовать пользовательские эмодзи за пределами исходных сообществ.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Без Премиума нельзя использовать пользовательские стикеры в ЛС.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Без Премиума нельзя использовать пользовательские стикеры за пределами исходных сообществ.",
"premium_and_plans.discriminator_change_requires_premium": "Для смены дискриминатора нужен Премиум.",
"premium_and_plans.no_active_subscription": "Нет активной подписки.",
"premium_and_plans.visionary_required_for_discriminator": "Использовать этот дискриминатор можно только с пожизненным тарифом Visionary.",
"rate_limits.accent_color_changed_too_often": "Ты слишком часто меняешь акцентный цвет. Попробуй ещё раз через {minutes} {minutes, plural, one {минуту} few {минуты} many {минут} other {минуты}}.",
+7 -7
View File
@@ -395,14 +395,14 @@ const ERROR_I18N_ZH_CN_MESSAGES = defineErrorI18nLocaleMessages({
"phone.verification_code_invalid": "无效的手机验证码。",
"phone.verification_needs_review": "我们无法自动验证这个号码。请发送邮件至 [email protected],会有工作人员审核你的账号。",
"phone.verification_required": "需要手机号码验证。",
"premium_and_plans.animated_avatars_require_premium": "动态头像需要 Plutonium 会员。",
"premium_and_plans.banners_require_premium": "横幅需要 Plutonium 会员。",
"premium_and_plans.bio_requires_premium_for_length": "个人简介超过 {maxLength} 个字符需要 Plutonium 会员。",
"premium_and_plans.animated_avatars_require_premium": "动态头像需要高级会员。",
"premium_and_plans.banners_require_premium": "横幅需要高级会员。",
"premium_and_plans.bio_requires_premium_for_length": "个人简介超过 {maxLength} 个字符需要高级会员。",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "无法使用 Visionary 兑换 {premium_tier_name}。",
"premium_and_plans.custom_emojis_outside_source_require_premium": "没有 Plutonium 会员,无法在来源社区之外使用自定义表情。",
"premium_and_plans.custom_stickers_in_dms_require_premium": "没有 Plutonium 会员,无法在私信中使用自定义贴纸。",
"premium_and_plans.custom_stickers_outside_source_require_premium": "没有 Plutonium 会员,无法在来源社区之外使用自定义贴纸。",
"premium_and_plans.discriminator_change_requires_premium": "修改识别码需要 Plutonium 会员。",
"premium_and_plans.custom_emojis_outside_source_require_premium": "没有高级会员,无法在来源社区之外使用自定义表情。",
"premium_and_plans.custom_stickers_in_dms_require_premium": "没有高级会员,无法在私信中使用自定义贴纸。",
"premium_and_plans.custom_stickers_outside_source_require_premium": "没有高级会员,无法在来源社区之外使用自定义贴纸。",
"premium_and_plans.discriminator_change_requires_premium": "修改识别码需要高级会员。",
"premium_and_plans.no_active_subscription": "没有有效的订阅。",
"premium_and_plans.visionary_required_for_discriminator": "你必须拥有 Visionary 终身计划才能使用该识别码。",
"rate_limits.accent_color_changed_too_often": "你最近修改强调色过于频繁。请在 {minutes, plural, other {# 分钟}}后重试。",
@@ -391,14 +391,14 @@
"phone.verification_code_invalid": "Neplatný ověřovací kód telefonu.",
"phone.verification_needs_review": "Toto číslo se nepodařilo ověřit automaticky. Napište na [email protected] a váš účet posoudí člověk.",
"phone.verification_required": "Je vyžadováno ověření telefonu.",
"premium_and_plans.animated_avatars_require_premium": "Animované avatary vyžadují tarif Plutonium.",
"premium_and_plans.banners_require_premium": "Bannery vyžadují tarif Plutonium.",
"premium_and_plans.bio_requires_premium_for_length": "Bio delší než {maxLength} znaků vyžaduje tarif Plutonium.",
"premium_and_plans.animated_avatars_require_premium": "Animované avatary vyžadují tarif Premium.",
"premium_and_plans.banners_require_premium": "Bannery vyžadují tarif Premium.",
"premium_and_plans.bio_requires_premium_for_length": "Bio delší než {maxLength} znaků vyžaduje tarif Premium.",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "Pokud máte tarif Visionary, nemůžete uplatnit {premium_tier_name}.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Bez tarifu Plutonium nemůžete používat vlastní emoji mimo jejich zdrojové komunity.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Bez tarifu Plutonium nemůžete používat vlastní samolepky v soukromých konverzacích.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Bez tarifu Plutonium nemůžete používat vlastní samolepky mimo jejich zdrojové komunity.",
"premium_and_plans.discriminator_change_requires_premium": "Změna čtyřmístného identifikátoru vyžaduje tarif Plutonium.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Bez tarifu Premium nemůžete používat vlastní emoji mimo jejich zdrojové komunity.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Bez tarifu Premium nemůžete používat vlastní samolepky v soukromých konverzacích.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Bez tarifu Premium nemůžete používat vlastní samolepky mimo jejich zdrojové komunity.",
"premium_and_plans.discriminator_change_requires_premium": "Změna čtyřmístného identifikátoru vyžaduje tarif Premium.",
"premium_and_plans.no_active_subscription": "Žádné aktivní předplatné.",
"premium_and_plans.visionary_required_for_discriminator": "Pro použití tohoto čtyřmístného identifikátoru musíte mít doživotní tarif Visionary.",
"rate_limits.accent_color_changed_too_often": "V poslední době jste měnili svou akcentní barvu příliš často. Zkuste to znovu za {minutes, plural, one {# minutu} few {# minuty} many {# minuty} other {# minut}}.",
@@ -391,14 +391,14 @@
"phone.verification_code_invalid": "Código de verificación del teléfono no válido.",
"phone.verification_needs_review": "No hemos podido verificar este número automáticamente. Escribe a [email protected] y una persona revisará tu cuenta.",
"phone.verification_required": "Se requiere verificación del teléfono.",
"premium_and_plans.animated_avatars_require_premium": "Los avatares animados requieren Plutonium.",
"premium_and_plans.banners_require_premium": "Los banners requieren Plutonium.",
"premium_and_plans.bio_requires_premium_for_length": "Una biografía de más de {maxLength} caracteres requiere Plutonium.",
"premium_and_plans.animated_avatars_require_premium": "Los avatares animados requieren Premium.",
"premium_and_plans.banners_require_premium": "Los banners requieren Premium.",
"premium_and_plans.bio_requires_premium_for_length": "Una biografía de más de {maxLength} caracteres requiere Premium.",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "No puedes canjear {premium_tier_name} si tienes el plan Visionary.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "No puedes usar emojis personalizados fuera de sus comunidades de origen sin Plutonium.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "No puedes usar pegatinas personalizadas en MD sin Plutonium.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "No puedes usar pegatinas personalizadas fuera de sus comunidades de origen sin Plutonium.",
"premium_and_plans.discriminator_change_requires_premium": "Cambiar tu discriminador requiere Plutonium.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "No puedes usar emojis personalizados fuera de sus comunidades de origen sin Premium.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "No puedes usar pegatinas personalizadas en MD sin Premium.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "No puedes usar pegatinas personalizadas fuera de sus comunidades de origen sin Premium.",
"premium_and_plans.discriminator_change_requires_premium": "Cambiar tu discriminador requiere Premium.",
"premium_and_plans.no_active_subscription": "No hay ninguna suscripción activa.",
"premium_and_plans.visionary_required_for_discriminator": "Necesitas el plan vitalicio de Visionary para usar ese discriminador.",
"rate_limits.accent_color_changed_too_often": "Has cambiado tu color de acento demasiadas veces últimamente. Vuelve a intentarlo en {minutes} {minutes, plural, one {minuto} other {minutos}}.",
@@ -391,14 +391,14 @@
"phone.verification_code_invalid": "Code de vérification téléphonique invalide.",
"phone.verification_needs_review": "Impossible de vérifier ce numéro automatiquement. Écrivez à [email protected] pour qu’une personne examine votre compte.",
"phone.verification_required": "La vérification téléphonique est requise.",
"premium_and_plans.animated_avatars_require_premium": "Les avatars animés nécessitent une formule Plutonium.",
"premium_and_plans.banners_require_premium": "Les bannières nécessitent une formule Plutonium.",
"premium_and_plans.bio_requires_premium_for_length": "Une bio de plus de {maxLength} caractères nécessite une formule Plutonium.",
"premium_and_plans.animated_avatars_require_premium": "Les avatars animés nécessitent une formule Premium.",
"premium_and_plans.banners_require_premium": "Les bannières nécessitent une formule Premium.",
"premium_and_plans.bio_requires_premium_for_length": "Une bio de plus de {maxLength} caractères nécessite une formule Premium.",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "Vous ne pouvez pas activer un cadeau {premium_tier_name} avec un abonnement Visionary.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Vous ne pouvez pas utiliser d’emojis personnalisés en dehors de leur communauté d’origine sans Plutonium.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Vous ne pouvez pas utiliser de stickers personnalisés dans les MP sans Plutonium.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Vous ne pouvez pas utiliser de stickers personnalisés en dehors de leur communauté d’origine sans Plutonium.",
"premium_and_plans.discriminator_change_requires_premium": "La modification de votre discriminateur nécessite Plutonium.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Vous ne pouvez pas utiliser d’emojis personnalisés en dehors de leur communauté d’origine sans Premium.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Vous ne pouvez pas utiliser de stickers personnalisés dans les MP sans Premium.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Vous ne pouvez pas utiliser de stickers personnalisés en dehors de leur communauté d’origine sans Premium.",
"premium_and_plans.discriminator_change_requires_premium": "La modification de votre discriminateur nécessite Premium.",
"premium_and_plans.no_active_subscription": "Aucun abonnement actif.",
"premium_and_plans.visionary_required_for_discriminator": "L’abonnement à vie Visionary est nécessaire pour utiliser ce discriminateur.",
"rate_limits.accent_color_changed_too_often": "Vous avez changé votre couleur d’accentuation trop souvent récemment. Réessayez dans {minutes, plural, =1 {# minute} other {# minutes}}.",
@@ -391,14 +391,14 @@
"phone.verification_code_invalid": "Nevažeći kod za provjeru telefona.",
"phone.verification_needs_review": "Ovaj broj nismo mogli automatski provjeriti. Piši na [email protected] i netko iz našeg tima pregledat će tvoj račun.",
"phone.verification_required": "Potrebna je provjera telefona.",
"premium_and_plans.animated_avatars_require_premium": "Animirani avatari zahtijevaju pretplatu na Plutonium.",
"premium_and_plans.banners_require_premium": "Banneri zahtijevaju pretplatu na Plutonium.",
"premium_and_plans.bio_requires_premium_for_length": "Opis profila duži od {maxLength} znakova zahtijeva pretplatu na Plutonium.",
"premium_and_plans.animated_avatars_require_premium": "Animirani avatari zahtijevaju Premium pretplatu.",
"premium_and_plans.banners_require_premium": "Banneri zahtijevaju Premium pretplatu.",
"premium_and_plans.bio_requires_premium_for_length": "Opis profila duži od {maxLength} znakova zahtijeva Premium pretplatu.",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "Ne možeš iskoristiti {premium_tier_name} uz Visionary.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Ne možeš koristiti prilagođene emojije izvan njihovih izvornih zajednica bez pretplate na Plutonium.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Ne možeš koristiti prilagođene naljepnice u izravnim porukama bez pretplate na Plutonium.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Ne možeš koristiti prilagođene naljepnice izvan njihovih izvornih zajednica bez pretplate na Plutonium.",
"premium_and_plans.discriminator_change_requires_premium": "Promjena diskriminatora zahtijeva pretplatu na Plutonium.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Ne možeš koristiti prilagođene emojije izvan njihovih izvornih zajednica bez Premium pretplate.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Ne možeš koristiti prilagođene naljepnice u izravnim porukama bez Premium pretplate.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Ne možeš koristiti prilagođene naljepnice izvan njihovih izvornih zajednica bez Premium pretplate.",
"premium_and_plans.discriminator_change_requires_premium": "Promjena diskriminatora zahtijeva Premium pretplatu.",
"premium_and_plans.no_active_subscription": "Nema aktivne pretplate.",
"premium_and_plans.visionary_required_for_discriminator": "Za taj diskriminator moraš biti na doživotnom planu Visionary.",
"rate_limits.accent_color_changed_too_often": "U zadnje vrijeme prečesto mijenjaš boju naglaska. Pokušaj ponovno za {minutes, plural, one {# minutu} few {# minute} other {# minuta}}.",
@@ -391,14 +391,14 @@
"phone.verification_code_invalid": "電話認証コードが無効です。",
"phone.verification_needs_review": "この番号を自動で認証できませんでした。[email protected]にメールしていただければ、担当者がアカウントを確認します。",
"phone.verification_required": "電話認証が必要です。",
"premium_and_plans.animated_avatars_require_premium": "アニメーションアバターにはPlutoniumが必要です。",
"premium_and_plans.banners_require_premium": "バナーにはPlutoniumが必要です。",
"premium_and_plans.bio_requires_premium_for_length": "{maxLength}文字を超える自己紹介にはPlutoniumが必要です。",
"premium_and_plans.animated_avatars_require_premium": "アニメーションアバターにはプレミアムが必要です。",
"premium_and_plans.banners_require_premium": "バナーにはプレミアムが必要です。",
"premium_and_plans.bio_requires_premium_for_length": "{maxLength}文字を超える自己紹介にはプレミアムが必要です。",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "Visionaryでは{premium_tier_name}を引き換えられません。",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Plutoniumをお持ちでない場合は、元のコミュニティ以外でカスタム絵文字を使えません。",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Plutoniumをお持ちでない場合は、DMでカスタムスタンプを使えません。",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Plutoniumをお持ちでない場合は、元のコミュニティ以外でカスタムスタンプを使えません。",
"premium_and_plans.discriminator_change_requires_premium": "識別子の変更にはPlutoniumが必要です。",
"premium_and_plans.custom_emojis_outside_source_require_premium": "プレミアムをお持ちでない場合は、元のコミュニティ以外でカスタム絵文字を使えません。",
"premium_and_plans.custom_stickers_in_dms_require_premium": "プレミアムをお持ちでない場合は、DMでカスタムスタンプを使えません。",
"premium_and_plans.custom_stickers_outside_source_require_premium": "プレミアムをお持ちでない場合は、元のコミュニティ以外でカスタムスタンプを使えません。",
"premium_and_plans.discriminator_change_requires_premium": "識別子の変更にはプレミアムが必要です。",
"premium_and_plans.no_active_subscription": "有効なサブスクリプションがありません。",
"premium_and_plans.visionary_required_for_discriminator": "その識別子を使うには、Visionaryライフタイムプランに加入している必要があります。",
"rate_limits.accent_color_changed_too_often": "アクセントカラーの変更回数が多すぎます。{minutes, plural, other {#分}}後にもう一度お試しください。",
@@ -391,14 +391,14 @@
"phone.verification_code_invalid": "전화 인증 코드가 올바르지 않아요.",
"phone.verification_needs_review": "이 번호를 자동으로 인증하지 못했어요. [email protected]으로 메일을 보내면 담당자가 회원님 계정을 검토해 드려요.",
"phone.verification_required": "전화 인증이 필요해요.",
"premium_and_plans.animated_avatars_require_premium": "움직이는 아바타는 Plutonium이 필요해요.",
"premium_and_plans.banners_require_premium": "배너는 Plutonium이 필요해요.",
"premium_and_plans.bio_requires_premium_for_length": "{maxLength}자가 넘는 소개글을 쓰려면 Plutonium이 필요해요.",
"premium_and_plans.animated_avatars_require_premium": "움직이는 아바타는 프리미엄이 필요해요.",
"premium_and_plans.banners_require_premium": "배너는 프리미엄이 필요해요.",
"premium_and_plans.bio_requires_premium_for_length": "{maxLength}자가 넘는 소개글을 쓰려면 프리미엄이 필요해요.",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "Visionary 이용 중에는 {premium_tier_name}을 사용할 수 없어요.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Plutonium 없이는 원본 커뮤니티 외부에서 커스텀 이모지를 사용할 수 없어요.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Plutonium 없이는 DM에서 커스텀 스티커를 사용할 수 없어요.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Plutonium 없이는 원본 커뮤니티 외부에서 커스텀 스티커를 사용할 수 없어요.",
"premium_and_plans.discriminator_change_requires_premium": "식별자를 변경하려면 Plutonium이 필요해요.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "프리미엄 없이는 원본 커뮤니티 외부에서 커스텀 이모지를 사용할 수 없어요.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "프리미엄 없이는 DM에서 커스텀 스티커를 사용할 수 없어요.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "프리미엄 없이는 원본 커뮤니티 외부에서 커스텀 스티커를 사용할 수 없어요.",
"premium_and_plans.discriminator_change_requires_premium": "식별자를 변경하려면 프리미엄이 필요해요.",
"premium_and_plans.no_active_subscription": "활성화된 구독이 없어요.",
"premium_and_plans.visionary_required_for_discriminator": "해당 식별자를 사용하려면 Visionary 평생 요금제를 이용해야 해요.",
"rate_limits.accent_color_changed_too_often": "최근에 강조 색상을 너무 자주 변경했어요. {minutes, plural, other {#분}} 후에 다시 시도해 주세요.",
@@ -391,14 +391,14 @@
"phone.verification_code_invalid": "Cod de verificare telefonică invalid.",
"phone.verification_needs_review": "Nu am putut verifica automat acest număr. Scrie la [email protected] și o persoană îți va examina contul.",
"phone.verification_required": "Este necesară verificarea telefonului.",
"premium_and_plans.animated_avatars_require_premium": "Avatarele animate necesită Plutonium.",
"premium_and_plans.banners_require_premium": "Bannerele necesită Plutonium.",
"premium_and_plans.bio_requires_premium_for_length": "O biografie mai lungă de {maxLength} caractere necesită Plutonium.",
"premium_and_plans.animated_avatars_require_premium": "Avatarele animate necesită Premium.",
"premium_and_plans.banners_require_premium": "Bannerele necesită Premium.",
"premium_and_plans.bio_requires_premium_for_length": "O biografie mai lungă de {maxLength} caractere necesită Premium.",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "Nu poți revendica {premium_tier_name} cu Visionary.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Nu poți folosi emoji personalizate din afara comunităților sursă fără Plutonium.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Nu poți folosi stickere personalizate în DM-uri fără Plutonium.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Nu poți folosi stickere personalizate din afara comunităților sursă fără Plutonium.",
"premium_and_plans.discriminator_change_requires_premium": "Schimbarea discriminatorului necesită Plutonium.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Nu poți folosi emoji personalizate din afara comunităților sursă fără Premium.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Nu poți folosi stickere personalizate în DM-uri fără Premium.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Nu poți folosi stickere personalizate din afara comunităților sursă fără Premium.",
"premium_and_plans.discriminator_change_requires_premium": "Schimbarea discriminatorului necesită Premium.",
"premium_and_plans.no_active_subscription": "Niciun abonament activ.",
"premium_and_plans.visionary_required_for_discriminator": "Trebuie să ai abonamentul Visionary pe viață pentru a folosi acel discriminator.",
"rate_limits.accent_color_changed_too_often": "Ți-ai schimbat culoarea de accent prea des recent. Încearcă din nou peste {minutes, plural, one {# minut} few {# minute} other {# de minute}}.",
@@ -391,14 +391,14 @@
"phone.verification_code_invalid": "Неверный код подтверждения телефона.",
"phone.verification_needs_review": "Нам не удалось подтвердить этот номер автоматически. Напиши на [email protected], и твой аккаунт проверит человек.",
"phone.verification_required": "Требуется подтверждение телефона.",
"premium_and_plans.animated_avatars_require_premium": "Для анимированных аватаров нужен Plutonium.",
"premium_and_plans.banners_require_premium": "Для баннеров нужен Plutonium.",
"premium_and_plans.bio_requires_premium_for_length": "Для биографии длиннее {maxLength} символов нужен Plutonium.",
"premium_and_plans.animated_avatars_require_premium": "Для анимированных аватаров нужен Премиум.",
"premium_and_plans.banners_require_premium": "Для баннеров нужен Премиум.",
"premium_and_plans.bio_requires_premium_for_length": "Для биографии длиннее {maxLength} символов нужен Премиум.",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "Нельзя активировать {premium_tier_name}, если у тебя уже есть Visionary.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Без Plutonium нельзя использовать пользовательские эмодзи за пределами исходных сообществ.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Без Plutonium нельзя использовать пользовательские стикеры в ЛС.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Без Plutonium нельзя использовать пользовательские стикеры за пределами исходных сообществ.",
"premium_and_plans.discriminator_change_requires_premium": "Для смены дискриминатора нужен Plutonium.",
"premium_and_plans.custom_emojis_outside_source_require_premium": "Без Премиума нельзя использовать пользовательские эмодзи за пределами исходных сообществ.",
"premium_and_plans.custom_stickers_in_dms_require_premium": "Без Премиума нельзя использовать пользовательские стикеры в ЛС.",
"premium_and_plans.custom_stickers_outside_source_require_premium": "Без Премиума нельзя использовать пользовательские стикеры за пределами исходных сообществ.",
"premium_and_plans.discriminator_change_requires_premium": "Для смены дискриминатора нужен Премиум.",
"premium_and_plans.no_active_subscription": "Нет активной подписки.",
"premium_and_plans.visionary_required_for_discriminator": "Использовать этот дискриминатор можно только с пожизненным тарифом Visionary.",
"rate_limits.accent_color_changed_too_often": "Ты слишком часто меняешь акцентный цвет. Попробуй ещё раз через {minutes} {minutes, plural, one {минуту} few {минуты} many {минут} other {минуты}}.",
@@ -391,14 +391,14 @@
"phone.verification_code_invalid": "无效的手机验证码。",
"phone.verification_needs_review": "我们无法自动验证这个号码。请发送邮件至 [email protected],会有工作人员审核你的账号。",
"phone.verification_required": "需要手机号码验证。",
"premium_and_plans.animated_avatars_require_premium": "动态头像需要 Plutonium 会员。",
"premium_and_plans.banners_require_premium": "横幅需要 Plutonium 会员。",
"premium_and_plans.bio_requires_premium_for_length": "个人简介超过 {maxLength} 个字符需要 Plutonium 会员。",
"premium_and_plans.animated_avatars_require_premium": "动态头像需要高级会员。",
"premium_and_plans.banners_require_premium": "横幅需要高级会员。",
"premium_and_plans.bio_requires_premium_for_length": "个人简介超过 {maxLength} 个字符需要高级会员。",
"premium_and_plans.cannot_redeem_plutonium_with_visionary": "无法使用 Visionary 兑换 {premium_tier_name}。",
"premium_and_plans.custom_emojis_outside_source_require_premium": "没有 Plutonium 会员,无法在来源社区之外使用自定义表情。",
"premium_and_plans.custom_stickers_in_dms_require_premium": "没有 Plutonium 会员,无法在私信中使用自定义贴纸。",
"premium_and_plans.custom_stickers_outside_source_require_premium": "没有 Plutonium 会员,无法在来源社区之外使用自定义贴纸。",
"premium_and_plans.discriminator_change_requires_premium": "修改识别码需要 Plutonium 会员。",
"premium_and_plans.custom_emojis_outside_source_require_premium": "没有高级会员,无法在来源社区之外使用自定义表情。",
"premium_and_plans.custom_stickers_in_dms_require_premium": "没有高级会员,无法在私信中使用自定义贴纸。",
"premium_and_plans.custom_stickers_outside_source_require_premium": "没有高级会员,无法在来源社区之外使用自定义贴纸。",
"premium_and_plans.discriminator_change_requires_premium": "修改识别码需要高级会员。",
"premium_and_plans.no_active_subscription": "没有有效的订阅。",
"premium_and_plans.visionary_required_for_discriminator": "你必须拥有 Visionary 终身计划才能使用该识别码。",
"rate_limits.accent_color_changed_too_often": "你最近修改强调色过于频繁。请在 {minutes, plural, other {# 分钟}}后重试。",
+1
View File
@@ -19,6 +19,7 @@ interface SchemaMetadata {
bitflagValues?: Array<BitflagEntry>;
format?: string;
preserveEmptyValues?: boolean;
preserveNullFields?: boolean;
}
export const schemaMetadata = z.registry<SchemaMetadata>();
@@ -23,6 +23,10 @@ import {
GatewayRolloutConfigResponse,
GatewayRolloutConfigUpdateRequest,
} from '@fluxer/schema/src/domains/admin/GatewayRolloutSchemas';
import {
InstanceBillingResponse,
InstanceBillingUpdateRequest,
} from '@fluxer/schema/src/domains/admin/InstanceBillingSchemas';
import {
ProfileTimezoneConfigResponse,
ProfileTimezoneConfigUpdateRequest,
@@ -67,6 +71,7 @@ import {
withOpenApiType,
} from '@fluxer/schema/src/primitives/SchemaPrimitives';
import {EmailType} from '@fluxer/schema/src/primitives/UserValidators';
import {schemaMetadata} from '@fluxer/schema/src/SchemaMetadata';
import {z} from 'zod';
const ReportStatusSchema = withOpenApiType(
@@ -504,6 +509,8 @@ const AppPublicConfigResponse = z.object({
theme_color: z.string().nullable(),
status_page_url: z.string().nullable(),
status_page_incident_history_url: z.string().nullable(),
premium_product_name: z.string(),
premium_info_url: z.string().nullable(),
}),
setup: z.object({
configured: z.boolean(),
@@ -517,6 +524,15 @@ const AppPublicConfigResponse = z.object({
}),
});
function isAbsoluteHttpUrl(value: string): boolean {
try {
const url = new URL(value);
return (url.protocol === 'http:' || url.protocol === 'https:') && url.hostname.length > 0;
} catch {
return false;
}
}
const AppPublicConfigUpdateRequest = z.object({
branding: z
.object({
@@ -529,7 +545,10 @@ const AppPublicConfigUpdateRequest = z.object({
theme_color: z.string().trim().max(64).nullish(),
status_page_url: z.string().trim().max(2048).nullish(),
status_page_incident_history_url: z.string().trim().max(2048).nullish(),
premium_product_name: z.string().trim().min(1).max(40).nullable().optional(),
premium_info_url: z.string().trim().max(2048).refine(isAbsoluteHttpUrl).nullish(),
})
.register(schemaMetadata, {preserveNullFields: true})
.nullish(),
setup: z
.object({
@@ -668,6 +687,7 @@ export const InstanceConfigResponse = z.object({
policy: InstancePolicyResponse,
integrations: InstanceIntegrationsResponse,
media: InstanceMediaResponse,
billing: InstanceBillingResponse,
});
export type InstanceConfigResponse = z.infer<typeof InstanceConfigResponse>;
@@ -804,6 +824,7 @@ export const InstanceConfigUpdateRequest = z.object({
})
.nullish(),
policy: InstancePolicyUpdateSchema.nullish(),
billing: InstanceBillingUpdateRequest.nullish(),
});
export type InstanceConfigUpdateRequest = z.infer<typeof InstanceConfigUpdateRequest>;
@@ -0,0 +1,127 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {PremiumCurrency} from '@fluxer/schema/src/domains/premium/PremiumSchemas';
import {schemaMetadata} from '@fluxer/schema/src/SchemaMetadata';
import {z} from 'zod';
export const BILLING_MAX_CURRENCIES = 64;
export const BILLING_MAX_COUNTRY_CURRENCIES = 300;
export const BILLING_MAX_LEGACY_SLOTS = 256;
export const BILLING_MAX_LEGACY_PRICES_PER_SLOT = 32;
export const BillingCountryCodeSchema = z.string().regex(/^[A-Z]{2}$/);
export const StripePriceIdSchema = z
.string()
.max(255)
.regex(/^price_[A-Za-z0-9]+$/);
export const BillingLegacyPriceSlotSchema = z.string().regex(/^(monthly|yearly|gift_1_month|gift_1_year)_[A-Z]{3}$/);
export const BillingCatalogModeSchema = z.enum(['env', 'operator']);
export type BillingCatalogMode = z.infer<typeof BillingCatalogModeSchema>;
function maxKeys(max: number) {
return (value: Record<string, unknown>) => Object.keys(value).length <= max;
}
export const BillingPriceSetResponse = z.object({
monthly: StripePriceIdSchema.nullable(),
yearly: StripePriceIdSchema.nullable(),
gift_1_month: StripePriceIdSchema.nullable(),
gift_1_year: StripePriceIdSchema.nullable(),
});
export type BillingPriceSetResponse = z.infer<typeof BillingPriceSetResponse>;
export const BillingPriceSetUpdateRequest = z.object({
monthly: StripePriceIdSchema.nullish(),
yearly: StripePriceIdSchema.nullish(),
gift_1_month: StripePriceIdSchema.nullish(),
gift_1_year: StripePriceIdSchema.nullish(),
});
export type BillingPriceSetUpdateRequest = z.infer<typeof BillingPriceSetUpdateRequest>;
const BillingPricesSchema = <T extends z.ZodType>(entry: T) =>
z
.record(PremiumCurrency, entry)
.refine(maxKeys(BILLING_MAX_CURRENCIES), {message: `At most ${BILLING_MAX_CURRENCIES} currencies`});
export const BillingCountryCurrenciesSchema = z
.record(BillingCountryCodeSchema, PremiumCurrency)
.refine(maxKeys(BILLING_MAX_COUNTRY_CURRENCIES), {
message: `At most ${BILLING_MAX_COUNTRY_CURRENCIES} country mappings`,
});
export const BillingLegacyPricesSchema = z
.record(BillingLegacyPriceSlotSchema, z.array(StripePriceIdSchema).max(BILLING_MAX_LEGACY_PRICES_PER_SLOT))
.refine(maxKeys(BILLING_MAX_LEGACY_SLOTS), {message: `At most ${BILLING_MAX_LEGACY_SLOTS} legacy price slots`});
export const InstanceBillingResponse = z.object({
enabled: z.boolean().nullable(),
effective_enabled: z.boolean(),
stripe_secret_key_set: z.boolean(),
stripe_webhook_secret_set: z.boolean(),
stripe_secret_key_stored: z.boolean(),
stripe_webhook_secret_stored: z.boolean(),
automatic_tax: z.boolean().nullable(),
tax_id_collection: z.boolean().nullable(),
terms_consent_required: z.boolean().nullable(),
effective_automatic_tax: z.boolean(),
effective_tax_id_collection: z.boolean(),
effective_terms_consent_required: z.boolean(),
default_currency: PremiumCurrency.nullable(),
prices: z.record(z.string(), BillingPriceSetResponse).nullable(),
country_currencies: z.record(z.string(), z.string()).nullable(),
legacy_prices: z.record(z.string(), z.array(z.string())).nullable(),
billing_active: z.boolean(),
stripe_serviceable: z.boolean(),
catalog_mode: BillingCatalogModeSchema,
webhook_url: z.string(),
});
export type InstanceBillingResponse = z.infer<typeof InstanceBillingResponse>;
export const InstanceBillingUpdateRequest = z
.object({
enabled: z.boolean().nullish(),
stripe_secret_key: z.string().trim().min(1).max(4096).nullish(),
stripe_webhook_secret: z.string().trim().min(1).max(4096).nullish(),
automatic_tax: z.boolean().nullish(),
tax_id_collection: z.boolean().nullish(),
terms_consent_required: z.boolean().nullish(),
default_currency: PremiumCurrency.nullish(),
prices: BillingPricesSchema(BillingPriceSetUpdateRequest).nullish(),
country_currencies: BillingCountryCurrenciesSchema.nullish(),
legacy_prices: BillingLegacyPricesSchema.nullish(),
})
.register(schemaMetadata, {preserveNullFields: true});
export type InstanceBillingUpdateRequest = z.infer<typeof InstanceBillingUpdateRequest>;
export const StoredBillingConfigSchema = z.object({
enabled: z.boolean().nullable().default(null),
stripe_secret_key: z
.string()
.trim()
.nullable()
.default(null)
.transform((value) => value || null),
stripe_webhook_secret: z
.string()
.trim()
.nullable()
.default(null)
.transform((value) => value || null),
automatic_tax: z.boolean().nullable().default(null),
tax_id_collection: z.boolean().nullable().default(null),
terms_consent_required: z.boolean().nullable().default(null),
default_currency: PremiumCurrency.nullable().default(null),
prices: BillingPricesSchema(
z.object({
monthly: StripePriceIdSchema.nullable().default(null),
yearly: StripePriceIdSchema.nullable().default(null),
gift_1_month: StripePriceIdSchema.nullable().default(null),
gift_1_year: StripePriceIdSchema.nullable().default(null),
}),
)
.nullable()
.default(null),
country_currencies: BillingCountryCurrenciesSchema.nullable().default(null),
legacy_prices: BillingLegacyPricesSchema.nullable().default(null),
});
export type StoredBillingConfig = z.output<typeof StoredBillingConfigSchema>;
@@ -39,6 +39,8 @@ export const InstanceBrandingSchema = z
.string()
.nullable()
.describe('Optional public status page incident history URL'),
premium_product_name: z.string().describe('Name of the premium tier shown by client applications'),
premium_info_url: z.string().nullable().describe('Optional absolute URL of a page describing the premium tier'),
})
.describe('Branding values safe to expose to clients');
export type InstanceBranding = z.infer<typeof InstanceBrandingSchema>;
@@ -104,7 +106,13 @@ export type InstanceCaptcha = z.infer<typeof InstanceCaptchaSchema>;
export const InstanceFeaturesSchema = z
.object({
voice_enabled: z.boolean().describe('Whether voice/video calling is enabled'),
stripe_enabled: z.boolean().describe('Whether Stripe payments are enabled'),
stripe_enabled: z.boolean().describe('Whether premium purchases through Stripe are available'),
premium_enabled: z
.boolean()
.describe('Whether this instance has a premium tier, so premium status, gifts and perks apply'),
stripe_serviceable: z
.boolean()
.describe('Whether existing Stripe subscriptions can be managed, cancelled and billed on this instance'),
self_hosted: z.boolean().describe('Whether this is a self-hosted instance'),
presigned_attachment_uploads: z.boolean().describe('Whether clients can request presigned attachment upload URLs'),
emails_enabled: z.boolean().describe('Whether the instance sends emails (verification, password reset, etc.)'),
@@ -4,7 +4,7 @@ import {createStringType} from '@fluxer/schema/src/primitives/SchemaPrimitives';
import {UserPremiumTypesSchema} from '@fluxer/schema/src/primitives/UserSettingsValidators';
import {z} from 'zod';
export const PremiumCurrency = z.enum(['USD', 'EUR', 'BRL', 'DKK', 'INR', 'NOK', 'PLN', 'SEK', 'TRY']);
export const PremiumCurrency = z.string().regex(/^[A-Z]{3}$/);
export type PremiumCurrency = z.infer<typeof PremiumCurrency>;
@@ -36,7 +36,9 @@ export const PriceIdsResponse = z.object({
.describe('Gift 1 month price amount in the currency minor unit'),
gift_1_year_amount_minor: z.number().int().nullish().describe('Gift 1 year price amount in the currency minor unit'),
currency: PremiumCurrency.describe('Currency for the prices'),
gift_currency: PremiumCurrency.describe('Currency for gift prices'),
gift_currency: PremiumCurrency.nullable().describe(
'Currency for gift prices, null when no gift prices are configured',
),
});
export type PriceIdsResponse = z.infer<typeof PriceIdsResponse>;