diff --git a/assets/l10n/app_ar.arb b/assets/l10n/app_ar.arb new file mode 100644 index 0000000000..1893ec7018 --- /dev/null +++ b/assets/l10n/app_ar.arb @@ -0,0 +1,108 @@ +{ + "@@locale": "ar", + "@@last_modified": "2024-05-23T13:20:40+02:00", + "aboutPageTitle": "حول Zulip", + "aboutPageAppVersion": "إصدار التطبيق", + "aboutPageOpenSourceLicenses": "رخص البرمجيات مفتوحة المصدر", + "aboutPageTapToView": "انقر للعرض", + "chooseAccountPageTitle": "اختر الحساب", + "chooseAccountButtonAddAnAccount": "إضافة حساب", + "profileButtonSendDirectMessage": "إرسال رسالة مباشرة", + "permissionsNeededTitle": "الصلاحيات المطلوبة", + "permissionsNeededOpenSettings": "فتح الإعدادات", + "permissionsDeniedCameraAccess": "لتحميل صورة، يرجى منح Zulip صلاحيات إضافية في الإعدادات.", + "permissionsDeniedReadExternalStorage": "لتحميل صورة، يرجى منح Zulip صلاحيات إضافية في الإعدادات.", + "actionSheetOptionCopy": "نسخ نص الرسالة", + "actionSheetOptionShare": "شارك", + "actionSheetOptionQuoteAndReply": "الاقتباس والرد", + "actionSheetOptionStarMessage": "رسالة مميزة بنجمة", + "actionSheetOptionUnstarMessage": "إلغاء تمييز الرسالة", + "errorWebAuthOperationalErrorTitle": "حدث خطأ ما", + "errorWebAuthOperationalError": "حدث خطأ غير متوقع.", + "errorAccountLoggedInTitle": "تم تسجيل الدخول إلى الحساب بالفعل", + "errorAccountLoggedIn": "الحساب {email} في {server} موجود بالفعل في قائمة حساباتك.", + "errorCouldNotFetchMessageSource": "تعذر جلب مصدر الرسالة", + "errorCopyingFailed": "فشل النسخ", + "errorFailedToUploadFileTitle": "فشل تحميل الملف: {filename}", + "errorFilesTooLarge": "{num, plural, =1{ الملف هو } other{{num} }} أكبر من حد الخادم البالغ {maxFileUploadSizeMib} MiB ولن يتم تحميلها: \n\n {listMessage}", + "errorFilesTooLargeTitle": "{num, plural, =1{الملف} other{الملفات}} كبيرة جداً", + "errorLoginInvalidInputTitle": "إدخال غير صالح", + "errorLoginFailedTitle": "فشل تسجيل الدخول", + "errorMessageNotSent": "لم يتم إرسال الرسالة", + "errorLoginCouldNotConnect": "فشل الاتصال بالخادم:\n {url}", + "errorLoginCouldNotConnectTitle": "تعذر الاتصال", + "errorMessageDoesNotSeemToExist": "يبدو أن هذه الرسالة غير موجودة.", + "errorQuotationFailed": "فشل الاقتباس", + "errorServerMessage": "قال الخادم:\n\n{message}", + "errorSharingFailed": "فشلت المشاركة", + "errorStarMessageFailedTitle": "فشل تمييز الرسالة بنجمة", + "errorUnstarMessageFailedTitle": "فشل إلغاء تمييز الرسالة", + "successLinkCopied": "تم نسخ الرابط", + "successMessageCopied": "تم نسخ الرسالة", + "composeBoxAttachFilesTooltip": "إرفاق الملفات", + "composeBoxAttachMediaTooltip": "إرفاق صور أو فيديو", + "composeBoxAttachFromCameraTooltip": "التقط صورة", + "composeBoxGenericContentHint": "اكتب رسالة", + "composeBoxDmContentHint": "الرسالة @ {user}", + "composeBoxGroupDmContentHint": "المجموعة \"رسالة\"", + "composeBoxSelfDmContentHint": "قم بتدوين شيء ما", + "composeBoxStreamContentHint": "الرسالة رقم{stream} > {topic}", + "composeBoxSendTooltip": "ارسل", + "composeBoxUnknownStreamName": "(قناة غير معروف)", + "composeBoxTopicHintText": "عنوان", + "composeBoxUploadingFilename": "جارٍ تحميل {filename} ...", + "unknownUserName": "(مستخدم غير معروف)", + "messageListGroupYouAndOthers": "أنت و {others}", + "messageListGroupYouWithYourself": "أنت بمفردك", + "contentValidationErrorTooLong": "يجب ألا يزيد طول الرسالة عن 10000 حرف.", + "contentValidationErrorEmpty": "ليس لديك ما ترسله!", + "contentValidationErrorQuoteAndReplyInProgress": "يرجى الانتظار حتى يكتمل الاقتباس.", + "contentValidationErrorUploadInProgress": "يرجى الانتظار حتى يكتمل التحميل.", + "dialogCancel": "إلغاء", + "dialogContinue": "استمر", + "errorDialogContinue": "حسناً", + "errorDialogTitle": "خطأ", + "lightboxCopyLinkTooltip": "نسخ الرابط", + "loginPageTitle": "تسجيل الدخول", + "loginFormSubmitLabel": "تسجيل الدخول", + "loginMethodDivider": "أو", + "signInWithFoo": "تسجيل الدخول باستخدام {method}", + "loginAddAnAccountPageTitle": "إضافة حساب", + "loginServerUrlInputLabel": "رابط خادم Zulip الخاص بك", + "loginHidePassword": "إخفاء كلمة المرور", + "loginEmailLabel": "عنوان البريد الإلكتروني", + "loginErrorMissingEmail": "الرجاء إدخال بريدك الإلكتروني", + "loginPasswordLabel": "كلمة المرور", + "loginErrorMissingPassword": "الرجاء إدخال كلمة المرور الخاصة بك.", + "loginUsernameLabel": "اسم المستخدم", + "loginErrorMissingUsername": "الرجاء إدخال اسم المستخدم.", + "topicValidationErrorTooLong": "يجب ألا يزيد طول الموضوع عن 60 حرفاً.", + "topicValidationErrorMandatoryButEmpty": "المواضيع مطلوبة في هذه المجموعة.", + "subscribedToNStreams": "مشترك في {num, plural, =0{ لا يوجد قنوات } =1{ 1 فناة } other{{num} قنوات }}", + "errorInvalidResponse": "أرسل الخادم استجابة غير صالحة", + "errorNetworkRequestFailed": "فشل طلب الشبكة", + "errorMalformedResponse": "أعطى الخادم استجابة غير صحيحة؛ حالة HTTP {httpStatus}", + "errorMalformedResponseWithCause": "أعطى الخادم استجابة غير صحيحة؛ حالة HTTP {httpStatus} ؛ {details}", + "errorRequestFailed": "فشل طلب الشبكة: حالة HTTP {httpStatus}", + "errorVideoPlayerFailed": "تعذر تشغيل الفيديو", + "serverUrlValidationErrorEmpty": "الرجاء إدخال عنوان URL.", + "serverUrlValidationErrorInvalidUrl": "أدخل رابط صحيح من فضلك.", + "serverUrlValidationErrorNoUseEmail": "الرجاء إدخال عنوان URL الخاص بالخادم، وليس بريدك الإلكتروني.", + "serverUrlValidationErrorUnsupportedScheme": "يجب أن يبدأ عنوان URL الخاص بالخادم بـ http:\/\/ أو https:\/\/.", + "spoilerDefaultHeaderText": "الإفصاح", + "markAllAsReadLabel": "وضع علامة على جميع الرسائل كمقروءة", + "markAsReadComplete": "تم وضع علامة على {num, plural, =1{ 1 message } other{{num} messages }} كمقروءة.", + "markAsReadInProgress": "وضع علامة على الرسائل كمقروءة...", + "errorMarkAsReadFailedTitle": "فشل في تحديد الرسالة كمقروءة", + "today": "اليوم", + "yesterday": "أمس", + "userRoleOwner": "المالك", + "userRoleAdministrator": "الإداري", + "userRoleModerator": "مشرف", + "userRoleMember": "عضو", + "userRoleGuest": "ضيف", + "userRoleUnknown": "غير معروف", + "recentDmConversationsPageTitle": "الرسائل الشخصية", + "combinedFeedPageTitle": "الملخص", + "notifGroupDmConversationLabel": "{senderFullName} لك و {numOthers, plural, =1{1 آخرين} other{{numOthers} آخرين}}" +} diff --git a/assets/l10n/app_en.arb b/assets/l10n/app_en.arb index 626f72e683..65b184e2b4 100644 --- a/assets/l10n/app_en.arb +++ b/assets/l10n/app_en.arb @@ -1,4 +1,5 @@ { + "@@locale": "en", "aboutPageTitle": "About Zulip", "@aboutPageTitle": { "description": "Title for About Zulip page" diff --git a/lib/widgets/app.dart b/lib/widgets/app.dart index 0e833e471f..8886e2e99e 100644 --- a/lib/widgets/app.dart +++ b/lib/widgets/app.dart @@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter_gen/gen_l10n/zulip_localizations.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import '../model/localizations.dart'; import '../model/narrow.dart'; @@ -117,7 +118,12 @@ class _ZulipAppState extends State with WidgetsBindingObserver { final initialAccountId = globalStore.accounts.firstOrNull?.id; return MaterialApp( title: 'Zulip', - localizationsDelegates: ZulipLocalizations.localizationsDelegates, + localizationsDelegates: const [ + ...ZulipLocalizations.localizationsDelegates, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], supportedLocales: ZulipLocalizations.supportedLocales, theme: themeData, @@ -129,7 +135,11 @@ class _ZulipAppState extends State with WidgetsBindingObserver { (_) => widget._declareReady()); } GlobalLocalizations.zulipLocalizations = ZulipLocalizations.of(context); - return child!; + final locale = Localizations.localeOf(context); // Get locale from context + return Directionality( + textDirection: locale.languageCode == 'ar' ? TextDirection.rtl : TextDirection.ltr, + child: child!, + ); }, // We use onGenerateInitialRoutes for the real work of specifying the