Add Farsi(fa) language
This commit is contained in:
@@ -69,8 +69,9 @@
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "settings",
|
||||
"appearance": {
|
||||
"sectionTitle": "appearance",
|
||||
"general": {
|
||||
"sectionTitle": "general",
|
||||
"locale": "language",
|
||||
"themeMode": "theme mode",
|
||||
"themeModes": {
|
||||
"system": "follow system theme",
|
||||
|
||||
126
assets/translations/strings_fa.i18n.json
Normal file
126
assets/translations/strings_fa.i18n.json
Normal file
@@ -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": "کانفیگ غیر معتبر"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
95
lib/features/settings/widgets/general_setting_tiles.dart
Normal file
95
lib/features/settings/widgets/general_setting_tiles.dart
Normal file
@@ -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<LocalePref>(
|
||||
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);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
export 'appearance_setting_tiles.dart';
|
||||
export 'clash_setting_tiles.dart';
|
||||
export 'general_setting_tiles.dart';
|
||||
export 'network_setting_tiles.dart';
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user