Skip to content

Commit

Permalink
feat: add Arabic translation
Browse files Browse the repository at this point in the history
  • Loading branch information
aradzie committed Apr 12, 2024
1 parent 7b55e69 commit e6b5f26
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 1 deletion.
4 changes: 3 additions & 1 deletion packages/keybr-intl/lib/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { createContext, useContext } from "react";
*/

export type LocaleId =
| "ar"
| "cs"
| "da"
| "de"
Expand Down Expand Up @@ -47,6 +48,7 @@ export const defaultLocale: LocaleId = "en";

export const allLocales: readonly LocaleId[] = [
defaultLocale,
"ar",
"cs",
"da",
"de",
Expand All @@ -71,7 +73,7 @@ export const allLocales: readonly LocaleId[] = [
];

export function getDir(locale: LocaleId): "ltr" | "rtl" {
return locale === "he" || locale === "fa" ? "rtl" : "ltr";
return locale === "ar" || locale === "fa" || locale === "he" ? "rtl" : "ltr";
}

export const PreferredLocaleContext = createContext<LocaleId>(defaultLocale);
Expand Down
1 change: 1 addition & 0 deletions packages/keybr-intl/lib/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type Messages = Record<string, string | any>;
export async function loadMessages(locale: LocaleId): Promise<Messages> {
// prettier-ignore
switch (locale) {
case "ar": return (await import(/* webpackChunkName: "messages-ar" */ "./messages/ar.json")).default;
case "cs": return (await import(/* webpackChunkName: "messages-cs" */ "./messages/cs.json")).default;
case "da": return (await import(/* webpackChunkName: "messages-da" */ "./messages/da.json")).default;
case "de": return (await import(/* webpackChunkName: "messages-de" */ "./messages/de.json")).default;
Expand Down
1 change: 1 addition & 0 deletions packages/keybr-intl/lib/messages/ar.json

Large diffs are not rendered by default.

104 changes: 104 additions & 0 deletions packages/keybr-intl/translations/ar.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
{
"account.accountDetails.legend": "تفاصيل الحساب",
"account.accountName.header": "الحساب | {name}",
"account.accountPage.description": "<p>أنت تستخدم حسابًا لتخزين بيانات الكتابة الخاصة بك على خوادمنا في الكلاود. ستكون قادرًا على الوصول إلى ملف تعريفك من أي حاسوب أو متصفح.</p>",
"account.anonymize.description": "إخفاء الهوية يقوم بتحويل صورتك واسم المستخدم الحقيقي إلى تلك التي نقدمها. يمكنك التبديل بين اسمك الحقيقي والاسم المجهول في أي وقت دون قيود.",
"account.anonymousUserName": "مستخدم مجهول",
"account.avatar.description": "صورتك الشخصية واسمك كما يظهران للجمهور في ملفك الشخصي، جدول أعلى النقاط، واللعبة متعددة اللاعبين.",
"account.checkout.description": "اشترِ حسابًا متميزًا لفتح ميزات إضافية والتمتع بتجربة خالية من الإعلانات.",
"account.checkout.title": "حساب متميز",
"account.deleteAccount.description": "سيؤدي هذا إلى حذف جميع المعلومات التي تمكننا من التعرف عليك بشكل شخصي، مثل اسمك وعنوان بريدك الإلكتروني، من قاعدة البيانات الخاصة بنا. هذا الإجراء لا يمكن التراجع عنه! إذا كنت ترغب فقط في مسح إحصائيات الكتابة الخاصة بك والبداية من جديد، يمكنك القيام بذلك على صفحة الملف الشخصي.",
"account.deleteAccount.legend": "حذف الحساب",
"account.deleteAccount.message": "هل أنت متأكد من رغبتك في حذف حسابك؟ هذا الإجراء دائم ولا يمكن التراجع عنه! ومع ذلك، يمكنك إنشاء حساب جديد في أي وقت.",
"account.emailForm.description": "تسجيل دخول بسيط لا يستخدم كلمات المرور. فقط أدخل عنوان بريدك الإلكتروني، وسنرسل لك رابط تسجيل الدخول. انتقل إلى البريد الوارد الخاص بك، وانقر على الرابط لإنشاء حساب جديد أو لفتح حساب قائم باستخدام عنوان البريد الإلكتروني المُقدم. الرابط مؤقت وتنتهي صلاحيته خلال بضع ساعات. لتسجيل الدخول مرة أخرى في وقت لاحق، أدخل نفس عنوان البريد الإلكتروني، وسنرسل رابطًا جديدًا لنفس الحساب.",
"account.emailSignIn.header": "تسجيل الدخول باستخدام البريد الإلكتروني",
"account.emailState.errorText": "تعذر إرسال البريد الإلكتروني إلى <strong>{email}</strong>: {message}",
"account.emailState.sendingText": "جارٍ إرسال بريد إلكتروني يحتوي على رابط تسجيل الدخول إلى <strong>{email}</strong>... يرجى الانتظار لحظة.",
"account.emailState.sentText": "لقد قمنا بإرسال بريد إلكتروني يحتوي على رابط تسجيل الدخول إلى <strong>{email}</strong>. من المفترض أن يصل قريبًا، يرجى التحقق من صندوق الوارد الخاص بك في دقيقة أو اثنتين.",
"account.freeAccountOverview": "<p>اشترِ <strong>حساب مميز</strong> لفتح ميزات إضافية والاستمتاع بتجربة خالية من الإعلانات. إليك قائمة فوائد الحساب المميز:</p><ul><li><strong>بدون إعلانات.</strong> قد تكون الإعلانات مزعجة وتعيق تقدمك في التعلم. هذه وسيلة جيدة للتخلص منها.</li><li><strong>بدون متتبعات.</strong> تأتي المتتبعات بالضرورة مع الإعلانات. قم بإزالة جميع المتتبعات لضمان الخصوصية الكاملة على الإنترنت.</li><li><strong>استجابة فائقة السرعة.</strong> تأخذ الإعلانات وقتًا طويلاً للتحميل. التخلص منها يعني أوقات تحميل أسرع لجميع الصفحات.</li></ul><p>إنها دفعة واحدة توفر الوصول مدى الحياة.</p>",
"account.premiumAccount.header": "حساب مميز",
"account.premiumAccount.legend": "حساب مميز",
"account.premiumAccountOverview": "<p>شكرًا لك على شراء حساب مميز! الآن يمكنك الاستمتاع بميزات إضافية وتجربة خالية من الإعلانات.</p>",
"account.signInPage.description": "<p>أنشئ حسابًا لتخزين بيانات الكتابة الخاصة بك على خوادمنا في السحابة. يتيح لك ذلك الوصول إلى ملف تعريفك من أي كمبيوتر أو متصفح. إذا لم يكن لديك حساب، فإن بيانات الكتابة الخاصة بك تخزن محليًا ويمكن الوصول إليها فقط من جهاز الكمبيوتر الحالي.</p><p>نحن لا نخزن أي كلمات مرور. بدلاً من ذلك، نستخدم خدمات طرف ثالث للتحقق من هوية مستخدمينا. نقدم طرقًا مريحة لإنشاء حساب وتسجيل الدخول.</p><p>يمكنك الانسحاب في أي وقت. حذف الحساب بسيط مثل إنشاء واحد.</p>",
"account.socialForm.description": "قم بتسجيل الدخول باستخدام شبكتك الاجتماعية المفضلة. نحن نحترم خصوصيتك ونعدك بعدم إرسال رسائل غير مرغوب فيها إلى حائطك، أو أصدقائك، أو بريدك الإلكتروني.",
"account.socialSignIn.header": "تسجيل الدخول باستخدام شبكات التواصل الاجتماعي",
"account.socialSignInButton.description": "تسجيل الدخول باستخدام شبكة اجتماعية.",
"account.socialSignInButton.label": "تسجيل الدخول باستخدام {name}",
"account.widget.anonymize.description": "إخفاء صورتك الحقيقية واسم المستخدم من العامة.",
"account.widget.anonymize.label": "أخف هويتي",
"account.widget.checkout.description": "افتح نموذج الدفع.",
"account.widget.checkout.label": "اشترِ حساب مميز",
"account.widget.deleteAccount.description": "احذف حسابك بشكل دائم.",
"account.widget.deleteAccount.label": "حذف الحساب",
"account.widget.email.description": "هذا هو عنوان البريد الإلكتروني الذي سنرسل إليه رابط تسجيل الدخول.",
"account.widget.email.placeholder": "عنوان بريدك الإلكتروني...",
"account.widget.resend.description": "أرسل بريدًا إلكترونيًا آخر.",
"account.widget.resend.label": "أعِد إرساله",
"account.widget.retrySend.description": "أرسل بريدًا إلكترونيًا آخر.",
"account.widget.retrySend.label": "حاول مرة أخرى",
"account.widget.send.description": "تسجيل الدخول باستخدام البريد الإلكتروني.",
"account.widget.send.label": "أرسل رابط تسجيل الدخول",
"account.widget.signOut.description": "قم بتسجيل الخروج من التطبيق.",
"account.widget.signOut.label": "تسجيل الخروج",
"calendar.weekDayName": "إ|ث|أ|خ|ج|س|أ",
"characterClass.digits": "أرقام",
"characterClass.letters": "حروف",
"characterClass.punctuationCharacters": "حروف الترقيم",
"characterClass.specialCharacters": "حروف خاصة",
"common.javaScriptDisabled.message": "لن تعمل هذا التطبيق لأن JavaScript معطل في متصفحك!",
"common.loading.message": "جاري تحميل التطبيق، يرجى الانتظار لحظة...",
"footer.discordLink.description": "المناقشة على خادم Discord الخاص بنا.",
"footer.emailLink.description": "أرسل تعليقاتك واقتراحاتك إلى [email protected]",
"footer.githubLink.description": "شفرة المصدر لـ keybr.com متاحة على Github.",
"footer.removeAds.description": "اشترِ حسابًا مميزًا لإزالة الإعلانات.",
"footer.removeAds.label": "إزالة الإعلانات",
"help.example1": "<a>المثال 1</a>، من 30 إلى 70 كلمة في الدقيقة بعد 4 ساعات و 20 دقيقة من الممارسة على مدى 15 يومًا.",
"help.example2": "<a>المثال 2</a>، من 35 إلى 70 كلمة في الدقيقة بعد 2 ساعة و 20 دقيقة من الممارسة على مدى 12 يومًا.",
"help.example3": "<a>المثال 3</a>، قفزة جيدة من أقل من 20 إلى 40 كلمة في الدقيقة بعد 5 ساعات و 30 دقيقة من الممارسة على مدى 11 يومًا.",
"help.example4": "<a>المثال 4</a>، بعد 2 ساعة و 10 دقائق من الممارسة على مدى 11 يومًا، بقيت سرعة الكتابة عند حوالي 70 كلمة في الدقيقة (وهو مستوى جيد بالفعل)، ولكن تحسنت الدقة.",
"help.example5": "<a>المثال 5</a>، من 20 إلى 45 كلمة في الدقيقة بعد حوالي 10 ساعات من الممارسة على مدى 22 يومًا (نعم، أحيانًا يستغرق الأمر وقتًا أطول).",
"help.indicators.caption": "رمز لون المؤشر.",
"help.keyboardZones.caption": "مناطق اللوحة المفاتيح ووضع الأصابع السليم.",
"help.rule2.title": "تتعلم الحروف الأولية",
"help.rule3.title": "تضيف الخوارزمية المزيد من الحروف",
"help.rule4.title": "تتعلم رسائل إضافية",
"help.section4": "<p> المعنى الدقيق لكل لون مؤشر في وسيلة الإيضاح التالية.</p>",
"help.section5": "<h2>الطريقة الصحيحة لاستخدام لوحة المفاتيح</h2><p>ضع كل أصابعك على الصف الرئيسي، وهو الصف الذي يحتوي على مفتاح <em>Caps Lock</em>. توجد نتوءات صغيرة على المفتاحين “<em>F</em>“ و“<em>J</em>“، ضع إصبعي السبابة على النتوءات. كل إصبع مسؤول عن مجموعة المفاتيح الخاصة به، كما هو موضح في الرسم التوضيحي التالي.</p>",
"help.section6": "<h2>فعالية هذا التطبيق</h2><p>لقد اخترنا بعض الأمثلة على الملفات الشخصية لنوضح لك مدى تقدم الأشخاص في تعلم الكتابة باللمس عند استخدام هذا التطبيق. هذه ملفات تعريف مستخدمين حقيقية ومجهولة المصدر. نأمل أن يلهموك لمواصلة التعلم!</p>",
"highScores.column.layout.label": "التصميم",
"highScores.column.score.label": "النتيجة",
"highScores.column.speed.label": "سرعة الكتابة",
"highScores.column.user.label": "المستخدِم",
"keyboard.language.label": "اللغة:",
"layouts.stats.bottomRowKeys.description": "النسبة المئوية للمفاتيح المكتوبة في صف Shift، كلما كانت أقل كلما كان ذلك أفضل.",
"layouts.stats.bottomRowKeys.name": "المفاتيح في الصف السفلي:",
"layouts.stats.homeRowKeys.name": "الأحرف على صف الارتكاز:",
"layouts.stats.sameFingerKeys.description": "نسبة المفاتيح المكتوبة بنفس الإصبع، كلما كانت أقل كلما كان ذلك أفضل.",
"layouts.stats.sameFingerKeys.name": "المفاتيح المكتوبة بنفس الإصبع:",
"layouts.stats.sameHandKeys.description": "نسبة المفاتيح المكتوبة بنفس اليد، كلما كانت أقل كلما كان ذلك أفضل.",
"learningRate.unknown": "تحتاج إلى مزيد من البيانات لحساب الدروس المتبقية لفتح هذه الرسالة.",
"lesson.keySetPanel.label": "جميع المفاتيح",
"lesson.notCalibrated.message": "لم تتم معايرتها، بحاجة إلى المزيد من العينات.",
"lessonType.customText.name": "نص مخصص",
"lessonType.guided.description": "أنشئ دروسًا في الكتابة باستخدام كلمات عشوائية باستخدام القواعد الصوتية للغتك. يتم توسيع مجموعة المفاتيح ديناميكيًا بناءً على أدائك. هذا الوضع للمبتدئين.",
"lessonType.guided.name": "دروس موجهة",
"lessonType.numbers.name": "أعداد",
"lessonType.wordlist.name": "كلمات شائعة",
"metric.accuracy.description": "نسبة الحروف المكتوبة بدون أخطاء في الدرس الأخير.",
"metric.accuracy.name": "دقة",
"metric.accuracyChange.description": "الإختلاف عن القيمة المتوسطة.",
"metric.averageSpeed.name": "متوسط السرعة",
"metric.bestSpeed.name": "أفضل سرعة",
"metric.speed.name": "السرعة",
"metric.summary.averageAccuracyToday.label": "متوسط الدقة",
"metric.summary.averageSpeed.description": "متوسط سرعة الكتابة",
"metric.summary.characterCount.label": "الأحرف",
"metric.summary.lessonCount.description": "عدد الدروس المكتملة",
"metric.summary.lessonCount.label": "الدروس",
"multiplayer.ticker.raceFinished": "انتهى السباق!",
"multiplayer.ticker.raceStarted": "بدأ السباق!",
"multiplayer.ticker.start": "انطلق!",
"multiplayer.ticker.waitingMorePlayers": "بانتظار المزيد من اللاعبين...",
"multiplayer.track.position.label": "المركز",
"page.account.anonymous.link.name": "تسجيل الدخول"
}
20 changes: 20 additions & 0 deletions packages/keybr-pages-server/lib/NavMenu.test.tsx.md
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,26 @@ Generated by [AVA](https://avajs.dev).
},
{
children: [
{
children: [
'ar',
],
props: {
className: 'link localeLink',
download: undefined,
href: '/ar/index',
id: undefined,
onClick: undefined,
onMouseDown: undefined,
onMouseEnter: undefined,
onMouseLeave: undefined,
onMouseUp: undefined,
target: undefined,
title: 'العربية / Arabic',
},
type: 'a',
},
' ',
{
children: [
'cs',
Expand Down
Binary file modified packages/keybr-pages-server/lib/NavMenu.test.tsx.snap
Binary file not shown.
58 changes: 58 additions & 0 deletions packages/keybr-pages-server/lib/StandardLayout.test.tsx.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ Generated by [AVA](https://avajs.dev).
},
type: 'link',
},
{
children: null,
props: {
href: 'https://www.keybr.com/ar/path',
hrefLang: 'ar',
rel: 'alternate',
},
type: 'link',
},
{
children: null,
props: {
Expand Down Expand Up @@ -1238,6 +1247,26 @@ Generated by [AVA](https://avajs.dev).
},
{
children: [
{
children: [
'ar',
],
props: {
className: 'link localeLink',
download: undefined,
href: '/ar/path',
id: undefined,
onClick: undefined,
onMouseDown: undefined,
onMouseEnter: undefined,
onMouseLeave: undefined,
onMouseUp: undefined,
target: undefined,
title: 'العربية / Arabic',
},
type: 'a',
},
' ',
{
children: [
'cs',
Expand Down Expand Up @@ -1944,6 +1973,15 @@ Generated by [AVA](https://avajs.dev).
},
type: 'link',
},
{
children: null,
props: {
href: 'https://www.keybr.com/ar/path',
hrefLang: 'ar',
rel: 'alternate',
},
type: 'link',
},
{
children: null,
props: {
Expand Down Expand Up @@ -3087,6 +3125,26 @@ Generated by [AVA](https://avajs.dev).
},
{
children: [
{
children: [
'ar',
],
props: {
className: 'link localeLink',
download: undefined,
href: '/ar/path',
id: undefined,
onClick: undefined,
onMouseDown: undefined,
onMouseEnter: undefined,
onMouseLeave: undefined,
onMouseUp: undefined,
target: undefined,
title: 'العربية / Arabic',
},
type: 'a',
},
' ',
{
children: [
'cs',
Expand Down
Binary file modified packages/keybr-pages-server/lib/StandardLayout.test.tsx.snap
Binary file not shown.
1 change: 1 addition & 0 deletions scripts/gen-translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const { rootDir, findPackages } = require("./root.js");
const packageDir = join(rootDir, "packages/keybr-intl");

const allLocales = [
"ar",
"cs",
"da",
"de",
Expand Down

0 comments on commit e6b5f26

Please sign in to comment.