feat: add subscription management for web (#1494)

This commit is contained in:
Huang Xin
2025-06-30 00:33:36 +08:00
committed by GitHub
parent 280cb75ca4
commit bc36da6b25
32 changed files with 1858 additions and 534 deletions
@@ -183,35 +183,18 @@
"Sign in with GitHub": "تسجيل الدخول عبر GitHub",
"Account": "الحساب",
"Failed to delete user. Please try again later.": "فشل حذف المستخدم. يرجى المحاولة مرة أخرى لاحقًا.",
"Unlimited Offline/Online Reading": "القراءة بدون حدود للكتب المتوفر على الجهاز أو عبر الانترنت",
"Unlimited Cloud Sync Devices": "مزامنة عبر السحابة لعدد غير محدود من الأجهزة",
"Essential Text-to-Speech Voices": "أصوات أساسية لتحويل النص إلى كلام",
"DeepL Free Access": "وصول مجاني لـ DeepL",
"Community Support": "دعم المجتمع",
"500 MB Cloud Sync Space": "مزامنة سحابية بمساحة تخزين 500 ميجابايت",
"Includes All Free Tier Benefits": "تشمل جميع مزايا الفئة المجانية",
"AI Summaries": "ملخصات الذكاء الاصطناعي",
"AI Translations": "ترجمات الذكاء الاصطناعي",
"Priority Support": "دعم ذو أولوية",
"DeepL Pro Access": "وصول لميزات DeepL Pro",
"Expanded Text-to-Speech Voices": "أصوات موسعة لتحويل النص إلى كلام",
"2000 MB Cloud Sync Space": "مزامنة سحابية بمساحة تخزين 2000 ميجابايت",
"Includes All Plus Tier Benefits": "تشمل جميع مزايا فئة Plus",
"Unlimited AI Summaries": "ملخصات ذكاء اصطناعي غير محدودة",
"Unlimited AI Translations": "ترجمات ذكاء اصطناعي غير محدودة",
"Unlimited DeepL Pro Access": "وصول غير محدود لميزات DeepL Pro",
"Advanced AI Tools": "أدوات ذكاء اصطناعي متقدمة",
"Early Feature Access": "وصول مبكر للميزات",
"10 GB Cloud Sync Space": "مزامنة سحابية بمساحة تخزين 10 جيجابايت",
"Loading profile...": "جارٍ تحميل الملف الشخصي...",
"Features": "الميزات",
"Delete Account": "حذف الحساب",
"Delete Your Account?": "حذف حسابك؟",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "لا يمكن التراجع عن هذا الإجراء. سيتم حذف جميع بياناتك في السحابة بشكل دائم.",
"Delete Permanently": "حذف نهائي",
"Free Tier": "الفئة المجانية",
"Plus Tier": "فئة Plus",
"Pro Tier": "فئة Pro",
"RTL Direction": "الاتجاه من اليمين إلى اليسار",
"Maximum Column Height": "الارتفاع الأقصى للعمود",
"Maximum Column Width": "العرض الأقصى للعمود",
@@ -393,5 +376,44 @@
"Show Remaining Pages": "عرض الصفحات المتبقية",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "إدارة الاشتراك",
"Coming Soon": "قريبًا",
"Upgrade to {{plan}}": "الترقية إلى {{plan}}",
"Upgrade to Plus or Pro": "الترقية إلى Plus أو Pro",
"Current Plan": "الخطة الحالية",
"Plan Limits": "حدود الخطة",
"Available Plans": "الخطط المتاحة",
"{{current}} of {{all}}": "{{current}} من {{all}}",
"Failed to manage subscription. Please try again later.": "فشل في إدارة الاشتراك. يرجى المحاولة مرة أخرى لاحقًا.",
"Processing your payment...": "جارٍ معالجة الدفع...",
"Please wait while we confirm your subscription.": "يرجى الانتظار بينما نقوم بتأكيد اشتراكك.",
"Payment Processing": "معالجة الدفع",
"Your payment is being processed. This usually takes a few moments.": "يتم الآن معالجة الدفع الخاص بك. عادةً ما يستغرق ذلك بضع لحظات.",
"Payment Failed": "فشل الدفع",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "تعذر علينا معالجة اشتراكك. يرجى المحاولة مرة أخرى أو التواصل مع الدعم إذا استمرت المشكلة.",
"Back to Profile": "العودة إلى الملف الشخصي",
"Subscription Successful!": "تم الاشتراك بنجاح!",
"Thank you for your subscription! Your payment has been processed successfully.": "شكرًا لاشتراكك! تم معالجة الدفع بنجاح.",
"Email:": "البريد الإلكتروني:",
"Plan:": "الخطة:",
"Amount:": "المبلغ:",
"Subscription ID:": "رقم الاشتراك:",
"Go to Library": "الانتقال إلى المكتبة",
"Need help? Contact our support team at support@readest.com": "تحتاج مساعدة؟ تواصل مع فريق الدعم على support@readest.com",
"Free Plan": "الخطة المجانية",
"month": "شهر",
"Unlimited Text-to-Speech Hours": "ساعات تحويل النص إلى كلام غير محدودة",
"DeepL Free Access (10K characters/day)": "وصول مجاني إلى DeepL (10 آلاف حرف يوميًا)",
"AI Translations (per day)": "ترجمات بالذكاء الاصطناعي (يوميًا)",
"Cloud Storage": "تخزين سحابي",
"Plus Plan": "خطة Plus",
"Includes All Free Plan Benefits": "تتضمن جميع مزايا الخطة المجانية",
"Basic AI Translations": "ترجمات أساسية بالذكاء الاصطناعي",
"DeepL Pro Access (50K characters/day)": "وصول احترافي إلى DeepL (50 ألف حرف يوميًا)",
"2 GB Cloud Sync Space": "2 جيجابايت مساحة مزامنة سحابية",
"Pro Plan": "خطة Pro",
"Includes All Plus Plan Benefits": "تتضمن جميع مزايا خطة Plus",
"More AI Translations": "المزيد من الترجمات بالذكاء الاصطناعي",
"DeepL Pro Access (200K characters/day)": "وصول احترافي إلى DeepL (200 ألف حرف يوميًا)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "Mit GitHub anmelden",
"Account": "Konto",
"Failed to delete user. Please try again later.": "Benutzer konnte nicht gelöscht werden. Bitte versuchen Sie es später erneut.",
"Unlimited Offline/Online Reading": "Unbegrenztes Offline/Online Lesen",
"Unlimited Cloud Sync Devices": "Unbegrenzte Cloud-Synchronisierungsgeräte",
"Essential Text-to-Speech Voices": "Grundlegende Text-zu-Sprache-Stimmen",
"DeepL Free Access": "Kostenloser DeepL-Zugang",
"Community Support": "Community-Support",
"500 MB Cloud Sync Space": "500 MB Cloud-Synchronisierungsspeicher",
"Includes All Free Tier Benefits": "Beinhaltet alle Vorteile der kostenlosen Stufe",
"AI Summaries": "KI-Zusammenfassungen",
"AI Translations": "KI-Übersetzungen",
"Priority Support": "Bevorzugter Support",
"DeepL Pro Access": "DeepL Pro-Zugang",
"Expanded Text-to-Speech Voices": "Erweiterte Text-zu-Sprache-Stimmen",
"2000 MB Cloud Sync Space": "2000 MB Cloud-Synchronisierungsspeicher",
"Includes All Plus Tier Benefits": "Beinhaltet alle Vorteile der Plus-Stufe",
"Unlimited AI Summaries": "Unbegrenzte KI-Zusammenfassungen",
"Unlimited AI Translations": "Unbegrenzte KI-Übersetzungen",
"Unlimited DeepL Pro Access": "Unbegrenzter DeepL Pro-Zugang",
"Advanced AI Tools": "Fortgeschrittene KI-Tools",
"Early Feature Access": "Früher Zugang zu neuen Funktionen",
"10 GB Cloud Sync Space": "10 GB Cloud-Synchronisierungsspeicher",
"Loading profile...": "Profil wird geladen...",
"Features": "Funktionen",
"Delete Account": "Konto löschen",
"Delete Your Account?": "Ihr Konto löschen?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Diese Aktion kann nicht rückgängig gemacht werden. Alle Ihre Daten in der Cloud werden dauerhaft gelöscht.",
"Delete Permanently": "Dauerhaft löschen",
"Free Tier": "Kostenlose Stufe",
"Plus Tier": "Plus-Stufe",
"Pro Tier": "Pro-Stufe",
"RTL Direction": "RTL-Richtung",
"Maximum Column Height": "Maximale Spaltenhöhe",
"Maximum Column Width": "Maximale Spaltenbreite",
@@ -377,5 +360,44 @@
"Show Remaining Pages": "Verbleibende Seiten anzeigen",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "Abo verwalten",
"Coming Soon": "Demnächst verfügbar",
"Upgrade to {{plan}}": "Upgrade auf {{plan}}",
"Upgrade to Plus or Pro": "Upgrade auf Plus oder Pro",
"Current Plan": "Aktueller Tarif",
"Plan Limits": "Tariflimits",
"Available Plans": "Verfügbare Tarife",
"{{current}} of {{all}}": "{{current}} von {{all}}",
"Failed to manage subscription. Please try again later.": "Verwaltung des Abos fehlgeschlagen. Bitte versuchen Sie es später erneut.",
"Processing your payment...": "Zahlung wird verarbeitet...",
"Please wait while we confirm your subscription.": "Bitte warten Sie, während wir Ihr Abo bestätigen.",
"Payment Processing": "Zahlung wird verarbeitet",
"Your payment is being processed. This usually takes a few moments.": "Ihre Zahlung wird verarbeitet. Dies dauert normalerweise nur wenige Augenblicke.",
"Payment Failed": "Zahlung fehlgeschlagen",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Ihr Abo konnte nicht verarbeitet werden. Bitte versuchen Sie es erneut oder kontaktieren Sie den Support, falls das Problem weiterhin besteht.",
"Back to Profile": "Zurück zum Profil",
"Subscription Successful!": "Abo erfolgreich!",
"Thank you for your subscription! Your payment has been processed successfully.": "Vielen Dank für Ihr Abo! Die Zahlung wurde erfolgreich verarbeitet.",
"Email:": "E-Mail:",
"Plan:": "Tarif:",
"Amount:": "Betrag:",
"Subscription ID:": "Abo-ID:",
"Go to Library": "Zur Bibliothek",
"Need help? Contact our support team at support@readest.com": "Brauchen Sie Hilfe? Kontaktieren Sie unser Support-Team unter support@readest.com",
"Free Plan": "Gratis-Tarif",
"month": "Monat",
"Unlimited Text-to-Speech Hours": "Unbegrenzte Text-to-Speech-Stunden",
"DeepL Free Access (10K characters/day)": "Kostenfreier DeepL-Zugang (10.000 Zeichen/Tag)",
"AI Translations (per day)": "KI-Übersetzungen (pro Tag)",
"Cloud Storage": "Cloud-Speicher",
"Plus Plan": "Plus-Tarif",
"Includes All Free Plan Benefits": "Enthält alle Vorteile des Gratis-Tarifs",
"Basic AI Translations": "Basis-KI-Übersetzungen",
"DeepL Pro Access (50K characters/day)": "DeepL Pro-Zugang (50.000 Zeichen/Tag)",
"2 GB Cloud Sync Space": "2 GB Cloud-Speicherplatz",
"Pro Plan": "Pro-Tarif",
"Includes All Plus Plan Benefits": "Enthält alle Vorteile des Plus-Tarifs",
"More AI Translations": "Mehr KI-Übersetzungen",
"DeepL Pro Access (200K characters/day)": "DeepL Pro-Zugang (200.000 Zeichen/Tag)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "Σύνδεση με GitHub",
"Account": "Λογαριασμός",
"Failed to delete user. Please try again later.": "Αποτυχία διαγραφής χρήστη. Παρακαλώ δοκιμάστε ξανά αργότερα.",
"Unlimited Offline/Online Reading": "Απεριόριστη ανάγνωση εκτός/εντός σύνδεσης",
"Unlimited Cloud Sync Devices": "Απεριόριστες συσκευές συγχρονισμού Cloud",
"Essential Text-to-Speech Voices": "Βασικές φωνές μετατροπής κειμένου σε ομιλία",
"DeepL Free Access": "Δωρεάν πρόσβαση DeepL",
"Community Support": "Υποστήριξη κοινότητας",
"500 MB Cloud Sync Space": "500 MB χώρος συγχρονισμού Cloud",
"Includes All Free Tier Benefits": "Περιλαμβάνει όλα τα οφέλη της δωρεάν βαθμίδας",
"AI Summaries": "Περιλήψεις AI",
"AI Translations": "Μεταφράσεις AI",
"Priority Support": "Υποστήριξη προτεραιότητας",
"DeepL Pro Access": "Πρόσβαση DeepL Pro",
"Expanded Text-to-Speech Voices": "Διευρυμένες φωνές μετατροπής κειμένου σε ομιλία",
"2000 MB Cloud Sync Space": "2000 MB χώρος συγχρονισμού Cloud",
"Includes All Plus Tier Benefits": "Περιλαμβάνει όλα τα οφέλη της βαθμίδας Plus",
"Unlimited AI Summaries": "Απεριόριστες περιλήψεις AI",
"Unlimited AI Translations": "Απεριόριστες μεταφράσεις AI",
"Unlimited DeepL Pro Access": "Απεριόριστη πρόσβαση DeepL Pro",
"Advanced AI Tools": "Προηγμένα εργαλεία AI",
"Early Feature Access": "Πρώιμη πρόσβαση σε λειτουργίες",
"10 GB Cloud Sync Space": "10 GB χώρος συγχρονισμού Cloud",
"Loading profile...": "Φόρτωση προφίλ...",
"Features": "Χαρακτηριστικά",
"Delete Account": "Διαγραφή λογαριασμού",
"Delete Your Account?": "Διαγραφή του λογαριασμού σας;",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Αυτή η ενέργεια δεν μπορεί να αναιρεθεί. Όλα τα δεδομένα σας στο cloud θα διαγραφούν μόνιμα.",
"Delete Permanently": "Μόνιμη διαγραφή",
"Free Tier": "Δωρεάν βαθμίδα",
"Plus Tier": "Βαθμίδα Plus",
"Pro Tier": "Βαθμίδα Pro",
"RTL Direction": "Κατεύθυνση RTL",
"Maximum Column Height": "Μέγιστο ύψος στήλης",
"Maximum Column Width": "Μέγιστο πλάτος στήλης",
@@ -377,5 +360,44 @@
"Show Remaining Pages": "Εμφάνιση υπολοίπων",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "Διαχείριση συνδρομής",
"Coming Soon": "Έρχεται σύντομα",
"Upgrade to {{plan}}": "Αναβάθμιση σε {{plan}}",
"Upgrade to Plus or Pro": "Αναβάθμιση σε Plus ή Pro",
"Current Plan": "Τρέχον πρόγραμμα",
"Plan Limits": "Όρια προγράμματος",
"Available Plans": "Διαθέσιμα προγράμματα",
"{{current}} of {{all}}": "{{current}} από {{all}}",
"Failed to manage subscription. Please try again later.": "Αποτυχία διαχείρισης της συνδρομής. Παρακαλώ δοκιμάστε ξανά αργότερα.",
"Processing your payment...": "Επεξεργασία πληρωμής...",
"Please wait while we confirm your subscription.": "Παρακαλώ περιμένετε όσο επιβεβαιώνουμε τη συνδρομή σας.",
"Payment Processing": "Επεξεργασία πληρωμής",
"Your payment is being processed. This usually takes a few moments.": "Η πληρωμή σας επεξεργάζεται. Συνήθως διαρκεί λίγες στιγμές.",
"Payment Failed": "Η πληρωμή απέτυχε",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Δεν ήταν δυνατή η επεξεργασία της συνδρομής σας. Παρακαλώ προσπαθήστε ξανά ή επικοινωνήστε με την υποστήριξη αν το πρόβλημα συνεχιστεί.",
"Back to Profile": "Επιστροφή στο προφίλ",
"Subscription Successful!": "Η συνδρομή ολοκληρώθηκε!",
"Thank you for your subscription! Your payment has been processed successfully.": "Σας ευχαριστούμε για τη συνδρομή σας! Η πληρωμή ολοκληρώθηκε με επιτυχία.",
"Email:": "Email:",
"Plan:": "Πρόγραμμα:",
"Amount:": "Ποσό:",
"Subscription ID:": "ID συνδρομής:",
"Go to Library": "Μετάβαση στη βιβλιοθήκη",
"Need help? Contact our support team at support@readest.com": "Χρειάζεστε βοήθεια; Επικοινωνήστε με την υποστήριξη στο support@readest.com",
"Free Plan": "Δωρεάν πρόγραμμα",
"month": "μήνας",
"Unlimited Text-to-Speech Hours": "Απεριόριστες ώρες μετατροπής κειμένου σε ομιλία",
"DeepL Free Access (10K characters/day)": "Δωρεάν πρόσβαση στο DeepL (10.000 χαρακτήρες/ημέρα)",
"AI Translations (per day)": "Μεταφράσεις AI (ανά ημέρα)",
"Cloud Storage": "Αποθήκευση στο cloud",
"Plus Plan": "Πρόγραμμα Plus",
"Includes All Free Plan Benefits": "Περιλαμβάνει όλα τα οφέλη του δωρεάν προγράμματος",
"Basic AI Translations": "Βασικές μεταφράσεις AI",
"DeepL Pro Access (50K characters/day)": "Pro πρόσβαση στο DeepL (50.000 χαρακτήρες/ημέρα)",
"2 GB Cloud Sync Space": "2 GB χώρος συγχρονισμού στο cloud",
"Pro Plan": "Πρόγραμμα Pro",
"Includes All Plus Plan Benefits": "Περιλαμβάνει όλα τα οφέλη του Plus προγράμματος",
"More AI Translations": "Περισσότερες μεταφράσεις AI",
"DeepL Pro Access (200K characters/day)": "Pro πρόσβαση στο DeepL (200.000 χαρακτήρες/ημέρα)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "Iniciar sesión con GitHub",
"Account": "Cuenta",
"Failed to delete user. Please try again later.": "Error al eliminar usuario. Por favor, inténtelo de nuevo más tarde.",
"Unlimited Offline/Online Reading": "Lectura sin límites en línea/sin conexión",
"Unlimited Cloud Sync Devices": "Sincronización ilimitada de dispositivos en la nube",
"Essential Text-to-Speech Voices": "Voces esenciales de texto a voz",
"DeepL Free Access": "Acceso gratuito a DeepL",
"Community Support": "Soporte comunitario",
"500 MB Cloud Sync Space": "500 MB de espacio de sincronización en la nube",
"Includes All Free Tier Benefits": "Incluye todos los beneficios del nivel gratuito",
"AI Summaries": "Resúmenes con IA",
"AI Translations": "Traducciones con IA",
"Priority Support": "Soporte prioritario",
"DeepL Pro Access": "Acceso a DeepL Pro",
"Expanded Text-to-Speech Voices": "Voces ampliadas de texto a voz",
"2000 MB Cloud Sync Space": "2000 MB de espacio de sincronización en la nube",
"Includes All Plus Tier Benefits": "Incluye todos los beneficios del nivel Plus",
"Unlimited AI Summaries": "Resúmenes ilimitados con IA",
"Unlimited AI Translations": "Traducciones ilimitadas con IA",
"Unlimited DeepL Pro Access": "Acceso ilimitado a DeepL Pro",
"Advanced AI Tools": "Herramientas avanzadas de IA",
"Early Feature Access": "Acceso anticipado a funciones",
"10 GB Cloud Sync Space": "10 GB de espacio de sincronización en la nube",
"Loading profile...": "Cargando perfil...",
"Features": "Características",
"Delete Account": "Eliminar cuenta",
"Delete Your Account?": "¿Eliminar tu cuenta?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Esta acción no se puede deshacer. Todos tus datos en la nube se eliminarán permanentemente.",
"Delete Permanently": "Eliminar permanentemente",
"Free Tier": "Nivel gratuito",
"Plus Tier": "Nivel Plus",
"Pro Tier": "Nivel Pro",
"RTL Direction": "Dirección RTL",
"Maximum Column Height": "Altura máxima de columna",
"Maximum Column Width": "Ancho máximo de columna",
@@ -381,5 +364,44 @@
"Show Remaining Pages": "Mostrar resto",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "Gestionar suscripción",
"Coming Soon": "Próximamente",
"Upgrade to {{plan}}": "Actualizar a {{plan}}",
"Upgrade to Plus or Pro": "Actualizar a Plus o Pro",
"Current Plan": "Plan actual",
"Plan Limits": "Límites del plan",
"Available Plans": "Planes disponibles",
"{{current}} of {{all}}": "{{current}} de {{all}}",
"Failed to manage subscription. Please try again later.": "No se pudo gestionar la suscripción. Por favor, inténtalo de nuevo más tarde.",
"Processing your payment...": "Procesando tu pago...",
"Please wait while we confirm your subscription.": "Espera mientras confirmamos tu suscripción.",
"Payment Processing": "Procesando pago",
"Payment Failed": "El pago ha fallado",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "No pudimos procesar tu suscripción. Inténtalo de nuevo o contacta con soporte si el problema persiste.",
"Back to Profile": "Volver al perfil",
"Subscription Successful!": "¡Suscripción exitosa!",
"Thank you for your subscription! Your payment has been processed successfully.": "¡Gracias por tu suscripción! Tu pago se ha procesado correctamente.",
"Email:": "Correo electrónico:",
"Plan:": "Plan:",
"Amount:": "Importe:",
"Subscription ID:": "ID de suscripción:",
"Go to Library": "Ir a la biblioteca",
"Need help? Contact our support team at support@readest.com": "¿Necesitas ayuda? Contacta con nuestro equipo de soporte en support@readest.com",
"Free Plan": "Plan gratuito",
"month": "mes",
"Unlimited Text-to-Speech Hours": "Horas ilimitadas de texto a voz",
"DeepL Free Access (10K characters/day)": "Acceso gratuito a DeepL (10.000 caracteres/día)",
"AI Translations (per day)": "Traducciones con IA (por día)",
"Cloud Storage": "Almacenamiento en la nube",
"Plus Plan": "Plan Plus",
"Includes All Free Plan Benefits": "Incluye todos los beneficios del plan gratuito",
"Basic AI Translations": "Traducciones básicas con IA",
"DeepL Pro Access (50K characters/day)": "Acceso Pro a DeepL (50.000 caracteres/día)",
"2 GB Cloud Sync Space": "2 GB de espacio de sincronización en la nube",
"Pro Plan": "Plan Pro",
"Includes All Plus Plan Benefits": "Incluye todos los beneficios del plan Plus",
"More AI Translations": "Más traducciones con IA",
"DeepL Pro Access (200K characters/day)": "Acceso Pro a DeepL (200.000 caracteres/día)",
"Your payment is being processed. This usually takes a few moments.": "Tu pago se está procesando. Normalmente tarda unos momentos."
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "Se connecter avec GitHub",
"Account": "Compte",
"Failed to delete user. Please try again later.": "Échec de la suppression de l'utilisateur. Veuillez réessayer plus tard.",
"Unlimited Offline/Online Reading": "Lecture illimitée hors ligne/en ligne",
"Unlimited Cloud Sync Devices": "Synchronisation cloud sur appareils illimitée",
"Essential Text-to-Speech Voices": "Voix de synthèse vocale essentielles",
"DeepL Free Access": "Accès gratuit à DeepL",
"Community Support": "Support communautaire",
"500 MB Cloud Sync Space": "500 Mo d'espace de synchronisation cloud",
"Includes All Free Tier Benefits": "Inclut tous les avantages du niveau gratuit",
"AI Summaries": "Résumés par IA",
"AI Translations": "Traductions par IA",
"Priority Support": "Support prioritaire",
"DeepL Pro Access": "Accès à DeepL Pro",
"Expanded Text-to-Speech Voices": "Voix de synthèse vocale étendues",
"2000 MB Cloud Sync Space": "2000 Mo d'espace de synchronisation cloud",
"Includes All Plus Tier Benefits": "Inclut tous les avantages du niveau Plus",
"Unlimited AI Summaries": "Résumés par IA illimités",
"Unlimited AI Translations": "Traductions par IA illimitées",
"Unlimited DeepL Pro Access": "Accès illimité à DeepL Pro",
"Advanced AI Tools": "Outils IA avancés",
"Early Feature Access": "Accès anticipé aux fonctionnalités",
"10 GB Cloud Sync Space": "10 Go d'espace de synchronisation cloud",
"Loading profile...": "Chargement du profil...",
"Features": "Fonctionnalités",
"Delete Account": "Supprimer le compte",
"Delete Your Account?": "Supprimer votre compte ?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Cette action est irréversible. Toutes vos données dans le cloud seront définitivement supprimées.",
"Delete Permanently": "Supprimer définitivement",
"Free Tier": "Niveau gratuit",
"Plus Tier": "Niveau Plus",
"Pro Tier": "Niveau Pro",
"RTL Direction": "Direction RTL",
"Maximum Column Height": "Hauteur maximale de colonne",
"Maximum Column Width": "Largeur maximale de colonne",
@@ -381,5 +364,44 @@
"Show Remaining Pages": "Voir restantes",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "Gérer labonnement",
"Coming Soon": "Bientôt disponible",
"Upgrade to {{plan}}": "Passer à {{plan}}",
"Upgrade to Plus or Pro": "Passer à Plus ou Pro",
"Current Plan": "Abonnement actuel",
"Plan Limits": "Limites de labonnement",
"Available Plans": "Abonnements disponibles",
"{{current}} of {{all}}": "{{current}} sur {{all}}",
"Failed to manage subscription. Please try again later.": "Échec de la gestion de labonnement. Veuillez réessayer plus tard.",
"Processing your payment...": "Traitement de votre paiement...",
"Please wait while we confirm your subscription.": "Veuillez patienter pendant la confirmation de votre abonnement.",
"Payment Processing": "Traitement du paiement",
"Your payment is being processed. This usually takes a few moments.": "Votre paiement est en cours de traitement. Cela prend généralement quelques instants.",
"Payment Failed": "Le paiement a échoué",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Nous navons pas pu traiter votre abonnement. Veuillez réessayer ou contacter le support si le problème persiste.",
"Back to Profile": "Retour au profil",
"Subscription Successful!": "Abonnement réussi!",
"Thank you for your subscription! Your payment has been processed successfully.": "Merci pour votre abonnement! Votre paiement a été traité avec succès.",
"Email:": "E-mail:",
"Plan:": "Abonnement:",
"Amount:": "Montant:",
"Subscription ID:": "ID dabonnement:",
"Go to Library": "Aller à la bibliothèque",
"Need help? Contact our support team at support@readest.com": "Besoin daide? Contactez notre équipe à support@readest.com",
"Free Plan": "Abonnement gratuit",
"month": "mois",
"Unlimited Text-to-Speech Hours": "Heures illimitées de synthèse vocale",
"DeepL Free Access (10K characters/day)": "Accès gratuit à DeepL (10000 caractères/jour)",
"AI Translations (per day)": "Traductions IA (par jour)",
"Cloud Storage": "Stockage cloud",
"Plus Plan": "Abonnement Plus",
"Includes All Free Plan Benefits": "Inclut tous les avantages de labonnement gratuit",
"Basic AI Translations": "Traductions IA de base",
"DeepL Pro Access (50K characters/day)": "Accès Pro à DeepL (50000 caractères/jour)",
"2 GB Cloud Sync Space": "2 Go despace de synchronisation cloud",
"Pro Plan": "Abonnement Pro",
"Includes All Plus Plan Benefits": "Inclut tous les avantages de labonnement Plus",
"More AI Translations": "Plus de traductions IA",
"DeepL Pro Access (200K characters/day)": "Accès Pro à DeepL (200000 caractères/jour)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "GitHub के साथ साइन इन करें",
"Account": "खाता",
"Failed to delete user. Please try again later.": "उपयोगकर्ता को हटाने में विफल। कृपया बाद में पुनः प्रयास करें।",
"Unlimited Offline/Online Reading": "असीमित ऑफलाइन/ऑनलाइन पढ़ना",
"Unlimited Cloud Sync Devices": "असीमित क्लाउड सिंक उपकरण",
"Essential Text-to-Speech Voices": "आवश्यक टेक्स्ट-टू-स्पीच आवाज़ें",
"DeepL Free Access": "DeepL मुफ्त पहुंच",
"Community Support": "सामुदायिक सहायता",
"500 MB Cloud Sync Space": "500 MB क्लाउड सिंक स्पेस",
"Includes All Free Tier Benefits": "सभी फ्री टियर लाभ शामिल हैं",
"AI Summaries": "AI सारांश",
"AI Translations": "AI अनुवाद",
"Priority Support": "प्राथमिकता सहायता",
"DeepL Pro Access": "DeepL प्रो पहुंच",
"Expanded Text-to-Speech Voices": "विस्तारित टेक्स्ट-टू-स्पीच आवाज़ें",
"2000 MB Cloud Sync Space": "2000 MB क्लाउड सिंक स्पेस",
"Includes All Plus Tier Benefits": "सभी प्लस टियर लाभ शामिल हैं",
"Unlimited AI Summaries": "असीमित AI सारांश",
"Unlimited AI Translations": "असीमित AI अनुवाद",
"Unlimited DeepL Pro Access": "असीमित DeepL प्रो पहुंच",
"Advanced AI Tools": "उन्नत AI टूल्स",
"Early Feature Access": "प्रारंभिक फीचर पहुंच",
"10 GB Cloud Sync Space": "10 GB क्लाउड सिंक स्पेस",
"Loading profile...": "प्रोफ़ाइल लोड हो रहा है...",
"Features": "विशेषताएं",
"Delete Account": "खाता हटाएं",
"Delete Your Account?": "अपना खाता हटाएं?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "यह क्रिया पूर्ववत नहीं की जा सकती। क्लाउड में आपका सभी डेटा स्थायी रूप से हटा दिया जाएगा।",
"Delete Permanently": "स्थायी रूप से हटाएं",
"Free Tier": "फ्री टियर",
"Plus Tier": "प्लस टियर",
"Pro Tier": "प्रो टियर",
"RTL Direction": "RTL दिशा",
"Maximum Column Height": "कॉलम की अधिकतम ऊँचाई",
"Maximum Column Width": "कॉलम की अधिकतम चौड़ाई",
@@ -377,5 +360,44 @@
"Show Remaining Pages": "शेष पृष्ठ दिखाएँ",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "सदस्यता प्रबंधित करें",
"Coming Soon": "जल्द आ रहा है",
"Upgrade to {{plan}}": "{{plan}} में अपग्रेड करें",
"Upgrade to Plus or Pro": "Plus या Pro में अपग्रेड करें",
"Current Plan": "वर्तमान योजना",
"Plan Limits": "योजना की सीमाएँ",
"Available Plans": "उपलब्ध योजनाएँ",
"{{current}} of {{all}}": "{{all}} में से {{current}}",
"Failed to manage subscription. Please try again later.": "सदस्यता प्रबंधित करने में विफल। कृपया बाद में पुनः प्रयास करें।",
"Processing your payment...": "आपका भुगतान संसाधित हो रहा है...",
"Please wait while we confirm your subscription.": "कृपया प्रतीक्षा करें, हम आपकी सदस्यता की पुष्टि कर रहे हैं।",
"Payment Processing": "भुगतान संसाधित हो रहा है",
"Your payment is being processed. This usually takes a few moments.": "आपका भुगतान संसाधित हो रहा है। इसमें कुछ क्षण लग सकते हैं।",
"Payment Failed": "भुगतान विफल",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "हम आपकी सदस्यता संसाधित नहीं कर सके। कृपया पुनः प्रयास करें या समस्या बने रहने पर सहायता से संपर्क करें।",
"Back to Profile": "प्रोफ़ाइल पर वापस जाएँ",
"Subscription Successful!": "सदस्यता सफल हुई!",
"Thank you for your subscription! Your payment has been processed successfully.": "आपकी सदस्यता के लिए धन्यवाद! आपका भुगतान सफलतापूर्वक संसाधित हो गया है।",
"Email:": "ईमेल:",
"Plan:": "योजना:",
"Amount:": "राशि:",
"Subscription ID:": "सदस्यता आईडी:",
"Go to Library": "लाइब्रेरी पर जाएँ",
"Need help? Contact our support team at support@readest.com": "मदद चाहिए? हमारी सहायता टीम से संपर्क करें: support@readest.com",
"Free Plan": "मुफ्त योजना",
"month": "महीना",
"Unlimited Text-to-Speech Hours": "अनलिमिटेड पाठ-पाठ ध्वनि घंटे",
"DeepL Free Access (10K characters/day)": "DeepL मुफ्त एक्सेस (10,000 अक्षर/दिन)",
"AI Translations (per day)": "AI अनुवाद (प्रतिदिन)",
"Cloud Storage": "क्लाउड स्टोरेज",
"Plus Plan": "Plus योजना",
"Includes All Free Plan Benefits": "सभी मुफ्त योजना के लाभ शामिल हैं",
"Basic AI Translations": "मूल AI अनुवाद",
"DeepL Pro Access (50K characters/day)": "DeepL प्रो एक्सेस (50,000 अक्षर/दिन)",
"2 GB Cloud Sync Space": "2 जीबी क्लाउड सिंक स्पेस",
"Pro Plan": "Pro योजना",
"Includes All Plus Plan Benefits": "सभी Plus योजना के लाभ शामिल हैं",
"More AI Translations": "और अधिक AI अनुवाद",
"DeepL Pro Access (200K characters/day)": "DeepL प्रो एक्सेस (200,000 अक्षर/दिन)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "Masuk dengan GitHub",
"Account": "Akun",
"Failed to delete user. Please try again later.": "Gagal menghapus pengguna. Silakan coba lagi nanti.",
"Unlimited Offline/Online Reading": "Membaca Offline/Online Tanpa Batas",
"Unlimited Cloud Sync Devices": "Perangkat Sinkronisasi Cloud Tanpa Batas",
"Essential Text-to-Speech Voices": "Suara Text-to-Speech Esensial",
"DeepL Free Access": "Akses DeepL Gratis",
"Community Support": "Dukungan Komunitas",
"500 MB Cloud Sync Space": "Ruang Sinkronisasi Cloud 500 MB",
"Includes All Free Tier Benefits": "Termasuk Semua Manfaat Tingkat Gratis",
"AI Summaries": "Ringkasan AI",
"AI Translations": "Terjemahan AI",
"Priority Support": "Dukungan Prioritas",
"DeepL Pro Access": "Akses DeepL Pro",
"Expanded Text-to-Speech Voices": "Suara Text-to-Speech yang Diperluas",
"2000 MB Cloud Sync Space": "Ruang Sinkronisasi Cloud 2000 MB",
"Includes All Plus Tier Benefits": "Termasuk Semua Manfaat Tingkat Plus",
"Unlimited AI Summaries": "Ringkasan AI Tanpa Batas",
"Unlimited AI Translations": "Terjemahan AI Tanpa Batas",
"Unlimited DeepL Pro Access": "Akses DeepL Pro Tanpa Batas",
"Advanced AI Tools": "Alat AI Lanjutan",
"Early Feature Access": "Akses Fitur Awal",
"10 GB Cloud Sync Space": "Ruang Sinkronisasi Cloud 10 GB",
"Loading profile...": "Memuat profil...",
"Features": "Fitur",
"Delete Account": "Hapus Akun",
"Delete Your Account?": "Hapus Akun Anda?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Tindakan ini tidak dapat dibatalkan. Semua data Anda di cloud akan dihapus secara permanen.",
"Delete Permanently": "Hapus Secara Permanen",
"Free Tier": "Tingkat Gratis",
"Plus Tier": "Tingkat Plus",
"Pro Tier": "Tingkat Pro",
"RTL Direction": "Arah RTL",
"Maximum Column Height": "Tinggi Kolom Maksimum",
"Maximum Column Width": "Lebar Kolom Maksimum",
@@ -373,5 +356,44 @@
"Show Remaining Pages": "Tampilkan halaman tersisa",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "Kelola Langganan",
"Coming Soon": "Segera Hadir",
"Upgrade to {{plan}}": "Tingkatkan ke {{plan}}",
"Upgrade to Plus or Pro": "Tingkatkan ke Plus atau Pro",
"Current Plan": "Paket Saat Ini",
"Plan Limits": "Batas Paket",
"Available Plans": "Paket yang Tersedia",
"{{current}} of {{all}}": "{{current}} dari {{all}}",
"Failed to manage subscription. Please try again later.": "Gagal mengelola langganan. Silakan coba lagi nanti.",
"Processing your payment...": "Memproses pembayaran Anda...",
"Please wait while we confirm your subscription.": "Mohon tunggu saat kami mengonfirmasi langganan Anda.",
"Payment Processing": "Memproses Pembayaran",
"Your payment is being processed. This usually takes a few moments.": "Pembayaran Anda sedang diproses. Ini biasanya memerlukan beberapa saat.",
"Payment Failed": "Pembayaran Gagal",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Kami tidak dapat memproses langganan Anda. Silakan coba lagi atau hubungi dukungan jika masalah berlanjut.",
"Back to Profile": "Kembali ke Profil",
"Subscription Successful!": "Langganan Berhasil!",
"Thank you for your subscription! Your payment has been processed successfully.": "Terima kasih atas langganan Anda! Pembayaran Anda telah berhasil diproses.",
"Email:": "Email:",
"Plan:": "Paket:",
"Amount:": "Jumlah:",
"Subscription ID:": "ID Langganan:",
"Go to Library": "Pergi ke Perpustakaan",
"Need help? Contact our support team at support@readest.com": "Perlu bantuan? Hubungi tim dukungan kami di support@readest.com",
"Free Plan": "Paket Gratis",
"month": "bulan",
"Unlimited Text-to-Speech Hours": "Jam Text-to-Speech Tanpa Batas",
"DeepL Free Access (10K characters/day)": "Akses DeepL Gratis (10.000 karakter/hari)",
"AI Translations (per day)": "Terjemahan AI (per hari)",
"Cloud Storage": "Penyimpanan Cloud",
"Plus Plan": "Paket Plus",
"Includes All Free Plan Benefits": "Termasuk Semua Manfaat Paket Gratis",
"Basic AI Translations": "Terjemahan AI Dasar",
"DeepL Pro Access (50K characters/day)": "Akses DeepL Pro (50.000 karakter/hari)",
"2 GB Cloud Sync Space": "2 GB Ruang Sinkronisasi Cloud",
"Pro Plan": "Paket Pro",
"Includes All Plus Plan Benefits": "Termasuk Semua Manfaat Paket Plus",
"More AI Translations": "Lebih Banyak Terjemahan AI",
"DeepL Pro Access (200K characters/day)": "Akses DeepL Pro (200.000 karakter/hari)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "Accedi con GitHub",
"Account": "Account",
"Failed to delete user. Please try again later.": "Impossibile eliminare l'utente. Riprova più tardi.",
"Unlimited Offline/Online Reading": "Lettura offline/online illimitata",
"Unlimited Cloud Sync Devices": "Sincronizzazione cloud su dispositivi illimitati",
"Essential Text-to-Speech Voices": "Voci essenziali di sintesi vocale",
"DeepL Free Access": "Accesso gratuito a DeepL",
"Community Support": "Supporto della community",
"500 MB Cloud Sync Space": "500 MB di spazio di sincronizzazione cloud",
"Includes All Free Tier Benefits": "Include tutti i vantaggi del piano gratuito",
"AI Summaries": "Riassunti AI",
"AI Translations": "Traduzioni AI",
"Priority Support": "Supporto prioritario",
"DeepL Pro Access": "Accesso a DeepL Pro",
"Expanded Text-to-Speech Voices": "Voci di sintesi vocale ampliate",
"2000 MB Cloud Sync Space": "2000 MB di spazio di sincronizzazione cloud",
"Includes All Plus Tier Benefits": "Include tutti i vantaggi del piano Plus",
"Unlimited AI Summaries": "Riassunti AI illimitati",
"Unlimited AI Translations": "Traduzioni AI illimitate",
"Unlimited DeepL Pro Access": "Accesso illimitato a DeepL Pro",
"Advanced AI Tools": "Strumenti AI avanzati",
"Early Feature Access": "Accesso anticipato alle funzionalità",
"10 GB Cloud Sync Space": "10 GB di spazio di sincronizzazione cloud",
"Loading profile...": "Caricamento profilo...",
"Features": "Funzionalità",
"Delete Account": "Elimina account",
"Delete Your Account?": "Eliminare il tuo account?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Questa azione non può essere annullata. Tutti i tuoi dati nel cloud verranno eliminati definitivamente.",
"Delete Permanently": "Elimina definitivamente",
"Free Tier": "Piano gratuito",
"Plus Tier": "Piano Plus",
"Pro Tier": "Piano Pro",
"RTL Direction": "Direzione RTL",
"Maximum Column Height": "Altezza massima colonna",
"Maximum Column Width": "Larghezza massima colonna",
@@ -381,5 +364,44 @@
"Show Remaining Pages": "Mostra pagine rimanenti",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "Gestisci Abbonamento",
"Coming Soon": "Prossimamente",
"Upgrade to {{plan}}": "Aggiorna a {{plan}}",
"Upgrade to Plus or Pro": "Aggiorna a Plus o Pro",
"Current Plan": "Piano Attuale",
"Plan Limits": "Limiti del Piano",
"Available Plans": "Piani Disponibili",
"{{current}} of {{all}}": "{{current}} di {{all}}",
"Failed to manage subscription. Please try again later.": "Impossibile gestire l'abbonamento. Riprova più tardi.",
"Processing your payment...": "Elaborazione del pagamento...",
"Please wait while we confirm your subscription.": "Attendi mentre confermiamo il tuo abbonamento.",
"Payment Processing": "Elaborazione Pagamento",
"Your payment is being processed. This usually takes a few moments.": "Il tuo pagamento è in elaborazione. Di solito richiede pochi istanti.",
"Payment Failed": "Pagamento Fallito",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Non è stato possibile elaborare l'abbonamento. Riprova o contatta il supporto se il problema persiste.",
"Back to Profile": "Torna al Profilo",
"Subscription Successful!": "Abbonamento Avvenuto con Successo!",
"Thank you for your subscription! Your payment has been processed successfully.": "Grazie per l'abbonamento! Il pagamento è stato elaborato con successo.",
"Email:": "Email:",
"Plan:": "Piano:",
"Amount:": "Importo:",
"Subscription ID:": "ID Abbonamento:",
"Go to Library": "Vai alla Libreria",
"Need help? Contact our support team at support@readest.com": "Hai bisogno di aiuto? Contatta il nostro supporto a support@readest.com",
"Free Plan": "Piano Gratuito",
"month": "mese",
"Unlimited Text-to-Speech Hours": "Ore Illimitate di Sintesi Vocale",
"DeepL Free Access (10K characters/day)": "Accesso Gratuito a DeepL (10.000 caratteri/giorno)",
"AI Translations (per day)": "Traduzioni AI (al giorno)",
"Cloud Storage": "Archiviazione Cloud",
"Plus Plan": "Piano Plus",
"Includes All Free Plan Benefits": "Include Tutti i Vantaggi del Piano Gratuito",
"Basic AI Translations": "Traduzioni AI di Base",
"DeepL Pro Access (50K characters/day)": "Accesso DeepL Pro (50.000 caratteri/giorno)",
"2 GB Cloud Sync Space": "2 GB di Spazio di Sincronizzazione Cloud",
"Pro Plan": "Piano Pro",
"Includes All Plus Plan Benefits": "Include Tutti i Vantaggi del Piano Plus",
"More AI Translations": "Più Traduzioni AI",
"DeepL Pro Access (200K characters/day)": "Accesso DeepL Pro (200.000 caratteri/giorno)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "GitHubでサインイン",
"Account": "アカウント",
"Failed to delete user. Please try again later.": "ユーザーの削除に失敗しました。後ほど再試行してください。",
"Unlimited Offline/Online Reading": "無制限のオフライン/オンライン読書",
"Unlimited Cloud Sync Devices": "無制限のクラウド同期デバイス",
"Essential Text-to-Speech Voices": "基本的な音声合成ボイス",
"DeepL Free Access": "DeepL無料アクセス",
"Community Support": "コミュニティサポート",
"500 MB Cloud Sync Space": "500 MBのクラウド同期スペース",
"Includes All Free Tier Benefits": "無料プランの全特典を含む",
"AI Summaries": "AI要約",
"AI Translations": "AI翻訳",
"Priority Support": "優先サポート",
"DeepL Pro Access": "DeepL Proアクセス",
"Expanded Text-to-Speech Voices": "拡張された音声合成ボイス",
"2000 MB Cloud Sync Space": "2000 MBのクラウド同期スペース",
"Includes All Plus Tier Benefits": "Plusプランの全特典を含む",
"Unlimited AI Summaries": "無制限のAI要約",
"Unlimited AI Translations": "無制限のAI翻訳",
"Unlimited DeepL Pro Access": "無制限のDeepL Proアクセス",
"Advanced AI Tools": "高度なAIツール",
"Early Feature Access": "新機能への早期アクセス",
"10 GB Cloud Sync Space": "10 GBのクラウド同期スペース",
"Loading profile...": "プロフィール読み込み中...",
"Features": "機能",
"Delete Account": "アカウント削除",
"Delete Your Account?": "アカウントを削除しますか?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "この操作は元に戻せません。クラウド上のすべてのデータが完全に削除されます。",
"Delete Permanently": "完全に削除",
"Free Tier": "無料プラン",
"Plus Tier": "Plusプラン",
"Pro Tier": "Proプラン",
"RTL Direction": "RTL方向",
"Maximum Column Height": "最大列高",
"Maximum Column Width": "最大列幅",
@@ -373,5 +356,44 @@
"Show Remaining Pages": "残りを表示",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "サブスクリプションを管理",
"Coming Soon": "近日公開",
"Upgrade to {{plan}}": "{{plan}} にアップグレード",
"Upgrade to Plus or Pro": "Plus または Pro にアップグレード",
"Current Plan": "現在のプラン",
"Plan Limits": "プランの上限",
"Available Plans": "利用可能なプラン",
"{{current}} of {{all}}": "{{all}} 中 {{current}}",
"Failed to manage subscription. Please try again later.": "サブスクリプションの管理に失敗しました。後でもう一度お試しください。",
"Processing your payment...": "お支払いを処理中...",
"Please wait while we confirm your subscription.": "サブスクリプションを確認しています。しばらくお待ちください。",
"Payment Processing": "支払いを処理中",
"Your payment is being processed. This usually takes a few moments.": "お支払いを処理しています。通常、数秒かかります。",
"Payment Failed": "支払いに失敗しました",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "サブスクリプションを処理できませんでした。再度お試しいただくか、問題が続く場合はサポートにお問い合わせください。",
"Back to Profile": "プロフィールに戻る",
"Subscription Successful!": "サブスクリプションが完了しました!",
"Thank you for your subscription! Your payment has been processed successfully.": "ご登録ありがとうございます!お支払いが正常に処理されました。",
"Email:": "メール:",
"Plan:": "プラン:",
"Amount:": "金額:",
"Subscription ID:": "サブスクリプションID:",
"Go to Library": "ライブラリへ移動",
"Need help? Contact our support team at support@readest.com": "サポートが必要ですか? support@readest.com までお問い合わせください。",
"Free Plan": "無料プラン",
"month": "月",
"Unlimited Text-to-Speech Hours": "無制限の音声読み上げ時間",
"DeepL Free Access (10K characters/day)": "DeepL無料アクセス(1日1万文字)",
"AI Translations (per day)": "AI翻訳(1日あたり)",
"Cloud Storage": "クラウドストレージ",
"Plus Plan": "Plusプラン",
"Includes All Free Plan Benefits": "無料プランの全特典を含む",
"Basic AI Translations": "基本的なAI翻訳",
"DeepL Pro Access (50K characters/day)": "DeepL Proアクセス(1日5万文字)",
"2 GB Cloud Sync Space": "2GBのクラウド同期容量",
"Pro Plan": "Proプラン",
"Includes All Plus Plan Benefits": "Plusプランの全特典を含む",
"More AI Translations": "さらに多くのAI翻訳",
"DeepL Pro Access (200K characters/day)": "DeepL Proアクセス(1日20万文字)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "GitHub로 로그인",
"Account": "계정",
"Failed to delete user. Please try again later.": "사용자 삭제에 실패했습니다. 나중에 다시 시도해 주세요.",
"Unlimited Offline/Online Reading": "무제한 오프라인/온라인 읽기",
"Unlimited Cloud Sync Devices": "무제한 클라우드 동기화 기기",
"Essential Text-to-Speech Voices": "필수 텍스트 음성 변환 목소리",
"DeepL Free Access": "DeepL 무료 접근",
"Community Support": "커뮤니티 지원",
"500 MB Cloud Sync Space": "500 MB 클라우드 동기화 공간",
"Includes All Free Tier Benefits": "무료 등급의 모든 혜택 포함",
"AI Summaries": "AI 요약",
"AI Translations": "AI 번역",
"Priority Support": "우선 지원",
"DeepL Pro Access": "DeepL 프로 접근",
"Expanded Text-to-Speech Voices": "확장된 텍스트 음성 변환 목소리",
"2000 MB Cloud Sync Space": "2000 MB 클라우드 동기화 공간",
"Includes All Plus Tier Benefits": "플러스 등급의 모든 혜택 포함",
"Unlimited AI Summaries": "무제한 AI 요약",
"Unlimited AI Translations": "무제한 AI 번역",
"Unlimited DeepL Pro Access": "무제한 DeepL 프로 접근",
"Advanced AI Tools": "고급 AI 도구",
"Early Feature Access": "신기능 조기 접근",
"10 GB Cloud Sync Space": "10 GB 클라우드 동기화 공간",
"Loading profile...": "프로필 로딩 중...",
"Features": "기능",
"Delete Account": "계정 삭제",
"Delete Your Account?": "계정을 삭제하시겠습니까?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "이 작업은 취소할 수 없습니다. 클라우드에 있는 모든 데이터가 영구적으로 삭제됩니다.",
"Delete Permanently": "영구 삭제",
"Free Tier": "무료 등급",
"Plus Tier": "플러스 등급",
"Pro Tier": "프로 등급",
"RTL Direction": "RTL 방향",
"Maximum Column Height": "최대 열 높이",
"Maximum Column Width": "최대 열 너비",
@@ -373,5 +356,44 @@
"Show Remaining Pages": "남은 페이지 보기",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "구독 관리",
"Coming Soon": "곧 출시 예정",
"Upgrade to {{plan}}": "{{plan}}로 업그레이드",
"Upgrade to Plus or Pro": "Plus 또는 Pro로 업그레이드",
"Current Plan": "현재 요금제",
"Plan Limits": "요금제 한도",
"Available Plans": "이용 가능한 요금제",
"{{current}} of {{all}}": "{{all}} 중 {{current}}",
"Failed to manage subscription. Please try again later.": "구독 관리에 실패했습니다. 나중에 다시 시도해주세요.",
"Processing your payment...": "결제를 처리 중입니다...",
"Please wait while we confirm your subscription.": "구독을 확인하는 중입니다. 잠시만 기다려주세요.",
"Payment Processing": "결제 처리 중",
"Your payment is being processed. This usually takes a few moments.": "결제가 처리되고 있습니다. 잠시만 기다려주세요.",
"Payment Failed": "결제 실패",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "구독을 처리할 수 없습니다. 다시 시도하거나 문제가 계속되면 지원팀에 문의해주세요.",
"Back to Profile": "프로필로 돌아가기",
"Subscription Successful!": "구독이 완료되었습니다!",
"Thank you for your subscription! Your payment has been processed successfully.": "구독해주셔서 감사합니다! 결제가 성공적으로 처리되었습니다.",
"Email:": "이메일:",
"Plan:": "요금제:",
"Amount:": "금액:",
"Subscription ID:": "구독 ID:",
"Go to Library": "라이브러리로 이동",
"Need help? Contact our support team at support@readest.com": "도움이 필요하시면 support@readest.com으로 문의해주세요.",
"Free Plan": "무료 요금제",
"month": "월",
"Unlimited Text-to-Speech Hours": "무제한 음성 변환 시간",
"DeepL Free Access (10K characters/day)": "DeepL 무료 액세스 (일 1만자)",
"AI Translations (per day)": "AI 번역 (일 기준)",
"Cloud Storage": "클라우드 저장소",
"Plus Plan": "Plus 요금제",
"Includes All Free Plan Benefits": "무료 요금제의 모든 혜택 포함",
"Basic AI Translations": "기본 AI 번역",
"DeepL Pro Access (50K characters/day)": "DeepL Pro 액세스 (일 5만자)",
"2 GB Cloud Sync Space": "2GB 클라우드 동기화 공간",
"Pro Plan": "Pro 요금제",
"Includes All Plus Plan Benefits": "Plus 요금제의 모든 혜택 포함",
"More AI Translations": "더 많은 AI 번역",
"DeepL Pro Access (200K characters/day)": "DeepL Pro 액세스 (일 20만자)"
}
@@ -225,31 +225,14 @@
"Fast": "Snel",
"Reading Progress Synced": "Leesvoortgang gesynchroniseerd",
"Failed to delete user. Please try again later.": "Gebruiker verwijderen mislukt. Probeer het later opnieuw.",
"Free Tier": "Gratis niveau",
"Community Support": "Community-ondersteuning",
"DeepL Free Access": "DeepL gratis toegang",
"Essential Text-to-Speech Voices": "Essentiële tekst-naar-spraak stemmen",
"Unlimited Offline/Online Reading": "Onbeperkt offline/online lezen",
"Unlimited Cloud Sync Devices": "Onbeperkt aantal cloud-synchronisatie apparaten",
"500 MB Cloud Sync Space": "500 MB cloud-synchronisatieruimte",
"Plus Tier": "Plus niveau",
"Includes All Free Tier Benefits": "Inclusief alle voordelen van het gratis niveau",
"Priority Support": "Prioriteitsondersteuning",
"AI Summaries": "AI-samenvattingen",
"AI Translations": "AI-vertalingen",
"DeepL Pro Access": "DeepL Pro toegang",
"Expanded Text-to-Speech Voices": "Uitgebreide tekst-naar-spraak stemmen",
"2000 MB Cloud Sync Space": "2000 MB cloud-synchronisatieruimte",
"Pro Tier": "Pro niveau",
"Includes All Plus Tier Benefits": "Inclusief alle voordelen van het Plus niveau",
"Unlimited AI Summaries": "Onbeperkte AI-samenvattingen",
"Unlimited AI Translations": "Onbeperkte AI-vertalingen",
"Unlimited DeepL Pro Access": "Onbeperkte DeepL Pro toegang",
"Advanced AI Tools": "Geavanceerde AI-tools",
"Early Feature Access": "Vroege toegang tot functies",
"10 GB Cloud Sync Space": "10 GB cloud-synchronisatieruimte",
"Loading profile...": "Profiel laden...",
"Features": "Functies",
"Sign Out": "Uitloggen",
"Delete Account": "Account verwijderen",
"Delete Your Account?": "Uw account verwijderen?",
@@ -377,5 +360,44 @@
"Show Remaining Pages": "Toon resterende paginas",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "Abonnement beheren",
"Coming Soon": "Binnenkort beschikbaar",
"Upgrade to {{plan}}": "Upgrade naar {{plan}}",
"Upgrade to Plus or Pro": "Upgrade naar Plus of Pro",
"Current Plan": "Huidig abonnement",
"Plan Limits": "Abonnementslimieten",
"Available Plans": "Beschikbare abonnementen",
"{{current}} of {{all}}": "{{current}} van {{all}}",
"Failed to manage subscription. Please try again later.": "Abonnement beheren is mislukt. Probeer het later opnieuw.",
"Processing your payment...": "Je betaling wordt verwerkt...",
"Please wait while we confirm your subscription.": "Even geduld terwijl we je abonnement bevestigen.",
"Payment Processing": "Betaling verwerken",
"Your payment is being processed. This usually takes a few moments.": "Je betaling wordt verwerkt. Dit duurt meestal een paar seconden.",
"Payment Failed": "Betaling mislukt",
"Back to Profile": "Terug naar profiel",
"Subscription Successful!": "Abonnement succesvol!",
"Email:": "E-mail:",
"Plan:": "Abonnement:",
"Amount:": "Bedrag:",
"Subscription ID:": "Abonnements-ID:",
"Go to Library": "Ga naar bibliotheek",
"Need help? Contact our support team at support@readest.com": "Hulp nodig? Neem contact op met support via support@readest.com",
"Free Plan": "Gratis abonnement",
"month": "maand",
"Unlimited Text-to-Speech Hours": "Onbeperkte tekst-naar-spraak-uren",
"DeepL Free Access (10K characters/day)": "DeepL gratis toegang (10.000 tekens/dag)",
"AI Translations (per day)": "AI-vertalingen (per dag)",
"Cloud Storage": "Cloudopslag",
"Plus Plan": "Plus-abonnement",
"Includes All Free Plan Benefits": "Bevat alle voordelen van het gratis abonnement",
"Basic AI Translations": "Basis AI-vertalingen",
"DeepL Pro Access (50K characters/day)": "DeepL Pro toegang (50.000 tekens/dag)",
"2 GB Cloud Sync Space": "2GB cloud-synchronisatie",
"Pro Plan": "Pro-abonnement",
"Includes All Plus Plan Benefits": "Bevat alle voordelen van het Plus-abonnement",
"More AI Translations": "Meer AI-vertalingen",
"DeepL Pro Access (200K characters/day)": "DeepL Pro toegang (200.000 tekens/dag)",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "We konden je abonnement niet verwerken. Probeer het opnieuw of neem contact op met support als het probleem blijft bestaan.",
"Thank you for your subscription! Your payment has been processed successfully.": "Bedankt voor je abonnement! Je betaling is succesvol verwerkt."
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "Zaloguj się za pomocą GitHub",
"Account": "Konto",
"Failed to delete user. Please try again later.": "Nie udało się usunąć użytkownika. Spróbuj ponownie później.",
"Unlimited Offline/Online Reading": "Nieograniczone czytanie offline/online",
"Unlimited Cloud Sync Devices": "Nieograniczona liczba urządzeń synchronizowanych w chmurze",
"Essential Text-to-Speech Voices": "Podstawowe głosy zamiany tekstu na mowę",
"DeepL Free Access": "Darmowy dostęp do DeepL",
"Community Support": "Wsparcie społeczności",
"500 MB Cloud Sync Space": "500 MB przestrzeni synchronizacji w chmurze",
"Includes All Free Tier Benefits": "Zawiera wszystkie korzyści darmowego planu",
"AI Summaries": "Podsumowania AI",
"AI Translations": "Tłumaczenia AI",
"Priority Support": "Priorytetowe wsparcie",
"DeepL Pro Access": "Dostęp do DeepL Pro",
"Expanded Text-to-Speech Voices": "Rozszerzone głosy zamiany tekstu na mowę",
"2000 MB Cloud Sync Space": "2000 MB przestrzeni synchronizacji w chmurze",
"Includes All Plus Tier Benefits": "Zawiera wszystkie korzyści planu Plus",
"Unlimited AI Summaries": "Nieograniczone podsumowania AI",
"Unlimited AI Translations": "Nieograniczone tłumaczenia AI",
"Unlimited DeepL Pro Access": "Nieograniczony dostęp do DeepL Pro",
"Advanced AI Tools": "Zaawansowane narzędzia AI",
"Early Feature Access": "Wczesny dostęp do nowych funkcji",
"10 GB Cloud Sync Space": "10 GB przestrzeni synchronizacji w chmurze",
"Loading profile...": "Ładowanie profilu...",
"Features": "Funkcje",
"Delete Account": "Usuń konto",
"Delete Your Account?": "Usunąć Twoje konto?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Tej operacji nie można cofnąć. Wszystkie Twoje dane w chmurze zostaną trwale usunięte.",
"Delete Permanently": "Usuń trwale",
"Free Tier": "Plan darmowy",
"Plus Tier": "Plan Plus",
"Pro Tier": "Plan Pro",
"RTL Direction": "Kierunek RTL",
"Maximum Column Height": "Maksymalna wysokość kolumny",
"Maximum Column Width": "Maksymalna szerokość kolumny",
@@ -385,5 +368,44 @@
"Show Remaining Pages": "Pokaż pozostałe strony",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "Zarządzaj subskrypcją",
"Coming Soon": "Wkrótce dostępne",
"Upgrade to {{plan}}": "Uaktualnij do {{plan}}",
"Upgrade to Plus or Pro": "Uaktualnij do Plus lub Pro",
"Current Plan": "Obecny plan",
"Plan Limits": "Limity planu",
"Available Plans": "Dostępne plany",
"{{current}} of {{all}}": "{{current}} z {{all}}",
"Failed to manage subscription. Please try again later.": "Nie udało się zarządzać subskrypcją. Spróbuj ponownie później.",
"Processing your payment...": "Przetwarzanie płatności...",
"Please wait while we confirm your subscription.": "Proszę czekać, potwierdzamy subskrypcję.",
"Payment Processing": "Przetwarzanie płatności",
"Your payment is being processed. This usually takes a few moments.": "Twoja płatność jest przetwarzana. Zwykle trwa to kilka chwil.",
"Payment Failed": "Płatność nie powiodła się",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Nie udało się przetworzyć subskrypcji. Spróbuj ponownie lub skontaktuj się z pomocą techniczną, jeśli problem będzie się powtarzać.",
"Back to Profile": "Powrót do profilu",
"Subscription Successful!": "Subskrypcja zakończona sukcesem!",
"Thank you for your subscription! Your payment has been processed successfully.": "Dziękujemy za subskrypcję! Twoja płatność została pomyślnie przetworzona.",
"Email:": "E-mail:",
"Plan:": "Plan:",
"Amount:": "Kwota:",
"Subscription ID:": "ID subskrypcji:",
"Go to Library": "Przejdź do biblioteki",
"Need help? Contact our support team at support@readest.com": "Potrzebujesz pomocy? Skontaktuj się z naszym zespołem wsparcia: support@readest.com",
"Free Plan": "Bezpłatny plan",
"month": "miesiąc",
"Unlimited Text-to-Speech Hours": "Nieograniczone godziny zamiany tekstu na mowę",
"DeepL Free Access (10K characters/day)": "Darmowy dostęp do DeepL (10 tys. znaków/dzień)",
"AI Translations (per day)": "Tłumaczenia AI (na dzień)",
"Cloud Storage": "Przechowywanie w chmurze",
"Plus Plan": "Plan Plus",
"Includes All Free Plan Benefits": "Zawiera wszystkie korzyści planu darmowego",
"Basic AI Translations": "Podstawowe tłumaczenia AI",
"DeepL Pro Access (50K characters/day)": "DeepL Pro (50 tys. znaków/dzień)",
"2 GB Cloud Sync Space": "2 GB miejsca na synchronizację w chmurze",
"Pro Plan": "Plan Pro",
"Includes All Plus Plan Benefits": "Zawiera wszystkie korzyści planu Plus",
"More AI Translations": "Więcej tłumaczeń AI",
"DeepL Pro Access (200K characters/day)": "DeepL Pro (200 tys. znaków/dzień)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "Entrar com o GitHub",
"Account": "Conta",
"Failed to delete user. Please try again later.": "Falha ao excluir usuário. Por favor, tente novamente mais tarde.",
"Unlimited Offline/Online Reading": "Leitura offline/online ilimitada",
"Unlimited Cloud Sync Devices": "Sincronização ilimitada de dispositivos na nuvem",
"Essential Text-to-Speech Voices": "Vozes essenciais de texto para fala",
"DeepL Free Access": "Acesso gratuito ao DeepL",
"Community Support": "Suporte da comunidade",
"500 MB Cloud Sync Space": "500 MB de espaço de sincronização na nuvem",
"Includes All Free Tier Benefits": "Inclui todos os benefícios do plano gratuito",
"AI Summaries": "Resumos de IA",
"AI Translations": "Traduções de IA",
"Priority Support": "Suporte prioritário",
"DeepL Pro Access": "Acesso ao DeepL Pro",
"Expanded Text-to-Speech Voices": "Vozes ampliadas de texto para fala",
"2000 MB Cloud Sync Space": "2000 MB de espaço de sincronização na nuvem",
"Includes All Plus Tier Benefits": "Inclui todos os benefícios do plano Plus",
"Unlimited AI Summaries": "Resumos de IA ilimitados",
"Unlimited AI Translations": "Traduções de IA ilimitadas",
"Unlimited DeepL Pro Access": "Acesso ilimitado ao DeepL Pro",
"Advanced AI Tools": "Ferramentas avançadas de IA",
"Early Feature Access": "Acesso antecipado a recursos",
"10 GB Cloud Sync Space": "10 GB de espaço de sincronização na nuvem",
"Loading profile...": "Carregando perfil...",
"Features": "Recursos",
"Delete Account": "Excluir conta",
"Delete Your Account?": "Excluir sua conta?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Esta ação não pode ser desfeita. Todos os seus dados na nuvem serão excluídos permanentemente.",
"Delete Permanently": "Excluir permanentemente",
"Free Tier": "Plano gratuito",
"Plus Tier": "Plano Plus",
"Pro Tier": "Plano Pro",
"RTL Direction": "Direção RTL",
"Maximum Column Height": "Altura Máxima da Coluna",
"Maximum Column Width": "Largura Máxima da Coluna",
@@ -381,5 +364,44 @@
"Show Remaining Pages": "Mostrar páginas restantes",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "Gerenciar assinatura",
"Coming Soon": "Em breve",
"Upgrade to {{plan}}": "Atualizar para {{plan}}",
"Upgrade to Plus or Pro": "Atualizar para Plus ou Pro",
"Current Plan": "Plano atual",
"Plan Limits": "Limites do plano",
"Available Plans": "Planos disponíveis",
"{{current}} of {{all}}": "{{current}} de {{all}}",
"Failed to manage subscription. Please try again later.": "Não foi possível gerenciar a assinatura. Tente novamente mais tarde.",
"Processing your payment...": "Processando seu pagamento...",
"Please wait while we confirm your subscription.": "Por favor, aguarde enquanto confirmamos sua assinatura.",
"Payment Processing": "Processando pagamento",
"Your payment is being processed. This usually takes a few moments.": "Seu pagamento está sendo processado. Isso normalmente leva alguns instantes.",
"Payment Failed": "Falha no pagamento",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Não foi possível processar sua assinatura. Tente novamente ou entre em contato com o suporte se o problema persistir.",
"Back to Profile": "Voltar ao perfil",
"Subscription Successful!": "Assinatura realizada com sucesso!",
"Thank you for your subscription! Your payment has been processed successfully.": "Obrigado pela sua assinatura! Seu pagamento foi processado com sucesso.",
"Email:": "E-mail:",
"Plan:": "Plano:",
"Amount:": "Valor:",
"Subscription ID:": "ID da assinatura:",
"Go to Library": "Ir para a biblioteca",
"Need help? Contact our support team at support@readest.com": "Precisa de ajuda? Entre em contato com nossa equipe de suporte: support@readest.com",
"Free Plan": "Plano gratuito",
"month": "mês",
"Unlimited Text-to-Speech Hours": "Horas ilimitadas de texto para fala",
"DeepL Free Access (10K characters/day)": "Acesso gratuito ao DeepL (10 mil caracteres/dia)",
"AI Translations (per day)": "Traduções com IA (por dia)",
"Cloud Storage": "Armazenamento na nuvem",
"Plus Plan": "Plano Plus",
"Includes All Free Plan Benefits": "Inclui todos os benefícios do plano gratuito",
"Basic AI Translations": "Traduções básicas com IA",
"DeepL Pro Access (50K characters/day)": "Acesso ao DeepL Pro (50 mil caracteres/dia)",
"2 GB Cloud Sync Space": "2 GB de espaço para sincronização na nuvem",
"Pro Plan": "Plano Pro",
"Includes All Plus Plan Benefits": "Inclui todos os benefícios do plano Plus",
"More AI Translations": "Mais traduções com IA",
"DeepL Pro Access (200K characters/day)": "Acesso ao DeepL Pro (200 mil caracteres/dia)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "Войти через GitHub",
"Account": "Аккаунт",
"Failed to delete user. Please try again later.": "Не удалось удалить пользователя. Пожалуйста, повторите попытку позже.",
"Unlimited Offline/Online Reading": "Безлимитное чтение офлайн/онлайн",
"Unlimited Cloud Sync Devices": "Неограниченное количество устройств для облачной синхронизации",
"Essential Text-to-Speech Voices": "Основные голоса для преобразования текста в речь",
"DeepL Free Access": "Бесплатный доступ к DeepL",
"Community Support": "Поддержка сообщества",
"500 MB Cloud Sync Space": "500 МБ облачного пространства для синхронизации",
"Includes All Free Tier Benefits": "Включает все преимущества бесплатного тарифа",
"AI Summaries": "AI-резюме",
"AI Translations": "AI-переводы",
"Priority Support": "Приоритетная поддержка",
"DeepL Pro Access": "Доступ к DeepL Pro",
"Expanded Text-to-Speech Voices": "Расширенный набор голосов для преобразования текста в речь",
"2000 MB Cloud Sync Space": "2000 МБ облачного пространства для синхронизации",
"Includes All Plus Tier Benefits": "Включает все преимущества тарифа Plus",
"Unlimited AI Summaries": "Безлимитные AI-резюме",
"Unlimited AI Translations": "Безлимитные AI-переводы",
"Unlimited DeepL Pro Access": "Неограниченный доступ к DeepL Pro",
"Advanced AI Tools": "Продвинутые AI-инструменты",
"Early Feature Access": "Ранний доступ к новым функциям",
"10 GB Cloud Sync Space": "10 ГБ облачного пространства для синхронизации",
"Loading profile...": "Загрузка профиля...",
"Features": "Функции",
"Delete Account": "Удалить аккаунт",
"Delete Your Account?": "Удалить ваш аккаунт?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Это действие нельзя отменить. Все ваши данные в облаке будут удалены безвозвратно.",
"Delete Permanently": "Удалить навсегда",
"Free Tier": "Бесплатный тариф",
"Plus Tier": "Тариф Plus",
"Pro Tier": "Тариф Pro",
"RTL Direction": "Направление RTL",
"Maximum Column Height": "Максимальная высота колонки",
"Maximum Column Width": "Максимальная ширина колонки",
@@ -385,5 +368,44 @@
"Show Remaining Pages": "Показать оставшиеся страницы",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "Управление подпиской",
"Coming Soon": "Скоро будет",
"Upgrade to {{plan}}": "Обновить до {{plan}}",
"Upgrade to Plus or Pro": "Обновить до Plus или Pro",
"Current Plan": "Текущий план",
"Plan Limits": "Лимиты плана",
"Available Plans": "Доступные планы",
"{{current}} of {{all}}": "{{current}} из {{all}}",
"Failed to manage subscription. Please try again later.": "Не удалось управлять подпиской. Пожалуйста, попробуйте позже.",
"Processing your payment...": "Обработка платежа...",
"Please wait while we confirm your subscription.": "Пожалуйста, подождите, пока мы подтверждаем вашу подписку.",
"Payment Processing": "Обработка платежа",
"Your payment is being processed. This usually takes a few moments.": "Ваш платеж обрабатывается. Обычно это занимает несколько секунд.",
"Payment Failed": "Не удалось провести платеж",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Не удалось обработать подписку. Пожалуйста, попробуйте еще раз или свяжитесь с поддержкой, если проблема сохраняется.",
"Back to Profile": "Назад в профиль",
"Subscription Successful!": "Подписка успешно оформлена!",
"Thank you for your subscription! Your payment has been processed successfully.": "Спасибо за подписку! Ваш платеж успешно обработан.",
"Email:": "Электронная почта:",
"Plan:": "План:",
"Amount:": "Сумма:",
"Subscription ID:": "ID подписки:",
"Go to Library": "Перейти в библиотеку",
"Need help? Contact our support team at support@readest.com": "Нужна помощь? Свяжитесь с нашей поддержкой: support@readest.com",
"Free Plan": "Бесплатный план",
"month": "месяц",
"Unlimited Text-to-Speech Hours": "Неограниченные часы озвучивания текста",
"DeepL Free Access (10K characters/day)": "Бесплатный доступ к DeepL (10 тыс. символов/день)",
"AI Translations (per day)": "Переводы ИИ (в день)",
"Cloud Storage": "Облачное хранилище",
"Plus Plan": "План Plus",
"Includes All Free Plan Benefits": "Включает все преимущества бесплатного плана",
"Basic AI Translations": "Базовые переводы ИИ",
"DeepL Pro Access (50K characters/day)": "Доступ к DeepL Pro (50 тыс. символов/день)",
"2 GB Cloud Sync Space": "2 ГБ для синхронизации в облаке",
"Pro Plan": "План Pro",
"Includes All Plus Plan Benefits": "Включает все преимущества плана Plus",
"More AI Translations": "Больше переводов ИИ",
"DeepL Pro Access (200K characters/day)": "Доступ к DeepL Pro (200 тыс. символов/день)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "GitHub ile giriş yap",
"Account": "Hesap",
"Failed to delete user. Please try again later.": "Kullanıcı silinemedi. Lütfen daha sonra tekrar deneyin.",
"Unlimited Offline/Online Reading": "Sınırsız Çevrimdışı/Çevrimiçi Okuma",
"Unlimited Cloud Sync Devices": "Sınırsız Bulut Senkronizasyon Cihazları",
"Essential Text-to-Speech Voices": "Temel Metinden Sese Dönüştürme Sesleri",
"DeepL Free Access": "DeepL Ücretsiz Erişim",
"Community Support": "Topluluk Desteği",
"500 MB Cloud Sync Space": "500 MB Bulut Senkronizasyon Alanı",
"Includes All Free Tier Benefits": "Tüm Ücretsiz Paket Avantajlarını İçerir",
"AI Summaries": "Yapay Zeka Özetleri",
"AI Translations": "Yapay Zeka Çevirileri",
"Priority Support": "Öncelikli Destek",
"DeepL Pro Access": "DeepL Pro Erişimi",
"Expanded Text-to-Speech Voices": "Genişletilmiş Metinden Sese Dönüştürme Sesleri",
"2000 MB Cloud Sync Space": "2000 MB Bulut Senkronizasyon Alanı",
"Includes All Plus Tier Benefits": "Tüm Plus Paket Avantajlarını İçerir",
"Unlimited AI Summaries": "Sınırsız Yapay Zeka Özetleri",
"Unlimited AI Translations": "Sınırsız Yapay Zeka Çevirileri",
"Unlimited DeepL Pro Access": "Sınırsız DeepL Pro Erişimi",
"Advanced AI Tools": "Gelişmiş Yapay Zeka Araçları",
"Early Feature Access": "Erken Özellik Erişimi",
"10 GB Cloud Sync Space": "10 GB Bulut Senkronizasyon Alanı",
"Loading profile...": "Profil yükleniyor...",
"Features": "Özellikler",
"Delete Account": "Hesabı Sil",
"Delete Your Account?": "Hesabınızı Silmek İstiyor musunuz?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Bu işlem geri alınamaz. Buluttaki tüm verileriniz kalıcı olarak silinecektir.",
"Delete Permanently": "Kalıcı Olarak Sil",
"Free Tier": "Ücretsiz Paket",
"Plus Tier": "Plus Paket",
"Pro Tier": "Pro Paket",
"RTL Direction": "RTL Yönü",
"Maximum Column Height": "Maksimum Sütun Yüksekliği",
"Maximum Column Width": "Maksimum Sütun Genişliği",
@@ -377,5 +360,44 @@
"Show Remaining Pages": "Kalan sayfaları göster",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "Aboneliği Yönet",
"Coming Soon": "Yakında",
"Upgrade to {{plan}}": "{{plan}} planına yükselt",
"Upgrade to Plus or Pro": "Plus veya Pro'ya yükselt",
"Current Plan": "Mevcut Plan",
"Plan Limits": "Plan Limitleri",
"Available Plans": "Mevcut Planlar",
"{{current}} of {{all}}": "{{all}} üzerinden {{current}}",
"Failed to manage subscription. Please try again later.": "Abonelik yönetimi başarısız oldu. Lütfen daha sonra tekrar deneyin.",
"Processing your payment...": "Ödemeniz işleniyor...",
"Please wait while we confirm your subscription.": "Aboneliğinizi onaylıyoruz, lütfen bekleyin.",
"Payment Processing": "Ödeme İşleniyor",
"Your payment is being processed. This usually takes a few moments.": "Ödemeniz işleniyor. Bu genelde birkaç saniye sürer.",
"Payment Failed": "Ödeme Başarısız",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Aboneliğinizi işleyemedik. Lütfen tekrar deneyin veya sorun devam ederse destek ile iletişime geçin.",
"Back to Profile": "Profille Dön",
"Subscription Successful!": "Abonelik Başarılı!",
"Thank you for your subscription! Your payment has been processed successfully.": "Aboneliğiniz için teşekkürler! Ödemeniz başarıyla işlendi.",
"Email:": "E-posta:",
"Plan:": "Plan:",
"Amount:": "Tutar:",
"Subscription ID:": "Abonelik ID'si:",
"Go to Library": "Kütüphaneye Git",
"Need help? Contact our support team at support@readest.com": "Yardım mı gerekiyor? Destek ekibimizle iletişime geçin: support@readest.com",
"Free Plan": "Ücretsiz Plan",
"month": "ay",
"Unlimited Text-to-Speech Hours": "Sınırsız Sesli Okuma Süresi",
"DeepL Free Access (10K characters/day)": "DeepL Ücretsiz Erişim (Günde 10K karakter)",
"AI Translations (per day)": "AI Çevirileri (günlük)",
"Cloud Storage": "Bulut Depolama",
"Plus Plan": "Plus Plan",
"Includes All Free Plan Benefits": "Tüm Ücretsiz Plan Özelliklerini İçerir",
"Basic AI Translations": "Temel AI Çevirileri",
"DeepL Pro Access (50K characters/day)": "DeepL Pro Erişim (Günde 50K karakter)",
"2 GB Cloud Sync Space": "2 GB Bulut Senkronizasyon Alanı",
"Pro Plan": "Pro Plan",
"Includes All Plus Plan Benefits": "Tüm Plus Plan Özelliklerini İçerir",
"More AI Translations": "Daha Fazla AI Çevirisi",
"DeepL Pro Access (200K characters/day)": "DeepL Pro Erişim (Günde 200K karakter)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "Увійти через GitHub",
"Account": "Обліковий запис",
"Failed to delete user. Please try again later.": "Не вдалося видалити користувача. Будь ласка, спробуйте пізніше.",
"Unlimited Offline/Online Reading": "Необмежене читання офлайн/онлайн",
"Unlimited Cloud Sync Devices": "Необмежена кількість пристроїв для хмарної синхронізації",
"Essential Text-to-Speech Voices": "Основні голоси для перетворення тексту в мовлення",
"DeepL Free Access": "Безкоштовний доступ до DeepL",
"Community Support": "Підтримка спільноти",
"500 MB Cloud Sync Space": "500 МБ простору для хмарної синхронізації",
"Includes All Free Tier Benefits": "Включає всі переваги безкоштовного тарифу",
"AI Summaries": "AI-резюме",
"AI Translations": "AI-переклади",
"Priority Support": "Пріоритетна підтримка",
"DeepL Pro Access": "Доступ до DeepL Pro",
"Expanded Text-to-Speech Voices": "Розширений набір голосів для перетворення тексту в мовлення",
"2000 MB Cloud Sync Space": "2000 МБ простору для хмарної синхронізації",
"Includes All Plus Tier Benefits": "Включає всі переваги тарифу Plus",
"Unlimited AI Summaries": "Необмежені AI-резюме",
"Unlimited AI Translations": "Необмежені AI-переклади",
"Unlimited DeepL Pro Access": "Необмежений доступ до DeepL Pro",
"Advanced AI Tools": "Розширені AI-інструменти",
"Early Feature Access": "Ранній доступ до нових функцій",
"10 GB Cloud Sync Space": "10 ГБ простору для хмарної синхронізації",
"Loading profile...": "Завантаження профілю...",
"Features": "Функції",
"Delete Account": "Видалити обліковий запис",
"Delete Your Account?": "Видалити ваш обліковий запис?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Цю дію неможливо скасувати. Всі ваші дані в хмарі будуть повністю видалені.",
"Delete Permanently": "Видалити назавжди",
"Free Tier": "Безкоштовний тариф",
"Plus Tier": "Тариф Plus",
"Pro Tier": "Тариф Pro",
"RTL Direction": "Напрямок RTL",
"Maximum Column Height": "Максимальна висота колонки",
"Maximum Column Width": "Максимальна ширина колонки",
@@ -385,5 +368,44 @@
"Show Remaining Pages": "Показати залишок сторінок",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "Керувати підпискою",
"Coming Soon": "Незабаром",
"Upgrade to {{plan}}": "Перейти на {{plan}}",
"Upgrade to Plus or Pro": "Перейти на Plus або Pro",
"Current Plan": "Поточний план",
"Plan Limits": "Обмеження плану",
"Available Plans": "Доступні плани",
"{{current}} of {{all}}": "{{current}} із {{all}}",
"Failed to manage subscription. Please try again later.": "Не вдалося керувати підпискою. Спробуйте ще раз пізніше.",
"Processing your payment...": "Обробка вашого платежу...",
"Please wait while we confirm your subscription.": "Зачекайте, ми підтверджуємо вашу підписку.",
"Payment Processing": "Обробка платежу",
"Your payment is being processed. This usually takes a few moments.": "Ваш платіж обробляється. Зазвичай це займає кілька секунд.",
"Payment Failed": "Платіж не вдався",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Не вдалося обробити вашу підписку. Спробуйте ще раз або зверніться до служби підтримки, якщо проблема не зникне.",
"Back to Profile": "Повернутися до профілю",
"Subscription Successful!": "Підписка активована!",
"Thank you for your subscription! Your payment has been processed successfully.": "Дякуємо за підписку! Ваш платіж успішно оброблено.",
"Email:": "Електронна пошта:",
"Plan:": "План:",
"Amount:": "Сума:",
"Subscription ID:": "ID підписки:",
"Go to Library": "Перейти до бібліотеки",
"Need help? Contact our support team at support@readest.com": "Потрібна допомога? Зверніться до служби підтримки: support@readest.com",
"Free Plan": "Безкоштовний план",
"month": "місяць",
"Unlimited Text-to-Speech Hours": "Необмежені години озвучення тексту",
"DeepL Free Access (10K characters/day)": "Безкоштовний доступ до DeepL (10 тис. символів/день)",
"AI Translations (per day)": "AI-переклади (на день)",
"Cloud Storage": "Хмарне сховище",
"Plus Plan": "План Plus",
"Includes All Free Plan Benefits": "Включає всі переваги Безкоштовного плану",
"Basic AI Translations": "Базові AI-переклади",
"DeepL Pro Access (50K characters/day)": "DeepL Pro доступ (50 тис. символів/день)",
"2 GB Cloud Sync Space": "2 ГБ хмарного сховища для синхронізації",
"Pro Plan": "План Pro",
"Includes All Plus Plan Benefits": "Включає всі переваги плану Plus",
"More AI Translations": "Більше AI-перекладів",
"DeepL Pro Access (200K characters/day)": "DeepL Pro доступ (200 тис. символів/день)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "Đăng nhập với GitHub",
"Account": "Tài khoản",
"Failed to delete user. Please try again later.": "Không thể xóa người dùng. Vui lòng thử lại sau.",
"Unlimited Offline/Online Reading": "Đọc ngoại tuyến/trực tuyến không giới hạn",
"Unlimited Cloud Sync Devices": "Đồng bộ hóa thiết bị đám mây không giới hạn",
"Essential Text-to-Speech Voices": "Giọng nói chuyển văn bản thành giọng nói cơ bản",
"DeepL Free Access": "Truy cập DeepL miễn phí",
"Community Support": "Hỗ trợ cộng đồng",
"500 MB Cloud Sync Space": "500 MB không gian đồng bộ hóa đám mây",
"Includes All Free Tier Benefits": "Bao gồm tất cả lợi ích của gói miễn phí",
"AI Summaries": "Tóm tắt AI",
"AI Translations": "Dịch thuật AI",
"Priority Support": "Hỗ trợ ưu tiên",
"DeepL Pro Access": "Truy cập DeepL Pro",
"Expanded Text-to-Speech Voices": "Giọng nói chuyển văn bản thành giọng nói mở rộng",
"2000 MB Cloud Sync Space": "2000 MB không gian đồng bộ hóa đám mây",
"Includes All Plus Tier Benefits": "Bao gồm tất cả lợi ích của gói Plus",
"Unlimited AI Summaries": "Tóm tắt AI không giới hạn",
"Unlimited AI Translations": "Dịch thuật AI không giới hạn",
"Unlimited DeepL Pro Access": "Truy cập DeepL Pro không giới hạn",
"Advanced AI Tools": "Công cụ AI nâng cao",
"Early Feature Access": "Truy cập tính năng sớm",
"10 GB Cloud Sync Space": "10 GB không gian đồng bộ hóa đám mây",
"Loading profile...": "Đang tải hồ sơ...",
"Features": "Tính năng",
"Delete Account": "Xóa tài khoản",
"Delete Your Account?": "Xóa tài khoản của bạn?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Hành động này không thể hoàn tác. Tất cả dữ liệu của bạn trên đám mây sẽ bị xóa vĩnh viễn.",
"Delete Permanently": "Xóa vĩnh viễn",
"Free Tier": "Gói miễn phí",
"Plus Tier": "Gói Plus",
"Pro Tier": "Gói Pro",
"RTL Direction": "Hướng RTL",
"Maximum Column Height": "Chiều cao cột tối đa",
"Maximum Column Width": "Chiều rộng cột tối đa",
@@ -373,5 +356,44 @@
"Show Remaining Pages": "Hiển thị trang còn lại",
"Source Han Serif CN VF": "Source Han Serif",
"Huiwen-mincho": "Huiwen Mincho",
"KingHwa_OldSong": "KingHwa Song"
"KingHwa_OldSong": "KingHwa Song",
"Manage Subscription": "Quản lý đăng ký",
"Coming Soon": "Sắp ra mắt",
"Upgrade to {{plan}}": "Nâng cấp lên {{plan}}",
"Upgrade to Plus or Pro": "Nâng cấp lên Plus hoặc Pro",
"Current Plan": "Gói hiện tại",
"Plan Limits": "Giới hạn gói",
"Available Plans": "Gói khả dụng",
"{{current}} of {{all}}": "{{current}} trên {{all}}",
"Failed to manage subscription. Please try again later.": "Không thể quản lý đăng ký. Vui lòng thử lại sau.",
"Processing your payment...": "Đang xử lý thanh toán...",
"Please wait while we confirm your subscription.": "Vui lòng chờ trong khi chúng tôi xác nhận đăng ký của bạn.",
"Payment Processing": "Đang xử lý thanh toán",
"Your payment is being processed. This usually takes a few moments.": "Thanh toán của bạn đang được xử lý. Thường mất vài giây.",
"Payment Failed": "Thanh toán thất bại",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Chúng tôi không thể xử lý đăng ký của bạn. Vui lòng thử lại hoặc liên hệ hỗ trợ nếu sự cố tiếp tục.",
"Back to Profile": "Quay lại hồ sơ",
"Subscription Successful!": "Đăng ký thành công!",
"Thank you for your subscription! Your payment has been processed successfully.": "Cảm ơn bạn đã đăng ký! Thanh toán của bạn đã được xử lý thành công.",
"Email:": "Email:",
"Plan:": "Gói:",
"Amount:": "Số tiền:",
"Subscription ID:": "ID đăng ký:",
"Go to Library": "Đi đến Thư viện",
"Need help? Contact our support team at support@readest.com": "Cần hỗ trợ? Liên hệ nhóm hỗ trợ tại support@readest.com",
"Free Plan": "Gói miễn phí",
"month": "tháng",
"Unlimited Text-to-Speech Hours": "Không giới hạn giờ chuyển văn bản thành giọng nói",
"DeepL Free Access (10K characters/day)": "Truy cập DeepL miễn phí (10.000 ký tự/ngày)",
"AI Translations (per day)": "Dịch AI (mỗi ngày)",
"Cloud Storage": "Lưu trữ đám mây",
"Plus Plan": "Gói Plus",
"Includes All Free Plan Benefits": "Bao gồm tất cả lợi ích của gói miễn phí",
"Basic AI Translations": "Dịch AI cơ bản",
"DeepL Pro Access (50K characters/day)": "Truy cập DeepL Pro (50.000 ký tự/ngày)",
"2 GB Cloud Sync Space": "2 GB đồng bộ đám mây",
"Pro Plan": "Gói Pro",
"Includes All Plus Plan Benefits": "Bao gồm tất cả lợi ích của gói Plus",
"More AI Translations": "Thêm dịch AI",
"DeepL Pro Access (200K characters/day)": "Truy cập DeepL Pro (200.000 ký tự/ngày)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "使用 GitHub 登录",
"Account": "账户",
"Failed to delete user. Please try again later.": "删除用户失败。请稍后重试。",
"Unlimited Offline/Online Reading": "无限离线和在线阅读",
"Unlimited Cloud Sync Devices": "无限云同步设备个数",
"Essential Text-to-Speech Voices": "基础 TTS 语音包",
"DeepL Free Access": "免费版 DeepL 翻译",
"Community Support": "社区支持",
"500 MB Cloud Sync Space": "500 MB 云同步空间",
"Includes All Free Tier Benefits": "包含所有免费版权益",
"AI Summaries": "AI 摘要",
"AI Translations": "AI 翻译",
"Priority Support": "优先支持",
"DeepL Pro Access": "专业版 DeepL 翻译",
"Expanded Text-to-Speech Voices": "更多文本转语音声音",
"2000 MB Cloud Sync Space": "2000 MB 云同步空间",
"Includes All Plus Tier Benefits": "包含所有增强版权益",
"Unlimited AI Summaries": "无限使用 AI 摘要",
"Unlimited AI Translations": "无限使用 AI 翻译",
"Unlimited DeepL Pro Access": "无限使用专业版 DeepL 翻译",
"Advanced AI Tools": "高级 AI 工具",
"Early Feature Access": "抢先体验新功能",
"10 GB Cloud Sync Space": "10 GB 云同步空间",
"Loading profile...": "加载个人资料中...",
"Features": "功能特性",
"Delete Account": "删除账户",
"Delete Your Account?": "删除您的账户?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "此操作无法撤销。您在云端的所有数据将被永久删除。",
"Delete Permanently": "永久删除",
"Free Tier": "免费版",
"Plus Tier": "增强版",
"Pro Tier": "专业版",
"RTL Direction": "从右向左",
"Maximum Column Height": "最大列高",
"Maximum Column Width": "最大列宽",
@@ -373,5 +356,44 @@
"Show Remaining Pages": "显示剩余页数",
"Source Han Serif CN VF": "思源宋体",
"Huiwen-mincho": "汇文明朝体",
"KingHwa_OldSong": "京华老宋体"
"KingHwa_OldSong": "京华老宋体",
"Manage Subscription": "管理订阅",
"Coming Soon": "即将上线",
"Upgrade to {{plan}}": "升级到 {{plan}}",
"Upgrade to Plus or Pro": "升级到 Plus 或 Pro",
"Current Plan": "当前套餐",
"Plan Limits": "套餐限制",
"Available Plans": "可用套餐",
"{{current}} of {{all}}": "{{current}} / {{all}}",
"Failed to manage subscription. Please try again later.": "无法管理订阅,请稍后再试。",
"Processing your payment...": "正在处理付款...",
"Please wait while we confirm your subscription.": "请稍候,我们正在确认您的订阅。",
"Payment Processing": "付款处理中",
"Your payment is being processed. This usually takes a few moments.": "您的付款正在处理中,通常需要几秒钟。",
"Payment Failed": "付款失败",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "我们无法处理您的订阅。请重试,或如问题持续请联系支持。",
"Back to Profile": "返回个人资料",
"Subscription Successful!": "订阅成功!",
"Thank you for your subscription! Your payment has been processed successfully.": "感谢您的订阅!您的付款已成功处理。",
"Email:": "邮箱:",
"Plan:": "套餐:",
"Amount:": "金额:",
"Subscription ID:": "订阅 ID",
"Go to Library": "前往书库",
"Need help? Contact our support team at support@readest.com": "需要帮助?请联系支持团队:support@readest.com",
"Free Plan": "免费套餐",
"month": "月",
"Unlimited Text-to-Speech Hours": "无限文本转语音时长",
"DeepL Free Access (10K characters/day)": "DeepL 免费额度(每日1万字符)",
"AI Translations (per day)": "AI 翻译(每日)",
"Cloud Storage": "云存储",
"Plus Plan": "Plus 套餐",
"Includes All Free Plan Benefits": "包含所有免费套餐功能",
"Basic AI Translations": "基础 AI 翻译",
"DeepL Pro Access (50K characters/day)": "DeepL Pro(每日5万字符)",
"2 GB Cloud Sync Space": "2GB 云同步空间",
"Pro Plan": "Pro 套餐",
"Includes All Plus Plan Benefits": "包含所有 Plus 套餐功能",
"More AI Translations": "更多 AI 翻译",
"DeepL Pro Access (200K characters/day)": "DeepL Pro(每日20万字符)"
}
@@ -183,35 +183,18 @@
"Sign in with GitHub": "使用 GitHub 登入",
"Account": "帳戶",
"Failed to delete user. Please try again later.": "刪除使用者失敗。請稍後再試。",
"Unlimited Offline/Online Reading": "無限離線/線上閱讀",
"Unlimited Cloud Sync Devices": "無限雲端同步裝置",
"Essential Text-to-Speech Voices": "基本文字轉語音聲音",
"DeepL Free Access": "DeepL免費存取",
"Community Support": "社群支援",
"500 MB Cloud Sync Space": "500 MB雲端同步空間",
"Includes All Free Tier Benefits": "包含所有免費方案權益",
"AI Summaries": "AI摘要",
"AI Translations": "AI翻譯",
"Priority Support": "優先支援",
"DeepL Pro Access": "DeepL專業版存取",
"Expanded Text-to-Speech Voices": "擴展文字轉語音聲音",
"2000 MB Cloud Sync Space": "2000 MB雲端同步空間",
"Includes All Plus Tier Benefits": "包含所有Plus方案權益",
"Unlimited AI Summaries": "無限AI摘要",
"Unlimited AI Translations": "無限AI翻譯",
"Unlimited DeepL Pro Access": "無限DeepL專業版存取",
"Advanced AI Tools": "進階AI工具",
"Early Feature Access": "搶先體驗新功能",
"10 GB Cloud Sync Space": "10 GB雲端同步空間",
"Loading profile...": "載入個人資料中...",
"Features": "功能",
"Delete Account": "刪除帳戶",
"Delete Your Account?": "刪除您的帳戶?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "此操作無法撤銷。您在雲端的所有資料將被永久刪除。",
"Delete Permanently": "永久刪除",
"Free Tier": "免費方案",
"Plus Tier": "Plus方案",
"Pro Tier": "專業方案",
"RTL Direction": "從右向左",
"Maximum Column Height": "最大列高",
"Maximum Column Width": "最大列寬",
@@ -373,5 +356,44 @@
"Show Remaining Pages": "顯示剩餘頁數",
"Source Han Serif CN VF": "思源宋體",
"Huiwen-mincho": "匯文明朝體",
"KingHwa_OldSong": "京華老宋體"
"KingHwa_OldSong": "京華老宋體",
"Manage Subscription": "管理訂閱",
"Coming Soon": "即將推出",
"Upgrade to {{plan}}": "升級到 {{plan}}",
"Upgrade to Plus or Pro": "升級到 Plus 或 Pro",
"Current Plan": "當前方案",
"Plan Limits": "方案限制",
"Available Plans": "可用方案",
"{{current}} of {{all}}": "{{current}} / {{all}}",
"Failed to manage subscription. Please try again later.": "無法管理訂閱,請稍後再試。",
"Processing your payment...": "正在處理付款...",
"Please wait while we confirm your subscription.": "請稍候,我們正在確認您的訂閱。",
"Payment Processing": "付款處理中",
"Your payment is being processed. This usually takes a few moments.": "您的付款正在處理中,通常需要幾秒鐘。",
"Payment Failed": "付款失敗",
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "我們無法處理您的訂閱。請重試,或若問題持續,請聯絡客服。",
"Back to Profile": "返回個人資料",
"Subscription Successful!": "訂閱成功!",
"Thank you for your subscription! Your payment has been processed successfully.": "感謝您的訂閱!您的付款已成功完成。",
"Email:": "電子郵件:",
"Plan:": "方案:",
"Amount:": "金額:",
"Subscription ID:": "訂閱 ID",
"Go to Library": "前往書庫",
"Need help? Contact our support team at support@readest.com": "需要協助?請聯絡支援團隊:support@readest.com",
"Free Plan": "免費方案",
"month": "月",
"Unlimited Text-to-Speech Hours": "無限文字轉語音時數",
"DeepL Free Access (10K characters/day)": "DeepL 免費使用(每日1萬字)",
"AI Translations (per day)": "AI 翻譯(每日)",
"Cloud Storage": "雲端儲存",
"Plus Plan": "Plus 方案",
"Includes All Free Plan Benefits": "包含所有免費方案功能",
"Basic AI Translations": "基本 AI 翻譯",
"DeepL Pro Access (50K characters/day)": "DeepL Pro(每日5萬字)",
"2 GB Cloud Sync Space": "2GB 雲端同步空間",
"Pro Plan": "Pro 方案",
"Includes All Plus Plan Benefits": "包含所有 Plus 方案功能",
"More AI Translations": "更多 AI 翻譯",
"DeepL Pro Access (200K characters/day)": "DeepL Pro(每日20萬字)"
}
+2 -2
View File
@@ -19,8 +19,8 @@
"img-src": "'self' blob: data: asset: http://asset.localhost https://*",
"style-src": "'self' 'unsafe-inline' blob: asset: http://asset.localhost https://cdn.jsdelivr.net https://fonts.googleapis.com https://ik.imagekit.io",
"font-src": "'self' blob: data: asset: http://asset.localhost tauri: https://db.onlinewebfonts.com https://cdn.jsdelivr.net https://fonts.gstatic.com https://ik.imagekit.io",
"frame-src": "'self' blob: asset: http://asset.localhost",
"script-src": "'self' 'unsafe-inline' 'unsafe-eval' blob: asset: http://asset.localhost https://*.sentry.io https://*.posthog.com"
"frame-src": "'self' blob: asset: http://asset.localhost https://*.stripe.com",
"script-src": "'self' 'unsafe-inline' 'unsafe-eval' blob: asset: http://asset.localhost https://*.sentry.io https://*.posthog.com https://*.stripe.com"
},
"assetProtocol": {
"enable": true,
@@ -0,0 +1,107 @@
import { useState } from 'react';
import { useTranslation } from '@/hooks/useTranslation';
import { UserPlan } from '@/types/user';
interface DeleteConfirmationModalProps {
show: boolean;
onCancel: () => void;
onConfirm: () => void;
}
const DeleteConfirmationModal: React.FC<DeleteConfirmationModalProps> = ({
show,
onCancel,
onConfirm,
}) => {
const _ = useTranslation();
if (!show) return null;
return (
<div className='fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50 p-4'>
<div className='w-full max-w-md rounded-2xl bg-white p-6'>
<h3 className='mb-4 text-xl font-bold text-gray-800'>{_('Delete Your Account?')}</h3>
<p className='mb-6 text-gray-600'>
{_(
'This action cannot be undone. All your data in the cloud will be permanently deleted.',
)}
</p>
<div className='flex flex-col gap-3 sm:flex-row'>
<button
onClick={onCancel}
className='flex-1 rounded-lg bg-gray-300 px-4 py-2 font-medium text-gray-800 hover:bg-gray-400'
>
{_('Cancel')}
</button>
<button
onClick={onConfirm}
className='flex-1 rounded-lg bg-red-500 px-4 py-2 font-medium text-white hover:bg-red-600'
>
{_('Delete Permanently')}
</button>
</div>
</div>
</div>
);
};
interface AccountActionsProps {
userPlan: UserPlan;
onLogout: () => void;
onConfirmDelete: () => void;
onManageSubscription: () => void;
}
const AccountActions: React.FC<AccountActionsProps> = ({
userPlan,
onLogout,
onConfirmDelete,
onManageSubscription,
}) => {
const _ = useTranslation();
const [showConfirmDelete, setShowConfirmDelete] = useState(false);
const handleDeleteRequest = () => {
setShowConfirmDelete(true);
};
const handleCancelDelete = () => {
setShowConfirmDelete(false);
};
return (
<>
<DeleteConfirmationModal
show={showConfirmDelete}
onCancel={handleCancelDelete}
onConfirm={async () => {
await onConfirmDelete();
setShowConfirmDelete(false);
}}
/>
<div className='flex flex-col gap-4 md:flex-row'>
{userPlan !== 'free' && (
<button
onClick={onManageSubscription}
className='w-full rounded-lg bg-blue-100 px-6 py-3 font-medium text-blue-600 transition-colors hover:bg-blue-200 md:w-auto'
>
{_('Manage Subscription')}
</button>
)}
<button
onClick={onLogout}
className='w-full rounded-lg bg-gray-200 px-6 py-3 font-medium text-gray-800 transition-colors hover:bg-gray-300 md:w-auto'
>
{_('Sign Out')}
</button>
<button
onClick={handleDeleteRequest}
className='w-full rounded-lg bg-red-100 px-6 py-3 font-medium text-red-600 transition-colors hover:bg-red-200 md:w-auto'
>
{_('Delete Account')}
</button>
</div>
</>
);
};
export default AccountActions;
@@ -0,0 +1,41 @@
import clsx from 'clsx';
import { useRef } from 'react';
import { IoArrowBack } from 'react-icons/io5';
import { useEnv } from '@/context/EnvContext';
import { useTrafficLightStore } from '@/store/trafficLightStore';
import WindowButtons from '@/components/WindowButtons';
interface ProfileHeaderProps {
onGoBack: () => void;
}
const ProfileHeader: React.FC<ProfileHeaderProps> = ({ onGoBack }) => {
const { appService } = useEnv();
const { isTrafficLightVisible } = useTrafficLightStore();
const headerRef = useRef<HTMLDivElement>(null);
return (
<div
ref={headerRef}
className={clsx(
'fixed z-30 flex w-full items-center justify-between py-2 pe-6 ps-4',
appService?.hasTrafficLight && 'pt-11',
)}
>
<button onClick={onGoBack} className={clsx('btn btn-ghost h-8 min-h-8 w-8 p-0')}>
<IoArrowBack className='text-base-content' />
</button>
{appService?.hasWindowBar && (
<WindowButtons
headerRef={headerRef}
showMinimize={!isTrafficLightVisible}
showMaximize={!isTrafficLightVisible}
showClose={!isTrafficLightVisible}
onClose={onGoBack}
/>
)}
</div>
);
};
export default ProfileHeader;
@@ -0,0 +1,69 @@
import { useTranslation } from '@/hooks/useTranslation';
import { PlanDetails } from '../utils/plan';
interface PlanActionButtonProps {
plan: PlanDetails;
isUserPlan: boolean;
comingSoon?: boolean;
upgradable?: boolean;
onSubscribe: (priceId?: string) => void;
onPlanSwipe: (direction: 'left' | 'right') => void;
}
const PlanActionButton: React.FC<PlanActionButtonProps> = ({
plan,
isUserPlan,
comingSoon,
upgradable,
onSubscribe,
onPlanSwipe,
}) => {
const _ = useTranslation();
if (upgradable && plan.plan !== 'free' && !isUserPlan) {
if (comingSoon) {
return (
<button
disabled
className='w-full cursor-default rounded-lg bg-gray-200 px-6 py-3 font-semibold text-gray-500'
>
{_('Coming Soon')}
</button>
);
}
return (
<button
onClick={() => onSubscribe(plan.price_id)}
className='w-full rounded-lg bg-blue-600 px-6 py-3 font-semibold text-white transition-colors hover:bg-blue-700'
>
{_('Upgrade to {{plan}}', { plan: _(plan.name) })}
</button>
);
}
if (plan.plan === 'free' && isUserPlan) {
return (
<button
onClick={() => onPlanSwipe('left')}
className='w-full rounded-lg bg-blue-600 px-6 py-3 font-semibold text-white transition-colors hover:bg-blue-700'
>
{_('Upgrade to Plus or Pro')}
</button>
);
}
if (isUserPlan) {
return (
<button
disabled
className='w-full cursor-default rounded-lg bg-green-100 px-6 py-3 font-semibold text-green-700'
>
{_('Current Plan')}
</button>
);
}
return null;
};
export default PlanActionButton;
@@ -0,0 +1,88 @@
import { IoCheckmark } from 'react-icons/io5';
import { useTranslation } from '@/hooks/useTranslation';
import { PlanDetails } from '../utils/plan';
import PlanActionButton from './PlanActionButton';
interface PlanCardProps {
plan: PlanDetails;
isUserPlan: boolean;
comingSoon?: boolean;
upgradable?: boolean;
index: number;
currentPlanIndex: number;
onSubscribe: (priceId?: string) => void;
onPlanSwipe: (direction: 'left' | 'right') => void;
}
const PlanCard: React.FC<PlanCardProps> = ({
plan,
isUserPlan,
comingSoon,
upgradable,
index,
currentPlanIndex,
onSubscribe,
onPlanSwipe,
}) => {
const _ = useTranslation();
return (
<div
key={plan.plan}
className='w-full min-w-72 max-w-96 flex-shrink-0 p-6'
style={{ scrollSnapAlign: 'start' }}
>
<div
className={`rounded-xl border-2 p-6 ${plan.color} ${index === currentPlanIndex ? 'ring-2 ring-blue-500' : ''}`}
>
<div className='mb-6 text-center'>
<h4 className='mb-2 text-2xl font-bold'>{_(plan.name)}</h4>
<div className='text-3xl font-bold'>
{`$${(plan.price / 100).toFixed(2)}`}
<span className='text-lg font-normal'>/{_(plan.interval)}</span>
</div>
{isUserPlan && (
<div className='mt-3'>
<span className='inline-flex items-center rounded-full bg-green-100 px-3 py-1 text-sm font-medium text-green-800'>
<IoCheckmark className='mr-1 h-4 w-4' />
{_('Current Plan')}
</span>
</div>
)}
</div>
<div className='mb-6 space-y-3'>
{plan.features.map((feature, featureIndex) => (
<div key={featureIndex} className='flex items-center'>
<IoCheckmark className='mr-3 h-5 w-5 flex-shrink-0 text-green-500' />
<span>{_(feature)}</span>
</div>
))}
</div>
<div className='mb-6 rounded-lg bg-white/50 p-4'>
<h5 className='mb-3 font-semibold'>{_('Plan Limits')}</h5>
<div className='space-y-2'>
{Object.entries(plan.limits).map(([key, value]) => (
<div key={key} className='flex justify-between text-sm'>
<span>{_(key)}:</span>
<span className='font-medium'>{value}</span>
</div>
))}
</div>
</div>
<PlanActionButton
plan={plan}
comingSoon={comingSoon}
upgradable={upgradable}
isUserPlan={isUserPlan}
onSubscribe={onSubscribe}
onPlanSwipe={onPlanSwipe}
/>
</div>
</div>
);
};
export default PlanCard;
@@ -0,0 +1,27 @@
import { PlanDetails } from '../utils/plan';
interface PlanIndicatorsProps {
allPlans: PlanDetails[];
currentPlanIndex: number;
onPlanSelect: (index: number) => void;
}
const PlanIndicators: React.FC<PlanIndicatorsProps> = ({
allPlans,
currentPlanIndex,
onPlanSelect,
}) => (
<div className='flex justify-center space-x-2 pb-6 pt-2'>
{allPlans.map((_, index) => (
<button
key={index}
onClick={() => onPlanSelect(index)}
className={`h-2 w-2 rounded-full transition-colors ${
index === currentPlanIndex ? 'bg-blue-500' : 'bg-gray-300'
}`}
/>
))}
</div>
);
export default PlanIndicators;
@@ -0,0 +1,48 @@
import { IoChevronBack, IoChevronForward } from 'react-icons/io5';
import { useTranslation } from '@/hooks/useTranslation';
interface PlanNavigationProps {
currentPlanIndex: number;
totalPlans: number;
onPlanSwipe: (direction: 'left' | 'right') => void;
}
const PlanNavigation: React.FC<PlanNavigationProps> = ({
currentPlanIndex,
totalPlans,
onPlanSwipe,
}) => {
const _ = useTranslation();
return (
<div className='border-b bg-gray-50 px-6 py-4'>
<div className='flex items-center justify-between'>
<h3 className='text-lg font-semibold'>{_('Available Plans')}</h3>
<div className='flex items-center space-x-2'>
<button
onClick={() => onPlanSwipe('right')}
disabled={currentPlanIndex === 0}
className='rounded-lg p-1 hover:bg-gray-200 disabled:cursor-not-allowed disabled:opacity-50'
>
<IoChevronBack className='h-5 w-5' />
</button>
<span className='text-sm text-gray-600'>
{_('{{current}} of {{all}}', {
current: currentPlanIndex + 1,
all: totalPlans,
})}
</span>
<button
onClick={() => onPlanSwipe('left')}
disabled={currentPlanIndex === totalPlans - 1}
className='rounded-lg p-1 hover:bg-gray-200 disabled:cursor-not-allowed disabled:opacity-50'
>
<IoChevronForward className='h-5 w-5' />
</button>
</div>
</div>
</div>
);
};
export default PlanNavigation;
@@ -0,0 +1,160 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import { debounce } from '@/utils/debounce';
import { isWebAppPlatform } from '@/services/environment';
import { getPlanDetails } from '../utils/plan';
import { AvailablePlan } from '../page';
import { UserPlan } from '@/types/user';
import PlanNavigation from './PlanNavigation';
import PlanCard from './PlanCard';
import PlanIndicators from './PlanIndicators';
interface PlansComparisonProps {
availablePlans: AvailablePlan[];
userPlan: UserPlan;
onSubscribe: (priceId?: string) => void;
}
const PlansComparison: React.FC<PlansComparisonProps> = ({
availablePlans,
userPlan,
onSubscribe,
}) => {
const [currentPlanIndex, setCurrentPlanIndex] = useState(0);
const [userPlanIndex, setUserPlanIndex] = useState(0);
const plansScrollRef = useRef<HTMLDivElement>(null);
const userPlans: UserPlan[] = ['free', 'plus', 'pro'];
useEffect(() => {
if (userPlan) {
const initialPlanIndex = userPlans.indexOf(userPlan);
setCurrentPlanIndex(Math.max(0, initialPlanIndex));
setUserPlanIndex(Math.max(0, initialPlanIndex));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [userPlan]);
const handlePlanSwipe = (direction: 'left' | 'right') => {
if (direction === 'left' && currentPlanIndex < allPlans.length - 1) {
setCurrentPlanIndex(currentPlanIndex + 1);
} else if (direction === 'right' && currentPlanIndex > 0) {
setCurrentPlanIndex(currentPlanIndex - 1);
}
};
const handleTouchStart = (e: React.TouchEvent) => {
const touchStart = e.touches[0]!.clientX;
const handleTouchMove = (moveEvent: TouchEvent) => {
const touchEnd = moveEvent.touches[0]!.clientX;
const diff = touchStart - touchEnd;
if (Math.abs(diff) > 50) {
if (diff > 0) {
handlePlanSwipe('left');
} else {
handlePlanSwipe('right');
}
document.removeEventListener('touchmove', handleTouchMove);
}
};
const handleTouchEnd = () => {
document.removeEventListener('touchmove', handleTouchMove);
document.removeEventListener('touchend', handleTouchEnd);
};
document.addEventListener('touchmove', handleTouchMove);
document.addEventListener('touchend', handleTouchEnd);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
const handleScroll = useCallback(
debounce(() => {
if (plansScrollRef.current) {
const container = plansScrollRef.current;
const scrollLeft = container.scrollLeft;
const containerWidth = container.clientWidth;
const scrollWidth = container.scrollWidth;
const cardWidth = scrollWidth / allPlans.length;
const viewportCenter = scrollLeft + containerWidth / 2;
const newIndex = Math.floor(viewportCenter / cardWidth);
const clampedIndex = Math.max(0, Math.min(newIndex, allPlans.length - 1));
if (clampedIndex !== currentPlanIndex) {
setCurrentPlanIndex(clampedIndex);
}
}
}, 100),
[currentPlanIndex],
);
useEffect(() => {
if (!plansScrollRef.current) return;
const container = plansScrollRef.current;
container.addEventListener('scroll', handleScroll);
return () => {
container.removeEventListener('scroll', handleScroll);
};
}, [currentPlanIndex, handleScroll]);
useEffect(() => {
if (plansScrollRef.current) {
const planWidth = plansScrollRef.current.scrollWidth / allPlans.length;
const scrollPosition = currentPlanIndex * planWidth;
plansScrollRef.current.scrollTo({
left: scrollPosition,
behavior: 'smooth',
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentPlanIndex]);
const allPlans = userPlans.map((plan) => ({
...getPlanDetails(plan, availablePlans),
}));
return (
<div className='overflow-hidden rounded-xl border bg-white shadow-sm'>
<PlanNavigation
currentPlanIndex={currentPlanIndex}
totalPlans={allPlans.length}
onPlanSwipe={handlePlanSwipe}
/>
<div
ref={plansScrollRef}
className='scrollbar-hide flex items-center overflow-x-auto scroll-smooth pe-20'
onTouchStart={handleTouchStart}
style={{
scrollSnapType: 'x mandatory',
scrollbarWidth: 'none',
msOverflowStyle: 'none',
}}
>
{allPlans.map((plan, index) => (
<PlanCard
key={plan.plan}
plan={plan}
comingSoon={!isWebAppPlatform()}
isUserPlan={plan.plan === userPlan}
upgradable={index > userPlanIndex}
index={index}
currentPlanIndex={currentPlanIndex}
onSubscribe={onSubscribe}
onPlanSwipe={handlePlanSwipe}
/>
))}
</div>
<PlanIndicators
allPlans={allPlans}
currentPlanIndex={currentPlanIndex}
onPlanSelect={setCurrentPlanIndex}
/>
</div>
);
};
export default PlansComparison;
@@ -0,0 +1,20 @@
import Quota from '@/components/Quota';
import { QuotaType } from '@/types/user';
interface UsageStatsProps {
quotas: QuotaType[];
}
const UsageStats: React.FC<UsageStatsProps> = ({ quotas }) => (
<div className='rounded-lg'>
<div className='p-0'>
{quotas && quotas.length > 0 ? (
<Quota quotas={quotas} showProgress className='space-y-4' labelClassName='pl-4 pr-2' />
) : (
<div className='h-10 animate-pulse'></div>
)}
</div>
</div>
);
export default UsageStats;
@@ -0,0 +1,42 @@
import { PiUserCircle } from 'react-icons/pi';
import { PlanDetails } from '../utils/plan';
import UserAvatar from '@/components/UserAvatar';
interface UserInfoProps {
avatarUrl?: string;
userFullName: string;
userEmail: string;
planDetails: PlanDetails;
}
const UserInfo: React.FC<UserInfoProps> = ({ avatarUrl, userFullName, userEmail, planDetails }) => (
<div className='flex flex-col items-center gap-x-6 gap-y-4 md:flex-row md:items-start'>
<div className='flex-shrink-0'>
{avatarUrl ? (
<UserAvatar
url={avatarUrl}
size={128}
DefaultIcon={PiUserCircle}
className='h-16 w-16 md:h-24 md:w-24'
borderClassName='border-base-100 border-4'
/>
) : (
<PiUserCircle className='h-16 w-16 md:h-24 md:w-24' />
)}
</div>
<div className='flex-grow text-center md:text-left'>
<h2 className='text-base-content text-xl font-bold md:text-2xl'>{userFullName}</h2>
<p className='text-base-content/60'>{userEmail}</p>
<div className='mt-3'>
<span
className={`inline-block rounded-full px-3 py-1 text-sm font-medium ${planDetails.color}`}
>
{planDetails.name}
</span>
</div>
</div>
</div>
);
export default UserInfo;
+108 -190
View File
@@ -1,36 +1,54 @@
'use client';
import clsx from 'clsx';
import React, { useState, useRef } from 'react';
import Stripe from 'stripe';
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { IoArrowBack } from 'react-icons/io5';
import { PiUserCircle } from 'react-icons/pi';
import { useEnv } from '@/context/EnvContext';
import { useAuth } from '@/context/AuthContext';
import { useTheme } from '@/hooks/useTheme';
import { useQuotaStats } from '@/hooks/useQuotaStats';
import { useTranslation } from '@/hooks/useTranslation';
import { useSettingsStore } from '@/store/settingsStore';
import { useTrafficLightStore } from '@/store/trafficLightStore';
import { UserPlan } from '@/types/user';
import { navigateToLibrary } from '@/utils/nav';
import { deleteUser } from '@/libs/user';
import { eventDispatcher } from '@/utils/event';
import { getStripe } from '@/libs/stripe/client';
import { getAPIBaseUrl } from '@/services/environment';
import { getAccessToken } from '@/utils/access';
import { getPlanDetails } from './utils/plan';
import { Toast } from '@/components/Toast';
import WindowButtons from '@/components/WindowButtons';
import Quota from '@/components/Quota';
import UserAvatar from '@/components/UserAvatar';
import ProfileHeader from './components/Header';
import UserInfo from './components/UserInfo';
import UsageStats from './components/UsageStats';
import PlansComparison from './components/PlansComparison';
import AccountActions from './components/AccountActions';
const WEB_STRIPE_PLANS_URL = `${getAPIBaseUrl()}/stripe/plans`;
const WEB_STRIPE_CHECKOUT_URL = `${getAPIBaseUrl()}/stripe/checkout`;
const WEB_STRIPE_PORTAL_URL = `${getAPIBaseUrl()}/stripe/portal`;
export type AvailablePlan = {
plan: UserPlan;
price_id: string;
price: number;
currency: string;
interval: string;
product: Stripe.Product;
};
const ProfilePage = () => {
const _ = useTranslation();
const router = useRouter();
const { envConfig, appService } = useEnv();
const { token, user, logout } = useAuth();
const { isTrafficLightVisible } = useTrafficLightStore();
const { settings, setSettings, saveSettings } = useSettingsStore();
const [showConfirmDelete, setShowConfirmDelete] = useState(false);
const headerRef = useRef<HTMLDivElement>(null);
const [availablePlans, setAvailablePlans] = useState<AvailablePlan[]>([]);
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
useTheme({ systemUIVisible: false });
@@ -48,14 +66,6 @@ const ProfilePage = () => {
navigateToLibrary(router);
};
const handleDeleteRequest = () => {
setShowConfirmDelete(true);
};
const handleCancelDelete = () => {
setShowConfirmDelete(false);
};
const handleConfirmDelete = async () => {
try {
await deleteUser();
@@ -67,55 +77,69 @@ const ProfilePage = () => {
message: _('Failed to delete user. Please try again later.'),
});
}
setShowConfirmDelete(false);
};
const getPlanDetails = (userPlan: UserPlan) => {
switch (userPlan) {
case 'free':
return {
name: _('Free Tier'),
color: 'bg-gray-200 text-gray-800',
features: [
_('Community Support'),
_('DeepL Free Access'),
_('Essential Text-to-Speech Voices'),
_('Unlimited Offline/Online Reading'),
_('Unlimited Cloud Sync Devices'),
_('500 MB Cloud Sync Space'),
],
};
case 'plus':
return {
name: _('Plus Tier'),
color: 'bg-blue-200 text-blue-800',
features: [
_('Includes All Free Tier Benefits'),
_('Priority Support'),
_('AI Summaries'),
_('AI Translations'),
_('DeepL Pro Access'),
_('Expanded Text-to-Speech Voices'),
_('2000 MB Cloud Sync Space'),
],
};
case 'pro':
return {
name: _('Pro Tier'),
color: 'bg-purple-200 text-purple-800',
features: [
_('Includes All Plus Tier Benefits'),
_('Unlimited AI Summaries'),
_('Unlimited AI Translations'),
_('Unlimited DeepL Pro Access'),
_('Advanced AI Tools'),
_('Early Feature Access'),
_('10 GB Cloud Sync Space'),
],
};
const handleSubscribe = async (priceId?: string) => {
const token = await getAccessToken();
const stripe = await getStripe();
if (!stripe) {
console.error('Stripe not loaded');
return;
}
const { sessionId, url } = await fetch(WEB_STRIPE_CHECKOUT_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({ priceId }),
}).then((res) => res.json());
if (url) {
window.location.href = url;
} else {
const result = await stripe.redirectToCheckout({ sessionId });
if (result.error) {
console.error(result.error);
}
}
};
const handleManageSubscription = async () => {
const token = await getAccessToken();
const response = await fetch(WEB_STRIPE_PORTAL_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
});
const { url, error } = await response.json();
if (error) {
console.error('Error creating portal session:', error);
eventDispatcher.dispatch('toast', {
type: 'error',
message: _('Failed to manage subscription. Please try again later.'),
});
return;
}
window.location.href = url;
};
useEffect(() => {
fetch(WEB_STRIPE_PLANS_URL)
.then((res) => res.json())
.then((data) => setAvailablePlans(data));
}, []);
if (!mounted) {
return null;
}
if (!user || !token) {
return (
<div className='mx-auto max-w-4xl px-4 py-8'>
@@ -131,7 +155,8 @@ const ProfilePage = () => {
const avatarUrl = user?.user_metadata?.['picture'] || user?.user_metadata?.['avatar_url'];
const userFullName = user?.user_metadata?.['full_name'] || '-';
const userEmail = user?.email || '';
const planDetails = getPlanDetails(userPlan) || getPlanDetails('free');
const planDetails =
getPlanDetails(userPlan, availablePlans) || getPlanDetails('free', availablePlans);
return (
<div
@@ -141,140 +166,33 @@ const ProfilePage = () => {
appService?.hasSafeAreaInset && 'pt-[env(safe-area-inset-top)]',
)}
>
<div
ref={headerRef}
className={clsx(
'fixed flex w-full items-center justify-between py-2 pe-6 ps-4',
appService?.hasTrafficLight && 'pt-11',
)}
>
<button onClick={handleGoBack} className={clsx('btn btn-ghost h-8 min-h-8 w-8 p-0')}>
<IoArrowBack className='text-base-content' />
</button>
{appService?.hasWindowBar && (
<WindowButtons
headerRef={headerRef}
showMinimize={!isTrafficLightVisible}
showMaximize={!isTrafficLightVisible}
showClose={!isTrafficLightVisible}
onClose={handleGoBack}
/>
)}
</div>
<ProfileHeader onGoBack={handleGoBack} />
<div className='w-full min-w-60 max-w-4xl px-4 py-10'>
<div className='bg-base-200 overflow-hidden rounded-lg p-2 shadow-md sm:p-6'>
<div className='p-2 sm:p-6'>
<div className='mb-8 flex flex-col items-center gap-x-6 gap-y-4 md:flex-row md:items-start'>
<div className='flex-shrink-0'>
{avatarUrl ? (
<UserAvatar
url={avatarUrl}
size={128}
DefaultIcon={PiUserCircle}
className='h-16 w-16 md:h-24 md:w-24'
borderClassName='border-base-100 border-4'
/>
) : (
<PiUserCircle className='h-16 w-16 md:h-24 md:w-24' />
)}
</div>
<div className='flex flex-col gap-y-8 p-2 sm:p-6'>
<UserInfo
avatarUrl={avatarUrl}
userFullName={userFullName}
userEmail={userEmail}
planDetails={planDetails}
/>
<div className='flex-grow text-center md:text-left'>
<h2 className='text-base-content text-xl font-bold md:text-2xl'>{userFullName}</h2>
<p className='text-base-content/60'>{userEmail}</p>
<div className='mt-3'>
<span
className={`inline-block rounded-full px-3 py-1 text-sm font-medium ${planDetails.color}`}
>
{planDetails.name}
</span>
</div>
</div>
</div>
<UsageStats quotas={quotas} />
<div className='bg-base-100 mb-8 rounded-lg px-4 py-6'>
<h3 className='text-base-content mb-2 text-lg font-semibold'>{_('Features')}</h3>
<div className='mt-6'>
<ul className='text-base-content/60 grid grid-cols-1 gap-2 md:grid-cols-2'>
{planDetails.features.map((feature, index) => (
<li key={index} className='flex items-center'>
<svg
className='mr-2 h-4 w-4 text-green-500'
fill='currentColor'
viewBox='0 0 20 20'
>
<path
fillRule='evenodd'
d='M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z'
clipRule='evenodd'
/>
</svg>
{feature}
</li>
))}
</ul>
</div>
</div>
<PlansComparison
availablePlans={availablePlans}
userPlan={userPlan}
onSubscribe={handleSubscribe}
/>
<div className='mb-8 rounded-lg'>
<div className='p-0'>
{quotas && quotas.length > 0 ? (
<Quota
quotas={quotas}
showProgress
className='space-y-4'
labelClassName='pl-4 pr-2'
/>
) : (
<div className='h-10 animate-pulse'></div>
)}
</div>
</div>
<div className='flex flex-col gap-4 md:flex-row'>
<button
onClick={handleLogout}
className='w-full rounded-lg bg-gray-200 px-6 py-3 font-medium text-gray-800 transition-colors hover:bg-gray-300 md:w-auto'
>
{_('Sign Out')}
</button>
<button
onClick={handleDeleteRequest}
className='w-full rounded-lg bg-red-100 px-6 py-3 font-medium text-red-600 transition-colors hover:bg-red-200 md:w-auto'
>
{_('Delete Account')}
</button>
</div>
<AccountActions
userPlan={userPlan}
onLogout={handleLogout}
onConfirmDelete={handleConfirmDelete}
onManageSubscription={handleManageSubscription}
/>
</div>
</div>
{showConfirmDelete && (
<div className='fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50 p-4'>
<div className='w-full max-w-md rounded-2xl bg-white p-6'>
<h3 className='mb-4 text-xl font-bold text-gray-800'>{_('Delete Your Account?')}</h3>
<p className='mb-6 text-gray-600'>
{_(
'This action cannot be undone. All your data in the cloud will be permanently deleted.',
)}
</p>
<div className='flex flex-col gap-3 sm:flex-row'>
<button
onClick={handleCancelDelete}
className='flex-1 rounded-lg bg-gray-300 px-4 py-2 font-medium text-gray-800 hover:bg-gray-400'
>
{_('Cancel')}
</button>
<button
onClick={handleConfirmDelete}
className='flex-1 rounded-lg bg-red-500 px-4 py-2 font-medium text-white hover:bg-red-600'
>
{_('Delete Permanently')}
</button>
</div>
</div>
</div>
)}
</div>
<Toast />
</div>
@@ -0,0 +1,300 @@
'use client';
import { Suspense, useEffect, useState } from 'react';
import { useSearchParams, useRouter } from 'next/navigation';
import { useTranslation } from '@/hooks/useTranslation';
import { getAPIBaseUrl } from '@/services/environment';
import { getAccessToken } from '@/utils/access';
import { supabase } from '@/utils/supabase';
import Spinner from '@/components/Spinner';
const WEB_STRIPE_CHECK_URL = `${getAPIBaseUrl()}/stripe/check`;
interface SessionStatus {
status: 'loading' | 'complete' | 'failed' | 'processing';
customerEmail: string;
subscriptionId?: string;
planName?: string;
amount?: number;
currency?: string;
}
const SuccessPageWithSearchParams = () => {
const _ = useTranslation();
const [sessionStatus, setSessionStatus] = useState<SessionStatus>({
status: 'loading',
customerEmail: '',
});
const [retryCount, setRetryCount] = useState(0);
const searchParams = useSearchParams();
const router = useRouter();
const sessionId = searchParams?.get('session_id');
async function fetchSessionStatus() {
try {
const token = await getAccessToken();
const response = await fetch(WEB_STRIPE_CHECK_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({ sessionId }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const { session, error } = await response.json();
if (error) {
setSessionStatus((prev) => ({ ...prev, status: 'failed' }));
console.error('Session check error:', error);
return;
}
setSessionStatus({
status:
session.payment_status === 'paid' ? 'complete' : session.payment_status || 'processing',
customerEmail: session.customer_email || session.customer_details?.email || '',
subscriptionId: session.subscription,
planName:
session.display_items?.[0]?.custom?.name || session.line_items?.data?.[0]?.description,
amount: session.amount_total,
currency: session.currency,
});
try {
await supabase.auth.refreshSession();
} catch {}
} catch (error) {
console.error('Failed to fetch session status:', error);
setSessionStatus((prev) => ({ ...prev, status: 'failed' }));
}
}
const handleRetry = () => {
setRetryCount(0);
setSessionStatus((prev) => ({ ...prev, status: 'loading' }));
fetchSessionStatus();
};
const handleGoToLibrary = () => {
router.push('/library');
};
const handleGoToProfile = () => {
router.push('/user');
};
useEffect(() => {
if (!sessionId) {
handleGoToProfile();
return;
}
fetchSessionStatus();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [sessionId, router]);
useEffect(() => {
if (sessionStatus.status === 'processing' && retryCount < 3) {
const timer = setTimeout(() => {
setRetryCount((prev) => prev + 1);
fetchSessionStatus();
}, 2000);
return () => clearTimeout(timer);
} else {
return;
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [sessionStatus.status, retryCount]);
// Loading state
if (sessionStatus.status === 'loading') {
return (
<div className='flex min-h-screen items-center justify-center bg-gray-50'>
<div className='text-center'>
<div className='mx-auto mb-4 h-12 w-12 animate-spin rounded-full border-b-2 border-blue-600'></div>
<h2 className='mb-2 text-xl font-semibold text-gray-800'>
{_('Processing your payment...')}
</h2>
<p className='text-gray-600'>{_('Please wait while we confirm your subscription.')}</p>
</div>
</div>
);
}
// Processing state (payment still being processed)
if (sessionStatus.status === 'processing') {
return (
<div className='flex min-h-screen items-center justify-center bg-gray-50'>
<div className='max-w-md text-center'>
<div className='mx-auto mb-4 flex h-12 w-12 animate-pulse items-center justify-center rounded-full bg-yellow-400'>
<svg
className='h-6 w-6 text-white'
fill='none'
stroke='currentColor'
viewBox='0 0 24 24'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z'
/>
</svg>
</div>
<h2 className='mb-2 text-xl font-semibold text-gray-800'>{_('Payment Processing')}</h2>
<p className='mb-4 text-gray-600'>
{_('Your payment is being processed. This usually takes a few moments.')}
</p>
</div>
</div>
);
}
// Failed state
if (sessionStatus.status === 'failed') {
return (
<div className='flex min-h-screen items-center justify-center bg-gray-50'>
<div className='max-w-md text-center'>
<div className='mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
<svg
className='h-6 w-6 text-red-600'
fill='none'
stroke='currentColor'
viewBox='0 0 24 24'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M6 18L18 6M6 6l12 12'
/>
</svg>
</div>
<h2 className='mb-2 text-xl font-semibold text-gray-800'>{_('Payment Failed')}</h2>
<p className='mb-6 text-gray-600'>
{_(
"We couldn't process your subscription. Please try again or contact support if the issue persists.",
)}
</p>
<div className='space-y-3'>
<button
onClick={handleRetry}
className='w-full rounded-lg bg-blue-600 px-4 py-2 font-medium text-white transition-colors duration-200 hover:bg-blue-700'
>
{_('Try Again')}
</button>
<button
onClick={handleGoToProfile}
className='w-full rounded-lg bg-gray-200 px-4 py-2 font-medium text-gray-800 transition-colors duration-200 hover:bg-gray-300'
>
{_('Back to Profile')}
</button>
</div>
</div>
</div>
);
}
// Success state
return (
<div className='flex min-h-screen items-center justify-center bg-gray-50'>
<div className='mx-auto max-w-2xl px-4 text-center'>
{/* Success Icon */}
<div className='mx-auto mb-6 flex h-16 w-16 items-center justify-center rounded-full bg-green-100'>
<svg
className='h-8 w-8 text-green-600'
fill='none'
stroke='currentColor'
viewBox='0 0 24 24'
>
<path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M5 13l4 4L19 7' />
</svg>
</div>
{/* Success Message */}
<h1 className='mb-4 text-3xl font-bold text-gray-800'>
🎉 {_('Subscription Successful!')}
</h1>
<div className='mb-6 rounded-lg bg-white p-6 shadow-md'>
<p className='mb-4 text-lg text-gray-700'>
{_('Thank you for your subscription! Your payment has been processed successfully.')}
</p>
{/* Subscription Details */}
<div className='space-y-2 text-left text-sm text-gray-600'>
{sessionStatus.customerEmail && (
<div className='flex justify-between'>
<span className='font-medium'>{_('Email:')}</span>
<span>{sessionStatus.customerEmail}</span>
</div>
)}
{sessionStatus.planName && (
<div className='flex justify-between'>
<span className='font-medium'>{_('Plan:')}</span>
<span>{sessionStatus.planName}</span>
</div>
)}
{sessionStatus.amount && sessionStatus.currency && (
<div className='flex justify-between'>
<span className='font-medium'>{_('Amount:')}</span>
<span>
{new Intl.NumberFormat('en-US', {
style: 'currency',
currency: sessionStatus.currency.toUpperCase(),
}).format(sessionStatus.amount / 100)}
</span>
</div>
)}
{sessionStatus.subscriptionId && (
<div className='flex justify-between'>
<span className='font-medium'>{_('Subscription ID:')}</span>
<span className='font-mono text-xs'>{sessionStatus.subscriptionId}</span>
</div>
)}
</div>
</div>
{/* Action Buttons */}
<div className='space-y-3 sm:flex sm:justify-center sm:space-x-4 sm:space-y-0'>
<button
onClick={handleGoToLibrary}
className='w-full rounded-lg bg-blue-600 px-6 py-3 font-medium text-white transition-colors duration-200 hover:bg-blue-700 sm:w-auto'
>
{_('Go to Library')}
</button>
<button
onClick={handleGoToProfile}
className='w-full rounded-lg bg-gray-200 px-6 py-3 font-medium text-gray-800 transition-colors duration-200 hover:bg-gray-300 sm:w-auto'
>
{_('Back to Profile')}
</button>
</div>
{/* Additional Info */}
<div className='mt-8 text-xs text-gray-500'>
<p>{_('Need help? Contact our support team at support@readest.com')}</p>
</div>
</div>
</div>
);
};
export default function SuccessPage() {
return (
<Suspense
fallback={
<div className='fixed inset-0 z-50 flex items-center justify-center'>
<Spinner loading />
</div>
}
>
<SuccessPageWithSearchParams />
</Suspense>
);
}
@@ -0,0 +1,86 @@
import { UserPlan } from '@/types/user';
import { stubTranslation as _ } from '@/utils/misc';
import { AvailablePlan } from '../page';
export type PlanDetails = {
name: string;
plan: UserPlan;
color: string;
price: number;
price_id?: string;
interval: string;
features: string[];
limits: Record<string, string | number>;
};
export const getPlanDetails = (
userPlan: UserPlan,
availablePlans: AvailablePlan[],
): PlanDetails => {
const availablePlan = availablePlans.find((plan) => plan.plan === userPlan);
switch (userPlan) {
case 'free':
return {
name: _('Free Plan'),
plan: userPlan,
color: 'bg-gray-200 text-gray-800',
price: 0,
price_id: availablePlan?.price_id,
interval: _('month'),
features: [
_('Community Support'),
_('Unlimited Text-to-Speech Hours'),
_('Unlimited Cloud Sync Devices'),
_('DeepL Free Access (10K characters/day)'),
_('500 MB Cloud Sync Space'),
],
limits: {
[_('AI Translations (per day)')]: '10K',
[_('Cloud Storage')]: '500 MB',
},
};
case 'plus':
return {
name: _('Plus Plan'),
plan: userPlan,
color: 'bg-blue-200 text-blue-800',
price: availablePlan?.price || 499,
price_id: availablePlan?.price_id,
interval: _('month'),
features: [
_('Includes All Free Plan Benefits'),
_('Priority Support'),
_('Basic AI Translations'),
_('DeepL Pro Access (50K characters/day)'),
_('2 GB Cloud Sync Space'),
],
limits: {
[_('AI Translations (per day)')]: '50K',
[_('Cloud Storage')]: '2 GB',
},
};
case 'pro':
return {
name: _('Pro Plan'),
plan: userPlan,
color: 'bg-purple-200 text-purple-800',
price: availablePlan?.price || 999,
price_id: availablePlan?.price_id,
interval: _('month'),
features: [
_('Includes All Plus Plan Benefits'),
_('Early Feature Access'),
_('More AI Translations'),
_('Advanced AI Tools'),
_('DeepL Pro Access (200K characters/day)'),
_('10 GB Cloud Sync Space'),
],
limits: {
[_('AI Translations (per day)')]: '200K',
[_('Cloud Storage')]: '10 GB',
},
};
default:
return getPlanDetails('free', availablePlans);
}
};