From bb2e1a2625bc50fe9a9b71a56af34598f690b1ec Mon Sep 17 00:00:00 2001 From: problematicconsumer Date: Sun, 17 Sep 2023 14:55:46 +0330 Subject: [PATCH] feat: add region and terms to intro --- assets/translations/strings.i18n.json | 14 ++++++- assets/translations/strings_fa.i18n.json | 12 +++++- lib/core/prefs/general_prefs.dart | 19 +++++++++ lib/core/prefs/locale_prefs.dart | 2 +- lib/domain/constants.dart | 2 + lib/domain/singbox/rules.dart | 12 ++++++ lib/features/common/general_pref_tiles.dart | 43 +++++++++++++++++++++ lib/features/intro/view/intro_page.dart | 23 +++++++++++ 8 files changed, 123 insertions(+), 4 deletions(-) diff --git a/assets/translations/strings.i18n.json b/assets/translations/strings.i18n.json index 448709d6..e47e1e0e 100644 --- a/assets/translations/strings.i18n.json +++ b/assets/translations/strings.i18n.json @@ -10,6 +10,7 @@ "sortBy": "Sort by" }, "intro": { + "termsAndPolicyCaution(rich)": "by continuing you agree with ${tap(@:about.termsAndConditions)}", "start": "Start" }, "home": { @@ -104,10 +105,17 @@ }, "settings": { "pageTitle": "Settings", - "requiresRestartMsg": "for this to take effect restart the app", + "requiresRestartMsg": "For this to take effect restart the app", "general": { "sectionTitle": "General", "locale": "Language", + "region": "Region", + "regionMsg": "Helps set default options to bypass domestic addresses", + "regions": { + "ir": "Iran (ir)", + "cn": "China (cn)", + "other": "Other" + }, "themeMode": "Theme Mode", "themeModes": { "system": "Follow system theme", @@ -182,7 +190,9 @@ "version": "Version", "sourceCode": "Source Code", "telegramChannel": "Telegram Channel", - "checkForUpdate": "Check for update" + "checkForUpdate": "Check for update", + "privacyPolicy": "Privacy policy", + "termsAndConditions": "Terms and conditions" }, "appUpdate": { "dialogTitle": "Update Available", diff --git a/assets/translations/strings_fa.i18n.json b/assets/translations/strings_fa.i18n.json index 91b4b90b..c0b727a7 100644 --- a/assets/translations/strings_fa.i18n.json +++ b/assets/translations/strings_fa.i18n.json @@ -10,6 +10,7 @@ "sortBy": "مرتب‌سازی براساس" }, "intro": { + "termsAndPolicyCaution(rich)": "در صورت ادامه با ${tap(@:about.termsAndConditions)} موافقت میکنید", "start": "شروع" }, "home": { @@ -108,6 +109,13 @@ "general": { "sectionTitle": "اصلی", "locale": "زبان", + "region": "منطقه", + "regionMsg": "به انتخاب تنظیمات پیش‌فرض برای دورزدن آدرس‌های داخلی کمک میکند", + "regions": { + "ir": "ایران (ir)", + "cn": "چین (cn)", + "other": "سایر" + }, "themeMode": "تم مود", "themeModes": { "system": "پیروی از تم دستگاه", @@ -182,7 +190,9 @@ "version": "ورژن", "sourceCode": "سورس کد", "telegramChannel": "کانال تلگرام", - "checkForUpdate": "بررسی آپدیت جدید" + "checkForUpdate": "بررسی آپدیت جدید", + "privacyPolicy": "سیاست حفظ حریم خصوصی", + "termsAndConditions": "شرایط و ضوابط استفاده" }, "appUpdate": { "dialogTitle": "نسخه جدید موجود است", diff --git a/lib/core/prefs/general_prefs.dart b/lib/core/prefs/general_prefs.dart index 0242724e..82cd1fa2 100644 --- a/lib/core/prefs/general_prefs.dart +++ b/lib/core/prefs/general_prefs.dart @@ -24,6 +24,25 @@ class IntroCompleted extends _$IntroCompleted { } } +@Riverpod(keepAlive: true) +class RegionNotifier extends _$RegionNotifier { + late final _pref = Pref( + ref.watch(sharedPreferencesProvider), + "region", + Region.other, + mapFrom: Region.values.byName, + mapTo: (value) => value.name, + ); + + @override + Region build() => _pref.getValue(); + + Future update(Region value) { + state = value; + return _pref.update(value); + } +} + @Riverpod(keepAlive: true) class SilentStartNotifier extends _$SilentStartNotifier { late final _pref = diff --git a/lib/core/prefs/locale_prefs.dart b/lib/core/prefs/locale_prefs.dart index 24a697d3..0f294743 100644 --- a/lib/core/prefs/locale_prefs.dart +++ b/lib/core/prefs/locale_prefs.dart @@ -13,7 +13,7 @@ class LocaleNotifier extends _$LocaleNotifier { late final _pref = Pref( ref.watch(sharedPreferencesProvider), "locale", - AppLocale.en, + AppLocaleUtils.findDeviceLocale(), mapFrom: AppLocale.values.byName, mapTo: (value) => value.name, ); diff --git a/lib/domain/constants.dart b/lib/domain/constants.dart index 8151c264..f7bf76b8 100644 --- a/lib/domain/constants.dart +++ b/lib/domain/constants.dart @@ -10,6 +10,8 @@ abstract class Constants { static const githubLatestReleaseUrl = "https://github.com/hiddify/hiddify-next/releases/latest"; static const telegramChannelUrl = "https://t.me/hiddify"; + static const privacyPolicyUrl = "https://hiddify.com/en/privacy-policy/"; + static const termsAndConditionsUrl = "https://hiddify.com/terms/"; } abstract class Defaults { diff --git a/lib/domain/singbox/rules.dart b/lib/domain/singbox/rules.dart index 29cede22..f30f024f 100644 --- a/lib/domain/singbox/rules.dart +++ b/lib/domain/singbox/rules.dart @@ -22,3 +22,15 @@ enum PerAppProxyMode { ), }; } + +enum Region { + ir, + cn, + other; + + String present(TranslationsEn t) => switch (this) { + ir => t.settings.general.regions.ir, + cn => t.settings.general.regions.cn, + other => t.settings.general.regions.other, + }; +} diff --git a/lib/features/common/general_pref_tiles.dart b/lib/features/common/general_pref_tiles.dart index eb4f8c91..7114bafd 100644 --- a/lib/features/common/general_pref_tiles.dart +++ b/lib/features/common/general_pref_tiles.dart @@ -3,6 +3,7 @@ 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/prefs/prefs.dart'; +import 'package:hiddify/domain/singbox/singbox.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; class LocalePrefTile extends HookConsumerWidget { @@ -54,6 +55,48 @@ class LocalePrefTile extends HookConsumerWidget { } } +class RegionPrefTile extends HookConsumerWidget { + const RegionPrefTile({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final t = ref.watch(translationsProvider); + + final region = ref.watch(regionNotifierProvider); + + return ListTile( + title: Text(t.settings.general.region), + subtitle: Text(region.present(t)), + leading: const Icon(Icons.my_location), + onTap: () async { + final selectedRegion = await showDialog( + context: context, + builder: (context) { + return SimpleDialog( + title: Text(t.settings.general.region), + children: Region.values + .map( + (e) => RadioListTile( + title: Text(e.present(t)), + value: e, + groupValue: region, + onChanged: (e) => context.pop(e), + ), + ) + .toList(), + ); + }, + ); + if (selectedRegion != null) { + await ref + .read(regionNotifierProvider.notifier) + .update(selectedRegion); + } + }, + ); + } +} + class EnableAnalyticsPrefTile extends HookConsumerWidget { const EnableAnalyticsPrefTile({ super.key, diff --git a/lib/features/intro/view/intro_page.dart b/lib/features/intro/view/intro_page.dart index ca5f5e61..b78084cb 100644 --- a/lib/features/intro/view/intro_page.dart +++ b/lib/features/intro/view/intro_page.dart @@ -1,7 +1,9 @@ +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:gap/gap.dart'; import 'package:hiddify/core/core_providers.dart'; import 'package:hiddify/core/prefs/prefs.dart'; +import 'package:hiddify/domain/constants.dart'; import 'package:hiddify/features/common/common.dart'; import 'package:hiddify/gen/assets.gen.dart'; import 'package:hiddify/utils/utils.dart'; @@ -37,7 +39,28 @@ class IntroPage extends HookConsumerWidget with PresLogger { children: [ const LocalePrefTile(), const SliverGap(8), + const RegionPrefTile(), + const SliverGap(8), const EnableAnalyticsPrefTile(), + const SliverGap(8), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Text.rich( + t.intro.termsAndPolicyCaution( + tap: (text) => TextSpan( + text: text, + style: const TextStyle(color: Colors.blue), + recognizer: TapGestureRecognizer() + ..onTap = () async { + await UriUtils.tryLaunch( + Uri.parse(Constants.termsAndConditionsUrl), + ); + }, + ), + ), + style: Theme.of(context).textTheme.bodySmall, + ), + ), Padding( padding: const EdgeInsets.symmetric( horizontal: 16,