Merge remote-tracking branch 'origin/master' into russian_locale
# Conflicts: # lib/main.dart
46
.github/workflows/release-beta.yaml
vendored
|
@ -2,19 +2,9 @@ name: Compile and release beta build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
branches:
|
||||||
version:
|
- beta
|
||||||
description: "Version"
|
|
||||||
required: true
|
|
||||||
default: "1.0.0"
|
|
||||||
beta-number:
|
|
||||||
description: "Beta number"
|
|
||||||
required: true
|
|
||||||
default: "1"
|
|
||||||
number:
|
|
||||||
description: "Build number"
|
|
||||||
required: true
|
|
||||||
default: "1"
|
|
||||||
jobs:
|
jobs:
|
||||||
build-android:
|
build-android:
|
||||||
name: Build Android .apk and .aab
|
name: Build Android .apk and .aab
|
||||||
|
@ -22,7 +12,9 @@ jobs:
|
||||||
env:
|
env:
|
||||||
ANDROID_AAB_RELEASE_PATH: build/app/outputs/bundle/release
|
ANDROID_AAB_RELEASE_PATH: build/app/outputs/bundle/release
|
||||||
ANDROID_APK_RELEASE_PATH: build/app/outputs/apk/release
|
ANDROID_APK_RELEASE_PATH: build/app/outputs/apk/release
|
||||||
VERSION_NAME: ${{ github.event.inputs.version }}-beta.${{ github.event.inputs.beta-number }}
|
outputs:
|
||||||
|
VERSION_NAME: ${{ steps.save_version.outputs.version_name }}
|
||||||
|
VERSION_NUMBER: ${{ steps.save_version.outputs.version_number }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
|
@ -33,8 +25,21 @@ jobs:
|
||||||
run: echo "${{ secrets.KEY_PROPERTIES }}" | base64 --decode > android/key.properties
|
run: echo "${{ secrets.KEY_PROPERTIES }}" | base64 --decode > android/key.properties
|
||||||
- name: Decode .env
|
- name: Decode .env
|
||||||
run: echo "${{ secrets.ENV }}" | base64 --decode > .env
|
run: echo "${{ secrets.ENV }}" | base64 --decode > .env
|
||||||
- name: Update version in YAML
|
- name: Read pubspec.yaml
|
||||||
run: sed -i 's/99.99.99+99/${{ env.VERSION_NAME }}+${{ github.event.inputs.number }}/g' pubspec.yaml
|
uses: adore-me/read-yaml@v1.0.0
|
||||||
|
id: read_pubspec
|
||||||
|
with:
|
||||||
|
file: './pubspec.yaml'
|
||||||
|
key-path: '["version"]'
|
||||||
|
- name: Save version on env variable
|
||||||
|
id: save_version
|
||||||
|
run: |
|
||||||
|
version=${{ steps.read_pubspec.outputs.data }}
|
||||||
|
IFS='+'
|
||||||
|
read -r -a split <<< "$version"
|
||||||
|
echo "VERSION_NAME=$(echo ${split[0]})" >> $GITHUB_ENV
|
||||||
|
echo "version_name=${split[0]}" >> $GITHUB_OUTPUT
|
||||||
|
echo "version_number=${split[1]}" >> $GITHUB_OUTPUT
|
||||||
- name: Update KeyStore password in gradle properties
|
- name: Update KeyStore password in gradle properties
|
||||||
run: sed -i 's/#{KEYSTORE_PASS}#/${{ secrets.KEYSTORE_PASS }}/g' android/key.properties
|
run: sed -i 's/#{KEYSTORE_PASS}#/${{ secrets.KEYSTORE_PASS }}/g' android/key.properties
|
||||||
- name: Update KeyStore key password in gradle properties
|
- name: Update KeyStore key password in gradle properties
|
||||||
|
@ -69,8 +74,9 @@ jobs:
|
||||||
name: Release beta build to GitHub
|
name: Release beta build to GitHub
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [build-android]
|
needs: [build-android]
|
||||||
env:
|
env:
|
||||||
VERSION_NAME: ${{ github.event.inputs.version }}-beta.${{ github.event.inputs.beta-number }}
|
VERSION_NAME: ${{ needs.build-android.outputs.VERSION_NAME }}
|
||||||
|
VERSION_NUMBER: ${{ needs.build-android.outputs.VERSION_NUMBER }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
|
@ -87,7 +93,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
artifacts: "releases/*"
|
artifacts: "releases/*"
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
token: ${{ secrets.GH_TOKEN }}
|
||||||
tag: '${{ env.VERSION_NAME }}_(${{ github.event.inputs.number }})'
|
tag: '${{ env.VERSION_NAME }}_(${{ env.VERSION_NUMBER }})'
|
||||||
name: v${{ env.VERSION_NAME }}
|
name: v${{ env.VERSION_NAME }}
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: true
|
prerelease: true
|
||||||
|
@ -97,7 +103,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [build-android]
|
needs: [build-android]
|
||||||
env:
|
env:
|
||||||
VERSION_NAME: ${{ github.event.inputs.version }}-beta.${{ github.event.inputs.beta-number }}
|
VERSION_NAME: ${{ needs.build-android.outputs.VERSION_NAME }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
|
|
153
.github/workflows/release-stable.yaml
vendored
|
@ -2,15 +2,9 @@ name: Compile and release production build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
branches:
|
||||||
version:
|
- master
|
||||||
description: "Version"
|
|
||||||
required: true
|
|
||||||
default: "1.0.0"
|
|
||||||
number:
|
|
||||||
description: "Build number"
|
|
||||||
required: true
|
|
||||||
default: "1"
|
|
||||||
jobs:
|
jobs:
|
||||||
build-android:
|
build-android:
|
||||||
name: Build Android .apk and .aab
|
name: Build Android .apk and .aab
|
||||||
|
@ -18,6 +12,9 @@ jobs:
|
||||||
env:
|
env:
|
||||||
ANDROID_AAB_RELEASE_PATH: build/app/outputs/bundle/release
|
ANDROID_AAB_RELEASE_PATH: build/app/outputs/bundle/release
|
||||||
ANDROID_APK_RELEASE_PATH: build/app/outputs/apk/release
|
ANDROID_APK_RELEASE_PATH: build/app/outputs/apk/release
|
||||||
|
outputs:
|
||||||
|
VERSION_NAME: ${{ steps.save_version.outputs.version_name }}
|
||||||
|
VERSION_NUMBER: ${{ steps.save_version.outputs.version_number }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Decode android/app/keystore.jks
|
- name: Decode android/app/keystore.jks
|
||||||
|
@ -26,8 +23,21 @@ jobs:
|
||||||
run: echo "${{ secrets.KEY_PROPERTIES }}" | base64 --decode > android/key.properties
|
run: echo "${{ secrets.KEY_PROPERTIES }}" | base64 --decode > android/key.properties
|
||||||
- name: Decode .env
|
- name: Decode .env
|
||||||
run: echo "${{ secrets.ENV }}" | base64 --decode > .env
|
run: echo "${{ secrets.ENV }}" | base64 --decode > .env
|
||||||
- name: Update version in YAML
|
- name: Read pubspec.yaml
|
||||||
run: sed -i 's/99.99.99+99/${{ github.event.inputs.version }}+${{ github.event.inputs.number }}/g' pubspec.yaml
|
uses: adore-me/read-yaml@v1.0.0
|
||||||
|
id: read_pubspec
|
||||||
|
with:
|
||||||
|
file: './pubspec.yaml'
|
||||||
|
key-path: '["version"]'
|
||||||
|
- name: Save version on env variable
|
||||||
|
id: save_version
|
||||||
|
run: |
|
||||||
|
version=${{ steps.read_pubspec.outputs.data }}
|
||||||
|
IFS='+'
|
||||||
|
read -r -a split <<< "$version"
|
||||||
|
echo "VERSION_NAME=$(echo ${split[0]})" >> $GITHUB_ENV
|
||||||
|
echo "version_name=${split[0]}" >> $GITHUB_OUTPUT
|
||||||
|
echo "version_number=${split[1]}" >> $GITHUB_OUTPUT
|
||||||
- name: Update KeyStore password in gradle properties
|
- name: Update KeyStore password in gradle properties
|
||||||
run: sed -i 's/#{KEYSTORE_PASS}#/${{ secrets.KEYSTORE_PASS }}/g' android/key.properties
|
run: sed -i 's/#{KEYSTORE_PASS}#/${{ secrets.KEYSTORE_PASS }}/g' android/key.properties
|
||||||
- name: Update KeyStore key password in gradle properties
|
- name: Update KeyStore key password in gradle properties
|
||||||
|
@ -44,37 +54,67 @@ jobs:
|
||||||
- run: flutter build apk --release
|
- run: flutter build apk --release
|
||||||
- run: flutter build appbundle --release
|
- run: flutter build appbundle --release
|
||||||
- name: Rename apk
|
- name: Rename apk
|
||||||
run: mv $ANDROID_APK_RELEASE_PATH/app-release.apk $ANDROID_APK_RELEASE_PATH/AdGuardHomeManager_${{ github.event.inputs.version }}_Android.apk
|
run: mv $ANDROID_APK_RELEASE_PATH/app-release.apk $ANDROID_APK_RELEASE_PATH/AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.apk
|
||||||
- name: Rename aab
|
- name: Rename aab
|
||||||
run: mv $ANDROID_AAB_RELEASE_PATH/app-release.aab $ANDROID_AAB_RELEASE_PATH/AdGuardHomeManager_${{ github.event.inputs.version }}_Android.aab
|
run: mv $ANDROID_AAB_RELEASE_PATH/app-release.aab $ANDROID_AAB_RELEASE_PATH/AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.aab
|
||||||
- name: Copy apk to project root
|
- name: Copy apk to project root
|
||||||
run: cp $ANDROID_APK_RELEASE_PATH/AdGuardHomeManager_${{ github.event.inputs.version }}_Android.apk AdGuardHomeManager_${{ github.event.inputs.version }}_Android.apk
|
run: cp $ANDROID_APK_RELEASE_PATH/AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.apk AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.apk
|
||||||
- name: Copy aab to project root
|
- name: Copy aab to project root
|
||||||
run: cp $ANDROID_AAB_RELEASE_PATH/AdGuardHomeManager_${{ github.event.inputs.version }}_Android.aab AdGuardHomeManager_${{ github.event.inputs.version }}_Android.aab
|
run: cp $ANDROID_AAB_RELEASE_PATH/AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.aab AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.aab
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: android
|
name: android
|
||||||
path: |
|
path: |
|
||||||
AdGuardHomeManager_${{ github.event.inputs.version }}_Android.aab
|
AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.aab
|
||||||
AdGuardHomeManager_${{ github.event.inputs.version }}_Android.apk
|
AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.apk
|
||||||
build-macos:
|
build-macos:
|
||||||
name: Build macOS .dmg
|
name: Build macOS .dmg
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
env:
|
env:
|
||||||
MACOS_APP_RELEASE_PATH: build/macos/Build/Products/Release
|
MACOS_APP_RELEASE_PATH: build/macos/Build/Products/Release
|
||||||
|
outputs:
|
||||||
|
VERSION_NAME: ${{ steps.save_version.outputs.version_name }}
|
||||||
|
VERSION_NUMBER: ${{ steps.save_version.outputs.version_number }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Decode .env
|
- name: Decode .env
|
||||||
run: echo "${{ secrets.ENV }}" | base64 --decode > .env
|
run: echo "${{ secrets.ENV }}" | base64 --decode > .env
|
||||||
- name: Update version in YAML
|
- name: Read pubspec.yaml
|
||||||
run: sed -i '' 's/99.99.99+99/${{ github.event.inputs.version }}+${{ github.event.inputs.number }}/g' pubspec.yaml
|
uses: adore-me/read-yaml@v1.0.0
|
||||||
|
id: read_pubspec
|
||||||
|
with:
|
||||||
|
file: './pubspec.yaml'
|
||||||
|
key-path: '["version"]'
|
||||||
|
- name: Save version on env variable
|
||||||
|
id: save_version
|
||||||
|
run: |
|
||||||
|
version=${{ steps.read_pubspec.outputs.data }}
|
||||||
|
IFS='+'
|
||||||
|
read -r -a split <<< "$version"
|
||||||
|
echo "VERSION_NAME=$(echo ${split[0]})" >> $GITHUB_ENV
|
||||||
|
echo "version_name=${split[0]}" >> $GITHUB_OUTPUT
|
||||||
|
echo "version_number=${split[1]}" >> $GITHUB_OUTPUT
|
||||||
- uses: subosito/flutter-action@v2
|
- uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
channel: "stable"
|
channel: "stable"
|
||||||
- run: flutter clean
|
- run: flutter clean
|
||||||
- run: flutter pub get
|
- run: flutter pub get
|
||||||
- run: flutter build macos --release
|
- run: flutter build macos --release
|
||||||
|
- name: Install the Apple certificate and sign the application
|
||||||
|
env:
|
||||||
|
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||||
|
APPLE_CERTIFICATE_PWD: ${{ secrets.APPLE_CERTIFICATE_PWD }}
|
||||||
|
APPLE_KEYCHAIN_PWD: ${{ secrets.APPLE_KEYCHAIN_PWD }}
|
||||||
|
APPLE_IDENTITY_ID: ${{ secrets.APPLE_IDENTITY_ID }}
|
||||||
|
run: |
|
||||||
|
echo "$APPLE_CERTIFICATE" | base64 --decode > certificate.p12
|
||||||
|
security create-keychain -p $APPLE_KEYCHAIN_PWD build.keychain
|
||||||
|
security default-keychain -s build.keychain
|
||||||
|
security unlock-keychain -p $APPLE_KEYCHAIN_PWD build.keychain
|
||||||
|
security import certificate.p12 -k build.keychain -P $APPLE_CERTIFICATE_PWD -T /usr/bin/codesign
|
||||||
|
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $APPLE_KEYCHAIN_PWD build.keychain
|
||||||
|
/usr/bin/codesign --force -s "$APPLE_IDENTITY_ID" $MACOS_APP_RELEASE_PATH/AdGuard\ Home\ Manager.app -v
|
||||||
- name: Create folder to build dmg
|
- name: Create folder to build dmg
|
||||||
run: mkdir $MACOS_APP_RELEASE_PATH/AdGuard\ Home\ Manager
|
run: mkdir $MACOS_APP_RELEASE_PATH/AdGuard\ Home\ Manager
|
||||||
- name: Copy app into folder
|
- name: Copy app into folder
|
||||||
|
@ -82,25 +122,41 @@ jobs:
|
||||||
- name: Generate symbolic link to Applications dir
|
- name: Generate symbolic link to Applications dir
|
||||||
run: ln -s /Applications $MACOS_APP_RELEASE_PATH/AdGuard\ Home\ Manager
|
run: ln -s /Applications $MACOS_APP_RELEASE_PATH/AdGuard\ Home\ Manager
|
||||||
- name: Generate dmg
|
- name: Generate dmg
|
||||||
run: hdiutil create -srcfolder $MACOS_APP_RELEASE_PATH/AdGuard\ Home\ Manager $MACOS_APP_RELEASE_PATH/AdGuardHomeManager_${{ github.event.inputs.version }}_macOS_Universal.dmg
|
run: hdiutil create -srcfolder $MACOS_APP_RELEASE_PATH/AdGuard\ Home\ Manager $MACOS_APP_RELEASE_PATH/AdGuardHomeManager_${{ env.VERSION_NAME }}_macOS_Universal.dmg
|
||||||
- name: Copy dmg to project root
|
- name: Copy dmg to project root
|
||||||
run: cp $MACOS_APP_RELEASE_PATH/AdGuardHomeManager_${{ github.event.inputs.version }}_macOS_Universal.dmg AdGuardHomeManager_${{ github.event.inputs.version }}_macOS_Universal.dmg
|
run: cp $MACOS_APP_RELEASE_PATH/AdGuardHomeManager_${{ env.VERSION_NAME }}_macOS_Universal.dmg AdGuardHomeManager_${{ env.VERSION_NAME }}_macOS_Universal.dmg
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: macos
|
name: macos
|
||||||
path: AdGuardHomeManager_${{ github.event.inputs.version }}_macOS_Universal.dmg
|
path: AdGuardHomeManager_${{ env.VERSION_NAME }}_macOS_Universal.dmg
|
||||||
build-linux:
|
build-linux:
|
||||||
name: Build Linux .tar.gz and .deb
|
name: Build Linux .tar.gz and .deb
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
VERSION_NAME: ${{ steps.save_version.outputs.version_name }}
|
||||||
|
VERSION_NUMBER: ${{ steps.save_version.outputs.version_number }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Decode .env
|
- name: Decode .env
|
||||||
run: echo "${{ secrets.ENV }}" | base64 --decode > .env
|
run: echo "${{ secrets.ENV }}" | base64 --decode > .env
|
||||||
- name: Update version in pubspec.yaml
|
- name: Read pubspec.yaml
|
||||||
run: sed -i 's/99.99.99+99/${{ github.event.inputs.version }}+${{ github.event.inputs.number }}/g' pubspec.yaml
|
uses: adore-me/read-yaml@v1.0.0
|
||||||
|
id: read_pubspec
|
||||||
|
with:
|
||||||
|
file: './pubspec.yaml'
|
||||||
|
key-path: '["version"]'
|
||||||
|
- name: Save version on env variable
|
||||||
|
id: save_version
|
||||||
|
run: |
|
||||||
|
version=${{ steps.read_pubspec.outputs.data }}
|
||||||
|
IFS='+'
|
||||||
|
read -r -a split <<< "$version"
|
||||||
|
echo "VERSION_NAME=$(echo ${split[0]})" >> $GITHUB_ENV
|
||||||
|
echo "version_name=${split[0]}" >> $GITHUB_OUTPUT
|
||||||
|
echo "version_number=${split[1]}" >> $GITHUB_OUTPUT
|
||||||
- name: Update version in debian.yaml
|
- name: Update version in debian.yaml
|
||||||
run: sed -i 's/<REPLACE_VERSION_NUMBER_ACTIONS>/${{ github.event.inputs.version }}/g' debian/debian.yaml
|
run: sed -i 's/<REPLACE_VERSION_NUMBER_ACTIONS>/${{ env.VERSION_NAME }}/g' debian/debian.yaml
|
||||||
- name: Update dependencies list
|
- name: Update dependencies list
|
||||||
run: sudo apt-get update
|
run: sudo apt-get update
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
@ -116,7 +172,7 @@ jobs:
|
||||||
- name: Generate .deb package
|
- name: Generate .deb package
|
||||||
run: flutter_to_debian
|
run: flutter_to_debian
|
||||||
- name: Move .deb package to project root
|
- name: Move .deb package to project root
|
||||||
run: mv debian/packages/AdGuardHomeManager_${{ github.event.inputs.version }}_amd64.deb AdGuardHomeManager_${{ github.event.inputs.version }}_Linux_amd64.deb
|
run: mv build/linux/x64/release/debian/AdGuardHomeManager_${{ env.VERSION_NAME }}_amd64.deb AdGuardHomeManager_${{ env.VERSION_NAME }}_Linux_amd64.deb
|
||||||
- name: Generate .tar.gz package
|
- name: Generate .tar.gz package
|
||||||
uses: a7ul/tar-action@v1.1.3
|
uses: a7ul/tar-action@v1.1.3
|
||||||
id: compress
|
id: compress
|
||||||
|
@ -127,30 +183,46 @@ jobs:
|
||||||
./data
|
./data
|
||||||
./lib
|
./lib
|
||||||
./AdGuardHomeManager
|
./AdGuardHomeManager
|
||||||
outPath: AdGuardHomeManager_${{ github.event.inputs.version }}_Linux.tar.gz
|
outPath: AdGuardHomeManager_${{ env.VERSION_NAME }}_Linux.tar.gz
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: linux
|
name: linux
|
||||||
path: |
|
path: |
|
||||||
AdGuardHomeManager_${{ github.event.inputs.version }}_Linux_amd64.deb
|
AdGuardHomeManager_${{ env.VERSION_NAME }}_Linux_amd64.deb
|
||||||
AdGuardHomeManager_${{ github.event.inputs.version }}_Linux.tar.gz
|
AdGuardHomeManager_${{ env.VERSION_NAME }}_Linux.tar.gz
|
||||||
build-windows:
|
build-windows:
|
||||||
name: Build Windows installer
|
name: Build Windows installer
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
outputs:
|
||||||
|
VERSION_NAME: ${{ steps.save_version.outputs.version_name }}
|
||||||
|
VERSION_NUMBER: ${{ steps.save_version.outputs.version_number }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Decode .env
|
- name: Decode .env
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
[IO.File]::WriteAllBytes('.env', [Convert]::FromBase64String('${{ secrets.ENV }}'))
|
[IO.File]::WriteAllBytes('.env', [Convert]::FromBase64String('${{ secrets.ENV }}'))
|
||||||
- name: Update version in pubspec.yaml
|
- name: Read pubspec.yaml
|
||||||
|
uses: adore-me/read-yaml@v1.0.0
|
||||||
|
id: read_pubspec
|
||||||
|
with:
|
||||||
|
file: './pubspec.yaml'
|
||||||
|
key-path: '["version"]'
|
||||||
|
- name: Save version on env variable
|
||||||
shell: bash
|
shell: bash
|
||||||
run: sed -i 's/99.99.99+99/${{ github.event.inputs.version }}+${{ github.event.inputs.number }}/g' pubspec.yaml
|
id: save_version
|
||||||
|
run: |
|
||||||
|
version=${{ steps.read_pubspec.outputs.data }}
|
||||||
|
IFS='+'
|
||||||
|
read -r -a split <<< "$version"
|
||||||
|
echo "VERSION_NAME=$(echo ${split[0]})" >> $GITHUB_ENV
|
||||||
|
echo "version_name=${split[0]}" >> $GITHUB_OUTPUT
|
||||||
|
echo "version_number=${split[1]}" >> $GITHUB_OUTPUT
|
||||||
- name: Update version in innosetup config file
|
- name: Update version in innosetup config file
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
(Get-Content windows/innosetup_installer_builder.iss) -replace '<REPLACE_VERSION_ACTIONS>', '${{ github.event.inputs.version }}' | Out-File -encoding ASCII windows/innosetup_installer_builder.iss
|
(Get-Content windows/innosetup_installer_builder.iss) -replace '<REPLACE_VERSION_ACTIONS>', '${{ env.VERSION_NAME }}' | Out-File -encoding ASCII windows/innosetup_installer_builder.iss
|
||||||
- uses: subosito/flutter-action@v2
|
- uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
channel: "stable"
|
channel: "stable"
|
||||||
|
@ -160,16 +232,19 @@ jobs:
|
||||||
- name: Build installer witn innosetup
|
- name: Build installer witn innosetup
|
||||||
run: iscc /Q windows/innosetup_installer_builder.iss
|
run: iscc /Q windows/innosetup_installer_builder.iss
|
||||||
- name: Move installer file to root directory
|
- name: Move installer file to root directory
|
||||||
run: move build/windows/aghm_installer.exe AdGuardHomeManager_${{ github.event.inputs.version }}_Windows_x64.exe
|
run: move build/windows/aghm_installer.exe AdGuardHomeManager_${{ env.VERSION_NAME }}_Windows_x64.exe
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: windows
|
name: windows
|
||||||
path: AdGuardHomeManager_${{ github.event.inputs.version }}_Windows_x64.exe
|
path: AdGuardHomeManager_${{ env.VERSION_NAME }}_Windows_x64.exe
|
||||||
release-builds-github:
|
release-builds-github:
|
||||||
name: Release builds to GitHub
|
name: Release builds to GitHub
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [build-android, build-macos, build-linux, build-windows]
|
needs: [build-android, build-macos, build-linux, build-windows]
|
||||||
|
env:
|
||||||
|
VERSION_NAME: ${{ needs.build-android.outputs.VERSION_NAME }}
|
||||||
|
VERSION_NUMBER: ${{ needs.build-android.outputs.VERSION_NUMBER }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Create builds directory
|
- name: Create builds directory
|
||||||
|
@ -199,8 +274,8 @@ jobs:
|
||||||
with:
|
with:
|
||||||
artifacts: "releases/*"
|
artifacts: "releases/*"
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
token: ${{ secrets.GH_TOKEN }}
|
||||||
tag: '${{ github.event.inputs.version }}_(${{ github.event.inputs.number }})'
|
tag: '${{ env.VERSION_NAME }}_(${{ env.VERSION_NUMBER }})'
|
||||||
name: v${{ github.event.inputs.version }}
|
name: v${{ env.VERSION_NAME }}
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: false
|
prerelease: false
|
||||||
commit: ${{ github.sha }}
|
commit: ${{ github.sha }}
|
||||||
|
@ -208,6 +283,8 @@ jobs:
|
||||||
name: Release Android build to the Google Play Store
|
name: Release Android build to the Google Play Store
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [build-android, build-macos, build-linux, build-windows]
|
needs: [build-android, build-macos, build-linux, build-windows]
|
||||||
|
env:
|
||||||
|
VERSION_NAME: ${{ needs.build-android.outputs.VERSION_NAME }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Download Android artifacts
|
- name: Download Android artifacts
|
||||||
|
@ -219,7 +296,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
serviceAccountJsonPlainText: ${{ secrets.PLAYSTORE_ACCOUNT_KEY }}
|
serviceAccountJsonPlainText: ${{ secrets.PLAYSTORE_ACCOUNT_KEY }}
|
||||||
packageName: com.jgeek00.adguard_home_manager
|
packageName: com.jgeek00.adguard_home_manager
|
||||||
releaseFiles: AdGuardHomeManager_${{ github.event.inputs.version }}_Android.aab
|
releaseFiles: AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.aab
|
||||||
track: production
|
track: production
|
||||||
status: draft
|
status: draft
|
||||||
releaseName: ${{ github.event.inputs.version }}
|
releaseName: ${{ env.VERSION_NAME }}
|
4
.gitignore
vendored
|
@ -46,4 +46,6 @@ app.*.map.json
|
||||||
/android/app/profile
|
/android/app/profile
|
||||||
/android/app/release
|
/android/app/release
|
||||||
|
|
||||||
/debian/packages
|
/debian/packages
|
||||||
|
|
||||||
|
untranslated.json
|
45
README.md
|
@ -44,18 +44,28 @@ On [this repository](https://github.com/JuanRodenas/Pihole_list) you can find a
|
||||||
|
|
||||||
## Generate production build
|
## Generate production build
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>
|
||||||
|
<b>Prerequisites</b>
|
||||||
|
<ol>
|
||||||
|
<li>Open <code>pubspec.yaml</code> and change the version name and the version number.</li>
|
||||||
|
<li>Run <code>flutter clean</code>.</li>
|
||||||
|
<li>Run <code>flutter pub get</code>.</li>
|
||||||
|
</ol>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>Android</b>
|
||||||
|
<ol>
|
||||||
|
<li>Make sure you have your <code>key.properties</code> file at <code>android/</code>, with all the required values of your signing key correctly set up.</li>
|
||||||
|
<li>Make sure you have your keystore file at <code>android/app</code>.</li>
|
||||||
|
<li>Run <code>flutter build apk --release</code> to compile the APK.</li>
|
||||||
|
<li>The .apk package is located at <code>build/app/outputs/flutter-apk/app-release.apk</code>.</li>
|
||||||
|
</ol>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>macOS</b>
|
<b>macOS</b>
|
||||||
<ol>
|
<ol>
|
||||||
<li>flutter clean</li>
|
<li>Run <code>flutter build macos --release</code> to compile the production build.</li>
|
||||||
<li>flutter pub get</li>
|
<li>The .app package is located at <code>build/macos/Build/Products/Release/AdGuard Home Manager.app</code>.</li>
|
||||||
<li>flutter build macos --release</li>
|
|
||||||
<li>Open macos/Runner.xcworkspace on Xcode</li>
|
|
||||||
<li>Make sure all the pods have the minimum deployment version at 10.14</li>
|
|
||||||
<li>Select Runner > Targets Runner</li>
|
|
||||||
<li>Make sure the Version and Build numbers are correct</li>
|
|
||||||
<li>Click on Product menu and on Archive</li>
|
|
||||||
<li>Select the first on the list and click on Distribute app, select Copy App and click on Next</li>
|
|
||||||
</ol>
|
</ol>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
@ -67,24 +77,22 @@ On [this repository](https://github.com/JuanRodenas/Pihole_list) you can find a
|
||||||
</ol>
|
</ol>
|
||||||
<b>Build</b>
|
<b>Build</b>
|
||||||
<ol>
|
<ol>
|
||||||
<li>Open debian.yaml file inside debian/ and update the version number</li>
|
<li>Open <code>debian.yaml</code> file inside debian/ and update the version number</li>
|
||||||
<li>run <code>rps build linux</code></li>
|
<li>run <code>rps build linux</code></li>
|
||||||
<li>The .tar.gz is at build/linux/x64/release/bundle</li>
|
<li>The .tar.gz is at <code>build/linux/x64/release/bundle</code></li>
|
||||||
<li>The .deb package is at debian/packages</li>
|
<li>The .deb package is at <code>build/linux/x64/release/debian/</code></li>
|
||||||
</ol>
|
</ol>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>Windows</b>
|
<b>Windows</b>
|
||||||
<ol>
|
<ol>
|
||||||
<li>flutter clean</li>
|
<li>Run <code>flutter build windows --release</code>.</li>
|
||||||
<li>flutter pub get</li>
|
|
||||||
<li>flutter build windows</li>
|
|
||||||
<li>Open Inno Setup Compiler application and load the script</li>
|
<li>Open Inno Setup Compiler application and load the script</li>
|
||||||
<li>The script is located at windows/innosetup_installer_builder.iss</li>
|
<li>The script is located at <code>windows/innosetup_installer_builder.iss</code></li>
|
||||||
<li>Update the version number and save the changes</li>
|
<li>Update the version number and save the changes</li>
|
||||||
<li>Click on the Compile button</li>
|
<li>Click on the Compile button</li>
|
||||||
<li>The installer will be generated at build/windows/aghm_installer.exe</li>
|
<li>The installer will be generated at <code>build/windows/aghm_installer.exe</code>.</li>
|
||||||
</ol>
|
</ol>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -119,6 +127,9 @@ On [this repository](https://github.com/JuanRodenas/Pihole_list) you can find a
|
||||||
- [async](https://pub.dev/packages/async)
|
- [async](https://pub.dev/packages/async)
|
||||||
- [sentry flutter](https://pub.dev/packages/sentry_flutter)
|
- [sentry flutter](https://pub.dev/packages/sentry_flutter)
|
||||||
- [flutter dotenv](https://pub.dev/packages/flutter_dotenv)
|
- [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)
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
android:label="AdGuard Home Manager"
|
android:label="AdGuard Home Manager"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:enableOnBackInvokedCallback="true">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
|
4
android/key.properties.sample
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
storePassword= # keystore password #
|
||||||
|
keyPassword= # keystore key password #
|
||||||
|
keyAlias= # key alias #
|
||||||
|
storeFile= # ./keystore-file-name.jks #
|
1
devtools_options.yaml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
extensions:
|
0
ios/.gitignore
vendored
Normal file → Executable file
0
ios/Flutter/AppFrameworkInfo.plist
Normal file → Executable file
0
ios/Flutter/Debug.xcconfig
Normal file → Executable file
0
ios/Flutter/Release.xcconfig
Normal file → Executable file
0
ios/Podfile
Normal file → Executable file
52
ios/Podfile.lock
Normal file → Executable file
|
@ -11,11 +11,35 @@ PODS:
|
||||||
- FMDB/standard (2.7.5)
|
- FMDB/standard (2.7.5)
|
||||||
- package_info_plus (0.4.5):
|
- package_info_plus (0.4.5):
|
||||||
- Flutter
|
- Flutter
|
||||||
- sqflite (0.0.2):
|
- Sentry/HybridSDK (8.15.2):
|
||||||
|
- SentryPrivate (= 8.15.2)
|
||||||
|
- sentry_flutter (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- FlutterMacOS
|
||||||
|
- Sentry/HybridSDK (= 8.15.2)
|
||||||
|
- SentryPrivate (8.15.2)
|
||||||
|
- sqflite (0.0.3):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FMDB (>= 2.7.5)
|
- FMDB (>= 2.7.5)
|
||||||
|
- sqlite3 (3.44.0):
|
||||||
|
- sqlite3/common (= 3.44.0)
|
||||||
|
- sqlite3/common (3.44.0)
|
||||||
|
- sqlite3/fts5 (3.44.0):
|
||||||
|
- sqlite3/common
|
||||||
|
- sqlite3/perf-threadsafe (3.44.0):
|
||||||
|
- sqlite3/common
|
||||||
|
- sqlite3/rtree (3.44.0):
|
||||||
|
- sqlite3/common
|
||||||
|
- sqlite3_flutter_libs (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- sqlite3 (~> 3.44.0)
|
||||||
|
- sqlite3/fts5
|
||||||
|
- sqlite3/perf-threadsafe
|
||||||
|
- sqlite3/rtree
|
||||||
- store_checker (0.0.1):
|
- store_checker (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- url_launcher_ios (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||||
|
@ -23,12 +47,18 @@ DEPENDENCIES:
|
||||||
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
||||||
- flutter_web_browser (from `.symlinks/plugins/flutter_web_browser/ios`)
|
- flutter_web_browser (from `.symlinks/plugins/flutter_web_browser/ios`)
|
||||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
|
- sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
|
||||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||||
|
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/ios`)
|
||||||
- store_checker (from `.symlinks/plugins/store_checker/ios`)
|
- store_checker (from `.symlinks/plugins/store_checker/ios`)
|
||||||
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- FMDB
|
- FMDB
|
||||||
|
- Sentry
|
||||||
|
- SentryPrivate
|
||||||
|
- sqlite3
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
device_info_plus:
|
device_info_plus:
|
||||||
|
@ -41,21 +71,33 @@ EXTERNAL SOURCES:
|
||||||
:path: ".symlinks/plugins/flutter_web_browser/ios"
|
:path: ".symlinks/plugins/flutter_web_browser/ios"
|
||||||
package_info_plus:
|
package_info_plus:
|
||||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||||
|
sentry_flutter:
|
||||||
|
:path: ".symlinks/plugins/sentry_flutter/ios"
|
||||||
sqflite:
|
sqflite:
|
||||||
:path: ".symlinks/plugins/sqflite/ios"
|
:path: ".symlinks/plugins/sqflite/ios"
|
||||||
|
sqlite3_flutter_libs:
|
||||||
|
:path: ".symlinks/plugins/sqlite3_flutter_libs/ios"
|
||||||
store_checker:
|
store_checker:
|
||||||
:path: ".symlinks/plugins/store_checker/ios"
|
:path: ".symlinks/plugins/store_checker/ios"
|
||||||
|
url_launcher_ios:
|
||||||
|
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
|
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
|
||||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||||
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
|
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
|
||||||
flutter_web_browser: 7bccaafbb0c5b8862afe7bcd158f15557109f61f
|
flutter_web_browser: 7bccaafbb0c5b8862afe7bcd158f15557109f61f
|
||||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||||
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85
|
||||||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
Sentry: 6f5742b4c47c17c9adcf265f6f328cf4a0ed1923
|
||||||
|
sentry_flutter: 2c309a1d4b45e59d02cfa15795705687f1e2081b
|
||||||
|
SentryPrivate: b2f7996f37781080f04a946eb4e377ff63c64195
|
||||||
|
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
|
||||||
|
sqlite3: 6e2d4a4879854d0ec86b476bf3c3e30870bac273
|
||||||
|
sqlite3_flutter_libs: eb769059df0356dc52ddda040f09cacc9391a7cf
|
||||||
store_checker: 359c5051d9ec30ff0a8fa39eb5ec9df021bb745d
|
store_checker: 359c5051d9ec30ff0a8fa39eb5ec9df021bb745d
|
||||||
|
url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b
|
||||||
|
|
||||||
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
|
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
|
||||||
|
|
||||||
COCOAPODS: 1.11.2
|
COCOAPODS: 1.14.3
|
||||||
|
|
44
ios/Runner.xcodeproj/project.pbxproj
Normal file → Executable file
|
@ -68,7 +68,6 @@
|
||||||
65533F0C0783FDE34AE79B0A /* Pods-Runner.release.xcconfig */,
|
65533F0C0783FDE34AE79B0A /* Pods-Runner.release.xcconfig */,
|
||||||
69C2CC4A6DE17506FC5C0F13 /* Pods-Runner.profile.xcconfig */,
|
69C2CC4A6DE17506FC5C0F13 /* Pods-Runner.profile.xcconfig */,
|
||||||
);
|
);
|
||||||
name = Pods;
|
|
||||||
path = Pods;
|
path = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
@ -156,7 +155,8 @@
|
||||||
97C146E61CF9000F007C117D /* Project object */ = {
|
97C146E61CF9000F007C117D /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastUpgradeCheck = 1300;
|
BuildIndependentTargetsInParallel = YES;
|
||||||
|
LastUpgradeCheck = 1430;
|
||||||
ORGANIZATIONNAME = "";
|
ORGANIZATIONNAME = "";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
97C146ED1CF9000F007C117D = {
|
97C146ED1CF9000F007C117D = {
|
||||||
|
@ -222,6 +222,7 @@
|
||||||
files = (
|
files = (
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
|
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
|
||||||
);
|
);
|
||||||
name = "Thin Binary";
|
name = "Thin Binary";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
|
@ -324,6 +325,7 @@
|
||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
@ -334,6 +336,7 @@
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
@ -342,7 +345,7 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
|
@ -360,15 +363,22 @@
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = 38Z3B9TJTR;
|
DEVELOPMENT_TEAM = 38Z3B9TJTR;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "AdGuard Home";
|
||||||
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.jgeek00.adguard_home_manager;
|
PRODUCT_BUNDLE_IDENTIFIER = com.jgeek00.adguardHomeManager;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
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_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Profile;
|
name = Profile;
|
||||||
|
@ -396,6 +406,7 @@
|
||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
@ -406,6 +417,7 @@
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
@ -420,7 +432,7 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -451,6 +463,7 @@
|
||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
@ -461,6 +474,7 @@
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
@ -469,7 +483,7 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
|
@ -489,16 +503,23 @@
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = 38Z3B9TJTR;
|
DEVELOPMENT_TEAM = 38Z3B9TJTR;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "AdGuard Home";
|
||||||
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.jgeek00.adguard_home_manager;
|
PRODUCT_BUNDLE_IDENTIFIER = com.jgeek00.adguardHomeManager;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
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_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
|
@ -512,15 +533,22 @@
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = 38Z3B9TJTR;
|
DEVELOPMENT_TEAM = 38Z3B9TJTR;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "AdGuard Home";
|
||||||
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.jgeek00.adguard_home_manager;
|
PRODUCT_BUNDLE_IDENTIFIER = com.jgeek00.adguardHomeManager;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
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_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
|
|
0
ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file → Executable file
0
ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
Normal file → Executable file
0
ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
Normal file → Executable file
2
ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
Normal file → Executable file
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1300"
|
LastUpgradeVersion = "1430"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|
0
ios/Runner.xcworkspace/contents.xcworkspacedata
generated
Normal file → Executable file
0
ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
Normal file → Executable file
0
ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
Normal file → Executable file
0
ios/Runner/AppDelegate.swift
Normal file → Executable file
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
Normal file → Executable file
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
Normal file → Executable file
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
Normal file → Executable file
Before Width: | Height: | Size: 526 B After Width: | Height: | Size: 526 B |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 1,005 B After Width: | Height: | Size: 1,005 B |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
Normal file → Executable file
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
Normal file → Executable file
Before Width: | Height: | Size: 773 B After Width: | Height: | Size: 773 B |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
Normal file → Executable file
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
Normal file → Executable file
Before Width: | Height: | Size: 1,005 B After Width: | Height: | Size: 1,005 B |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
Normal file → Executable file
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png
Normal file → Executable file
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
Normal file → Executable file
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
Normal file → Executable file
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png
Normal file → Executable file
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
Normal file → Executable file
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
0
ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json
vendored
Normal file → Executable file
0
ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png
vendored
Normal file → Executable file
Before Width: | Height: | Size: 68 B After Width: | Height: | Size: 68 B |
0
ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png
vendored
Normal file → Executable file
Before Width: | Height: | Size: 70 B After Width: | Height: | Size: 70 B |
0
ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
vendored
Normal file → Executable file
0
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
vendored
Normal file → Executable file
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
0
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
vendored
Normal file → Executable file
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
0
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
vendored
Normal file → Executable file
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
0
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark.png
vendored
Normal file → Executable file
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
0
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@2x.png
vendored
Normal file → Executable file
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
0
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@3x.png
vendored
Normal file → Executable file
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
0
ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
vendored
Normal file → Executable file
0
ios/Runner/Base.lproj/LaunchScreen.storyboard
Normal file → Executable file
0
ios/Runner/Base.lproj/Main.storyboard
Normal file → Executable file
98
ios/Runner/Info.plist
Normal file → Executable file
|
@ -1,53 +1,53 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<true/>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>AdGuard Home Manager</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>AdGuard Home</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>6.0</string>
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>adguard_home_manager</string>
|
<string>6.0</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundleName</key>
|
||||||
<string>APPL</string>
|
<string>adguardHomeManager</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>????</string>
|
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
<string>????</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>CFBundleVersion</key>
|
||||||
<true/>
|
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<string>LaunchScreen</string>
|
<true/>
|
||||||
<key>UIMainStoryboardFile</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<string>Main</string>
|
<true/>
|
||||||
<key>UISupportedInterfaceOrientations</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<array>
|
<string>LaunchScreen</string>
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
<key>UIMainStoryboardFile</key>
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>Main</string>
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<key>UIStatusBarHidden</key>
|
||||||
</array>
|
<false/>
|
||||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
<array>
|
<array>
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
</array>
|
||||||
</array>
|
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<array>
|
||||||
<false/>
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||||
<true/>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
<true/>
|
</array>
|
||||||
<key>UIStatusBarHidden</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
0
ios/Runner/Runner-Bridging-Header.h
Normal file → Executable file
|
@ -1,3 +1,4 @@
|
||||||
arb-dir: lib/l10n
|
arb-dir: lib/l10n
|
||||||
template-arb-file: app_en.arb
|
template-arb-file: app_en.arb
|
||||||
output-localization-file: app_localizations.dart
|
output-localization-file: app_localizations.dart
|
||||||
|
untranslated-messages-file: untranslated.json
|
116
lib/base.dart
|
@ -1,116 +0,0 @@
|
||||||
// ignore_for_file: use_build_context_synchronously, depend_on_referenced_packages
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:animations/animations.dart';
|
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
|
|
||||||
import 'package:adguard_home_manager/widgets/bottom_nav_bar.dart';
|
|
||||||
import 'package:adguard_home_manager/widgets/menu_bar.dart';
|
|
||||||
import 'package:adguard_home_manager/widgets/update_modal.dart';
|
|
||||||
import 'package:adguard_home_manager/widgets/navigation_rail.dart';
|
|
||||||
|
|
||||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
|
||||||
import 'package:adguard_home_manager/functions/check_app_updates.dart';
|
|
||||||
import 'package:adguard_home_manager/functions/open_url.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 {
|
|
||||||
const Base({Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<Base> createState() => _BaseState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _BaseState extends State<Base> with WidgetsBindingObserver {
|
|
||||||
int selectedScreen = 0;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
WidgetsBinding.instance.addObserver(this);
|
|
||||||
|
|
||||||
super.initState();
|
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
|
||||||
final appConfigProvider = Provider.of<AppConfigProvider>(context, listen: false);
|
|
||||||
final result = await checkAppUpdates(
|
|
||||||
currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber,
|
|
||||||
installationSource: appConfigProvider.installationSource,
|
|
||||||
setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable,
|
|
||||||
isBeta: appConfigProvider.getAppInfo!.version.contains('beta'),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result != null && appConfigProvider.doNotRememberVersion != result.tagName) {
|
|
||||||
await showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (context) => UpdateModal(
|
|
||||||
gitHubRelease: result,
|
|
||||||
onDownload: (link, version) => openUrl(link),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final serversProvider = Provider.of<ServersProvider>(context);
|
|
||||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
|
||||||
|
|
||||||
final width = MediaQuery.of(context).size.width;
|
|
||||||
|
|
||||||
List<AppScreen> screens = serversProvider.selectedServer != null
|
|
||||||
? screensServerConnected
|
|
||||||
: screensSelectServer;
|
|
||||||
|
|
||||||
if (kDebugMode && dotenv.env['ENABLE_SENTRY'] == "true") {
|
|
||||||
Sentry.captureMessage("Debug mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
return CustomMenuBar(
|
|
||||||
child: AnnotatedRegion<SystemUiOverlayStyle>(
|
|
||||||
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: Row(
|
|
||||||
children: [
|
|
||||||
if (width > 900) const SideNavigationRail(),
|
|
||||||
Expanded(
|
|
||||||
child: PageTransitionSwitcher(
|
|
||||||
duration: const Duration(milliseconds: 200),
|
|
||||||
transitionBuilder: (
|
|
||||||
(child, primaryAnimation, secondaryAnimation) => FadeThroughTransition(
|
|
||||||
animation: primaryAnimation,
|
|
||||||
secondaryAnimation: secondaryAnimation,
|
|
||||||
child: child,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
child: screens[appConfigProvider.selectedScreen].body,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
bottomNavigationBar: width <= 900
|
|
||||||
? const BottomNavBar()
|
|
||||||
: null,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
216
lib/classes/http_client.dart
Normal file
|
@ -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<HttpResponse> 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<HttpResponse> 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<HttpResponse> 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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,20 +1,14 @@
|
||||||
|
import 'package:adguard_home_manager/config/globals.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/widgets/process_dialog.dart';
|
import 'package:adguard_home_manager/widgets/process_dialog.dart';
|
||||||
|
|
||||||
class ProcessModal {
|
class ProcessModal {
|
||||||
late BuildContext context;
|
|
||||||
|
|
||||||
ProcessModal({
|
|
||||||
required this.context
|
|
||||||
});
|
|
||||||
|
|
||||||
void open(String message) async {
|
void open(String message) async {
|
||||||
await Future.delayed(const Duration(seconds: 0), () => {
|
await Future.delayed(const Duration(seconds: 0), () => {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: globalNavigatorKey.currentContext!,
|
||||||
builder: (c) {
|
builder: (ctx) {
|
||||||
context = c;
|
|
||||||
return ProcessDialog(
|
return ProcessDialog(
|
||||||
message: message,
|
message: message,
|
||||||
);
|
);
|
||||||
|
@ -26,6 +20,6 @@ class ProcessModal {
|
||||||
}
|
}
|
||||||
|
|
||||||
void close() {
|
void close() {
|
||||||
Navigator.pop(context);
|
Navigator.pop(globalNavigatorKey.currentContext!);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
import 'package:flutter/material.dart';
|
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/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/screens/settings/settings.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/models/app_screen.dart';
|
import 'package:adguard_home_manager/models/app_screen.dart';
|
||||||
|
@ -13,12 +13,12 @@ List<AppScreen> screensSelectServer = [
|
||||||
const AppScreen(
|
const AppScreen(
|
||||||
name: "connect",
|
name: "connect",
|
||||||
icon: Icons.link_rounded,
|
icon: Icons.link_rounded,
|
||||||
body: Connect(),
|
child: Connect()
|
||||||
),
|
),
|
||||||
const AppScreen(
|
const AppScreen(
|
||||||
name: "settings",
|
name: "settings",
|
||||||
icon: Icons.settings_rounded,
|
icon: Icons.settings_rounded,
|
||||||
body: Settings()
|
child: Settings()
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -26,26 +26,26 @@ List<AppScreen> screensServerConnected = [
|
||||||
const AppScreen(
|
const AppScreen(
|
||||||
name: "home",
|
name: "home",
|
||||||
icon: Icons.home_rounded,
|
icon: Icons.home_rounded,
|
||||||
body: Home(),
|
child: Home()
|
||||||
),
|
),
|
||||||
const AppScreen(
|
const AppScreen(
|
||||||
name: "clients",
|
name: "clients",
|
||||||
icon: Icons.devices,
|
icon: Icons.devices,
|
||||||
body: Clients()
|
child: Clients()
|
||||||
),
|
),
|
||||||
const AppScreen(
|
const AppScreen(
|
||||||
name: "logs",
|
name: "logs",
|
||||||
icon: Icons.list_alt_rounded,
|
icon: Icons.list_alt_rounded,
|
||||||
body: Logs(),
|
child: Logs()
|
||||||
),
|
),
|
||||||
const AppScreen(
|
const AppScreen(
|
||||||
name: "filters",
|
name: "filters",
|
||||||
icon: Icons.shield_rounded,
|
icon: Icons.shield_rounded,
|
||||||
body: Filters(),
|
child: Filters()
|
||||||
),
|
),
|
||||||
const AppScreen(
|
const AppScreen(
|
||||||
name: "settings",
|
name: "settings",
|
||||||
icon: Icons.settings_rounded,
|
icon: Icons.settings_rounded,
|
||||||
body: Settings()
|
child: Settings()
|
||||||
)
|
)
|
||||||
];
|
];
|
|
@ -1,3 +1,4 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
final GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
|
final GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
|
||||||
|
final GlobalKey<NavigatorState> globalNavigatorKey = GlobalKey<NavigatorState>();
|
|
@ -5,7 +5,9 @@ import 'package:adguard_home_manager/constants/enums.dart';
|
||||||
final List<HomeTopItems> homeTopItemsDefaultOrder = [
|
final List<HomeTopItems> homeTopItemsDefaultOrder = [
|
||||||
HomeTopItems.queriedDomains,
|
HomeTopItems.queriedDomains,
|
||||||
HomeTopItems.blockedDomains,
|
HomeTopItems.blockedDomains,
|
||||||
HomeTopItems.recurrentClients
|
HomeTopItems.recurrentClients,
|
||||||
|
HomeTopItems.topUpstreams,
|
||||||
|
HomeTopItems.avgUpstreamResponseTime
|
||||||
];
|
];
|
||||||
|
|
||||||
final String homeTopItemsDefaultOrderString = jsonEncode(
|
final String homeTopItemsDefaultOrderString = jsonEncode(
|
||||||
|
|
4
lib/config/minimum_server_version.dart
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
class MinimumServerVersion {
|
||||||
|
static const String stable = "v0.107.28";
|
||||||
|
static const String beta = "v0.108.0-b.33";
|
||||||
|
}
|
1
lib/config/sizes.dart
Normal file
|
@ -0,0 +1 @@
|
||||||
|
const double desktopBreakpoint = 1000;
|
|
@ -15,7 +15,6 @@ ThemeData lightTheme(ColorScheme? dynamicColorScheme) => ThemeData(
|
||||||
textColor: dynamicColorScheme != null ? dynamicColorScheme.onSurfaceVariant : const Color.fromRGBO(117, 117, 117, 1),
|
textColor: dynamicColorScheme != null ? dynamicColorScheme.onSurfaceVariant : const Color.fromRGBO(117, 117, 117, 1),
|
||||||
iconColor: 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,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData(
|
ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData(
|
||||||
|
@ -34,7 +33,6 @@ ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData(
|
||||||
textColor: dynamicColorScheme != null ? dynamicColorScheme.onSurfaceVariant : const Color.fromRGBO(187, 187, 187, 1),
|
textColor: dynamicColorScheme != null ? dynamicColorScheme.onSurfaceVariant : const Color.fromRGBO(187, 187, 187, 1),
|
||||||
iconColor: 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,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
ThemeData lightThemeOldVersions(MaterialColor primaryColor) => ThemeData(
|
ThemeData lightThemeOldVersions(MaterialColor primaryColor) => ThemeData(
|
||||||
|
@ -53,7 +51,6 @@ ThemeData lightThemeOldVersions(MaterialColor primaryColor) => ThemeData(
|
||||||
iconColor: Color.fromRGBO(117, 117, 117, 1),
|
iconColor: Color.fromRGBO(117, 117, 117, 1),
|
||||||
),
|
),
|
||||||
brightness: Brightness.light,
|
brightness: Brightness.light,
|
||||||
androidOverscrollIndicator: AndroidOverscrollIndicator.stretch
|
|
||||||
);
|
);
|
||||||
|
|
||||||
ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData(
|
ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData(
|
||||||
|
@ -75,5 +72,4 @@ ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData(
|
||||||
iconColor: Color.fromRGBO(187, 187, 187, 1),
|
iconColor: Color.fromRGBO(187, 187, 187, 1),
|
||||||
),
|
),
|
||||||
brightness: Brightness.dark,
|
brightness: Brightness.dark,
|
||||||
androidOverscrollIndicator: AndroidOverscrollIndicator.stretch
|
|
||||||
);
|
);
|
|
@ -1,2 +1,2 @@
|
||||||
enum LoadStatus { loading, loaded, error }
|
enum LoadStatus { loading, loaded, error }
|
||||||
enum HomeTopItems { queriedDomains, blockedDomains, recurrentClients }
|
enum HomeTopItems { queriedDomains, blockedDomains, recurrentClients, topUpstreams, avgUpstreamResponseTime }
|
31
lib/constants/routes_names.dart
Normal file
|
@ -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";
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ class Urls {
|
||||||
static const String gitHub = "https://github.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 customRuleDocs = "https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters";
|
||||||
static const String getReleasesGitHub = "https://api.github.com/repos/JGeek00/adguard-home-manager/releases";
|
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 adGuardHomeReleasesTags = "https://api.github.com/repos/AdGuardTeam/AdGuardHome/releases/tags";
|
||||||
static const String googleSearchUrl = "https://www.google.com/search";
|
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 connectionInstructions = "https://github.com/JGeek00/adguard-home-manager/wiki/Create-a-connection";
|
||||||
|
|
|
@ -3,8 +3,8 @@ import 'dart:io';
|
||||||
import 'package:store_checker/store_checker.dart';
|
import 'package:store_checker/store_checker.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||||
|
import 'package:adguard_home_manager/services/external_requests.dart';
|
||||||
import 'package:adguard_home_manager/models/github_release.dart';
|
import 'package:adguard_home_manager/models/github_release.dart';
|
||||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
|
||||||
|
|
||||||
Future<GitHubRelease?> checkAppUpdates({
|
Future<GitHubRelease?> checkAppUpdates({
|
||||||
required String currentBuildNumber,
|
required String currentBuildNumber,
|
||||||
|
@ -12,21 +12,27 @@ Future<GitHubRelease?> checkAppUpdates({
|
||||||
required Source installationSource,
|
required Source installationSource,
|
||||||
required bool isBeta
|
required bool isBeta
|
||||||
}) async {
|
}) async {
|
||||||
final result = await checkAppUpdatesGitHub();
|
var result = isBeta
|
||||||
|
? await ExternalRequests.getReleasesGitHub()
|
||||||
|
: await ExternalRequests.getReleaseData();
|
||||||
|
|
||||||
|
if (result.successful == true) {
|
||||||
|
late GitHubRelease gitHubRelease;
|
||||||
|
if (isBeta) {
|
||||||
|
gitHubRelease = (result.content as List<GitHubRelease>).firstWhere((r) => r.prerelease == true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gitHubRelease = result.content as GitHubRelease;
|
||||||
|
}
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
|
||||||
final update = gitHubUpdateExists(
|
final update = gitHubUpdateExists(
|
||||||
currentBuildNumber: currentBuildNumber,
|
currentBuildNumber: currentBuildNumber,
|
||||||
gitHubReleases: result['body'],
|
gitHubRelease: gitHubRelease,
|
||||||
isBeta: isBeta
|
isBeta: isBeta
|
||||||
);
|
);
|
||||||
|
print(update);
|
||||||
if (update == true) {
|
if (update == true) {
|
||||||
final release = isBeta == true
|
setUpdateAvailable(gitHubRelease);
|
||||||
? result['body'].firstWhere((release) => release.prerelease == true)
|
|
||||||
: result['body'].firstWhere((release) => release.prerelease == false);
|
|
||||||
|
|
||||||
setUpdateAvailable(release);
|
|
||||||
|
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
if (
|
if (
|
||||||
|
@ -34,7 +40,7 @@ Future<GitHubRelease?> checkAppUpdates({
|
||||||
installationSource == Source.IS_INSTALLED_FROM_PLAY_PACKAGE_INSTALLER ||
|
installationSource == Source.IS_INSTALLED_FROM_PLAY_PACKAGE_INSTALLER ||
|
||||||
installationSource == Source.UNKNOWN
|
installationSource == Source.UNKNOWN
|
||||||
) {
|
) {
|
||||||
return release;
|
return gitHubRelease;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -44,7 +50,7 @@ Future<GitHubRelease?> checkAppUpdates({
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return release;
|
return gitHubRelease;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -4,27 +4,20 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/services/api_client.dart';
|
||||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||||
import 'package:adguard_home_manager/models/server.dart';
|
import 'package:adguard_home_manager/models/server.dart';
|
||||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
|
||||||
|
|
||||||
Future<bool> clearDnsCache(BuildContext context, Server server) async {
|
Future<ApiResponse> clearDnsCache(BuildContext context, Server server) async {
|
||||||
final serversProvider = Provider.of<ServersProvider>(context, listen: false);
|
final serversProvider = Provider.of<ServersProvider>(context, listen: false);
|
||||||
|
|
||||||
final ProcessModal processModal = ProcessModal(context: context);
|
final ProcessModal processModal = ProcessModal();
|
||||||
processModal.open(AppLocalizations.of(context)!.clearingDnsCache);
|
processModal.open(AppLocalizations.of(context)!.clearingDnsCache);
|
||||||
|
|
||||||
final result = await serversProvider.apiClient!.resetDnsCache();
|
final result = await serversProvider.apiClient2!.resetDnsCache();
|
||||||
|
|
||||||
processModal.close();
|
processModal.close();
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
return result;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
final appConfigProvider = Provider.of<AppConfigProvider>(context, listen: false);
|
|
||||||
appConfigProvider.addLog(result['log']);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -151,15 +151,11 @@ bool serverVersionIsAhead({
|
||||||
|
|
||||||
bool gitHubUpdateExists({
|
bool gitHubUpdateExists({
|
||||||
required String currentBuildNumber,
|
required String currentBuildNumber,
|
||||||
required List<GitHubRelease> gitHubReleases,
|
required GitHubRelease gitHubRelease,
|
||||||
required bool isBeta
|
required bool isBeta
|
||||||
}) {
|
}) {
|
||||||
final release = isBeta == true
|
|
||||||
? gitHubReleases.firstWhere((release) => release.prerelease == true)
|
|
||||||
: gitHubReleases.firstWhere((release) => release.prerelease == false);
|
|
||||||
|
|
||||||
final versionNumberRegex = RegExp(r'\(\d+\)');
|
final versionNumberRegex = RegExp(r'\(\d+\)');
|
||||||
final releaseNumberExtractedMatches = versionNumberRegex.allMatches(release.tagName);
|
final releaseNumberExtractedMatches = versionNumberRegex.allMatches(gitHubRelease.tagName);
|
||||||
|
|
||||||
if (releaseNumberExtractedMatches.isNotEmpty) {
|
if (releaseNumberExtractedMatches.isNotEmpty) {
|
||||||
final releaseNumberExtracted = releaseNumberExtractedMatches.first.group(0);
|
final releaseNumberExtracted = releaseNumberExtractedMatches.first.group(0);
|
||||||
|
@ -181,12 +177,12 @@ bool gitHubUpdateExists({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Sentry.captureMessage("Invalid release number. Tagname: ${release.tagName}");
|
Sentry.captureMessage("Invalid release number. Tagname: ${gitHubRelease.tagName}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Sentry.captureMessage("No matches. ${release.tagName}");
|
Sentry.captureMessage("No matches. ${gitHubRelease.tagName}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
5
lib/functions/desktop_mode.dart
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import 'package:adguard_home_manager/config/sizes.dart';
|
||||||
|
|
||||||
|
bool isDesktop(double width) {
|
||||||
|
return width > desktopBreakpoint;
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
"connect": "Connect",
|
"connect": "Connect",
|
||||||
"servers": "Servers",
|
"servers": "Servers",
|
||||||
"createConnection": "Create connection",
|
"createConnection": "Create connection",
|
||||||
|
"editConnection": "Edit connection",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"ipDomain": "IP address or domain",
|
"ipDomain": "IP address or domain",
|
||||||
"path": "Path",
|
"path": "Path",
|
||||||
|
@ -56,10 +57,10 @@
|
||||||
"serverStatusNotRefreshed": "Server status could not be refreshed",
|
"serverStatusNotRefreshed": "Server status could not be refreshed",
|
||||||
"loadingStatus": "Loading status...",
|
"loadingStatus": "Loading status...",
|
||||||
"errorLoadServerStatus": "Server status could not be loaded",
|
"errorLoadServerStatus": "Server status could not be loaded",
|
||||||
"topQueriedDomains": "Top queried domains",
|
"topQueriedDomains": "Queried domains",
|
||||||
"viewMore": "View more",
|
"viewMore": "View more",
|
||||||
"topClients": "Top clients",
|
"topClients": "Clients",
|
||||||
"topBlockedDomains": "Top blocked domains",
|
"topBlockedDomains": "Blocked domains",
|
||||||
"appSettings": "App settings",
|
"appSettings": "App settings",
|
||||||
"theme": "Theme",
|
"theme": "Theme",
|
||||||
"light": "Light",
|
"light": "Light",
|
||||||
|
@ -170,7 +171,7 @@
|
||||||
"dnsQueries": "DNS queries",
|
"dnsQueries": "DNS queries",
|
||||||
"average": "Average",
|
"average": "Average",
|
||||||
"blockedFilters": "Blocked by filters",
|
"blockedFilters": "Blocked by filters",
|
||||||
"malwarePhisingBlocked": "Blocked malware/phising",
|
"malwarePhishingBlocked": "Blocked malware/phishing",
|
||||||
"blockedAdultWebsites": "Blocked adult websites",
|
"blockedAdultWebsites": "Blocked adult websites",
|
||||||
"generalSettings": "General settings",
|
"generalSettings": "General settings",
|
||||||
"generalSettingsDescription": "Various different settings",
|
"generalSettingsDescription": "Various different settings",
|
||||||
|
@ -316,6 +317,7 @@
|
||||||
"deletingRule": "Deleting rule...",
|
"deletingRule": "Deleting rule...",
|
||||||
"enablingList": "Enabling list...",
|
"enablingList": "Enabling list...",
|
||||||
"disablingList": "Disabling list...",
|
"disablingList": "Disabling list...",
|
||||||
|
"savingList": "Saving list...",
|
||||||
"disableFiltering": "Disable filtering",
|
"disableFiltering": "Disable filtering",
|
||||||
"enablingFiltering": "Enabling filtering...",
|
"enablingFiltering": "Enabling filtering...",
|
||||||
"disablingFiltering": "Disabling filtering...",
|
"disablingFiltering": "Disabling filtering...",
|
||||||
|
@ -649,7 +651,7 @@
|
||||||
"october": "October",
|
"october": "October",
|
||||||
"november": "November",
|
"november": "November",
|
||||||
"december": "December",
|
"december": "December",
|
||||||
"malwarePhising": "Malware/phising",
|
"malwarePhishing": "Malware/phishing",
|
||||||
"queries": "Queries",
|
"queries": "Queries",
|
||||||
"adultSites": "Adult sites",
|
"adultSites": "Adult sites",
|
||||||
"quickFilters": "Quick filters",
|
"quickFilters": "Quick filters",
|
||||||
|
@ -660,5 +662,69 @@
|
||||||
"topItemsOrderDescription": "Order the home screen top items lists",
|
"topItemsOrderDescription": "Order the home screen top items lists",
|
||||||
"topItemsReorderInfo": "Hold and swipe an item to reorder it.",
|
"topItemsReorderInfo": "Hold and swipe an item to reorder it.",
|
||||||
"discardChanges": "Discard changes",
|
"discardChanges": "Discard changes",
|
||||||
"discardChangesDescription": "Are you sure you want to discard the changes?"
|
"discardChangesDescription": "Are you sure you want to discard the changes?",
|
||||||
|
"others": "Others",
|
||||||
|
"showChart": "Show chart",
|
||||||
|
"hideChart": "Hide chart",
|
||||||
|
"showTopItemsChart": "Show top items chart",
|
||||||
|
"showTopItemsChartDescription": "Shows by default the ring chart on the top items sections. Only affects to the mobile view.",
|
||||||
|
"openMenu": "Open menu",
|
||||||
|
"closeMenu": "Close menu",
|
||||||
|
"openListUrl": "Open list URL",
|
||||||
|
"selectionMode": "Selection mode",
|
||||||
|
"enableDisableSelected": "Enable or disable selected items",
|
||||||
|
"deleteSelected": "Delete selected items",
|
||||||
|
"deleteSelectedLists": "Delete selected lists",
|
||||||
|
"allSelectedListsDeletedSuccessfully": "All selected lists have been deleted successfully.",
|
||||||
|
"deletionResult": "Deletion result",
|
||||||
|
"deletingLists": "Deleting lists...",
|
||||||
|
"failedElements": "Failed elements",
|
||||||
|
"processingLists": "Processing lists...",
|
||||||
|
"enableDisableResult": "Enable or disable result",
|
||||||
|
"selectedListsEnabledDisabledSuccessfully": "All selected lists have been enabled or disabled successfully",
|
||||||
|
"sslWarning": "If you are using an HTTPS connection with a self signed certificate, make sure to enable \"Don't check SSL certificate\" at Settings > Advanced settings.",
|
||||||
|
"unsupportedServerVersion": "Unsupported server version",
|
||||||
|
"unsupportedServerVersionMessage": "Your AdGuard Home server version is too old and is not supported by AdGuard Home Manager. You will need to upgrade your AdGuard Home server to a newer version to use this application.",
|
||||||
|
"yourVersion": "Your version: {version}",
|
||||||
|
"minimumRequiredVersion": "Minimum required version: {version}",
|
||||||
|
"topUpstreams": "Top upstreams",
|
||||||
|
"averageUpstreamResponseTime": "Average upstream response time",
|
||||||
|
"dhcpNotAvailable": "The DHCP server is not available.",
|
||||||
|
"osServerInstalledIncompatible": "The OS where the server is installed is not compatible with this feature.",
|
||||||
|
"resetSettings": "Reset settings",
|
||||||
|
"resetEncryptionSettingsDescription": "Are you sure you want to reset to default values the encryption settings?",
|
||||||
|
"resettingConfig": "Resetting configuration...",
|
||||||
|
"configurationResetSuccessfully": "Configuration resetted successfully",
|
||||||
|
"configurationResetError": "The configuration couldn't be resetted",
|
||||||
|
"testUpstreamDnsServers": "Test upstream DNS servers",
|
||||||
|
"errorTestUpstreamDns": "Error when testing upstream DNS servers.",
|
||||||
|
"useCustomIpEdns": "Use custom IP for EDNS",
|
||||||
|
"useCustomIpEdnsDescription": "Allow to use custom IP for EDNS",
|
||||||
|
"sortingOptions": "Sorting options",
|
||||||
|
"fromHighestToLowest": "From highest to lowest",
|
||||||
|
"fromLowestToHighest": "From lowest to highest",
|
||||||
|
"queryLogsAndStatistics": "Query logs and statistics",
|
||||||
|
"ignoreClientQueryLog": "Ignore this client in query log",
|
||||||
|
"ignoreClientStatistics": "Ignore this client in statistics",
|
||||||
|
"savingChanges": "Saving changes...",
|
||||||
|
"fallbackDnsServers": "Fallback DNS servers",
|
||||||
|
"fallbackDnsServersDescription": "Configure fallback DNS servers",
|
||||||
|
"fallbackDnsServersInfo": "List of fallback DNS servers used when upstream DNS servers are not responding. The syntax is the same as in the main upstreams field above.",
|
||||||
|
"noFallbackDnsAdded": "No fallback DNS servers added.",
|
||||||
|
"blockedResponseTtl": "Blocked response TTL",
|
||||||
|
"blockedResponseTtlDescription": "Specifies for how many seconds the clients should cache a filtered response",
|
||||||
|
"invalidValue": "Invalid value",
|
||||||
|
"noDataChart": "There's no data to display this chart.",
|
||||||
|
"noData": "No data",
|
||||||
|
"unblockClient": "Unblock client",
|
||||||
|
"blockingClient": "Blocking client...",
|
||||||
|
"unblockingClient": "Unblocking client...",
|
||||||
|
"upstreamDnsCacheConfiguration": "Configuración de la caché DNS upstream",
|
||||||
|
"enableDnsCachingClient": "Enable DNS caching for this client",
|
||||||
|
"dnsCacheSize": "DNS cache size",
|
||||||
|
"nameInvalid": "Name is required",
|
||||||
|
"oneIdentifierRequired": "At least one identifier is required",
|
||||||
|
"dnsCacheNumber": "DNS cache size must be a number",
|
||||||
|
"errors": "Errors",
|
||||||
|
"redirectHttpsWarning": "If you have enabled \"Redirect to HTTPS automatically\" on your AdGuard Home server, you must select an HTTPS connection and use the HTTPS port of your server."
|
||||||
}
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
"connect": "Conectar",
|
"connect": "Conectar",
|
||||||
"servers": "Servidores",
|
"servers": "Servidores",
|
||||||
"createConnection": "Crear conexión",
|
"createConnection": "Crear conexión",
|
||||||
|
"editConnection": "Editar conexión",
|
||||||
"name": "Nombre",
|
"name": "Nombre",
|
||||||
"ipDomain": "Dirección IP o dominio",
|
"ipDomain": "Dirección IP o dominio",
|
||||||
"path": "Ruta",
|
"path": "Ruta",
|
||||||
|
@ -56,10 +57,10 @@
|
||||||
"serverStatusNotRefreshed": "No se ha podido actualizar el estado del servidor",
|
"serverStatusNotRefreshed": "No se ha podido actualizar el estado del servidor",
|
||||||
"loadingStatus": "Cargando estado...",
|
"loadingStatus": "Cargando estado...",
|
||||||
"errorLoadServerStatus": "Error al cargar el estado",
|
"errorLoadServerStatus": "Error al cargar el estado",
|
||||||
"topQueriedDomains": "Top dominios solicitados",
|
"topQueriedDomains": "Dominios solicitados",
|
||||||
"viewMore": "Ver más",
|
"viewMore": "Ver más",
|
||||||
"topClients": "Top clientes recurrentes",
|
"topClients": "Clientes recurrentes",
|
||||||
"topBlockedDomains": "Top dominios bloqueados",
|
"topBlockedDomains": "Dominios bloqueados",
|
||||||
"appSettings": "Ajustes de la app",
|
"appSettings": "Ajustes de la app",
|
||||||
"theme": "Tema",
|
"theme": "Tema",
|
||||||
"light": "Claro",
|
"light": "Claro",
|
||||||
|
@ -170,7 +171,7 @@
|
||||||
"dnsQueries": "Consultas DNS",
|
"dnsQueries": "Consultas DNS",
|
||||||
"average": "Promedio",
|
"average": "Promedio",
|
||||||
"blockedFilters": "Bloqueado por filtros",
|
"blockedFilters": "Bloqueado por filtros",
|
||||||
"malwarePhisingBlocked": "Malware/phising bloqueado",
|
"malwarePhishingBlocked": "Malware/phising bloqueado",
|
||||||
"blockedAdultWebsites": "Sitios para adultos bloqueados",
|
"blockedAdultWebsites": "Sitios para adultos bloqueados",
|
||||||
"generalSettings": "Ajustes generales",
|
"generalSettings": "Ajustes generales",
|
||||||
"generalSettingsDescription": "Varios ajustes generales",
|
"generalSettingsDescription": "Varios ajustes generales",
|
||||||
|
@ -316,6 +317,7 @@
|
||||||
"deletingRule": "Eliminando regla...",
|
"deletingRule": "Eliminando regla...",
|
||||||
"enablingList": "Habilitando lista...",
|
"enablingList": "Habilitando lista...",
|
||||||
"disablingList": "Deshabilitando lista...",
|
"disablingList": "Deshabilitando lista...",
|
||||||
|
"savingList": "Guardando lista...",
|
||||||
"disableFiltering": "Deshabilitar filtrado",
|
"disableFiltering": "Deshabilitar filtrado",
|
||||||
"enablingFiltering": "Habilitando filtrado...",
|
"enablingFiltering": "Habilitando filtrado...",
|
||||||
"disablingFiltering": "Deshabilitando filtrado...",
|
"disablingFiltering": "Deshabilitando filtrado...",
|
||||||
|
@ -649,7 +651,7 @@
|
||||||
"october": "Octubre",
|
"october": "Octubre",
|
||||||
"november": "Noviembre",
|
"november": "Noviembre",
|
||||||
"december": "Diciembre",
|
"december": "Diciembre",
|
||||||
"malwarePhising": "Malware/phising",
|
"malwarePhishing": "Malware/phising",
|
||||||
"queries": "Peticiones",
|
"queries": "Peticiones",
|
||||||
"adultSites": "Sitios de adultos",
|
"adultSites": "Sitios de adultos",
|
||||||
"quickFilters": "Filtros rápidos",
|
"quickFilters": "Filtros rápidos",
|
||||||
|
@ -660,5 +662,69 @@
|
||||||
"topItemsOrderDescription": "Ordena las listas de top de elementos en la pantalla de inicio",
|
"topItemsOrderDescription": "Ordena las listas de top de elementos en la pantalla de inicio",
|
||||||
"topItemsReorderInfo": "Mantén presionado y desliza un elemento para reordenarlo.",
|
"topItemsReorderInfo": "Mantén presionado y desliza un elemento para reordenarlo.",
|
||||||
"discardChanges": "Descartar cambios",
|
"discardChanges": "Descartar cambios",
|
||||||
"discardChangesDescription": "¿Estás seguro de que deseas descartar los cambios realizados?"
|
"discardChangesDescription": "¿Estás seguro de que deseas descartar los cambios realizados?",
|
||||||
|
"others": "Otros",
|
||||||
|
"showChart": "Mostrar gráfico",
|
||||||
|
"hideChart": "Ocultar gráfico",
|
||||||
|
"showTopItemsChart": "Mostrar gráfico en top de items",
|
||||||
|
"showTopItemsChartDescription": "Muestra por defecto el gráfico de anillo en las secciones de top de items. Sólo afecta a la vista móvil.",
|
||||||
|
"openMenu": "Abrir menú",
|
||||||
|
"closeMenu": "Cerrar menú",
|
||||||
|
"openListUrl": "Abrir URL de lista",
|
||||||
|
"selectionMode": "Modo de selección",
|
||||||
|
"enableDisableSelected": "Activar o desactivar elementos seleccionados",
|
||||||
|
"deleteSelected": "Eliminar elementos seleccionados",
|
||||||
|
"deleteSelectedLists": "Eliminar listas seleccionadas",
|
||||||
|
"allSelectedListsDeletedSuccessfully": "Todas las listas seleccionadas han sido eliminadas correctamente.",
|
||||||
|
"deletionResult": "Resultado de eliminación",
|
||||||
|
"deletingLists": "Eliminando listas...",
|
||||||
|
"failedElements": "Elementos fallidos",
|
||||||
|
"processingLists": "Procesando listas...",
|
||||||
|
"enableDisableResult": "Resultado de activar o desactivar",
|
||||||
|
"selectedListsEnabledDisabledSuccessfully": "Todas las listas seleccionadas se han activado o desactivado correctamente.",
|
||||||
|
"sslWarning": "Si estás usando una conexión HTTPS con un certificado autofirmado, asegúrate de activar \"No comprobar el certificado SSL\" en Ajustes > Ajustes avanzados.",
|
||||||
|
"unsupportedServerVersion": "Versión del servidor no soportada",
|
||||||
|
"unsupportedServerVersionMessage": "La versión de tu servidor AdGuard Home es demasiado antigua y no está soportada por AdGuard Home Manager. Necesitarás actualizar tu servidor AdGuard Home a una versión más actual para utilizar esta aplicación.",
|
||||||
|
"yourVersion": "Tu versión: {version}",
|
||||||
|
"minimumRequiredVersion": "Versión mínima requerida: {version}",
|
||||||
|
"topUpstreams": "DNS de subida más frecuentes",
|
||||||
|
"averageUpstreamResponseTime": "Tiempo promedio de respuesta upstream",
|
||||||
|
"dhcpNotAvailable": "El servidor DHCP no está disponible.",
|
||||||
|
"osServerInstalledIncompatible": "El SO donde el servidor está instalado no es compatible con esta característica.",
|
||||||
|
"resetSettings": "Resetear configuración",
|
||||||
|
"resetEncryptionSettingsDescription": "Estás seguro que deseas restaurar a valores por defecto la configuración de encriptación?",
|
||||||
|
"resettingConfig": "Reseteando configuración...",
|
||||||
|
"configurationResetSuccessfully": "Configuración reseteada correctamente",
|
||||||
|
"configurationResetError": "La configuración no ha podido ser reseteada",
|
||||||
|
"testUpstreamDnsServers": "Probar servidores DNS de subida",
|
||||||
|
"errorTestUpstreamDns": "Error al probar los servidores DNS de subida.",
|
||||||
|
"useCustomIpEdns": "Usar IP personalizada para EDNS",
|
||||||
|
"useCustomIpEdnsDescription": "Permitir usar IP personalizada para EDNS",
|
||||||
|
"sortingOptions": "Opciones de ordenación",
|
||||||
|
"fromHighestToLowest": "De mayor a menor",
|
||||||
|
"fromLowestToHighest": "De menor a mayor",
|
||||||
|
"queryLogsAndStatistics": "Registro de consultas y estadísticas",
|
||||||
|
"ignoreClientQueryLog": "Ignorar este cliente en el registro de consultas",
|
||||||
|
"ignoreClientStatistics": "Ignorar este cliente en las estadísticas",
|
||||||
|
"savingChanges": "Guardando cambios...",
|
||||||
|
"fallbackDnsServers": "Servidores DNS alternativos",
|
||||||
|
"fallbackDnsServersDescription": "Configura los servidores DNS alternativos",
|
||||||
|
"fallbackDnsServersInfo": "Lista de servidores DNS alternativos utilizados cuando los servidores DNS de subida no responden. La sintaxis es la misma que en el campo de los principales DNS de subida anterior.",
|
||||||
|
"noFallbackDnsAdded": "No hay servidores DNS alternativos añadidos.",
|
||||||
|
"blockedResponseTtl": "Respuesta TTL bloqueada",
|
||||||
|
"blockedResponseTtlDescription": "Especifica durante cuántos segundos los clientes deben almacenar en cache una respuesta filtrada",
|
||||||
|
"invalidValue": "Valor no válido",
|
||||||
|
"noDataChart": "No hay datos para mostrar este gráfico.",
|
||||||
|
"noData": "No hay datos",
|
||||||
|
"unblockClient": "Desbloquear cliente",
|
||||||
|
"blockingClient": "Bloqueando cliente...",
|
||||||
|
"unblockingClient": "Desbloqueando cliente...",
|
||||||
|
"upstreamDnsCacheConfiguration": "Configuración de la caché DNS upstream",
|
||||||
|
"enableDnsCachingClient": "Habilitar caché de DNS para este cliente",
|
||||||
|
"dnsCacheSize": "Tamaño de caché de DNS",
|
||||||
|
"nameInvalid": "Se requiere un nombre",
|
||||||
|
"oneIdentifierRequired": "Se require al menos un identificador",
|
||||||
|
"dnsCacheNumber": "El tamaño de caché de DNS debe ser un número",
|
||||||
|
"errors": "Errores",
|
||||||
|
"redirectHttpsWarning": "Si tienes activado \"Redireccionar a HTTPS automáticamente\" en tu servidor AdGuard Home, debes seleccionar una conexión HTTPS y utilizar el puerto de HTTPS de tu servidor."
|
||||||
}
|
}
|
|
@ -170,7 +170,7 @@
|
||||||
"dnsQueries": "Zapytania DNS",
|
"dnsQueries": "Zapytania DNS",
|
||||||
"average": "Średnia",
|
"average": "Średnia",
|
||||||
"blockedFilters": "Zablokowane przez filtry",
|
"blockedFilters": "Zablokowane przez filtry",
|
||||||
"malwarePhisingBlocked": "Zablokowane złośliwe oprogramowanie/phishing",
|
"malwarePhishingBlocked": "Zablokowane złośliwe oprogramowanie/phishing",
|
||||||
"blockedAdultWebsites": "Zablokowane witryny dla dorosłych",
|
"blockedAdultWebsites": "Zablokowane witryny dla dorosłych",
|
||||||
"generalSettings": "Ustawienia główne",
|
"generalSettings": "Ustawienia główne",
|
||||||
"generalSettingsDescription": "Różne ustawienia",
|
"generalSettingsDescription": "Różne ustawienia",
|
||||||
|
@ -649,7 +649,7 @@
|
||||||
"october": "Październik",
|
"october": "Październik",
|
||||||
"november": "Listopad",
|
"november": "Listopad",
|
||||||
"december": "Grudzień",
|
"december": "Grudzień",
|
||||||
"malwarePhising": "Złośliwe oprogramowanie / wyłudzanie informacji",
|
"malwarePhishing": "Złośliwe oprogramowanie / wyłudzanie informacji",
|
||||||
"queries": "Zapytania",
|
"queries": "Zapytania",
|
||||||
"adultSites": "Strony dla dorosłych",
|
"adultSites": "Strony dla dorosłych",
|
||||||
"quickFilters": "Szybkie filtry",
|
"quickFilters": "Szybkie filtry",
|
||||||
|
|
692
lib/l10n/app_tr.arb
Normal file
|
@ -0,0 +1,692 @@
|
||||||
|
{
|
||||||
|
"home": "Anasayfa",
|
||||||
|
"settings": "Ayarlar",
|
||||||
|
"connect": "Bağlan",
|
||||||
|
"servers": "Sunucular",
|
||||||
|
"createConnection": "Bağlantı oluştur",
|
||||||
|
"editConnection": "Bağlantıyı düzenle",
|
||||||
|
"name": "Ad",
|
||||||
|
"ipDomain": "IP adresi veya alan adı",
|
||||||
|
"path": "Dosya Yolu",
|
||||||
|
"port": "Bağlantı noktası",
|
||||||
|
"username": "Kullanıcı adı",
|
||||||
|
"password": "Şifre",
|
||||||
|
"defaultServer": "Varsayılan sunucu",
|
||||||
|
"general": "Genel",
|
||||||
|
"connection": "Bağlantı",
|
||||||
|
"authentication": "Kimlik doğrulama",
|
||||||
|
"other": "Diğer",
|
||||||
|
"invalidPort": "Geçersiz bağlantı noktası",
|
||||||
|
"invalidPath": "Geçersiz dosya yolu",
|
||||||
|
"invalidIpDomain": "Geçersiz IP veya alan adı",
|
||||||
|
"ipDomainNotEmpty": "IP veya alan adı boş olamaz",
|
||||||
|
"nameNotEmpty": "Ad boş bırakılamaz",
|
||||||
|
"invalidUsernamePassword": "Geçersiz kullanıcı adı veya şifre",
|
||||||
|
"tooManyAttempts": "Çok fazla deneme yapıldı. Daha sonra tekrar deneyin.",
|
||||||
|
"cantReachServer": "Sunucuya ulaşılamıyor. Bağlantınızı kontrol edin.",
|
||||||
|
"sslError": "SSL hatası. Ayarlar > Gelişmiş ayarlar bölümüne gidin ve SSL doğrulamasını geçersiz kıl seçeneğini etkinleştirin.",
|
||||||
|
"unknownError": "Bilinmeyen hata",
|
||||||
|
"connectionNotCreated": "Bağlantı kurulamadı",
|
||||||
|
"connecting": "Bağlanılıyor...",
|
||||||
|
"connected": "Bağlantı kuruldu",
|
||||||
|
"selectedDisconnected": "Seçildi ancak bağlantı kesildi",
|
||||||
|
"connectionDefaultSuccessfully": "Bağlantı başarıyla varsayılan olarak ayarlandı.",
|
||||||
|
"connectionDefaultFailed": "Bağlantı varsayılan olarak ayarlanamadı.",
|
||||||
|
"noSavedConnections": "Kaydedilmiş bağlantı yok",
|
||||||
|
"cannotConnect": "Sunucuya bağlanılamıyor",
|
||||||
|
"connectionRemoved": "Bağlantı başarıyla kaldırıldı",
|
||||||
|
"connectionCannotBeRemoved": "Bağlantı kaldırılamaz.",
|
||||||
|
"remove": "Kaldır",
|
||||||
|
"removeWarning": "Bu AdGuard Home sunucusuyla olan bağlantıyı kaldırmak istediğinizden emin misiniz?",
|
||||||
|
"cancel": "İptal",
|
||||||
|
"defaultConnection": "Varsayılan bağlantı",
|
||||||
|
"setDefault": "Varsayılan ayarla",
|
||||||
|
"edit": "Düzenle",
|
||||||
|
"delete": "Sil",
|
||||||
|
"save": "Kaydet",
|
||||||
|
"serverStatus": "Sunucu durumu",
|
||||||
|
"connectionNotUpdated": "Bağlantı Güncellenmedi",
|
||||||
|
"ruleFilteringWidget": "Kural filtreleme",
|
||||||
|
"safeBrowsingWidget": "Güvenli gezinti",
|
||||||
|
"parentalFilteringWidget": "Ebeveyn filtreleme",
|
||||||
|
"safeSearchWidget": "Güvenli arama",
|
||||||
|
"ruleFiltering": "Kural filtreleme",
|
||||||
|
"safeBrowsing": "Güvenli gezinti",
|
||||||
|
"parentalFiltering": "Ebeveyn filtreleme",
|
||||||
|
"safeSearch": "Güvenli arama",
|
||||||
|
"serverStatusNotRefreshed": "Sunucu durumu yenilenemedi",
|
||||||
|
"loadingStatus": "Durum yükleniyor...",
|
||||||
|
"errorLoadServerStatus": "Sunucu durumu yüklenemedi",
|
||||||
|
"topQueriedDomains": "En çok sorgulananlar",
|
||||||
|
"viewMore": "Daha fazla göster",
|
||||||
|
"topClients": "Öne çıkan istemciler",
|
||||||
|
"topBlockedDomains": "En çok engellenenler",
|
||||||
|
"appSettings": "Uygulama ayarları",
|
||||||
|
"theme": "Tema",
|
||||||
|
"light": "Aydınlık",
|
||||||
|
"dark": "Karanlık",
|
||||||
|
"systemDefined": "Sistemle uyumlu hale getir",
|
||||||
|
"close": "Kapat",
|
||||||
|
"connectedTo": "Bağlandı:",
|
||||||
|
"selectedServer": "Seçili sunucu:",
|
||||||
|
"noServerSelected": "Seçili sunucu yok",
|
||||||
|
"manageServer": "Sunucuyu yönet",
|
||||||
|
"allProtections": "Tüm korumalar",
|
||||||
|
"userNotEmpty": "Kullanıcı adı boş bırakılamaz",
|
||||||
|
"passwordNotEmpty": "Şifre boş bırakılamaz",
|
||||||
|
"examplePath": "Örnek: /adguard",
|
||||||
|
"helperPath": "Ters proxy kullanıyorsanız",
|
||||||
|
"aboutApp": "Uygulama hakkında",
|
||||||
|
"appVersion": "Uygulama sürümü",
|
||||||
|
"createdBy": "Geliştirici",
|
||||||
|
"clients": "İstemciler",
|
||||||
|
"allowed": "İzin verildi",
|
||||||
|
"blocked": "Engellendi",
|
||||||
|
"noClientsList": "Bu listede hiç istemci yok",
|
||||||
|
"activeClients": "Etkin",
|
||||||
|
"removeClient": "İstemciyi kaldır",
|
||||||
|
"removeClientMessage": "Bu istemciyi listeden çıkarmak istediğinize emin misiniz?",
|
||||||
|
"confirm": "Onayla",
|
||||||
|
"removingClient": "İstemci kaldırılıyor...",
|
||||||
|
"clientNotRemoved": "İstemci listeden çıkarılamadı",
|
||||||
|
"addClient": "İstemci ekle",
|
||||||
|
"list": "Liste",
|
||||||
|
"ipAddress": "IP adresi",
|
||||||
|
"ipNotValid": "IP adresi geçersiz",
|
||||||
|
"clientAddedSuccessfully": "İstemci listeye başarıyla eklendi",
|
||||||
|
"addingClient": "İstemci ekleniyor...",
|
||||||
|
"clientNotAdded": "İstemci listeye eklenemedi",
|
||||||
|
"clientAnotherList": "Bu istemci henüz başka bir listede",
|
||||||
|
"noSavedLogs": "Kayıtlı günlük yok",
|
||||||
|
"logs": "Günlükler",
|
||||||
|
"copyLogsClipboard": "Günlükleri panoya kopyala",
|
||||||
|
"logsCopiedClipboard": "Günlükler panoya kopyalandı",
|
||||||
|
"advancedSettings": "Gelişmiş ayarlar",
|
||||||
|
"dontCheckCertificate": "SSL sertifikasını asla kontrol etme",
|
||||||
|
"dontCheckCertificateDescription": "Sunucunun SSL sertifikası doğrulamasını geçersiz kılar",
|
||||||
|
"advancedSetupDescription": "Gelişmiş seçenekleri yönet",
|
||||||
|
"settingsUpdatedSuccessfully": "Ayarlar başarıyla güncellendi.",
|
||||||
|
"cannotUpdateSettings": "Ayarlar güncellenemiyor.",
|
||||||
|
"restartAppTakeEffect": "Uygulamayı yeniden başlat",
|
||||||
|
"loadingLogs": "Günlükler yükleniyor...",
|
||||||
|
"logsNotLoaded": "Günlüklerin listesi yüklenemedi",
|
||||||
|
"processed": "İşlendi\nListe yok",
|
||||||
|
"processedRow": "İşlendi (Liste yok)",
|
||||||
|
"blockedBlacklist": "Engellendi\nKara Liste",
|
||||||
|
"blockedBlacklistRow": "Engellendi (Kara liste)",
|
||||||
|
"blockedSafeBrowsing": "Engellendi\nGüvenli gezinti",
|
||||||
|
"blockedSafeBrowsingRow": "Engellendi (Güvenli gezinti)",
|
||||||
|
"blockedParental": "Engellendi\nEbeveyn filtreleme",
|
||||||
|
"blockedParentalRow": "Engellendi (Ebeveyn filtreleme)",
|
||||||
|
"blockedInvalid": "Engellendi\nGeçersiz",
|
||||||
|
"blockedInvalidRow": "Engellendi (Geçersiz)",
|
||||||
|
"blockedSafeSearch": "Engellendi\nGüvenli arama",
|
||||||
|
"blockedSafeSearchRow": "Engellendi (Güvenli arama)",
|
||||||
|
"blockedService": "Engellendi\nBelirlenen hizmet",
|
||||||
|
"blockedServiceRow": "Engellendi (Belirlenen hizmet)",
|
||||||
|
"processedWhitelist": "İşlendi\nBeyaz liste",
|
||||||
|
"processedWhitelistRow": "İşlendi (Beyaz liste)",
|
||||||
|
"processedError": "İşlendi\nHata",
|
||||||
|
"processedErrorRow": "İşlendi (Hata)",
|
||||||
|
"rewrite": "Yeniden Yaz",
|
||||||
|
"status": "Durum",
|
||||||
|
"result": "Sonuç",
|
||||||
|
"time": "Zaman",
|
||||||
|
"blocklist": "Engelleme Listesi",
|
||||||
|
"request": "İstek",
|
||||||
|
"domain": "Alan adı",
|
||||||
|
"type": "Tip",
|
||||||
|
"clas": "Sınıf",
|
||||||
|
"response": "Yanıt",
|
||||||
|
"dnsServer": "DNS sunucusu",
|
||||||
|
"elapsedTime": "İşlem süresi",
|
||||||
|
"responseCode": "Yanıt kodu",
|
||||||
|
"client": "İstemci",
|
||||||
|
"deviceIp": "IP adresi",
|
||||||
|
"deviceName": "İstemci adı",
|
||||||
|
"logDetails": "Günlük detayları",
|
||||||
|
"blockingRule": "Engelleme kuralı",
|
||||||
|
"blockDomain": "Alan adını engelle",
|
||||||
|
"couldntGetFilteringStatus": "Filtreleme durumu alınamıyor",
|
||||||
|
"unblockDomain": "Alan adı engelini kaldır",
|
||||||
|
"userFilteringRulesNotUpdated": "Kullanıcı filtreleme kuralları güncellenemedi",
|
||||||
|
"userFilteringRulesUpdated": "Kullanıcı filtreleme kuralları başarıyla güncellendi",
|
||||||
|
"savingUserFilters": "Kullanıcı filtreleri kaydediliyor...",
|
||||||
|
"filters": "Filtreler",
|
||||||
|
"logsOlderThan": "Daha eski günlükler",
|
||||||
|
"responseStatus": "Yanıt durumu",
|
||||||
|
"selectTime": "Zaman seç",
|
||||||
|
"notSelected": "Seçili değil",
|
||||||
|
"resetFilters": "Filtreleri sıfırla",
|
||||||
|
"noLogsDisplay": "Gösterilecek günlük yok",
|
||||||
|
"noLogsThatOld": "Seçilen zaman için kaydedilmiş herhangi bir günlük bulunmuyor olabilir. Daha yakın bir zaman seçmeyi deneyin.",
|
||||||
|
"apply": "Uygula",
|
||||||
|
"selectAll": "Hepsini seç",
|
||||||
|
"unselectAll": "Seçimleri kaldır",
|
||||||
|
"all": "Hepsi",
|
||||||
|
"filtered": "Filtrelenmiş",
|
||||||
|
"checkAppLogs": "Uygulama günlüklerini kontrol edin",
|
||||||
|
"refresh": "Yenile",
|
||||||
|
"search": "Ara",
|
||||||
|
"dnsQueries": "DNS sorguları",
|
||||||
|
"average": "Ortalama",
|
||||||
|
"blockedFilters": "Engellenen alan adları",
|
||||||
|
"malwarePhishingBlocked": "Engellenen zararlı içerikler",
|
||||||
|
"blockedAdultWebsites": "Engellenen yetişkin içerikler",
|
||||||
|
"generalSettings": "Genel ayarlar",
|
||||||
|
"generalSettingsDescription": "Çeşitli farklı ayarları yönet",
|
||||||
|
"hideZeroValues": "Sıfır değerlerini gizle",
|
||||||
|
"hideZeroValuesDescription": "Ana ekranda, değeri sıfır olan blokları gizler.",
|
||||||
|
"webAdminPanel": "Web yönetim paneli",
|
||||||
|
"visitGooglePlay": "Google Play sayfasını ziyaret et",
|
||||||
|
"gitHub": "Kaynak kodlarına GitHub'dan ulaşabilirsiniz",
|
||||||
|
"blockClient": "İstemciyi engelle",
|
||||||
|
"selectTags": "Etiketleri seçin",
|
||||||
|
"noTagsSelected": "Seçili etiket yok",
|
||||||
|
"tags": "Etiketler",
|
||||||
|
"identifiers": "Tanımlayıcılar",
|
||||||
|
"identifier": "Tanımlayıcı",
|
||||||
|
"identifierHelper": "IP adresi, CIDR, MAC adresi veya ClientID",
|
||||||
|
"noIdentifiers": "Tanımlayıcı eklenmedi",
|
||||||
|
"useGlobalSettings": "Küresel ayarları kullan",
|
||||||
|
"enableFiltering": "Filtrelemeyi etkinleştir",
|
||||||
|
"enableSafeBrowsing": "Güvenli gezintiyi etkinleştir",
|
||||||
|
"enableParentalControl": "Ebeveyn kontrolünü etkinleştir",
|
||||||
|
"enableSafeSearch": "Güvenli aramayı aktif et",
|
||||||
|
"blockedServices": "Engellenen hizmetler",
|
||||||
|
"selectBlockedServices": "Engellenen hizmetleri seç",
|
||||||
|
"noBlockedServicesSelected": "Engellenen hizmetler seçilmedi",
|
||||||
|
"services": "Hizmetler",
|
||||||
|
"servicesBlocked": "Hizmetler engellendi",
|
||||||
|
"tagsSelected": "Seçilen etiketler",
|
||||||
|
"upstreamServers": "Üst kaynak sunucuları",
|
||||||
|
"serverAddress": "Sunucu adresi",
|
||||||
|
"noUpstreamServers": "Üst kaynak sunucusu yok.",
|
||||||
|
"willBeUsedGeneralServers": "Genel üst kaynak sunucuları kullanılacak.",
|
||||||
|
"added": "Eklenenler",
|
||||||
|
"clientUpdatedSuccessfully": "İstemci başarıyla güncellendi",
|
||||||
|
"clientNotUpdated": "İstemci güncellenemedi",
|
||||||
|
"clientDeletedSuccessfully": "İstemci başarıyla kaldırıldı",
|
||||||
|
"clientNotDeleted": "İstemci silinemedi",
|
||||||
|
"options": "Seçenekler",
|
||||||
|
"loadingFilters": "Filtreler yükleniyor...",
|
||||||
|
"filtersNotLoaded": "Filtreler yüklenemedi.",
|
||||||
|
"whitelists": "Beyaz listeler",
|
||||||
|
"blacklists": "Kara listeler",
|
||||||
|
"rules": "Kurallar",
|
||||||
|
"customRules": "Özel kurallar",
|
||||||
|
"enabledRules": "Etkin kurallar",
|
||||||
|
"enabled": "Etkin",
|
||||||
|
"disabled": "Devre dışı",
|
||||||
|
"rule": "Kural",
|
||||||
|
"addCustomRule": "Özel kural ekle",
|
||||||
|
"removeCustomRule": "Özel kuralı kaldır",
|
||||||
|
"removeCustomRuleMessage": "Bu özel kuralı kaldırmak istediğinizden emin misiniz?",
|
||||||
|
"updatingRules": "Özel kurallar güncelleniyor...",
|
||||||
|
"ruleRemovedSuccessfully": "Kural başarıyla kaldırıldı",
|
||||||
|
"ruleNotRemoved": "Kural kaldırılamadı",
|
||||||
|
"ruleAddedSuccessfully": "Kural başarıyla eklendi",
|
||||||
|
"ruleNotAdded": "Kural eklenemedi",
|
||||||
|
"noCustomFilters": "Özel filtreler yok",
|
||||||
|
"noBlockedClients": "Engellenmiş istemci yok",
|
||||||
|
"noBlackLists": "Kara listeler yok",
|
||||||
|
"noWhiteLists": "Beyaz listeler yok",
|
||||||
|
"addWhitelist": "Beyaz liste ekle",
|
||||||
|
"addBlacklist": "Kara liste ekle",
|
||||||
|
"urlNotValid": "Bağlantı adresi geçerli değil",
|
||||||
|
"urlAbsolutePath": "Bağlantı adresi veya kesin dosya yolu",
|
||||||
|
"addingList": "Liste ekleniyor...",
|
||||||
|
"listAdded": "Liste başarıyla eklendi. Eklenen öğeler:",
|
||||||
|
"listAlreadyAdded": "Liste zaten eklenmiş",
|
||||||
|
"listUrlInvalid": "Liste bağlantı adresi geçersiz",
|
||||||
|
"listNotAdded": "Liste eklenemedi",
|
||||||
|
"listDetails": "Liste detayları",
|
||||||
|
"listType": "Liste türü",
|
||||||
|
"whitelist": "Beyaz liste",
|
||||||
|
"blacklist": "Kara liste",
|
||||||
|
"latestUpdate": "Son güncelleme",
|
||||||
|
"disable": "Devre dışı bırak",
|
||||||
|
"enable": "Etkinleştir",
|
||||||
|
"currentStatus": "Mevcut durum",
|
||||||
|
"listDataUpdated": "Liste verileri başarıyla güncellendi",
|
||||||
|
"listDataNotUpdated": "Liste verileri güncellenemedi",
|
||||||
|
"updatingListData": "Liste verileri güncelleniyor...",
|
||||||
|
"editWhitelist": "Beyaz listeyi düzenle",
|
||||||
|
"editBlacklist": "Kara listeyi düzenle",
|
||||||
|
"deletingList": "Liste siliniyor...",
|
||||||
|
"listDeleted": "Liste başarıyla silindi",
|
||||||
|
"listNotDeleted": "Liste silinemedi",
|
||||||
|
"deleteList": "Listeyi sil",
|
||||||
|
"deleteListMessage": "Bu listeyi silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.",
|
||||||
|
"serverSettings": "Sunucu ayarları",
|
||||||
|
"serverInformation": "Sunucu bilgisi",
|
||||||
|
"serverInformationDescription": "Sunucu bilgisi ve durumunu öğren",
|
||||||
|
"loadingServerInfo": "Sunucu bilgisi yükleniyor...",
|
||||||
|
"serverInfoNotLoaded": "Sunucu bilgisi yüklenemedi.",
|
||||||
|
"dnsAddresses": "DNS adresleri",
|
||||||
|
"seeDnsAddresses": "DNS adreslerine göz at",
|
||||||
|
"dnsPort": "DNS bağlantı noktası",
|
||||||
|
"httpPort": "HTTP bağlantı noktası",
|
||||||
|
"protectionEnabled": "Koruma etkin mi?",
|
||||||
|
"dhcpAvailable": "DHCP mevcut mu?",
|
||||||
|
"serverRunning": "Sunucu çalışıyor mu?",
|
||||||
|
"serverVersion": "Sunucu sürümü",
|
||||||
|
"serverLanguage": "Sunucu dili",
|
||||||
|
"yes": "Evet",
|
||||||
|
"no": "Hayır",
|
||||||
|
"allowedClients": "İzin verilen istemciler",
|
||||||
|
"disallowedClients": "İzin verilmeyen istemciler",
|
||||||
|
"disallowedDomains": "İzin verilmeyen alan adları",
|
||||||
|
"accessSettings": "Erişim ayarları",
|
||||||
|
"accessSettingsDescription": "Sunucu için erişim kurallarını yapılandır",
|
||||||
|
"loadingClients": "İstemciler yükleniyor...",
|
||||||
|
"clientsNotLoaded": "İstemciler yüklenemedi.",
|
||||||
|
"noAllowedClients": "İzin verilmiş istemci yok",
|
||||||
|
"allowedClientsDescription": "Eğer bu liste girdiler içeriyorsa, AdGuard Home yalnızca bu istemcilerden gelen talepleri kabul edecektir.",
|
||||||
|
"blockedClientsDescription": "Bu liste girdileri içeriyorsa, AdGuard Home bu istemcilerden gelen talepleri reddedecektir. Bu alan adı, İzin Verilen İstemciler'de girdi varsa görmezden gelinir.",
|
||||||
|
"disallowedDomainsDescription": "AdGuard Home, bu alan adlarına uyan DNS sorgularını reddeder ve bu sorgular sorgu günlüğünde bile görünmez.",
|
||||||
|
"addClientFieldDescription": "CIDR'ler, IP adresi veya ClientID",
|
||||||
|
"clientIdentifier": "İstemci tanımlayıcısı",
|
||||||
|
"allowClient": "İstemciye izin ver",
|
||||||
|
"disallowClient": "İstemciye izin verme",
|
||||||
|
"noDisallowedDomains": "İzin verilmeyen alan adı yok",
|
||||||
|
"domainNotAdded": "Alan adı eklenemedi",
|
||||||
|
"statusSelected": "Durum seçildi.",
|
||||||
|
"updateLists": "Listeleri güncelle",
|
||||||
|
"checkHostFiltered": "Filtrelemeyi kontrol et",
|
||||||
|
"updatingLists": "Listeler güncelleniyor...",
|
||||||
|
"listsUpdated": "Listeler güncellendi",
|
||||||
|
"listsNotUpdated": "Listeler güncellenemedi",
|
||||||
|
"listsNotLoaded": "Listeler yüklenemedi",
|
||||||
|
"domainNotValid": "Alan adı geçersiz",
|
||||||
|
"check": "Kontrol et",
|
||||||
|
"checkingHost": "Kontrol ediliyor",
|
||||||
|
"errorCheckingHost": "Kontrol etme başarısız",
|
||||||
|
"block": "Engelle",
|
||||||
|
"unblock": "Engeli kaldır",
|
||||||
|
"custom": "Özel",
|
||||||
|
"addImportant": "Ekle ($important)",
|
||||||
|
"howCreateRules": "Özel kurallar nasıl oluşturulur?",
|
||||||
|
"examples": "Örnekler",
|
||||||
|
"example1": "example.org ve tüm alt alan adlarına erişimi engeller.",
|
||||||
|
"example2": "example.org ve tüm alt alan adlarına erişimi engellemeyi kaldırır.",
|
||||||
|
"example3": "Yorum ekler.",
|
||||||
|
"example4": "Belirtilen düzenli ifadeye uyan alan adlarına erişimi engeller.",
|
||||||
|
"moreInformation": "Daha fazla bilgi",
|
||||||
|
"addingRule": "Kural ekleniyor...",
|
||||||
|
"deletingRule": "Kural siliniyor...",
|
||||||
|
"enablingList": "Liste etkinleştiriliyor...",
|
||||||
|
"disablingList": "Liste devre dışı bırakılıyor...",
|
||||||
|
"savingList": "Liste kaydediliyor...",
|
||||||
|
"disableFiltering": "Filtrelemeyi devre dışı bırak",
|
||||||
|
"enablingFiltering": "Filtreleme etkinleştiriliyor...",
|
||||||
|
"disablingFiltering": "Filtreleme devre dışı bırakılıyor...",
|
||||||
|
"filteringStatusUpdated": "Filtreleme durumu başarıyla güncellendi",
|
||||||
|
"filteringStatusNotUpdated": "Filtreleme durumu güncellenemedi",
|
||||||
|
"updateFrequency": "Güncelleme sıklığı",
|
||||||
|
"never": "Asla",
|
||||||
|
"hour1": "1 saat",
|
||||||
|
"hours12": "12 saat",
|
||||||
|
"hours24": "24 saat",
|
||||||
|
"days3": "3 gün",
|
||||||
|
"days7": "7 gün",
|
||||||
|
"changingUpdateFrequency": "Değiştiriliyor...",
|
||||||
|
"updateFrequencyChanged": "Güncelleme sıklığı başarıyla değiştirildi",
|
||||||
|
"updateFrequencyNotChanged": "Güncelleme sıklığı değiştirilemedi",
|
||||||
|
"updating": "Değerler güncelleniyor...",
|
||||||
|
"blockedServicesUpdated": "Engellenen hizmetler başarıyla güncellendi",
|
||||||
|
"blockedServicesNotUpdated": "Engellenen hizmetler güncellenemedi",
|
||||||
|
"insertDomain": "Filtreleme durumunu kontrol etmek için bir alan adı ekleyin.",
|
||||||
|
"dhcpSettings": "DHCP ayarları",
|
||||||
|
"dhcpSettingsDescription": "DHCP sunucusunu yapılandır",
|
||||||
|
"dhcpSettingsNotLoaded": "DHCP ayarları yüklenemedi",
|
||||||
|
"loadingDhcp": "DHCP ayarları yükleniyor...",
|
||||||
|
"enableDhcpServer": "DHCP sunucusunu etkinleştir",
|
||||||
|
"selectInterface": "Arayüz seçin",
|
||||||
|
"hardwareAddress": "Donanım adresi",
|
||||||
|
"gatewayIp": "Ağ Geçidi IP'si",
|
||||||
|
"ipv4addresses": "IPv4 adresleri",
|
||||||
|
"ipv6addresses": "IPv6 adresleri",
|
||||||
|
"neededSelectInterface": "DHCP sunucusunu yapılandırmak için bir arayüz seçmeniz gerekir.",
|
||||||
|
"ipv4settings": "IPv4 ayarları",
|
||||||
|
"startOfRange": "Menzilin başlangıcı",
|
||||||
|
"endOfRange": "Menzilin sonu",
|
||||||
|
"ipv6settings": "IPv6 ayarları",
|
||||||
|
"subnetMask": "Alt ağ maskesi",
|
||||||
|
"subnetMaskNotValid": "Alt ağ maskesi geçerli değil",
|
||||||
|
"gateway": "Ağ Geçidi",
|
||||||
|
"gatewayNotValid": "Ağ geçidi geçerli değil",
|
||||||
|
"leaseTime": "Kira süresi",
|
||||||
|
"seconds": "{time} saniye",
|
||||||
|
"leaseTimeNotValid": "Kira süresi geçerli değil",
|
||||||
|
"restoreConfiguration": "Yapılandırmayı sıfırla",
|
||||||
|
"restoreConfigurationMessage": "Devam etmek istediğinizden emin misiniz? Bu, tüm yapılandırmayı sıfırlayacak. Bu işlem geri alınamaz.",
|
||||||
|
"changeInterface": "Arayüzü değiştir",
|
||||||
|
"savingSettings": "Ayarlar kaydediliyor...",
|
||||||
|
"settingsSaved": "Ayarlar başarıyla kaydedildi",
|
||||||
|
"settingsNotSaved": "Ayarlar kaydedilemedi",
|
||||||
|
"restoringConfig": "Yapılandırma geri yükleniyor...",
|
||||||
|
"configRestored": "Yapılandırma başarıyla sıfırlandı",
|
||||||
|
"configNotRestored": "Yapılandırma sıfırlanamadı",
|
||||||
|
"dhcpStatic": "DHCP statik kiralamaları",
|
||||||
|
"noDhcpStaticLeases": "DHCP statik kiralamaları bulunamadı",
|
||||||
|
"deleting": "Siliniyor...",
|
||||||
|
"staticLeaseDeleted": "DHCP statik kiralama başarıyla silindi",
|
||||||
|
"staticLeaseNotDeleted": "DHCP statik kiralaması silinemedi",
|
||||||
|
"deleteStaticLease": "Statik kiralamayı sil",
|
||||||
|
"deleteStaticLeaseDescription": "DHCP statik kirası silinecek. Bu işlem geri alınamaz.",
|
||||||
|
"addStaticLease": "Statik kiralama ekleyin",
|
||||||
|
"macAddress": "MAC adresi",
|
||||||
|
"macAddressNotValid": "MAC adresi geçersiz",
|
||||||
|
"hostName": "Ana bilgisayar adı",
|
||||||
|
"hostNameError": "Ana bilgisayar adı boş olamaz",
|
||||||
|
"creating": "Oluşturuluyor...",
|
||||||
|
"staticLeaseCreated": "DHCP statik kiralaması başarıyla oluşturuldu",
|
||||||
|
"staticLeaseNotCreated": "DHCP statik kiralaması oluşturulamadı",
|
||||||
|
"staticLeaseExists": "DHCP statik kiralaması zaten mevcut",
|
||||||
|
"serverNotConfigured": "Sunucu yapılandırılmamış",
|
||||||
|
"restoreLeases": "Kiralamaları sıfırla",
|
||||||
|
"restoreLeasesMessage": "Devam etmek istediğinizden emin misiniz? Bu, mevcut tüm kiralamaları sıfırlayacaktır. Bu işlem geri alınamaz.",
|
||||||
|
"restoringLeases": "Kiralamalar sıfırlanıyor...",
|
||||||
|
"leasesRestored": "Kiralamalar başarıyla sıfırlandı",
|
||||||
|
"leasesNotRestored": "Kiralar sıfırlanamadı",
|
||||||
|
"dhcpLeases": "DHCP kiralamaları",
|
||||||
|
"noLeases": "Kullanılabilir DHCP kiralaması yok",
|
||||||
|
"dnsRewrites": "DNS yeniden yazımları",
|
||||||
|
"dnsRewritesDescription": "Özel DNS kurallarını yapılandır",
|
||||||
|
"loadingRewriteRules": "Yeniden yazım kuralları yükleniyor...",
|
||||||
|
"rewriteRulesNotLoaded": "DNS yeniden yazım kuralları yüklenemedi.",
|
||||||
|
"noRewriteRules": "DNS yeniden yazım kuralları yok",
|
||||||
|
"answer": "Yanıt",
|
||||||
|
"deleteDnsRewrite": "DNS yeniden yazımı sil",
|
||||||
|
"deleteDnsRewriteMessage": "Bu DNS yeniden yazımını silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.",
|
||||||
|
"dnsRewriteRuleDeleted": "DNS yeniden yazım kuralı başarıyla silindi",
|
||||||
|
"dnsRewriteRuleNotDeleted": "DNS yeniden yazım kuralı silinemedi",
|
||||||
|
"addDnsRewrite": "DNS yeniden yazımı ekle",
|
||||||
|
"addingRewrite": "Yeniden yazım ekleniyor...",
|
||||||
|
"dnsRewriteRuleAdded": "DNS yeniden yazım kuralı başarıyla eklendi",
|
||||||
|
"dnsRewriteRuleNotAdded": "DNS yeniden yazım kuralı eklenemedi",
|
||||||
|
"logsSettings": "Günlük ayarları",
|
||||||
|
"enableLog": "Günlüğü etkinleştir",
|
||||||
|
"clearLogs": "Günlükleri temizle",
|
||||||
|
"anonymizeClientIp": "İstemci IP'sini anonimleştir",
|
||||||
|
"hours6": "6 saat",
|
||||||
|
"days30": "30 gün",
|
||||||
|
"days90": "90 gün",
|
||||||
|
"retentionTime": "Saklama süresi",
|
||||||
|
"selectOneItem": "Bir öğe seçin",
|
||||||
|
"logSettingsNotLoaded": "Günlük ayarları yüklenemedi.",
|
||||||
|
"updatingSettings": "Ayarlar güncelleniyor...",
|
||||||
|
"logsConfigUpdated": "Günlük ayarları başarıyla güncellendi",
|
||||||
|
"logsConfigNotUpdated": "Günlük ayarları başarıyla güncellendi",
|
||||||
|
"deletingLogs": "Günlükler temizleniyor...",
|
||||||
|
"logsCleared": "Günlükler başarıyla temizlendi",
|
||||||
|
"logsNotCleared": "Günlükler temizlenemedi",
|
||||||
|
"runningHomeAssistant": "Ev asistanı üzerinde çalıştır",
|
||||||
|
"serverError": "Sunucu hatası",
|
||||||
|
"noItems": "Burada gösterilecek öğe yok",
|
||||||
|
"dnsSettings": "DNS ayarları",
|
||||||
|
"dnsSettingsDescription": "DNS sunucuları ile bağlantıyı yapılandır",
|
||||||
|
"upstreamDns": "Üst kaynak DNS sunucuları",
|
||||||
|
"bootstrapDns": "Önyükleme DNS sunucuları",
|
||||||
|
"noUpstreamDns": "Üst kaynak DNS sunucuları eklenmedi.",
|
||||||
|
"dnsMode": "DNS modu",
|
||||||
|
"noDnsMode": "DNS modu seçili değil",
|
||||||
|
"loadBalancing": "Yük dengeleme",
|
||||||
|
"parallelRequests": "Paralel istekler",
|
||||||
|
"fastestIpAddress": "En hızlı IP adresi",
|
||||||
|
"loadBalancingDescription": "Her seferinde bir üst kaynak sunucusuna sorgu yap. AdGuard Home, sunucuyu seçmek için ağırlıklı rastgele algoritmasını kullanır, böylece en hızlı sunucu daha sık kullanılır.",
|
||||||
|
"parallelRequestsDescription": "Tüm üst kaynak sunucularını aynı anda sorgulayarak çözümlemeyi hızlandırmak için paralel sorgular kullanın.",
|
||||||
|
"fastestIpAddressDescription": "Tüm DNS sunucularına sorgu yapın ve tüm yanıtlar arasında en hızlı IP adresini döndürün. Bu, AdGuard Home'un tüm DNS sunucularından yanıtları beklemesi gerektiği için DNS sorgularını yavaşlatır, ancak genel bağlantıyı iyileştirir.",
|
||||||
|
"noBootstrapDns": "Önyükleme DNS sunucuları eklenmedi.",
|
||||||
|
"bootstrapDnsServersInfo": "Önyükleme DNS sunucuları, üst kaynaklarda belirttiğiniz DoH/DoT çözümleyicilerinin IP adreslerini çözmek için kullanılır.",
|
||||||
|
"privateReverseDnsServers": "Özel ters DNS sunucuları",
|
||||||
|
"privateReverseDnsServersDescription": "AdGuard Home'un yerel PTR sorguları için kullandığı DNS sunucuları. Bu sunucular, özel IP aralıklarındaki adresler için ters DNS kullanarak PTR isteklerini çözmek için kullanılır, örneğin '192.168.12.34' olarak ayarlanmamışsa AdGuard Home, AdGuard Home'un kendi adresleri dışında, işletim sisteminizin varsayılan DNS çözümleyicilerinin adreslerini kullanır.",
|
||||||
|
"reverseDnsDefault": "Varsayılan olarak, AdGuard Home aşağıdaki ters DNS çözümleyicilerini kullanır",
|
||||||
|
"addItem": "Öğe ekle",
|
||||||
|
"noServerAddressesAdded": "Sunucu adresleri eklenmedi.",
|
||||||
|
"usePrivateReverseDnsResolvers": "Özel ters DNS çözümleyicilerini kullan",
|
||||||
|
"usePrivateReverseDnsResolversDescription": "Bu üst kaynak sunucularını kullanarak yerel olarak sunulan adresler için ters DNS sorguları gerçekleştirin. Devre dışı bırakılırsa, AdGuard Home, DHCP, /etc/hosts vb. kaynaklardan bilinen istemciler dışında tüm PTR isteklerine NXDOMAIN yanıtı verir.",
|
||||||
|
"enableReverseResolving": "İstemcilerin IP adreslerinin ters çözümlemesini etkinleştir",
|
||||||
|
"enableReverseResolvingDescription": "İstemcilerin IP adreslerini karşılık gelen çözücülere PTR sorguları göndererek IP adreslerini tersine çözümleyerek (yerel istemciler için özel DNS sunucuları, genel IP adresine sahip istemciler için üst kaynak sunucuları) istemcilerin ana bilgisayar adlarını tersine çöz.",
|
||||||
|
"dnsServerSettings": "AdGuard Home DNS sunucusu ayarları",
|
||||||
|
"limitRequestsSecond": "Saniye başına sınırlama isteği",
|
||||||
|
"valueNotNumber": "Değer bir sayı değil",
|
||||||
|
"enableEdns": "EDNS istemci alt ağını etkinleştir",
|
||||||
|
"enableEdnsDescription": "Kaynak yönü isteklerine EDNS İstemci Alt Ağı Seçeneği (ECS) ekleyin ve istemciler tarafından gönderilen değerleri sorgu günlüğüne kaydedin.",
|
||||||
|
"enableDnssec": "DNSSEC'i etkinleştir",
|
||||||
|
"enableDnssecDescription": "Giden DNS sorguları için DNSSEC özelliğini etkinleştir ve sonucu kontrol edin.(DNSSEC etkinleştirilmiş bir çözümleyici gerekli)",
|
||||||
|
"disableResolvingIpv6": "IPv6 adreslerinin çözümlenmesini devre dışı bırak",
|
||||||
|
"disableResolvingIpv6Description": "IPv6 adresleri için tüm DNS sorgularını bırakın (AAAA yazın) ve HTTPS yanıtlarından IPv6 ipuçlarını kaldırın.",
|
||||||
|
"blockingMode": "Engelleme modu",
|
||||||
|
"defaultMode": "Varsayılan",
|
||||||
|
"defaultDescription": "Reklam engelleme tarzı bir kural tarafından engellendiğinde sıfır IP adresi ile yanıt verin. (A için 0.0.0.0; :: AAAA için) /etc/hosts tarzı bir kural tarafından engellendiğinde kuralda belirtilen IP adresi ile yanıt verin.",
|
||||||
|
"refusedDescription": "REFUSED kodu ile yanıt verin.",
|
||||||
|
"nxdomainDescription": "NXDOMAIN kodu ile yanıt verin.",
|
||||||
|
"nullIp": "Boş IP",
|
||||||
|
"nullIpDescription": "Sıfır IP adresi ile yanıt verin. (A için 0.0.0.0; :: AAAA için)",
|
||||||
|
"customIp": "Özel IP",
|
||||||
|
"customIpDescription": "Manuel olarak ayarlanmış bir IP adresi ile yanıt verin.",
|
||||||
|
"dnsCacheConfig": "DNS önbellek yapılandırması",
|
||||||
|
"cacheSize": "Önbellek boyutu",
|
||||||
|
"inBytes": "Bayt olarak",
|
||||||
|
"overrideMinimumTtl": "Minimum kullanım süresini geçersiz kıl",
|
||||||
|
"overrideMinimumTtlDescription": "DNS yanıtlarını önbelleğe alırken üst sunucudan alınan minimum kullanım süresi değerini ayarlayın (saniye olarak)",
|
||||||
|
"overrideMaximumTtl": "Maksimum kullanım süresini geçersiz kıl",
|
||||||
|
"overrideMaximumTtlDescription": "DNS önbelleğindeki girişler için maksimum kullanım süresi değerini ayarlayın (saniye olarak)",
|
||||||
|
"optimisticCaching": "İyimser önbelleğe alma",
|
||||||
|
"optimisticCachingDescription": "Girişlerin süresi dolmuş olsa bile Adguard Home'un önbellekten yanıt vermesini sağlayın ve aynı zamanda bunları yenilemeye çalışın.",
|
||||||
|
"loadingDnsConfig": "DNS yapılandırması yükleniyor...",
|
||||||
|
"dnsConfigNotLoaded": "DNS yapılandırması yüklenemedi.",
|
||||||
|
"blockingIpv4": "IPv4 engelleniyor",
|
||||||
|
"blockingIpv4Description": "Engellenen bir A isteği için döndürülecek IP adresi",
|
||||||
|
"blockingIpv6": "IPv6 engelleniyor",
|
||||||
|
"blockingIpv6Description": "Engellenen bir AAAA isteği için döndürülecek IP adresi",
|
||||||
|
"invalidIp": "Geçersiz IP adresi",
|
||||||
|
"dnsConfigSaved": "DNS sunucusu yapılandırması başarıyla kaydedildi",
|
||||||
|
"dnsConfigNotSaved": "DNS sunucusu yapılandırması kaydedilemedi",
|
||||||
|
"savingConfig": "Yapılandırma kaydediliyor...",
|
||||||
|
"someValueNotValid": "Bazı değerler geçerli değil",
|
||||||
|
"upstreamDnsDescription": "Üst kaynak sunucularını ve DNS modunu yapılandır",
|
||||||
|
"bootstrapDnsDescription": "Önyükleme DNS sunucularını yapılandır",
|
||||||
|
"privateReverseDnsDescription": "Özel DNS çözümleyicileri yapılandır ve özel ters DNS çözümlemeyi etkinleştir",
|
||||||
|
"dnsServerSettingsDescription": "Hız limiti, engelleme modu ve daha fazlasını yapılandır",
|
||||||
|
"dnsCacheConfigDescription": "Sunucunun DNS önbelleğini nasıl yöneteceğini yapılandır",
|
||||||
|
"comment": "Yorum",
|
||||||
|
"address": "Adres",
|
||||||
|
"commentsDescription": "Yorumlar her zaman # işareti ile başlar. Onu eklemenize gerek yok, otomatik olarak eklenir.",
|
||||||
|
"encryptionSettings": "Şifreleme ayarları",
|
||||||
|
"encryptionSettingsDescription": "Şifreleme (HTTPS/QUIC/TLS) desteği",
|
||||||
|
"loadingEncryptionSettings": "Şifreleme ayarları yükleniyor...",
|
||||||
|
"encryptionSettingsNotLoaded": "Şifreleme ayarları yüklenemedi.",
|
||||||
|
"enableEncryption": "Şifrelemeyi etkinleştir",
|
||||||
|
"enableEncryptionTypes": "HTTPS, DNS-over-HTTPS ve DNS-over-TLS",
|
||||||
|
"enableEncryptionDescription": "Eğer şifreleme etkinleştirilmişse, AdGuard Home yönetici arayüzü HTTPS üzerinden çalışacaktır ve DNS sunucusu DNS üzerinden HTTPS ve TLS ile gelen isteklere yanıt verecektir.",
|
||||||
|
"serverConfiguration": "Sunucu yapılandırması",
|
||||||
|
"domainName": "Alan adı",
|
||||||
|
"domainNameDescription": "Eğer ayarlanırsa, AdGuard Home istemci kimliklerini tespit eder, DDR sorgularına yanıt verir ve ek bağlantı doğrulamalarını gerçekleştirir. Ayarlanmazsa, bu özellikler devre dışı bırakılır. Sertifikadaki DNS adlarından biriyle eşleşmelidir.",
|
||||||
|
"redirectHttps": "Otomatik olarak HTTPS'e yönlendir",
|
||||||
|
"httpsPort": "HTTPS bağlantı noktası",
|
||||||
|
"tlsPort": "DNS-over-TLS bağlantı noktası",
|
||||||
|
"dnsOverQuicPort": "DNS-over-QUIC bağlantı noktası",
|
||||||
|
"certificates": "Sertifikalar",
|
||||||
|
"certificatesDescription": "Şifreleme kullanmak için, alan adınız için geçerli bir SSL sertifikası zinciri sağlamanız gereklidir. letsencrypt.org'dan ücretsiz bir sertifika alabilir veya güvenilir sertifika yetkililerinden satın alabilirsiniz.",
|
||||||
|
"certificateFilePath": "Sertifika dosyası belirle",
|
||||||
|
"pasteCertificateContent": "Sertifika içeriğini yapıştır",
|
||||||
|
"certificatePath": "Sertifika dosya yolu",
|
||||||
|
"certificateContent": "Sertifika içeriği",
|
||||||
|
"privateKey": "Özel anahtarlar",
|
||||||
|
"privateKeyFile": "Özel anahtar dosyası belirle",
|
||||||
|
"pastePrivateKey": "Özel anahtar içeriğini yapıştır",
|
||||||
|
"usePreviousKey": "Önceden kaydedilmiş anahtarı kullan",
|
||||||
|
"privateKeyPath": "Özel anahtar dosya yolu",
|
||||||
|
"invalidCertificate": "Geçersiz sertifika",
|
||||||
|
"invalidPrivateKey": "Geçersiz özel anahtar",
|
||||||
|
"validatingData": "Veri doğrulama",
|
||||||
|
"dataValid": "Veri geçerli",
|
||||||
|
"dataNotValid": "Veri geçersiz",
|
||||||
|
"encryptionConfigSaved": "Şifreleme yapılandırması başarıyla kaydedildi",
|
||||||
|
"encryptionConfigNotSaved": "Şifreleme yapılandırması kaydedilemedi",
|
||||||
|
"configError": "Yapılandırma hatası",
|
||||||
|
"enterOnlyCertificate": "Yalnızca sertifikayı girin. ---BEGIN--- ve ---END--- satırlarını girmeyin.",
|
||||||
|
"enterOnlyPrivateKey": "Yalnızca anahtarı girin. ---BEGIN--- ve ---END--- satırlarını girmeyin.",
|
||||||
|
"noItemsSearch": "Bu arama için hiçbir öğe yok.",
|
||||||
|
"clearSearch": "Aramayı temizle",
|
||||||
|
"exitSearch": "Aramadan çık",
|
||||||
|
"searchClients": "İstemcileri ara",
|
||||||
|
"noClientsSearch": "Bu arama ile ilgili hiçbir istemci bulunamadı.",
|
||||||
|
"customization": "Özelleştirme",
|
||||||
|
"customizationDescription": "Bu uygulamayı özelleştir",
|
||||||
|
"color": "Renk",
|
||||||
|
"useDynamicTheme": "Dinamik renk teması kullan",
|
||||||
|
"red": "Kırmızı",
|
||||||
|
"green": "Yeşil",
|
||||||
|
"blue": "Mavi",
|
||||||
|
"yellow": "Sarı",
|
||||||
|
"orange": "Turuncu",
|
||||||
|
"brown": "Kahverengi",
|
||||||
|
"cyan": "Camgöbeği",
|
||||||
|
"purple": "Mor",
|
||||||
|
"pink": "Pembe",
|
||||||
|
"deepOrange": "Koyu turuncu",
|
||||||
|
"indigo": "Çivit mavisi",
|
||||||
|
"useThemeColorStatus": "Durum için tema rengini kullan",
|
||||||
|
"useThemeColorStatusDescription": "Yeşil ve kırmızı durum renklerini tema rengi ve gri ile değiştirir.",
|
||||||
|
"invalidCertificateChain": "Geçersiz sertifika zinciri",
|
||||||
|
"validCertificateChain": "Geçerli sertifika zinciri",
|
||||||
|
"subject": "Konu",
|
||||||
|
"issuer": "Veren",
|
||||||
|
"expires": "Süresi dolacak",
|
||||||
|
"validPrivateKey": "Geçerli özel anahtar",
|
||||||
|
"expirationDate": "Son kullanma tarihi",
|
||||||
|
"keysNotMatch": "Geçersiz bir sertifika veya anahtar: tls: özel anahtar genel anahtarla eşleşmiyor.",
|
||||||
|
"timeLogs": "Günlüklerdeki işlem süresi",
|
||||||
|
"timeLogsDescription": "Günlükler listesinde zaman yerine işlem süresini göster",
|
||||||
|
"hostNames": "Ana bilgisayar adları",
|
||||||
|
"keyType": "Anahtar türü",
|
||||||
|
"updateAvailable": "Güncelleme mevcut",
|
||||||
|
"installedVersion": "Yüklü sürüm",
|
||||||
|
"newVersion": "Yeni sürüm",
|
||||||
|
"source": "Kaynak",
|
||||||
|
"downloadUpdate": "Güncellemeyi indir",
|
||||||
|
"download": "İndir",
|
||||||
|
"doNotRememberAgainUpdate": "Bu sürüm için tekrar hatırlama.",
|
||||||
|
"downloadingUpdate": "İndiriliyor",
|
||||||
|
"completed": "Tamamlandı",
|
||||||
|
"permissionNotGranted": "İzin verilmedi",
|
||||||
|
"inputSearchTerm": "Bir arama terimi girin.",
|
||||||
|
"answers": "Yanıtlar",
|
||||||
|
"copyClipboard": "Panoya kopyala",
|
||||||
|
"domainCopiedClipboard": "Alan adı panoya kopyalandı",
|
||||||
|
"clearDnsCache": "DNS önbelleğini temizle",
|
||||||
|
"clearDnsCacheMessage": "DNS önbelleğini temizlemek istediğinizden emin misiniz?",
|
||||||
|
"dnsCacheCleared": "DNS önbelleği başarıyla temizlendi",
|
||||||
|
"clearingDnsCache": "Önbellek temizleniyor...",
|
||||||
|
"dnsCacheNotCleared": "DNS önbelleği temizlenemedi",
|
||||||
|
"clientsSelected": "Seçilmiş istemci",
|
||||||
|
"invalidDomain": "Geçersiz alan adı",
|
||||||
|
"loadingBlockedServicesList": "Engellenen hizmetler listesi yükleniyor...",
|
||||||
|
"blockedServicesListNotLoaded": "Engellenen hizmetler listesi yüklenemedi",
|
||||||
|
"error": "Hata",
|
||||||
|
"updates": "Güncellemeler",
|
||||||
|
"updatesDescription": "AdGuard Home sunucusunu güncelle",
|
||||||
|
"updateNow": "Şimdi güncelle",
|
||||||
|
"currentVersion": "Mevcut sürüm",
|
||||||
|
"requestStartUpdateFailed": "Güncellemeyi başlatma isteği başarısız oldu",
|
||||||
|
"requestStartUpdateSuccessful": "Güncellemeyi başlatma isteği başarılı",
|
||||||
|
"serverUpdated": "Sunucu güncellendi",
|
||||||
|
"unknownStatus": "Bilinmeyen durum",
|
||||||
|
"checkingUpdates": "Güncellemeler kontrol ediliyor...",
|
||||||
|
"checkUpdates": "Güncellemeleri kontrol et",
|
||||||
|
"requestingUpdate": "Güncelleme talep ediliyor...",
|
||||||
|
"autoupdateUnavailable": "Otomatik güncelleme kullanılamıyor",
|
||||||
|
"autoupdateUnavailableDescription": "Otomatik güncelleme servisi bu sunucu için kullanılamıyor. Bunun nedeni sunucunun bir Docker konteynerinde çalışıyor olması olabilir. Sunucunuzu manuel olarak güncellemeniz gerekecektir.",
|
||||||
|
"minute": "{time} dakika",
|
||||||
|
"minutes": "{time} dakika",
|
||||||
|
"hour": "{time} saat",
|
||||||
|
"hours": "{time} saat",
|
||||||
|
"remainingTime": "Kalan süre",
|
||||||
|
"safeSearchSettings": "Güvenli arama ayarları",
|
||||||
|
"loadingSafeSearchSettings": "Güvenli arama ayarları yükleniyor...",
|
||||||
|
"safeSearchSettingsNotLoaded": "Güvenli arama ayarları yüklenirken hata oluştu.",
|
||||||
|
"loadingLogsSettings": "Günlük ayarları yükleniyor...",
|
||||||
|
"selectOptionLeftColumn": "Sol sütundan bir seçenek seçin",
|
||||||
|
"selectClientLeftColumn": "Sol sütundan bir istemci seçin",
|
||||||
|
"disableList": "Listeyi devre dışı bırak",
|
||||||
|
"enableList": "Listeyi etkinleştir",
|
||||||
|
"screens": "Ekranlar",
|
||||||
|
"copiedClipboard": "Panoya kopyalandı",
|
||||||
|
"seeDetails": "Detayları gör",
|
||||||
|
"listNotAvailable": "Liste mevcut değil",
|
||||||
|
"copyListUrl": "Liste bağlantısını kopyala",
|
||||||
|
"listUrlCopied": "Panoya kopyalanan bağlantı adresini listeleyin",
|
||||||
|
"unsupportedVersion": "Desteklenmeyen sürüm",
|
||||||
|
"unsupprtedVersionMessage": "Sunucu sürümünüz {version} için destek garantisi verilmiyor. Bu uygulamanın bu sunucu sürümüyle çalışmasında bazı sorunlar olabilir. AdGuard Home Yöneticisi, AdGuard Home sunucunun kararlı sürümleriyle çalışacak şekilde tasarlanmıştır. Alfa ve beta sürümleriyle çalışabilir, ancak uyumluluk garanti edilmez ve uygulama bu sürümlerle çalışırken bazı sorunlar yaşayabilir.",
|
||||||
|
"iUnderstand": "Anladım",
|
||||||
|
"appUpdates": "Uygulama güncellemeleri",
|
||||||
|
"usingLatestVersion": "En son sürümü kullanıyorsunuz :)",
|
||||||
|
"ipLogs": "Günlüklerdeki IP",
|
||||||
|
"ipLogsDescription": "Günlükler listesinde istemci adı yerine IP adresini göster",
|
||||||
|
"application": "Uygulama",
|
||||||
|
"combinedChart": "Birleştirilmiş grafik",
|
||||||
|
"combinedChartDescription": "Tüm grafikleri bir araya getirir.",
|
||||||
|
"statistics": "İstatistikler",
|
||||||
|
"errorLoadFilters": "Filtreler yüklenirken hata oluştu.",
|
||||||
|
"clientRemovedSuccessfully": "İstemci başarıyla kaldırıldı.",
|
||||||
|
"editRewriteRule": "Yeniden yazım kuralını düzenle",
|
||||||
|
"dnsRewriteRuleUpdated": "DNS yeniden yazım kuralı başarıyla güncellendi",
|
||||||
|
"dnsRewriteRuleNotUpdated": "DNS yeniden yazım kuralı güncellenemedi",
|
||||||
|
"updatingRule": "Kural güncelleniyor...",
|
||||||
|
"serverUpdateNeeded": "Sunucu güncellemesi gerekli",
|
||||||
|
"updateYourServer": "Bu özelliği kullanmak için AdGuard Home sunucunuzu {version} veya üzeri bir sürüme güncelleyin.",
|
||||||
|
"january": "Ocak",
|
||||||
|
"february": "Şubat",
|
||||||
|
"march": "Mart",
|
||||||
|
"april": "Nisan",
|
||||||
|
"may": "Mayıs",
|
||||||
|
"june": "Haziran",
|
||||||
|
"july": "Temmuz",
|
||||||
|
"august": "Ağustos",
|
||||||
|
"september": "Eylül",
|
||||||
|
"october": "Ekim",
|
||||||
|
"november": "Kasım",
|
||||||
|
"december": "Aralık",
|
||||||
|
"malwarePhishing": "Zararlı yazılım/oltalama",
|
||||||
|
"queries": "Sorgular",
|
||||||
|
"adultSites": "Yetişkin içerikler",
|
||||||
|
"quickFilters": "Hızlı filtreler",
|
||||||
|
"searchDomainInternet": "İnternette alan adı ara",
|
||||||
|
"hideServerAddress": "Sunucu adresini gizle",
|
||||||
|
"hideServerAddressDescription": "Ana ekranda sunucu adresini gizler.",
|
||||||
|
"topItemsOrder": "Öne çıkan öğeler sıralaması",
|
||||||
|
"topItemsOrderDescription": "Ana ekrandaki öne çıkan öğe listelerini sırala",
|
||||||
|
"topItemsReorderInfo": "Yeniden sıralamak için bir öğeyi basılı tutun ve kaydırın.",
|
||||||
|
"discardChanges": "Değişiklikleri iptal et",
|
||||||
|
"discardChangesDescription": "Değişiklikleri iptal etmek istediğinizden emin misiniz?",
|
||||||
|
"others": "Diğerleri",
|
||||||
|
"showChart": "Göster",
|
||||||
|
"hideChart": "Gizle",
|
||||||
|
"showTopItemsChart": "Öne çıkan öğeler grafiği",
|
||||||
|
"showTopItemsChartDescription": "Varsayılan olarak öne çıkan öğeler bölümünde halka grafiğini gösterir. Sadece mobil görünümü etkiler.",
|
||||||
|
"openMenu": "Menüyü genişlet",
|
||||||
|
"closeMenu": "Menüyü daralt",
|
||||||
|
"openListUrl": "Liste bağlantısını aç",
|
||||||
|
"selectionMode": "Seçim modu",
|
||||||
|
"enableDisableSelected": "Seçili öğeleri etkinleştir veya devre dışı bırak",
|
||||||
|
"deleteSelected": "Seçili öğeleri sil",
|
||||||
|
"deleteSelectedLists": "Seçili listeleri sil",
|
||||||
|
"allSelectedListsDeletedSuccessfully": "Seçilen tüm listeler başarıyla silindi.",
|
||||||
|
"deletionResult": "Silinme sonucu",
|
||||||
|
"deletingLists": "Listeler siliniyor...",
|
||||||
|
"failedElements": "Başarısız öğeler",
|
||||||
|
"processingLists": "Listeler işleniyor...",
|
||||||
|
"enableDisableResult": "Sonucu etkinleştir veya devre dışı bırak",
|
||||||
|
"selectedListsEnabledDisabledSuccessfully": "Seçilen tüm listeler başarıyla etkinleştirildi veya devre dışı bırakıldı",
|
||||||
|
"sslWarning": "Kendinden imzalı bir sertifika ile HTTPS bağlantısı kullanıyorsanız, Ayarlar > Gelişmiş ayarlar bölümünde \"SSL sertifikasını asla kontrol etme\" seçeneğini etkinleştirdiğinizden emin olun.",
|
||||||
|
"unsupportedServerVersion": "Desteklenmeyen sunucu sürümü",
|
||||||
|
"unsupportedServerVersionMessage": "AdGuard Home sunucu sürümünüz çok eski ve AdGuard Home Manager tarafından desteklenmiyor. Bu uygulamayı kullanmak için AdGuard Home sunucunuzu daha yeni bir sürüme yükseltmeniz gerekecektir.",
|
||||||
|
"yourVersion": "Yüklü sürüm: {version}",
|
||||||
|
"minimumRequiredVersion": "Gerekli minimum sürüm: {version}",
|
||||||
|
"topUpstreams": "Öne çıkan üst kaynaklar",
|
||||||
|
"averageUpstreamResponseTime": "Üst kaynak ortalama yanıt süresi"
|
||||||
|
}
|
|
@ -170,7 +170,7 @@
|
||||||
"dnsQueries": "DNS 查询",
|
"dnsQueries": "DNS 查询",
|
||||||
"average": "平均值",
|
"average": "平均值",
|
||||||
"blockedFilters": "被过滤器拦截",
|
"blockedFilters": "被过滤器拦截",
|
||||||
"malwarePhisingBlocked": "被拦截的恶意/钓鱼网站",
|
"malwarePhishingBlocked": "被拦截的恶意/钓鱼网站",
|
||||||
"blockedAdultWebsites": "被拦截的成人网站",
|
"blockedAdultWebsites": "被拦截的成人网站",
|
||||||
"generalSettings": "常规设置",
|
"generalSettings": "常规设置",
|
||||||
"generalSettingsDescription": "各种不同的设置",
|
"generalSettingsDescription": "各种不同的设置",
|
||||||
|
@ -649,9 +649,16 @@
|
||||||
"october": "10月",
|
"october": "10月",
|
||||||
"november": "11月",
|
"november": "11月",
|
||||||
"december": "12月",
|
"december": "12月",
|
||||||
"malwarePhising": "恶意/钓鱼网站",
|
"malwarePhishing": "恶意/钓鱼网站",
|
||||||
"queries": "查询",
|
"queries": "查询",
|
||||||
"adultSites": "成人网站",
|
"adultSites": "成人网站",
|
||||||
"quickFilters": "状态过滤器",
|
"quickFilters": "状态过滤器",
|
||||||
"searchDomainInternet": "在互联网上搜索该域名"
|
"searchDomainInternet": "在互联网上搜索该域名",
|
||||||
|
"hideServerAddress": "隐藏服务器地址",
|
||||||
|
"hideServerAddressDescription": "在主页上隐藏服务器地址",
|
||||||
|
"topItemsOrder": "顶部项目顺序",
|
||||||
|
"topItemsOrderDescription": "排列主页顶部项目列表",
|
||||||
|
"topItemsReorderInfo": "按住并滑动一个项目以重新排序。",
|
||||||
|
"discardChanges": "放弃更改",
|
||||||
|
"discardChangesDescription": "您确定要放弃更改吗?"
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,7 @@
|
||||||
"dnsQueries": "DNS 查询",
|
"dnsQueries": "DNS 查询",
|
||||||
"average": "平均值",
|
"average": "平均值",
|
||||||
"blockedFilters": "被过滤器拦截",
|
"blockedFilters": "被过滤器拦截",
|
||||||
"malwarePhisingBlocked": "被拦截的恶意/钓鱼网站",
|
"malwarePhishingBlocked": "被拦截的恶意/钓鱼网站",
|
||||||
"blockedAdultWebsites": "被拦截的成人网站",
|
"blockedAdultWebsites": "被拦截的成人网站",
|
||||||
"generalSettings": "常规设置",
|
"generalSettings": "常规设置",
|
||||||
"generalSettingsDescription": "各种不同的设置",
|
"generalSettingsDescription": "各种不同的设置",
|
||||||
|
@ -649,9 +649,16 @@
|
||||||
"october": "10月",
|
"october": "10月",
|
||||||
"november": "11月",
|
"november": "11月",
|
||||||
"december": "12月",
|
"december": "12月",
|
||||||
"malwarePhising": "恶意/钓鱼网站",
|
"malwarePhishing": "恶意/钓鱼网站",
|
||||||
"queries": "查询",
|
"queries": "查询",
|
||||||
"adultSites": "成人网站",
|
"adultSites": "成人网站",
|
||||||
"quickFilters": "状态过滤器",
|
"quickFilters": "状态过滤器",
|
||||||
"searchDomainInternet": "在互联网上搜索该域名"
|
"searchDomainInternet": "在互联网上搜索该域名",
|
||||||
|
"hideServerAddress": "隐藏服务器地址",
|
||||||
|
"hideServerAddressDescription": "在主页上隐藏服务器地址",
|
||||||
|
"topItemsOrder": "顶部项目顺序",
|
||||||
|
"topItemsOrderDescription": "排列主页顶部项目列表",
|
||||||
|
"topItemsReorderInfo": "按住并滑动一个项目以重新排序。",
|
||||||
|
"discardChanges": "放弃更改",
|
||||||
|
"discardChangesDescription": "您确定要放弃更改吗?"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,10 @@ import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter_displaymode/flutter_displaymode.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:flutter_displaymode/flutter_displaymode.dart';
|
||||||
import 'package:dynamic_color/dynamic_color.dart';
|
import 'package:dynamic_color/dynamic_color.dart';
|
||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
|
@ -15,7 +16,8 @@ import 'package:window_size/window_size.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/base.dart';
|
import 'package:adguard_home_manager/widgets/layout.dart';
|
||||||
|
import 'package:adguard_home_manager/widgets/menu_bar.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/providers/logs_provider.dart';
|
import 'package:adguard_home_manager/providers/logs_provider.dart';
|
||||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||||
|
@ -34,6 +36,7 @@ import 'package:adguard_home_manager/services/db/database.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
|
||||||
|
|
||||||
if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
|
if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
|
||||||
setWindowMinSize(const Size(500, 500));
|
setWindowMinSize(const Size(500, 500));
|
||||||
|
@ -196,6 +199,7 @@ class _MainState extends State<Main> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
displayMode();
|
displayMode();
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,22 +234,16 @@ class _MainState extends State<Main> {
|
||||||
Locale('zh', ''),
|
Locale('zh', ''),
|
||||||
Locale('zh', 'CN'),
|
Locale('zh', 'CN'),
|
||||||
Locale('pl', ''),
|
Locale('pl', ''),
|
||||||
|
Locale('tr', ''),
|
||||||
Locale('ru', '')
|
Locale('ru', '')
|
||||||
],
|
],
|
||||||
scaffoldMessengerKey: scaffoldMessengerKey,
|
scaffoldMessengerKey: scaffoldMessengerKey,
|
||||||
builder: (context, child) {
|
navigatorKey: globalNavigatorKey,
|
||||||
return MediaQuery(
|
builder: (context, child) => CustomMenuBar(
|
||||||
data: MediaQuery.of(context).copyWith(
|
child: child!,
|
||||||
textScaleFactor: !(Platform.isAndroid || Platform.isIOS)
|
),
|
||||||
? 0.9
|
home: const Layout(),
|
||||||
: 1.0
|
|
||||||
),
|
|
||||||
child: child!,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
home: const Base(),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,14 @@ class AppScreen {
|
||||||
final String name;
|
final String name;
|
||||||
final IconData icon;
|
final IconData icon;
|
||||||
final PreferredSizeWidget? appBar;
|
final PreferredSizeWidget? appBar;
|
||||||
final Widget body;
|
|
||||||
final Widget? fab;
|
final Widget? fab;
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
const AppScreen({
|
const AppScreen({
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.icon,
|
required this.icon,
|
||||||
this.appBar,
|
this.appBar,
|
||||||
required this.body,
|
this.fab,
|
||||||
this.fab
|
required this.child,
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -84,10 +84,13 @@ class Client {
|
||||||
final bool filteringEnabled;
|
final bool filteringEnabled;
|
||||||
final bool parentalEnabled;
|
final bool parentalEnabled;
|
||||||
final bool safebrowsingEnabled;
|
final bool safebrowsingEnabled;
|
||||||
final bool? safesearchEnabled;
|
|
||||||
final bool useGlobalBlockedServices;
|
final bool useGlobalBlockedServices;
|
||||||
final bool useGlobalSettings;
|
final bool useGlobalSettings;
|
||||||
final SafeSearch? safeSearch;
|
final SafeSearch? safeSearch;
|
||||||
|
final bool? ignoreQuerylog;
|
||||||
|
final bool? ignoreStatistics;
|
||||||
|
final bool? upstreamsCacheEnabled;
|
||||||
|
final int? upstreamsCacheSize;
|
||||||
|
|
||||||
Client({
|
Client({
|
||||||
required this.name,
|
required this.name,
|
||||||
|
@ -98,10 +101,13 @@ class Client {
|
||||||
required this.filteringEnabled,
|
required this.filteringEnabled,
|
||||||
required this.parentalEnabled,
|
required this.parentalEnabled,
|
||||||
required this.safebrowsingEnabled,
|
required this.safebrowsingEnabled,
|
||||||
required this.safesearchEnabled,
|
|
||||||
required this.useGlobalBlockedServices,
|
required this.useGlobalBlockedServices,
|
||||||
required this.useGlobalSettings,
|
required this.useGlobalSettings,
|
||||||
required this.safeSearch,
|
required this.safeSearch,
|
||||||
|
required this.ignoreQuerylog,
|
||||||
|
required this.ignoreStatistics,
|
||||||
|
required this.upstreamsCacheEnabled,
|
||||||
|
required this.upstreamsCacheSize,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Client.fromJson(Map<String, dynamic> json) => Client(
|
factory Client.fromJson(Map<String, dynamic> json) => Client(
|
||||||
|
@ -113,12 +119,15 @@ class Client {
|
||||||
filteringEnabled: json["filtering_enabled"],
|
filteringEnabled: json["filtering_enabled"],
|
||||||
parentalEnabled: json["parental_enabled"],
|
parentalEnabled: json["parental_enabled"],
|
||||||
safebrowsingEnabled: json["safebrowsing_enabled"],
|
safebrowsingEnabled: json["safebrowsing_enabled"],
|
||||||
safesearchEnabled: json["safesearch_enabled"],
|
|
||||||
useGlobalBlockedServices: json["use_global_blocked_services"],
|
useGlobalBlockedServices: json["use_global_blocked_services"],
|
||||||
useGlobalSettings: json["use_global_settings"],
|
useGlobalSettings: json["use_global_settings"],
|
||||||
safeSearch: json["safe_search"] != null
|
safeSearch: json["safe_search"] != null
|
||||||
? SafeSearch.fromJson(json["safe_search"])
|
? SafeSearch.fromJson(json["safe_search"])
|
||||||
: null
|
: null,
|
||||||
|
ignoreQuerylog: json["ignore_querylog"],
|
||||||
|
ignoreStatistics: json["ignore_statistics"],
|
||||||
|
upstreamsCacheEnabled: json["upstreams_cache_enabled"],
|
||||||
|
upstreamsCacheSize: json["upstreams_cache_size"]
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
|
@ -130,9 +139,12 @@ class Client {
|
||||||
"filtering_enabled": filteringEnabled,
|
"filtering_enabled": filteringEnabled,
|
||||||
"parental_enabled": parentalEnabled,
|
"parental_enabled": parentalEnabled,
|
||||||
"safebrowsing_enabled": safebrowsingEnabled,
|
"safebrowsing_enabled": safebrowsingEnabled,
|
||||||
"safesearch_enabled": safesearchEnabled,
|
|
||||||
"safe_search": safeSearch,
|
"safe_search": safeSearch,
|
||||||
"use_global_blocked_services": useGlobalBlockedServices,
|
"use_global_blocked_services": useGlobalBlockedServices,
|
||||||
"use_global_settings": useGlobalSettings,
|
"use_global_settings": useGlobalSettings,
|
||||||
|
"ignore_querylog": ignoreQuerylog,
|
||||||
|
"ignore_statistics": ignoreStatistics,
|
||||||
|
"upstreams_cache_enabled": upstreamsCacheEnabled,
|
||||||
|
"upstreams_cache_size": upstreamsCacheSize
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -1,9 +1,11 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
class DhcpModel {
|
class DhcpModel {
|
||||||
|
bool dhcpAvailable;
|
||||||
List<NetworkInterface> networkInterfaces;
|
List<NetworkInterface> networkInterfaces;
|
||||||
DhcpStatus dhcpStatus;
|
DhcpStatus? dhcpStatus;
|
||||||
|
|
||||||
DhcpModel({
|
DhcpModel({
|
||||||
|
required this.dhcpAvailable,
|
||||||
required this.networkInterfaces,
|
required this.networkInterfaces,
|
||||||
required this.dhcpStatus,
|
required this.dhcpStatus,
|
||||||
});
|
});
|
||||||
|
@ -72,11 +74,11 @@ class DhcpStatus {
|
||||||
|
|
||||||
factory DhcpStatus.fromJson(Map<String, dynamic> json) => DhcpStatus(
|
factory DhcpStatus.fromJson(Map<String, dynamic> json) => DhcpStatus(
|
||||||
interfaceName: json["interface_name"],
|
interfaceName: json["interface_name"],
|
||||||
v4: IpVersion.fromJson(json["v4"]),
|
v4: json["v4"] != null ? IpVersion.fromJson(json["v4"]) : null,
|
||||||
v6: IpVersion.fromJson(json["v6"]),
|
v6: json["v6"] != null ? IpVersion.fromJson(json["v6"]) : null,
|
||||||
leases: List<Lease>.from(json["leases"].map((x) => Lease.fromJson(x))),
|
leases: List<Lease>.from(json["leases"].map((x) => Lease.fromJson(x))),
|
||||||
staticLeases: List<Lease>.from(json["static_leases"].map((x) => Lease.fromJson(x))),
|
staticLeases: List<Lease>.from(json["static_leases"].map((x) => Lease.fromJson(x))),
|
||||||
enabled: json["enabled"],
|
enabled: json["enabled"] ?? false,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
|
|
|
@ -2,32 +2,39 @@ class DnsInfo {
|
||||||
List<String> upstreamDns;
|
List<String> upstreamDns;
|
||||||
String? upstreamDnsFile;
|
String? upstreamDnsFile;
|
||||||
List<String> bootstrapDns;
|
List<String> bootstrapDns;
|
||||||
|
List<String>? fallbackDns;
|
||||||
bool protectionEnabled;
|
bool protectionEnabled;
|
||||||
int ratelimit;
|
int ratelimit;
|
||||||
String blockingMode;
|
String blockingMode;
|
||||||
bool ednsCsEnabled;
|
bool ednsCsEnabled;
|
||||||
|
bool? ednsCsUseCustom;
|
||||||
|
String? ednsCsCustomIp;
|
||||||
bool dnssecEnabled;
|
bool dnssecEnabled;
|
||||||
bool disableIpv6;
|
bool disableIpv6;
|
||||||
String? upstreamMode;
|
String? upstreamMode;
|
||||||
int? cacheSize;
|
int? cacheSize;
|
||||||
int? cacheTtlMin;
|
int? cacheTtlMin;
|
||||||
int? cacheTtlMax;
|
int? cacheTtlMax;
|
||||||
bool cacheOptimistic;
|
bool? cacheOptimistic;
|
||||||
bool resolveClients;
|
bool? resolveClients;
|
||||||
bool usePrivatePtrResolvers;
|
bool? usePrivatePtrResolvers;
|
||||||
List<String> localPtrUpstreams;
|
List<String> localPtrUpstreams;
|
||||||
String blockingIpv4;
|
String blockingIpv4;
|
||||||
String blockingIpv6;
|
String blockingIpv6;
|
||||||
List<String> defaultLocalPtrUpstreams;
|
List<String> defaultLocalPtrUpstreams;
|
||||||
|
int? blockedResponseTtl;
|
||||||
|
|
||||||
DnsInfo({
|
DnsInfo({
|
||||||
required this.upstreamDns,
|
required this.upstreamDns,
|
||||||
required this.upstreamDnsFile,
|
required this.upstreamDnsFile,
|
||||||
required this.bootstrapDns,
|
required this.bootstrapDns,
|
||||||
|
required this.fallbackDns,
|
||||||
required this.protectionEnabled,
|
required this.protectionEnabled,
|
||||||
required this.ratelimit,
|
required this.ratelimit,
|
||||||
required this.blockingMode,
|
required this.blockingMode,
|
||||||
required this.ednsCsEnabled,
|
required this.ednsCsEnabled,
|
||||||
|
required this.ednsCsUseCustom,
|
||||||
|
required this.ednsCsCustomIp,
|
||||||
required this.dnssecEnabled,
|
required this.dnssecEnabled,
|
||||||
required this.disableIpv6,
|
required this.disableIpv6,
|
||||||
required this.upstreamMode,
|
required this.upstreamMode,
|
||||||
|
@ -41,16 +48,20 @@ class DnsInfo {
|
||||||
required this.blockingIpv4,
|
required this.blockingIpv4,
|
||||||
required this.blockingIpv6,
|
required this.blockingIpv6,
|
||||||
required this.defaultLocalPtrUpstreams,
|
required this.defaultLocalPtrUpstreams,
|
||||||
|
required this.blockedResponseTtl,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory DnsInfo.fromJson(Map<String, dynamic> json) => DnsInfo(
|
factory DnsInfo.fromJson(Map<String, dynamic> json) => DnsInfo(
|
||||||
upstreamDns: json["upstream_dns"] != null ? List<String>.from(json["upstream_dns"].map((x) => x)) : [],
|
upstreamDns: json["upstream_dns"] != null ? List<String>.from(json["upstream_dns"].map((x) => x)) : [],
|
||||||
upstreamDnsFile: json["upstream_dns_file"],
|
upstreamDnsFile: json["upstream_dns_file"],
|
||||||
bootstrapDns: json["bootstrap_dns"] != null ? List<String>.from(json["bootstrap_dns"].map((x) => x)) : [],
|
bootstrapDns: json["bootstrap_dns"] != null ? List<String>.from(json["bootstrap_dns"].map((x) => x)) : [],
|
||||||
|
fallbackDns: json["fallback_dns"] != null ? List<String>.from(json["fallback_dns"].map((x) => x)) : [],
|
||||||
protectionEnabled: json["protection_enabled"],
|
protectionEnabled: json["protection_enabled"],
|
||||||
ratelimit: json["ratelimit"],
|
ratelimit: json["ratelimit"],
|
||||||
blockingMode: json["blocking_mode"],
|
blockingMode: json["blocking_mode"],
|
||||||
ednsCsEnabled: json["edns_cs_enabled"],
|
ednsCsEnabled: json["edns_cs_enabled"],
|
||||||
|
ednsCsUseCustom: json["edns_cs_use_custom"],
|
||||||
|
ednsCsCustomIp: json["edns_cs_custom_ip"],
|
||||||
dnssecEnabled: json["dnssec_enabled"],
|
dnssecEnabled: json["dnssec_enabled"],
|
||||||
disableIpv6: json["disable_ipv6"],
|
disableIpv6: json["disable_ipv6"],
|
||||||
upstreamMode: json["upstream_mode"],
|
upstreamMode: json["upstream_mode"],
|
||||||
|
@ -64,16 +75,20 @@ class DnsInfo {
|
||||||
blockingIpv4: json["blocking_ipv4"],
|
blockingIpv4: json["blocking_ipv4"],
|
||||||
blockingIpv6: json["blocking_ipv6"],
|
blockingIpv6: json["blocking_ipv6"],
|
||||||
defaultLocalPtrUpstreams: json["default_local_ptr_upstreams"] != null ? List<String>.from(json["default_local_ptr_upstreams"].map((x) => x)) : [],
|
defaultLocalPtrUpstreams: json["default_local_ptr_upstreams"] != null ? List<String>.from(json["default_local_ptr_upstreams"].map((x) => x)) : [],
|
||||||
|
blockedResponseTtl: json["blocked_response_ttl"]
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
"upstream_dns": List<dynamic>.from(upstreamDns.map((x) => x)),
|
"upstream_dns": List<dynamic>.from(upstreamDns.map((x) => x)),
|
||||||
"upstream_dns_file": upstreamDnsFile,
|
"upstream_dns_file": upstreamDnsFile,
|
||||||
"bootstrap_dns": List<dynamic>.from(bootstrapDns.map((x) => x)),
|
"bootstrap_dns": List<dynamic>.from(bootstrapDns.map((x) => x)),
|
||||||
|
"fallback_dns": List<dynamic>.from(bootstrapDns.map((x) => x)),
|
||||||
"protection_enabled": protectionEnabled,
|
"protection_enabled": protectionEnabled,
|
||||||
"ratelimit": ratelimit,
|
"ratelimit": ratelimit,
|
||||||
"blocking_mode": blockingMode,
|
"blocking_mode": blockingMode,
|
||||||
"edns_cs_enabled": ednsCsEnabled,
|
"edns_cs_enabled": ednsCsEnabled,
|
||||||
|
"edns_cs_use_custom": ednsCsUseCustom,
|
||||||
|
"edns_cs_custom_ip": ednsCsCustomIp,
|
||||||
"dnssec_enabled": dnssecEnabled,
|
"dnssec_enabled": dnssecEnabled,
|
||||||
"disable_ipv6": disableIpv6,
|
"disable_ipv6": disableIpv6,
|
||||||
"upstream_mode": upstreamMode,
|
"upstream_mode": upstreamMode,
|
||||||
|
@ -87,5 +102,6 @@ class DnsInfo {
|
||||||
"blocking_ipv4": blockingIpv4,
|
"blocking_ipv4": blockingIpv4,
|
||||||
"blocking_ipv6": blockingIpv6,
|
"blocking_ipv6": blockingIpv6,
|
||||||
"default_local_ptr_upstreams": List<dynamic>.from(defaultLocalPtrUpstreams.map((x) => x)),
|
"default_local_ptr_upstreams": List<dynamic>.from(defaultLocalPtrUpstreams.map((x) => x)),
|
||||||
|
"blocked_response_ttl": blockedResponseTtl
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ class DnsStatistics {
|
||||||
final List<Map<String, int>> topQueriedDomains;
|
final List<Map<String, int>> topQueriedDomains;
|
||||||
final List<Map<String, int>> topClients;
|
final List<Map<String, int>> topClients;
|
||||||
final List<Map<String, int>> topBlockedDomains;
|
final List<Map<String, int>> topBlockedDomains;
|
||||||
|
final List<Map<String, int>>? topUpstreamResponses;
|
||||||
|
final List<Map<String, double>>? topUpstreamsAvgTime;
|
||||||
final List<int> dnsQueries;
|
final List<int> dnsQueries;
|
||||||
final List<int> blockedFiltering;
|
final List<int> blockedFiltering;
|
||||||
final List<int> replacedSafebrowsing;
|
final List<int> replacedSafebrowsing;
|
||||||
|
@ -25,6 +27,8 @@ class DnsStatistics {
|
||||||
required this.topQueriedDomains,
|
required this.topQueriedDomains,
|
||||||
required this.topClients,
|
required this.topClients,
|
||||||
required this.topBlockedDomains,
|
required this.topBlockedDomains,
|
||||||
|
required this.topUpstreamResponses,
|
||||||
|
required this.topUpstreamsAvgTime,
|
||||||
required this.dnsQueries,
|
required this.dnsQueries,
|
||||||
required this.blockedFiltering,
|
required this.blockedFiltering,
|
||||||
required this.replacedSafebrowsing,
|
required this.replacedSafebrowsing,
|
||||||
|
@ -42,6 +46,8 @@ class DnsStatistics {
|
||||||
topQueriedDomains: List<Map<String, int>>.from(json["top_queried_domains"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))),
|
topQueriedDomains: List<Map<String, int>>.from(json["top_queried_domains"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))),
|
||||||
topClients: List<Map<String, int>>.from(json["top_clients"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))),
|
topClients: List<Map<String, int>>.from(json["top_clients"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))),
|
||||||
topBlockedDomains: List<Map<String, int>>.from(json["top_blocked_domains"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))),
|
topBlockedDomains: List<Map<String, int>>.from(json["top_blocked_domains"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))),
|
||||||
|
topUpstreamResponses: json["top_upstreams_responses"] != null ? List<Map<String, int>>.from(json["top_upstreams_responses"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))) : null,
|
||||||
|
topUpstreamsAvgTime: json["top_upstreams_avg_time"] != null ? List<Map<String, double>>.from(json["top_upstreams_avg_time"].map((x) => Map.from(x).map((k, v) => MapEntry<String, double>(k, v)))) : null,
|
||||||
dnsQueries: List<int>.from(json["dns_queries"].map((x) => x)),
|
dnsQueries: List<int>.from(json["dns_queries"].map((x) => x)),
|
||||||
blockedFiltering: List<int>.from(json["blocked_filtering"].map((x) => x)),
|
blockedFiltering: List<int>.from(json["blocked_filtering"].map((x) => x)),
|
||||||
replacedSafebrowsing: List<int>.from(json["replaced_safebrowsing"].map((x) => x)),
|
replacedSafebrowsing: List<int>.from(json["replaced_safebrowsing"].map((x) => x)),
|
||||||
|
@ -59,6 +65,8 @@ class DnsStatistics {
|
||||||
"top_queried_domains": List<dynamic>.from(topQueriedDomains.map((x) => Map.from(x).map((k, v) => MapEntry<String, dynamic>(k, v)))),
|
"top_queried_domains": List<dynamic>.from(topQueriedDomains.map((x) => Map.from(x).map((k, v) => MapEntry<String, dynamic>(k, v)))),
|
||||||
"top_clients": List<dynamic>.from(topClients.map((x) => Map.from(x).map((k, v) => MapEntry<String, dynamic>(k, v)))),
|
"top_clients": List<dynamic>.from(topClients.map((x) => Map.from(x).map((k, v) => MapEntry<String, dynamic>(k, v)))),
|
||||||
"top_blocked_domains": List<dynamic>.from(topBlockedDomains.map((x) => Map.from(x).map((k, v) => MapEntry<String, dynamic>(k, v)))),
|
"top_blocked_domains": List<dynamic>.from(topBlockedDomains.map((x) => Map.from(x).map((k, v) => MapEntry<String, dynamic>(k, v)))),
|
||||||
|
"top_upstreams_responses": topUpstreamResponses != null ? List<dynamic>.from(topUpstreamResponses!.map((x) => Map.from(x).map((k, v) => MapEntry<String, dynamic>(k, v)))) : null,
|
||||||
|
"top_upstreams_avg_time": topUpstreamsAvgTime != null ? List<dynamic>.from(topUpstreamsAvgTime!.map((x) => Map.from(x).map((k, v) => MapEntry<String, dynamic>(k, v)))) : null,
|
||||||
"dns_queries": List<dynamic>.from(dnsQueries.map((x) => x)),
|
"dns_queries": List<dynamic>.from(dnsQueries.map((x) => x)),
|
||||||
"blocked_filtering": List<dynamic>.from(blockedFiltering.map((x) => x)),
|
"blocked_filtering": List<dynamic>.from(blockedFiltering.map((x) => x)),
|
||||||
"replaced_safebrowsing": List<dynamic>.from(replacedSafebrowsing.map((x) => x)),
|
"replaced_safebrowsing": List<dynamic>.from(replacedSafebrowsing.map((x) => x)),
|
||||||
|
|
|
@ -122,3 +122,128 @@ class EncryptionData {
|
||||||
"private_key_saved": privateKeySaved,
|
"private_key_saved": privateKeySaved,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class EncryptionValidationResult {
|
||||||
|
final bool isObject;
|
||||||
|
final EncryptionValidation? encryptionValidation;
|
||||||
|
final String? message;
|
||||||
|
|
||||||
|
const EncryptionValidationResult({
|
||||||
|
required this.isObject,
|
||||||
|
this.encryptionValidation,
|
||||||
|
this.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class EncryptionValidation {
|
||||||
|
final String? subject;
|
||||||
|
final String? issuer;
|
||||||
|
final String? keyType;
|
||||||
|
final DateTime? notBefore;
|
||||||
|
final DateTime? notAfter;
|
||||||
|
final String? warningValidation;
|
||||||
|
final List<String>? dnsNames;
|
||||||
|
final bool? validCert;
|
||||||
|
final bool? validChain;
|
||||||
|
final bool? validKey;
|
||||||
|
final bool? validPair;
|
||||||
|
final bool? enabled;
|
||||||
|
final String? serverName;
|
||||||
|
final bool? forceHttps;
|
||||||
|
final int? portHttps;
|
||||||
|
final int? portDnsOverTls;
|
||||||
|
final int? portDnsOverQuic;
|
||||||
|
final int? portDnscrypt;
|
||||||
|
final String? dnscryptConfigFile;
|
||||||
|
final bool? allowUnencryptedDoh;
|
||||||
|
final String? certificateChain;
|
||||||
|
final String? privateKey;
|
||||||
|
final String? certificatePath;
|
||||||
|
final String? privateKeyPath;
|
||||||
|
final bool? privateKeySaved;
|
||||||
|
|
||||||
|
EncryptionValidation({
|
||||||
|
this.subject,
|
||||||
|
this.issuer,
|
||||||
|
this.keyType,
|
||||||
|
this.notBefore,
|
||||||
|
this.notAfter,
|
||||||
|
this.warningValidation,
|
||||||
|
this.dnsNames,
|
||||||
|
this.validCert,
|
||||||
|
this.validChain,
|
||||||
|
this.validKey,
|
||||||
|
this.validPair,
|
||||||
|
this.enabled,
|
||||||
|
this.serverName,
|
||||||
|
this.forceHttps,
|
||||||
|
this.portHttps,
|
||||||
|
this.portDnsOverTls,
|
||||||
|
this.portDnsOverQuic,
|
||||||
|
this.portDnscrypt,
|
||||||
|
this.dnscryptConfigFile,
|
||||||
|
this.allowUnencryptedDoh,
|
||||||
|
this.certificateChain,
|
||||||
|
this.privateKey,
|
||||||
|
this.certificatePath,
|
||||||
|
this.privateKeyPath,
|
||||||
|
this.privateKeySaved,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory EncryptionValidation.fromJson(Map<String, dynamic> json) => EncryptionValidation(
|
||||||
|
subject: json["subject"],
|
||||||
|
issuer: json["issuer"],
|
||||||
|
keyType: json["key_type"],
|
||||||
|
notBefore: json["not_before"] == null ? null : DateTime.parse(json["not_before"]),
|
||||||
|
notAfter: json["not_after"] == null ? null : DateTime.parse(json["not_after"]),
|
||||||
|
warningValidation: json["warning_validation"],
|
||||||
|
dnsNames: json["dns_names"] == null ? [] : List<String>.from(json["dns_names"]!.map((x) => x)),
|
||||||
|
validCert: json["valid_cert"],
|
||||||
|
validChain: json["valid_chain"],
|
||||||
|
validKey: json["valid_key"],
|
||||||
|
validPair: json["valid_pair"],
|
||||||
|
enabled: json["enabled"],
|
||||||
|
serverName: json["server_name"],
|
||||||
|
forceHttps: json["force_https"],
|
||||||
|
portHttps: json["port_https"],
|
||||||
|
portDnsOverTls: json["port_dns_over_tls"],
|
||||||
|
portDnsOverQuic: json["port_dns_over_quic"],
|
||||||
|
portDnscrypt: json["port_dnscrypt"],
|
||||||
|
dnscryptConfigFile: json["dnscrypt_config_file"],
|
||||||
|
allowUnencryptedDoh: json["allow_unencrypted_doh"],
|
||||||
|
certificateChain: json["certificate_chain"],
|
||||||
|
privateKey: json["private_key"],
|
||||||
|
certificatePath: json["certificate_path"],
|
||||||
|
privateKeyPath: json["private_key_path"],
|
||||||
|
privateKeySaved: json["private_key_saved"],
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"subject": subject,
|
||||||
|
"issuer": issuer,
|
||||||
|
"key_type": keyType,
|
||||||
|
"not_before": notBefore?.toIso8601String(),
|
||||||
|
"not_after": notAfter?.toIso8601String(),
|
||||||
|
"warning_validation": warningValidation,
|
||||||
|
"dns_names": dnsNames == null ? [] : List<dynamic>.from(dnsNames!.map((x) => x)),
|
||||||
|
"valid_cert": validCert,
|
||||||
|
"valid_chain": validChain,
|
||||||
|
"valid_key": validKey,
|
||||||
|
"valid_pair": validPair,
|
||||||
|
"enabled": enabled,
|
||||||
|
"server_name": serverName,
|
||||||
|
"force_https": forceHttps,
|
||||||
|
"port_https": portHttps,
|
||||||
|
"port_dns_over_tls": portDnsOverTls,
|
||||||
|
"port_dns_over_quic": portDnsOverQuic,
|
||||||
|
"port_dnscrypt": portDnscrypt,
|
||||||
|
"dnscrypt_config_file": dnscryptConfigFile,
|
||||||
|
"allow_unencrypted_doh": allowUnencryptedDoh,
|
||||||
|
"certificate_chain": certificateChain,
|
||||||
|
"private_key": privateKey,
|
||||||
|
"certificate_path": certificatePath,
|
||||||
|
"private_key_path": privateKeyPath,
|
||||||
|
"private_key_saved": privateKeySaved,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class Filtering {
|
class Filtering {
|
||||||
final List<Filter> filters;
|
List<Filter> filters;
|
||||||
final List<Filter> whitelistFilters;
|
List<Filter> whitelistFilters;
|
||||||
List<String> userRules;
|
List<String> userRules;
|
||||||
List<String> blockedServices;
|
List<String> blockedServices;
|
||||||
int interval;
|
int interval;
|
||||||
|
@ -40,7 +40,7 @@ class Filter {
|
||||||
final DateTime? lastUpdated;
|
final DateTime? lastUpdated;
|
||||||
final int id;
|
final int id;
|
||||||
final int rulesCount;
|
final int rulesCount;
|
||||||
final bool enabled;
|
bool enabled;
|
||||||
|
|
||||||
Filter({
|
Filter({
|
||||||
required this.url,
|
required this.url,
|
||||||
|
@ -69,3 +69,13 @@ class Filter {
|
||||||
"enabled": enabled,
|
"enabled": enabled,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ProcessedList {
|
||||||
|
final Filter list;
|
||||||
|
final bool successful;
|
||||||
|
|
||||||
|
const ProcessedList({
|
||||||
|
required this.list,
|
||||||
|
required this.successful
|
||||||
|
});
|
||||||
|
}
|
|
@ -52,6 +52,8 @@ class AppConfigProvider with ChangeNotifier {
|
||||||
|
|
||||||
int _combinedChartHome = 0;
|
int _combinedChartHome = 0;
|
||||||
|
|
||||||
|
int _showTopItemsChart = 0;
|
||||||
|
|
||||||
String? _doNotRememberVersion;
|
String? _doNotRememberVersion;
|
||||||
|
|
||||||
GitHubRelease? _appUpdatesAvailable;
|
GitHubRelease? _appUpdatesAvailable;
|
||||||
|
@ -168,6 +170,10 @@ class AppConfigProvider with ChangeNotifier {
|
||||||
return _hideServerAddress == 1 ? true : false;
|
return _hideServerAddress == 1 ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get showTopItemsChart {
|
||||||
|
return _showTopItemsChart == 1 ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
void setDbInstance(Database db) {
|
void setDbInstance(Database db) {
|
||||||
_dbInstance = db;
|
_dbInstance = db;
|
||||||
}
|
}
|
||||||
|
@ -402,6 +408,22 @@ class AppConfigProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> setShowTopItemsChart(bool value) async {
|
||||||
|
final updated = await updateConfigQuery(
|
||||||
|
db: _dbInstance!,
|
||||||
|
column: 'showTopItemsChart',
|
||||||
|
value: value == true ? 1 : 0
|
||||||
|
);
|
||||||
|
if (updated == true) {
|
||||||
|
_showTopItemsChart = value == true ? 1 : 0;
|
||||||
|
notifyListeners();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<bool> setDoNotRememberVersion(String value) async {
|
Future<bool> setDoNotRememberVersion(String value) async {
|
||||||
final updated = await updateConfigQuery(
|
final updated = await updateConfigQuery(
|
||||||
|
@ -424,9 +446,10 @@ class AppConfigProvider with ChangeNotifier {
|
||||||
_showIpLogs = dbData['showIpLogs'] ?? 0;
|
_showIpLogs = dbData['showIpLogs'] ?? 0;
|
||||||
_combinedChartHome = dbData['combinedChart'] ?? 0;
|
_combinedChartHome = dbData['combinedChart'] ?? 0;
|
||||||
_hideServerAddress = dbData['hideServerAddress'];
|
_hideServerAddress = dbData['hideServerAddress'];
|
||||||
|
_showTopItemsChart = dbData['showTopItemsChart'];
|
||||||
if (dbData['homeTopItemsOrder'] != null) {
|
if (dbData['homeTopItemsOrder'] != null) {
|
||||||
try {
|
try {
|
||||||
_homeTopItemsOrder = List<HomeTopItems>.from(
|
final itemsOrder = List<HomeTopItems>.from(
|
||||||
List<String>.from(jsonDecode(dbData['homeTopItemsOrder'])).map((e) {
|
List<String>.from(jsonDecode(dbData['homeTopItemsOrder'])).map((e) {
|
||||||
switch (e) {
|
switch (e) {
|
||||||
case 'queriedDomains':
|
case 'queriedDomains':
|
||||||
|
@ -438,11 +461,22 @@ class AppConfigProvider with ChangeNotifier {
|
||||||
case 'recurrentClients':
|
case 'recurrentClients':
|
||||||
return HomeTopItems.recurrentClients;
|
return HomeTopItems.recurrentClients;
|
||||||
|
|
||||||
|
case 'topUpstreams':
|
||||||
|
return HomeTopItems.topUpstreams;
|
||||||
|
|
||||||
|
case 'avgUpstreamResponseTime':
|
||||||
|
return HomeTopItems.avgUpstreamResponseTime;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}).where((e) => e != null).toList()
|
}).where((e) => e != null).toList()
|
||||||
);
|
);
|
||||||
|
final missingItems = homeTopItemsDefaultOrder.where((e) => !itemsOrder.contains(e));
|
||||||
|
_homeTopItemsOrder = [
|
||||||
|
...itemsOrder,
|
||||||
|
...missingItems
|
||||||
|
];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Sentry.captureException(e);
|
Sentry.captureException(e);
|
||||||
_homeTopItemsOrder = homeTopItemsDefaultOrder;
|
_homeTopItemsOrder = homeTopItemsDefaultOrder;
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/services/api_client.dart';
|
||||||
import 'package:adguard_home_manager/models/clients.dart';
|
import 'package:adguard_home_manager/models/clients.dart';
|
||||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
|
||||||
import 'package:adguard_home_manager/functions/maps_fns.dart';
|
import 'package:adguard_home_manager/functions/maps_fns.dart';
|
||||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||||
import 'package:adguard_home_manager/models/clients_allowed_blocked.dart';
|
import 'package:adguard_home_manager/models/clients_allowed_blocked.dart';
|
||||||
import 'package:adguard_home_manager/constants/enums.dart';
|
import 'package:adguard_home_manager/constants/enums.dart';
|
||||||
|
|
||||||
|
enum AccessSettingsList { allowed, disallowed, domains }
|
||||||
|
|
||||||
class ClientsProvider with ChangeNotifier {
|
class ClientsProvider with ChangeNotifier {
|
||||||
ServersProvider? _serversProvider;
|
ServersProvider? _serversProvider;
|
||||||
StatusProvider? _statusProvider;
|
|
||||||
|
|
||||||
update(ServersProvider? servers, StatusProvider? status) {
|
update(ServersProvider? servers, StatusProvider? status) {
|
||||||
_serversProvider = servers;
|
_serversProvider = servers;
|
||||||
_statusProvider = status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadStatus _loadStatus = LoadStatus.loading;
|
LoadStatus _loadStatus = LoadStatus.loading;
|
||||||
|
@ -103,9 +103,9 @@ class ClientsProvider with ChangeNotifier {
|
||||||
if (updateLoading == true) {
|
if (updateLoading == true) {
|
||||||
_loadStatus = LoadStatus.loading;
|
_loadStatus = LoadStatus.loading;
|
||||||
}
|
}
|
||||||
final result = await _serversProvider!.apiClient!.getClients();
|
final result = await _serversProvider!.apiClient2!.getClients();
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
setClientsData(result['data'], false);
|
setClientsData(result.content as Clients, false);
|
||||||
_loadStatus = LoadStatus.loaded;
|
_loadStatus = LoadStatus.loaded;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return true;
|
return true;
|
||||||
|
@ -120,9 +120,9 @@ class ClientsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> deleteClient(Client client) async {
|
Future<bool> deleteClient(Client client) async {
|
||||||
final result = await _serversProvider!.apiClient!.postDeleteClient(name: client.name);
|
final result = await _serversProvider!.apiClient2!.postDeleteClient(name: client.name);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
Clients clientsData = clients!;
|
Clients clientsData = clients!;
|
||||||
clientsData.clients = clientsData.clients.where((c) => c.name != client.name).toList();
|
clientsData.clients = clientsData.clients.where((c) => c.name != client.name).toList();
|
||||||
setClientsData(clientsData, false);
|
setClientsData(clientsData, false);
|
||||||
|
@ -136,20 +136,14 @@ class ClientsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> editClient(Client client) async {
|
Future<bool> editClient(Client client) async {
|
||||||
final result = await _serversProvider!.apiClient!.postUpdateClient(
|
final result = await _serversProvider!.apiClient2!.postUpdateClient(
|
||||||
data: {
|
data: {
|
||||||
'name': client.name,
|
'name': client.name,
|
||||||
'data': serverVersionIsAhead(
|
'data': removePropFromMap(client.toJson(), 'safe_search')
|
||||||
currentVersion: _statusProvider!.serverStatus!.serverVersion,
|
|
||||||
referenceVersion: 'v0.107.28',
|
|
||||||
referenceVersionBeta: 'v0.108.0-b.33'
|
|
||||||
) == false
|
|
||||||
? removePropFromMap(client.toJson(), 'safesearch_enabled')
|
|
||||||
: removePropFromMap(client.toJson(), 'safe_search')
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
Clients clientsData = clients!;
|
Clients clientsData = clients!;
|
||||||
clientsData.clients = clientsData.clients.map((e) {
|
clientsData.clients = clientsData.clients.map((e) {
|
||||||
if (e.name == client.name) {
|
if (e.name == client.name) {
|
||||||
|
@ -171,17 +165,11 @@ class ClientsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> addClient(Client client) async {
|
Future<bool> addClient(Client client) async {
|
||||||
final result = await _serversProvider!.apiClient!.postAddClient(
|
final result = await _serversProvider!.apiClient2!.postAddClient(
|
||||||
data: serverVersionIsAhead(
|
data: removePropFromMap(client.toJson(), 'safe_search')
|
||||||
currentVersion: _statusProvider!.serverStatus!.serverVersion,
|
|
||||||
referenceVersion: 'v0.107.28',
|
|
||||||
referenceVersionBeta: 'v0.108.0-b.33'
|
|
||||||
) == false
|
|
||||||
? removePropFromMap(client.toJson(), 'safesearch_enabled')
|
|
||||||
: removePropFromMap(client.toJson(), 'safe_search')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
Clients clientsData = clients!;
|
Clients clientsData = clients!;
|
||||||
clientsData.clients.add(client);
|
clientsData.clients.add(client);
|
||||||
setClientsData(clientsData, false);
|
setClientsData(clientsData, false);
|
||||||
|
@ -195,91 +183,105 @@ class ClientsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> addClientList(String item, String type) async {
|
Future<ApiResponse> addClientList(String item, AccessSettingsList type) async {
|
||||||
Map<String, List<String>> body = {
|
Map<String, List<String>> body = {
|
||||||
"allowed_clients": clients!.clientsAllowedBlocked?.allowedClients ?? [],
|
"allowed_clients": clients!.clientsAllowedBlocked?.allowedClients ?? [],
|
||||||
"disallowed_clients": clients!.clientsAllowedBlocked?.disallowedClients ?? [],
|
"disallowed_clients": clients!.clientsAllowedBlocked?.disallowedClients ?? [],
|
||||||
"blocked_hosts": clients!.clientsAllowedBlocked?.blockedHosts ?? [],
|
"blocked_hosts": clients!.clientsAllowedBlocked?.blockedHosts ?? [],
|
||||||
};
|
};
|
||||||
|
|
||||||
if (type == 'allowed') {
|
if (body['allowed_clients']!.contains(item)) {
|
||||||
|
body['allowed_clients'] = body['allowed_clients']!.where((e) => e != item).toList();
|
||||||
|
}
|
||||||
|
else if (body['disallowed_clients']!.contains(item)) {
|
||||||
|
body['disallowed_clients'] = body['disallowed_clients']!.where((e) => e != item).toList();
|
||||||
|
}
|
||||||
|
else if (body['blocked_hosts']!.contains(item)) {
|
||||||
|
body['blocked_hosts'] = body['blocked_hosts']!.where((e) => e != item).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == AccessSettingsList.allowed) {
|
||||||
body['allowed_clients']!.add(item);
|
body['allowed_clients']!.add(item);
|
||||||
}
|
}
|
||||||
else if (type == 'disallowed') {
|
else if (type == AccessSettingsList.disallowed) {
|
||||||
body['disallowed_clients']!.add(item);
|
body['disallowed_clients']!.add(item);
|
||||||
}
|
}
|
||||||
else if (type == 'domains') {
|
else if (type == AccessSettingsList.domains) {
|
||||||
body['blocked_hosts']!.add(item);
|
body['blocked_hosts']!.add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.requestAllowedBlockedClientsHosts(body);
|
final result = await _serversProvider!.apiClient2!.requestAllowedBlockedClientsHosts(
|
||||||
|
body: body
|
||||||
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_clients?.clientsAllowedBlocked = ClientsAllowedBlocked(
|
_clients?.clientsAllowedBlocked = ClientsAllowedBlocked(
|
||||||
allowedClients: body['allowed_clients'] ?? [],
|
allowedClients: body['allowed_clients'] ?? [],
|
||||||
disallowedClients: body['disallowed_clients'] ?? [],
|
disallowedClients: body['disallowed_clients'] ?? [],
|
||||||
blockedHosts: body['blocked_hosts'] ?? [],
|
blockedHosts: body['blocked_hosts'] ?? [],
|
||||||
);
|
);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return { 'success': true };
|
return result;
|
||||||
}
|
}
|
||||||
else if (result['result'] == 'error' && result['message'] == 'client_another_list') {
|
else if (result.successful == false && result.content == 'client_another_list') {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return {
|
return result;
|
||||||
'success': false,
|
|
||||||
'error': 'client_another_list'
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return {
|
return result;
|
||||||
'success': false,
|
|
||||||
'error': null
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> removeClientList(String client, String type) async {
|
AccessSettingsList? checkClientList(String client) {
|
||||||
|
if (_clients!.clientsAllowedBlocked!.allowedClients.contains(client)) {
|
||||||
|
return AccessSettingsList.allowed;
|
||||||
|
}
|
||||||
|
else if (_clients!.clientsAllowedBlocked!.disallowedClients.contains(client)) {
|
||||||
|
return AccessSettingsList.disallowed;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ApiResponse> removeClientList(String client, AccessSettingsList type) async {
|
||||||
Map<String, List<String>> body = {
|
Map<String, List<String>> body = {
|
||||||
"allowed_clients": clients!.clientsAllowedBlocked?.allowedClients ?? [],
|
"allowed_clients": clients!.clientsAllowedBlocked?.allowedClients ?? [],
|
||||||
"disallowed_clients": clients!.clientsAllowedBlocked?.disallowedClients ?? [],
|
"disallowed_clients": clients!.clientsAllowedBlocked?.disallowedClients ?? [],
|
||||||
"blocked_hosts": clients!.clientsAllowedBlocked?.blockedHosts ?? [],
|
"blocked_hosts": clients!.clientsAllowedBlocked?.blockedHosts ?? [],
|
||||||
};
|
};
|
||||||
|
|
||||||
if (type == 'allowed') {
|
if (type == AccessSettingsList.allowed) {
|
||||||
body['allowed_clients'] = body['allowed_clients']!.where((c) => c != client).toList();
|
body['allowed_clients'] = body['allowed_clients']!.where((c) => c != client).toList();
|
||||||
}
|
}
|
||||||
else if (type == 'disallowed') {
|
else if (type == AccessSettingsList.disallowed) {
|
||||||
body['disallowed_clients'] = body['disallowed_clients']!.where((c) => c != client).toList();
|
body['disallowed_clients'] = body['disallowed_clients']!.where((c) => c != client).toList();
|
||||||
}
|
}
|
||||||
else if (type == 'domains') {
|
else if (type == AccessSettingsList.domains) {
|
||||||
body['blocked_hosts'] = body['blocked_hosts']!.where((c) => c != client).toList();
|
body['blocked_hosts'] = body['blocked_hosts']!.where((c) => c != client).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.requestAllowedBlockedClientsHosts(body);
|
final result = await _serversProvider!.apiClient2!.requestAllowedBlockedClientsHosts(
|
||||||
|
body: body
|
||||||
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_clients?.clientsAllowedBlocked = ClientsAllowedBlocked(
|
_clients?.clientsAllowedBlocked = ClientsAllowedBlocked(
|
||||||
allowedClients: body['allowed_clients'] ?? [],
|
allowedClients: body['allowed_clients'] ?? [],
|
||||||
disallowedClients: body['disallowed_clients'] ?? [],
|
disallowedClients: body['disallowed_clients'] ?? [],
|
||||||
blockedHosts: body['blocked_hosts'] ?? [],
|
blockedHosts: body['blocked_hosts'] ?? [],
|
||||||
);
|
);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return { 'success': true };
|
return result;
|
||||||
}
|
}
|
||||||
else if (result['result'] == 'error' && result['message'] == 'client_another_list') {
|
else if (result.successful == false && result.content == 'client_another_list') {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return {
|
return result;
|
||||||
'success': false,
|
|
||||||
'error': 'client_another_list'
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return {
|
return result;
|
||||||
'success': false,
|
|
||||||
'error': null
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/services/api_client.dart';
|
||||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||||
import 'package:adguard_home_manager/constants/enums.dart';
|
import 'package:adguard_home_manager/constants/enums.dart';
|
||||||
import 'package:adguard_home_manager/models/dhcp.dart';
|
import 'package:adguard_home_manager/models/dhcp.dart';
|
||||||
|
@ -41,9 +42,9 @@ class DhcpProvider with ChangeNotifier {
|
||||||
_loadStatus = LoadStatus.loading;
|
_loadStatus = LoadStatus.loading;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
final result = await _serversProvider!.apiClient!.getDhcpData();
|
final result = await _serversProvider!.apiClient2!.getDhcpData();
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_dhcp = result['data'];
|
_dhcp = result.content as DhcpModel;
|
||||||
_loadStatus = LoadStatus.loaded;
|
_loadStatus = LoadStatus.loaded;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return true;
|
return true;
|
||||||
|
@ -58,7 +59,7 @@ class DhcpProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> deleteLease(Lease lease) async {
|
Future<bool> deleteLease(Lease lease) async {
|
||||||
final result = await _serversProvider!.apiClient!.deleteStaticLease(
|
final result = await _serversProvider!.apiClient2!.deleteStaticLease(
|
||||||
data: {
|
data: {
|
||||||
"mac": lease.mac,
|
"mac": lease.mac,
|
||||||
"ip": lease.ip,
|
"ip": lease.ip,
|
||||||
|
@ -66,9 +67,9 @@ class DhcpProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
DhcpModel data = dhcp!;
|
DhcpModel data = dhcp!;
|
||||||
data.dhcpStatus.staticLeases = data.dhcpStatus.staticLeases.where((l) => l.mac != lease.mac).toList();
|
data.dhcpStatus!.staticLeases = data.dhcpStatus!.staticLeases.where((l) => l.mac != lease.mac).toList();
|
||||||
setDhcpData(data);
|
setDhcpData(data);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -78,8 +79,8 @@ class DhcpProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> createLease(Lease lease) async {
|
Future<ApiResponse> createLease(Lease lease) async {
|
||||||
final result = await _serversProvider!.apiClient!.createStaticLease(
|
final result = await _serversProvider!.apiClient2!.createStaticLease(
|
||||||
data: {
|
data: {
|
||||||
"mac": lease.mac,
|
"mac": lease.mac,
|
||||||
"ip": lease.ip,
|
"ip": lease.ip,
|
||||||
|
@ -87,29 +88,14 @@ class DhcpProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
DhcpModel data = dhcp!;
|
DhcpModel data = dhcp!;
|
||||||
data.dhcpStatus.staticLeases.add(lease);
|
data.dhcpStatus!.staticLeases.add(lease);
|
||||||
setDhcpData(data);
|
setDhcpData(data);
|
||||||
return { 'success': true };
|
return result;
|
||||||
}
|
|
||||||
else if (result['result'] == 'error' && result['message'] == 'already_exists' ) {
|
|
||||||
return {
|
|
||||||
'success': false,
|
|
||||||
'error': 'already_exists'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (result['result'] == 'error' && result['message'] == 'server_not_configured' ) {
|
|
||||||
return {
|
|
||||||
'success': false,
|
|
||||||
'error': 'server_not_configured'
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return {
|
return result;
|
||||||
'success': false,
|
|
||||||
'error': null
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/services/api_client.dart';
|
||||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||||
import 'package:adguard_home_manager/constants/enums.dart';
|
import 'package:adguard_home_manager/constants/enums.dart';
|
||||||
import 'package:adguard_home_manager/models/dns_info.dart';
|
import 'package:adguard_home_manager/models/dns_info.dart';
|
||||||
|
@ -41,10 +42,10 @@ class DnsProvider with ChangeNotifier {
|
||||||
_loadStatus = LoadStatus.loading;
|
_loadStatus = LoadStatus.loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.getDnsInfo();
|
final result = await _serversProvider!.apiClient2!.getDnsInfo();
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_dnsInfo = result['data'];
|
_dnsInfo = result.content as DnsInfo;
|
||||||
_loadStatus = LoadStatus.loaded;
|
_loadStatus = LoadStatus.loaded;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return true;
|
return true;
|
||||||
|
@ -58,12 +59,12 @@ class DnsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> savePrivateReverseServersConfig(Map<String, dynamic> value) async {
|
Future<ApiResponse> savePrivateReverseServersConfig(Map<String, dynamic> value) async {
|
||||||
final result = await _serversProvider!.apiClient!.setDnsConfig(
|
final result = await _serversProvider!.apiClient2!.setDnsConfig(
|
||||||
data: value
|
data: value
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
DnsInfo data = dnsInfo!;
|
DnsInfo data = dnsInfo!;
|
||||||
if (value['local_ptr_upstreams'] != null) {
|
if (value['local_ptr_upstreams'] != null) {
|
||||||
data.localPtrUpstreams = value['local_ptr_upstreams'];
|
data.localPtrUpstreams = value['local_ptr_upstreams'];
|
||||||
|
@ -71,107 +72,87 @@ class DnsProvider with ChangeNotifier {
|
||||||
data.usePrivatePtrResolvers = value['use_private_ptr_resolvers'];
|
data.usePrivatePtrResolvers = value['use_private_ptr_resolvers'];
|
||||||
data.resolveClients = value['resolve_clients'];
|
data.resolveClients = value['resolve_clients'];
|
||||||
setDnsInfoData(data);
|
setDnsInfoData(data);
|
||||||
return { 'success': true };
|
return result;
|
||||||
}
|
|
||||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
|
||||||
return {
|
|
||||||
'success': false,
|
|
||||||
'error': 400
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return {
|
return result;
|
||||||
'success': false,
|
}
|
||||||
'error': null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> saveUpstreamDnsConfig(Map<String, dynamic> value) async {
|
Future<ApiResponse> saveUpstreamDnsConfig(Map<String, dynamic> value) async {
|
||||||
final result = await _serversProvider!.apiClient!.setDnsConfig(
|
final result = await _serversProvider!.apiClient2!.setDnsConfig(
|
||||||
data: value
|
data: value
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
DnsInfo data = dnsInfo!;
|
DnsInfo data = dnsInfo!;
|
||||||
data.upstreamDns = List<String>.from(value['upstream_dns']);
|
data.upstreamDns = List<String>.from(value['upstream_dns']);
|
||||||
data.upstreamMode = value['upstream_mode'];
|
data.upstreamMode = value['upstream_mode'];
|
||||||
setDnsInfoData(data);
|
setDnsInfoData(data);
|
||||||
return { 'success': true };
|
return result;
|
||||||
}
|
|
||||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
|
||||||
return {
|
|
||||||
'success': false,
|
|
||||||
'error': 400
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return {
|
return result;
|
||||||
'success': false,
|
}
|
||||||
'error': null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> saveBootstrapDnsConfig(Map<String, dynamic> value) async {
|
Future<ApiResponse> saveBootstrapDnsConfig(Map<String, dynamic> value) async {
|
||||||
final result = await _serversProvider!.apiClient!.setDnsConfig(
|
final result = await _serversProvider!.apiClient2!.setDnsConfig(
|
||||||
data: value
|
data: value
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
DnsInfo data = dnsInfo!;
|
DnsInfo data = dnsInfo!;
|
||||||
data.bootstrapDns = List<String>.from(value['bootstrap_dns']);
|
data.bootstrapDns = List<String>.from(value['bootstrap_dns']);
|
||||||
setDnsInfoData(data);
|
setDnsInfoData(data);
|
||||||
return { 'success': true };
|
return result;
|
||||||
}
|
|
||||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
|
||||||
return {
|
|
||||||
'success': false,
|
|
||||||
'error': 400
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return {
|
return result;
|
||||||
'success': false,
|
}
|
||||||
'error': null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> saveCacheCacheConfig(Map<String, dynamic> value) async {
|
Future<ApiResponse> saveFallbackDnsConfig(Map<String, dynamic> value) async {
|
||||||
final result = await _serversProvider!.apiClient!.setDnsConfig(
|
final result = await _serversProvider!.apiClient2!.setDnsConfig(
|
||||||
data: value
|
data: value
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
|
DnsInfo data = dnsInfo!;
|
||||||
|
data.fallbackDns = List<String>.from(value['fallback_dns']);
|
||||||
|
setDnsInfoData(data);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ApiResponse> saveCacheCacheConfig(Map<String, dynamic> value) async {
|
||||||
|
final result = await _serversProvider!.apiClient2!.setDnsConfig(
|
||||||
|
data: value
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.successful == true) {
|
||||||
DnsInfo data = dnsInfo!;
|
DnsInfo data = dnsInfo!;
|
||||||
data.cacheSize = value['cache_size'];
|
data.cacheSize = value['cache_size'];
|
||||||
data.cacheTtlMin = value['cache_ttl_min'];
|
data.cacheTtlMin = value['cache_ttl_min'];
|
||||||
data.cacheTtlMax = value['cache_ttl_max'];
|
data.cacheTtlMax = value['cache_ttl_max'];
|
||||||
data.cacheOptimistic = value['cache_optimistic'];
|
data.cacheOptimistic = value['cache_optimistic'];
|
||||||
setDnsInfoData(data);
|
setDnsInfoData(data);
|
||||||
return { 'success': true };
|
return result;
|
||||||
}
|
|
||||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
|
||||||
return {
|
|
||||||
'success': false,
|
|
||||||
'error': 400
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return {
|
return result;
|
||||||
'success': false,
|
}
|
||||||
'error': null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> saveDnsServerConfig(Map<String, dynamic> value) async {
|
Future<ApiResponse> saveDnsServerConfig(Map<String, dynamic> value) async {
|
||||||
final result = await _serversProvider!.apiClient!.setDnsConfig(
|
final result = await _serversProvider!.apiClient2!.setDnsConfig(
|
||||||
data: value
|
data: value
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
DnsInfo data = dnsInfo!;
|
DnsInfo data = dnsInfo!;
|
||||||
data.ratelimit = value['ratelimit'];
|
data.ratelimit = value['ratelimit'];
|
||||||
data.ednsCsEnabled = value['edns_cs_enabled'];
|
data.ednsCsEnabled = value['edns_cs_enabled'];
|
||||||
|
@ -180,20 +161,12 @@ class DnsProvider with ChangeNotifier {
|
||||||
data.blockingMode = value['blocking_mode'];
|
data.blockingMode = value['blocking_mode'];
|
||||||
data.blockingIpv4 = value['blocking_ipv4'];
|
data.blockingIpv4 = value['blocking_ipv4'];
|
||||||
data.blockingIpv6 = value['blocking_ipv6'];
|
data.blockingIpv6 = value['blocking_ipv6'];
|
||||||
|
data.blockedResponseTtl = value['blocked_response_ttl'];
|
||||||
setDnsInfoData(data);
|
setDnsInfoData(data);
|
||||||
return { 'success': true };
|
return result;
|
||||||
}
|
|
||||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
|
||||||
return {
|
|
||||||
'success': false,
|
|
||||||
'error': 400
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return {
|
return result;
|
||||||
'success': false,
|
}
|
||||||
'error': null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -88,10 +88,10 @@ class FilteringProvider with ChangeNotifier {
|
||||||
_blockedServicesLoadStatus = LoadStatus.loading;
|
_blockedServicesLoadStatus = LoadStatus.loading;
|
||||||
if (showLoader == true) notifyListeners();
|
if (showLoader == true) notifyListeners();
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.getBlockedServices();
|
final result = await _serversProvider!.apiClient2!.getBlockedServices();
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_blockedServicesLoadStatus = LoadStatus.loaded;
|
_blockedServicesLoadStatus = LoadStatus.loaded;
|
||||||
_blockedServicesList = BlockedServices(services: result['data']);
|
_blockedServicesList = BlockedServices(services: result.content as List<BlockedService>);
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return true;
|
return true;
|
||||||
|
@ -112,9 +112,9 @@ class FilteringProvider with ChangeNotifier {
|
||||||
_loadStatus = LoadStatus.loading;
|
_loadStatus = LoadStatus.loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.getFiltering();
|
final result = await _serversProvider!.apiClient2!.getFiltering();
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_filtering = result['data'];
|
_filtering = result.content as Filtering;
|
||||||
_loadStatus = LoadStatus.loaded;
|
_loadStatus = LoadStatus.loaded;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return true;
|
return true;
|
||||||
|
@ -127,15 +127,16 @@ class FilteringProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> updateLists() async {
|
Future<Map<String, dynamic>> updateLists() async {
|
||||||
final result = await _serversProvider!.apiClient!.updateLists();
|
final result = await _serversProvider!.apiClient2!.updateLists();
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
final result2 = await _serversProvider!.apiClient!.getFiltering();
|
final result2 = await _serversProvider!.apiClient2!.getFiltering();
|
||||||
if (result2['result'] == 'success') {
|
if (result2.successful == true) {
|
||||||
_filtering = result2['data'];
|
_filtering = result2.content as Filtering;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
print(result.content);
|
||||||
return {
|
return {
|
||||||
"success": true,
|
"success": true,
|
||||||
"data": result['data']
|
"data": result.content
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -151,10 +152,10 @@ class FilteringProvider with ChangeNotifier {
|
||||||
|
|
||||||
Future<bool> enableDisableFiltering() async {
|
Future<bool> enableDisableFiltering() async {
|
||||||
final newValue = !_statusProvider!.serverStatus!.filteringEnabled;
|
final newValue = !_statusProvider!.serverStatus!.filteringEnabled;
|
||||||
final result = await _serversProvider!.apiClient!.updateFiltering(
|
final result = await _serversProvider!.apiClient2!.updateFiltering(
|
||||||
enable: newValue
|
enable: newValue
|
||||||
);
|
);
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
setFilteringProtectionStatus(newValue, false);
|
setFilteringProtectionStatus(newValue, false);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return true;
|
return true;
|
||||||
|
@ -166,13 +167,13 @@ class FilteringProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> changeUpdateFrequency(int value) async {
|
Future<bool> changeUpdateFrequency(int value) async {
|
||||||
final result = await _serversProvider!.apiClient!.requestChangeUpdateFrequency(
|
final result = await _serversProvider!.apiClient2!.requestChangeUpdateFrequency(
|
||||||
data: {
|
data: {
|
||||||
"enabled": filtering!.enabled,
|
"enabled": filtering!.enabled,
|
||||||
"interval": value
|
"interval": value
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
setFiltersUpdateFrequency(value);
|
setFiltersUpdateFrequency(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -185,9 +186,9 @@ class FilteringProvider with ChangeNotifier {
|
||||||
Future<bool> removeCustomRule(String rule) async {
|
Future<bool> removeCustomRule(String rule) async {
|
||||||
final List<String> newRules = filtering!.userRules.where((r) => r != rule).toList();
|
final List<String> newRules = filtering!.userRules.where((r) => r != rule).toList();
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.setCustomRules(rules: newRules);
|
final result = await _serversProvider!.apiClient2!.setCustomRules(rules: newRules);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
Filtering filteringData = filtering!;
|
Filtering filteringData = filtering!;
|
||||||
filteringData.userRules = newRules;
|
filteringData.userRules = newRules;
|
||||||
_filtering = filteringData;
|
_filtering = filteringData;
|
||||||
|
@ -205,18 +206,18 @@ class FilteringProvider with ChangeNotifier {
|
||||||
required String listUrl,
|
required String listUrl,
|
||||||
required String type
|
required String type
|
||||||
}) async {
|
}) async {
|
||||||
final result1 = await _serversProvider!.apiClient!.deleteFilterList(
|
final result1 = await _serversProvider!.apiClient2!.deleteFilterList(
|
||||||
data: {
|
data: {
|
||||||
"url": listUrl,
|
"url": listUrl,
|
||||||
"whitelist": type == 'whitelist' ? true : false
|
"whitelist": type == 'whitelist' ? true : false
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result1['result'] == 'success') {
|
if (result1.successful == true) {
|
||||||
final result2 = await _serversProvider!.apiClient!.getFiltering();
|
final result2 = await _serversProvider!.apiClient2!.getFiltering();
|
||||||
|
|
||||||
if (result2['result'] == 'success') {
|
if (result2.successful == true) {
|
||||||
_filtering = result2['data'];
|
_filtering = result2.content as Filtering;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -236,7 +237,7 @@ class FilteringProvider with ChangeNotifier {
|
||||||
required String type,
|
required String type,
|
||||||
required FilteringListActions action
|
required FilteringListActions action
|
||||||
}) async {
|
}) async {
|
||||||
final result1 = await _serversProvider!.apiClient!.updateFilterList(
|
final result1 = await _serversProvider!.apiClient2!.updateFilterList(
|
||||||
data: {
|
data: {
|
||||||
"data": {
|
"data": {
|
||||||
"enabled": action == FilteringListActions.disable || action == FilteringListActions.enable
|
"enabled": action == FilteringListActions.disable || action == FilteringListActions.enable
|
||||||
|
@ -250,11 +251,11 @@ class FilteringProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result1['result'] == 'success') {
|
if (result1.successful == true) {
|
||||||
final result2 = await _serversProvider!.apiClient!.getFiltering();
|
final result2 = await _serversProvider!.apiClient2!.getFiltering();
|
||||||
|
|
||||||
if (result2['result'] == 'success') {
|
if (result2.successful == true) {
|
||||||
_filtering = result2['data'];
|
_filtering = result2.content as Filtering;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -273,9 +274,9 @@ class FilteringProvider with ChangeNotifier {
|
||||||
final List<String> newRules = filtering!.userRules;
|
final List<String> newRules = filtering!.userRules;
|
||||||
newRules.add(rule);
|
newRules.add(rule);
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.setCustomRules(rules: newRules);
|
final result = await _serversProvider!.apiClient2!.setCustomRules(rules: newRules);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
Filtering filteringData = filtering!;
|
Filtering filteringData = filtering!;
|
||||||
filteringData.userRules = newRules;
|
filteringData.userRules = newRules;
|
||||||
_filtering = filteringData;
|
_filtering = filteringData;
|
||||||
|
@ -287,8 +288,9 @@ class FilteringProvider with ChangeNotifier {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> addList({required String name, required String url, required String type}) async {
|
Future<Map<String, dynamic>> addList({required String name, required String url, required String type}) async {
|
||||||
final result1 = await _serversProvider!.apiClient!.addFilteringList(
|
final result1 = await _serversProvider!.apiClient2!.addFilteringList(
|
||||||
data: {
|
data: {
|
||||||
'name': name,
|
'name': name,
|
||||||
'url': url,
|
'url': url,
|
||||||
|
@ -296,13 +298,13 @@ class FilteringProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result1['result'] == 'success') {
|
if (result1.successful == true) {
|
||||||
if (result1['data'].toString().contains("OK")) {
|
if (result1.content.toString().contains("OK")) {
|
||||||
final result2 = await _serversProvider!.apiClient!.getFiltering();
|
final result2 = await _serversProvider!.apiClient2!.getFiltering();
|
||||||
final items = result1['data'].toString().split(' ')[1];
|
final items = result1.content.toString().split(' ')[1];
|
||||||
|
|
||||||
if (result2['result'] == 'success') {
|
if (result2.successful == true) {
|
||||||
_filtering = result2['data'];
|
_filtering = result2.content as Filtering;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return {
|
return {
|
||||||
'success': true,
|
'success': true,
|
||||||
|
@ -325,14 +327,14 @@ class FilteringProvider with ChangeNotifier {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (result1['result'] == 'error' && result1['log'].statusCode == '400' && result1['log'].resBody.toString().contains("Couldn't fetch filter from url")) {
|
else if (result1.successful == false && result1.statusCode == 400 && result1.content.toString().contains("data is HTML, not plain text")) {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return {
|
return {
|
||||||
'success': false,
|
'success': false,
|
||||||
'error': 'invalid_url'
|
'error': 'invalid_url'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if (result1['result'] == 'error' && result1['log'].statusCode == '400' && result1['log'].resBody.toString().contains('Filter URL already added')) {
|
else if (result1.successful == false && result1.statusCode == 400 && result1.content.toString().contains('url already exists')) {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return {
|
return {
|
||||||
'success': false,
|
'success': false,
|
||||||
|
@ -355,9 +357,9 @@ class FilteringProvider with ChangeNotifier {
|
||||||
_blockedServicesLoadStatus = LoadStatus.loading;
|
_blockedServicesLoadStatus = LoadStatus.loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.getBlockedServices();
|
final result = await _serversProvider!.apiClient2!.getBlockedServices();
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_blockedServicesList = BlockedServices(services: result['data']);
|
_blockedServicesList = BlockedServices(services: result.content as List<BlockedService>);
|
||||||
_blockedServicesLoadStatus = LoadStatus.loaded;
|
_blockedServicesLoadStatus = LoadStatus.loaded;
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
@ -371,11 +373,11 @@ class FilteringProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> updateBlockedServices(List<String> values) async {
|
Future<bool> updateBlockedServices(List<String> values) async {
|
||||||
final result = await _serversProvider!.apiClient!.setBlockedServices(
|
final result = await _serversProvider!.apiClient2!.setBlockedServices(
|
||||||
data: values
|
data: values
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
setBlockedServices(values);
|
setBlockedServices(values);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -384,4 +386,75 @@ class FilteringProvider with ChangeNotifier {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<ProcessedList>> deleteMultipleLists({
|
||||||
|
required List<Filter> blacklists,
|
||||||
|
required List<Filter> whitelists
|
||||||
|
}) async {
|
||||||
|
Future<ProcessedList> deleteList({
|
||||||
|
required Filter list,
|
||||||
|
required bool isWhitelist,
|
||||||
|
}) async {
|
||||||
|
final result = await _serversProvider!.apiClient2!.deleteFilterList(
|
||||||
|
data: {
|
||||||
|
"url": list.url,
|
||||||
|
"whitelist": isWhitelist
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (result.successful == true) {
|
||||||
|
return ProcessedList(list: list, successful: true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ProcessedList(list: list, successful: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final resultWhitelists = await Future.wait(whitelists.map((e) => deleteList(list: e, isWhitelist: true)));
|
||||||
|
final resultBlacklists = await Future.wait(blacklists.map((e) => deleteList(list: e, isWhitelist: false)));
|
||||||
|
|
||||||
|
await fetchFilters();
|
||||||
|
|
||||||
|
return [
|
||||||
|
...resultWhitelists,
|
||||||
|
...resultBlacklists,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<ProcessedList>> enableDisableMultipleLists({
|
||||||
|
required List<Filter> blacklists,
|
||||||
|
required List<Filter> whitelists
|
||||||
|
}) async {
|
||||||
|
Future<ProcessedList> enableDisableList({
|
||||||
|
required Filter list,
|
||||||
|
required bool isWhitelist,
|
||||||
|
}) async {
|
||||||
|
final result = await _serversProvider!.apiClient2!.updateFilterList(
|
||||||
|
data: {
|
||||||
|
"data": {
|
||||||
|
"enabled": !list.enabled,
|
||||||
|
"name": list.name,
|
||||||
|
"url": list.url
|
||||||
|
},
|
||||||
|
"url": list.url,
|
||||||
|
"whitelist": isWhitelist
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (result.successful == true) {
|
||||||
|
return ProcessedList(list: list, successful: true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ProcessedList(list: list, successful: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final resultWhitelists = await Future.wait(whitelists.map((e) => enableDisableList(list: e, isWhitelist: true)));
|
||||||
|
final resultBlacklists = await Future.wait(blacklists.map((e) => enableDisableList(list: e, isWhitelist: false)));
|
||||||
|
|
||||||
|
await fetchFilters();
|
||||||
|
|
||||||
|
return [
|
||||||
|
...resultWhitelists,
|
||||||
|
...resultBlacklists,
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -114,9 +114,15 @@ class LogsProvider with ChangeNotifier {
|
||||||
_offset = value;
|
_offset = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSelectedResultStatus(String value) {
|
void setSelectedResultStatus({
|
||||||
|
required String value,
|
||||||
|
bool? refetch
|
||||||
|
}) {
|
||||||
_selectedResultStatus = value;
|
_selectedResultStatus = value;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
if (refetch = true) {
|
||||||
|
filterLogs();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSearchText(String? value) {
|
void setSearchText(String? value) {
|
||||||
|
@ -153,7 +159,7 @@ class LogsProvider with ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.getLogs(
|
final result = await _serversProvider!.apiClient2!.getLogs(
|
||||||
count: logsQuantity,
|
count: logsQuantity,
|
||||||
offset: offst,
|
offset: offst,
|
||||||
olderThan: logsOlderThan,
|
olderThan: logsOlderThan,
|
||||||
|
@ -166,11 +172,11 @@ class LogsProvider with ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_offset = inOffset != null ? inOffset+logsQuantity : offset+logsQuantity;
|
_offset = inOffset != null ? inOffset+logsQuantity : offset+logsQuantity;
|
||||||
if (loadingMore != null && loadingMore == true && logsData != null) {
|
if (loadingMore != null && loadingMore == true && logsData != null) {
|
||||||
LogsData newLogsData = result['data'];
|
LogsData newLogsData = result.content;
|
||||||
newLogsData.data = [...logsData!.data, ...result['data'].data];
|
newLogsData.data = [...logsData!.data, ...(result.content as LogsData).data];
|
||||||
if (appliedFilters.clients != null) {
|
if (appliedFilters.clients != null) {
|
||||||
newLogsData.data = newLogsData.data.where(
|
newLogsData.data = newLogsData.data.where(
|
||||||
(item) => appliedFilters.clients!.contains(item.client)
|
(item) => appliedFilters.clients!.contains(item.client)
|
||||||
|
@ -179,7 +185,7 @@ class LogsProvider with ChangeNotifier {
|
||||||
_logsData = newLogsData;
|
_logsData = newLogsData;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogsData newLogsData = result['data'];
|
LogsData newLogsData = result.content;
|
||||||
if (appliedFilters.clients != null) {
|
if (appliedFilters.clients != null) {
|
||||||
newLogsData.data = newLogsData.data.where(
|
newLogsData.data = newLogsData.data.where(
|
||||||
(item) => appliedFilters.clients!.contains(item.client)
|
(item) => appliedFilters.clients!.contains(item.client)
|
||||||
|
@ -204,7 +210,7 @@ class LogsProvider with ChangeNotifier {
|
||||||
|
|
||||||
resetFilters();
|
resetFilters();
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.getLogs(
|
final result = await _serversProvider!.apiClient2!.getLogs(
|
||||||
count: logsQuantity
|
count: logsQuantity
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -214,8 +220,8 @@ class LogsProvider with ChangeNotifier {
|
||||||
clients: null
|
clients: null
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_logsData = result['data'];
|
_logsData = result.content as LogsData;
|
||||||
_loadStatus = LoadStatus.loaded;
|
_loadStatus = LoadStatus.loaded;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return true;
|
return true;
|
||||||
|
@ -233,7 +239,7 @@ class LogsProvider with ChangeNotifier {
|
||||||
|
|
||||||
setOffset(0);
|
setOffset(0);
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.getLogs(
|
final result = await _serversProvider!.apiClient2!.getLogs(
|
||||||
count: logsQuantity,
|
count: logsQuantity,
|
||||||
olderThan: logsOlderThan,
|
olderThan: logsOlderThan,
|
||||||
responseStatus: selectedResultStatus,
|
responseStatus: selectedResultStatus,
|
||||||
|
@ -246,8 +252,8 @@ class LogsProvider with ChangeNotifier {
|
||||||
clients: selectedClients
|
clients: selectedClients
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
LogsData newLogsData = result['data'];
|
LogsData newLogsData = result.content as LogsData;
|
||||||
if (appliedFilters.clients != null) {
|
if (appliedFilters.clients != null) {
|
||||||
newLogsData.data = newLogsData.data.where(
|
newLogsData.data = newLogsData.data.where(
|
||||||
(item) => appliedFilters.clients!.contains(item.client)
|
(item) => appliedFilters.clients!.contains(item.client)
|
||||||
|
|
|
@ -35,14 +35,14 @@ class RewriteRulesProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> addDnsRewrite(RewriteRules rule) async {
|
Future<bool> addDnsRewrite(RewriteRules rule) async {
|
||||||
final result = await _serversProvider!.apiClient!.addDnsRewriteRule(
|
final result = await _serversProvider!.apiClient2!.addDnsRewriteRule(
|
||||||
data: {
|
data: {
|
||||||
"domain": rule.domain,
|
"domain": rule.domain,
|
||||||
"answer": rule.answer
|
"answer": rule.answer
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
List<RewriteRules> data = rewriteRules!;
|
List<RewriteRules> data = rewriteRules!;
|
||||||
data.add(rule);
|
data.add(rule);
|
||||||
setRewriteRulesData(data);
|
setRewriteRulesData(data);
|
||||||
|
@ -55,7 +55,7 @@ class RewriteRulesProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> editDnsRewrite(RewriteRules newRule, RewriteRules oldRule) async {
|
Future<bool> editDnsRewrite(RewriteRules newRule, RewriteRules oldRule) async {
|
||||||
final result = await _serversProvider!.apiClient!.updateRewriteRule(
|
final result = await _serversProvider!.apiClient2!.updateRewriteRule(
|
||||||
body: {
|
body: {
|
||||||
"target": {
|
"target": {
|
||||||
"answer": oldRule.answer,
|
"answer": oldRule.answer,
|
||||||
|
@ -68,7 +68,7 @@ class RewriteRulesProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
List<RewriteRules> data = rewriteRules!;
|
List<RewriteRules> data = rewriteRules!;
|
||||||
final index = data.indexOf(oldRule);
|
final index = data.indexOf(oldRule);
|
||||||
data[index] = newRule;
|
data[index] = newRule;
|
||||||
|
@ -82,14 +82,14 @@ class RewriteRulesProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> deleteDnsRewrite(RewriteRules rule) async {
|
Future<bool> deleteDnsRewrite(RewriteRules rule) async {
|
||||||
final result = await _serversProvider!.apiClient!.deleteDnsRewriteRule(
|
final result = await _serversProvider!.apiClient2!.deleteDnsRewriteRule(
|
||||||
data: {
|
data: {
|
||||||
"domain": rule.domain,
|
"domain": rule.domain,
|
||||||
"answer": rule.answer
|
"answer": rule.answer
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
List<RewriteRules> data = rewriteRules!;
|
List<RewriteRules> data = rewriteRules!;
|
||||||
data = data.where((item) => item.domain != rule.domain).toList();
|
data = data.where((item) => item.domain != rule.domain).toList();
|
||||||
setRewriteRulesData(data);
|
setRewriteRulesData(data);
|
||||||
|
@ -108,10 +108,10 @@ class RewriteRulesProvider with ChangeNotifier {
|
||||||
_loadStatus = LoadStatus.loading;
|
_loadStatus = LoadStatus.loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.getDnsRewriteRules();
|
final result = await _serversProvider!.apiClient2!.getDnsRewriteRules();
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_rewriteRules = result['data'];
|
_rewriteRules = result.content as List<RewriteRules>;
|
||||||
_loadStatus = LoadStatus.loaded;
|
_loadStatus = LoadStatus.loaded;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -3,9 +3,11 @@ import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:sqflite/sqflite.dart';
|
import 'package:sqflite/sqflite.dart';
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/models/github_release.dart';
|
||||||
|
import 'package:adguard_home_manager/services/api_client.dart';
|
||||||
|
import 'package:adguard_home_manager/services/external_requests.dart';
|
||||||
import 'package:adguard_home_manager/models/server.dart';
|
import 'package:adguard_home_manager/models/server.dart';
|
||||||
import 'package:adguard_home_manager/models/update_available.dart';
|
import 'package:adguard_home_manager/models/update_available.dart';
|
||||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
|
||||||
import 'package:adguard_home_manager/functions/conversions.dart';
|
import 'package:adguard_home_manager/functions/conversions.dart';
|
||||||
import 'package:adguard_home_manager/services/db/queries.dart';
|
import 'package:adguard_home_manager/services/db/queries.dart';
|
||||||
import 'package:adguard_home_manager/constants/enums.dart';
|
import 'package:adguard_home_manager/constants/enums.dart';
|
||||||
|
@ -15,7 +17,8 @@ class ServersProvider with ChangeNotifier {
|
||||||
|
|
||||||
List<Server> _serversList = [];
|
List<Server> _serversList = [];
|
||||||
Server? _selectedServer;
|
Server? _selectedServer;
|
||||||
ApiClient? _apiClient;
|
// ApiClient? _apiClient;
|
||||||
|
ApiClientV2? _apiClient2;
|
||||||
|
|
||||||
bool _updatingServer = false;
|
bool _updatingServer = false;
|
||||||
|
|
||||||
|
@ -24,8 +27,12 @@ class ServersProvider with ChangeNotifier {
|
||||||
data: null,
|
data: null,
|
||||||
);
|
);
|
||||||
|
|
||||||
ApiClient? get apiClient {
|
// ApiClient? get apiClient {
|
||||||
return _apiClient;
|
// return _apiClient;
|
||||||
|
// }
|
||||||
|
|
||||||
|
ApiClientV2? get apiClient2 {
|
||||||
|
return _apiClient2;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Server> get serversList {
|
List<Server> get serversList {
|
||||||
|
@ -53,7 +60,7 @@ class ServersProvider with ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSelectedServer(Server server) {
|
void setSelectedServer(Server? server) {
|
||||||
_selectedServer = server;
|
_selectedServer = server;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
@ -70,8 +77,13 @@ class ServersProvider with ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setApiClient(ApiClient client) {
|
// void setApiClient(ApiClient client) {
|
||||||
_apiClient = client;
|
// _apiClient = client;
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
|
||||||
|
void setApiClient2(ApiClientV2 client) {
|
||||||
|
_apiClient2 = client;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +153,8 @@ class ServersProvider with ChangeNotifier {
|
||||||
_serversList = newServers;
|
_serversList = newServers;
|
||||||
|
|
||||||
if (selectedServer != null &&server.id == selectedServer!.id) {
|
if (selectedServer != null &&server.id == selectedServer!.id) {
|
||||||
_apiClient = ApiClient(server: server);
|
// _apiClient = ApiClient(server: server);
|
||||||
|
_apiClient2 = ApiClientV2(server: server);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
@ -156,7 +169,7 @@ class ServersProvider with ChangeNotifier {
|
||||||
final result = await removeServerQuery(_dbInstance!, server.id);
|
final result = await removeServerQuery(_dbInstance!, server.id);
|
||||||
if (result == true) {
|
if (result == true) {
|
||||||
_selectedServer = null;
|
_selectedServer = null;
|
||||||
_apiClient = null;
|
// _apiClient = null;
|
||||||
List<Server> newServers = _serversList.where((s) => s.id != server.id).toList();
|
List<Server> newServers = _serversList.where((s) => s.id != server.id).toList();
|
||||||
_serversList = newServers;
|
_serversList = newServers;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
@ -169,14 +182,16 @@ class ServersProvider with ChangeNotifier {
|
||||||
|
|
||||||
void checkServerUpdatesAvailable({
|
void checkServerUpdatesAvailable({
|
||||||
required Server server,
|
required Server server,
|
||||||
|
ApiClientV2? apiClient
|
||||||
}) async {
|
}) async {
|
||||||
|
final client = apiClient ?? _apiClient2;
|
||||||
setUpdateAvailableLoadStatus(LoadStatus.loading, true);
|
setUpdateAvailableLoadStatus(LoadStatus.loading, true);
|
||||||
final result = await _apiClient!.checkServerUpdates();
|
final result = await client!.checkServerUpdates();
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
UpdateAvailableData data = UpdateAvailableData.fromJson(result['data']);
|
UpdateAvailableData data = UpdateAvailableData.fromJson(result.content);
|
||||||
final gitHubResult = await _apiClient!.getUpdateChangelog(releaseTag: data.newVersion ?? data.currentVersion);
|
final gitHubResult = await ExternalRequests.getReleaseData(releaseTag: data.newVersion ?? data.currentVersion);
|
||||||
if (gitHubResult['result'] == 'success') {
|
if (gitHubResult.successful == true) {
|
||||||
data.changelog = gitHubResult['body'];
|
data.changelog = (gitHubResult.content as GitHubRelease).body;
|
||||||
}
|
}
|
||||||
setUpdateAvailableData(data);
|
setUpdateAvailableData(data);
|
||||||
setUpdateAvailableLoadStatus(LoadStatus.loaded, true);
|
setUpdateAvailableLoadStatus(LoadStatus.loaded, true);
|
||||||
|
@ -186,11 +201,12 @@ class ServersProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future initializateServer(Server server) async {
|
Future initializateServer(Server server, /*ApiClient apiClient, */ ApiClientV2 apiClient2) async {
|
||||||
final serverStatus = await _apiClient!.getServerStatus();
|
final serverStatus = await _apiClient2!.getServerStatus();
|
||||||
if (serverStatus['result'] == 'success') {
|
if (serverStatus.successful == true) {
|
||||||
checkServerUpdatesAvailable( // Do not await
|
checkServerUpdatesAvailable( // Do not await
|
||||||
server: server,
|
server: server,
|
||||||
|
apiClient: apiClient2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,8 +238,11 @@ class ServersProvider with ChangeNotifier {
|
||||||
|
|
||||||
if (defaultServer != null) {
|
if (defaultServer != null) {
|
||||||
_selectedServer = defaultServer;
|
_selectedServer = defaultServer;
|
||||||
_apiClient = ApiClient(server: defaultServer);
|
// final client = ApiClient(server: defaultServer);
|
||||||
initializateServer(defaultServer);
|
final client2 = ApiClientV2(server: defaultServer);
|
||||||
|
// _apiClient = client;
|
||||||
|
_apiClient2 = client2;
|
||||||
|
initializateServer(defaultServer, /*client,*/ client2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -240,13 +259,13 @@ class ServersProvider with ChangeNotifier {
|
||||||
const Duration(seconds: 2),
|
const Duration(seconds: 2),
|
||||||
(timer) async {
|
(timer) async {
|
||||||
if (_selectedServer != null && _selectedServer == server) {
|
if (_selectedServer != null && _selectedServer == server) {
|
||||||
final result = await _apiClient!.checkServerUpdates();
|
final result = await _apiClient2!.checkServerUpdates();
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
UpdateAvailableData data = UpdateAvailableData.fromJsonUpdate(result['data']);
|
UpdateAvailableData data = UpdateAvailableData.fromJsonUpdate(result.content);
|
||||||
if (data.currentVersion == data.newVersion) {
|
if (data.currentVersion == data.newVersion) {
|
||||||
final gitHubResult = await _apiClient!.getUpdateChangelog(releaseTag: data.newVersion ?? data.currentVersion);
|
final gitHubResult = await ExternalRequests.getReleaseData(releaseTag: data.newVersion ?? data.currentVersion);
|
||||||
if (gitHubResult['result'] == 'success') {
|
if (gitHubResult.successful == true) {
|
||||||
data.changelog = gitHubResult['body'];
|
data.changelog = (gitHubResult.content as GitHubRelease).body;
|
||||||
}
|
}
|
||||||
setUpdateAvailableData(data);
|
setUpdateAvailableData(data);
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
|
|
|
@ -2,11 +2,15 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/widgets/add_server/unsupported_version_modal.dart';
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/config/globals.dart';
|
||||||
|
import 'package:adguard_home_manager/config/minimum_server_version.dart';
|
||||||
|
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||||
import 'package:adguard_home_manager/models/server_status.dart';
|
import 'package:adguard_home_manager/models/server_status.dart';
|
||||||
import 'package:adguard_home_manager/models/filtering_status.dart';
|
import 'package:adguard_home_manager/models/filtering_status.dart';
|
||||||
import 'package:adguard_home_manager/constants/enums.dart';
|
import 'package:adguard_home_manager/constants/enums.dart';
|
||||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
|
||||||
import 'package:adguard_home_manager/functions/time_server_disabled.dart';
|
import 'package:adguard_home_manager/functions/time_server_disabled.dart';
|
||||||
|
|
||||||
class StatusProvider with ChangeNotifier {
|
class StatusProvider with ChangeNotifier {
|
||||||
|
@ -104,7 +108,7 @@ class StatusProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> updateBlocking({
|
Future<bool> updateBlocking({
|
||||||
required String block,
|
required String block,
|
||||||
required bool newStatus,
|
required bool newStatus,
|
||||||
int? time
|
int? time
|
||||||
|
@ -114,14 +118,14 @@ class StatusProvider with ChangeNotifier {
|
||||||
_protectionsManagementProcess.add('general');
|
_protectionsManagementProcess.add('general');
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.updateGeneralProtection(
|
final result = await _serversProvider!.apiClient2!.updateGeneralProtection(
|
||||||
enable: newStatus,
|
enable: newStatus,
|
||||||
time: time
|
time: time
|
||||||
);
|
);
|
||||||
|
|
||||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'general').toList();
|
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'general').toList();
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_serverStatus!.generalEnabled = newStatus;
|
_serverStatus!.generalEnabled = newStatus;
|
||||||
if (time != null) {
|
if (time != null) {
|
||||||
final deadline = generateTimeDeadline(time);
|
final deadline = generateTimeDeadline(time);
|
||||||
|
@ -135,111 +139,80 @@ class StatusProvider with ChangeNotifier {
|
||||||
stopCountdown();
|
stopCountdown();
|
||||||
}
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return null;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
notifyListeners();
|
return false;
|
||||||
return result['log'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'general_legacy':
|
|
||||||
_protectionsManagementProcess.add('general');
|
|
||||||
notifyListeners();
|
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.updateGeneralProtectionLegacy(newStatus);
|
|
||||||
|
|
||||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'general').toList();
|
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
|
||||||
_serverStatus!.generalEnabled = newStatus;
|
|
||||||
notifyListeners();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
notifyListeners();
|
|
||||||
return result['log'];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
case 'filtering':
|
case 'filtering':
|
||||||
_protectionsManagementProcess.add('filtering');
|
_protectionsManagementProcess.add('filtering');
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.updateFiltering(
|
final result = await _serversProvider!.apiClient2!.updateFiltering(
|
||||||
enable: newStatus,
|
enable: newStatus,
|
||||||
);
|
);
|
||||||
|
|
||||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'filtering').toList();
|
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'filtering').toList();
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_serverStatus!.filteringEnabled = newStatus;
|
_serverStatus!.filteringEnabled = newStatus;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return null;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
return false;
|
||||||
notifyListeners();
|
|
||||||
return result['log'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'safeSearch':
|
case 'safeSearch':
|
||||||
_protectionsManagementProcess.add('safeSearch');
|
_protectionsManagementProcess.add('safeSearch');
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
final result = serverVersionIsAhead(
|
final result = await _serversProvider!.apiClient2!.updateSafeSearchSettings(body: { 'enabled': newStatus });
|
||||||
currentVersion: serverStatus!.serverVersion,
|
|
||||||
referenceVersion: 'v0.107.28',
|
|
||||||
referenceVersionBeta: 'v0.108.0-b.33'
|
|
||||||
) == true
|
|
||||||
? await _serversProvider!.apiClient!.updateSafeSearchSettings(body: { 'enabled': newStatus })
|
|
||||||
: await _serversProvider!.apiClient!.updateSafeSearchLegacy(newStatus);
|
|
||||||
|
|
||||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'safeSearch').toList();
|
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'safeSearch').toList();
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_serverStatus!.safeSearchEnabled = newStatus;
|
_serverStatus!.safeSearchEnabled = newStatus;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return null;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
notifyListeners();
|
return false;
|
||||||
return result['log'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'safeBrowsing':
|
case 'safeBrowsing':
|
||||||
_protectionsManagementProcess.add('safeBrowsing');
|
_protectionsManagementProcess.add('safeBrowsing');
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.updateSafeBrowsing(newStatus);
|
final result = await _serversProvider!.apiClient2!.updateSafeBrowsing(enable: newStatus);
|
||||||
|
|
||||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'safeBrowsing').toList();
|
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'safeBrowsing').toList();
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_serverStatus!.safeBrowsingEnabled = newStatus;
|
_serverStatus!.safeBrowsingEnabled = newStatus;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return null;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
notifyListeners();
|
return false;
|
||||||
return result['log'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'parentalControl':
|
case 'parentalControl':
|
||||||
_protectionsManagementProcess.add('parentalControl');
|
_protectionsManagementProcess.add('parentalControl');
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.updateParentalControl(newStatus);
|
final result = await _serversProvider!.apiClient2!.updateParentalControl(enable: newStatus);
|
||||||
|
|
||||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'parentalControl').toList();
|
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'parentalControl').toList();
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_serverStatus!.parentalControlEnabled = newStatus;
|
_serverStatus!.parentalControlEnabled = newStatus;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return null;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
notifyListeners();
|
return false;
|
||||||
return result['log'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -252,9 +225,9 @@ class StatusProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> getFilteringRules() async {
|
Future<bool> getFilteringRules() async {
|
||||||
final result = await _serversProvider!.apiClient!.getFilteringRules();
|
final result = await _serversProvider!.apiClient2!.getFilteringRules();
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
_filteringStatus = result['data'];
|
_filteringStatus = result.content as FilteringStatus;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -264,19 +237,39 @@ class StatusProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> getServerStatus({
|
Future<bool> getServerStatus({
|
||||||
bool? withLoadingIndicator
|
bool? withLoadingIndicator = true,
|
||||||
|
bool? overrideCheckServerVersion
|
||||||
}) async {
|
}) async {
|
||||||
if (withLoadingIndicator == true) {
|
if (withLoadingIndicator == true) {
|
||||||
_loadStatus = LoadStatus.loading;
|
_loadStatus = LoadStatus.loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.getServerStatus();
|
final result = await _serversProvider!.apiClient2!.getServerStatus();
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
|
final status = result.content as ServerStatus;
|
||||||
setServerStatusData(
|
setServerStatusData(
|
||||||
data: result['data']
|
data: status
|
||||||
);
|
);
|
||||||
_loadStatus = LoadStatus.loaded;
|
_loadStatus = LoadStatus.loaded;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
|
// Check server version and launch modal if not valid
|
||||||
|
final validVersion = serverVersionIsAhead(
|
||||||
|
currentVersion: status.serverVersion,
|
||||||
|
referenceVersion: MinimumServerVersion.stable,
|
||||||
|
referenceVersionBeta: MinimumServerVersion.beta
|
||||||
|
);
|
||||||
|
if (validVersion == false && overrideCheckServerVersion != true) {
|
||||||
|
showDialog(
|
||||||
|
context: globalNavigatorKey.currentContext!,
|
||||||
|
builder: (ctx) => UnsupportedVersionModal(
|
||||||
|
serverVersion: status.serverVersion,
|
||||||
|
onClose: () {
|
||||||
|
_serversProvider!.setSelectedServer(null);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -292,12 +285,12 @@ class StatusProvider with ChangeNotifier {
|
||||||
}) async {
|
}) async {
|
||||||
if (_serverStatus == null) return false;
|
if (_serverStatus == null) return false;
|
||||||
|
|
||||||
final rules = await _serversProvider!.apiClient!.getFilteringRules();
|
final rules = await _serversProvider!.apiClient2!.getFilteringRules();
|
||||||
|
|
||||||
if (rules['result'] == 'success') {
|
if (rules.successful == true) {
|
||||||
FilteringStatus oldStatus = _serverStatus!.filteringStatus;
|
FilteringStatus oldStatus = _serverStatus!.filteringStatus;
|
||||||
|
|
||||||
List<String> newRules = rules['data'].userRules.where((d) => !d.contains(domain)).toList();
|
List<String> newRules = (rules.content as FilteringStatus).userRules.where((d) => !d.contains(domain)).toList();
|
||||||
if (newStatus == 'block') {
|
if (newStatus == 'block') {
|
||||||
newRules.add("||$domain^");
|
newRules.add("||$domain^");
|
||||||
}
|
}
|
||||||
|
@ -308,9 +301,9 @@ class StatusProvider with ChangeNotifier {
|
||||||
newObj.userRules = newRules;
|
newObj.userRules = newRules;
|
||||||
_filteringStatus = newObj;
|
_filteringStatus = newObj;
|
||||||
|
|
||||||
final result = await _serversProvider!.apiClient!.postFilteringRules(data: {'rules': newRules});
|
final result = await _serversProvider!.apiClient2!.postFilteringRules(data: {'rules': newRules});
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -324,11 +317,11 @@ class StatusProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> updateSafeSearchConfig(Map<String, bool> status) async {
|
Future<bool> updateSafeSearchConfig(Map<String, bool> status) async {
|
||||||
final result = await _serversProvider!.apiClient!.updateSafeSearchSettings(
|
final result = await _serversProvider!.apiClient2!.updateSafeSearchSettings(
|
||||||
body: status
|
body: status
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result['result'] == 'success') {
|
if (result.successful == true) {
|
||||||
ServerStatus data = serverStatus!;
|
ServerStatus data = serverStatus!;
|
||||||
data.safeSearchEnabled = status['enabled'] ?? false;
|
data.safeSearchEnabled = status['enabled'] ?? false;
|
||||||
data.safeSeachBing = status['bing'] ?? false;
|
data.safeSeachBing = status['bing'] ?? false;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:animations/animations.dart';
|
import 'package:animations/animations.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
|
@ -9,11 +7,10 @@ import 'package:flutter_split_view/flutter_split_view.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/screens/clients/client_screen.dart';
|
import 'package:adguard_home_manager/screens/clients/client/client_screen_functions.dart';
|
||||||
import 'package:adguard_home_manager/screens/clients/added_client_tile.dart';
|
import 'package:adguard_home_manager/screens/clients/client/added_client_tile.dart';
|
||||||
import 'package:adguard_home_manager/screens/clients/remove_client_modal.dart';
|
import 'package:adguard_home_manager/screens/clients/client/remove_client_modal.dart';
|
||||||
import 'package:adguard_home_manager/screens/clients/fab.dart';
|
import 'package:adguard_home_manager/screens/clients/fab.dart';
|
||||||
import 'package:adguard_home_manager/screens/clients/options_modal.dart';
|
|
||||||
import 'package:adguard_home_manager/widgets/tab_content_list.dart';
|
import 'package:adguard_home_manager/widgets/tab_content_list.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||||
|
@ -32,13 +29,13 @@ class AddedList extends StatefulWidget {
|
||||||
final bool splitView;
|
final bool splitView;
|
||||||
|
|
||||||
const AddedList({
|
const AddedList({
|
||||||
Key? key,
|
super.key,
|
||||||
required this.scrollController,
|
required this.scrollController,
|
||||||
required this.data,
|
required this.data,
|
||||||
required this.onClientSelected,
|
required this.onClientSelected,
|
||||||
this.selectedClient,
|
this.selectedClient,
|
||||||
required this.splitView
|
required this.splitView
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<AddedList> createState() => _AddedListState();
|
State<AddedList> createState() => _AddedListState();
|
||||||
|
@ -77,8 +74,8 @@ class _AddedListState extends State<AddedList> {
|
||||||
final width = MediaQuery.of(context).size.width;
|
final width = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
void confirmEditClient(Client client) async {
|
void confirmEditClient(Client client) async {
|
||||||
ProcessModal processModal = ProcessModal(context: context);
|
ProcessModal processModal = ProcessModal();
|
||||||
processModal.open(AppLocalizations.of(context)!.addingClient);
|
processModal.open(AppLocalizations.of(context)!.savingChanges);
|
||||||
|
|
||||||
final result = await clientsProvider.editClient(client);
|
final result = await clientsProvider.editClient(client);
|
||||||
|
|
||||||
|
@ -101,7 +98,7 @@ class _AddedListState extends State<AddedList> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteClient(Client client) async {
|
void deleteClient(Client client) async {
|
||||||
ProcessModal processModal = ProcessModal(context: context);
|
ProcessModal processModal = ProcessModal();
|
||||||
processModal.open(AppLocalizations.of(context)!.removingClient);
|
processModal.open(AppLocalizations.of(context)!.removingClient);
|
||||||
|
|
||||||
final result = await clientsProvider.deleteClient(client);
|
final result = await clientsProvider.deleteClient(client);
|
||||||
|
@ -128,31 +125,13 @@ class _AddedListState extends State<AddedList> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void openClientModal(Client client) {
|
void openClientModal(Client client) {
|
||||||
if (width > 900 || !(Platform.isAndroid | Platform.isIOS)) {
|
openClientFormModal(
|
||||||
showDialog(
|
context: context,
|
||||||
barrierDismissible: false,
|
width: width,
|
||||||
context: context,
|
client: client,
|
||||||
builder: (BuildContext context) => ClientScreen(
|
onConfirm: confirmEditClient,
|
||||||
onConfirm: confirmEditClient,
|
onDelete: deleteClient
|
||||||
serverVersion: statusProvider.serverStatus!.serverVersion,
|
);
|
||||||
onDelete: deleteClient,
|
|
||||||
client: client,
|
|
||||||
dialog: true,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Navigator.push(context, MaterialPageRoute(
|
|
||||||
fullscreenDialog: true,
|
|
||||||
builder: (BuildContext context) => ClientScreen(
|
|
||||||
onConfirm: confirmEditClient,
|
|
||||||
serverVersion: statusProvider.serverStatus!.serverVersion,
|
|
||||||
onDelete: deleteClient,
|
|
||||||
client: client,
|
|
||||||
dialog: false,
|
|
||||||
)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void openDeleteModal(Client client) {
|
void openDeleteModal(Client client) {
|
||||||
|
@ -163,19 +142,13 @@ class _AddedListState extends State<AddedList> {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
final clientsDisplay = clientsProvider.searchTermClients != null && clientsProvider.searchTermClients != ""
|
||||||
void openOptionsModal(Client client) {
|
? widget.data.where(
|
||||||
showModal(
|
(c) => c.name.toLowerCase().contains(clientsProvider.searchTermClients.toString()) || c.ids.where((id) => id.contains(clientsProvider.searchTermClients.toString())).isNotEmpty
|
||||||
context: context,
|
).toList()
|
||||||
builder: (ctx) => OptionsModal(
|
: widget.data;
|
||||||
onDelete: () => openDeleteModal(client),
|
|
||||||
onEdit: () => openClientModal(client),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CustomTabContentList(
|
return CustomTabContentList(
|
||||||
noSliver: !(Platform.isAndroid || Platform.isIOS),
|
|
||||||
listPadding: widget.splitView == true
|
listPadding: widget.splitView == true
|
||||||
? const EdgeInsets.only(top: 8)
|
? const EdgeInsets.only(top: 8)
|
||||||
: null,
|
: null,
|
||||||
|
@ -198,15 +171,16 @@ class _AddedListState extends State<AddedList> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
itemsCount: widget.data.length,
|
itemsCount: clientsDisplay.length,
|
||||||
contentWidget: (index) => AddedClientTile(
|
contentWidget: (index) => AddedClientTile(
|
||||||
selectedClient: widget.selectedClient,
|
selectedClient: widget.selectedClient,
|
||||||
client: widget.data[index],
|
client: clientsDisplay[index],
|
||||||
onTap: widget.onClientSelected,
|
onTap: widget.onClientSelected,
|
||||||
onLongPress: openOptionsModal,
|
onEdit: statusProvider.serverStatus != null
|
||||||
onEdit: openClientModal,
|
? (c) => openClientModal(c)
|
||||||
|
: null,
|
||||||
|
onDelete: openDeleteModal,
|
||||||
splitView: widget.splitView,
|
splitView: widget.splitView,
|
||||||
serverVersion: statusProvider.serverStatus!.serverVersion,
|
|
||||||
),
|
),
|
||||||
noData: SizedBox(
|
noData: SizedBox(
|
||||||
width: double.maxFinite,
|
width: double.maxFinite,
|
||||||
|
|