From 5c23a75398d7d08523dfe7e9825de6150938c5a2 Mon Sep 17 00:00:00 2001 From: problematicconsumer Date: Sat, 8 Jul 2023 23:16:22 +0330 Subject: [PATCH] Add Farsi(fa) language --- assets/translations/strings.i18n.json | 5 +- assets/translations/strings_fa.i18n.json | 126 ++++++++++++++++++ lib/core/locale/locale_pref.dart | 3 +- lib/features/settings/view/settings_page.dart | 2 +- .../widgets/appearance_setting_tiles.dart | 54 -------- .../widgets/general_setting_tiles.dart | 95 +++++++++++++ lib/features/settings/widgets/widgets.dart | 2 +- pubspec.lock | 8 ++ pubspec.yaml | 1 + 9 files changed, 237 insertions(+), 59 deletions(-) create mode 100644 assets/translations/strings_fa.i18n.json delete mode 100644 lib/features/settings/widgets/appearance_setting_tiles.dart create mode 100644 lib/features/settings/widgets/general_setting_tiles.dart diff --git a/assets/translations/strings.i18n.json b/assets/translations/strings.i18n.json index fa56448d..a3d5e4ac 100644 --- a/assets/translations/strings.i18n.json +++ b/assets/translations/strings.i18n.json @@ -69,8 +69,9 @@ }, "settings": { "pageTitle": "settings", - "appearance": { - "sectionTitle": "appearance", + "general": { + "sectionTitle": "general", + "locale": "language", "themeMode": "theme mode", "themeModes": { "system": "follow system theme", diff --git a/assets/translations/strings_fa.i18n.json b/assets/translations/strings_fa.i18n.json new file mode 100644 index 00000000..2cbf8164 --- /dev/null +++ b/assets/translations/strings_fa.i18n.json @@ -0,0 +1,126 @@ +{ + "general": { + "appTitle": "هیدیفای", + "reset": "ریست", + "toggle": { + "enabled": "فعال", + "disabled": "غیر فعال" + } + }, + "home": { + "pageTitle": "خانه", + "emptyProfilesMsg": "با افزودن پروفایل شروع کنید", + "noActiveProfileMsg": "انتخاب پروفایل", + "connection": { + "tapToConnect": "برای اتصال ضربه بزنید", + "connecting": "در حال اتصال", + "disconnecting": "در حال قطع اتصال", + "connected": "متصل" + } + }, + "profile": { + "overviewPageTitle": "پروفایل‌ها", + "detailsPageTitle": "پروفایل", + "subscription": { + "traffic": "ترافیک", + "updatedTimeAgo": "بروزرسانی شده در ${timeago}", + "remaining": "باقی مانده", + "expired": "منقضی شده", + "noTraffic": "پایان ترافیک" + }, + "add": { + "buttonText": "افزودن پروفایل جدید", + "fromClipboard": "افزودن از کلیپ‌بورد", + "scanQr": "اسکن QR کد", + "manually": "افزودن دستی", + "invalidUrlMsg": "لینک نامعتبر" + }, + "update": { + "failureMsg": "در بروزرسانی پروفایل خطایی رخ داد: ${reason}", + "successMsg": "پروفایل با موفقیت بروزرسانی شد" + }, + "delete": { + "buttonText": "حذف", + "confirmationMsg": "حذف پروفایل برای همیشه؟ این عمل قابل لغو نیست.", + "successMsg": "پروفایل با موفقیت حذف شد" + }, + "save": { + "buttonText": "ذخیره", + "successMsg": "پروفایل با موفقیت ذخیره شد" + }, + "detailsForm": { + "nameHint": "نام", + "urlHint": "لینک", + "emptyNameMsg": "نام نمیتواند خالی باشد", + "invalidUrlMsg": "لینک غیر معتبر" + } + }, + "proxies": { + "pageTitle": "پراکسی‌ها", + "emptyProxiesMsg": "پراکسی وجود ندارد", + "delayTestTooltip": "تست تاخیر", + "cancelTestButtonText": "لغو تست" + }, + "logs": { + "pageTitle": "لاگ‌ها", + "clearLogsButtonText": "پاک‌سازی", + "filterHint": "فیلتر", + "allLevelsFilter": "همه" + }, + "settings": { + "pageTitle": "تنظیمات", + "general": { + "sectionTitle": "اصلی", + "locale": "زبان", + "themeMode": "تم مود", + "themeModes": { + "system": "پیروی از تم دستگاه", + "dark": "تم تیره", + "light": "تم روشن" + }, + "trueBlack": "کاملا سیاه" + }, + "network": { + "sectionTitle": "شبکه", + "systemProxy": "سیستم پراکسی", + "systemProxyMsg": "افزودن سیستم پراکسی به سرویس VPN", + "bypassPrivateNetworks": "عبور دادن شبکه خصوصی", + "bypassPrivateNetworksMsg": "عبور دادن آدرس‌های شبکه خصوصی" + }, + "clash": { + "sectionTitle": "جاگزین‌های پراکسی کلش", + "doNotModify": "تغییر نده", + "overrides": { + "httpPort": "HTTP Port", + "socksPort": "Socks Port", + "redirPort": "Redirect Port", + "tproxyPort": "TProxy Port", + "mixedPort": "Mixed Port", + "allowLan": "Allow LAN", + "ipv6": "IPv6", + "mode": "Mode", + "logLevel": "Log Level" + } + } + }, + "tray": { + "dashboard": "داشبورد", + "quit": "خروج", + "systemProxy": "پراکسی سیستم" + }, + "failure": { + "unexpected": "خطایی رخ داده", + "clash": { + "unexpected": "خطایی رخ داده", + "core": "خطای کلش ${reason}" + }, + "connectivity": { + "unexpected": "خطایی رخ داده" + }, + "profiles": { + "unexpected": "خطایی رخ داده", + "notFound": "پروفایل یافت نشد", + "invalidConfig": "کانفیگ غیر معتبر" + } + } +} \ No newline at end of file diff --git a/lib/core/locale/locale_pref.dart b/lib/core/locale/locale_pref.dart index ae25e09e..7fc66436 100644 --- a/lib/core/locale/locale_pref.dart +++ b/lib/core/locale/locale_pref.dart @@ -5,7 +5,8 @@ import 'package:hiddify/gen/translations.g.dart'; export 'package:hiddify/gen/translations.g.dart'; enum LocalePref { - en; + en, + fa; Locale get locale { return Locale(name); diff --git a/lib/features/settings/view/settings_page.dart b/lib/features/settings/view/settings_page.dart index 04a8baf8..bbac71cf 100644 --- a/lib/features/settings/view/settings_page.dart +++ b/lib/features/settings/view/settings_page.dart @@ -25,7 +25,7 @@ class SettingsPage extends HookConsumerWidget { child: ListView( children: [ _SettingsSectionHeader( - t.settings.appearance.sectionTitle.titleCase, + t.settings.general.sectionTitle.titleCase, ), const AppearanceSettingTiles(), divider, diff --git a/lib/features/settings/widgets/appearance_setting_tiles.dart b/lib/features/settings/widgets/appearance_setting_tiles.dart deleted file mode 100644 index 2465c4c8..00000000 --- a/lib/features/settings/widgets/appearance_setting_tiles.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:hiddify/core/core_providers.dart'; -import 'package:hiddify/core/theme/theme.dart'; -import 'package:hiddify/features/settings/widgets/theme_mode_switch_button.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:recase/recase.dart'; - -class AppearanceSettingTiles extends HookConsumerWidget { - const AppearanceSettingTiles({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final t = ref.watch(translationsProvider); - - final theme = ref.watch(themeControllerProvider); - final themeController = ref.watch(themeControllerProvider.notifier); - - return Column( - children: [ - ListTile( - title: Text(t.settings.appearance.themeMode.titleCase), - subtitle: Text( - switch (theme.themeMode) { - ThemeMode.system => t.settings.appearance.themeModes.system, - ThemeMode.light => t.settings.appearance.themeModes.light, - ThemeMode.dark => t.settings.appearance.themeModes.dark, - } - .sentenceCase, - ), - trailing: ThemeModeSwitch( - themeMode: theme.themeMode, - onChanged: (value) { - themeController.change(themeMode: value); - }, - ), - onTap: () async { - await themeController.change( - themeMode: Theme.of(context).brightness == Brightness.light - ? ThemeMode.dark - : ThemeMode.light, - ); - }, - ), - SwitchListTile( - title: Text(t.settings.appearance.trueBlack.titleCase), - value: theme.trueBlack, - onChanged: (value) { - themeController.change(trueBlack: value); - }, - ), - ], - ); - } -} diff --git a/lib/features/settings/widgets/general_setting_tiles.dart b/lib/features/settings/widgets/general_setting_tiles.dart new file mode 100644 index 00000000..fc7d0585 --- /dev/null +++ b/lib/features/settings/widgets/general_setting_tiles.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_localized_locales/flutter_localized_locales.dart'; +import 'package:go_router/go_router.dart'; +import 'package:hiddify/core/core_providers.dart'; +import 'package:hiddify/core/locale/locale.dart'; +import 'package:hiddify/core/theme/theme.dart'; +import 'package:hiddify/features/settings/widgets/theme_mode_switch_button.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:recase/recase.dart'; + +class AppearanceSettingTiles extends HookConsumerWidget { + const AppearanceSettingTiles({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final t = ref.watch(translationsProvider); + + final locale = ref.watch(localeControllerProvider); + + final theme = ref.watch(themeControllerProvider); + final themeController = ref.watch(themeControllerProvider.notifier); + + return Column( + children: [ + ListTile( + title: Text(t.settings.general.locale.titleCase), + subtitle: Text( + LocaleNamesLocalizationsDelegate.nativeLocaleNames[locale.name] ?? + locale.name, + ), + onTap: () async { + final selectedLocale = await showDialog( + context: context, + builder: (context) { + return SimpleDialog( + title: Text(t.settings.general.locale.titleCase), + children: LocalePref.values + .map( + (e) => RadioListTile( + title: Text( + LocaleNamesLocalizationsDelegate + .nativeLocaleNames[e.name] ?? + e.name, + ), + value: e, + groupValue: locale, + onChanged: (e) => context.pop(e), + ), + ) + .toList(), + ); + }, + ); + if (selectedLocale != null) { + await ref + .read(localeControllerProvider.notifier) + .change(selectedLocale); + } + }, + ), + ListTile( + title: Text(t.settings.general.themeMode.titleCase), + subtitle: Text( + switch (theme.themeMode) { + ThemeMode.system => t.settings.general.themeModes.system, + ThemeMode.light => t.settings.general.themeModes.light, + ThemeMode.dark => t.settings.general.themeModes.dark, + } + .sentenceCase, + ), + trailing: ThemeModeSwitch( + themeMode: theme.themeMode, + onChanged: (value) { + themeController.change(themeMode: value); + }, + ), + onTap: () async { + await themeController.change( + themeMode: Theme.of(context).brightness == Brightness.light + ? ThemeMode.dark + : ThemeMode.light, + ); + }, + ), + SwitchListTile( + title: Text(t.settings.general.trueBlack.titleCase), + value: theme.trueBlack, + onChanged: (value) { + themeController.change(trueBlack: value); + }, + ), + ], + ); + } +} diff --git a/lib/features/settings/widgets/widgets.dart b/lib/features/settings/widgets/widgets.dart index eab6f4d1..4dcd11bc 100644 --- a/lib/features/settings/widgets/widgets.dart +++ b/lib/features/settings/widgets/widgets.dart @@ -1,3 +1,3 @@ -export 'appearance_setting_tiles.dart'; export 'clash_setting_tiles.dart'; +export 'general_setting_tiles.dart'; export 'network_setting_tiles.dart'; diff --git a/pubspec.lock b/pubspec.lock index dcd0149a..25660f26 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -483,6 +483,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_localized_locales: + dependency: "direct main" + description: + name: flutter_localized_locales + sha256: f219350dffcfd56692b4e41953710c2975888dd9c507d977ec6853d7ea140336 + url: "https://pub.dev" + source: hosted + version: "2.0.4" flutter_loggy: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 36273907..5f2b1695 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -76,6 +76,7 @@ dependencies: sliver_tools: ^0.2.10 flutter_adaptive_scaffold: ^0.1.5 fl_chart: ^0.63.0 + flutter_localized_locales: ^2.0.4 dev_dependencies: flutter_test: