Skip to content

Commit a08103c

Browse files
nouha06Tayebsed93
andauthored
feat : enable RTL mode and support for arabic language management (#134)(#147)
* feat : add shortcuts from about to app settings to change language * feat: add arabic translations for OUDS lib (Google Translated) #134 * feat: add arabic translations for Demo App (Google Translated) #134 * feat: Activation of arabic in [Demo App] #134 * feat : Tests app and components and look for bugs #134 * review: update CHANGELOG.md files, add missing force of support of RTL in main.dart * review : Info.plist to include supported locales * review : add arabe traduction opacity * review : change color settings app --------- Signed-off-by: Nouha Hammami < nouha.hammami@sofrecom.com > Co-authored-by: Tayeb Sedraia <tayeb.sedraia@orange.com>
1 parent 360f5b8 commit a08103c

36 files changed

+571
-129
lines changed

app/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
### Added
1010

11+
- [DemoApp][Library] RTL : activation of RTL mode / manage arabic language ([#134](https://github.com/Orange-OpenSource/ouds-flutter/issues/134))
1112
- [DemoApp] Tokens: screen opacity ([#123](https://github.com/Orange-OpenSource/ouds-flutter/issues/84))
1213
- [DemoApp] Migration of PNG Illustrations to SVG ([#143](https://github.com/Orange-OpenSource/ouds-flutter/issues/143))
1314
- [DemoApp] Tokens: screen color ([#124](https://github.com/Orange-OpenSource/ouds-flutter/issues/124))

app/android/app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
<application
33
android:label="@string/app_name"
44
android:name="${applicationName}"
5-
android:icon="@mipmap/ic_launcher">
5+
android:icon="@mipmap/ic_launcher"
6+
android:localeConfig="@xml/locale_config">
67
<activity
78
android:name=".MainActivity"
89
android:exported="true"
Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
package com.orange.ouds.flutterapp
22

3+
import com.orange.ouds.flutterapp.navigation.SystemSettingsNavigator
34
import io.flutter.embedding.android.FlutterActivity
5+
import io.flutter.embedding.engine.FlutterEngine
6+
import io.flutter.plugin.common.MethodChannel
47

5-
class MainActivity: FlutterActivity()
8+
class MainActivity: FlutterActivity() {
9+
private val CHANNEL = "app.channel.shared.data"
10+
11+
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
12+
super.configureFlutterEngine(flutterEngine)
13+
14+
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
15+
call, result ->
16+
if (call.method == "openLanguageSettings") {
17+
SystemSettingsNavigator.openAppLanguageSettings(this)
18+
result.success(null)
19+
} else {
20+
result.notImplemented()
21+
}
22+
}
23+
}
24+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.orange.ouds.flutterapp.navigation
2+
3+
import android.content.Context
4+
import android.content.Intent
5+
import android.net.Uri
6+
import android.os.Build
7+
import android.provider.Settings
8+
import android.util.Log
9+
10+
object SystemSettingsNavigator {
11+
12+
fun openAppLanguageSettings(context: Context) {
13+
val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
14+
Intent(Settings.ACTION_APP_LOCALE_SETTINGS, Uri.parse("package:${context.packageName}"))
15+
} else {
16+
Intent(Settings.ACTION_LOCALE_SETTINGS)
17+
}.apply {
18+
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
19+
}
20+
21+
if (intent.resolveActivity(context.packageManager) != null) {
22+
context.startActivity(intent)
23+
} else {
24+
Log.e("SystemSettings", "No activity found to handle intent: ${intent.action}")
25+
}
26+
}
27+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
3+
<locale android:name="en" />
4+
<locale android:name="ar" />
5+
</locale-config>

app/ios/Runner/Info.plist

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
33
<plist version="1.0">
44
<dict>
5+
<key>CFBundleLocalizations</key>
6+
<array>
7+
<string>en</string>
8+
<string>ar</string>
9+
</array>
510
<key>CADisableMinimumFrameDurationOnPhone</key>
611
<true/>
712
<key>CFBundleDevelopmentRegion</key>

app/lib/l10n/gen/ouds_flutter_app_localizations.dart

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:flutter/widgets.dart';
55
import 'package:flutter_localizations/flutter_localizations.dart';
66
import 'package:intl/intl.dart' as intl;
77

8+
import 'ouds_flutter_app_localizations_ar.dart';
89
import 'ouds_flutter_app_localizations_en.dart';
910

1011
// ignore_for_file: type=lint
@@ -90,6 +91,7 @@ abstract class AppLocalizations {
9091

9192
/// A list of this localizations delegate's supported locales.
9293
static const List<Locale> supportedLocales = <Locale>[
94+
Locale('ar'),
9395
Locale('en')
9496
];
9597

@@ -303,6 +305,30 @@ abstract class AppLocalizations {
303305
/// **'Content'**
304306
String get app_tokens_color_content_label;
305307

308+
/// No description provided for @app_tokens_elevation_label.
309+
///
310+
/// In en, this message translates to:
311+
/// **'Elevation'**
312+
String get app_tokens_elevation_label;
313+
314+
/// No description provided for @app_tokens_elevation_description_text.
315+
///
316+
/// In en, this message translates to:
317+
/// **'Shadows are used to give the impression of distance or elevation between surfaces, which adds depth to our designs.'**
318+
String get app_tokens_elevation_description_text;
319+
320+
/// No description provided for @app_tokens_opacity_label.
321+
///
322+
/// In en, this message translates to:
323+
/// **'Opacity'**
324+
String get app_tokens_opacity_label;
325+
326+
/// No description provided for @app_tokens_opacity_description_text.
327+
///
328+
/// In en, this message translates to:
329+
/// **'Opacity can help distinguish foreground elements from background elements, making content easier to read and important actions more noticeable.'**
330+
String get app_tokens_opacity_description_text;
331+
306332
/// No description provided for @app_components_common_layout_label.
307333
///
308334
/// In en, this message translates to:
@@ -369,30 +395,6 @@ abstract class AppLocalizations {
369395
/// **'Icon'**
370396
String get app_components_button_icon_a11y;
371397

372-
/// No description provided for @app_tokens_elevation_label.
373-
///
374-
/// In en, this message translates to:
375-
/// **'Elevation'**
376-
String get app_tokens_elevation_label;
377-
378-
/// No description provided for @app_tokens_elevation_description_text.
379-
///
380-
/// In en, this message translates to:
381-
/// **'Shadows are used to give the impression of distance or elevation between surfaces, which adds depth to our designs.'**
382-
String get app_tokens_elevation_description_text;
383-
384-
/// No description provided for @app_tokens_opacity_label.
385-
///
386-
/// In en, this message translates to:
387-
/// **'Opacity'**
388-
String get app_tokens_opacity_label;
389-
390-
/// No description provided for @app_tokens_opacity_description_text.
391-
///
392-
/// In en, this message translates to:
393-
/// **'Opacity can help distinguish foreground elements from background elements, making content easier to read and important actions more noticeable.'**
394-
String get app_tokens_opacity_description_text;
395-
396398
/// No description provided for @app_about_name_label.
397399
///
398400
/// In en, this message translates to:
@@ -422,6 +424,12 @@ abstract class AppLocalizations {
422424
/// In en, this message translates to:
423425
/// **'Changelog'**
424426
String get app_about_changelog_label;
427+
428+
/// No description provided for @app_about_appSettings_label.
429+
///
430+
/// In en, this message translates to:
431+
/// **'Open the app settings'**
432+
String get app_about_appSettings_label;
425433
}
426434

427435
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
@@ -433,7 +441,7 @@ class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations>
433441
}
434442

435443
@override
436-
bool isSupported(Locale locale) => <String>['en'].contains(locale.languageCode);
444+
bool isSupported(Locale locale) => <String>['ar', 'en'].contains(locale.languageCode);
437445

438446
@override
439447
bool shouldReload(_AppLocalizationsDelegate old) => false;
@@ -444,6 +452,7 @@ AppLocalizations lookupAppLocalizations(Locale locale) {
444452

445453
// Lookup logic when only language code is specified.
446454
switch (locale.languageCode) {
455+
case 'ar': return AppLocalizationsAr();
447456
case 'en': return AppLocalizationsEn();
448457
}
449458

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
// ignore: unused_import
2+
import 'package:intl/intl.dart' as intl;
3+
import 'ouds_flutter_app_localizations.dart';
4+
5+
// ignore_for_file: type=lint
6+
7+
/// The translations for Arabic (`ar`).
8+
class AppLocalizationsAr extends AppLocalizations {
9+
AppLocalizationsAr([String locale = 'ar']) : super(locale);
10+
11+
@override
12+
String get app_name => 'OudsPlayground';
13+
14+
@override
15+
String get app_common_selected_a11y => 'محدد';
16+
17+
@override
18+
String get app_common_unselected_a11y => 'غير محدد';
19+
20+
@override
21+
String get app_common_back_a11y => 'رجوع';
22+
23+
@override
24+
String get app_common_copyCode_a11y => 'نسخ الكود';
25+
26+
@override
27+
String get app_common_codeCopied_text => 'تم نسخ الكود إلى الحافظة';
28+
29+
@override
30+
String get app_common_collapsed_a11y => 'مطوي';
31+
32+
@override
33+
String get app_common_expanded_a11y => 'موسّع';
34+
35+
@override
36+
String get app_common_bottomSheetExpanded_a11y => 'الشريط السفلى موسعة';
37+
38+
@override
39+
String get app_common_bottomSheetCollapsed_a11y => 'الشريط السفلي مطوي';
40+
41+
@override
42+
String get app_common_customize_label => 'تخصيص';
43+
44+
@override
45+
String get app_common_enabled_label => 'مُفعّل';
46+
47+
@override
48+
String get app_common_onColoredBackground_label => 'على خلفية ملوّنة';
49+
50+
@override
51+
String get app_common_customizeChips_label_a11y => 'قائمة الشرائح';
52+
53+
@override
54+
String get app_common_customizeChips_hint_a11y => 'يرجى اختيار شريحة من خلال التنقل بين الخيارات';
55+
56+
@override
57+
String get app_topBar_theme_button_a11y => 'تغيير السمة';
58+
59+
@override
60+
String get app_topBar_theme_hint_a11y => 'اضغط لتغيير وضع السمة';
61+
62+
@override
63+
String get app_topBar_darkMode_button_a11y => 'داكن';
64+
65+
@override
66+
String get app_topBar_lightMode_button_a11y => 'فاتح';
67+
68+
@override
69+
String get app_topBar_systemMode_button_a11y => 'النظام';
70+
71+
@override
72+
String get app_bottomBar_tokens_label => 'الرموز';
73+
74+
@override
75+
String get app_bottomBar_components_label => 'المكوّنات';
76+
77+
@override
78+
String get app_bottomBar_about_label => 'حول';
79+
80+
@override
81+
String get app_tokens_viewCodeExample_label => 'عرض مثال على كود الرمز';
82+
83+
@override
84+
String get app_tokens_color_decorative_label => 'زخرفي';
85+
86+
@override
87+
String get app_tokens_color_overlay_label => 'تراكب';
88+
89+
@override
90+
String get app_tokens_color_surface_label => 'السطح';
91+
92+
@override
93+
String get app_tokens_color_label => 'اللون';
94+
95+
@override
96+
String get app_tokens_color_description_text => 'يعزز اللون هوية علامتنا التجارية ويضمن الاتساق في تجربة المستخدم عبر جميع المنتجات. الرموز الدلالية الموضحة هنا هي التي ينبغي استخدامها عند بناء تطبيقات الجوال.';
97+
98+
@override
99+
String get app_tokens_color_action_label => 'الإجراء';
100+
101+
@override
102+
String get app_tokens_color_always_label => 'دائمًا';
103+
104+
@override
105+
String get app_tokens_color_background_label => 'الخلفية';
106+
107+
@override
108+
String get app_tokens_color_border_label => 'الحدود';
109+
110+
@override
111+
String get app_tokens_color_brand_label => 'العلامة التجارية';
112+
113+
@override
114+
String get app_tokens_color_content_label => 'المحتوى';
115+
116+
@override
117+
String get app_tokens_elevation_label => 'الارتفاع';
118+
119+
@override
120+
String get app_tokens_elevation_description_text => 'تُستخدم الظلال لإعطاء انطباع بالمسافة أو الارتفاع بين الأسطح، مما يضيف عمقًا لتصميماتنا.';
121+
122+
@override
123+
String get app_tokens_opacity_label => 'العتامة';
124+
125+
@override
126+
String get app_tokens_opacity_description_text => 'يمكن أن تساعد العتامة في التمييز بين عناصر المقدمة وعناصر الخلفية، مما يجعل المحتوى أسهل في القراءة والإجراءات المهمة أكثر وضوحًا.';
127+
128+
@override
129+
String get app_components_common_layout_label => 'التخطيط';
130+
131+
@override
132+
String get app_components_common_textOnlyLayout_label => 'نص فقط';
133+
134+
@override
135+
String get app_components_common_iconAndTextLayout_label => 'أيقونة + نص';
136+
137+
@override
138+
String get app_components_common_style_label => 'النمط';
139+
140+
@override
141+
String get app_components_common_text_label => 'نص';
142+
143+
@override
144+
String get app_components_common_onColoredBackground_label => 'على خلفية ملوّنة';
145+
146+
@override
147+
String get app_components_button_label => 'زر';
148+
149+
@override
150+
String get app_components_button_description_text => 'تتيح الأزرار للمستخدمين اتخاذ قرارات أو تنفيذ إجراء. لها أنماط متعددة لتناسب مختلف الاحتياجات.';
151+
152+
@override
153+
String get app_components_button_hierarchy_label => 'التسلسل';
154+
155+
@override
156+
String get app_components_button_iconOnlyLayout_label => 'أيقونة فقط';
157+
158+
@override
159+
String get app_components_button_icon_a11y => 'أيقونة';
160+
161+
@override
162+
String get app_about_name_label => 'أداة نظام التصميم';
163+
164+
@override
165+
String get app_about_privacyPolicy_label => 'سياسة الخصوصية';
166+
167+
@override
168+
String get app_about_legalInformation_label => 'المعلومات القانونية';
169+
170+
@override
171+
String get app_about_materialComponents_label => 'مكوّنات Material 3';
172+
173+
@override
174+
String get app_about_changelog_label => 'سجل التغييرات';
175+
176+
@override
177+
String get app_about_appSettings_label => 'افتح إعدادات التطبيق';
178+
}

0 commit comments

Comments
 (0)