diff --git a/.env.sample b/.env.sample
new file mode 100644
index 0000000..db332bb
--- /dev/null
+++ b/.env.sample
@@ -0,0 +1,2 @@
+SENTRY_DSN=
+ENABLE_SENTRY=false
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000..cf174cb
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,51 @@
+name: Report a bug
+description: |
+ You detected something wrong on the application.
+labels: ["bug"]
+body:
+ - type: textarea
+ id: steps
+ attributes:
+ label: Steps to reproduce
+ description: Steps to reproduce the problem you are running into.
+ placeholder: |
+ 1. ...
+ 2. ...
+ 3. ...
+ validations:
+ required: true
+ - type: textarea
+ id: expected-results
+ attributes:
+ label: Expected results
+ description: What is expected to happen.
+ validations:
+ required: true
+ - type: textarea
+ id: actual-results
+ attributes:
+ label: Actual results
+ description: What is actually happening.
+ validations:
+ required: true
+ - type: textarea
+ id: screenshots
+ attributes:
+ label: Screenshots or Video
+ description: |
+ Upload any screenshots or video of the bug.
+ value: |
+ Screenshots or video demonstration
+ validations:
+ required: true
+ - type: textarea
+ id: app-os-details
+ attributes:
+ label: App and OS details
+ description: |
+ Some details about the app version and the OS where you are running the application.
+ value: |
+ - App version: (eg: v2.16.0)
+ - Device OS version: (eg: Android 14)
+ validations:
+ required: true
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature_request_agh.yml b/.github/ISSUE_TEMPLATE/feature_request_agh.yml
new file mode 100644
index 0000000..55972db
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request_agh.yml
@@ -0,0 +1,32 @@
+name: Request a new feature that has been added to AdGuard Home
+description: |
+ The AdGuard Home team added recently a new feature that you want on the app.
+labels: ["agh feature request"]
+body:
+ - type: textarea
+ id: description
+ attributes:
+ label: Description
+ description: Describe the feature that you want on the app.
+ placeholder: |
+ Write the details here...
+ validations:
+ required: true
+ - type: textarea
+ id: screenshots
+ attributes:
+ label: Screenshots
+ description: Attach some screenshots of where that new feature is located on the web administration panel.
+ placeholder: |
+ Screenshots here.
+ validations:
+ required: true
+ - type: textarea
+ id: version-introduced
+ attributes:
+ label: Version where feature was introduced
+ description: Version of the AdGuard Home server where this feature was introduced.
+ placeholder: |
+ - Version: (eg: v0.107.44)
+ validations:
+ required: true
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature_request_app.yml b/.github/ISSUE_TEMPLATE/feature_request_app.yml
new file mode 100644
index 0000000..3cf08e6
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request_app.yml
@@ -0,0 +1,20 @@
+name: Request a new feature or an improvement for the app itself
+description: |
+ You want a new feature for the application, or an improvement for an existing one.
+labels: ["app feature request"]
+body:
+ - type: markdown
+ id: important-info
+ attributes:
+ value: |
+ ℹ️ IMPORTANT INFO ℹ️
+ Please note that if the functionality is related to data representation, it may not be implemented, as AdGuard Home Manager depends on the capabilities of the AdGuard Home API.
+ - type: textarea
+ id: description
+ attributes:
+ label: Description
+ description: Describe the feature that you want on the app.
+ placeholder: |
+ Write the details here...
+ validations:
+ required: true
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml
new file mode 100644
index 0000000..805783f
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/question.yml
@@ -0,0 +1,19 @@
+name: You have a question about the app
+description: |
+ You want ask something that's not related with a feature request or a bug.
+labels: ["question"]
+body:
+ - type: markdown
+ id: important-info
+ attributes:
+ value: |
+ Having problems while adding a connection to a server? Check out [this guide](https://github.com/JGeek00/adguard-home-manager/wiki/Create-a-connection).
+ - type: textarea
+ id: question
+ attributes:
+ label: Question
+ description: Write your question here giving the maximum detail possible.
+ placeholder: |
+ Write your question here...
+ validations:
+ required: true
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 24476c5..e9d1504 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,11 +5,16 @@
*.swp
.DS_Store
.atom/
+.build/
.buildlog/
.history
.svn/
+.swiftpm/
migrate_working_dir/
+# Env
+.env
+
# IntelliJ related
*.iml
*.ipr
@@ -42,3 +47,9 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
+
+/debian/packages
+
+untranslated.json
+
+android/app/.cxx
diff --git a/.metadata b/.metadata
index e27f5cc..656c923 100644
--- a/.metadata
+++ b/.metadata
@@ -4,7 +4,7 @@
# This file should be version controlled.
version:
- revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
+ revision: f72efea43c3013323d1b95cff571f3c1caa37583
channel: stable
project_type: app
@@ -13,26 +13,11 @@ project_type: app
migration:
platforms:
- platform: root
- create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
- base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
- - platform: android
- create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
- base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
- - platform: ios
- create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
- base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
+ create_revision: f72efea43c3013323d1b95cff571f3c1caa37583
+ base_revision: f72efea43c3013323d1b95cff571f3c1caa37583
- platform: linux
- create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
- base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
- - platform: macos
- create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
- base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
- - platform: web
- create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
- base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
- - platform: windows
- create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
- base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
+ create_revision: f72efea43c3013323d1b95cff571f3c1caa37583
+ base_revision: f72efea43c3013323d1b95cff571f3c1caa37583
# User provided section
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..fab9821
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,20 @@
+{
+ "editor.formatOnSave": false,
+ "editor.formatOnPaste": false,
+ "editor.formatOnType": false,
+ "editor.defaultFormatter": "Dart-Code.flutter",
+ "dart.lineLength": 120,
+ "[dart]": {
+ "editor.rulers": [
+ 120
+ ],
+ "editor.defaultFormatter": "Dart-Code.dart-code",
+ "editor.formatOnSave": false,
+ "editor.formatOnPaste": false,
+ "editor.formatOnType": false
+ },
+ "cSpell.ignorePaths": [
+ "/pubspec.yaml",
+ "/.github/workflows"
+ ],
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index aabbe0f..1dcbc67 100644
--- a/README.md
+++ b/README.md
@@ -30,13 +30,82 @@
▶ See the clients list and create a custom configuration for a client.
▶ Configure the allowed devices, DHCP, DNS or rewrites among others.
▶ Material You interface with dynamic theming (only Android 12+).
+▶ Full desktop support with builds for macOS, Linux and Windows.
+▶ Responsive UI adapted for landscape displays.
## Privacy policy
-AdGuard Home Manager does not collect any personal user data. All data stored into the application is kept on the user's device.
+Check the privacy policy [here](https://github.com/JGeek00/adguard-home-manager/wiki/Privacy-policy).
## Disclaimer
This is an unofficial application. The AdGuard Home team and the development of the AdGuard Home software is not related in any way with this application.
+## Recommended configuration and lists
+On [this repository](https://github.com/juanico10/Pihole_list) you can find a recommended configuration for AdGuard Home and some lists. Thanks to [juanico10](https://github.com/juanico10).
+
+## Donations
+If you like the project and you want to contribute with the development, you can [become a sponsor on GitHub](https://github.com/sponsors/JGeek00), or you can donate using PayPal.
+
+
+
+## Generate production build
+
+ -
+ Prerequisites
+
+ - Open
pubspec.yaml
and change the version name and the version number.
+ - Run
flutter clean
.
+ - Run
flutter pub get
.
+
+
+ -
+ Android
+
+ - Make sure you have your
key.properties
file at android/
, with all the required values of your signing key correctly set up.
+ - Make sure you have your keystore file at
android/app
.
+ - Run
flutter build apk --release
to compile the APK.
+ - The .apk package is located at
build/app/outputs/flutter-apk/app-release.apk
.
+
+
+ -
+ macOS
+
+ - Run
flutter build macos --release
to compile the production build.
+ - The .app package is located at
build/macos/Build/Products/Release/AdGuard Home Manager.app
.
+
+
+ -
+ Linux
+
+ Prerequisites
+
+ - Install rps by running
dart pub global activate rps --version 0.7.0-dev.6
+
+ Build
+
+ - Open
debian.yaml
file inside debian/ and update the version number
+ - run
rps build linux
+ - The .tar.gz is at
build/linux/x64/release/bundle
+ - The .deb package is at
build/linux/x64/release/debian/
+
+
+
+ -
+ Windows
+
+ - Run
flutter build windows --release
.
+ - Open Inno Setup Compiler application and load the script
+ - The script is located at
windows/innosetup_installer_builder.iss
+ - Update the version number and save the changes
+ - Click on the Compile button
+ - The installer will be generated at
build/windows/aghm_installer.exe
.
+
+
+
+
## Third party libraries
- [provider](https://pub.dev/packages/provider)
- [sqflite](https://pub.dev/packages/sqflite)
@@ -44,7 +113,6 @@ This is an unofficial application. The AdGuard Home team and the development of
- [expandable](https://pub.dev/packages/expandable)
- [package info plus](https://pub.dev/packages/package_info_plus)
- [flutter phoenix](https://pub.dev/packages/flutter_phoenix)
-- [flutter displaymode](https://pub.dev/packages/flutter_displaymode)
- [flutter launcher icons](https://pub.dev/packages/flutter_launcher_icons)
- [flutter native splash](https://pub.dev/packages/flutter_native_splash)
- [intl](https://pub.dev/packages/intl)
@@ -52,12 +120,28 @@ This is an unofficial application. The AdGuard Home team and the development of
- [dynamic color](https://pub.dev/packages/dynamic_color)
- [device info](https://pub.dev/packages/device_info)
- [fl chart](https://pub.dev/packages/fl_chart)
-- [flutter web browser](https://pub.dev/packages/flutter_web_browser)
- [flutter svg](https://pub.dev/packages/flutter_svg)
-- [bottom sheet](https://pub.dev/packages/bottom_sheet)
- [percent indicator](https://pub.dev/packages/percent_indicator)
-- [store checker](https://pub.dev/packages/store_checker)
+- [flutter markdown](https://pub.dev/packages/flutter_markdown)
+- [markdown](https://pub.dev/packages/markdown)
+- [html](https://pub.dev/packages/html)
+- [flutter html](https://pub.dev/packages/flutter_html)
+- [sqlite3 flutter libs](https://pub.dev/packages/sqlite3_flutter_libs)
+- [sqflite common ffi](https://pub.dev/packages/sqflite_common_ffi)
+- [window size](https://github.com/google/flutter-desktop-embedding)
+- [flutter split view](https://github.com/JGeek00/flutter_split_view) (forked from [here](https://pub.dev/packages/flutter_split_view))
+- [async](https://pub.dev/packages/async)
+- [sentry flutter](https://pub.dev/packages/sentry_flutter)
+- [flutter dotenv](https://pub.dev/packages/flutter_dotenv)
+- [flutter reorderable list](https://pub.dev/packages/flutter_reorderable_list)
+- [pie chart](https://pub.dev/packages/pie_chart)
+- [segmented button slide](https://pub.dev/packages/segmented_button_slide)
+- [timezone](https://pub.dev/packages/timezone)
+- [url launcher](https://pub.dev/packages/url_launcher)
+- [flutter custom tabs](https://pub.dev/packages/flutter_custom_tabs)
+- [shared preferences](https://pub.dev/packages/shared_preferences)
+- [window manager](https://pub.dev/packages/window_manager)
-##### Created by JGeek00
\ No newline at end of file
+##### Created by JGeek00
diff --git a/android/app/build.gradle b/android/app/build.gradle
index d93673c..ab6291c 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -1,3 +1,9 @@
+plugins {
+ id "com.android.application"
+ id "kotlin-android"
+ id "dev.flutter.flutter-gradle-plugin"
+}
+
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
@@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
}
}
-def flutterRoot = localProperties.getProperty('flutter.sdk')
-if (flutterRoot == null) {
- throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
-}
-
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
@@ -21,13 +22,16 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+def keystoreProperties = new Properties()
+def keystorePropertiesFile = rootProject.file('key.properties')
+if (keystorePropertiesFile.exists()) {
+ keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
+}
android {
- compileSdkVersion 33
- ndkVersion flutter.ndkVersion
+ namespace "com.jgeek00.adguard_home_manager"
+ compileSdkVersion 35
+ ndkVersion "26.1.10909125"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
@@ -43,21 +47,25 @@ android {
}
defaultConfig {
- // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.jgeek00.adguard_home_manager"
- // You can update the following values to match your application needs.
- // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
minSdkVersion 26
- targetSdkVersion 33
+ targetSdkVersion 35
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
+ signingConfigs {
+ release {
+ keyAlias keystoreProperties['keyAlias']
+ keyPassword keystoreProperties['keyPassword']
+ storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
+ storePassword keystoreProperties['storePassword']
+ }
+ }
+
buildTypes {
release {
- // TODO: Add your own signing config for the release build.
- // Signing with the debug keys for now, so `flutter run --release` works.
- signingConfig signingConfigs.debug
+ signingConfig signingConfigs.release
}
}
}
@@ -67,5 +75,5 @@ flutter {
}
dependencies {
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20"
}
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index dbe31f9..603fecc 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -15,7 +15,8 @@
android:label="AdGuard Home Manager"
android:name="${applicationName}"
android:requestLegacyExternalStorage="true"
- android:icon="@mipmap/ic_launcher">
+ android:icon="@mipmap/ic_launcher"
+ android:enableOnBackInvokedCallback="true">
-
-
+
+
-
+
\ No newline at end of file
diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..036d09b
--- /dev/null
+++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 620121e..0000000
Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..ee4fa4d
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..4d52a73
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..ee4fa4d
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 4b33d20..0000000
Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..2ae3642
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..8a39f50
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..2ae3642
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 3128163..0000000
Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..1c206bb
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..e490246
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1c206bb
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 7eb67dc..0000000
Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aefe0b6
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..3599460
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..aefe0b6
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 7eadefb..0000000
Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..68173f9
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..7d57305
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..68173f9
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml
deleted file mode 100644
index ab98328..0000000
--- a/android/app/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- #ffffff
-
\ No newline at end of file
diff --git a/android/app/src/main/res/values/ic_launcher_background.xml b/android/app/src/main/res/values/ic_launcher_background.xml
new file mode 100644
index 0000000..c5d5899
--- /dev/null
+++ b/android/app/src/main/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #FFFFFF
+
\ No newline at end of file
diff --git a/android/build.gradle b/android/build.gradle
index 61a47e7..bc157bd 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -1,16 +1,3 @@
-buildscript {
- ext.kotlin_version = '1.6.10'
- repositories {
- google()
- mavenCentral()
- }
-
- dependencies {
- classpath 'com.android.tools.build:gradle:7.2.2'
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- }
-}
-
allprojects {
repositories {
google()
@@ -26,6 +13,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
-task clean(type: Delete) {
+tasks.register("clean", Delete) {
delete rootProject.buildDir
}
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
index cb24abd..19cfad9 100644
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
diff --git a/android/key.properties.sample b/android/key.properties.sample
new file mode 100644
index 0000000..b51dc2c
--- /dev/null
+++ b/android/key.properties.sample
@@ -0,0 +1,4 @@
+storePassword= # keystore password #
+keyPassword= # keystore key password #
+keyAlias= # key alias #
+storeFile= # ./keystore-file-name.jks #
\ No newline at end of file
diff --git a/android/settings.gradle b/android/settings.gradle
index 44e62bc..e8481f5 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -1,11 +1,26 @@
-include ':app'
+pluginManagement {
+ def flutterSdkPath = {
+ def properties = new Properties()
+ file("local.properties").withInputStream { properties.load(it) }
+ def flutterSdkPath = properties.getProperty("flutter.sdk")
+ assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+ return flutterSdkPath
+ }
+ settings.ext.flutterSdkPath = flutterSdkPath()
-def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
-def properties = new Properties()
+ includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
-assert localPropertiesFile.exists()
-localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
-def flutterSdkPath = properties.getProperty("flutter.sdk")
-assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
-apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
+plugins {
+ id "dev.flutter.flutter-plugin-loader" version "1.0.0"
+ id "com.android.application" version '8.6.0' apply false
+ id "org.jetbrains.kotlin.android" version "1.8.20" apply false
+}
+
+include ":app"
diff --git a/assets/icon/icon-circle-256.png b/assets/icon/icon-circle-256.png
new file mode 100644
index 0000000..517e26a
Binary files /dev/null and b/assets/icon/icon-circle-256.png differ
diff --git a/assets/icon/icon-circle.ico b/assets/icon/icon-circle.ico
new file mode 100644
index 0000000..e4da1bd
Binary files /dev/null and b/assets/icon/icon-circle.ico differ
diff --git a/assets/icon/icon-circle.png b/assets/icon/icon-circle.png
new file mode 100644
index 0000000..5b39396
Binary files /dev/null and b/assets/icon/icon-circle.png differ
diff --git a/assets/icon/icon-macos.png b/assets/icon/icon-macos.png
new file mode 100755
index 0000000..c201d70
Binary files /dev/null and b/assets/icon/icon-macos.png differ
diff --git a/assets/screenshots/linux/clients.png b/assets/screenshots/linux/clients.png
new file mode 100644
index 0000000..5804d46
Binary files /dev/null and b/assets/screenshots/linux/clients.png differ
diff --git a/assets/screenshots/linux/home.png b/assets/screenshots/linux/home.png
new file mode 100644
index 0000000..6666046
Binary files /dev/null and b/assets/screenshots/linux/home.png differ
diff --git a/assets/screenshots/linux/logs.png b/assets/screenshots/linux/logs.png
new file mode 100644
index 0000000..2cf184f
Binary files /dev/null and b/assets/screenshots/linux/logs.png differ
diff --git a/debian/compile_deb.txt b/debian/compile_deb.txt
new file mode 100644
index 0000000..4a18706
--- /dev/null
+++ b/debian/compile_deb.txt
@@ -0,0 +1 @@
+https://pub.dev/packages/flutter_to_debian
\ No newline at end of file
diff --git a/debian/debian.yaml b/debian/debian.yaml
new file mode 100644
index 0000000..43a90f9
--- /dev/null
+++ b/debian/debian.yaml
@@ -0,0 +1,14 @@
+flutter_app:
+ command: AdGuardHomeManager
+ arch: x64
+ parent: /usr/local/lib
+
+control:
+ Package: AdGuardHomeManager
+ Version: 2.20.1
+ Architecture: amd64
+ Essential: no
+ Priority: optional
+ Depends:
+ Maintainer: JGeek00
+ Description: AdGuard Home control app
\ No newline at end of file
diff --git a/debian/gui/adguard-home-manager.desktop b/debian/gui/adguard-home-manager.desktop
new file mode 100644
index 0000000..a011591
--- /dev/null
+++ b/debian/gui/adguard-home-manager.desktop
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Name=AdGuard Home Manager
+Comment=Manage your AdGuard Home server
+Exec=adguard-home-manager
+Icon=${SNAP}/meta/gui/adguard-home-manager.png
+Terminal=false
+Type=Application
+Categories=Utilities;
diff --git a/debian/gui/adguard-home-manager.png b/debian/gui/adguard-home-manager.png
new file mode 100644
index 0000000..5b39396
Binary files /dev/null and b/debian/gui/adguard-home-manager.png differ
diff --git a/devtools_options.yaml b/devtools_options.yaml
new file mode 100644
index 0000000..7e7e7f6
--- /dev/null
+++ b/devtools_options.yaml
@@ -0,0 +1 @@
+extensions:
diff --git a/ios/.gitignore b/ios/.gitignore
old mode 100644
new mode 100755
diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist
old mode 100644
new mode 100755
index 9625e10..7c56964
--- a/ios/Flutter/AppFrameworkInfo.plist
+++ b/ios/Flutter/AppFrameworkInfo.plist
@@ -21,6 +21,6 @@
CFBundleVersion
1.0
MinimumOSVersion
- 11.0
+ 12.0
diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig
old mode 100644
new mode 100755
diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig
old mode 100644
new mode 100755
diff --git a/ios/Podfile b/ios/Podfile
old mode 100644
new mode 100755
index 88359b2..279576f
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
-# platform :ios, '11.0'
+# platform :ios, '12.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 9a238fd..2c2d827 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -2,60 +2,91 @@ PODS:
- device_info_plus (0.0.1):
- Flutter
- Flutter (1.0.0)
+ - flutter_custom_tabs_ios (2.0.0):
+ - Flutter
- flutter_native_splash (0.0.1):
- Flutter
- - flutter_web_browser (0.17.1):
- - Flutter
- - FMDB (2.7.5):
- - FMDB/standard (= 2.7.5)
- - FMDB/standard (2.7.5)
- package_info_plus (0.4.5):
- Flutter
- - sqflite (0.0.2):
+ - Sentry/HybridSDK (8.18.0):
+ - SentryPrivate (= 8.18.0)
+ - sentry_flutter (0.0.1):
- Flutter
- - FMDB (>= 2.7.5)
+ - FlutterMacOS
+ - Sentry/HybridSDK (= 8.18.0)
+ - SentryPrivate (8.18.0)
+ - sqflite (0.0.3):
+ - Flutter
+ - FlutterMacOS
+ - sqlite3 (3.45.0):
+ - sqlite3/common (= 3.45.0)
+ - sqlite3/common (3.45.0)
+ - sqlite3/fts5 (3.45.0):
+ - sqlite3/common
+ - sqlite3/perf-threadsafe (3.45.0):
+ - sqlite3/common
+ - sqlite3/rtree (3.45.0):
+ - sqlite3/common
+ - sqlite3_flutter_libs (0.0.1):
+ - Flutter
+ - sqlite3 (~> 3.45.0)
+ - sqlite3/fts5
+ - sqlite3/perf-threadsafe
+ - sqlite3/rtree
- store_checker (0.0.1):
- Flutter
DEPENDENCIES:
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- Flutter (from `Flutter`)
+ - flutter_custom_tabs_ios (from `.symlinks/plugins/flutter_custom_tabs_ios/ios`)
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
- - flutter_web_browser (from `.symlinks/plugins/flutter_web_browser/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- - sqflite (from `.symlinks/plugins/sqflite/ios`)
+ - sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
+ - sqflite (from `.symlinks/plugins/sqflite/darwin`)
+ - sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/ios`)
- store_checker (from `.symlinks/plugins/store_checker/ios`)
SPEC REPOS:
trunk:
- - FMDB
+ - Sentry
+ - SentryPrivate
+ - sqlite3
EXTERNAL SOURCES:
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
Flutter:
:path: Flutter
+ flutter_custom_tabs_ios:
+ :path: ".symlinks/plugins/flutter_custom_tabs_ios/ios"
flutter_native_splash:
:path: ".symlinks/plugins/flutter_native_splash/ios"
- flutter_web_browser:
- :path: ".symlinks/plugins/flutter_web_browser/ios"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
+ sentry_flutter:
+ :path: ".symlinks/plugins/sentry_flutter/ios"
sqflite:
- :path: ".symlinks/plugins/sqflite/ios"
+ :path: ".symlinks/plugins/sqflite/darwin"
+ sqlite3_flutter_libs:
+ :path: ".symlinks/plugins/sqlite3_flutter_libs/ios"
store_checker:
:path: ".symlinks/plugins/store_checker/ios"
SPEC CHECKSUMS:
- device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
- Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
+ device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
+ Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
+ flutter_custom_tabs_ios: 62439c843b2691aae516fd50119a01eb9755fff7
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
- flutter_web_browser: 7bccaafbb0c5b8862afe7bcd158f15557109f61f
- FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
- package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
- sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
+ package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85
+ Sentry: 8984a4ffb2b9bd2894d74fb36e6f5833865bc18e
+ sentry_flutter: c87a0556eeb6cbf7f9f924d30e878bdedf22d364
+ SentryPrivate: 2f0c9ba4c3fc993f70eab6ca95673509561e0085
+ sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
+ sqlite3: f307b6291c4db7b5086c38d6237446b98a738581
+ sqlite3_flutter_libs: aeb4d37509853dfa79d9b59386a2dac5dd079428
store_checker: 359c5051d9ec30ff0a8fa39eb5ec9df021bb745d
-PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
+PODFILE CHECKSUM: c4c93c5f6502fe2754f48404d3594bf779584011
-COCOAPODS: 1.11.2
+COCOAPODS: 1.14.3
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
old mode 100644
new mode 100755
index 1ffa568..00edeae
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -68,7 +68,6 @@
65533F0C0783FDE34AE79B0A /* Pods-Runner.release.xcconfig */,
69C2CC4A6DE17506FC5C0F13 /* Pods-Runner.profile.xcconfig */,
);
- name = Pods;
path = Pods;
sourceTree = "";
};
@@ -156,7 +155,8 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 1300;
+ BuildIndependentTargetsInParallel = YES;
+ LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
@@ -222,6 +222,7 @@
files = (
);
inputPaths = (
+ "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
@@ -324,6 +325,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -334,6 +336,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -342,7 +345,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@@ -360,15 +363,22 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 38Z3B9TJTR;
ENABLE_BITCODE = NO;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
INFOPLIST_FILE = Runner/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = "AdGuard Home";
+ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = com.example.adguardHomeManager;
+ PRODUCT_BUNDLE_IDENTIFIER = com.jgeek00.adguardHomeManager;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
@@ -396,6 +406,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -406,6 +417,7 @@
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@@ -420,7 +432,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -451,6 +463,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -461,6 +474,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -469,7 +483,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@@ -489,16 +503,23 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 38Z3B9TJTR;
ENABLE_BITCODE = NO;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
INFOPLIST_FILE = Runner/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = "AdGuard Home";
+ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = com.example.adguardHomeManager;
+ PRODUCT_BUNDLE_IDENTIFIER = com.jgeek00.adguardHomeManager;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
@@ -512,15 +533,22 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 38Z3B9TJTR;
ENABLE_BITCODE = NO;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
INFOPLIST_FILE = Runner/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = "AdGuard Home";
+ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = com.example.adguardHomeManager;
+ PRODUCT_BUNDLE_IDENTIFIER = com.jgeek00.adguardHomeManager;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
old mode 100644
new mode 100755
diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
old mode 100644
new mode 100755
diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
old mode 100644
new mode 100755
diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
old mode 100644
new mode 100755
index c87d15a..a6b826d
--- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -1,6 +1,6 @@
-
- CFBundleDevelopmentRegion
- $(DEVELOPMENT_LANGUAGE)
- CFBundleDisplayName
- AdGuard Home Manager
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- adguard_home_manager
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- $(FLUTTER_BUILD_NAME)
- CFBundleSignature
- ????
- CFBundleVersion
- $(FLUTTER_BUILD_NUMBER)
- LSRequiresIPhoneOS
-
- UILaunchStoryboardName
- LaunchScreen
- UIMainStoryboardFile
- Main
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- UISupportedInterfaceOrientations~ipad
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- UIViewControllerBasedStatusBarAppearance
-
- CADisableMinimumFrameDurationOnPhone
-
- UIApplicationSupportsIndirectInputEvents
-
- UIStatusBarHidden
-
-
+
+ CADisableMinimumFrameDurationOnPhone
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleDisplayName
+ AdGuard Home
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ adguardHomeManager
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(FLUTTER_BUILD_NAME)
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ $(FLUTTER_BUILD_NUMBER)
+ LSRequiresIPhoneOS
+
+ UIApplicationSupportsIndirectInputEvents
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UIViewControllerBasedStatusBarAppearance
+
+
diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h
old mode 100644
new mode 100755
diff --git a/l10n.yaml b/l10n.yaml
index 4e6692e..764d005 100644
--- a/l10n.yaml
+++ b/l10n.yaml
@@ -1,3 +1,4 @@
arb-dir: lib/l10n
template-arb-file: app_en.arb
-output-localization-file: app_localizations.dart
\ No newline at end of file
+output-localization-file: app_localizations.dart
+untranslated-messages-file: untranslated.json
\ No newline at end of file
diff --git a/lib/base.dart b/lib/base.dart
deleted file mode 100644
index 327b6ca..0000000
--- a/lib/base.dart
+++ /dev/null
@@ -1,144 +0,0 @@
-// ignore_for_file: use_build_context_synchronously, depend_on_referenced_packages
-
-import 'dart:async';
-
-import 'package:flutter/material.dart';
-import 'package:animations/animations.dart';
-import 'package:flutter_web_browser/flutter_web_browser.dart';
-import 'package:provider/provider.dart';
-import 'package:store_checker/store_checker.dart';
-import 'package:flutter/services.dart';
-
-import 'package:adguard_home_manager/widgets/bottom_nav_bar.dart';
-import 'package:adguard_home_manager/widgets/update_modal.dart';
-
-import 'package:adguard_home_manager/providers/app_config_provider.dart';
-import 'package:adguard_home_manager/models/github_release.dart';
-import 'package:adguard_home_manager/services/http_requests.dart';
-import 'package:adguard_home_manager/models/app_screen.dart';
-import 'package:adguard_home_manager/config/app_screens.dart';
-import 'package:adguard_home_manager/providers/servers_provider.dart';
-
-class Base extends StatefulWidget {
- final AppConfigProvider appConfigProvider;
-
- const Base({
- Key? key,
- required this.appConfigProvider,
- }) : super(key: key);
-
- @override
- State createState() => _BaseState();
-}
-
-class _BaseState extends State with WidgetsBindingObserver {
- int selectedScreen = 0;
-
- bool updateExists(String appVersion, String gitHubVersion) {
- final List appVersionSplit = List.from(appVersion.split('.').map((e) => int.parse(e)));
- final List gitHubVersionSplit = List.from(gitHubVersion.split('.').map((e) => int.parse(e)));
-
- if (gitHubVersionSplit[0] > appVersionSplit[0]) {
- return true;
- }
- else if (gitHubVersionSplit[0] == appVersionSplit[0] && gitHubVersionSplit[1] > appVersionSplit[1]) {
- return true;
- }
- else if (gitHubVersionSplit[0] == appVersionSplit[0] && gitHubVersionSplit[1] == appVersionSplit[1] && gitHubVersionSplit[2] > appVersionSplit[2]) {
- return true;
- }
- else {
- return false;
- }
- }
-
- Future checkInstallationSource() async {
- Source installationSource = await StoreChecker.getSource;
- if (installationSource != Source.IS_INSTALLED_FROM_PLAY_STORE) {
- final result = await checkAppUpdatesGitHub();
- if (result['result'] == 'success') {
- if (updateExists(widget.appConfigProvider.getAppInfo!.version, result['body'].tagName)) {
- return result['body'];
- }
- }
- }
- return null;
- }
-
- void download(String link, String version) async {
- FlutterWebBrowser.openWebPage(
- url: link,
- customTabsOptions: const CustomTabsOptions(
- instantAppsEnabled: true,
- showTitle: true,
- urlBarHidingEnabled: false,
- ),
- safariVCOptions: const SafariViewControllerOptions(
- barCollapsingEnabled: true,
- dismissButtonStyle: SafariViewControllerDismissButtonStyle.close,
- modalPresentationCapturesStatusBarAppearance: true,
- )
- );
- }
-
- @override
- void initState() {
- WidgetsBinding.instance.addObserver(this);
-
- super.initState();
-
- WidgetsBinding.instance.addPostFrameCallback((_) async {
- final result = await checkInstallationSource();
-
- if (result != null && widget.appConfigProvider.doNotRememberVersion != result.tagName) {
- await showDialog(
- context: context,
- builder: (context) => UpdateModal(
- gitHubRelease: result,
- onDownload: download,
- ),
- );
- }
- });
- }
-
- @override
- Widget build(BuildContext context) {
- final serversProvider = Provider.of(context);
- final appConfigProvider = Provider.of(context);
-
- List screens = serversProvider.selectedServer != null
- ? screensServerConnected
- : screensSelectServer;
-
- return AnnotatedRegion(
- value: SystemUiOverlayStyle(
- statusBarColor: Colors.transparent,
- statusBarBrightness: Theme.of(context).brightness == Brightness.light
- ? Brightness.light
- : Brightness.dark,
- statusBarIconBrightness: Theme.of(context).brightness == Brightness.light
- ? Brightness.dark
- : Brightness.light,
- systemNavigationBarColor: Theme.of(context).scaffoldBackgroundColor,
- systemNavigationBarIconBrightness: Theme.of(context).brightness == Brightness.light
- ? Brightness.dark
- : Brightness.light,
- ),
- child: Scaffold(
- body: PageTransitionSwitcher(
- duration: const Duration(milliseconds: 200),
- transitionBuilder: (
- (child, primaryAnimation, secondaryAnimation) => FadeThroughTransition(
- animation: primaryAnimation,
- secondaryAnimation: secondaryAnimation,
- child: child,
- )
- ),
- child: screens[appConfigProvider.selectedScreen].body,
- ),
- bottomNavigationBar: const BottomNavBar(),
- )
- );
- }
-}
\ No newline at end of file
diff --git a/lib/classes/http_client.dart b/lib/classes/http_client.dart
new file mode 100644
index 0000000..d64e1d1
--- /dev/null
+++ b/lib/classes/http_client.dart
@@ -0,0 +1,216 @@
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:adguard_home_manager/models/server.dart';
+
+enum ExceptionType { socket, timeout, handshake, http, unknown }
+
+class HttpResponse {
+ final bool successful;
+ final String? body;
+ final int? statusCode;
+ final ExceptionType? exception;
+
+ const HttpResponse({
+ required this.successful,
+ required this.body,
+ required this.statusCode,
+ this.exception,
+ });
+}
+
+String getConnectionString({
+ required Server server,
+ required String urlPath,
+}) {
+ return "${server.connectionMethod}://${server.domain}${server.port != null ? ':${server.port}' : ""}${server.path ?? ""}/control$urlPath";
+}
+
+class HttpRequestClient {
+ static Future get({
+ required String urlPath,
+ required Server server,
+ int timeout = 10,
+ }) async{
+ final String connectionString = getConnectionString(server: server, urlPath: urlPath);
+ try {
+ HttpClient httpClient = HttpClient();
+ HttpClientRequest request = await httpClient.getUrl(Uri.parse(connectionString));
+ if (server.authToken != null) {
+ request.headers.set('Authorization', 'Basic ${server.authToken}');
+ }
+ HttpClientResponse response = await request.close().timeout(
+ Duration(seconds: timeout)
+ );
+ String reply = await response.transform(utf8.decoder).join();
+ httpClient.close();
+ return HttpResponse(
+ successful: response.statusCode >= 400 ? false : true,
+ body: reply,
+ statusCode: response.statusCode
+ );
+ } on SocketException {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.socket
+ );
+ } on TimeoutException {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.timeout
+ );
+ } on HandshakeException {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.handshake
+ );
+ } on HttpException {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.http
+ );
+ } catch (e) {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.unknown
+ );
+ }
+ }
+
+ static Future post({
+ required String urlPath,
+ required Server server,
+ dynamic body,
+ int timeout = 10,
+ }) async{
+ final String connectionString = getConnectionString(server: server, urlPath: urlPath);
+ try {
+ HttpClient httpClient = HttpClient();
+ HttpClientRequest request = await httpClient.postUrl(Uri.parse(connectionString));
+ if (server.authToken != null) {
+ request.headers.set('Authorization', 'Basic ${server.authToken}');
+ }
+ request.headers.set('content-type', 'application/json');
+ request.add(utf8.encode(json.encode(body)));
+ HttpClientResponse response = await request.close().timeout(
+ Duration(seconds: timeout)
+ );
+ String reply = await response.transform(utf8.decoder).join();
+ httpClient.close();
+ return HttpResponse(
+ successful: response.statusCode >= 400 ? false : true,
+ body: reply,
+ statusCode: response.statusCode
+ );
+ } on SocketException {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.socket
+ );
+ } on TimeoutException {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.timeout
+ );
+ } on HttpException {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.http
+ );
+ } on HandshakeException {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.handshake
+ );
+ } catch (e) {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.unknown
+ );
+ }
+ }
+
+ static Future put({
+ required String urlPath,
+ required Server server,
+ dynamic body,
+ int timeout = 10,
+ }) async{
+ final String connectionString = getConnectionString(server: server, urlPath: urlPath);
+ try {
+ HttpClient httpClient = HttpClient();
+ HttpClientRequest request = await httpClient.putUrl(Uri.parse(connectionString));
+ if (server.authToken != null) {
+ request.headers.set('Authorization', 'Basic ${server.authToken}');
+ }
+ request.headers.set('content-type', 'application/json');
+ request.add(utf8.encode(json.encode(body)));
+ HttpClientResponse response = await request.close().timeout(
+ Duration(seconds: timeout)
+ );
+ String reply = await response.transform(utf8.decoder).join();
+ httpClient.close();
+ return HttpResponse(
+ successful: response.statusCode >= 400 ? false : true,
+ body: reply,
+ statusCode: response.statusCode
+ );
+ } on SocketException {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.socket
+ );
+ } on TimeoutException {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.timeout
+ );
+ } on HttpException {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.http
+ );
+ } on HandshakeException {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.handshake
+ );
+ } catch (e) {
+ return const HttpResponse(
+ successful: false,
+ body: null,
+ statusCode: null,
+ exception: ExceptionType.unknown
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/classes/process_modal.dart b/lib/classes/process_modal.dart
index 6febebb..ac3db92 100644
--- a/lib/classes/process_modal.dart
+++ b/lib/classes/process_modal.dart
@@ -1,20 +1,14 @@
+import 'package:adguard_home_manager/config/globals.dart';
import 'package:flutter/material.dart';
import 'package:adguard_home_manager/widgets/process_dialog.dart';
class ProcessModal {
- late BuildContext context;
-
- ProcessModal({
- required this.context
- });
-
void open(String message) async {
await Future.delayed(const Duration(seconds: 0), () => {
showDialog(
- context: context,
- builder: (c) {
- context = c;
+ context: globalNavigatorKey.currentContext!,
+ builder: (ctx) {
return ProcessDialog(
message: message,
);
@@ -26,6 +20,6 @@ class ProcessModal {
}
void close() {
- Navigator.pop(context);
+ Navigator.pop(globalNavigatorKey.currentContext!);
}
}
\ No newline at end of file
diff --git a/lib/config/app_screens.dart b/lib/config/app_screens.dart
index 1835dc4..2326e31 100644
--- a/lib/config/app_screens.dart
+++ b/lib/config/app_screens.dart
@@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
-import 'package:adguard_home_manager/screens/filters/filters.dart';
-import 'package:adguard_home_manager/screens/logs/logs.dart';
-import 'package:adguard_home_manager/screens/connect/connect.dart';
-import 'package:adguard_home_manager/screens/home/home.dart';
import 'package:adguard_home_manager/screens/clients/clients.dart';
+import 'package:adguard_home_manager/screens/connect/connect.dart';
+import 'package:adguard_home_manager/screens/filters/filters.dart';
+import 'package:adguard_home_manager/screens/home/home.dart';
+import 'package:adguard_home_manager/screens/logs/logs.dart';
import 'package:adguard_home_manager/screens/settings/settings.dart';
import 'package:adguard_home_manager/models/app_screen.dart';
@@ -13,12 +13,12 @@ List screensSelectServer = [
const AppScreen(
name: "connect",
icon: Icons.link_rounded,
- body: Connect(),
+ child: Connect()
),
const AppScreen(
name: "settings",
icon: Icons.settings_rounded,
- body: Settings()
+ child: Settings()
)
];
@@ -26,26 +26,26 @@ List screensServerConnected = [
const AppScreen(
name: "home",
icon: Icons.home_rounded,
- body: Home(),
+ child: Home()
),
const AppScreen(
name: "clients",
icon: Icons.devices,
- body: Clients()
+ child: Clients()
),
const AppScreen(
name: "logs",
icon: Icons.list_alt_rounded,
- body: Logs(),
+ child: Logs()
),
const AppScreen(
name: "filters",
icon: Icons.shield_rounded,
- body: Filters(),
+ child: Filters()
),
const AppScreen(
name: "settings",
icon: Icons.settings_rounded,
- body: Settings()
+ child: Settings()
)
];
\ No newline at end of file
diff --git a/lib/config/globals.dart b/lib/config/globals.dart
new file mode 100644
index 0000000..a955a77
--- /dev/null
+++ b/lib/config/globals.dart
@@ -0,0 +1,4 @@
+import 'package:flutter/material.dart';
+
+final GlobalKey scaffoldMessengerKey = GlobalKey();
+final GlobalKey globalNavigatorKey = GlobalKey();
\ No newline at end of file
diff --git a/lib/config/home_top_items_default_order.dart b/lib/config/home_top_items_default_order.dart
new file mode 100644
index 0000000..a5a23f0
--- /dev/null
+++ b/lib/config/home_top_items_default_order.dart
@@ -0,0 +1,15 @@
+import 'dart:convert';
+
+import 'package:adguard_home_manager/constants/enums.dart';
+
+final List homeTopItemsDefaultOrder = [
+ HomeTopItems.queriedDomains,
+ HomeTopItems.blockedDomains,
+ HomeTopItems.recurrentClients,
+ HomeTopItems.topUpstreams,
+ HomeTopItems.avgUpstreamResponseTime
+];
+
+final String homeTopItemsDefaultOrderString = jsonEncode(
+ List.from(homeTopItemsDefaultOrder.map((e) => e.name))
+);
\ No newline at end of file
diff --git a/lib/config/minimum_server_version.dart b/lib/config/minimum_server_version.dart
new file mode 100644
index 0000000..f554cb9
--- /dev/null
+++ b/lib/config/minimum_server_version.dart
@@ -0,0 +1,4 @@
+class MinimumServerVersion {
+ static const String stable = "v0.107.28";
+ static const String beta = "v0.108.0-b.33";
+}
\ No newline at end of file
diff --git a/lib/config/sizes.dart b/lib/config/sizes.dart
new file mode 100644
index 0000000..0fc2640
--- /dev/null
+++ b/lib/config/sizes.dart
@@ -0,0 +1 @@
+const double desktopBreakpoint = 1000;
\ No newline at end of file
diff --git a/lib/config/theme.dart b/lib/config/theme.dart
index 7391677..eba0b9c 100644
--- a/lib/config/theme.dart
+++ b/lib/config/theme.dart
@@ -15,7 +15,24 @@ ThemeData lightTheme(ColorScheme? dynamicColorScheme) => ThemeData(
textColor: dynamicColorScheme != null ? dynamicColorScheme.onSurfaceVariant : const Color.fromRGBO(117, 117, 117, 1),
iconColor: dynamicColorScheme != null ? dynamicColorScheme.onSurfaceVariant : const Color.fromRGBO(117, 117, 117, 1),
),
- androidOverscrollIndicator: AndroidOverscrollIndicator.stretch,
+ cardTheme: CardTheme(
+ surfaceTintColor: dynamicColorScheme?.surfaceTint
+ ),
+ popupMenuTheme: PopupMenuThemeData(
+ surfaceTintColor: dynamicColorScheme?.surfaceTint
+ ),
+ navigationBarTheme: NavigationBarThemeData(
+ surfaceTintColor: dynamicColorScheme?.surfaceTint
+ ),
+ dialogTheme: DialogTheme(
+ surfaceTintColor: dynamicColorScheme?.surfaceTint
+ ),
+ // DISABLE PREDICTIVE BACK GESTURE
+ // pageTransitionsTheme: const PageTransitionsTheme(
+ // builders: {
+ // TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
+ // }
+ // )
);
ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData(
@@ -34,7 +51,24 @@ ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData(
textColor: dynamicColorScheme != null ? dynamicColorScheme.onSurfaceVariant : const Color.fromRGBO(187, 187, 187, 1),
iconColor: dynamicColorScheme != null ? dynamicColorScheme.onSurfaceVariant : const Color.fromRGBO(187, 187, 187, 1),
),
- androidOverscrollIndicator: AndroidOverscrollIndicator.stretch,
+ cardTheme: CardTheme(
+ surfaceTintColor: dynamicColorScheme?.surfaceTint
+ ),
+ popupMenuTheme: PopupMenuThemeData(
+ surfaceTintColor: dynamicColorScheme?.surfaceTint
+ ),
+ navigationBarTheme: NavigationBarThemeData(
+ surfaceTintColor: dynamicColorScheme?.surfaceTint
+ ),
+ dialogTheme: DialogTheme(
+ surfaceTintColor: dynamicColorScheme?.surfaceTint
+ ),
+ // DISABLE PREDICTIVE BACK GESTURE
+ // pageTransitionsTheme: const PageTransitionsTheme(
+ // builders: {
+ // TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
+ // }
+ // )
);
ThemeData lightThemeOldVersions(MaterialColor primaryColor) => ThemeData(
@@ -53,7 +87,12 @@ ThemeData lightThemeOldVersions(MaterialColor primaryColor) => ThemeData(
iconColor: Color.fromRGBO(117, 117, 117, 1),
),
brightness: Brightness.light,
- androidOverscrollIndicator: AndroidOverscrollIndicator.stretch
+ // DISABLE PREDICTIVE BACK GESTURE
+ // pageTransitionsTheme: const PageTransitionsTheme(
+ // builders: {
+ // TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
+ // }
+ // )
);
ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData(
@@ -75,5 +114,10 @@ ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData(
iconColor: Color.fromRGBO(187, 187, 187, 1),
),
brightness: Brightness.dark,
- androidOverscrollIndicator: AndroidOverscrollIndicator.stretch
+ // DISABLE PREDICTIVE BACK GESTURE
+ // pageTransitionsTheme: const PageTransitionsTheme(
+ // builders: {
+ // TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
+ // }
+ // )
);
\ No newline at end of file
diff --git a/lib/constants/enums.dart b/lib/constants/enums.dart
new file mode 100644
index 0000000..569db37
--- /dev/null
+++ b/lib/constants/enums.dart
@@ -0,0 +1,3 @@
+enum LoadStatus { loading, loaded, error }
+enum HomeTopItems { queriedDomains, blockedDomains, recurrentClients, topUpstreams, avgUpstreamResponseTime }
+enum CustomRulesSorting { topBottom, bottomTop }
\ No newline at end of file
diff --git a/lib/constants/regexps.dart b/lib/constants/regexps.dart
new file mode 100644
index 0000000..e882913
--- /dev/null
+++ b/lib/constants/regexps.dart
@@ -0,0 +1,12 @@
+class Regexps {
+ static final wildcardDomain = RegExp(r'^(\*\.)?(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,10}$');
+ static final domain = RegExp(r'^((?:(?:[a-zA-Z]{1})|(?:[a-zA-Z]{1}[a-zA-Z]{1})|(?:[a-zA-Z]{1}[0-9]{1})|(?:[0-9]{1}[a-zA-Z]{1})|(?:[a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.)+([a-zA-Z]{2,10}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,10})$');
+ static final ipv4Address = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$');
+ static final ipv6Address = RegExp(r'(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))');
+ static final subroute = RegExp(r'^\/\b([A-Za-z0-9_\-~/]*)[^\/|\.|\:]$');
+ static final macAddress = RegExp(r'^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$');
+ static final url = RegExp(r'^(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})$');
+ static final certificate = RegExp(r'(-{3,}(\bBEGIN CERTIFICATE\b))|(-{3,}-{3,}(\END CERTIFICATE\b)-{3,})', multiLine: true);
+ static final privateKey = RegExp(r'(-{3,}(\bBEGIN\b).*(PRIVATE KEY\b))|(-{3,}-{3,}(\bEND\b).*(PRIVATE KEY\b)-{3,})', multiLine: true);
+ static final path = RegExp(r'^(\/{0,1}(?!\/))[A-Za-z0-9\/\-_]+(\.([a-zA-Z]+))?$');
+}
\ No newline at end of file
diff --git a/lib/constants/routes_names.dart b/lib/constants/routes_names.dart
new file mode 100644
index 0000000..fa0b07c
--- /dev/null
+++ b/lib/constants/routes_names.dart
@@ -0,0 +1,31 @@
+class RoutesNames {
+ static const String connect = "/connect";
+
+ static const String home = "/home";
+ static const String queriedDomains = "/home/queried-domains";
+ static const String blockedDomains = "/home/blocked-domains";
+ static const String recurrentClients = "/home/recurrent-clients";
+
+ static const String clients = "/clients";
+ static const String clientsList = "/clients/list";
+ static const String clientPlaceholder = "/clients/list/placeholder";
+ static const String client = "/clients/list:id";
+
+ static const String logs = "/logs";
+
+ static const String filters = "/filters";
+
+ static const String settings = "/settings";
+ static const String safeSearch = "/settings/safe-search";
+ static const String accessSettings = "/settings/access-settigs";
+ static const String dhcpSettings = "/settings/dhcp-settings";
+ static const String dnsSettings = "/settings/dns-settings";
+ static const String encryptionSettings = "/settings/encryption-settings";
+ static const String dnsRewrites = "/settings/dns-rewrites";
+ static const String serverUpdates = "/settings/server-updates";
+ static const String serverInfo = "/settings/server-info";
+ static const String customization = "/settings/customization";
+ static const String servers = "/settings/servers";
+ static const String generalSettings = "/settings/general-settings";
+ static const String advancedSettings = "/settings/advanced-settings";
+}
\ No newline at end of file
diff --git a/lib/constants/urls.dart b/lib/constants/urls.dart
index 5b60855..0a8ece3 100644
--- a/lib/constants/urls.dart
+++ b/lib/constants/urls.dart
@@ -2,5 +2,11 @@ class Urls {
static const String playStore = "https://play.google.com/store/apps/details?id=com.jgeek00.adguard_home_manager";
static const String gitHub = "https://github.com/JGeek00/adguard-home-manager";
static const String customRuleDocs = "https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters";
- static const String checkLatestReleaseUrl = "https://api.github.com/repos/JGeek00/adguard-home-manager/releases/latest";
+ static const String getReleasesGitHub = "https://api.github.com/repos/JGeek00/adguard-home-manager/releases";
+ static const String getLatestReleaseGitHub = "https://api.github.com/repos/JGeek00/adguard-home-manager/releases/latest";
+ static const String adGuardHomeReleasesTags = "https://api.github.com/repos/AdGuardTeam/AdGuardHome/releases/tags";
+ static const String googleSearchUrl = "https://www.google.com/search";
+ static const String connectionInstructions = "https://github.com/JGeek00/adguard-home-manager/wiki/Create-a-connection";
+ static const String appDetailsWebpage = "https://apps.jgeek00.com/jlfed8mcgyz6laf";
+ static const String jgeek00AppsWebpage = "https://apps.jgeek00.com";
}
\ No newline at end of file
diff --git a/lib/functions/app_update_download_link.dart b/lib/functions/app_update_download_link.dart
new file mode 100644
index 0000000..48c798a
--- /dev/null
+++ b/lib/functions/app_update_download_link.dart
@@ -0,0 +1,25 @@
+import 'dart:io';
+
+import 'package:adguard_home_manager/models/github_release.dart';
+
+String? getAppUpdateDownloadLink(GitHubRelease gitHubRelease) {
+ try {
+ if (Platform.isAndroid) {
+ return gitHubRelease.assets.firstWhere((item) => item.browserDownloadUrl.contains('apk')).browserDownloadUrl;
+ }
+ else if (Platform.isMacOS) {
+ return gitHubRelease.assets.firstWhere((item) => item.browserDownloadUrl.contains('macOS')).browserDownloadUrl;
+ }
+ else if (Platform.isWindows) {
+ return gitHubRelease.assets.firstWhere((item) => item.browserDownloadUrl.contains('exe')).browserDownloadUrl;
+ }
+ else if (Platform.isLinux) {
+ return gitHubRelease.assets.firstWhere((item) => item.browserDownloadUrl.contains('deb')).browserDownloadUrl;
+ }
+ else {
+ return null;
+ }
+ } catch (e) {
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/lib/functions/encode_base64.dart b/lib/functions/base64.dart
similarity index 80%
rename from lib/functions/encode_base64.dart
rename to lib/functions/base64.dart
index 3ed3d59..cb34296 100644
--- a/lib/functions/encode_base64.dart
+++ b/lib/functions/base64.dart
@@ -9,4 +9,8 @@ String encodeBase64UserPass(String user, String pass) {
String encodeBase64(String value) {
Codec stringToBase64 = utf8.fuse(base64);
return stringToBase64.encode(value);
+}
+
+String decodeBase64(String value) {
+ return utf8.decode(base64.decode(value));
}
\ No newline at end of file
diff --git a/lib/functions/block_unblock_domain.dart b/lib/functions/block_unblock_domain.dart
deleted file mode 100644
index cc2c8ed..0000000
--- a/lib/functions/block_unblock_domain.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// ignore_for_file: use_build_context_synchronously
-
-import 'package:flutter/material.dart';
-import 'package:provider/provider.dart';
-import 'package:flutter_gen/gen_l10n/app_localizations.dart';
-
-import 'package:adguard_home_manager/classes/process_modal.dart';
-import 'package:adguard_home_manager/models/filtering_status.dart';
-import 'package:adguard_home_manager/providers/app_config_provider.dart';
-import 'package:adguard_home_manager/providers/servers_provider.dart';
-import 'package:adguard_home_manager/services/http_requests.dart';
-
-Future