new: add dnstt

This commit is contained in:
hiddify
2026-03-05 17:20:44 +03:30
40 changed files with 394 additions and 375 deletions
+24 -18
View File
@@ -20,6 +20,7 @@ env:
UPLOAD_ARTIFACT: "${{ inputs.upload-artifact }}"
TAG_NAME: "${{ inputs.tag-name }}"
TARGET_NAME_gz: "Hiddify-Linux-x64-AppImage.tar"
TARGET_NAME_AppImage: "Hiddify-Linux-x64-AppImage"
TARGET_NAME_deb: "Hiddify-Debian-x64"
# TARGET_NAME_rpm: "Hiddify-rpm-x64"
TARGET_NAME_apk: "Hiddify-Android"
@@ -64,18 +65,23 @@ jobs:
fail-fast: false
matrix:
include:
# - platform: android-apk
# os: ubuntu-latest
# targets: apk
- platform: android-apk
os: ubuntu-latest
targets: apk
- platform: android-aab
os: ubuntu-latest
targets: aab
# - platform: windows
# os: windows-latest
# aarch: amd64
# targets: exe,msix,zip
- platform: windows
os: windows-latest
aarch: amd64
targets: exe,msix,zip
- platform: linux
os: ubuntu-22.04
aarch: amd64
targets: deb,gz,AppImage
# - platform: linux-amd64
# os: ubuntu-22.04
@@ -97,10 +103,10 @@ jobs:
# aarch: arm64
# targets: deb,gz
# - platform: macos
# os: macos-15
# aarch: universal
# targets: dmg,pkg
- platform: macos
os: macos-15
aarch: universal
targets: dmg,pkg
# - platform: ios
# os: macos-15
@@ -133,21 +139,21 @@ jobs:
- name: Setup Flutter for arm64
if: ${{ startsWith(matrix.platform,'linux-arm64') }}
uses: hurelhuyag/flutter-arm64-action@HEAD
with:
channel: 'stable'
flutter-version: ${{ env.FLUTTER_VERSION }}
# - name: Setup Flutter for arm64
# if: ${{ startsWith(matrix.platform,'linux-arm64') }}
# uses: hurelhuyag/flutter-arm64-action@HEAD
# with:
# channel: 'stable'
# flutter-version: ${{ env.FLUTTER_VERSION }}
- name: Setup Flutter
if: ${{ !startsWith(matrix.platform, 'linux-arm64') }}
uses: subosito/flutter-action@v2.21.0 #issue with 2.13
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
# flutter-version-file: pubspec.yaml
channel: 'stable'
cache: true
- name: Clean up disk space
if: startsWith(matrix.platform,'android')
run: |
+5 -3
View File
@@ -92,7 +92,7 @@ ios-prepare: common-prepare ios-libs
cd ios; pod repo update; pod install;echo "done ios prepare"
macos-prepare: common-prepare macos-libs
linux-prepare: common-prepare linux-libs
linux-prepare: common-prepare linux-amd64-libs
linux-amd64-prepare: common-prepare linux-amd64-libs
@@ -388,6 +388,8 @@ linux-appimage-release:
sed -i '/^\[Desktop Entry\]/a StartupWMClass=app.hiddify.com' "squashfs-root/hiddify.desktop"; \
$(BLUE)Removing old AppImage$(DONE); \
rm *.AppImage; \
$(BLUE)Deleting bundled libstdc++ to fix Arch Linux compatibility...$(DONE); \
find squashfs-root/usr/lib -name "libstdc++.so.6" -delete; \
$(BLUE)Rebuilding AppImage$(DONE); \
ARCH=x86_64 appimagetool --no-appstream squashfs-root Hiddify.AppImage > /dev/null; \
$(BLUE)Cleaning up squashfs$(DONE); \
@@ -396,8 +398,8 @@ linux-appimage-release:
PKG_DIR_NAME="hiddify-linux-appimage"; \
$(BLUE)Creating dir: $$PKG_DIR_NAME$(DONE); \
mkdir -p "$$PKG_DIR_NAME"; \
$(BLUE)Moving and Renaming to Hiddify.AppImage$(DONE); \
mv "Hiddify.AppImage" "$$PKG_DIR_NAME/Hiddify.AppImage"; \
$(BLUE)Moving Hiddify.AppImage$(DONE); \
cp -p "Hiddify.AppImage" "$$PKG_DIR_NAME/Hiddify.AppImage"; \
$(BLUE)Creating Portable Home directory$(DONE); \
mkdir -p "$$PKG_DIR_NAME/Hiddify.AppImage.home"; \
$(BLUE)Compressing to .tar.gz$(DONE); \
+6 -5
View File
@@ -131,12 +131,9 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH etc.
## 🌎 Translations
<div align=center>
[![inlang status badge](https://inlang.com/badge?url=github.com/hiddify/hiddify-next)](https://inlang.com/editor/github.com/hiddify/hiddify-next?ref=badge)
</div>
You can improve existing languages or contribute new ones either by editing the JSON files in `/assets/translations` or [![Translate with Inlang](https://img.shields.io/badge/%20-%20-3ECF8E?logo=i18next&logoColor=white)](https://fink.inlang.com/github.com/hiddify/hiddify-app) by using [Inlang online editor](https://fink.inlang.com/github.com/hiddify/hiddify-app).
Improve existing languages or add new ones by manually editing the JSON files located in `/assets/translations` or by using the [Inlang online editor](https://fink.inlang.com/github.com/hiddify/hiddify-next).
## ✏️ Acknowledgements
@@ -155,6 +152,8 @@ We would like to express our sincere appreciation to the contributors of the fol
The easiest way to support us is to click on the star (⭐) at the top of this page.
<div align=center>
<a href="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history?repo_id=643504282" target="_blank" style="display: block" align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history/thumbnail.png?repo_id=643504282&image_size=auto&color_scheme=dark" width="721" height="auto">
@@ -162,7 +161,9 @@ The easiest way to support us is to click on the star (⭐) at the top of this p
</picture>
</a>
We also need financial support for our services. All of our activities are done voluntarily and financial support will be spent on the development of the project. You can view our support addresses [here](https://github.com/hiddify/hiddify-server/wiki/support).
</div>
We also need financial support for our services. All of our activities are done voluntarily and financial support will be spent on the development of the project. You can view our support addresses [here](https://hiddify.com/donation-and-support/).
## 👩‍🏫 Collaboration and Contact Information
+8 -7
View File
@@ -133,12 +133,8 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH, etc.
## 🌎 Tradução
<div align=center>
[![inlang status badge](https://inlang.com/badge?url=github.com/hiddify/hiddify-next)](https://inlang.com/editor/github.com/hiddify/hiddify-next?ref=badge)
</div>
Melhore os idiomas existentes ou adicione novos editando manualmente os arquivos JSON localizados em `/assets/translations` ou usando o [editor online Inlang](https://inlang.com/editor/github.com/hiddify/hiddify-next).
Melhore os idiomas existentes ou adicione novos editando manualmente os arquivos JSON localizados em `/assets/translations` ou [![Translate with Inlang](https://img.shields.io/badge/%20-%20-3ECF8E?logo=i18next&logoColor=white)](https://fink.inlang.com/github.com/hiddify/hiddify-app) usando o [editor online Inlang](https://fink.inlang.com/editor/github.com/hiddify/hiddify-app).
## ✏️ Agradecimentos
@@ -159,11 +155,16 @@ A maneira mais fácil de nos apoiar é clicar na estrela (⭐) no topo desta pá
<div align=center>
<img alt="Star History Chart" width=50% src="https://api.star-history.com/svg?repos=Hiddify/hiddify-next&type=Date)](https://star-history.com/#Hiddify/hiddify-next&Date" />
<a href="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history?repo_id=643504282" target="_blank" style="display: block" align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history/thumbnail.png?repo_id=643504282&image_size=auto&color_scheme=dark" width="721" height="auto">
<img alt="Star History of hiddify/hiddify-app" src="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history/thumbnail.png?repo_id=643504282&image_size=auto&color_scheme=light" width="721" height="auto">
</picture>
</a>
</div>
Também precisamos de apoio financeiro para nossos serviços. Todas as nossas atividades são realizadas voluntariamente e o apoio financeiro será utilizado no desenvolvimento do projeto. Você pode ver nossos links de suporte [aqui](https://github.com/hiddify/hiddify-server/wiki/support).
Também precisamos de apoio financeiro para nossos serviços. Todas as nossas atividades são realizadas voluntariamente e o apoio financeiro será utilizado no desenvolvimento do projeto. Você pode ver nossos links de suporte [aqui](https://hiddify.com/donation-and-support/).
## 👩‍🏫 Colaboração e Informações de Contato
+8 -8
View File
@@ -127,13 +127,8 @@
## 🌎 翻译
<div align=center>
[![inlang status badge](https://inlang.com/badge?url=github.com/hiddify/hiddify-next)](https://inlang.com/editor/github.com/hiddify/hiddify-next?ref=badge)
</div>
您可以通过手动编辑位于 `/assets/translations` 中的 JSON 文件,或使用 [Inlang 在线编辑器](https://inlang.com/editor/github.com/hiddify/hiddify-next)来改进现有语言或添加新语言。
您可以通过手动编辑位于 `/assets/translations` 中的 JSON 文件,或使用 [Inlang 在线编辑器](https://fink.inlang.com/editor/github.com/hiddify/hiddify-app)来改进现有语言或添加新语言。
## ✏️ 致谢
我们谨向以下项目的贡献者表示诚挚的谢意,这些项目打下的坚实基础和开发的创新功能,显着增强了本项目的功能,为本项目的开发带来了成功。
@@ -154,11 +149,16 @@
<div align=center>
<img alt="Star History Chart" width=50% src="https://api.star-history.com/svg?repos=Hiddify/hiddify-next&type=Date)](https://star-history.com/#Hiddify/hiddify-next&Date" />
<a href="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history?repo_id=643504282" target="_blank" style="display: block" align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history/thumbnail.png?repo_id=643504282&image_size=auto&color_scheme=dark" width="721" height="auto">
<img alt="Star History of hiddify/hiddify-app" src="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history/thumbnail.png?repo_id=643504282&image_size=auto&color_scheme=light" width="721" height="auto">
</picture>
</a>
</div>
我们的服务也需要经济支持。我们所有的活动都是志愿性质的,经济支持将被用于项目的发展。您可以在 [这里](https://github.com/hiddify/hiddify-server/wiki/support) 查看我们的支持地址。
我们的服务也需要经济支持。我们所有的活动都是志愿性质的,经济支持将被用于项目的发展。您可以在 [这里](https://hiddify.com/donation-and-support/) 查看我们的支持地址。
## 👩‍🏫 合作及联系信息
+8 -6
View File
@@ -132,12 +132,9 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH, etc.
## 🌎 ترجمه‌ها
<div align=center>
![Improve Translations](https://github.com/hiddify/hiddify-app/assets/125398461/c6f1f746-db8e-477d-ae05-b8305af838aa)
</div>
با ویرایش دستی فایل‌های JSON در assets/translations/ یا با استفاده از [ویرایشگر آنلاین Inlang](https://inlang.com/editor/github.com/hiddify/hiddify-next)، زبان‌های موجود را بهبود بدهید و یا زبان‌های جدید اضافه کنید.
با ویرایش دستی فایل‌های JSON در assets/translations/ یا با استفاده از [![Translate with Inlang](https://img.shields.io/badge/%20-%20-3ECF8E?logo=i18next&logoColor=white)](https://fink.inlang.com/github.com/hiddify/hiddify-app) [ویرایشگر آنلاین Inlang](https://fink.inlang.com/editor/github.com/hiddify/hiddify-app)، زبان‌های موجود را بهبود بدهید و یا زبان‌های جدید اضافه کنید.
## ✏️ سپاسگزاری‌ها
مایلیم از دست‌اندرکاران پروژه‌های زیر صمیمانه قدردانی کنیم که پایه قوی و ویژگی‌های نوآورانه آنها موفقیت و عملکرد این پروژه را به میزان قابل توجهی افزایش داده است.
@@ -157,11 +154,16 @@ Vless, Vmess, Reality, TUIC, Hysteria, Wireguard, SSH, etc.
<div align=center>
<img alt="Star History Chart" width=50% src="https://api.star-history.com/svg?repos=Hiddify/hiddify-next&type=Date)](https://star-history.com/#Hiddify/hiddify-next&Date" />
<a href="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history?repo_id=643504282" target="_blank" style="display: block" align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history/thumbnail.png?repo_id=643504282&image_size=auto&color_scheme=dark" width="721" height="auto">
<img alt="Star History of hiddify/hiddify-app" src="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history/thumbnail.png?repo_id=643504282&image_size=auto&color_scheme=light" width="721" height="auto">
</picture>
</a>
</div>
ما برای سرویس هایمان به کمک مالی هم نیاز داریم. تمامی فعالیت‌های ما به صورت داوطلبانه انجام می‌شود و حمایت‌های مالی صرف توسعه پروژه می‌شود. اطلاعات و آدرس‌های حمایت‌ از ما را در [این لینک](https://github.com/hiddify/hiddify-server/wiki/support) مشاهده فرمایید.
ما برای سرویس هایمان به کمک مالی هم نیاز داریم. تمامی فعالیت‌های ما به صورت داوطلبانه انجام می‌شود و حمایت‌های مالی صرف توسعه پروژه می‌شود. اطلاعات و آدرس‌های حمایت‌ از ما را در [این لینک](https://hiddify.com/fa/donation-and-support/) مشاهده فرمایید.
## 👩‍🏫 راه‌های همکاری و ارتباط با ما
+8 -8
View File
@@ -135,12 +135,7 @@ Vless、Vmess、Reality、TUIC、Hysteria、Wireguard、SSH など。
## 🌎 翻訳
<div align=center>
[![inlang status badge](https://inlang.com/badge?url=github.com/hiddify/hiddify-next)](https://inlang.com/editor/github.com/hiddify/hiddify-next?ref=badge)
</div>
インストールとチュートリアル `/assets/translations` にある JSON ファイルを手動で編集するか、[Inlang オンラインエディタ](https://inlang.com/editor/github.com/hiddify/hiddify-next)を使って、既存の言語を改良したり、新しい言語を追加したりすることができます。
インストールとチュートリアル `/assets/translations` にある JSON ファイルを手動で編集するか、[Inlang オンラインエディタ](https://fink.inlang.com/editor/github.com/hiddify/hiddify-app)を使って、既存の言語を改良したり、新しい言語を追加したりすることができます。
## ✏️ 謝辞
@@ -161,11 +156,16 @@ Vless、Vmess、Reality、TUIC、Hysteria、Wireguard、SSH など。
<div align=center>
<img alt="Star History Chart" width=50% src="https://api.star-history.com/svg?repos=Hiddify/hiddify-next&type=Date)](https://star-history.com/#Hiddify/hiddify-next&Date" />
<a href="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history?repo_id=643504282" target="_blank" style="display: block" align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history/thumbnail.png?repo_id=643504282&image_size=auto&color_scheme=dark" width="721" height="auto">
<img alt="Star History of hiddify/hiddify-app" src="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history/thumbnail.png?repo_id=643504282&image_size=auto&color_scheme=light" width="721" height="auto">
</picture>
</a>
</div>
また、私たちのサービスには財政的な支援も必要です。私たちの活動はすべて自発的に行われており、経済的支援はプロジェクトの発展に費やされます。私たちのサポートアドレスは[こちら](https://github.com/hiddify/hiddify-server/wiki/support)からご覧いただけます。
また、私たちのサービスには財政的な支援も必要です。私たちの活動はすべて自発的に行われており、経済的支援はプロジェクトの発展に費やされます。私たちのサポートアドレスは[こちら](https://hiddify.com/donation-and-support/)からご覧いただけます。
## 👩‍🏫 コラボレーションおよび連絡先
+8 -8
View File
@@ -119,12 +119,7 @@
## 🌎 Переводы
<div align=center>
[![inlang панель статуса](https://inlang.com/badge?url=github.com/hiddify/hiddify-next)](https://inlang.com/editor/github.com/hiddify/hiddify-next?ref=badge)
</div>
Улучшайте существующие языки или добавляйте новые, вручную редактируя JSON-файлы, расположенные в `/assets/translations`, или используя [Онлайн редактор Inlang](https://inlang.com/editor/github.com/hiddify/hiddify-next)
Улучшайте существующие языки или добавляйте новые, вручную редактируя JSON-файлы, расположенные в `/assets/translations`, или используя [Онлайн редактор Inlang](https://fink.inlang.com/editor/github.com/hiddify/hiddify-app)
## ✏️ Благодарности
@@ -145,12 +140,17 @@
<div align=center>
<img alt="Star History Chart" width=50% src="https://api.star-history.com/svg?repos=Hiddify/hiddify-next&type=Date)](https://star-history.com/#Hiddify/hiddify-next&Date" />
<a href="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history?repo_id=643504282" target="_blank" style="display: block" align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history/thumbnail.png?repo_id=643504282&image_size=auto&color_scheme=dark" width="721" height="auto">
<img alt="Star History of hiddify/hiddify-app" src="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history/thumbnail.png?repo_id=643504282&image_size=auto&color_scheme=light" width="721" height="auto">
</picture>
</a>
</div>
Нам также нужна финансовая поддержка для наших сервисов. Вся наша деятельность осуществляется на добровольных началах, а финансовая поддержка будет направлена на развитие проекта. Вы можете просмотреть адреса нашей поддержки [здесь](https://github.com/hiddify/hiddify-server/wiki/support).
Нам также нужна финансовая поддержка для наших сервисов. Вся наша деятельность осуществляется на добровольных началах, а финансовая поддержка будет направлена на развитие проекта. Вы можете просмотреть адреса нашей поддержки [здесь](https://hiddify.com/donation-and-support/).
## 👩‍🏫 Сотрудничество и контактная информация
+7 -7
View File
@@ -279,13 +279,13 @@
},
"region": "المنطقة",
"regions": {
"ir": "إيران (ir) 🇮🇷",
"cn": "الصين (cn) 🇨🇳",
"ru": "روسيا (ru) 🇷🇺",
"af": "أفغانستان (af) 🇦🇫",
"id": "إندونيسيا (id) 🇮🇩",
"tr": "تركيا (tr) 🇹🇷",
"br": "البرازيل (br) 🇧🇷",
"ir": "إيران (ir)",
"cn": "الصين (cn)",
"ru": "روسيا (ru)",
"af": "أفغانستان (af)",
"id": "إندونيسيا (id)",
"tr": "تركيا (tr)",
"br": "البرازيل (br)",
"other": "أخرى"
},
"balancerStrategy": {
+7 -7
View File
@@ -274,13 +274,13 @@
},
"region": "Region",
"regions": {
"ir": "Iran (ir) 🇮🇷",
"cn": "China (cn) 🇨🇳",
"ru": "Russia (ru) 🇷🇺",
"af": "Afghanistan (af) 🇦🇫",
"id": "Indonesia (id) 🇮🇩",
"tr": "Türkiye (tr) 🇹🇷",
"br": "Brazil (br) 🇧🇷",
"ir": "Iran (ir)",
"cn": "China (cn)",
"ru": "Russia (ru)",
"af": "Afghanistan (af)",
"id": "Indonesia (id)",
"tr": "Türkiye (tr)",
"br": "Brazil (br)",
"other": "Other"
},
"balancerStrategy": {
+7 -7
View File
@@ -273,13 +273,13 @@
},
"region": "Región",
"regions": {
"ir": "Irán (ir) 🇮🇷",
"cn": "China (cn) 🇨🇳",
"ru": "Rusia (ru) 🇷🇺",
"af": "Afganistán (af) 🇦🇫",
"id": "Indonesia (id) 🇮🇩",
"tr": "Turquía (tr) 🇹🇷",
"br": "Brasil (br) 🇧🇷",
"ir": "Irán (ir)",
"cn": "China (cn)",
"ru": "Rusia (ru)",
"af": "Afganistán (af)",
"id": "Indonesia (id)",
"tr": "Turquía (tr)",
"br": "Brasil (br)",
"other": "Otro"
},
"balancerStrategy": {
+7 -7
View File
@@ -273,13 +273,13 @@
},
"region": "منطقه",
"regions": {
"ir": "ایران (ir) 🇮🇷",
"cn": "چین (cn) 🇨🇳",
"ru": "روسیه (ru) 🇷🇺",
"af": "افغانستان (af) 🇦🇫",
"id": "اندونزی (id) 🇮🇩",
"tr": "ترکیه (tr) 🇹🇷",
"br": "برزیل (br) 🇧🇷",
"ir": "ایران (ir)",
"cn": "چین (cn)",
"ru": "روسیه (ru)",
"af": "افغانستان (af)",
"id": "اندونزی (id)",
"tr": "ترکیه (tr)",
"br": "برزیل (br)",
"other": "سایر"
},
"balancerStrategy": {
+7 -7
View File
@@ -273,13 +273,13 @@
},
"region": "Région",
"regions": {
"ir": "Iran (ir) 🇮🇷",
"cn": "Chine (cn) 🇨🇳",
"ru": "Russie (ru) 🇷🇺",
"af": "Afghanistan (af) 🇦🇫",
"id": "Indonésie (id) 🇮🇩",
"tr": "Turquie (tr) 🇹🇷",
"br": "Brésil (br) 🇧🇷",
"ir": "Iran (ir)",
"cn": "Chine (cn)",
"ru": "Russie (ru)",
"af": "Afghanistan (af)",
"id": "Indonésie (id)",
"tr": "Turquie (tr)",
"br": "Brésil (br)",
"other": "Autre"
},
"balancerStrategy": {
+7 -7
View File
@@ -273,13 +273,13 @@
},
"region": "Wilayah",
"regions": {
"ir": "Iran (ir) 🇮🇷",
"cn": "Tiongkok (cn) 🇨🇳",
"ru": "Rusia (ru) 🇷🇺",
"af": "Afghanistan (af) 🇦🇫",
"id": "Indonesia (id) 🇮🇩",
"tr": "Turki (tr) 🇹🇷",
"br": "Brasil (br) 🇧🇷",
"ir": "Iran (ir)",
"cn": "Tiongkok (cn)",
"ru": "Rusia (ru)",
"af": "Afghanistan (af)",
"id": "Indonesia (id)",
"tr": "Turki (tr)",
"br": "Brasil (br)",
"other": "Lainnya"
},
"balancerStrategy": {
+7 -7
View File
@@ -273,13 +273,13 @@
},
"region": "Região",
"regions": {
"ir": "Irã (ir) 🇮🇷",
"cn": "China (cn) 🇨🇳",
"ru": "Rússia (ru) 🇷🇺",
"af": "Afeganistão (af) 🇦🇫",
"id": "Indonésia (id) 🇮🇩",
"tr": "Turquia (tr) 🇹🇷",
"br": "Brasil (br) 🇧🇷",
"ir": "Irã (ir)",
"cn": "China (cn)",
"ru": "Rússia (ru)",
"af": "Afeganistão (af)",
"id": "Indonésia (id)",
"tr": "Turquia (tr)",
"br": "Brasil (br)",
"other": "Outro"
},
"balancerStrategy": {
+7 -7
View File
@@ -277,13 +277,13 @@
},
"region": "Регион",
"regions": {
"ir": "Иран (ir) 🇮🇷",
"cn": "Китай (cn) 🇨🇳",
"ru": "Россия (ru) 🇷🇺",
"af": "Афганистан (af) 🇦🇫",
"id": "Индонезия (id) 🇮🇩",
"tr": "Турция (tr) 🇹🇷",
"br": "Бразилия (br) 🇧🇷",
"ir": "Иран (ir)",
"cn": "Китай (cn)",
"ru": "Россия (ru)",
"af": "Афганистан (af)",
"id": "Индонезия (id)",
"tr": "Турция (tr)",
"br": "Бразилия (br)",
"other": "Другой"
},
"balancerStrategy": {
+7 -7
View File
@@ -273,13 +273,13 @@
},
"region": "Bölge",
"regions": {
"ir": "İran (ir) 🇮🇷",
"cn": "Çin (cn) 🇨🇳",
"ru": "Rusya (ru) 🇷🇺",
"af": "Afganistan (af) 🇦🇫",
"id": "Endonezya (id) 🇮🇩",
"tr": "Türkiye (tr) 🇹🇷",
"br": "Brezilya (br) 🇧🇷",
"ir": "İran (ir)",
"cn": "Çin (cn)",
"ru": "Rusya (ru)",
"af": "Afganistan (af)",
"id": "Endonezya (id)",
"tr": "Türkiye (tr)",
"br": "Brezilya (br)",
"other": "Diğer"
},
"balancerStrategy": {
+7 -7
View File
@@ -273,13 +273,13 @@
},
"region": "地区",
"regions": {
"ir": "伊朗 (ir) 🇮🇷",
"cn": "中国 (cn) 🇨🇳",
"ru": "俄罗斯 (ru) 🇷🇺",
"af": "阿富汗 (af) 🇦🇫",
"id": "印度尼西亚 (id) 🇮🇩",
"tr": "土耳其 (tr) 🇹🇷",
"br": "巴西 (br) 🇧🇷",
"ir": "伊朗 (ir)",
"cn": "中国 (cn)",
"ru": "俄罗斯 (ru)",
"af": "阿富汗 (af)",
"id": "印度尼西亚 (id)",
"tr": "土耳其 (tr)",
"br": "巴西 (br)",
"other": "其他"
},
"balancerStrategy": {
+7 -7
View File
@@ -273,13 +273,13 @@
},
"region": "地區",
"regions": {
"ir": "伊朗 (ir) 🇮🇷",
"cn": "中國 (cn) 🇨🇳",
"ru": "俄羅斯 (ru) 🇷🇺",
"af": "阿富汗 (af) 🇦🇫",
"id": "印尼 (id) 🇮🇩",
"tr": "土耳其 (tr) 🇹🇷",
"br": "巴西 (br) 🇧🇷",
"ir": "伊朗 (ir)",
"cn": "中國 (cn)",
"ru": "俄羅斯 (ru)",
"af": "阿富汗 (af)",
"id": "印尼 (id)",
"tr": "土耳其 (tr)",
"br": "巴西 (br)",
"other": "其他"
},
"balancerStrategy": {
+5 -79
View File
@@ -46,58 +46,11 @@ PODS:
- Flutter
- flutter_native_splash (2.4.3):
- Flutter
- flutter_timezone (0.0.1):
- Flutter
- GoogleDataTransport (10.1.0):
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- GoogleMLKit/BarcodeScanning (7.0.0):
- GoogleMLKit/MLKitCore
- MLKitBarcodeScanning (~> 6.0.0)
- GoogleMLKit/MLKitCore (7.0.0):
- MLKitCommon (~> 12.0.0)
- GoogleToolboxForMac/Defines (4.2.1)
- GoogleToolboxForMac/Logger (4.2.1):
- GoogleToolboxForMac/Defines (= 4.2.1)
- "GoogleToolboxForMac/NSData+zlib (4.2.1)":
- GoogleToolboxForMac/Defines (= 4.2.1)
- GoogleUtilities/Environment (8.1.0):
- GoogleUtilities/Privacy
- GoogleUtilities/Logger (8.1.0):
- GoogleUtilities/Environment
- GoogleUtilities/Privacy
- GoogleUtilities/Privacy (8.1.0)
- GoogleUtilities/UserDefaults (8.1.0):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- GTMSessionFetcher/Core (3.5.0)
- in_app_review (2.0.0):
- Flutter
- MLImage (1.0.0-beta6)
- MLKitBarcodeScanning (6.0.0):
- MLKitCommon (~> 12.0)
- MLKitVision (~> 8.0)
- MLKitCommon (12.0.0):
- GoogleDataTransport (~> 10.0)
- GoogleToolboxForMac/Logger (< 5.0, >= 4.2.1)
- "GoogleToolboxForMac/NSData+zlib (< 5.0, >= 4.2.1)"
- GoogleUtilities/Logger (~> 8.0)
- GoogleUtilities/UserDefaults (~> 8.0)
- GTMSessionFetcher/Core (< 4.0, >= 3.3.2)
- MLKitVision (8.0.0):
- GoogleToolboxForMac/Logger (< 5.0, >= 4.2.1)
- "GoogleToolboxForMac/NSData+zlib (< 5.0, >= 4.2.1)"
- GTMSessionFetcher/Core (< 4.0, >= 3.3.2)
- MLImage (= 1.0.0-beta6)
- MLKitCommon (~> 12.0)
- mobile_scanner (6.0.2):
- mobile_scanner (7.0.0):
- Flutter
- GoogleMLKit/BarcodeScanning (~> 7.0.0)
- nanopb (3.30910.0):
- nanopb/decode (= 3.30910.0)
- nanopb/encode (= 3.30910.0)
- nanopb/decode (3.30910.0)
- nanopb/encode (3.30910.0)
- FlutterMacOS
- network_info_plus (0.0.1):
- Flutter
- objective_c (0.0.1):
@@ -109,7 +62,6 @@ PODS:
- FlutterMacOS
- pointer_interceptor_ios (0.0.1):
- Flutter
- PromisesObjC (2.4.0)
- SDWebImage (5.21.6):
- SDWebImage/Core (= 5.21.6)
- SDWebImage/Core (5.21.6)
@@ -155,9 +107,8 @@ DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
- flutter_timezone (from `.symlinks/plugins/flutter_timezone/ios`)
- in_app_review (from `.symlinks/plugins/in_app_review/ios`)
- mobile_scanner (from `.symlinks/plugins/mobile_scanner/ios`)
- mobile_scanner (from `.symlinks/plugins/mobile_scanner/darwin`)
- network_info_plus (from `.symlinks/plugins/network_info_plus/ios`)
- objective_c (from `.symlinks/plugins/objective_c/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
@@ -174,17 +125,6 @@ SPEC REPOS:
- DKImagePickerController
- DKPhotoGallery
- EasyPermissionX
- GoogleDataTransport
- GoogleMLKit
- GoogleToolboxForMac
- GoogleUtilities
- GTMSessionFetcher
- MLImage
- MLKitBarcodeScanning
- MLKitCommon
- MLKitVision
- nanopb
- PromisesObjC
- SDWebImage
- Sentry
- sqlite3
@@ -205,12 +145,10 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
flutter_native_splash:
:path: ".symlinks/plugins/flutter_native_splash/ios"
flutter_timezone:
:path: ".symlinks/plugins/flutter_timezone/ios"
in_app_review:
:path: ".symlinks/plugins/in_app_review/ios"
mobile_scanner:
:path: ".symlinks/plugins/mobile_scanner/ios"
:path: ".symlinks/plugins/mobile_scanner/darwin"
network_info_plus:
:path: ".symlinks/plugins/network_info_plus/ios"
objective_c:
@@ -243,25 +181,13 @@ SPEC CHECKSUMS:
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
flutter_native_splash: df59bb2e1421aa0282cb2e95618af4dcb0c56c29
flutter_timezone: ac3da59ac941ff1c98a2e1f0293420e020120282
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleMLKit: eff9e23ec1d90ea4157a1ee2e32a4f610c5b3318
GoogleToolboxForMac: d1a2cbf009c453f4d6ded37c105e2f67a32206d8
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6
in_app_review: a31b5257259646ea78e0e35fc914979b0031d011
MLImage: 0ad1c5f50edd027672d8b26b0fee78a8b4a0fc56
MLKitBarcodeScanning: 0a3064da0a7f49ac24ceb3cb46a5bc67496facd2
MLKitCommon: 07c2c33ae5640e5380beaaa6e4b9c249a205542d
MLKitVision: 45e79d68845a2de77e2dd4d7f07947f0ed157b0e
mobile_scanner: fd0054c52ede661e80bf5a4dea477a2467356bee
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
mobile_scanner: 77265f3dc8d580810e91849d4a0811a90467ed5e
network_info_plus: 6613d9d7cdeb0e6f366ed4dbe4b3c51c52d567a9
objective_c: 77e887b5ba1827970907e10e832eec1683f3431d
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
pointer_interceptor_ios: 508241697ff0947f853c061945a8b822463947c1
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
SDWebImage: 1bb6a1b84b6fe87b972a102bdc77dd589df33477
Sentry: da60d980b197a46db0b35ea12cb8f39af48d8854
sentry_flutter: 2df8b0aab7e4aba81261c230cbea31c82a62dd1b
+1 -29
View File
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 60;
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
@@ -413,8 +413,6 @@
dependencies = (
);
name = HiddifyPacketTunnel;
packageProductDependencies = (
);
productName = HiddifyPacketTunnel;
productReference = 03E392B62ADDA00E000ADF15 /* HiddifyPacketTunnel.appex */;
productType = "com.apple.product-type.app-extension";
@@ -450,7 +448,6 @@
FBEFD3291AEA65EDE2F5AEF6 /* [CP] Embed Pods Frameworks */,
97C146EB1CF9000F007C117D /* Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
738EC814CF019E6FA6F32C6B /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -582,27 +579,6 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n";
};
738EC814CF019E6FA6F32C6B /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
@@ -648,14 +624,10 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
@@ -1,5 +1,7 @@
import 'dart:io';
import 'package:hiddify/core/model/environment.dart';
import 'package:hiddify/utils/platform_utils.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:loggy/loggy.dart';
import 'package:path/path.dart' as p;
@@ -16,6 +18,7 @@ Future<SharedPreferences> sharedPreferences(Ref ref) async {
logger.debug("initializing preferences");
try {
if (PlatformUtils.isWindows && Environment.isPortable) SharedPreferences.setPrefix('portable.');
sharedPreferences = await SharedPreferences.getInstance();
} catch (e) {
logger.error("error initializing preferences", e);
+9 -7
View File
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:hiddify/core/model/region.dart';
import 'package:hiddify/core/preferences/actions_at_closing.dart';
import 'package:hiddify/core/router/dialog/widgets/action_at_closing_dialog.dart';
import 'package:hiddify/core/router/dialog/widgets/confirmation_dialog.dart';
@@ -10,7 +9,6 @@ import 'package:hiddify/core/router/dialog/widgets/new_version_dialog.dart';
import 'package:hiddify/core/router/dialog/widgets/no_active_profile_dialog.dart';
import 'package:hiddify/core/router/dialog/widgets/ok_dialog.dart';
import 'package:hiddify/core/router/dialog/widgets/proxy_info_dialog.dart';
import 'package:hiddify/core/router/dialog/widgets/region_dialog.dart';
import 'package:hiddify/core/router/dialog/widgets/save_dialog.dart';
import 'package:hiddify/core/router/dialog/widgets/setting_checkbox_dialog.dart';
import 'package:hiddify/core/router/dialog/widgets/setting_input_dialog.dart';
@@ -112,10 +110,6 @@ class DialogNotifier extends _$DialogNotifier {
false;
}
Future<Region?> showRegion({required Region selected}) async {
return await _show<Region?>(RegionDialog(selected: selected));
}
Future<ActionsAtClosing?> showActionAtClosing({required ActionsAtClosing selected}) async {
return await _show<ActionsAtClosing?>(ActionsAtClosingDialog(selected: selected));
}
@@ -216,13 +210,21 @@ class DialogNotifier extends _$DialogNotifier {
Future<T?> showSettingPicker<T>({
required String title,
bool showFlag = false,
required T selected,
required List<T> options,
required String Function(T e) getTitle,
VoidCallback? onReset,
}) async {
return await _show<T?>(
SettingPickerDialog(title: title, selected: selected, options: options, getTitle: getTitle, onReset: onReset),
SettingPickerDialog(
title: title,
showFlag: showFlag,
selected: selected,
options: options,
getTitle: getTitle,
onReset: onReset,
),
);
}
@@ -1,21 +0,0 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hiddify/core/localization/translations.dart';
import 'package:hiddify/core/model/region.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
class RegionDialog extends HookConsumerWidget {
const RegionDialog({super.key, required this.selected});
final Region selected;
@override
Widget build(BuildContext context, WidgetRef ref) {
final t = ref.watch(translationsProvider).requireValue;
return SimpleDialog(
title: Text(t.pages.settings.routing.region),
children: Region.values
.map((e) => RadioListTile(title: Text(e.present(t)), value: e, groupValue: selected, onChanged: context.pop))
.toList(),
);
}
}
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hiddify/core/localization/translations.dart';
import 'package:hiddify/features/proxy/active/ip_widget.dart';
import 'package:hiddify/utils/custom_loggers.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
@@ -8,6 +9,7 @@ class SettingPickerDialog<T> extends HookConsumerWidget with PresLogger {
const SettingPickerDialog({
super.key,
required this.title,
this.showFlag = false,
required this.selected,
required this.options,
required this.getTitle,
@@ -15,6 +17,7 @@ class SettingPickerDialog<T> extends HookConsumerWidget with PresLogger {
});
final String title;
final bool showFlag;
final T selected;
final List<T> options;
final String Function(T e) getTitle;
@@ -29,16 +32,17 @@ class SettingPickerDialog<T> extends HookConsumerWidget with PresLogger {
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: options
.map(
(e) => RadioListTile(
title: Text(getTitle(e)),
value: e,
groupValue: selected,
onChanged: (value) => context.pop(e),
),
)
.toList(),
children: options.map((e) {
final title = getTitle(e);
final countryCode = title.substring(title.length - 3, title.length - 1);
return RadioListTile(
title: Text(title),
secondary: showFlag ? IPCountryFlag(countryCode: countryCode, size: 32) : null,
value: e,
groupValue: selected,
onChanged: (value) => context.pop(e),
);
}).toList(),
),
),
actions: [
@@ -7,7 +7,6 @@ import 'package:hiddify/core/preferences/general_preferences.dart';
import 'package:hiddify/core/router/dialog/dialog_notifier.dart';
import 'package:hiddify/core/theme/app_theme_mode.dart';
import 'package:hiddify/core/theme/theme_preferences.dart';
import 'package:hiddify/features/settings/data/config_option_repository.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
class LocalePrefTile extends ConsumerWidget {
@@ -40,41 +39,6 @@ class LocalePrefTile extends ConsumerWidget {
}
}
class RegionPrefTile extends ConsumerWidget {
const RegionPrefTile({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final t = ref.watch(translationsProvider).requireValue;
final region = ref.watch(ConfigOptions.region);
return ListTile(
title: Text(t.pages.settings.routing.region),
subtitle: Text(region.present(t), style: Theme.of(context).textTheme.bodySmall),
leading: const Icon(Icons.place_rounded),
onTap: () async {
final selectedRegion = await ref.read(dialogNotifierProvider.notifier).showRegion(selected: region);
if (selectedRegion != null) {
// await ref.read(Preferences.region.notifier).update(selectedRegion);
await ref.watch(ConfigOptions.region.notifier).update(selectedRegion);
await ref.watch(ConfigOptions.directDnsAddress.notifier).reset();
// 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
}
},
);
}
}
class EnableAnalyticsPrefTile extends ConsumerWidget {
const EnableAnalyticsPrefTile({super.key, this.onChanged});
+195 -5
View File
@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
@@ -14,10 +15,10 @@ import 'package:hiddify/core/model/region.dart';
import 'package:hiddify/core/preferences/general_preferences.dart';
import 'package:hiddify/features/common/general_pref_tiles.dart';
import 'package:hiddify/features/settings/data/config_option_repository.dart';
import 'package:hiddify/features/settings/widget/preference_tile.dart';
import 'package:hiddify/gen/assets.gen.dart';
import 'package:hiddify/utils/utils.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:timezone_to_country/timezone_to_country.dart';
class IntroPage extends HookConsumerWidget with PresLogger {
const IntroPage({super.key});
@@ -94,7 +95,18 @@ class IntroPage extends HookConsumerWidget with PresLogger {
),
const Gap(24),
const LocalePrefTile(),
const RegionPrefTile(),
ChoicePreferenceWidget(
selected: ref.watch(ConfigOptions.region),
preferences: ref.watch(ConfigOptions.region.notifier),
choices: Region.values,
title: t.pages.settings.routing.region,
showFlag: true,
icon: Icons.place_rounded,
presentChoice: (value) => value.present(t),
onChanged: (val) async {
await ref.read(ConfigOptions.directDnsAddress.notifier).reset();
},
),
const EnableAnalyticsPrefTile(),
const Gap(24),
Focus(
@@ -182,7 +194,7 @@ class IntroPage extends HookConsumerWidget with PresLogger {
Future<void> autoSelectRegion(WidgetRef ref) async {
try {
final countryCode = await TimeZoneToCountry.getLocalCountryCode();
final countryCode = RegionDetector.detect();
final regionLocale = _getRegionLocale(countryCode);
loggy.debug('Timezone Region: ${regionLocale.region} Locale: ${regionLocale.locale}');
await ref.read(ConfigOptions.region.notifier).update(regionLocale.region);
@@ -227,9 +239,9 @@ class IntroPage extends HookConsumerWidget with PresLogger {
case "AF":
return RegionLocale(Region.af, AppLocale.fa);
case "BR":
return RegionLocale(Region.other, AppLocale.ptBr);
return RegionLocale(Region.br, AppLocale.ptBr);
case "TR":
return RegionLocale(Region.other, AppLocale.tr);
return RegionLocale(Region.tr, AppLocale.tr);
default:
return RegionLocale(Region.other, AppLocale.en);
}
@@ -242,3 +254,181 @@ class RegionLocale {
RegionLocale(this.region, this.locale);
}
class RegionDetector {
/// Returns: 'IR' | 'AF' | 'CN' | 'TR' | 'RU' | 'BR' | 'US'
static String detect() {
final now = DateTime.now();
final offset = now.timeZoneOffset.inMinutes;
final tz = now.timeZoneName.toLowerCase().trim();
if (offset == 210) return 'IR';
if (offset == 270) {
final (_, country) = _parseLocale();
return country == 'IR' ? 'IR' : 'AF';
}
final fromName = _fromTzName(tz, offset);
if (fromName != null) return fromName;
final candidates = _candidatesForOffset(offset);
if (candidates.isEmpty) return 'US';
return _resolveByLocale(candidates);
}
static String? _fromTzName(String tz, int offset) {
if (tz.contains('/')) {
final city = tz.split('/').last.replaceAll(' ', '_');
final r = _ianaCities[city];
if (r != null) return r;
}
if (tz == 'irst' || tz == 'irdt' || tz.contains('iran')) return 'IR';
if (tz == 'aft' || tz.contains('afghanistan')) return 'AF';
if (tz == 'trt' || tz.contains('turkey') || tz.contains('istanbul')) {
return 'TR';
}
if (tz.contains('china') || tz.contains('beijing')) return 'CN';
if (tz == 'cst' && offset == 480) return 'CN';
if (_matchesRussiaTz(tz)) return 'RU';
if (_matchesBrazilTz(tz)) return 'BR';
return null;
}
static bool _matchesRussiaTz(String tz) {
if (tz.contains('russia') || tz.contains('moscow')) return true;
const abbrs = {'msk', 'yekt', 'omst', 'krat', 'irkt', 'yakt', 'vlat', 'magt', 'pett', 'sakt', 'sret'};
if (abbrs.contains(tz)) return true;
const winKeys = [
'ekaterinburg',
'kaliningrad',
'yakutsk',
'vladivostok',
'magadan',
'sakhalin',
'kamchatka',
'astrakhan',
'saratov',
'volgograd',
'altai',
'tomsk',
'transbaikal',
'n. central asia',
'north asia',
];
return winKeys.any(tz.contains);
}
static bool _matchesBrazilTz(String tz) {
if (tz == 'brt' || tz == 'brst') return true;
if (tz.contains('brazil') || tz.contains('brasilia')) return true;
const winKeys = ['e. south america', 'central brazilian', 'tocantins', 'bahia'];
return winKeys.any(tz.contains);
}
static Set<String> _candidatesForOffset(int offset) {
final c = <String>{};
if (offset == 180) c.add('TR');
if (offset == 480) c.add('CN');
if (_ruOffsets.contains(offset)) c.add('RU');
if (_brOffsets.contains(offset)) c.add('BR');
return c;
}
static const _ruOffsets = {120, 180, 240, 300, 360, 420, 480, 540, 600, 660, 720};
static const _brOffsets = {-120, -180, -240, -300};
static String _resolveByLocale(Set<String> candidates) {
final (lang, country) = _parseLocale();
if (country != null && candidates.contains(country)) {
return country;
}
final regionFromLang = _langToRegion[lang];
if (regionFromLang != null && candidates.contains(regionFromLang)) {
return regionFromLang;
}
return 'US';
}
static (String, String?) _parseLocale() {
try {
final parts = Platform.localeName.split(RegExp(r'[_\-.]'));
final lang = parts.first.toLowerCase();
String? country;
for (final p in parts.skip(1)) {
if (p.length == 2) {
country = p.toUpperCase();
break;
}
}
return (lang, country);
} catch (_) {
return ('en', null);
}
}
static const _langToRegion = <String, String>{'fa': 'IR', 'ps': 'AF', 'tr': 'TR', 'zh': 'CN', 'ru': 'RU', 'pt': 'BR'};
static const _ianaCities = <String, String>{
'tehran': 'IR',
'kabul': 'AF',
'istanbul': 'TR',
'shanghai': 'CN',
'chongqing': 'CN',
'urumqi': 'CN',
'harbin': 'CN',
'moscow': 'RU',
'kaliningrad': 'RU',
'samara': 'RU',
'yekaterinburg': 'RU',
'omsk': 'RU',
'novosibirsk': 'RU',
'barnaul': 'RU',
'tomsk': 'RU',
'krasnoyarsk': 'RU',
'irkutsk': 'RU',
'chita': 'RU',
'yakutsk': 'RU',
'vladivostok': 'RU',
'magadan': 'RU',
'sakhalin': 'RU',
'kamchatka': 'RU',
'anadyr': 'RU',
'volgograd': 'RU',
'saratov': 'RU',
'astrakhan': 'RU',
'sao_paulo': 'BR',
'fortaleza': 'BR',
'recife': 'BR',
'manaus': 'BR',
'belem': 'BR',
'cuiaba': 'BR',
'bahia': 'BR',
'rio_branco': 'BR',
'noronha': 'BR',
'porto_velho': 'BR',
'campo_grande': 'BR',
};
}
@@ -46,6 +46,7 @@ class RouteOptionsPage extends HookConsumerWidget {
preferences: ref.watch(ConfigOptions.region.notifier),
choices: Region.values,
title: t.pages.settings.routing.region,
showFlag: true,
icon: Icons.place_rounded,
presentChoice: (value) => value.present(t),
onChanged: (val) async {
@@ -71,6 +71,7 @@ class ChoicePreferenceWidget<T> extends HookConsumerWidget {
this.enabled = true,
required this.choices,
required this.title,
this.showFlag = false,
this.icon,
required this.presentChoice,
this.validateInput,
@@ -82,6 +83,7 @@ class ChoicePreferenceWidget<T> extends HookConsumerWidget {
final bool enabled;
final List<T> choices;
final String title;
final bool showFlag;
final IconData? icon;
final String Function(T value) presentChoice;
final bool Function(String value)? validateInput;
@@ -98,6 +100,7 @@ class ChoicePreferenceWidget<T> extends HookConsumerWidget {
.read(dialogNotifierProvider.notifier)
.showSettingPicker<T>(
title: title,
showFlag: showFlag,
selected: selected,
options: choices,
getTitle: (e) => presentChoice(e),
@@ -7,7 +7,6 @@
#include "generated_plugin_registrant.h"
#include <dynamic_color/dynamic_color_plugin.h>
#include <flutter_timezone/flutter_timezone_plugin.h>
#include <gtk/gtk_plugin.h>
#include <screen_retriever_linux/screen_retriever_linux_plugin.h>
#include <sentry_flutter/sentry_flutter_plugin.h>
@@ -20,9 +19,6 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) dynamic_color_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin");
dynamic_color_plugin_register_with_registrar(dynamic_color_registrar);
g_autoptr(FlPluginRegistrar) flutter_timezone_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterTimezonePlugin");
flutter_timezone_plugin_register_with_registrar(flutter_timezone_registrar);
g_autoptr(FlPluginRegistrar) gtk_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin");
gtk_plugin_register_with_registrar(gtk_registrar);
-1
View File
@@ -4,7 +4,6 @@
list(APPEND FLUTTER_PLUGIN_LIST
dynamic_color
flutter_timezone
gtk
screen_retriever_linux
sentry_flutter
@@ -9,7 +9,6 @@ import app_links
import device_info_plus
import dynamic_color
import file_picker
import flutter_timezone
import in_app_review
import mobile_scanner
import network_info_plus
@@ -29,7 +28,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
FlutterTimezonePlugin.register(with: registry.registrar(forPlugin: "FlutterTimezonePlugin"))
InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin"))
MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin"))
NetworkInfoPlusPlugin.register(with: registry.registrar(forPlugin: "NetworkInfoPlusPlugin"))
-6
View File
@@ -10,8 +10,6 @@ PODS:
- FlutterMacOS
- file_picker (0.0.1):
- FlutterMacOS
- flutter_timezone (0.1.0):
- FlutterMacOS
- FlutterMacOS (1.0.0)
- in_app_review (2.0.0):
- FlutterMacOS
@@ -71,7 +69,6 @@ DEPENDENCIES:
- device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
- dynamic_color (from `Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos`)
- file_picker (from `Flutter/ephemeral/.symlinks/plugins/file_picker/macos`)
- flutter_timezone (from `Flutter/ephemeral/.symlinks/plugins/flutter_timezone/macos`)
- FlutterMacOS (from `Flutter/ephemeral`)
- in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`)
- mobile_scanner (from `Flutter/ephemeral/.symlinks/plugins/mobile_scanner/darwin`)
@@ -104,8 +101,6 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos
file_picker:
:path: Flutter/ephemeral/.symlinks/plugins/file_picker/macos
flutter_timezone:
:path: Flutter/ephemeral/.symlinks/plugins/flutter_timezone/macos
FlutterMacOS:
:path: Flutter/ephemeral
in_app_review:
@@ -143,7 +138,6 @@ SPEC CHECKSUMS:
device_info_plus: 1b14eed9bf95428983aed283a8d51cce3d8c4215
dynamic_color: 2eaa27267de1ca20d879fbd6e01259773fb1670f
file_picker: e716a70a9fe5fd9e09ebc922d7541464289443af
flutter_timezone: 62400baa441155f2a4144188648f2ff861649747
FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1
in_app_review: a6a031b9acd03c7d103e341aa334adf2c493fb93
mobile_scanner: 77265f3dc8d580810e91849d4a0811a90467ed5e
Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

+9 -4
View File
@@ -1,10 +1,15 @@
title: Hiddify
background: "background.png"
window:
size:
width: 600
height: 400
contents:
- x: 448
y: 344
- x: 440
y: 230
type: link
path: "/Applications"
- x: 192
y: 344
- x: 160
y: 230
type: file
path: Hiddify.app
-24
View File
@@ -721,14 +721,6 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_timezone:
dependency: transitive
description:
name: flutter_timezone
sha256: bc286cecb0366d88e6c4644e3962ebd1ce1d233abc658eb1e0cd803389f84b64
url: "https://pub.dev"
source: hosted
version: "4.1.0"
flutter_typeahead:
dependency: "direct main"
description:
@@ -1892,22 +1884,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.5"
timezone:
dependency: transitive
description:
name: timezone
sha256: ffc9d5f4d1193534ef051f9254063fa53d588609418c84299956c3db9383587d
url: "https://pub.dev"
source: hosted
version: "0.10.0"
timezone_to_country:
dependency: "direct main"
description:
name: timezone_to_country
sha256: c96ffcfbd92f56c1727c18166a73bc6973e47d0516a6989148f219414682948e
url: "https://pub.dev"
source: hosted
version: "3.0.0"
timing:
dependency: transitive
description:
-1
View File
@@ -85,7 +85,6 @@ dependencies:
cupertino_http: ^2.0.1
dart_mappable: ^4.2.1
fluentui_system_icons: ^1.1.229
timezone_to_country: ^3.0.0
json_path: ^0.7.1
# permission_handler: ^11.3.0 # is not compatible with windows
#flutter_easy_permission: ^1.1.2
@@ -8,7 +8,6 @@
#include <app_links/app_links_plugin_c_api.h>
#include <dynamic_color/dynamic_color_plugin_c_api.h>
#include <flutter_timezone/flutter_timezone_plugin_c_api.h>
#include <screen_retriever_windows/screen_retriever_windows_plugin_c_api.h>
#include <sentry_flutter/sentry_flutter_plugin.h>
#include <share_plus/share_plus_windows_plugin_c_api.h>
@@ -23,8 +22,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("AppLinksPluginCApi"));
DynamicColorPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
FlutterTimezonePluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterTimezonePluginCApi"));
ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ScreenRetrieverWindowsPluginCApi"));
SentryFlutterPluginRegisterWithRegistrar(
-1
View File
@@ -5,7 +5,6 @@
list(APPEND FLUTTER_PLUGIN_LIST
app_links
dynamic_color
flutter_timezone
screen_retriever_windows
sentry_flutter
share_plus
+1 -1
View File
@@ -1,6 +1,6 @@
display_name: Hiddify
publisher_display_name: Hiddify
identity_name: Hiddify.App
identity_name: Hiddify.HiddifyNext
msix_version: 4.0.5.0
logo_path: windows\runner\resources\app_icon.ico
capabilities: internetClient, internetClientServer, privateNetworkClientServer