diff --git a/assets/translations/strings_en.i18n.json b/assets/translations/strings_en.i18n.json index 45b59b37..6bb29c05 100644 --- a/assets/translations/strings_en.i18n.json +++ b/assets/translations/strings_en.i18n.json @@ -225,7 +225,8 @@ "update": "Update", "download": "Download", "failureMsg": "Failed to update asset", - "successMsg": "Successfully updated asset" + "successMsg": "Successfully updated asset", + "addRecommended": "Add Recommended Assets" } }, "about": { diff --git a/assets/translations/strings_fa.i18n.json b/assets/translations/strings_fa.i18n.json index 98e59148..a774f9a0 100644 --- a/assets/translations/strings_fa.i18n.json +++ b/assets/translations/strings_fa.i18n.json @@ -225,7 +225,8 @@ "update": "به روز رسانی", "download": "دانلود", "failureMsg": "دارایی به روز نشد", - "successMsg": "دارایی با موفقیت به روز شد" + "successMsg": "دارایی با موفقیت به روز شد", + "addRecommended": "اضافه کردن دارایی های توصیه شده" } }, "about": { diff --git a/assets/translations/strings_ru.i18n.json b/assets/translations/strings_ru.i18n.json index 30f211d3..4d75e461 100644 --- a/assets/translations/strings_ru.i18n.json +++ b/assets/translations/strings_ru.i18n.json @@ -225,7 +225,8 @@ "update": "Обновлять", "download": "Скачать", "failureMsg": "Не удалось обновить объект.", - "successMsg": "Объект успешно обновлен." + "successMsg": "Объект успешно обновлен.", + "addRecommended": "Добавить рекомендуемые активы" } }, "about": { diff --git a/assets/translations/strings_tr.i18n.json b/assets/translations/strings_tr.i18n.json index ea1e802c..15309c26 100644 --- a/assets/translations/strings_tr.i18n.json +++ b/assets/translations/strings_tr.i18n.json @@ -225,7 +225,8 @@ "update": "Güncelleme", "download": "İndirmek", "failureMsg": "Öğe güncellenemedi", - "successMsg": "Öğe başarıyla güncellendi" + "successMsg": "Öğe başarıyla güncellendi", + "addRecommended": "Önerilen Varlıkları Ekle" } }, "about": { diff --git a/assets/translations/strings_zh.i18n.json b/assets/translations/strings_zh.i18n.json index 035810f7..649b113b 100644 --- a/assets/translations/strings_zh.i18n.json +++ b/assets/translations/strings_zh.i18n.json @@ -225,7 +225,8 @@ "update": "更新", "download": "下载", "failureMsg": "更新资产失败", - "successMsg": "已成功更新资产" + "successMsg": "已成功更新资产", + "addRecommended": "添加推荐资产" } }, "about": { diff --git a/lib/data/local/dao/geo_assets_dao.dart b/lib/data/local/dao/geo_assets_dao.dart index 13a04436..25ef879a 100644 --- a/lib/data/local/dao/geo_assets_dao.dart +++ b/lib/data/local/dao/geo_assets_dao.dart @@ -12,6 +12,10 @@ class GeoAssetsDao extends DatabaseAccessor with _$GeoAssetsDaoMixin, InfraLogger { GeoAssetsDao(super.db); + Future add(GeoAsset geoAsset) async { + await into(geoAssetEntries).insert(geoAsset.toCompanion()); + } + Future getActive(GeoAssetType type) async { return (geoAssetEntries.select() ..where((tbl) => tbl.active.equals(true)) diff --git a/lib/data/repository/geo_assets_repository.dart b/lib/data/repository/geo_assets_repository.dart index 104c8677..57c7c638 100644 --- a/lib/data/repository/geo_assets_repository.dart +++ b/lib/data/repository/geo_assets_repository.dart @@ -146,4 +146,23 @@ class GeoAssetsRepositoryImpl GeoAssetFailure.unexpected, ); } + + @override + TaskEither addRecommended() { + return exceptionHandler( + () async { + final persistedIds = await geoAssetsDao + .watchAll() + .first + .then((value) => value.map((e) => e.id)); + final missing = + recommendedGeoAssets.where((e) => !persistedIds.contains(e.id)); + for (final geoAsset in missing) { + await geoAssetsDao.add(geoAsset); + } + return right(unit); + }, + GeoAssetFailure.unexpected, + ); + } } diff --git a/lib/domain/rules/geo_asset.dart b/lib/domain/rules/geo_asset.dart index 2420d913..409b7b82 100644 --- a/lib/domain/rules/geo_asset.dart +++ b/lib/domain/rules/geo_asset.dart @@ -49,3 +49,21 @@ const defaultGeosite = GeoAsset( ); const defaultGeoAssets = [defaultGeoip, defaultGeosite]; + +const recommendedGeoAssets = [ + ...defaultGeoAssets, + GeoAsset( + id: "chocolate4U-geoip", + name: "geoip.db", + type: GeoAssetType.geoip, + active: false, + providerName: "Chocolate4U/Iran-sing-box-rules", + ), + GeoAsset( + id: "chocolate4U-geosite", + name: "geosite.db", + type: GeoAssetType.geosite, + active: false, + providerName: "Chocolate4U/Iran-sing-box-rules", + ), +]; diff --git a/lib/domain/rules/geo_assets_repository.dart b/lib/domain/rules/geo_assets_repository.dart index b063129a..2e55632d 100644 --- a/lib/domain/rules/geo_assets_repository.dart +++ b/lib/domain/rules/geo_assets_repository.dart @@ -11,4 +11,6 @@ abstract interface class GeoAssetsRepository { TaskEither update(GeoAsset geoAsset); TaskEither markAsActive(GeoAsset geoAsset); + + TaskEither addRecommended(); } diff --git a/lib/features/settings/geo_assets/geo_asset_tile.dart b/lib/features/settings/geo_assets/geo_asset_tile.dart index b05e8dc7..db1f6de0 100644 --- a/lib/features/settings/geo_assets/geo_asset_tile.dart +++ b/lib/features/settings/geo_assets/geo_asset_tile.dart @@ -89,6 +89,11 @@ class GeoAssetTile extends HookConsumerWidget { ], ), selected: geoAsset.active, + onTap: () async { + await ref + .read(geoAssetsNotifierProvider.notifier) + .markAsActive(geoAsset); + }, trailing: PopupMenuButton( itemBuilder: (context) { return [ diff --git a/lib/features/settings/geo_assets/geo_assets_notifier.dart b/lib/features/settings/geo_assets/geo_assets_notifier.dart index d7669962..0e1cb3db 100644 --- a/lib/features/settings/geo_assets/geo_assets_notifier.dart +++ b/lib/features/settings/geo_assets/geo_assets_notifier.dart @@ -20,7 +20,28 @@ class GeoAssetsNotifier extends _$GeoAssetsNotifier with AppLogger { Future updateGeoAsset(GeoAsset geoAsset) async { await ref.read(geoAssetsRepositoryProvider).update(geoAsset).getOrElse( (f) { - loggy.warning("error updating profile", f); + loggy.warning("error updating geo asset", f); + throw f; + }, + ).run(); + } + + Future markAsActive(GeoAsset geoAsset) async { + await ref + .read(geoAssetsRepositoryProvider) + .markAsActive(geoAsset) + .getOrElse( + (f) { + loggy.warning("error marking geo asset as active", f); + throw f; + }, + ).run(); + } + + Future addRecommended() async { + await ref.read(geoAssetsRepositoryProvider).addRecommended().getOrElse( + (f) { + loggy.warning("error adding recommended geo assets", f); throw f; }, ).run(); diff --git a/lib/features/settings/geo_assets/geo_assets_page.dart b/lib/features/settings/geo_assets/geo_assets_page.dart index b4ddfdc5..b53aedf1 100644 --- a/lib/features/settings/geo_assets/geo_assets_page.dart +++ b/lib/features/settings/geo_assets/geo_assets_page.dart @@ -17,6 +17,22 @@ class GeoAssetsPage extends HookConsumerWidget { slivers: [ SliverAppBar( title: Text(t.settings.geoAssets.pageTitle), + actions: [ + PopupMenuButton( + itemBuilder: (context) { + return [ + PopupMenuItem( + child: Text(t.settings.geoAssets.addRecommended), + onTap: () { + ref + .read(geoAssetsNotifierProvider.notifier) + .addRecommended(); + }, + ), + ]; + }, + ), + ], ), switch (state) { AsyncData(value: final geoAssets) => SliverList.builder(