diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index a6454a48..665eb9a1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -30,9 +30,9 @@ body: - type: textarea id: reproduce attributes: - label: Reproduce the Bug + label: Minimal Reproducible Example (MRE) description: | - Please tell us the steps to reproduce the bug. + Please tell us the steps to reproduce the bug. A [Minimal Reproducible Example (MRE)](https://stackoverflow.com/help/minimal-reproducible-example) is needed. placeholder: | 1. Go to '...' 2. Click on '....' @@ -78,6 +78,14 @@ body: If applicable, add screenshots, screen recordings or additional context to help explain your problem. validations: required: false + + - type: textarea + id: configs + attributes: + label: Application Config Options + description: Please copy and paste Application config + render: shell + - type: textarea id: logs attributes: diff --git a/.github/release_message.md b/.github/release_message.md index 9d281a37..a2a6ce08 100644 --- a/.github/release_message.md +++ b/.github/release_message.md @@ -1,21 +1,8 @@ +
+ [![Release Downloads](https://img.shields.io/github/downloads/hiddify/hiddify-next/RELEASE_TAG/total?style=flat-square&logo=github)](https://img.shields.io/github/downloads/hiddify/hiddify-next/RELEASE_TAG/) - - - -**Release Highlights:** - -- -- - -
-تغییرات اصلی به فارسی - -- -- -- - -
+
**Download based on your OS:** @@ -36,31 +23,36 @@ + + iOS + + + Android -
-
-
- +
+
+
+ Windows -
-
- +
+
+ macOS (v10.15+) -
- +
+ Linux -
-
- +
+
+ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ee8d526f..db102505 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,15 +36,15 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - # - uses: subosito/flutter-action@v2.12.0 #issue with 2.13 - # with: - # flutter-version: ${{ env.FLUTTER_VERSION }} - # channel: 'stable' - # cache: true - # - name: Prepare - # run: make linux-prepare - # - name: Test - # run: flutter test + - uses: subosito/flutter-action@v2.12.0 #issue with 2.13 + with: + flutter-version: ${{ env.FLUTTER_VERSION }} + channel: 'stable' + cache: true + - name: Prepare + run: make linux-prepare + - name: Test + run: flutter test - name: make draftBuildCode id: draftBuildCode @@ -149,13 +149,13 @@ jobs: [IO.File]::WriteAllBytes("windows\sign.pfx", [Convert]::FromBase64String("${{ secrets.WINDOWS_SIGNING_KEY }}")) (Get-Content "windows\packaging\msix\make_config.yaml") -replace '^certificate_password:.*$', 'certificate_password: ${{ secrets.WINDOWS_SIGNING_PASSWORD }}' | Set-Content "windows\packaging\msix\make_config.yaml" - - name: Temporary disable Permission Handler for windows due to its issue in permission - if: ${{ startsWith(matrix.platform,'windows') }} - run: | - (Get-Content -Path "pubspec.yaml") -notmatch "permission_handler" | Set-Content -Path "pubspec.yaml" - (Get-Content -Path "lib\features\profile\add\add_profile_modal.dart") -notmatch "qr_code_scanner_screen" | Set-Content -Path "lib\features\profile\add\add_profile_modal.dart" - (Get-Content -Path lib\features\profile\add\add_profile_modal.dart) -replace 'await QRCodeScannerScreen\(\).open\(context\);', 'null;' | Set-Content -Path lib\features\profile\add\add_profile_modal.dart - Remove-Item -Path "lib\features\common\qr_code_scanner_screen.dart" + # - name: Temporary disable Permission Handler for windows due to its issue in permission + # if: ${{ startsWith(matrix.platform,'windows') }} + # run: | + # (Get-Content -Path "pubspec.yaml") -notmatch "permission_handler" | Set-Content -Path "pubspec.yaml" + # (Get-Content -Path "lib\features\profile\add\add_profile_modal.dart") -notmatch "qr_code_scanner_screen" | Set-Content -Path "lib\features\profile\add\add_profile_modal.dart" + # (Get-Content -Path lib\features\profile\add\add_profile_modal.dart) -replace 'await QRCodeScannerScreen\(\).open\(context\);', 'null;' | Set-Content -Path lib\features\profile\add\add_profile_modal.dart + # Remove-Item -Path "lib\features\common\qr_code_scanner_screen.dart" @@ -368,8 +368,8 @@ jobs: upload-to-testflight: needs: [build] - # if: ${{ inputs.upload-artifact && inputs.tag-name != 'draft' }} - if: ${{ inputs.upload-artifact }} + if: ${{ inputs.upload-artifact && inputs.tag-name != 'draft' }} + #if: ${{ inputs.upload-artifact }} runs-on: macOS-latest timeout-minutes: 30 steps: diff --git a/.vscode/launch.json b/.vscode/launch.json index 3fcb0f2b..fa9c6ea9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,6 +7,8 @@ "type": "dart", "flutterMode": "debug", "program": "lib/main.dart", + // "args": ["-d","192.168.1.35:36463"] + }, { "name": "Hiddify Dev Release", @@ -36,7 +38,7 @@ "program": "lib/main.dart", "args": [ "--app-id", - "com.hiddify.ios" + "app.hiddify.com" ], "deviceId": "designed-for-ipad", } diff --git a/Makefile b/Makefile index d25c1ca1..76557a60 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ prepare: windows-prepare: get-geo-assets get gen translate windows-libs -ios-prepare: get-geo-assets get gen translate ios-libs +ios-prepare: get-geo-assets get gen translate ios-libs macos-prepare: get-geo-assets get gen translate macos-libs linux-prepare: get-geo-assets get gen translate linux-libs linux-appimage-prepare:linux-prepare diff --git a/README.md b/README.md index 96d6a078..8e99f64b 100644 --- a/README.md +++ b/README.md @@ -75,30 +75,42 @@ Vless, Vmess, Reality, TUIC, Hysteria, SSH etc. - Android -
-
-
- - + iOS + + + + + + Android + +
+
+
+ + Windows -
-
- - + +
+
+ + macOS -
- + +
+ + Linux -
-
- + +
+
+ + diff --git a/README_br.md b/README_br.md index fdc79bf9..928cd2dd 100644 --- a/README_br.md +++ b/README_br.md @@ -56,9 +56,14 @@ Vless, Vmess, Reality, TUIC, Hysteria, SSH, etc. ⭐ Configuração adequada para Irã, China, Rússia e outros países -📱 Disponível no [Google Play](https://play.google.com/store/apps/details?id=app.hiddify.com) +📱 Disponível nas lojas oficiais -## 🔗 Download +## 🛍️ Obtenha nas lojas +         +         + + +## 📥 Download direto
@@ -69,28 +74,42 @@ Vless, Vmess, Reality, TUIC, Hysteria, SSH, etc. + + + + - + - + - +
iOS + +
Android -
-
-
-
- +
+
+
+
Windows
- -
+
+
+ +
macOS +
+ +
Linux +
+
+ +
diff --git a/README_cn.md b/README_cn.md index 44ef45cb..06034984 100644 --- a/README_cn.md +++ b/README_cn.md @@ -50,9 +50,14 @@ ⭐ 适用于伊朗、中国、俄罗斯或其他国家的配置 -📱 可在 [Google Play](https://play.google.com/store/apps/details?id=app.hiddify.com) 上获取 +📱 官方商店有售 -## 🔗 下载 +## 🛍️ 在商店购买 +         +         + + +## 📥 直接下载
@@ -64,27 +69,42 @@ - + + + + + + - + - + - +
Android -
-
-
-
- -
iOS + +
Android +
+
+
+ +
Windows
- -
+
+
+ +
macOS +
+ +
Linux +
+
+ +
diff --git a/README_fa.md b/README_fa.md index b5a60c57..a2098efa 100644 --- a/README_fa.md +++ b/README_fa.md @@ -78,31 +78,42 @@ Vless, Vmess, Reality, TUIC, Hysteria, SSH, etc. + + iOS + + + + اندروید -
-
-
- +
+
+
+ ویندوز -
-
- + +
+
+ مک -
- + +
+ + لینوکس -
-
- + +
+
+ + diff --git a/README_ja.md b/README_ja.md index a67aeb72..4299d99c 100644 --- a/README_ja.md +++ b/README_ja.md @@ -57,9 +57,14 @@ Vless、Vmess、Reality、TUIC、Hysteria、SSHなど。 ⭐ イラン、中国、ロシア、その他の国に適した構成 -📱 [Google Play](https://play.google.com/store/apps/details?id=app.hiddify.com) で入手可能 +📱公式ストアで購入可能 -## 🔗 ダウンロード +## 🛍️ 店舗で入手 +         +         + + +## 📥 直接ダウンロード
@@ -71,27 +76,42 @@ Vless、Vmess、Reality、TUIC、Hysteria、SSHなど。 - + + + + + + - + - + - +
Android -
-
-
-
- -
iOS + +
Android +
+
+
+ +
Windows
- -
+
+
+ +
macOS +
+ +
Linux +
+
+ +
diff --git a/README_ru.md b/README_ru.md index 5f7fb2b5..a08b63ff 100644 --- a/README_ru.md +++ b/README_ru.md @@ -46,9 +46,14 @@ ⭐ Подходящая конфигурация для Ирана, Китая, России и других стран. -📱 Доступно в [Google Play](https://play.google.com/store/apps/details?id=app.hiddify.com) +📱Доступно в официальных магазинах. -## 🔗 Скачать +## 🛍️ Приобретите в магазинах +         +         + + +## 📥 Прямая загрузка
@@ -59,27 +64,42 @@ - + + + + + + - + - + - +
Android -
-
-
-
- -
iOS + +
Android +
+
+
+ +
Windows
- -
+
+
+ +
MacOS +
+ +
Linux +
+
+ +
diff --git a/android/app/src/main/kotlin/com/hiddify/hiddify/bg/BoxService.kt b/android/app/src/main/kotlin/com/hiddify/hiddify/bg/BoxService.kt index b89353bf..0935bc1a 100644 --- a/android/app/src/main/kotlin/com/hiddify/hiddify/bg/BoxService.kt +++ b/android/app/src/main/kotlin/com/hiddify/hiddify/bg/BoxService.kt @@ -292,6 +292,9 @@ class BoxService( } } } + override fun postServiceClose(){ + //TODO: + } private suspend fun stopAndAlert(type: Alert, message: String? = null) { Settings.startedByUser = false diff --git a/assets/images/connect_norouz.PNG b/assets/images/connect_norouz.PNG new file mode 100644 index 00000000..280edc56 Binary files /dev/null and b/assets/images/connect_norouz.PNG differ diff --git a/assets/images/disconnect_norouz.PNG b/assets/images/disconnect_norouz.PNG new file mode 100644 index 00000000..05bcb560 Binary files /dev/null and b/assets/images/disconnect_norouz.PNG differ diff --git a/assets/translations/strings_en.i18n.json b/assets/translations/strings_en.i18n.json index b09df18c..94f76aa8 100644 --- a/assets/translations/strings_en.i18n.json +++ b/assets/translations/strings_en.i18n.json @@ -74,7 +74,8 @@ "permissionDeniedError": "Permission Denied", "unexpectedError": "Something Went Wrong", "torchSemanticLabel": "Flash Light", - "facingSemanticLabel": "Camera Facing" + "facingSemanticLabel": "Camera Facing", + "permissionRequest": "Permission to camera to scan QR Code" }, "manually": "Manual Entry", "addingProfileMsg": "Adding Profile", @@ -372,7 +373,7 @@ "directDnsDomainStrategy": "Direct DNS Domain Strategy", "mixedPort": "Mixed Port", "localDnsPort": "Local DNS Port", - "allowConnectionFromLan": "Allow Connection from LAN", + "allowConnectionFromLan": "Share VPN in Local Network", "tunImplementation": "TUN Implementation", "mtu": "MTU", "connectionTestUrl": "Connection Test URL", diff --git a/assets/translations/strings_fa.i18n.json b/assets/translations/strings_fa.i18n.json index fe47c651..32081246 100644 --- a/assets/translations/strings_fa.i18n.json +++ b/assets/translations/strings_fa.i18n.json @@ -218,17 +218,17 @@ "clearSelection": "پاک کردن انتخاب‌ها" }, "geoAssets": { - "pageTitle": "دارایی‌های مسیریابی", + "pageTitle": "فایل‌های مسیریابی", "geoip": "ژئو آی‌پی", "geosite": "ژئو سایت", "version": "نسخه ${version}", "fileMissing": "فایل موجود نیست", "update": "به‌روزرسانی", "download": "دانلود", - "failureMsg": "به‌روزرسانی دارایی انجام نشد", - "successMsg": "دارایی با موفقیت به‌روزرسانی شد", - "addRecommended": "افزودن دارایی‌های پیشنهادی", - "missingGeoAssetsMsg": "فایل‌های دارایی‌های مسیریابی انتخابی وجود ندارد. یا آن‌ها را دانلود کنید و یا موارد موجود را انتخاب کنید" + "failureMsg": "به‌روزرسانی فایل انجام نشد", + "successMsg": "فایل‌ با موفقیت به‌روزرسانی شد", + "addRecommended": "افزودن فایل‌های توصیه‌شده", + "missingGeoAssetsMsg": "فایل‌های مسیریابی انتخابی وجود ندارد. یا آن‌ها را دانلود کنید و یا موارد موجود را انتخاب کنید" } }, "about": { @@ -271,11 +271,12 @@ "unexpected": "خطای غیرمنتظره در سرویس", "serviceNotRunning": "سرویس در حال اجرا نیست", "missingPrivilege": "نیازمند دسترسی", - "missingPrivilegeMsg": "حالت VPN به دسترسی سرپرست نیاز دارد. یا برنامه را دوباره به‌عنوان سرپرست راه‌اندازی کنید و یا حالت سرویس را تغییر دهید.", - "missingGeoAssets": "دارایی‌های جغرافیایی وجود ندارند", - "missingGeoAssetsMsg": "دارایی‌های جغرافیایی گم شده‌اند. تغییر دارایی فعال را در نظر بگیرید و یا یکی را در تنظیمات دانلود کنید.", - "invalidConfigOptions": "تنظیمات پیکربندی نامعتبر است", - "invalidConfig": "پیکربندی نامعتبر است", + + "missingPrivilegeMsg": "حالت VPN به دسترسی سرپرست نیاز دارد. یا برنامه را دوباره به‌عنوان سرپرست راه‌اندازی کنید یا حالت سرویس را تغییر دهید.", + "missingGeoAssets": "فایل‌های جغرافیایی وجود ندارد", + "missingGeoAssetsMsg": "فایل‌های جغرافیایی گم شده‌اند. تغییر فایل فعال را در نظر بگیرید و یا یکی را در تنظیمات دانلود کنید.", + "invalidConfigOptions": "تنظیمات پیکربندی نامعتبر", + "invalidConfig": "پیکربندی نامعتبر", "create": "خطای ایجاد سرویس", "start": "خطای راه‌اندازی سرویس" }, @@ -301,7 +302,7 @@ "geoAssets": { "unexpected": "خطای غیرمنتظره", "notUpdate": "هیچ به‌روزرسانی موجود نیست", - "activeNotFound": "دارایی فعال ژئو یافت نشد" + "activeNotFound": "فایل فعال ژئو یافت نشد" } }, "play": { @@ -372,7 +373,7 @@ "directDnsDomainStrategy": "استراتژی دامنه DNS مستقیم", "mixedPort": "درگاه چندمنظوره", "localDnsPort": "درگاه DNS داخلی", - "allowConnectionFromLan": "اجازه‌ی اتصال از LAN", + "allowConnectionFromLan": "اشتراک فیلترشکن در شبکه", "tunImplementation": "پیاده‌سازی TUN", "mtu": "سایز بسته‌ها", "connectionTestUrl": "لینک بررسی ارتباط", @@ -395,15 +396,15 @@ "muxProtocol": "پروتکل Mux", "muxMaxStreams": "حداکثر جریان‌های هم‌زمان", "enableWarp": "فعال‌سازی WARP", - "warpDetourMode": "حالت انحرافی", + "warpDetourMode": "حالت وارپ", "warpDetourModes": { - "proxyOverWarp": "انحراف پراکسی‌ها از طریق WARP", - "warpOverProxy": "انحراف WARP از طریق پراکسی‌ها", - "inbound": "انحراف WARP از طریق پراکسی‌ها", - "outbound": "انحراف پراکسی‌ها از طریق WARP" + "proxyOverWarp": "عبور پراکسی‌ها از طریق WARP", + "warpOverProxy": "عبور WARP از طریق پراکسی‌ها", + "inbound": "عبور WARP از طریق پراکسی‌ها", + "outbound": "عبور پراکسی‌ها از طریق WARP" }, "warpLicenseKey": "کلید مجوز", - "warpCleanIp": "پاک‌سازی آی‌پی", + "warpCleanIp": "آی‌پی تمیز", "warpPort": "درگاه", "warpNoise": "تعداد نویز", "warpNoiseDelay": "تأخیر نویز" diff --git a/dependencies.properties b/dependencies.properties index 5ae439c2..6b49c2fc 100644 --- a/dependencies.properties +++ b/dependencies.properties @@ -1 +1 @@ -core.version=0.17.8 \ No newline at end of file +core.version=1.0.0 \ No newline at end of file diff --git a/ios/Podfile b/ios/Podfile index c461cbd0..8e07cf3d 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -32,6 +32,8 @@ target 'Runner' do use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + pod 'EasyPermissionX/Camera' + target 'RunnerTests' do inherit! :search_paths end diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index f5a6151e..3522728a 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -751,7 +751,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = SingBoxPacketTunnel/SingBoxPacketTunnel.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1712; + CURRENT_PROJECT_VERSION = 10000; ENABLE_USER_SCRIPT_SANDBOXING = YES; EXCLUDED_ARCHS = armv7; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -770,7 +770,7 @@ "@executable_path/libcore/", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 0.17.12; + MARKETING_VERSION = 1.0.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; OTHER_LDFLAGS = "-lresolv"; @@ -802,7 +802,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = SingBoxPacketTunnel/SingBoxPacketTunnel.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1712; + CURRENT_PROJECT_VERSION = 10000; ENABLE_USER_SCRIPT_SANDBOXING = YES; EXCLUDED_ARCHS = armv7; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -821,7 +821,7 @@ "@executable_path/libcore/", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 0.17.12; + MARKETING_VERSION = 1.0.0; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = "-lresolv"; @@ -851,7 +851,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = SingBoxPacketTunnel/SingBoxPacketTunnel.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1712; + CURRENT_PROJECT_VERSION = 10000; ENABLE_USER_SCRIPT_SANDBOXING = YES; EXCLUDED_ARCHS = armv7; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -870,7 +870,7 @@ "@executable_path/libcore/", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 0.17.12; + MARKETING_VERSION = 1.0.0; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = "-lresolv"; diff --git a/ios/SingBoxPacketTunnel/SingBox/ExtensionPlatformInterface.swift b/ios/SingBoxPacketTunnel/SingBox/ExtensionPlatformInterface.swift index 8d8bb9fb..ff8f68cd 100644 --- a/ios/SingBoxPacketTunnel/SingBox/ExtensionPlatformInterface.swift +++ b/ios/SingBoxPacketTunnel/SingBox/ExtensionPlatformInterface.swift @@ -222,7 +222,12 @@ public class ExtensionPlatformInterface: NSObject, LibboxPlatformInterfaceProtoc } } + public func postServiceClose() { + // TODO + } + func reset() { networkSettings = nil } + } diff --git a/ios/SingBoxPacketTunnel/SingBox/ExtensionProvider.swift b/ios/SingBoxPacketTunnel/SingBox/ExtensionProvider.swift index 3be722fb..85ab3102 100644 --- a/ios/SingBoxPacketTunnel/SingBox/ExtensionProvider.swift +++ b/ios/SingBoxPacketTunnel/SingBox/ExtensionProvider.swift @@ -137,6 +137,7 @@ open class ExtensionProvider: NEPacketTunnelProvider { stopService() await startService() } + override open func stopTunnel(with reason: NEProviderStopReason) async { writeMessage("(packet-tunnel) stopping, reason: \(reason)") diff --git a/lib/core/preferences/general_preferences.dart b/lib/core/preferences/general_preferences.dart index aefae330..bc36ab66 100644 --- a/lib/core/preferences/general_preferences.dart +++ b/lib/core/preferences/general_preferences.dart @@ -64,6 +64,11 @@ abstract class Preferences { "started_by_user", false, ); + + static final storeReviewedByUser = PreferencesNotifier.create( + "store_reviewed_by_user", + false, + ); } @Riverpod(keepAlive: true) diff --git a/lib/features/common/qr_code_scanner_screen.dart b/lib/features/common/qr_code_scanner_screen.dart index d534279f..cfb3f679 100644 --- a/lib/features/common/qr_code_scanner_screen.dart +++ b/lib/features/common/qr_code_scanner_screen.dart @@ -1,14 +1,15 @@ import 'package:dartx/dartx.dart'; import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_easy_permission/easy_permissions.dart'; import 'package:hiddify/core/localization/translations.dart'; import 'package:hiddify/utils/utils.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; -import 'package:permission_handler/permission_handler.dart'; +// import 'package:permission_handler/permission_handler.dart'; -final _cameraPermissionProvider = - FutureProvider.autoDispose((ref) => Permission.camera.request()); +const permissions = [Permissions.CAMERA]; +const permissionGroup = [PermissionGroup.Camera]; class QRCodeScannerScreen extends StatefulHookConsumerWidget { const QRCodeScannerScreen({super.key}); @@ -32,185 +33,157 @@ class _QRCodeScannerScreenState extends ConsumerState final controller = MobileScannerController(detectionTimeoutMs: 500, autoStart: false); bool started = false; - bool settingsOpened = false; + late FlutterEasyPermission _easyPermission; @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); + + _easyPermission = FlutterEasyPermission() + ..addPermissionCallback(onGranted: (requestCode, androidPerms, iosPerm) { + debugPrint("android:$androidPerms"); + debugPrint("iOS:$iosPerm"); + startQrScannerIfPermissionGranted(); + }, onDenied: (requestCode, androidPerms, iosPerm, isPermanent) { + if (isPermanent) { + FlutterEasyPermission.showAppSettingsDialog(title: "Camera"); + } else { + debugPrint("android:$androidPerms"); + debugPrint("iOS:$iosPerm"); + } + }, onSettingsReturned: () { + startQrScannerIfPermissionGranted(); + }); } @override void dispose() { controller.stop(); + _easyPermission.dispose(); WidgetsBinding.instance.removeObserver(this); super.dispose(); } - @override - void didChangeAppLifecycleState(AppLifecycleState state) { - if (state == AppLifecycleState.resumed && settingsOpened) { - loggy.debug("resumed"); - ref.invalidate(_cameraPermissionProvider); - settingsOpened = false; - } + void startQrScannerIfPermissionGranted() { + FlutterEasyPermission.has(perms: permissions, permsGroup: permissionGroup) + .then((value) { + if (value) { + controller.start().then((result) { + if (result != null) { + setState(() { + started = true; + }); + } + }).catchError((error) { + loggy.warning("Error starting scanner: $error"); + }); + } else {} + }); } @override Widget build(BuildContext context) { final t = ref.watch(translationsProvider); - ref.listen( - _cameraPermissionProvider, - (previous, next) async { - if (next case AsyncData(:final value) - when value == PermissionStatus.granted) { - try { - final result = await controller.start(); - if (result != null) { - setState(() { - started = true; - }); - } - } catch (error) { - loggy.warning("error starting scanner: $error", error); - } - } - }, - ); + startQrScannerIfPermissionGranted(); - switch (ref.watch(_cameraPermissionProvider)) { - case AsyncData(value: final status) - when status == PermissionStatus.granted: - final size = MediaQuery.sizeOf(context); - final overlaySize = (size.shortestSide - 12).coerceAtMost(248); + final size = MediaQuery.sizeOf(context); + final overlaySize = (size.shortestSide - 12).coerceAtMost(248); - return Scaffold( - extendBodyBehindAppBar: true, - appBar: AppBar( - backgroundColor: Colors.transparent, - iconTheme: Theme.of(context).iconTheme.copyWith( - color: Colors.white, - size: 32, - ), - actions: [ - IconButton( - icon: ValueListenableBuilder( - valueListenable: controller.torchState, - builder: (context, state, child) { - switch (state) { - case TorchState.off: - return const Icon( - FluentIcons.flash_off_24_regular, - color: Colors.grey, - ); - case TorchState.on: - return const Icon( - FluentIcons.flash_24_regular, - color: Colors.yellow, - ); - } - }, - ), - tooltip: t.profile.add.qrScanner.torchSemanticLabel, - onPressed: () => controller.toggleTorch(), - ), - IconButton( - icon: const Icon(FluentIcons.camera_switch_24_regular), - tooltip: t.profile.add.qrScanner.facingSemanticLabel, - onPressed: () => controller.switchCamera(), - ), - ], - ), - body: Stack( - children: [ - MobileScanner( - controller: controller, - onDetect: (capture) { - final rawData = capture.barcodes.first.rawValue; - loggy.debug('captured raw: [$rawData]'); - if (rawData != null) { - final uri = Uri.tryParse(rawData); - if (context.mounted && uri != null) { - loggy.debug('captured url: [$uri]'); - Navigator.of(context, rootNavigator: true) - .pop(uri.toString()); - } - } else { - loggy.warning("unable to capture"); - } - }, - errorBuilder: (_, error, __) { - final message = switch (error.errorCode) { - MobileScannerErrorCode.permissionDenied => - t.profile.add.qrScanner.permissionDeniedError, - _ => t.profile.add.qrScanner.unexpectedError, - }; - - return Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Padding( - padding: EdgeInsets.only(bottom: 8), - child: Icon( - FluentIcons.error_circle_24_regular, - color: Colors.white, - ), - ), - Text(message), - Text(error.errorDetails?.message ?? ''), - ], - ), - ); - }, - ), - if (started) - CustomPaint( - painter: ScannerOverlay( - Rect.fromCenter( - center: size.center(Offset.zero), - width: overlaySize, - height: overlaySize, - ), - ), - ), - ], - ), - ); - - case AsyncData(value: final status): - return Scaffold( - appBar: AppBar(), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text(t.profile.add.qrScanner.permissionDeniedError), - if (status == PermissionStatus.permanentlyDenied) - TextButton( - onPressed: () async { - settingsOpened = await openAppSettings(); - }, - child: Text(t.general.openAppSettings), - ) - else - TextButton( - onPressed: () { - ref.invalidate(_cameraPermissionProvider); - }, - child: Text(t.general.grantPermission), - ), - ], + return Scaffold( + extendBodyBehindAppBar: true, + appBar: AppBar( + backgroundColor: Colors.transparent, + iconTheme: Theme.of(context).iconTheme.copyWith( + color: Colors.white, + size: 32, ), + actions: [ + IconButton( + icon: ValueListenableBuilder( + valueListenable: controller.torchState, + builder: (context, state, child) { + switch (state) { + case TorchState.off: + return const Icon( + FluentIcons.flash_off_24_regular, + color: Colors.grey, + ); + case TorchState.on: + return const Icon( + FluentIcons.flash_24_regular, + color: Colors.yellow, + ); + } + }, + ), + tooltip: t.profile.add.qrScanner.torchSemanticLabel, + onPressed: () => controller.toggleTorch(), ), - ); + IconButton( + icon: const Icon(FluentIcons.camera_switch_24_regular), + tooltip: t.profile.add.qrScanner.facingSemanticLabel, + onPressed: () => controller.switchCamera(), + ), + ], + ), + body: Stack( + children: [ + MobileScanner( + controller: controller, + onDetect: (capture) { + final rawData = capture.barcodes.first.rawValue; + loggy.debug('captured raw: [$rawData]'); + if (rawData != null) { + final uri = Uri.tryParse(rawData); + if (context.mounted && uri != null) { + loggy.debug('captured url: [$uri]'); + Navigator.of(context, rootNavigator: true) + .pop(uri.toString()); + } + } else { + loggy.warning("unable to capture"); + } + }, + errorBuilder: (_, error, __) { + final message = switch (error.errorCode) { + MobileScannerErrorCode.permissionDenied => + t.profile.add.qrScanner.permissionDeniedError, + _ => t.profile.add.qrScanner.unexpectedError, + }; - default: - return Scaffold( - appBar: AppBar(), - ); - } + return Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Padding( + padding: EdgeInsets.only(bottom: 8), + child: Icon( + FluentIcons.error_circle_24_regular, + color: Colors.white, + ), + ), + Text(message), + Text(error.errorDetails?.message ?? ''), + ], + ), + ); + }, + ), + if (started) + CustomPaint( + painter: ScannerOverlay( + Rect.fromCenter( + center: size.center(Offset.zero), + width: overlaySize, + height: overlaySize, + ), + ), + ), + ], + ), + ); } } diff --git a/lib/features/config_option/notifier/warp_option_notifier.dart b/lib/features/config_option/notifier/warp_option_notifier.dart index 31cb58a9..5dcdc2ed 100644 --- a/lib/features/config_option/notifier/warp_option_notifier.dart +++ b/lib/features/config_option/notifier/warp_option_notifier.dart @@ -65,7 +65,9 @@ class WarpOptionNotifier extends _$WarpOptionNotifier with AppLogger { await ref .read(ConfigOptions.warpAccessToken.notifier) .update(warp.accessToken); - + await ref + .read(ConfigOptions.warpWireguardConfig.notifier) + .update(warp.wireguardConfig); return warp.log; }); diff --git a/lib/features/config_option/overview/config_options_page.dart b/lib/features/config_option/overview/config_options_page.dart index ff2e4104..c03ea937 100644 --- a/lib/features/config_option/overview/config_options_page.dart +++ b/lib/features/config_option/overview/config_options_page.dart @@ -212,29 +212,29 @@ class ConfigOptionsPage extends HookConsumerWidget { .watch(ConfigOptions.enableDnsRouting.notifier) .update, ), - const SettingsDivider(), - SettingsSection(experimental(t.config.section.mux)), - SwitchListTile( - title: Text(t.config.enableMux), - value: ref.watch(ConfigOptions.enableMux), - onChanged: - ref.watch(ConfigOptions.enableMux.notifier).update, - ), - ChoicePreferenceWidget( - selected: ref.watch(ConfigOptions.muxProtocol), - preferences: ref.watch(ConfigOptions.muxProtocol.notifier), - choices: MuxProtocol.values, - title: t.config.muxProtocol, - presentChoice: (value) => value.name, - ), - ValuePreferenceWidget( - value: ref.watch(ConfigOptions.muxMaxStreams), - preferences: - ref.watch(ConfigOptions.muxMaxStreams.notifier), - title: t.config.muxMaxStreams, - inputToValue: int.tryParse, - digitsOnly: true, - ), + // const SettingsDivider(), + // SettingsSection(experimental(t.config.section.mux)), + // SwitchListTile( + // title: Text(t.config.enableMux), + // value: ref.watch(ConfigOptions.enableMux), + // onChanged: + // ref.watch(ConfigOptions.enableMux.notifier).update, + // ), + // ChoicePreferenceWidget( + // selected: ref.watch(ConfigOptions.muxProtocol), + // preferences: ref.watch(ConfigOptions.muxProtocol.notifier), + // choices: MuxProtocol.values, + // title: t.config.muxProtocol, + // presentChoice: (value) => value.name, + // ), + // ValuePreferenceWidget( + // value: ref.watch(ConfigOptions.muxMaxStreams), + // preferences: + // ref.watch(ConfigOptions.muxMaxStreams.notifier), + // title: t.config.muxMaxStreams, + // inputToValue: int.tryParse, + // digitsOnly: true, + // ), const SettingsDivider(), SettingsSection(t.config.section.inbound), ChoicePreferenceWidget( diff --git a/lib/features/config_option/widget/quick_settings_modal.dart b/lib/features/config_option/widget/quick_settings_modal.dart index 2ed83d1c..e5acea73 100644 --- a/lib/features/config_option/widget/quick_settings_modal.dart +++ b/lib/features/config_option/widget/quick_settings_modal.dart @@ -65,11 +65,11 @@ class QuickSettingsModal extends HookConsumerWidget { ref.watch(ConfigOptions.enableTlsFragment.notifier).update, title: Text(t.config.enableTlsFragment), ), - SwitchListTile( - value: ref.watch(ConfigOptions.enableMux), - onChanged: ref.watch(ConfigOptions.enableMux.notifier).update, - title: Text(t.config.enableMux), - ), + // SwitchListTile( + // value: ref.watch(ConfigOptions.enableMux), + // onChanged: ref.watch(ConfigOptions.enableMux.notifier).update, + // title: Text(t.config.enableMux), + // ), ListTile( title: Text(t.config.allOptions), trailing: const Icon(FluentIcons.chevron_right_24_regular), diff --git a/lib/features/connection/notifier/connection_notifier.dart b/lib/features/connection/notifier/connection_notifier.dart index 8e3b07f7..8ce1ddfa 100644 --- a/lib/features/connection/notifier/connection_notifier.dart +++ b/lib/features/connection/notifier/connection_notifier.dart @@ -11,6 +11,7 @@ import 'package:hiddify/utils/utils.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'; @@ -30,6 +31,14 @@ class ConnectionNotifier extends _$ConnectionNotifier with AppLogger { if (previous case AsyncData(:final value) when !value.isConnected) { if (next case AsyncData(value: final Connected _)) { await ref.read(hapticServiceProvider.notifier).heavyImpact(); + + if (Platform.isAndroid && + !ref.read(Preferences.storeReviewedByUser)) { + if (await InAppReview.instance.isAvailable()) { + InAppReview.instance.requestReview(); + ref.read(Preferences.storeReviewedByUser.notifier).update(true); + } + } } } }, diff --git a/lib/features/home/widget/connection_button.dart b/lib/features/home/widget/connection_button.dart index e8aa4b29..e0cda02b 100644 --- a/lib/features/home/widget/connection_button.dart +++ b/lib/features/home/widget/connection_button.dart @@ -25,6 +25,7 @@ class ConnectionButton extends HookConsumerWidget { final connectionStatus = ref.watch(connectionNotifierProvider); final requiresReconnect = ref.watch(configOptionNotifierProvider).valueOrNull; + final today = DateTime.now(); ref.listen( connectionNotifierProvider, @@ -93,6 +94,19 @@ class ConnectionButton extends HookConsumerWidget { AsyncData(value: _) => buttonTheme.idleColor!, _ => Colors.red, }, + image: switch (connectionStatus) { + AsyncData(value: Connected()) when requiresReconnect == true => + Assets.images.disconnectNorouz, + AsyncData(value: Connected()) => Assets.images.connectNorouz, + AsyncData(value: _) => Assets.images.disconnectNorouz, + _ => Assets.images.disconnectNorouz, + AsyncData(value: Disconnected()) || + AsyncError() => + Assets.images.disconnectNorouz, + AsyncData(value: Connected()) => Assets.images.connectNorouz, + _ => Assets.images.disconnectNorouz, + }, + useImage: today.day >= 19 && today.day <= 23 && today.month == 3, ); } } @@ -103,12 +117,16 @@ class _ConnectionButton extends StatelessWidget { required this.enabled, required this.label, required this.buttonColor, + required this.image, + required this.useImage, }); final VoidCallback onTap; final bool enabled; final String label; final Color buttonColor; + final AssetGenImage image; + final bool useImage; @override Widget build(BuildContext context) { @@ -144,12 +162,16 @@ class _ConnectionButton extends StatelessWidget { tween: ColorTween(end: buttonColor), duration: const Duration(milliseconds: 250), builder: (context, value, child) { - return Assets.images.logo.svg( - colorFilter: ColorFilter.mode( - value!, - BlendMode.srcIn, - ), - ); + if (useImage) { + return image.image(filterQuality: FilterQuality.medium); + } else { + return Assets.images.logo.svg( + colorFilter: ColorFilter.mode( + value!, + BlendMode.srcIn, + ), + ); + } }, ), ), diff --git a/lib/singbox/service/ffi_singbox_service.dart b/lib/singbox/service/ffi_singbox_service.dart index 61b72675..83583a0f 100644 --- a/lib/singbox/service/ffi_singbox_service.dart +++ b/lib/singbox/service/ffi_singbox_service.dart @@ -287,7 +287,7 @@ class FFISingboxService with InfraLogger implements SingboxService { logger.debug("stopping"); receiver.close(); _outboundsStream = null; - final err = _box.stopCommandClient(4).cast().toDartString(); + final err = _box.stopCommandClient(5).cast().toDartString(); if (err.isNotEmpty) { _logger.error("error stopping group client"); } @@ -311,7 +311,7 @@ class FFISingboxService with InfraLogger implements SingboxService { try { final err = _box - .startCommandClient(4, receiver.sendPort.nativePort) + .startCommandClient(5, receiver.sendPort.nativePort) .cast() .toDartString(); if (err.isNotEmpty) { @@ -334,7 +334,7 @@ class FFISingboxService with InfraLogger implements SingboxService { onCancel: (_) { logger.debug("stopping"); receiver.close(); - final err = _box.stopCommandClient(12).cast().toDartString(); + final err = _box.stopCommandClient(13).cast().toDartString(); if (err.isNotEmpty) { logger.error("failed stopping: $err"); } @@ -358,7 +358,7 @@ class FFISingboxService with InfraLogger implements SingboxService { try { final err = _box - .startCommandClient(12, receiver.sendPort.nativePort) + .startCommandClient(13, receiver.sendPort.nativePort) .cast() .toDartString(); if (err.isNotEmpty) { diff --git a/lib/singbox/service/platform_singbox_service.dart b/lib/singbox/service/platform_singbox_service.dart index e7707efa..e8376584 100644 --- a/lib/singbox/service/platform_singbox_service.dart +++ b/lib/singbox/service/platform_singbox_service.dart @@ -9,14 +9,11 @@ import 'package:hiddify/singbox/model/singbox_outbound.dart'; import 'package:hiddify/singbox/model/singbox_stats.dart'; import 'package:hiddify/singbox/model/singbox_status.dart'; import 'package:hiddify/singbox/model/warp_account.dart'; -import 'package:hiddify/singbox/service/core_singbox_service.dart'; import 'package:hiddify/singbox/service/singbox_service.dart'; import 'package:hiddify/utils/custom_loggers.dart'; import 'package:rxdart/rxdart.dart'; -class PlatformSingboxService extends CoreSingboxService - with InfraLogger - implements SingboxService { +class PlatformSingboxService with InfraLogger implements SingboxService { static const channelPrefix = "com.hiddify.app"; static const methodChannel = MethodChannel("$channelPrefix/method"); @@ -49,13 +46,34 @@ class PlatformSingboxService extends CoreSingboxService TaskEither setup(Directories directories, bool debug) { return TaskEither( () async { - await methodChannel.invokeMethod("setup"); + if (!Platform.isIOS) { + return right(unit); + } + await methodChannel.invokeMethod("setup"); return right(unit); }, ); } + @override + TaskEither validateConfigByPath( + String path, + String tempPath, + bool debug, + ) { + return TaskEither( + () async { + final message = await methodChannel.invokeMethod( + "parse_config", + {"path": path, "tempPath": tempPath, "debug": debug}, + ); + if (message == null || message.isEmpty) return right(unit); + return left(message); + }, + ); + } + @override TaskEither changeOptions(SingboxConfigOption options) { return TaskEither( @@ -70,6 +88,23 @@ class PlatformSingboxService extends CoreSingboxService ); } + @override + TaskEither generateFullConfigByPath(String path) { + return TaskEither( + () async { + loggy.debug("generating full config by path"); + final configJson = await methodChannel.invokeMethod( + "generate_config", + {"path": path}, + ); + if (configJson == null || configJson.isEmpty) { + return left("null response"); + } + return right(configJson); + }, + ); + } + @override TaskEither start( String path, diff --git a/libcore b/libcore index 85cc81a4..aab998fa 160000 --- a/libcore +++ b/libcore @@ -1 +1 @@ -Subproject commit 85cc81a46ad041a5c6f4ebb22df3af2ce9c3206a +Subproject commit aab998fae98d47abf8531e5ed8a736c62bd0f3dc diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index caa49dda..b54cb7b6 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -7,6 +7,7 @@ import Foundation import device_info_plus import flutter_timezone +import in_app_review import mobile_scanner import package_info_plus import path_provider_foundation @@ -23,6 +24,7 @@ import window_manager func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) FlutterTimezonePlugin.register(with: registry.registrar(forPlugin: "FlutterTimezonePlugin")) + InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin")) MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) diff --git a/pubspec.lock b/pubspec.lock index fe3121a1..d633ab54 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -503,6 +503,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.0" + flutter_easy_permission: + dependency: "direct main" + description: + name: flutter_easy_permission + sha256: "05eb1b561c894adef28b3ae38d8087fc2635f1047c5e18cf2698fb42b6ccc132" + url: "https://pub.dev" + source: hosted + version: "1.1.2" flutter_gen_core: dependency: transitive description: @@ -822,6 +830,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.3" + in_app_review: + dependency: "direct main" + description: + name: in_app_review + sha256: "99869244d09adc76af16bf8fd731dd13cef58ecafd5917847589c49f378cbb30" + url: "https://pub.dev" + source: hosted + version: "2.0.9" + in_app_review_platform_interface: + dependency: transitive + description: + name: in_app_review_platform_interface + sha256: fed2c755f2125caa9ae10495a3c163aa7fab5af3585a9c62ef4a6920c5b45f10 + url: "https://pub.dev" + source: hosted + version: "2.0.5" injector: dependency: transitive description: @@ -1134,54 +1158,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.2.3" - permission_handler: - dependency: "direct main" - description: - name: permission_handler - sha256: "74e962b7fad7ff75959161bb2c0ad8fe7f2568ee82621c9c2660b751146bfe44" - url: "https://pub.dev" - source: hosted - version: "11.3.0" - permission_handler_android: - dependency: transitive - description: - name: permission_handler_android - sha256: "1acac6bae58144b442f11e66621c062aead9c99841093c38f5bcdcc24c1c3474" - url: "https://pub.dev" - source: hosted - version: "12.0.5" - permission_handler_apple: - dependency: transitive - description: - name: permission_handler_apple - sha256: bdafc6db74253abb63907f4e357302e6bb786ab41465e8635f362ee71fd8707b - url: "https://pub.dev" - source: hosted - version: "9.4.0" - permission_handler_html: - dependency: transitive - description: - name: permission_handler_html - sha256: "54bf176b90f6eddd4ece307e2c06cf977fb3973719c35a93b85cc7093eb6070d" - url: "https://pub.dev" - source: hosted - version: "0.1.1" - permission_handler_platform_interface: - dependency: transitive - description: - name: permission_handler_platform_interface - sha256: "23dfba8447c076ab5be3dee9ceb66aad345c4a648f0cac292c77b1eb0e800b78" - url: "https://pub.dev" - source: hosted - version: "4.2.0" - permission_handler_windows: - dependency: transitive - description: - name: permission_handler_windows - sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" - url: "https://pub.dev" - source: hosted - version: "0.2.1" petitparser: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index bba7cd48..a085ce28 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: hiddify description: Cross Platform Multi Protocol Proxy Frontend. publish_to: "none" -version: 0.17.12+1712 +version: 1.0.0+10000 environment: sdk: ">=3.3.0 <4.0.0" @@ -76,7 +76,9 @@ dependencies: http: ^1.2.0 timezone_to_country: ^2.1.0 json_path: ^0.7.1 - permission_handler: ^11.3.0 + # permission_handler: ^11.3.0 # is not compatible with windows + flutter_easy_permission: ^1.1.2 + in_app_review: ^2.0.9 # circle_flags: ^4.0.2 circle_flags: git: https://github.com/hiddify-com/flutter_circle_flags.git @@ -113,6 +115,8 @@ flutter: - assets/images/tray_icon.png - assets/images/tray_icon_connected.ico - assets/images/tray_icon_disconnected.ico + - assets/images/connect_norouz.PNG + - assets/images/disconnect_norouz.PNG fonts: - family: Shabnam diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 47f071f8..c9dae969 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,7 +6,6 @@ #include "generated_plugin_registrant.h" -#include #include #include #include @@ -18,8 +17,6 @@ #include void RegisterPlugins(flutter::PluginRegistry* registry) { - PermissionHandlerWindowsPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); ProtocolHandlerWindowsPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("ProtocolHandlerWindowsPluginCApi")); ScreenRetrieverPluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 58127d66..9642d1c9 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,7 +3,6 @@ # list(APPEND FLUTTER_PLUGIN_LIST - permission_handler_windows protocol_handler_windows screen_retriever sentry_flutter diff --git a/windows/packaging/msix/make_config.yaml b/windows/packaging/msix/make_config.yaml index b4cb74e5..e4c3b768 100644 --- a/windows/packaging/msix/make_config.yaml +++ b/windows/packaging/msix/make_config.yaml @@ -1,7 +1,7 @@ display_name: Hiddify publisher_display_name: Hiddify identity_name: Hiddify.HiddifyNext -msix_version: 0.17.12.0 +msix_version: 1.0.0.0 logo_path: windows\runner\resources\app_icon.ico capabilities: internetClient, internetClientServer, privateNetworkClientServer languages: en-us, zh-cn, zh-tw, tr-tr,fa-ir,ru-ru,pt-br,es-es