diff --git a/Makefile b/Makefile index cea1f572..79afdcf4 100644 --- a/Makefile +++ b/Makefile @@ -190,8 +190,9 @@ ios-libs: #not tested curl -L $(CORE_URL)/$(CORE_NAME)-ios.tar.gz | tar xz -C "$(IOS_OUT)" get-geo-assets: - curl -L https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db -o $(GEO_ASSETS_DIR)/geoip.db - curl -L https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db -o $(GEO_ASSETS_DIR)/geosite.db + echo "" + # curl -L https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db -o $(GEO_ASSETS_DIR)/geoip.db + # curl -L https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db -o $(GEO_ASSETS_DIR)/geosite.db build-headers: make -C libcore -f Makefile headers && mv $(BINDIR)/$(CORE_NAME)-headers.h $(BINDIR)/libcore.h diff --git a/assets/translations/strings_en.i18n.json b/assets/translations/strings_en.i18n.json index 99d19ebe..97d055ba 100644 --- a/assets/translations/strings_en.i18n.json +++ b/assets/translations/strings_en.i18n.json @@ -361,6 +361,7 @@ "warpConfigGenerated": "WARP Config Generated", "pageTitle": "Config Options", "logLevel": "Log Level", + "blockAds": "Block Advertisements", "resolveDestination": "Resolve Destination", "ipv6Mode": "IPv6 Route", "ipv6Modes": { diff --git a/assets/translations/strings_fa.i18n.json b/assets/translations/strings_fa.i18n.json index 29510dad..737fc28a 100644 --- a/assets/translations/strings_fa.i18n.json +++ b/assets/translations/strings_fa.i18n.json @@ -361,6 +361,7 @@ "warpConfigGenerated": "پیکربندی WARP ایجاد شد", "pageTitle": "تنظیمات پیکربندی", "logLevel": "سطح گزارش", + "blockAds": "مسدود سازی تبلیغات", "resolveDestination": "جایگذاری مقصد", "ipv6Mode": "مسیریابی IPv6", "ipv6Modes": { diff --git a/lib/bootstrap.dart b/lib/bootstrap.dart index c9abc2fb..ad7d1b17 100644 --- a/lib/bootstrap.dart +++ b/lib/bootstrap.dart @@ -17,7 +17,7 @@ import 'package:hiddify/core/preferences/preferences_provider.dart'; import 'package:hiddify/features/app/widget/app.dart'; import 'package:hiddify/features/auto_start/notifier/auto_start_notifier.dart'; import 'package:hiddify/features/deep_link/notifier/deep_link_notifier.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_data_providers.dart'; + import 'package:hiddify/features/log/data/log_data_providers.dart'; import 'package:hiddify/features/profile/data/profile_data_providers.dart'; import 'package:hiddify/features/profile/notifier/active_profile_notifier.dart'; @@ -36,8 +36,7 @@ Future lazyBootstrap( LoggerController.preInit(); FlutterError.onError = Logger.logFlutterError; - WidgetsBinding.instance.platformDispatcher.onError = - Logger.logPlatformDispatcherError; + WidgetsBinding.instance.platformDispatcher.onError = Logger.logPlatformDispatcherError; final stopWatch = Stopwatch()..start(); @@ -62,14 +61,11 @@ Future lazyBootstrap( () => container.read(sharedPreferencesProvider.future), ); - final enableAnalytics = - await container.read(analyticsControllerProvider.future); + final enableAnalytics = await container.read(analyticsControllerProvider.future); if (enableAnalytics) { await _init( "analytics", - () => container - .read(analyticsControllerProvider.notifier) - .enableAnalytics(), + () => container.read(analyticsControllerProvider.notifier).enableAnalytics(), ); } @@ -78,8 +74,7 @@ Future lazyBootstrap( () async { try { await PreferencesMigration( - sharedPreferences: - container.read(sharedPreferencesProvider).requireValue, + sharedPreferences: container.read(sharedPreferencesProvider).requireValue, ).migrate(); } catch (e, stackTrace) { Logger.bootstrap.error("preferences migration failed", e, stackTrace); @@ -99,8 +94,7 @@ Future lazyBootstrap( ); final silentStart = container.read(Preferences.silentStart); - Logger.bootstrap - .debug("silent start [${silentStart ? "Enabled" : "Disabled"}]"); + Logger.bootstrap.debug("silent start [${silentStart ? "Enabled" : "Disabled"}]"); if (!silentStart) { await container.read(windowNotifierProvider.notifier).open(focus: false); } else { @@ -118,10 +112,7 @@ Future lazyBootstrap( await _init("logger controller", () => LoggerController.postInit(debug)); Logger.bootstrap.info(appInfo.format()); - await _init( - "geo assets repository", - () => container.read(geoAssetRepositoryProvider.future), - ); + await _init( "profile repository", () => container.read(profileRepositoryProvider.future), @@ -180,13 +171,10 @@ Future _init( }) async { final stopWatch = Stopwatch()..start(); Logger.bootstrap.info("initializing [$name]"); - Future func() => timeout != null - ? initializer().timeout(Duration(milliseconds: timeout)) - : initializer(); + Future func() => timeout != null ? initializer().timeout(Duration(milliseconds: timeout)) : initializer(); try { final result = await func(); - Logger.bootstrap - .debug("[$name] initialized in ${stopWatch.elapsedMilliseconds}ms"); + Logger.bootstrap.debug("[$name] initialized in ${stopWatch.elapsedMilliseconds}ms"); return result; } catch (e, stackTrace) { Logger.bootstrap.error("[$name] error initializing", e, stackTrace); diff --git a/lib/core/database/app_database.dart b/lib/core/database/app_database.dart index 84aedb6f..d9e86e37 100644 --- a/lib/core/database/app_database.dart +++ b/lib/core/database/app_database.dart @@ -6,8 +6,8 @@ import 'package:hiddify/core/database/connection/database_connection.dart'; import 'package:hiddify/core/database/converters/duration_converter.dart'; import 'package:hiddify/core/database/schema_versions.dart'; import 'package:hiddify/core/database/tables/database_tables.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_data_mapper.dart'; -import 'package:hiddify/features/geo_asset/model/default_geo_assets.dart'; +// import 'package:hiddify/features/geo_asset/data/geo_asset_data_mapper.dart'; +// import 'package:hiddify/features/geo_asset/model/default_geo_assets.dart'; import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart'; import 'package:hiddify/features/profile/model/profile_entity.dart'; import 'package:hiddify/utils/custom_loggers.dart'; @@ -60,11 +60,11 @@ class AppDatabase extends _$AppDatabase with InfraLogger { Future _prePopulateGeoAssets() async { loggy.debug("populating default geo assets"); await transaction(() async { - final geoAssets = defaultGeoAssets.map((e) => e.toEntry()); - for (final geoAsset in geoAssets) { - await into(geoAssetEntries) - .insert(geoAsset, mode: InsertMode.insertOrIgnore); - } + // final geoAssets = defaultGeoAssets.map((e) => e.toEntry()); + // for (final geoAsset in geoAssets) { + // await into(geoAssetEntries) + // .insert(geoAsset, mode: InsertMode.insertOrIgnore); + // } }); } } diff --git a/lib/core/preferences/general_preferences.dart b/lib/core/preferences/general_preferences.dart index bc36ab66..0c92e31e 100644 --- a/lib/core/preferences/general_preferences.dart +++ b/lib/core/preferences/general_preferences.dart @@ -1,7 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:hiddify/core/app_info/app_info_provider.dart'; import 'package:hiddify/core/model/environment.dart'; -import 'package:hiddify/core/model/region.dart'; +// import 'package:hiddify/core/model/region.dart'; import 'package:hiddify/core/preferences/preferences_provider.dart'; import 'package:hiddify/core/utils/preferences_utils.dart'; import 'package:hiddify/features/per_app_proxy/model/per_app_proxy_mode.dart'; @@ -19,13 +19,6 @@ abstract class Preferences { overrideValue: _debugIntroPage && kDebugMode ? false : null, ); - static final region = PreferencesNotifier.create( - "region", - Region.other, - mapFrom: Region.values.byName, - mapTo: (value) => value.name, - ); - static final silentStart = PreferencesNotifier.create( "silent_start", false, @@ -37,8 +30,7 @@ abstract class Preferences { PlatformUtils.isDesktop, ); - static final perAppProxyMode = - PreferencesNotifier.create( + static final perAppProxyMode = PreferencesNotifier.create( "per_app_proxy_mode", PerAppProxyMode.off, mapFrom: PerAppProxyMode.values.byName, @@ -103,10 +95,7 @@ class PerAppProxyList extends _$PerAppProxyList { ); @override - List build() => - ref.watch(Preferences.perAppProxyMode) == PerAppProxyMode.include - ? _include.read() - : _exclude.read(); + List build() => ref.watch(Preferences.perAppProxyMode) == PerAppProxyMode.include ? _include.read() : _exclude.read(); Future update(List value) { state = value; diff --git a/lib/core/router/routes.dart b/lib/core/router/routes.dart index 0cfce287..d60713c3 100644 --- a/lib/core/router/routes.dart +++ b/lib/core/router/routes.dart @@ -4,7 +4,7 @@ import 'package:hiddify/core/router/app_router.dart'; import 'package:hiddify/features/common/adaptive_root_scaffold.dart'; import 'package:hiddify/features/config_option/overview/config_options_page.dart'; import 'package:hiddify/features/config_option/widget/quick_settings_modal.dart'; -import 'package:hiddify/features/geo_asset/overview/geo_assets_overview_page.dart'; + import 'package:hiddify/features/home/widget/home_page.dart'; import 'package:hiddify/features/intro/widget/intro_page.dart'; import 'package:hiddify/features/log/overview/logs_overview_page.dart'; @@ -19,8 +19,7 @@ import 'package:hiddify/utils/utils.dart'; part 'routes.g.dart'; -GlobalKey? _dynamicRootKey = - useMobileRouter ? rootNavigatorKey : null; +GlobalKey? _dynamicRootKey = useMobileRouter ? rootNavigatorKey : null; @TypedShellRoute( routes: [ @@ -60,10 +59,6 @@ GlobalKey? _dynamicRootKey = path: "per-app-proxy", name: PerAppProxyRoute.name, ), - TypedGoRoute( - path: "routing-assets", - name: GeoAssetsRoute.name, - ), ], ), TypedGoRoute( @@ -130,12 +125,7 @@ class MobileWrapperRoute extends ShellRouteData { TypedGoRoute( path: "/settings", name: SettingsRoute.name, - routes: [ - TypedGoRoute( - path: "routing-assets", - name: GeoAssetsRoute.name, - ), - ], + routes: [], ), TypedGoRoute( path: "/logs", @@ -229,8 +219,7 @@ class ProfilesOverviewRoute extends GoRouteData { Page buildPage(BuildContext context, GoRouterState state) { return BottomSheetPage( name: name, - builder: (controller) => - ProfilesOverviewModal(scrollController: controller), + builder: (controller) => ProfilesOverviewModal(scrollController: controller), ); } } @@ -358,28 +347,6 @@ class PerAppProxyRoute extends GoRouteData { } } -class GeoAssetsRoute extends GoRouteData { - const GeoAssetsRoute(); - static const name = "Routing Assets"; - - static final GlobalKey? $parentNavigatorKey = _dynamicRootKey; - - @override - Page buildPage(BuildContext context, GoRouterState state) { - if (useMobileRouter) { - return const MaterialPage( - name: name, - child: GeoAssetsOverviewPage(), - ); - } - return const MaterialPage( - fullscreenDialog: true, - name: name, - child: GeoAssetsOverviewPage(), - ); - } -} - class AboutRoute extends GoRouteData { const AboutRoute(); static const name = "About"; diff --git a/lib/features/app/widget/app.dart b/lib/features/app/widget/app.dart index 90efc596..202aca4b 100644 --- a/lib/features/app/widget/app.dart +++ b/lib/features/app/widget/app.dart @@ -39,36 +39,37 @@ class App extends HookConsumerWidget with PresLogger { return WindowWrapper( TrayWrapper( ShortcutWrapper( - ConnectionWrapper(DynamicColorBuilder( - builder: - (ColorScheme? lightColorScheme, ColorScheme? darkColorScheme) { - return MaterialApp.router( - routerConfig: router, - locale: locale.flutterLocale, - supportedLocales: AppLocaleUtils.supportedLocales, - localizationsDelegates: GlobalMaterialLocalizations.delegates, - debugShowCheckedModeBanner: false, - themeMode: themeMode.flutterThemeMode, - theme: theme.lightTheme(lightColorScheme), - darkTheme: theme.darkTheme(darkColorScheme), - title: Constants.appName, - builder: (context, child) { - child = UpgradeAlert( - upgrader: upgrader, - navigatorKey: router.routerDelegate.navigatorKey, - child: child ?? const SizedBox(), - ); - if (kDebugMode && _debugAccessibility) { - return AccessibilityTools( - checkFontOverflows: true, - child: child, + ConnectionWrapper( + DynamicColorBuilder( + builder: (ColorScheme? lightColorScheme, ColorScheme? darkColorScheme) { + return MaterialApp.router( + routerConfig: router, + locale: locale.flutterLocale, + supportedLocales: AppLocaleUtils.supportedLocales, + localizationsDelegates: GlobalMaterialLocalizations.delegates, + debugShowCheckedModeBanner: false, + themeMode: themeMode.flutterThemeMode, + theme: theme.lightTheme(lightColorScheme), + darkTheme: theme.darkTheme(darkColorScheme), + title: Constants.appName, + builder: (context, child) { + child = UpgradeAlert( + upgrader: upgrader, + navigatorKey: router.routerDelegate.navigatorKey, + child: child ?? const SizedBox(), ); - } - return child; - }, - ); - }, - )), + if (kDebugMode && _debugAccessibility) { + return AccessibilityTools( + checkFontOverflows: true, + child: child, + ); + } + return child; + }, + ); + }, + ), + ), ), ), ); diff --git a/lib/features/common/general_pref_tiles.dart b/lib/features/common/general_pref_tiles.dart index 60884ba3..5073f3b9 100644 --- a/lib/features/common/general_pref_tiles.dart +++ b/lib/features/common/general_pref_tiles.dart @@ -6,6 +6,8 @@ import 'package:hiddify/core/localization/locale_preferences.dart'; import 'package:hiddify/core/localization/translations.dart'; import 'package:hiddify/core/model/region.dart'; import 'package:hiddify/core/preferences/general_preferences.dart'; +import 'package:hiddify/features/config_option/data/config_option_repository.dart'; +import 'package:hiddify/features/config_option/notifier/config_option_notifier.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; class LocalePrefTile extends HookConsumerWidget { @@ -41,9 +43,7 @@ class LocalePrefTile extends HookConsumerWidget { }, ); if (selectedLocale != null) { - await ref - .read(localePreferencesProvider.notifier) - .changeLocale(selectedLocale); + await ref.read(localePreferencesProvider.notifier).changeLocale(selectedLocale); } }, ); @@ -57,7 +57,7 @@ class RegionPrefTile extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final t = ref.watch(translationsProvider); - final region = ref.watch(Preferences.region); + final region = ref.watch(ConfigOptions.region); return ListTile( title: Text(t.settings.general.region), @@ -83,7 +83,16 @@ class RegionPrefTile extends HookConsumerWidget { }, ); if (selectedRegion != null) { - await ref.read(Preferences.region.notifier).update(selectedRegion); + // await ref.read(Preferences.region.notifier).update(selectedRegion); + await ref.watch(ConfigOptions.region.notifier).update(selectedRegion); + + // await ref.read(configOptionNotifierProvider.notifier).build(); + // await ref.watch(ConfigOptions.resolveDestination.notifier).update(!ref.watch(ConfigOptions.resolveDestination.notifier).raw()); + //for reload config + // final tmp = ref.watch(ConfigOptions.resolveDestination.notifier).raw(); + // await ref.watch(ConfigOptions.resolveDestination.notifier).update(!tmp); + // await ref.watch(ConfigOptions.resolveDestination.notifier).update(tmp); + //TODO: fix it } }, ); @@ -117,13 +126,9 @@ class EnableAnalyticsPrefTile extends HookConsumerWidget { return onChanged!(value); } if (enabled) { - await ref - .read(analyticsControllerProvider.notifier) - .disableAnalytics(); + await ref.read(analyticsControllerProvider.notifier).disableAnalytics(); } else { - await ref - .read(analyticsControllerProvider.notifier) - .enableAnalytics(); + await ref.read(analyticsControllerProvider.notifier).enableAnalytics(); } }, ); diff --git a/lib/features/config_option/data/config_option_data_providers.dart b/lib/features/config_option/data/config_option_data_providers.dart index f28d127e..36e41b43 100644 --- a/lib/features/config_option/data/config_option_data_providers.dart +++ b/lib/features/config_option/data/config_option_data_providers.dart @@ -1,6 +1,6 @@ import 'package:hiddify/core/preferences/preferences_provider.dart'; import 'package:hiddify/features/config_option/data/config_option_repository.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_data_providers.dart'; + import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'config_option_data_providers.g.dart'; @@ -12,7 +12,5 @@ ConfigOptionRepository configOptionRepository( return ConfigOptionRepository( preferences: ref.watch(sharedPreferencesProvider).requireValue, getConfigOptions: () => ref.read(ConfigOptions.singboxConfigOptions.future), - geoAssetRepository: ref.watch(geoAssetRepositoryProvider).requireValue, - geoAssetPathResolver: ref.watch(geoAssetPathResolverProvider), ); } diff --git a/lib/features/config_option/data/config_option_repository.dart b/lib/features/config_option/data/config_option_repository.dart index bc61a9c3..b1c041fc 100644 --- a/lib/features/config_option/data/config_option_repository.dart +++ b/lib/features/config_option/data/config_option_repository.dart @@ -3,13 +3,12 @@ import 'package:fpdart/fpdart.dart'; import 'package:hiddify/core/model/optional_range.dart'; import 'package:hiddify/core/model/region.dart'; import 'package:hiddify/core/preferences/general_preferences.dart'; + import 'package:hiddify/core/utils/exception_handler.dart'; import 'package:hiddify/core/utils/json_converters.dart'; import 'package:hiddify/core/utils/preferences_utils.dart'; import 'package:hiddify/features/config_option/model/config_option_failure.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_data_providers.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_path_resolver.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_repository.dart'; + import 'package:hiddify/features/log/model/log_level.dart'; import 'package:hiddify/singbox/model/singbox_config_enum.dart'; import 'package:hiddify/singbox/model/singbox_config_option.dart'; @@ -26,6 +25,17 @@ abstract class ConfigOptions { mapTo: (value) => value.key, ); + static final region = PreferencesNotifier.create( + "region", + Region.other, + mapFrom: Region.values.byName, + mapTo: (value) => value.name, + ); + + static final blockAds = PreferencesNotifier.create( + "block-ads", + false, + ); static final logLevel = PreferencesNotifier.create( "log-level", LogLevel.warn, @@ -305,6 +315,8 @@ abstract class ConfigOptions { }; static final Map> preferences = { + "region": region, + "block-ads": blockAds, "service-mode": serviceMode, "log-level": logLevel, "resolve-destination": resolveDestination, @@ -359,44 +371,46 @@ abstract class ConfigOptions { static final singboxConfigOptions = FutureProvider( (ref) async { - final region = ref.watch(Preferences.region); - final rules = switch (region) { - Region.ir => [ - const SingboxRule( - domains: "domain:.ir,geosite:ir", - ip: "geoip:ir", - outbound: RuleOutbound.bypass, - ), - ], - Region.cn => [ - const SingboxRule( - domains: "domain:.cn,geosite:cn", - ip: "geoip:cn", - outbound: RuleOutbound.bypass, - ), - ], - Region.ru => [ - const SingboxRule( - domains: "domain:.ru", - ip: "geoip:ru", - outbound: RuleOutbound.bypass, - ), - ], - Region.af => [ - const SingboxRule( - domains: "domain:.af,geosite:af", - ip: "geoip:af", - outbound: RuleOutbound.bypass, - ), - ], - _ => [], - }; - - final geoAssetsRepo = await ref.watch(geoAssetRepositoryProvider.future); - final geoAssets = await geoAssetsRepo.getActivePair().getOrElse((l) => throw l).run(); + // final region = ref.watch(Preferences.region); + final rules = []; + // final rules = switch (region) { + // Region.ir => [ + // const SingboxRule( + // domains: "domain:.ir,geosite:ir", + // ip: "geoip:ir", + // outbound: RuleOutbound.bypass, + // ), + // ], + // Region.cn => [ + // const SingboxRule( + // domains: "domain:.cn,geosite:cn", + // ip: "geoip:cn", + // outbound: RuleOutbound.bypass, + // ), + // ], + // Region.ru => [ + // const SingboxRule( + // domains: "domain:.ru", + // ip: "geoip:ru", + // outbound: RuleOutbound.bypass, + // ), + // ], + // Region.af => [ + // const SingboxRule( + // domains: "domain:.af,geosite:af", + // ip: "geoip:af", + // outbound: RuleOutbound.bypass, + // ), + // ], + // _ => [], + // }; final mode = ref.watch(serviceMode); + // final reg = ref.watch(Preferences.region.notifier).raw(); + return SingboxConfigOption( + region: ref.watch(region).name, + blockAds: ref.watch(blockAds), executeConfigAsIs: false, logLevel: ref.watch(logLevel), resolveDestination: ref.watch(resolveDestination), @@ -461,14 +475,14 @@ abstract class ConfigOptions { noise: ref.watch(warpNoise), noiseDelay: ref.watch(warpNoiseDelay), ), - geoipPath: ref.watch(geoAssetPathResolverProvider).relativePath( - geoAssets.geoip.providerName, - geoAssets.geoip.fileName, - ), - geositePath: ref.watch(geoAssetPathResolverProvider).relativePath( - geoAssets.geosite.providerName, - geoAssets.geosite.fileName, - ), + // geoipPath: ref.watch(geoAssetPathResolverProvider).relativePath( + // geoAssets.geoip.providerName, + // geoAssets.geoip.fileName, + // ), + // geositePath: ref.watch(geoAssetPathResolverProvider).relativePath( + // geoAssets.geosite.providerName, + // geoAssets.geosite.fileName, + // ), rules: rules, ); }, @@ -479,14 +493,10 @@ class ConfigOptionRepository with ExceptionHandler, InfraLogger { ConfigOptionRepository({ required this.preferences, required this.getConfigOptions, - required this.geoAssetRepository, - required this.geoAssetPathResolver, }); final SharedPreferences preferences; final Future Function() getConfigOptions; - final GeoAssetRepository geoAssetRepository; - final GeoAssetPathResolver geoAssetPathResolver; TaskEither getFullSingboxConfigOption() { return exceptionHandler( diff --git a/lib/features/config_option/notifier/config_option_notifier.dart b/lib/features/config_option/notifier/config_option_notifier.dart index cd7793b5..96750017 100644 --- a/lib/features/config_option/notifier/config_option_notifier.dart +++ b/lib/features/config_option/notifier/config_option_notifier.dart @@ -15,16 +15,13 @@ class ConfigOptionNotifier extends _$ConfigOptionNotifier with AppLogger { @override Future build() async { final serviceRunning = await ref.watch(serviceRunningProvider.future); - final serviceSingboxOptions = - ref.read(connectionRepositoryProvider).configOptionsSnapshot; + final serviceSingboxOptions = ref.read(connectionRepositoryProvider).configOptionsSnapshot; ref.listen( ConfigOptions.singboxConfigOptions, (previous, next) async { if (!serviceRunning || serviceSingboxOptions == null) return; if (next case AsyncData(:final value) when next != previous) { - if (_lastUpdate == null || - DateTime.now().difference(_lastUpdate!) > - const Duration(milliseconds: 100)) { + if (_lastUpdate == null || DateTime.now().difference(_lastUpdate!) > const Duration(milliseconds: 100)) { _lastUpdate = DateTime.now(); state = AsyncData(value != serviceSingboxOptions); } @@ -63,8 +60,7 @@ class ConfigOptionNotifier extends _$ConfigOptionNotifier with AppLogger { Future importFromClipboard() async { try { - final input = - await Clipboard.getData("text/plain").then((value) => value?.text); + final input = await Clipboard.getData("text/plain").then((value) => value?.text); if (input == null) return false; if (jsonDecode(input) case final Map map) { for (final option in ConfigOptions.preferences.entries) { diff --git a/lib/features/config_option/overview/config_options_page.dart b/lib/features/config_option/overview/config_options_page.dart index 3ef2a948..b8af676b 100644 --- a/lib/features/config_option/overview/config_options_page.dart +++ b/lib/features/config_option/overview/config_options_page.dart @@ -4,8 +4,8 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:gap/gap.dart'; import 'package:hiddify/core/localization/translations.dart'; import 'package:hiddify/core/model/optional_range.dart'; +import 'package:hiddify/core/model/region.dart'; import 'package:hiddify/core/notification/in_app_notification_controller.dart'; -import 'package:hiddify/core/preferences/general_preferences.dart'; import 'package:hiddify/core/widget/adaptive_icon.dart'; import 'package:hiddify/core/widget/tip_card.dart'; import 'package:hiddify/features/common/confirmation_dialogs.dart'; @@ -140,6 +140,18 @@ class ConfigOptionsPage extends HookConsumerWidget { ), const SettingsDivider(), SettingsSection(t.config.section.route), + ChoicePreferenceWidget( + selected: ref.watch(ConfigOptions.region), + preferences: ref.watch(ConfigOptions.region.notifier), + choices: Region.values, + title: t.settings.general.region, + presentChoice: (value) => value.present(t), + ), + SwitchListTile( + title: Text(experimental(t.config.blockAds)), + value: ref.watch(ConfigOptions.blockAds), + onChanged: ref.watch(ConfigOptions.blockAds.notifier).update, + ), SwitchListTile( title: Text(experimental(t.config.bypassLan)), value: ref.watch(ConfigOptions.bypassLan), diff --git a/lib/features/connection/data/connection_data_providers.dart b/lib/features/connection/data/connection_data_providers.dart index 96de56d9..e62edf6c 100644 --- a/lib/features/connection/data/connection_data_providers.dart +++ b/lib/features/connection/data/connection_data_providers.dart @@ -2,7 +2,7 @@ import 'package:hiddify/core/directories/directories_provider.dart'; import 'package:hiddify/features/config_option/data/config_option_data_providers.dart'; import 'package:hiddify/features/connection/data/connection_platform_source.dart'; import 'package:hiddify/features/connection/data/connection_repository.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_data_providers.dart'; + import 'package:hiddify/features/profile/data/profile_data_providers.dart'; import 'package:hiddify/singbox/service/singbox_service_provider.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; @@ -19,6 +19,5 @@ ConnectionRepository connectionRepository( singbox: ref.watch(singboxServiceProvider), platformSource: ConnectionPlatformSourceImpl(), profilePathResolver: ref.watch(profilePathResolverProvider), - geoAssetPathResolver: ref.watch(geoAssetPathResolverProvider), ); } diff --git a/lib/features/connection/data/connection_repository.dart b/lib/features/connection/data/connection_repository.dart index 27c35625..71267019 100644 --- a/lib/features/connection/data/connection_repository.dart +++ b/lib/features/connection/data/connection_repository.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:fpdart/fpdart.dart'; import 'package:hiddify/core/model/directories.dart'; import 'package:hiddify/core/utils/exception_handler.dart'; @@ -7,7 +5,7 @@ import 'package:hiddify/features/config_option/data/config_option_repository.dar import 'package:hiddify/features/connection/data/connection_platform_source.dart'; import 'package:hiddify/features/connection/model/connection_failure.dart'; import 'package:hiddify/features/connection/model/connection_status.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_path_resolver.dart'; + import 'package:hiddify/features/profile/data/profile_path_resolver.dart'; import 'package:hiddify/singbox/model/singbox_config_option.dart'; import 'package:hiddify/singbox/model/singbox_status.dart'; @@ -33,16 +31,13 @@ abstract interface class ConnectionRepository { ); } -class ConnectionRepositoryImpl - with ExceptionHandler, InfraLogger - implements ConnectionRepository { +class ConnectionRepositoryImpl with ExceptionHandler, InfraLogger implements ConnectionRepository { ConnectionRepositoryImpl({ required this.directories, required this.singbox, required this.platformSource, required this.configOptionRepository, required this.profilePathResolver, - required this.geoAssetPathResolver, }); final Directories directories; @@ -50,7 +45,6 @@ class ConnectionRepositoryImpl final ConnectionPlatformSource platformSource; final ConfigOptionRepository configOptionRepository; final ProfilePathResolver profilePathResolver; - final GeoAssetPathResolver geoAssetPathResolver; SingboxConfigOption? _configOptionsSnapshot; @override @@ -64,16 +58,10 @@ class ConnectionRepositoryImpl (event) => switch (event) { SingboxStopped(:final alert?, :final message) => Disconnected( switch (alert) { - SingboxAlert.emptyConfiguration => - ConnectionFailure.invalidConfig(message), - SingboxAlert.requestNotificationPermission => - ConnectionFailure.missingNotificationPermission(message), - SingboxAlert.requestVPNPermission => - ConnectionFailure.missingVpnPermission(message), - SingboxAlert.startCommandServer || - SingboxAlert.createService || - SingboxAlert.startService => - ConnectionFailure.unexpected(message), + SingboxAlert.emptyConfiguration => ConnectionFailure.invalidConfig(message), + SingboxAlert.requestNotificationPermission => ConnectionFailure.missingNotificationPermission(message), + SingboxAlert.requestVPNPermission => ConnectionFailure.missingVpnPermission(message), + SingboxAlert.startCommandServer || SingboxAlert.createService || SingboxAlert.startService => ConnectionFailure.unexpected(message), }, ), SingboxStopped() => const Disconnected(), @@ -89,21 +77,19 @@ class ConnectionRepositoryImpl return TaskEither.Do( ($) async { final options = await $( - configOptionRepository - .getFullSingboxConfigOption() - .mapLeft((l) => const InvalidConfigOption()), + configOptionRepository.getFullSingboxConfigOption().mapLeft((l) => const InvalidConfigOption()), ); return $( TaskEither( () async { - final geoip = geoAssetPathResolver.resolvePath(options.geoipPath); - final geosite = - geoAssetPathResolver.resolvePath(options.geositePath); - if (!await File(geoip).exists() || - !await File(geosite).exists()) { - return left(const ConnectionFailure.missingGeoAssets()); - } + // final geoip = geoAssetPathResolver.resolvePath(options.geoipPath); + // final geosite = + // geoAssetPathResolver.resolvePath(options.geositePath); + // if (!await File(geoip).exists() || + // !await File(geosite).exists()) { + // return left(const ConnectionFailure.missingGeoAssets()); + // } return right(options); }, ), @@ -119,10 +105,7 @@ class ConnectionRepositoryImpl return exceptionHandler( () { _configOptionsSnapshot = options; - return singbox - .changeOptions(options) - .mapLeft(InvalidConfigOption.new) - .run(); + return singbox.changeOptions(options).mapLeft(InvalidConfigOption.new).run(); }, UnexpectedConnectionFailure.new, ); diff --git a/lib/features/connection/notifier/connection_notifier.dart b/lib/features/connection/notifier/connection_notifier.dart index 8ce1ddfa..e09cebfd 100644 --- a/lib/features/connection/notifier/connection_notifier.dart +++ b/lib/features/connection/notifier/connection_notifier.dart @@ -8,10 +8,10 @@ import 'package:hiddify/features/connection/model/connection_status.dart'; import 'package:hiddify/features/profile/model/profile_entity.dart'; import 'package:hiddify/features/profile/notifier/active_profile_notifier.dart'; import 'package:hiddify/utils/utils.dart'; +import 'package:in_app_review/in_app_review.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:rxdart/rxdart.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; -import 'package:in_app_review/in_app_review.dart'; part 'connection_notifier.g.dart'; @@ -32,8 +32,7 @@ class ConnectionNotifier extends _$ConnectionNotifier with AppLogger { if (next case AsyncData(value: final Connected _)) { await ref.read(hapticServiceProvider.notifier).heavyImpact(); - if (Platform.isAndroid && - !ref.read(Preferences.storeReviewedByUser)) { + if (Platform.isAndroid && !ref.read(Preferences.storeReviewedByUser)) { if (await InAppReview.instance.isAvailable()) { InAppReview.instance.requestReview(); ref.read(Preferences.storeReviewedByUser.notifier).update(true); @@ -55,16 +54,14 @@ class ConnectionNotifier extends _$ConnectionNotifier with AppLogger { }, ); yield* _connectionRepo.watchConnectionStatus().doOnData((event) { - if (event case Disconnected(connectionFailure: final _?) - when PlatformUtils.isDesktop) { + if (event case Disconnected(connectionFailure: final _?) when PlatformUtils.isDesktop) { ref.read(Preferences.startedByUser.notifier).update(false); } loggy.info("connection status: ${event.format()}"); }); } - ConnectionRepository get _connectionRepo => - ref.read(connectionRepositoryProvider); + ConnectionRepository get _connectionRepo => ref.read(connectionRepositoryProvider); Future mayConnect() async { if (state case AsyncData(:final value)) { diff --git a/lib/features/geo_asset/data/geo_asset_data_providers.dart b/lib/features/geo_asset/data/geo_asset_data_providers.dart index 2290ab6a..7eaecde2 100644 --- a/lib/features/geo_asset/data/geo_asset_data_providers.dart +++ b/lib/features/geo_asset/data/geo_asset_data_providers.dart @@ -1,32 +1,32 @@ -import 'package:hiddify/core/database/database_provider.dart'; -import 'package:hiddify/core/directories/directories_provider.dart'; -import 'package:hiddify/core/http_client/http_client_provider.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_data_source.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_path_resolver.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_repository.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; +// import 'package:hiddify/core/database/database_provider.dart'; +// import 'package:hiddify/core/directories/directories_provider.dart'; +// import 'package:hiddify/core/http_client/http_client_provider.dart'; +// import 'package:hiddify/features/geo_asset/data/geo_asset_data_source.dart'; +// import 'package:hiddify/features/geo_asset/data/geo_asset_path_resolver.dart'; +// import 'package:hiddify/features/geo_asset/data/geo_asset_repository.dart'; +// import 'package:riverpod_annotation/riverpod_annotation.dart'; -part 'geo_asset_data_providers.g.dart'; +// part 'geo_asset_data_providers.g.dart'; -@Riverpod(keepAlive: true) -Future geoAssetRepository(GeoAssetRepositoryRef ref) async { - final repo = GeoAssetRepositoryImpl( - geoAssetDataSource: ref.watch(geoAssetDataSourceProvider), - geoAssetPathResolver: ref.watch(geoAssetPathResolverProvider), - httpClient: ref.watch(httpClientProvider), - ); - await repo.init().getOrElse((l) => throw l).run(); - return repo; -} +// @Riverpod(keepAlive: true) +// Future geoAssetRepository(GeoAssetRepositoryRef ref) async { +// final repo = GeoAssetRepositoryImpl( +// geoAssetDataSource: ref.watch(geoAssetDataSourceProvider), +// geoAssetPathResolver: ref.watch(geoAssetPathResolverProvider), +// httpClient: ref.watch(httpClientProvider), +// ); +// await repo.init().getOrElse((l) => throw l).run(); +// return repo; +// } -@Riverpod(keepAlive: true) -GeoAssetDataSource geoAssetDataSource(GeoAssetDataSourceRef ref) { - return GeoAssetsDao(ref.watch(appDatabaseProvider)); -} +// @Riverpod(keepAlive: true) +// GeoAssetDataSource geoAssetDataSource(GeoAssetDataSourceRef ref) { +// return GeoAssetsDao(ref.watch(appDatabaseProvider)); +// } -@Riverpod(keepAlive: true) -GeoAssetPathResolver geoAssetPathResolver(GeoAssetPathResolverRef ref) { - return GeoAssetPathResolver( - ref.watch(appDirectoriesProvider).requireValue.workingDir, - ); -} +// @Riverpod(keepAlive: true) +// GeoAssetPathResolver geoAssetPathResolver(GeoAssetPathResolverRef ref) { +// return GeoAssetPathResolver( +// ref.watch(appDirectoriesProvider).requireValue.workingDir, +// ); +// } diff --git a/lib/features/geo_asset/data/geo_asset_repository.dart b/lib/features/geo_asset/data/geo_asset_repository.dart index a8f7a68b..2cf7b9de 100644 --- a/lib/features/geo_asset/data/geo_asset_repository.dart +++ b/lib/features/geo_asset/data/geo_asset_repository.dart @@ -1,232 +1,232 @@ -import 'dart:io'; +// import 'dart:io'; -import 'package:dartx/dartx_io.dart'; -import 'package:drift/drift.dart'; -import 'package:flutter/services.dart'; -import 'package:fpdart/fpdart.dart'; -import 'package:hiddify/core/database/app_database.dart'; -import 'package:hiddify/core/http_client/dio_http_client.dart'; -import 'package:hiddify/core/utils/exception_handler.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_data_mapper.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_data_source.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_path_resolver.dart'; -import 'package:hiddify/features/geo_asset/model/default_geo_assets.dart'; -import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart'; -import 'package:hiddify/features/geo_asset/model/geo_asset_failure.dart'; -import 'package:hiddify/gen/assets.gen.dart'; -import 'package:hiddify/utils/custom_loggers.dart'; -import 'package:rxdart/rxdart.dart'; -import 'package:watcher/watcher.dart'; +// import 'package:dartx/dartx_io.dart'; +// import 'package:drift/drift.dart'; +// import 'package:flutter/services.dart'; +// import 'package:fpdart/fpdart.dart'; +// import 'package:hiddify/core/database/app_database.dart'; +// import 'package:hiddify/core/http_client/dio_http_client.dart'; +// import 'package:hiddify/core/utils/exception_handler.dart'; +// import 'package:hiddify/features/geo_asset/data/geo_asset_data_mapper.dart'; +// import 'package:hiddify/features/geo_asset/data/geo_asset_data_source.dart'; +// import 'package:hiddify/features/geo_asset/data/geo_asset_path_resolver.dart'; +// import 'package:hiddify/features/geo_asset/model/default_geo_assets.dart'; +// import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart'; +// import 'package:hiddify/features/geo_asset/model/geo_asset_failure.dart'; +// import 'package:hiddify/gen/assets.gen.dart'; +// import 'package:hiddify/utils/custom_loggers.dart'; +// import 'package:rxdart/rxdart.dart'; +// import 'package:watcher/watcher.dart'; -abstract interface class GeoAssetRepository { - /// populate bundled geo assets directory with bundled files if needed - TaskEither init(); - TaskEither - getActivePair(); - Stream>> watchAll(); - TaskEither update(GeoAssetEntity geoAsset); - TaskEither markAsActive(GeoAssetEntity geoAsset); - TaskEither addRecommended(); -} +// abstract interface class GeoAssetRepository { +// /// populate bundled geo assets directory with bundled files if needed +// TaskEither init(); +// TaskEither +// getActivePair(); +// Stream>> watchAll(); +// TaskEither update(GeoAssetEntity geoAsset); +// TaskEither markAsActive(GeoAssetEntity geoAsset); +// TaskEither addRecommended(); +// } -class GeoAssetRepositoryImpl - with ExceptionHandler, InfraLogger - implements GeoAssetRepository { - GeoAssetRepositoryImpl({ - required this.geoAssetDataSource, - required this.geoAssetPathResolver, - required this.httpClient, - }); +// class GeoAssetRepositoryImpl +// with ExceptionHandler, InfraLogger +// implements GeoAssetRepository { +// GeoAssetRepositoryImpl({ +// required this.geoAssetDataSource, +// required this.geoAssetPathResolver, +// required this.httpClient, +// }); - final GeoAssetDataSource geoAssetDataSource; - final GeoAssetPathResolver geoAssetPathResolver; - final DioHttpClient httpClient; +// final GeoAssetDataSource geoAssetDataSource; +// final GeoAssetPathResolver geoAssetPathResolver; +// final DioHttpClient httpClient; - @override - TaskEither init() { - return exceptionHandler( - () async { - loggy.debug("initializing"); - final geoipFile = geoAssetPathResolver.file( - defaultGeoip.providerName, - defaultGeoip.fileName, - ); - final geositeFile = geoAssetPathResolver.file( - defaultGeosite.providerName, - defaultGeosite.fileName, - ); +// @override +// TaskEither init() { +// return exceptionHandler( +// () async { +// loggy.debug("initializing"); +// final geoipFile = geoAssetPathResolver.file( +// defaultGeoip.providerName, +// defaultGeoip.fileName, +// ); +// final geositeFile = geoAssetPathResolver.file( +// defaultGeosite.providerName, +// defaultGeosite.fileName, +// ); - final dirExists = await geoAssetPathResolver.directory.exists(); - if (!dirExists) { - await geoAssetPathResolver.directory.create(recursive: true); - } +// final dirExists = await geoAssetPathResolver.directory.exists(); +// if (!dirExists) { +// await geoAssetPathResolver.directory.create(recursive: true); +// } - if (!dirExists || !await geoipFile.exists()) { - final bundledGeoip = await rootBundle.load(Assets.core.geoip); - await geoipFile.writeAsBytes(bundledGeoip.buffer.asInt8List()); - } - if (!dirExists || !await geositeFile.exists()) { - final bundledGeosite = await rootBundle.load(Assets.core.geosite); - await geositeFile.writeAsBytes(bundledGeosite.buffer.asInt8List()); - } - return right(unit); - }, - GeoAssetUnexpectedFailure.new, - ); - } +// if (!dirExists || !await geoipFile.exists()) { +// final bundledGeoip = await rootBundle.load(Assets.core.geoip); +// await geoipFile.writeAsBytes(bundledGeoip.buffer.asInt8List()); +// } +// if (!dirExists || !await geositeFile.exists()) { +// final bundledGeosite = await rootBundle.load(Assets.core.geosite); +// await geositeFile.writeAsBytes(bundledGeosite.buffer.asInt8List()); +// } +// return right(unit); +// }, +// GeoAssetUnexpectedFailure.new, +// ); +// } - @override - TaskEither - getActivePair() { - return exceptionHandler( - () async { - final geoip = - await geoAssetDataSource.getActiveAssetByType(GeoAssetType.geoip); - final geosite = - await geoAssetDataSource.getActiveAssetByType(GeoAssetType.geosite); - if (geoip == null || geosite == null) { - return left(const GeoAssetFailure.activeAssetNotFound()); - } - return right((geoip: geoip.toEntity(), geosite: geosite.toEntity())); - }, - GeoAssetUnexpectedFailure.new, - ); - } +// @override +// TaskEither +// getActivePair() { +// return exceptionHandler( +// () async { +// final geoip = +// await geoAssetDataSource.getActiveAssetByType(GeoAssetType.geoip); +// final geosite = +// await geoAssetDataSource.getActiveAssetByType(GeoAssetType.geosite); +// if (geoip == null || geosite == null) { +// return left(const GeoAssetFailure.activeAssetNotFound()); +// } +// return right((geoip: geoip.toEntity(), geosite: geosite.toEntity())); +// }, +// GeoAssetUnexpectedFailure.new, +// ); +// } - @override - Stream>> watchAll() { - final persistedStream = geoAssetDataSource - .watchAll() - .map((event) => event.map((e) => e.toEntity())); - final filesStream = _watchGeoFiles(); +// @override +// Stream>> watchAll() { +// final persistedStream = geoAssetDataSource +// .watchAll() +// .map((event) => event.map((e) => e.toEntity())); +// final filesStream = _watchGeoFiles(); - return Rx.combineLatest2( - persistedStream, - filesStream, - (assets, files) => assets.map( - (e) { - final path = - geoAssetPathResolver.file(e.providerName, e.fileName).path; - final file = files.firstOrNullWhere((e) => e.path == path); - final stat = file?.statSync(); - return (e, stat?.size); - }, - ).toList(), - ).handleExceptions(GeoAssetUnexpectedFailure.new); - } +// return Rx.combineLatest2( +// persistedStream, +// filesStream, +// (assets, files) => assets.map( +// (e) { +// final path = +// geoAssetPathResolver.file(e.providerName, e.fileName).path; +// final file = files.firstOrNullWhere((e) => e.path == path); +// final stat = file?.statSync(); +// return (e, stat?.size); +// }, +// ).toList(), +// ).handleExceptions(GeoAssetUnexpectedFailure.new); +// } - Iterable _geoFiles = []; - Stream> _watchGeoFiles() async* { - yield await _readGeoFiles(); - yield* Watcher( - geoAssetPathResolver.directory.path, - pollingDelay: const Duration(seconds: 1), - ).events.asyncMap((event) async { - await _readGeoFiles(); - return _geoFiles; - }); - } +// Iterable _geoFiles = []; +// Stream> _watchGeoFiles() async* { +// yield await _readGeoFiles(); +// yield* Watcher( +// geoAssetPathResolver.directory.path, +// pollingDelay: const Duration(seconds: 1), +// ).events.asyncMap((event) async { +// await _readGeoFiles(); +// return _geoFiles; +// }); +// } - Future> _readGeoFiles() async { - return _geoFiles = Directory(geoAssetPathResolver.directory.path) - .listSync() - .whereType() - .where((e) => e.extension == '.db'); - } +// Future> _readGeoFiles() async { +// return _geoFiles = Directory(geoAssetPathResolver.directory.path) +// .listSync() +// .whereType() +// .where((e) => e.extension == '.db'); +// } - @override - TaskEither update(GeoAssetEntity geoAsset) { - return exceptionHandler( - () async { - loggy.debug( - "checking latest release of [${geoAsset.name}] on [${geoAsset.repositoryUrl}]", - ); - final response = await httpClient.get(geoAsset.repositoryUrl); - if (response.statusCode != 200 || response.data == null) { - return left( - GeoAssetUnexpectedFailure.new( - "invalid response", - StackTrace.current, - ), - ); - } +// @override +// TaskEither update(GeoAssetEntity geoAsset) { +// return exceptionHandler( +// () async { +// loggy.debug( +// "checking latest release of [${geoAsset.name}] on [${geoAsset.repositoryUrl}]", +// ); +// final response = await httpClient.get(geoAsset.repositoryUrl); +// if (response.statusCode != 200 || response.data == null) { +// return left( +// GeoAssetUnexpectedFailure.new( +// "invalid response", +// StackTrace.current, +// ), +// ); +// } - final file = - geoAssetPathResolver.file(geoAsset.providerName, geoAsset.name); - final tagName = response.data!['tag_name'] as String; - loggy.debug("latest release of [${geoAsset.name}]: [$tagName]"); - if (tagName == geoAsset.version && await file.exists()) { - await geoAssetDataSource.patch( - geoAsset.id, - GeoAssetEntriesCompanion(lastCheck: Value(DateTime.now())), - ); - return left(const GeoAssetFailure.noUpdateAvailable()); - } +// final file = +// geoAssetPathResolver.file(geoAsset.providerName, geoAsset.name); +// final tagName = response.data!['tag_name'] as String; +// loggy.debug("latest release of [${geoAsset.name}]: [$tagName]"); +// if (tagName == geoAsset.version && await file.exists()) { +// await geoAssetDataSource.patch( +// geoAsset.id, +// GeoAssetEntriesCompanion(lastCheck: Value(DateTime.now())), +// ); +// return left(const GeoAssetFailure.noUpdateAvailable()); +// } - final assets = (response.data!['assets'] as List) - .whereType>(); - final asset = - assets.firstOrNullWhere((e) => e["name"] == geoAsset.name); - if (asset == null) { - return left( - GeoAssetUnexpectedFailure.new( - "couldn't find [${geoAsset.name}] on [${geoAsset.repositoryUrl}]", - StackTrace.current, - ), - ); - } +// final assets = (response.data!['assets'] as List) +// .whereType>(); +// final asset = +// assets.firstOrNullWhere((e) => e["name"] == geoAsset.name); +// if (asset == null) { +// return left( +// GeoAssetUnexpectedFailure.new( +// "couldn't find [${geoAsset.name}] on [${geoAsset.repositoryUrl}]", +// StackTrace.current, +// ), +// ); +// } - final downloadUrl = asset["browser_download_url"] as String; - loggy.debug("[${geoAsset.name}] download url: [$downloadUrl]"); - final tempPath = "${file.path}.tmp"; - await file.parent.create(recursive: true); - await httpClient.download(downloadUrl, tempPath); - await File(tempPath).rename(file.path); +// final downloadUrl = asset["browser_download_url"] as String; +// loggy.debug("[${geoAsset.name}] download url: [$downloadUrl]"); +// final tempPath = "${file.path}.tmp"; +// await file.parent.create(recursive: true); +// await httpClient.download(downloadUrl, tempPath); +// await File(tempPath).rename(file.path); - await geoAssetDataSource.patch( - geoAsset.id, - GeoAssetEntriesCompanion( - version: Value(tagName), - lastCheck: Value(DateTime.now()), - ), - ); +// await geoAssetDataSource.patch( +// geoAsset.id, +// GeoAssetEntriesCompanion( +// version: Value(tagName), +// lastCheck: Value(DateTime.now()), +// ), +// ); - return right(unit); - }, - GeoAssetUnexpectedFailure.new, - ); - } +// return right(unit); +// }, +// GeoAssetUnexpectedFailure.new, +// ); +// } - @override - TaskEither markAsActive(GeoAssetEntity geoAsset) { - return exceptionHandler( - () async { - await geoAssetDataSource.patch( - geoAsset.id, - const GeoAssetEntriesCompanion(active: Value(true)), - ); - return right(unit); - }, - GeoAssetUnexpectedFailure.new, - ); - } +// @override +// TaskEither markAsActive(GeoAssetEntity geoAsset) { +// return exceptionHandler( +// () async { +// await geoAssetDataSource.patch( +// geoAsset.id, +// const GeoAssetEntriesCompanion(active: Value(true)), +// ); +// return right(unit); +// }, +// GeoAssetUnexpectedFailure.new, +// ); +// } - @override - TaskEither addRecommended() { - return exceptionHandler( - () async { - final persistedIds = await geoAssetDataSource - .watchAll() - .first - .then((value) => value.map((e) => e.id)); - final missing = - recommendedGeoAssets.where((e) => !persistedIds.contains(e.id)); - for (final geoAsset in missing) { - await geoAssetDataSource.insert(geoAsset.toEntry()); - } - return right(unit); - }, - GeoAssetUnexpectedFailure.new, - ); - } -} +// @override +// TaskEither addRecommended() { +// return exceptionHandler( +// () async { +// final persistedIds = await geoAssetDataSource +// .watchAll() +// .first +// .then((value) => value.map((e) => e.id)); +// final missing = +// recommendedGeoAssets.where((e) => !persistedIds.contains(e.id)); +// for (final geoAsset in missing) { +// await geoAssetDataSource.insert(geoAsset.toEntry()); +// } +// return right(unit); +// }, +// GeoAssetUnexpectedFailure.new, +// ); +// } +// } diff --git a/lib/features/geo_asset/model/default_geo_assets.dart b/lib/features/geo_asset/model/default_geo_assets.dart index 40b3aaa6..70ca48dc 100644 --- a/lib/features/geo_asset/model/default_geo_assets.dart +++ b/lib/features/geo_asset/model/default_geo_assets.dart @@ -1,53 +1,53 @@ -import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart'; +// import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart'; -/// default geoip asset bundled with the app -const defaultGeoip = GeoAssetEntity( - id: "sing-box-geoip", - name: "geoip.db", - type: GeoAssetType.geoip, - active: true, - providerName: "SagerNet/sing-geoip", -); +// /// default geoip asset bundled with the app +// const defaultGeoip = GeoAssetEntity( +// id: "sing-box-geoip", +// name: "geoip.db", +// type: GeoAssetType.geoip, +// active: true, +// providerName: "SagerNet/sing-geoip", +// ); -/// default geosite asset bundled with the app -const defaultGeosite = GeoAssetEntity( - id: "sing-box-geosite", - name: "geosite.db", - type: GeoAssetType.geosite, - active: true, - providerName: "SagerNet/sing-geosite", -); +// /// default geosite asset bundled with the app +// const defaultGeosite = GeoAssetEntity( +// id: "sing-box-geosite", +// name: "geosite.db", +// type: GeoAssetType.geosite, +// active: true, +// providerName: "SagerNet/sing-geosite", +// ); -const defaultGeoAssets = [defaultGeoip, defaultGeosite]; +// const defaultGeoAssets = [defaultGeoip, defaultGeosite]; -const recommendedGeoAssets = [ - ...defaultGeoAssets, - GeoAssetEntity( - id: "chocolate4U-geoip", - name: "geoip.db", - type: GeoAssetType.geoip, - active: false, - providerName: "Chocolate4U/Iran-sing-box-rules", - ), - GeoAssetEntity( - id: "chocolate4U-geosite", - name: "geosite.db", - type: GeoAssetType.geosite, - active: false, - providerName: "Chocolate4U/Iran-sing-box-rules", - ), - GeoAssetEntity( - id: "soffchen-geoip", - name: "geoip.db", - type: GeoAssetType.geoip, - active: false, - providerName: "soffchen/sing-geoip", - ), - GeoAssetEntity( - id: "soffchen-geosite", - name: "geosite.db", - type: GeoAssetType.geosite, - active: false, - providerName: "soffchen/sing-geosite", - ), -]; +// const recommendedGeoAssets = [ +// ...defaultGeoAssets, +// GeoAssetEntity( +// id: "chocolate4U-geoip", +// name: "geoip.db", +// type: GeoAssetType.geoip, +// active: false, +// providerName: "Chocolate4U/Iran-sing-box-rules", +// ), +// GeoAssetEntity( +// id: "chocolate4U-geosite", +// name: "geosite.db", +// type: GeoAssetType.geosite, +// active: false, +// providerName: "Chocolate4U/Iran-sing-box-rules", +// ), +// GeoAssetEntity( +// id: "soffchen-geoip", +// name: "geoip.db", +// type: GeoAssetType.geoip, +// active: false, +// providerName: "soffchen/sing-geoip", +// ), +// GeoAssetEntity( +// id: "soffchen-geosite", +// name: "geosite.db", +// type: GeoAssetType.geosite, +// active: false, +// providerName: "soffchen/sing-geosite", +// ), +// ]; diff --git a/lib/features/geo_asset/notifier/geo_asset_notifier.dart b/lib/features/geo_asset/notifier/geo_asset_notifier.dart index 94f1ddac..f351f46c 100644 --- a/lib/features/geo_asset/notifier/geo_asset_notifier.dart +++ b/lib/features/geo_asset/notifier/geo_asset_notifier.dart @@ -1,33 +1,33 @@ -import 'package:fpdart/fpdart.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_data_providers.dart'; -import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart'; -import 'package:hiddify/utils/custom_loggers.dart'; -import 'package:hiddify/utils/riverpod_utils.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; +// import 'package:fpdart/fpdart.dart'; +// import 'package:hiddify/features/geo_asset/data/geo_asset_data_providers.dart'; +// import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart'; +// import 'package:hiddify/utils/custom_loggers.dart'; +// import 'package:hiddify/utils/riverpod_utils.dart'; +// import 'package:riverpod_annotation/riverpod_annotation.dart'; -part 'geo_asset_notifier.g.dart'; +// part 'geo_asset_notifier.g.dart'; -@riverpod -class FetchGeoAsset extends _$FetchGeoAsset with AppLogger { - @override - Future build(String id) async { - ref.disposeDelay(const Duration(seconds: 10)); - return null; - } +// @riverpod +// class FetchGeoAsset extends _$FetchGeoAsset with AppLogger { +// @override +// Future build(String id) async { +// ref.disposeDelay(const Duration(seconds: 10)); +// return null; +// } - Future fetch(GeoAssetEntity geoAsset) async { - state = const AsyncLoading(); - state = await AsyncValue.guard( - () => ref - .read(geoAssetRepositoryProvider) - .requireValue - .update(geoAsset) - .getOrElse( - (failure) { - loggy.warning("error updating geo asset $failure", failure); - throw failure; - }, - ).run(), - ); - } -} +// Future fetch(GeoAssetEntity geoAsset) async { +// state = const AsyncLoading(); +// state = await AsyncValue.guard( +// () => ref +// .read(geoAssetRepositoryProvider) +// .requireValue +// .update(geoAsset) +// .getOrElse( +// (failure) { +// loggy.warning("error updating geo asset $failure", failure); +// throw failure; +// }, +// ).run(), +// ); +// } +// } diff --git a/lib/features/geo_asset/overview/geo_assets_overview_notifier.dart b/lib/features/geo_asset/overview/geo_assets_overview_notifier.dart index be063f77..38174c19 100644 --- a/lib/features/geo_asset/overview/geo_assets_overview_notifier.dart +++ b/lib/features/geo_asset/overview/geo_assets_overview_notifier.dart @@ -1,55 +1,55 @@ -import 'package:dartx/dartx.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_data_providers.dart'; -import 'package:hiddify/features/geo_asset/data/geo_asset_repository.dart'; -import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart'; -import 'package:hiddify/utils/custom_loggers.dart'; -import 'package:hiddify/utils/riverpod_utils.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; +// import 'package:dartx/dartx.dart'; +// import 'package:hiddify/features/geo_asset/data/geo_asset_data_providers.dart'; +// import 'package:hiddify/features/geo_asset/data/geo_asset_repository.dart'; +// import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart'; +// import 'package:hiddify/utils/custom_loggers.dart'; +// import 'package:hiddify/utils/riverpod_utils.dart'; +// import 'package:riverpod_annotation/riverpod_annotation.dart'; -part 'geo_assets_overview_notifier.g.dart'; +// part 'geo_assets_overview_notifier.g.dart'; -typedef GroupedRoutingAssets = ({ - List geoip, - List geosite, -}); +// typedef GroupedRoutingAssets = ({ +// List geoip, +// List geosite, +// }); -@riverpod -class GeoAssetsOverviewNotifier extends _$GeoAssetsOverviewNotifier - with AppLogger { - @override - Stream build() { - ref.disposeDelay(const Duration(seconds: 5)); - return ref.watch(geoAssetRepositoryProvider).requireValue.watchAll().map( - (event) { - final grouped = event - .getOrElse((l) => throw l) - .groupBy((element) => element.$1.type); - return ( - geoip: grouped.getOrElse(GeoAssetType.geoip, () => []), - geosite: grouped.getOrElse(GeoAssetType.geosite, () => []), - ); - }, - ); - } +// @riverpod +// class GeoAssetsOverviewNotifier extends _$GeoAssetsOverviewNotifier +// with AppLogger { +// @override +// Stream build() { +// ref.disposeDelay(const Duration(seconds: 5)); +// return ref.watch(geoAssetRepositoryProvider).requireValue.watchAll().map( +// (event) { +// final grouped = event +// .getOrElse((l) => throw l) +// .groupBy((element) => element.$1.type); +// return ( +// geoip: grouped.getOrElse(GeoAssetType.geoip, () => []), +// geosite: grouped.getOrElse(GeoAssetType.geosite, () => []), +// ); +// }, +// ); +// } - GeoAssetRepository get _geoAssetRepo => - ref.read(geoAssetRepositoryProvider).requireValue; +// GeoAssetRepository get _geoAssetRepo => +// ref.read(geoAssetRepositoryProvider).requireValue; - Future markAsActive(GeoAssetEntity geoAsset) async { - await _geoAssetRepo.markAsActive(geoAsset).getOrElse( - (f) { - loggy.warning("error marking geo asset as active", f); - throw f; - }, - ).run(); - } +// Future markAsActive(GeoAssetEntity geoAsset) async { +// await _geoAssetRepo.markAsActive(geoAsset).getOrElse( +// (f) { +// loggy.warning("error marking geo asset as active", f); +// throw f; +// }, +// ).run(); +// } - Future addRecommended() async { - await _geoAssetRepo.addRecommended().getOrElse( - (f) { - loggy.warning("error adding recommended geo assets", f); - throw f; - }, - ).run(); - } -} +// Future addRecommended() async { +// await _geoAssetRepo.addRecommended().getOrElse( +// (f) { +// loggy.warning("error adding recommended geo assets", f); +// throw f; +// }, +// ).run(); +// } +// } diff --git a/lib/features/geo_asset/overview/geo_assets_overview_page.dart b/lib/features/geo_asset/overview/geo_assets_overview_page.dart index 2af65703..92d9d9be 100644 --- a/lib/features/geo_asset/overview/geo_assets_overview_page.dart +++ b/lib/features/geo_asset/overview/geo_assets_overview_page.dart @@ -1,102 +1,102 @@ -import 'package:flutter/material.dart'; -import 'package:gap/gap.dart'; -import 'package:hiddify/core/localization/translations.dart'; -import 'package:hiddify/core/widget/adaptive_icon.dart'; -import 'package:hiddify/core/widget/animated_visibility.dart'; -import 'package:hiddify/core/widget/tip_card.dart'; -import 'package:hiddify/features/geo_asset/overview/geo_assets_overview_notifier.dart'; -import 'package:hiddify/features/geo_asset/widget/geo_asset_tile.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:sliver_tools/sliver_tools.dart'; +// import 'package:flutter/material.dart'; +// import 'package:gap/gap.dart'; +// import 'package:hiddify/core/localization/translations.dart'; +// import 'package:hiddify/core/widget/adaptive_icon.dart'; +// import 'package:hiddify/core/widget/animated_visibility.dart'; +// import 'package:hiddify/core/widget/tip_card.dart'; +// import 'package:hiddify/features/geo_asset/overview/geo_assets_overview_notifier.dart'; +// import 'package:hiddify/features/geo_asset/widget/geo_asset_tile.dart'; +// import 'package:hooks_riverpod/hooks_riverpod.dart'; +// import 'package:sliver_tools/sliver_tools.dart'; -class GeoAssetsOverviewPage extends HookConsumerWidget { - const GeoAssetsOverviewPage({super.key}); +// class GeoAssetsOverviewPage extends HookConsumerWidget { +// const GeoAssetsOverviewPage({super.key}); - @override - Widget build(BuildContext context, WidgetRef ref) { - final t = ref.watch(translationsProvider); - final state = ref.watch(geoAssetsOverviewNotifierProvider); +// @override +// Widget build(BuildContext context, WidgetRef ref) { +// final t = ref.watch(translationsProvider); +// final state = ref.watch(geoAssetsOverviewNotifierProvider); - return Scaffold( - body: CustomScrollView( - slivers: [ - SliverAppBar( - title: Text(t.settings.geoAssets.pageTitle), - pinned: true, - actions: [ - PopupMenuButton( - icon: Icon(AdaptiveIcon(context).more), - itemBuilder: (context) { - return [ - PopupMenuItem( - child: Text(t.settings.geoAssets.addRecommended), - onTap: () { - ref - .read(geoAssetsOverviewNotifierProvider.notifier) - .addRecommended(); - }, - ), - ]; - }, - ), - ], - ), - if (state case AsyncData(value: (:final geoip, :final geosite))) - SliverPinnedHeader( - child: AnimatedVisibility( - visible: (geoip + geosite) - .where((e) => e.$1.active && e.$2 == null) - .isNotEmpty, - axis: Axis.vertical, - child: - TipCard(message: t.settings.geoAssets.missingGeoAssetsMsg), - ), - ), - switch (state) { - AsyncData(value: (:final geoip, :final geosite)) => MultiSliver( - children: [ - ListTile( - title: Text("${t.settings.geoAssets.geoip} ›"), - titleTextStyle: Theme.of(context).textTheme.headlineSmall, - dense: true, - ), - SliverList.builder( - itemBuilder: (context, index) { - final geoAsset = geoip[index]; - return GeoAssetTile( - geoAsset, - onMarkAsActive: () => ref - .read(geoAssetsOverviewNotifierProvider.notifier) - .markAsActive(geoAsset.$1), - ); - }, - itemCount: geoip.length, - ), - const Divider(indent: 16, endIndent: 16), - ListTile( - title: Text("${t.settings.geoAssets.geosite} ›"), - titleTextStyle: Theme.of(context).textTheme.headlineSmall, - dense: true, - ), - SliverList.builder( - itemBuilder: (context, index) { - final geoAsset = geosite[index]; - return GeoAssetTile( - geoAsset, - onMarkAsActive: () => ref - .read(geoAssetsOverviewNotifierProvider.notifier) - .markAsActive(geoAsset.$1), - ); - }, - itemCount: geosite.length, - ), - const Gap(16), - ], - ), - _ => const SliverToBoxAdapter(), - }, - ], - ), - ); - } -} +// return Scaffold( +// body: CustomScrollView( +// slivers: [ +// SliverAppBar( +// title: Text(t.settings.geoAssets.pageTitle), +// pinned: true, +// actions: [ +// PopupMenuButton( +// icon: Icon(AdaptiveIcon(context).more), +// itemBuilder: (context) { +// return [ +// PopupMenuItem( +// child: Text(t.settings.geoAssets.addRecommended), +// onTap: () { +// ref +// .read(geoAssetsOverviewNotifierProvider.notifier) +// .addRecommended(); +// }, +// ), +// ]; +// }, +// ), +// ], +// ), +// if (state case AsyncData(value: (:final geoip, :final geosite))) +// SliverPinnedHeader( +// child: AnimatedVisibility( +// visible: (geoip + geosite) +// .where((e) => e.$1.active && e.$2 == null) +// .isNotEmpty, +// axis: Axis.vertical, +// child: +// TipCard(message: t.settings.geoAssets.missingGeoAssetsMsg), +// ), +// ), +// switch (state) { +// AsyncData(value: (:final geoip, :final geosite)) => MultiSliver( +// children: [ +// ListTile( +// title: Text("${t.settings.geoAssets.geoip} ›"), +// titleTextStyle: Theme.of(context).textTheme.headlineSmall, +// dense: true, +// ), +// SliverList.builder( +// itemBuilder: (context, index) { +// final geoAsset = geoip[index]; +// return GeoAssetTile( +// geoAsset, +// onMarkAsActive: () => ref +// .read(geoAssetsOverviewNotifierProvider.notifier) +// .markAsActive(geoAsset.$1), +// ); +// }, +// itemCount: geoip.length, +// ), +// const Divider(indent: 16, endIndent: 16), +// ListTile( +// title: Text("${t.settings.geoAssets.geosite} ›"), +// titleTextStyle: Theme.of(context).textTheme.headlineSmall, +// dense: true, +// ), +// SliverList.builder( +// itemBuilder: (context, index) { +// final geoAsset = geosite[index]; +// return GeoAssetTile( +// geoAsset, +// onMarkAsActive: () => ref +// .read(geoAssetsOverviewNotifierProvider.notifier) +// .markAsActive(geoAsset.$1), +// ); +// }, +// itemCount: geosite.length, +// ), +// const Gap(16), +// ], +// ), +// _ => const SliverToBoxAdapter(), +// }, +// ], +// ), +// ); +// } +// } diff --git a/lib/features/geo_asset/widget/geo_asset_tile.dart b/lib/features/geo_asset/widget/geo_asset_tile.dart index 9180a6ff..500ac1bb 100644 --- a/lib/features/geo_asset/widget/geo_asset_tile.dart +++ b/lib/features/geo_asset/widget/geo_asset_tile.dart @@ -1,116 +1,116 @@ -import 'package:dartx/dartx.dart'; -import 'package:flutter/material.dart'; -import 'package:hiddify/core/localization/translations.dart'; -import 'package:hiddify/core/model/failures.dart'; -import 'package:hiddify/core/widget/adaptive_icon.dart'; -import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart'; -import 'package:hiddify/features/geo_asset/model/geo_asset_failure.dart'; -import 'package:hiddify/features/geo_asset/notifier/geo_asset_notifier.dart'; -import 'package:hiddify/utils/utils.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:humanizer/humanizer.dart'; +// import 'package:dartx/dartx.dart'; +// import 'package:flutter/material.dart'; +// import 'package:hiddify/core/localization/translations.dart'; +// import 'package:hiddify/core/model/failures.dart'; +// import 'package:hiddify/core/widget/adaptive_icon.dart'; +// import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart'; +// import 'package:hiddify/features/geo_asset/model/geo_asset_failure.dart'; +// import 'package:hiddify/features/geo_asset/notifier/geo_asset_notifier.dart'; +// import 'package:hiddify/utils/utils.dart'; +// import 'package:hooks_riverpod/hooks_riverpod.dart'; +// import 'package:humanizer/humanizer.dart'; -class GeoAssetTile extends HookConsumerWidget { - GeoAssetTile( - GeoAssetWithFileSize geoAssetWithFileSize, { - super.key, - required this.onMarkAsActive, - }) : geoAsset = geoAssetWithFileSize.$1, - size = geoAssetWithFileSize.$2; +// class GeoAssetTile extends HookConsumerWidget { +// GeoAssetTile( +// GeoAssetWithFileSize geoAssetWithFileSize, { +// super.key, +// required this.onMarkAsActive, +// }) : geoAsset = geoAssetWithFileSize.$1, +// size = geoAssetWithFileSize.$2; - final GeoAssetEntity geoAsset; - final int? size; - final VoidCallback onMarkAsActive; +// final GeoAssetEntity geoAsset; +// final int? size; +// final VoidCallback onMarkAsActive; - @override - Widget build(BuildContext context, WidgetRef ref) { - final t = ref.watch(translationsProvider); - final fetchState = ref.watch(fetchGeoAssetProvider(geoAsset.id)); - final fileMissing = size == null; +// @override +// Widget build(BuildContext context, WidgetRef ref) { +// final t = ref.watch(translationsProvider); +// final fetchState = ref.watch(fetchGeoAssetProvider(geoAsset.id)); +// final fileMissing = size == null; - ref.listen( - fetchGeoAssetProvider(geoAsset.id), - (_, next) { - switch (next) { - case AsyncError(:final error): - if (error case GeoAssetNoUpdateAvailable()) { - return CustomToast(t.failure.geoAssets.notUpdate).show(context); - } - CustomAlertDialog.fromErr(t.presentError(error)).show(context); - case AsyncData(value: final _?): - CustomToast.success(t.settings.geoAssets.successMsg).show(context); - } - }, - ); +// ref.listen( +// fetchGeoAssetProvider(geoAsset.id), +// (_, next) { +// switch (next) { +// case AsyncError(:final error): +// if (error case GeoAssetNoUpdateAvailable()) { +// return CustomToast(t.failure.geoAssets.notUpdate).show(context); +// } +// CustomAlertDialog.fromErr(t.presentError(error)).show(context); +// case AsyncData(value: final _?): +// CustomToast.success(t.settings.geoAssets.successMsg).show(context); +// } +// }, +// ); - return ListTile( - title: Text.rich( - TextSpan( - children: [ - TextSpan(text: geoAsset.name), - if (geoAsset.providerName.isNotBlank) - TextSpan(text: " (${geoAsset.providerName})"), - ], - ), - ), - isThreeLine: true, - subtitle: fetchState.isLoading - ? const LinearProgressIndicator() - : Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - if (geoAsset.version.isNotNullOrBlank) - Padding( - padding: const EdgeInsetsDirectional.only(end: 8), - child: Text( - t.settings.geoAssets.version(version: geoAsset.version!), - overflow: TextOverflow.ellipsis, - ), - ) - else - const SizedBox(), - Flexible( - child: Text.rich( - TextSpan( - children: [ - if (fileMissing) - TextSpan( - text: t.settings.geoAssets.fileMissing, - style: TextStyle( - color: Theme.of(context).colorScheme.error, - ), - ) - else - TextSpan(text: size?.bytes().toString()), - if (geoAsset.lastCheck != null) ...[ - const TextSpan(text: " • "), - TextSpan(text: geoAsset.lastCheck!.format()), - ], - ], - ), - overflow: TextOverflow.ellipsis, - ), - ), - ], - ), - selected: geoAsset.active, - onTap: onMarkAsActive, - trailing: PopupMenuButton( - icon: Icon(AdaptiveIcon(context).more), - itemBuilder: (context) { - return [ - PopupMenuItem( - enabled: !fetchState.isLoading, - onTap: () => ref - .read(FetchGeoAssetProvider(geoAsset.id).notifier) - .fetch(geoAsset), - child: fileMissing - ? Text(t.settings.geoAssets.download) - : Text(t.settings.geoAssets.update), - ), - ]; - }, - ), - ); - } -} +// return ListTile( +// title: Text.rich( +// TextSpan( +// children: [ +// TextSpan(text: geoAsset.name), +// if (geoAsset.providerName.isNotBlank) +// TextSpan(text: " (${geoAsset.providerName})"), +// ], +// ), +// ), +// isThreeLine: true, +// subtitle: fetchState.isLoading +// ? const LinearProgressIndicator() +// : Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// if (geoAsset.version.isNotNullOrBlank) +// Padding( +// padding: const EdgeInsetsDirectional.only(end: 8), +// child: Text( +// t.settings.geoAssets.version(version: geoAsset.version!), +// overflow: TextOverflow.ellipsis, +// ), +// ) +// else +// const SizedBox(), +// Flexible( +// child: Text.rich( +// TextSpan( +// children: [ +// if (fileMissing) +// TextSpan( +// text: t.settings.geoAssets.fileMissing, +// style: TextStyle( +// color: Theme.of(context).colorScheme.error, +// ), +// ) +// else +// TextSpan(text: size?.bytes().toString()), +// if (geoAsset.lastCheck != null) ...[ +// const TextSpan(text: " • "), +// TextSpan(text: geoAsset.lastCheck!.format()), +// ], +// ], +// ), +// overflow: TextOverflow.ellipsis, +// ), +// ), +// ], +// ), +// selected: geoAsset.active, +// onTap: onMarkAsActive, +// trailing: PopupMenuButton( +// icon: Icon(AdaptiveIcon(context).more), +// itemBuilder: (context) { +// return [ +// PopupMenuItem( +// enabled: !fetchState.isLoading, +// onTap: () => ref +// .read(FetchGeoAssetProvider(geoAsset.id).notifier) +// .fetch(geoAsset), +// child: fileMissing +// ? Text(t.settings.geoAssets.download) +// : Text(t.settings.geoAssets.update), +// ), +// ]; +// }, +// ), +// ); +// } +// } diff --git a/lib/features/settings/widgets/advanced_setting_tiles.dart b/lib/features/settings/widgets/advanced_setting_tiles.dart index 6558158b..63e8ebe6 100644 --- a/lib/features/settings/widgets/advanced_setting_tiles.dart +++ b/lib/features/settings/widgets/advanced_setting_tiles.dart @@ -23,16 +23,16 @@ class AdvancedSettingTiles extends HookConsumerWidget { return Column( children: [ - const RegionPrefTile(), - ListTile( - title: Text(t.settings.geoAssets.pageTitle), - leading: const Icon( - FluentIcons.arrow_routing_rectangle_multiple_24_regular, - ), - onTap: () async { - await const GeoAssetsRoute().push(context); - }, - ), + // const RegionPrefTile(), + // ListTile( + // title: Text(t.settings.geoAssets.pageTitle), + // leading: const Icon( + // FluentIcons.arrow_routing_rectangle_multiple_24_regular, + // ), + // onTap: () async { + // // await const GeoAssetsRoute().push(context); + // }, + // ), if (Platform.isAndroid) ...[ ListTile( title: Text(t.settings.network.perAppProxyPageTitle), @@ -40,11 +40,8 @@ class AdvancedSettingTiles extends HookConsumerWidget { trailing: Switch( value: perAppProxy, onChanged: (value) async { - final newMode = - perAppProxy ? PerAppProxyMode.off : PerAppProxyMode.exclude; - await ref - .read(Preferences.perAppProxyMode.notifier) - .update(newMode); + final newMode = perAppProxy ? PerAppProxyMode.off : PerAppProxyMode.exclude; + await ref.read(Preferences.perAppProxyMode.notifier).update(newMode); if (!perAppProxy && context.mounted) { await const PerAppProxyRoute().push(context); } @@ -52,9 +49,7 @@ class AdvancedSettingTiles extends HookConsumerWidget { ), onTap: () async { if (!perAppProxy) { - await ref - .read(Preferences.perAppProxyMode.notifier) - .update(PerAppProxyMode.exclude); + await ref.read(Preferences.perAppProxyMode.notifier).update(PerAppProxyMode.exclude); } if (context.mounted) await const PerAppProxyRoute().push(context); }, @@ -66,9 +61,7 @@ class AdvancedSettingTiles extends HookConsumerWidget { value: !disableMemoryLimit, secondary: const Icon(FluentIcons.developer_board_24_regular), onChanged: (value) async { - await ref - .read(Preferences.disableMemoryLimit.notifier) - .update(!value); + await ref.read(Preferences.disableMemoryLimit.notifier).update(!value); }, ), if (Platform.isIOS) diff --git a/lib/features/settings/widgets/general_setting_tiles.dart b/lib/features/settings/widgets/general_setting_tiles.dart index 0ac84a68..48cf45e1 100644 --- a/lib/features/settings/widgets/general_setting_tiles.dart +++ b/lib/features/settings/widgets/general_setting_tiles.dart @@ -23,7 +23,7 @@ class GeneralSettingTiles extends HookConsumerWidget { return Column( children: [ - const LocalePrefTile(), + // const LocalePrefTile(), ListTile( title: Text(t.settings.general.themeMode), subtitle: Text(themeMode.present(t)), @@ -48,9 +48,7 @@ class GeneralSettingTiles extends HookConsumerWidget { }, ); if (selectedThemeMode != null) { - await ref - .read(themePreferencesProvider.notifier) - .changeThemeMode(selectedThemeMode); + await ref.read(themePreferencesProvider.notifier).changeThemeMode(selectedThemeMode); } }, ), @@ -67,17 +65,14 @@ class GeneralSettingTiles extends HookConsumerWidget { secondary: const Icon(FluentIcons.top_speed_24_regular), value: ref.watch(Preferences.dynamicNotification), onChanged: (value) async { - await ref - .read(Preferences.dynamicNotification.notifier) - .update(value); + await ref.read(Preferences.dynamicNotification.notifier).update(value); }, ), SwitchListTile( title: Text(t.settings.general.hapticFeedback), secondary: const Icon(FluentIcons.phone_vibrate_24_regular), value: ref.watch(hapticServiceProvider), - onChanged: - ref.read(hapticServiceProvider.notifier).updatePreference, + onChanged: ref.read(hapticServiceProvider.notifier).updatePreference, ), ], if (PlatformUtils.isDesktop) ...[ diff --git a/lib/singbox/model/singbox_config_option.dart b/lib/singbox/model/singbox_config_option.dart index 3bcd2798..06735e79 100644 --- a/lib/singbox/model/singbox_config_option.dart +++ b/lib/singbox/model/singbox_config_option.dart @@ -16,6 +16,8 @@ class SingboxConfigOption with _$SingboxConfigOption { @JsonSerializable(fieldRename: FieldRename.kebab) const factory SingboxConfigOption({ + required String region, + required bool blockAds, required bool executeConfigAsIs, required LogLevel logLevel, required bool resolveDestination, @@ -42,8 +44,8 @@ class SingboxConfigOption with _$SingboxConfigOption { required bool enableFakeDns, required bool enableDnsRouting, required bool independentDnsCache, - required String geoipPath, - required String geositePath, + // required String geoipPath, + // required String geositePath, required List rules, required SingboxMuxOption mux, required SingboxTlsTricks tlsTricks, diff --git a/lib/singbox/model/singbox_rule.dart b/lib/singbox/model/singbox_rule.dart index b927ffee..4b9b574a 100644 --- a/lib/singbox/model/singbox_rule.dart +++ b/lib/singbox/model/singbox_rule.dart @@ -9,6 +9,7 @@ class SingboxRule with _$SingboxRule { @JsonSerializable(fieldRename: FieldRename.kebab) const factory SingboxRule({ + String? ruleSetUrl, String? domains, String? ip, String? port, @@ -17,8 +18,7 @@ class SingboxRule with _$SingboxRule { @Default(RuleOutbound.proxy) RuleOutbound outbound, }) = _SingboxRule; - factory SingboxRule.fromJson(Map json) => - _$SingboxRuleFromJson(json); + factory SingboxRule.fromJson(Map json) => _$SingboxRuleFromJson(json); } enum RuleOutbound { proxy, bypass, block }