mirror of
https://github.com/JGeek00/adguard-home-manager.git
synced 2025-04-21 14:29:12 +00:00
Compare commits
47 commits
2.19.0_(14
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
a4bf4cd3c5 | ||
|
61b0f724ba | ||
|
52945b04ff | ||
|
8e5bbdbd4b | ||
|
e6a01ac546 | ||
|
e8440f7d1d | ||
|
6cc212751b | ||
|
ae9d23d4a8 | ||
|
566254e617 | ||
|
88339d1c40 | ||
|
254bbcef57 | ||
|
e7aacfbec1 | ||
|
7a75a67701 | ||
|
7632d9ef87 | ||
|
eded494024 | ||
|
e5979edf63 | ||
|
f27b17aad0 | ||
|
fd4daba2aa | ||
|
ce7a8e8cc5 | ||
|
4282792ebd | ||
|
4766d1907f | ||
|
7f6f686b2b | ||
|
02b659c1bc | ||
|
db6e63c4aa | ||
|
a666d109d9 | ||
|
1f23f1f3ca | ||
|
51b8a6b610 | ||
|
28034d4b74 | ||
|
10ff5183f1 | ||
|
47b5313bf3 | ||
|
791400f565 | ||
|
06c9f7c771 | ||
|
2a0db84959 | ||
|
74cade6553 | ||
|
1b5f258c96 | ||
|
aa511f8c42 | ||
|
c28d2440b1 | ||
|
9d4c002813 | ||
|
d7392e4b8d | ||
|
4dc54794bd | ||
|
a36335ef92 | ||
|
9096367843 | ||
|
0d0321a5ab | ||
|
d903da0051 | ||
|
b65dc35cb7 | ||
|
7bb7ad40c4 | ||
|
7579e2d580 |
63 changed files with 991 additions and 1129 deletions
121
.github/workflows/release-beta.yaml
vendored
121
.github/workflows/release-beta.yaml
vendored
|
@ -1,121 +0,0 @@
|
||||||
name: Compile and release beta build
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-android:
|
|
||||||
name: Build Android .apk and .aab
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
ANDROID_AAB_RELEASE_PATH: build/app/outputs/bundle/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:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
ref: beta
|
|
||||||
- name: Decode android/app/keystore.jks
|
|
||||||
run: echo "${{ secrets.KEYSTORE_JKS }}" | base64 --decode > android/app/keystore.jks
|
|
||||||
- name: Decode android/key.properties
|
|
||||||
run: echo "${{ secrets.KEY_PROPERTIES }}" | base64 --decode > android/key.properties
|
|
||||||
- name: Decode .env
|
|
||||||
run: echo "${{ secrets.ENV }}" | base64 --decode > .env
|
|
||||||
- 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
|
|
||||||
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
|
|
||||||
run: sed -i 's/#{KEYSTORE_PASS}#/${{ secrets.KEYSTORE_PASS }}/g' android/key.properties
|
|
||||||
- name: Update KeyStore key password in gradle properties
|
|
||||||
run: sed -i 's/#{KEYSTORE_KEY_PASS}#/${{ secrets.KEYSTORE_KEY_PASS }}/g' android/key.properties
|
|
||||||
- uses: actions/setup-java@v3
|
|
||||||
with:
|
|
||||||
distribution: 'zulu'
|
|
||||||
java-version: '18.x'
|
|
||||||
- uses: subosito/flutter-action@v2
|
|
||||||
with:
|
|
||||||
channel: "stable"
|
|
||||||
- run: flutter clean
|
|
||||||
- run: flutter pub get
|
|
||||||
- run: flutter build apk --release
|
|
||||||
- run: flutter build appbundle --release
|
|
||||||
- name: Rename apk
|
|
||||||
run: mv $ANDROID_APK_RELEASE_PATH/app-release.apk $ANDROID_APK_RELEASE_PATH/AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.apk
|
|
||||||
- name: Rename 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
|
|
||||||
run: cp $ANDROID_APK_RELEASE_PATH/AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.apk AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.apk
|
|
||||||
- name: Copy aab to project root
|
|
||||||
run: cp $ANDROID_AAB_RELEASE_PATH/AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.aab AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.aab
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: android
|
|
||||||
path: |
|
|
||||||
AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.aab
|
|
||||||
AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.apk
|
|
||||||
release-builds-github:
|
|
||||||
name: Release beta build to GitHub
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [build-android]
|
|
||||||
env:
|
|
||||||
VERSION_NAME: ${{ needs.build-android.outputs.VERSION_NAME }}
|
|
||||||
VERSION_NUMBER: ${{ needs.build-android.outputs.VERSION_NUMBER }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
ref: beta
|
|
||||||
- name: Create builds directory
|
|
||||||
run: mkdir releases
|
|
||||||
- name: Download Android artifacts
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: android
|
|
||||||
path: releases/
|
|
||||||
- name: Release to GitHub
|
|
||||||
uses: ncipollo/release-action@v1
|
|
||||||
with:
|
|
||||||
artifacts: "releases/*"
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
tag: '${{ env.VERSION_NAME }}_(${{ env.VERSION_NUMBER }})'
|
|
||||||
name: v${{ env.VERSION_NAME }}
|
|
||||||
draft: true
|
|
||||||
prerelease: true
|
|
||||||
commit: ${{ github.sha }}
|
|
||||||
release-build-google-play:
|
|
||||||
name: Release Android beta build to the Google Play Store
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [build-android]
|
|
||||||
env:
|
|
||||||
VERSION_NAME: ${{ needs.build-android.outputs.VERSION_NAME }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
ref: beta
|
|
||||||
- name: Download Android artifacts
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: android
|
|
||||||
- name: Release app to Google Play
|
|
||||||
uses: r0adkll/upload-google-play@v1
|
|
||||||
with:
|
|
||||||
serviceAccountJsonPlainText: ${{ secrets.PLAYSTORE_ACCOUNT_KEY }}
|
|
||||||
packageName: com.jgeek00.adguard_home_manager
|
|
||||||
releaseFiles: AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.aab
|
|
||||||
track: beta
|
|
||||||
status: draft
|
|
||||||
releaseName: ${{ env.VERSION_NAME }}
|
|
300
.github/workflows/release-stable.yaml
vendored
300
.github/workflows/release-stable.yaml
vendored
|
@ -1,300 +0,0 @@
|
||||||
name: Compile and release production build
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-android:
|
|
||||||
name: Build Android .apk and .aab
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
ANDROID_AAB_RELEASE_PATH: build/app/outputs/bundle/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:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Decode android/app/keystore.jks
|
|
||||||
run: echo "${{ secrets.KEYSTORE_JKS }}" | base64 --decode > android/app/keystore.jks
|
|
||||||
- name: Decode android/key.properties
|
|
||||||
run: echo "${{ secrets.KEY_PROPERTIES }}" | base64 --decode > android/key.properties
|
|
||||||
- name: Decode .env
|
|
||||||
run: echo "${{ secrets.ENV }}" | base64 --decode > .env
|
|
||||||
- name: Read pubspec.yaml
|
|
||||||
uses: jbutcher5/read-yaml@1.6
|
|
||||||
id: read_pubspec
|
|
||||||
with:
|
|
||||||
file: './pubspec.yaml' # File to read from
|
|
||||||
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
|
|
||||||
run: sed -i 's/#{KEYSTORE_PASS}#/${{ secrets.KEYSTORE_PASS }}/g' android/key.properties
|
|
||||||
- name: Update KeyStore key password in gradle properties
|
|
||||||
run: sed -i 's/#{KEYSTORE_KEY_PASS}#/${{ secrets.KEYSTORE_KEY_PASS }}/g' android/key.properties
|
|
||||||
- uses: actions/setup-java@v3
|
|
||||||
with:
|
|
||||||
distribution: 'zulu'
|
|
||||||
java-version: '18.x'
|
|
||||||
- uses: subosito/flutter-action@v2
|
|
||||||
with:
|
|
||||||
channel: "stable"
|
|
||||||
- run: flutter clean
|
|
||||||
- run: flutter pub get
|
|
||||||
- run: flutter build apk --release
|
|
||||||
- run: flutter build appbundle --release
|
|
||||||
- name: Rename apk
|
|
||||||
run: mv $ANDROID_APK_RELEASE_PATH/app-release.apk $ANDROID_APK_RELEASE_PATH/AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.apk
|
|
||||||
- name: Rename 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
|
|
||||||
run: cp $ANDROID_APK_RELEASE_PATH/AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.apk AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.apk
|
|
||||||
- name: Copy aab to project root
|
|
||||||
run: cp $ANDROID_AAB_RELEASE_PATH/AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.aab AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.aab
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: android
|
|
||||||
path: |
|
|
||||||
AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.aab
|
|
||||||
AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.apk
|
|
||||||
build-macos:
|
|
||||||
name: Build macOS .dmg
|
|
||||||
runs-on: macos-latest
|
|
||||||
env:
|
|
||||||
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:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Decode .env
|
|
||||||
run: echo "${{ secrets.ENV }}" | base64 --decode > .env
|
|
||||||
- name: Read pubspec.yaml
|
|
||||||
uses: jbutcher5/read-yaml@1.6
|
|
||||||
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
|
|
||||||
with:
|
|
||||||
channel: "stable"
|
|
||||||
- run: flutter clean
|
|
||||||
- run: flutter pub get
|
|
||||||
- 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
|
|
||||||
run: mkdir $MACOS_APP_RELEASE_PATH/AdGuard\ Home\ Manager
|
|
||||||
- name: Copy app into folder
|
|
||||||
run: cp -r $MACOS_APP_RELEASE_PATH/AdGuard\ Home\ Manager.app $MACOS_APP_RELEASE_PATH/AdGuard\ Home\ Manager/AdGuard\ Home\ Manager.app
|
|
||||||
- name: Generate symbolic link to Applications dir
|
|
||||||
run: ln -s /Applications $MACOS_APP_RELEASE_PATH/AdGuard\ Home\ Manager
|
|
||||||
- name: Generate 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
|
|
||||||
run: cp $MACOS_APP_RELEASE_PATH/AdGuardHomeManager_${{ env.VERSION_NAME }}_macOS_Universal.dmg AdGuardHomeManager_${{ env.VERSION_NAME }}_macOS_Universal.dmg
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: macos
|
|
||||||
path: AdGuardHomeManager_${{ env.VERSION_NAME }}_macOS_Universal.dmg
|
|
||||||
build-linux:
|
|
||||||
name: Build Linux .tar.gz and .deb
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
VERSION_NAME: ${{ steps.save_version.outputs.version_name }}
|
|
||||||
VERSION_NUMBER: ${{ steps.save_version.outputs.version_number }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Decode .env
|
|
||||||
run: echo "${{ secrets.ENV }}" | base64 --decode > .env
|
|
||||||
- name: Read pubspec.yaml
|
|
||||||
uses: jbutcher5/read-yaml@1.6
|
|
||||||
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
|
|
||||||
run: sed -i 's/<REPLACE_VERSION_NUMBER_ACTIONS>/${{ env.VERSION_NAME }}/g' debian/debian.yaml
|
|
||||||
- name: Update dependencies list
|
|
||||||
run: sudo apt-get update
|
|
||||||
- name: Install dependencies
|
|
||||||
run: sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev
|
|
||||||
- uses: subosito/flutter-action@v2
|
|
||||||
with:
|
|
||||||
channel: "stable"
|
|
||||||
- run: flutter clean
|
|
||||||
- run: flutter pub get
|
|
||||||
- run: flutter build linux --release
|
|
||||||
- name: Install flutter_to_debian
|
|
||||||
run: dart pub global activate flutter_to_debian
|
|
||||||
- name: Generate .deb package
|
|
||||||
run: flutter_to_debian
|
|
||||||
- name: Move .deb package to project root
|
|
||||||
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
|
|
||||||
uses: a7ul/tar-action@v1.1.3
|
|
||||||
id: compress
|
|
||||||
with:
|
|
||||||
command: c
|
|
||||||
cwd: build/linux/x64/release/bundle
|
|
||||||
files: |
|
|
||||||
./data
|
|
||||||
./lib
|
|
||||||
./AdGuardHomeManager
|
|
||||||
outPath: AdGuardHomeManager_${{ env.VERSION_NAME }}_Linux.tar.gz
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: linux
|
|
||||||
path: |
|
|
||||||
AdGuardHomeManager_${{ env.VERSION_NAME }}_Linux_amd64.deb
|
|
||||||
AdGuardHomeManager_${{ env.VERSION_NAME }}_Linux.tar.gz
|
|
||||||
build-windows:
|
|
||||||
name: Build Windows installer
|
|
||||||
runs-on: windows-latest
|
|
||||||
outputs:
|
|
||||||
VERSION_NAME: ${{ steps.save_version.outputs.version_name }}
|
|
||||||
VERSION_NUMBER: ${{ steps.save_version.outputs.version_number }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Decode .env
|
|
||||||
shell: pwsh
|
|
||||||
run: |
|
|
||||||
[IO.File]::WriteAllBytes('.env', [Convert]::FromBase64String('${{ secrets.ENV }}'))
|
|
||||||
- name: Read pubspec.yaml
|
|
||||||
uses: jbutcher5/read-yaml@1.6
|
|
||||||
id: read_pubspec
|
|
||||||
with:
|
|
||||||
file: './pubspec.yaml'
|
|
||||||
key-path: '["version"]'
|
|
||||||
- name: Save version on env variable
|
|
||||||
shell: bash
|
|
||||||
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
|
|
||||||
shell: pwsh
|
|
||||||
run: |
|
|
||||||
(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
|
|
||||||
with:
|
|
||||||
channel: "stable"
|
|
||||||
- run: flutter clean
|
|
||||||
- run: flutter pub get
|
|
||||||
- run: flutter build windows --release
|
|
||||||
- name: Build installer witn innosetup
|
|
||||||
run: iscc /Q windows/innosetup_installer_builder.iss
|
|
||||||
- name: Move installer file to root directory
|
|
||||||
run: move build/windows/aghm_installer.exe AdGuardHomeManager_${{ env.VERSION_NAME }}_Windows_x64.exe
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: windows
|
|
||||||
path: AdGuardHomeManager_${{ env.VERSION_NAME }}_Windows_x64.exe
|
|
||||||
release-builds-github:
|
|
||||||
name: Release builds to GitHub
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
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:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Create builds directory
|
|
||||||
run: mkdir releases
|
|
||||||
- name: Download Android artifacts
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: android
|
|
||||||
path: releases/
|
|
||||||
- name: Download macOS artifacts
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: macos
|
|
||||||
path: releases/
|
|
||||||
- name: Download Linux artifacts
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: linux
|
|
||||||
path: releases/
|
|
||||||
- name: Download Windows artifacts
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: windows
|
|
||||||
path: releases/
|
|
||||||
- name: Release to GitHub
|
|
||||||
uses: ncipollo/release-action@v1
|
|
||||||
with:
|
|
||||||
artifacts: "releases/*"
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
tag: '${{ env.VERSION_NAME }}_(${{ env.VERSION_NUMBER }})'
|
|
||||||
name: v${{ env.VERSION_NAME }}
|
|
||||||
draft: true
|
|
||||||
prerelease: false
|
|
||||||
commit: ${{ github.sha }}
|
|
||||||
release-build-google-play:
|
|
||||||
name: Release Android build to the Google Play Store
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [build-android, build-macos, build-linux, build-windows]
|
|
||||||
env:
|
|
||||||
VERSION_NAME: ${{ needs.build-android.outputs.VERSION_NAME }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Download Android artifacts
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: android
|
|
||||||
- name: Release app to Google Play
|
|
||||||
uses: r0adkll/upload-google-play@v1
|
|
||||||
with:
|
|
||||||
serviceAccountJsonPlainText: ${{ secrets.PLAYSTORE_ACCOUNT_KEY }}
|
|
||||||
packageName: com.jgeek00.adguard_home_manager
|
|
||||||
releaseFiles: AdGuardHomeManager_${{ env.VERSION_NAME }}_Android.aab
|
|
||||||
track: production
|
|
||||||
status: draft
|
|
||||||
releaseName: ${{ env.VERSION_NAME }}
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -5,9 +5,11 @@
|
||||||
*.swp
|
*.swp
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.atom/
|
.atom/
|
||||||
|
.build/
|
||||||
.buildlog/
|
.buildlog/
|
||||||
.history
|
.history
|
||||||
.svn/
|
.svn/
|
||||||
|
.swiftpm/
|
||||||
migrate_working_dir/
|
migrate_working_dir/
|
||||||
|
|
||||||
# Env
|
# Env
|
||||||
|
@ -49,3 +51,5 @@ app.*.map.json
|
||||||
/debian/packages
|
/debian/packages
|
||||||
|
|
||||||
untranslated.json
|
untranslated.json
|
||||||
|
|
||||||
|
android/app/.cxx
|
||||||
|
|
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
|
@ -12,5 +12,9 @@
|
||||||
"editor.formatOnSave": false,
|
"editor.formatOnSave": false,
|
||||||
"editor.formatOnPaste": false,
|
"editor.formatOnPaste": false,
|
||||||
"editor.formatOnType": false
|
"editor.formatOnType": false
|
||||||
}
|
},
|
||||||
|
"cSpell.ignorePaths": [
|
||||||
|
"/pubspec.yaml",
|
||||||
|
"/.github/workflows"
|
||||||
|
],
|
||||||
}
|
}
|
|
@ -113,7 +113,6 @@ If you like the project and you want to contribute with the development, you can
|
||||||
- [expandable](https://pub.dev/packages/expandable)
|
- [expandable](https://pub.dev/packages/expandable)
|
||||||
- [package info plus](https://pub.dev/packages/package_info_plus)
|
- [package info plus](https://pub.dev/packages/package_info_plus)
|
||||||
- [flutter phoenix](https://pub.dev/packages/flutter_phoenix)
|
- [flutter phoenix](https://pub.dev/packages/flutter_phoenix)
|
||||||
- [flutter displaymode](https://pub.dev/packages/flutter_displaymode)
|
|
||||||
- [flutter launcher icons](https://pub.dev/packages/flutter_launcher_icons)
|
- [flutter launcher icons](https://pub.dev/packages/flutter_launcher_icons)
|
||||||
- [flutter native splash](https://pub.dev/packages/flutter_native_splash)
|
- [flutter native splash](https://pub.dev/packages/flutter_native_splash)
|
||||||
- [intl](https://pub.dev/packages/intl)
|
- [intl](https://pub.dev/packages/intl)
|
||||||
|
@ -142,7 +141,6 @@ If you like the project and you want to contribute with the development, you can
|
||||||
- [flutter custom tabs](https://pub.dev/packages/flutter_custom_tabs)
|
- [flutter custom tabs](https://pub.dev/packages/flutter_custom_tabs)
|
||||||
- [shared preferences](https://pub.dev/packages/shared_preferences)
|
- [shared preferences](https://pub.dev/packages/shared_preferences)
|
||||||
- [window manager](https://pub.dev/packages/window_manager)
|
- [window manager](https://pub.dev/packages/window_manager)
|
||||||
- [install referrer](https://pub.dev/packages/install_referrer)
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,9 @@ if (keystorePropertiesFile.exists()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 34
|
namespace "com.jgeek00.adguard_home_manager"
|
||||||
ndkVersion flutter.ndkVersion
|
compileSdkVersion 35
|
||||||
|
ndkVersion "26.1.10909125"
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
@ -46,12 +47,9 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
|
||||||
applicationId "com.jgeek00.adguard_home_manager"
|
applicationId "com.jgeek00.adguard_home_manager"
|
||||||
// You can update the following values to match your application needs.
|
|
||||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
|
|
||||||
minSdkVersion 26
|
minSdkVersion 26
|
||||||
targetSdkVersion 34
|
targetSdkVersion 35
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ pluginManagement {
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||||
id "com.android.application" version '7.4.2' apply false
|
id "com.android.application" version '8.6.0' apply false
|
||||||
id "org.jetbrains.kotlin.android" version "1.8.20" apply false
|
id "org.jetbrains.kotlin.android" version "1.8.20" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
debian/debian.yaml
vendored
2
debian/debian.yaml
vendored
|
@ -5,7 +5,7 @@ flutter_app:
|
||||||
|
|
||||||
control:
|
control:
|
||||||
Package: AdGuardHomeManager
|
Package: AdGuardHomeManager
|
||||||
Version: <REPLACE_VERSION_NUMBER_ACTIONS>
|
Version: 2.20.1
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Essential: no
|
Essential: no
|
||||||
Priority: optional
|
Priority: optional
|
||||||
|
|
|
@ -27,11 +27,12 @@ ThemeData lightTheme(ColorScheme? dynamicColorScheme) => ThemeData(
|
||||||
dialogTheme: DialogTheme(
|
dialogTheme: DialogTheme(
|
||||||
surfaceTintColor: dynamicColorScheme?.surfaceTint
|
surfaceTintColor: dynamicColorScheme?.surfaceTint
|
||||||
),
|
),
|
||||||
pageTransitionsTheme: const PageTransitionsTheme(
|
// DISABLE PREDICTIVE BACK GESTURE
|
||||||
builders: {
|
// pageTransitionsTheme: const PageTransitionsTheme(
|
||||||
TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
|
// builders: {
|
||||||
}
|
// TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
|
||||||
)
|
// }
|
||||||
|
// )
|
||||||
);
|
);
|
||||||
|
|
||||||
ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData(
|
ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData(
|
||||||
|
@ -62,11 +63,12 @@ ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData(
|
||||||
dialogTheme: DialogTheme(
|
dialogTheme: DialogTheme(
|
||||||
surfaceTintColor: dynamicColorScheme?.surfaceTint
|
surfaceTintColor: dynamicColorScheme?.surfaceTint
|
||||||
),
|
),
|
||||||
pageTransitionsTheme: const PageTransitionsTheme(
|
// DISABLE PREDICTIVE BACK GESTURE
|
||||||
builders: {
|
// pageTransitionsTheme: const PageTransitionsTheme(
|
||||||
TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
|
// builders: {
|
||||||
}
|
// TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
|
||||||
)
|
// }
|
||||||
|
// )
|
||||||
);
|
);
|
||||||
|
|
||||||
ThemeData lightThemeOldVersions(MaterialColor primaryColor) => ThemeData(
|
ThemeData lightThemeOldVersions(MaterialColor primaryColor) => ThemeData(
|
||||||
|
@ -85,11 +87,12 @@ 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,
|
||||||
pageTransitionsTheme: const PageTransitionsTheme(
|
// DISABLE PREDICTIVE BACK GESTURE
|
||||||
builders: {
|
// pageTransitionsTheme: const PageTransitionsTheme(
|
||||||
TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
|
// builders: {
|
||||||
}
|
// TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
|
||||||
)
|
// }
|
||||||
|
// )
|
||||||
);
|
);
|
||||||
|
|
||||||
ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData(
|
ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData(
|
||||||
|
@ -111,9 +114,10 @@ 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,
|
||||||
pageTransitionsTheme: const PageTransitionsTheme(
|
// DISABLE PREDICTIVE BACK GESTURE
|
||||||
builders: {
|
// pageTransitionsTheme: const PageTransitionsTheme(
|
||||||
TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
|
// builders: {
|
||||||
}
|
// TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
|
||||||
)
|
// }
|
||||||
|
// )
|
||||||
);
|
);
|
|
@ -1,2 +1,3 @@
|
||||||
enum LoadStatus { loading, loaded, error }
|
enum LoadStatus { loading, loaded, error }
|
||||||
enum HomeTopItems { queriedDomains, blockedDomains, recurrentClients, topUpstreams, avgUpstreamResponseTime }
|
enum HomeTopItems { queriedDomains, blockedDomains, recurrentClients, topUpstreams, avgUpstreamResponseTime }
|
||||||
|
enum CustomRulesSorting { topBottom, bottomTop }
|
12
lib/constants/regexps.dart
Normal file
12
lib/constants/regexps.dart
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
class Regexps {
|
||||||
|
static final wildcardDomain = RegExp(r'^(\*\.)?(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,10}$');
|
||||||
|
static final domain = RegExp(r'^((?:(?:[a-zA-Z]{1})|(?:[a-zA-Z]{1}[a-zA-Z]{1})|(?:[a-zA-Z]{1}[0-9]{1})|(?:[0-9]{1}[a-zA-Z]{1})|(?:[a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.)+([a-zA-Z]{2,10}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,10})$');
|
||||||
|
static final ipv4Address = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$');
|
||||||
|
static final ipv6Address = RegExp(r'(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))');
|
||||||
|
static final subroute = RegExp(r'^\/\b([A-Za-z0-9_\-~/]*)[^\/|\.|\:]$');
|
||||||
|
static final macAddress = RegExp(r'^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$');
|
||||||
|
static final url = RegExp(r'^(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})$');
|
||||||
|
static final certificate = RegExp(r'(-{3,}(\bBEGIN CERTIFICATE\b))|(-{3,}-{3,}(\END CERTIFICATE\b)-{3,})', multiLine: true);
|
||||||
|
static final privateKey = RegExp(r'(-{3,}(\bBEGIN\b).*(PRIVATE KEY\b))|(-{3,}-{3,}(\bEND\b).*(PRIVATE KEY\b)-{3,})', multiLine: true);
|
||||||
|
static final path = RegExp(r'^(\/{0,1}(?!\/))[A-Za-z0-9\/\-_]+(\.([a-zA-Z]+))?$');
|
||||||
|
}
|
|
@ -7,4 +7,6 @@ class Urls {
|
||||||
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";
|
||||||
|
static const String appDetailsWebpage = "https://apps.jgeek00.com/jlfed8mcgyz6laf";
|
||||||
|
static const String jgeek00AppsWebpage = "https://apps.jgeek00.com";
|
||||||
}
|
}
|
|
@ -1,57 +0,0 @@
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:install_referrer/install_referrer.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';
|
|
||||||
|
|
||||||
Future<GitHubRelease?> checkAppUpdates({
|
|
||||||
required String currentBuildNumber,
|
|
||||||
required void Function(GitHubRelease?) setUpdateAvailable,
|
|
||||||
required InstallationAppReferrer? installationSource,
|
|
||||||
required bool isBeta
|
|
||||||
}) async {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
final update = gitHubUpdateExists(
|
|
||||||
currentBuildNumber: currentBuildNumber,
|
|
||||||
gitHubRelease: gitHubRelease,
|
|
||||||
isBeta: isBeta
|
|
||||||
);
|
|
||||||
|
|
||||||
if (update == true) {
|
|
||||||
setUpdateAvailable(gitHubRelease);
|
|
||||||
|
|
||||||
if (Platform.isAndroid) {
|
|
||||||
if (installationSource == InstallationAppReferrer.androidManually) {
|
|
||||||
return gitHubRelease;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Platform.isIOS) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return gitHubRelease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setUpdateAvailable(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
import 'package:adguard_home_manager/constants/regexps.dart';
|
||||||
|
|
||||||
bool isIpAddress(String value) {
|
bool isIpAddress(String value) {
|
||||||
final ipv4Regexp = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$');
|
if (Regexps.ipv4Address.hasMatch(value) || Regexps.ipv6Address.hasMatch(value)) {
|
||||||
final ipv6Regexp = RegExp(r'(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))');
|
|
||||||
if (ipv4Regexp.hasMatch(value) || ipv6Regexp.hasMatch(value)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -5,6 +5,15 @@ import 'package:url_launcher/url_launcher.dart' as url_launcher;
|
||||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||||
|
|
||||||
void openUrl(String url) async {
|
void openUrl(String url) async {
|
||||||
|
if (!(url.startsWith("http") || url.startsWith("https"))) {
|
||||||
|
try {
|
||||||
|
url_launcher.launchUrl(Uri.parse(url));
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
Sentry.captureException(e, stackTrace: stackTrace);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Platform.isAndroid || Platform.isIOS) {
|
if (Platform.isAndroid || Platform.isIOS) {
|
||||||
try {
|
try {
|
||||||
await flutter_custom_tabs.launchUrl(
|
await flutter_custom_tabs.launchUrl(
|
||||||
|
@ -20,6 +29,7 @@ void openUrl(String url) async {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} catch (e, stackTrace) {
|
} catch (e, stackTrace) {
|
||||||
|
url_launcher.launchUrl(Uri.parse(url));
|
||||||
Sentry.captureException(e, stackTrace: stackTrace);
|
Sentry.captureException(e, stackTrace: stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -797,5 +797,14 @@
|
||||||
"dnsServerAddressCopied": "DNS server address copied to the clipboard",
|
"dnsServerAddressCopied": "DNS server address copied to the clipboard",
|
||||||
"select": "Select",
|
"select": "Select",
|
||||||
"liveLogs": "Live logs",
|
"liveLogs": "Live logs",
|
||||||
"hereWillAppearRealtimeLogs": "Here there will appear the logs on realtime."
|
"hereWillAppearRealtimeLogs": "Here there will appear the logs on realtime.",
|
||||||
|
"applicationDetails": "Application details",
|
||||||
|
"applicationDetailsDescription": "App repository, stores where it's available, and more",
|
||||||
|
"myOtherApps": "My other apps",
|
||||||
|
"myOtherAppsDescription": "Check my other apps, make a donation, contact support, and more",
|
||||||
|
"topToBottom": "From top to bottom",
|
||||||
|
"bottomToTop": "From bottom to top",
|
||||||
|
"upstreamTimeout": "Upstream timeout",
|
||||||
|
"upstreamTimeoutHelper": "Specifies the number of seconds to wait for a response from the upstream server",
|
||||||
|
"fieldCannotBeEmpty": "This field cannot be empty"
|
||||||
}
|
}
|
|
@ -403,7 +403,7 @@
|
||||||
"dnsRewriteRuleDeleted": "Reescritura DNS eliminada correctamente",
|
"dnsRewriteRuleDeleted": "Reescritura DNS eliminada correctamente",
|
||||||
"dnsRewriteRuleNotDeleted": "La reescritura DNS no pudo ser eliminada",
|
"dnsRewriteRuleNotDeleted": "La reescritura DNS no pudo ser eliminada",
|
||||||
"addDnsRewrite": "Añadir reescritura DNS",
|
"addDnsRewrite": "Añadir reescritura DNS",
|
||||||
"addingRewrite": "Añadiend reescritura...",
|
"addingRewrite": "Añadiendo reescritura...",
|
||||||
"dnsRewriteRuleAdded": "Regla de reescritura DNS añadida correctamente",
|
"dnsRewriteRuleAdded": "Regla de reescritura DNS añadida correctamente",
|
||||||
"dnsRewriteRuleNotAdded": "La regla de reescritura DNS no ha podido ser añadida",
|
"dnsRewriteRuleNotAdded": "La regla de reescritura DNS no ha podido ser añadida",
|
||||||
"logsSettings": "Ajustes de registros",
|
"logsSettings": "Ajustes de registros",
|
||||||
|
@ -797,5 +797,14 @@
|
||||||
"dnsServerAddressCopied": "Dirección del servidor DNS copiada al portapapeles",
|
"dnsServerAddressCopied": "Dirección del servidor DNS copiada al portapapeles",
|
||||||
"select": "Seleccionar",
|
"select": "Seleccionar",
|
||||||
"liveLogs": "Registros en directo",
|
"liveLogs": "Registros en directo",
|
||||||
"hereWillAppearRealtimeLogs": "Aquí aparecerán los registros en tiempo real."
|
"hereWillAppearRealtimeLogs": "Aquí aparecerán los registros en tiempo real.",
|
||||||
|
"applicationDetails": "Detalles de la aplicación",
|
||||||
|
"applicationDetailsDescription": "Repositorio de la app, tiendas donde está disponible, y más",
|
||||||
|
"myOtherApps": "Mis otras apps",
|
||||||
|
"myOtherAppsDescription": "Comprueba mis otras apps, hacer una donación, contactar al soporte, y más",
|
||||||
|
"topToBottom": "Desde arriba hacia abajo",
|
||||||
|
"bottomToTop": "Desde abajo hacia arriba",
|
||||||
|
"upstreamTimeout": "Tiempo de espera del upstream",
|
||||||
|
"upstreamTimeoutHelper": "Especifica el número de segundos que se debe esperar para recibir una respuesta del servidor upstream",
|
||||||
|
"fieldCannotBeEmpty": "El campo no puede estar vacío"
|
||||||
}
|
}
|
|
@ -791,5 +791,20 @@
|
||||||
"clientDisallowedSuccessfully": "İstemci başarıyla reddedildi",
|
"clientDisallowedSuccessfully": "İstemci başarıyla reddedildi",
|
||||||
"changesNotSaved": "Değişiklikler kaydedilemedi",
|
"changesNotSaved": "Değişiklikler kaydedilemedi",
|
||||||
"allowingClient": "İstemciye izin veriliyor...",
|
"allowingClient": "İstemciye izin veriliyor...",
|
||||||
"disallowingClient": "İstemci reddediliyor..."
|
"disallowingClient": "İstemci reddediliyor...",
|
||||||
|
"clientIpCopied": "İstemci IP'si panoya kopyalandı",
|
||||||
|
"clientNameCopied": "İstemci adı panoya kopyalandı",
|
||||||
|
"dnsServerAddressCopied": "DNS sunucu adresi panoya kopyalandı",
|
||||||
|
"select": "Seç",
|
||||||
|
"liveLogs": "Canlı günlükler",
|
||||||
|
"hereWillAppearRealtimeLogs": "Burada gerçek zamanlı günlükler görünecek.",
|
||||||
|
"applicationDetails": "Uygulama detayları",
|
||||||
|
"applicationDetailsDescription": "Uygulama deposu, mevcut olduğu mağazalar ve daha fazlası",
|
||||||
|
"myOtherApps": "Diğer uygulamalarım",
|
||||||
|
"myOtherAppsDescription": "Diğer uygulamalarımı kontrol et, bağış yap, destekle iletişime geç ve daha fazlası",
|
||||||
|
"topToBottom": "Yukarıdan aşağıya",
|
||||||
|
"bottomToTop": "Aşağıdan yukarıya",
|
||||||
|
"upstreamTimeout": "Üst sunucu zaman aşımı",
|
||||||
|
"upstreamTimeoutHelper": "Üst DNS sunucusundan yanıt bekleme süresini saniye cinsinden belirtir",
|
||||||
|
"fieldCannotBeEmpty": "Bu alan boş olamaz"
|
||||||
}
|
}
|
|
@ -4,9 +4,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
import 'package:install_referrer/install_referrer.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';
|
||||||
|
@ -79,11 +77,6 @@ void main() async {
|
||||||
HttpOverrides.global = MyHttpOverrides();
|
HttpOverrides.global = MyHttpOverrides();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Platform.isAndroid || Platform.isIOS) {
|
|
||||||
InstallationAppReferrer installationSource = await InstallReferrer.referrer;
|
|
||||||
appConfigProvider.setInstallationSource(installationSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
final dbData = await loadDb();
|
final dbData = await loadDb();
|
||||||
serversProvider.setDbInstance(dbData['dbInstance']);
|
serversProvider.setDbInstance(dbData['dbInstance']);
|
||||||
serversProvider.saveFromDb(dbData['servers']);
|
serversProvider.saveFromDb(dbData['servers']);
|
||||||
|
@ -169,6 +162,31 @@ void main() async {
|
||||||
(options) {
|
(options) {
|
||||||
options.dsn = dotenv.env['SENTRY_DSN'];
|
options.dsn = dotenv.env['SENTRY_DSN'];
|
||||||
options.sendDefaultPii = false;
|
options.sendDefaultPii = false;
|
||||||
|
options.beforeSend = (event, hint) {
|
||||||
|
if (event.throwable is HttpException) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.message?.formatted.contains("HttpException") == true) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
event.message?.formatted.contains("Unexpected character") ?? false ||
|
||||||
|
(event.throwable != null && event.throwable!.toString().contains("Unexpected character"))
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
event.message?.formatted.contains("Unexpected end of input") ?? false ||
|
||||||
|
(event.throwable != null && event.throwable!.toString().contains("Unexpected end of input"))
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return event;
|
||||||
|
};
|
||||||
},
|
},
|
||||||
appRunner: () => startApp()
|
appRunner: () => startApp()
|
||||||
);
|
);
|
||||||
|
@ -178,37 +196,9 @@ void main() async {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Main extends StatefulWidget {
|
class Main extends StatelessWidget {
|
||||||
const Main({super.key});
|
const Main({super.key});
|
||||||
|
|
||||||
@override
|
|
||||||
State<Main> createState() => _MainState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MainState extends State<Main> {
|
|
||||||
List<DisplayMode> modes = <DisplayMode>[];
|
|
||||||
DisplayMode? active;
|
|
||||||
DisplayMode? preferred;
|
|
||||||
|
|
||||||
Future<void> displayMode() async {
|
|
||||||
try {
|
|
||||||
modes = await FlutterDisplayMode.supported;
|
|
||||||
preferred = await FlutterDisplayMode.preferred;
|
|
||||||
active = await FlutterDisplayMode.active;
|
|
||||||
await FlutterDisplayMode.setHighRefreshRate();
|
|
||||||
setState(() {});
|
|
||||||
} catch (_) {
|
|
||||||
// ---- //
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
displayMode();
|
|
||||||
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||||
|
|
|
@ -26,6 +26,7 @@ class DnsInfo {
|
||||||
int? ratelimitSubnetLenIpv4;
|
int? ratelimitSubnetLenIpv4;
|
||||||
int? ratelimitSubnetLenIpv6;
|
int? ratelimitSubnetLenIpv6;
|
||||||
List<String>? ratelimitWhitelist;
|
List<String>? ratelimitWhitelist;
|
||||||
|
int? upstreamTimeout;
|
||||||
|
|
||||||
DnsInfo({
|
DnsInfo({
|
||||||
required this.upstreamDns,
|
required this.upstreamDns,
|
||||||
|
@ -55,6 +56,7 @@ class DnsInfo {
|
||||||
required this.ratelimitSubnetLenIpv4,
|
required this.ratelimitSubnetLenIpv4,
|
||||||
required this.ratelimitSubnetLenIpv6,
|
required this.ratelimitSubnetLenIpv6,
|
||||||
required this.ratelimitWhitelist,
|
required this.ratelimitWhitelist,
|
||||||
|
required this.upstreamTimeout,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory DnsInfo.fromJson(Map<String, dynamic> json) => DnsInfo(
|
factory DnsInfo.fromJson(Map<String, dynamic> json) => DnsInfo(
|
||||||
|
@ -85,6 +87,7 @@ class DnsInfo {
|
||||||
ratelimitSubnetLenIpv4: json["ratelimit_subnet_len_ipv4"],
|
ratelimitSubnetLenIpv4: json["ratelimit_subnet_len_ipv4"],
|
||||||
ratelimitSubnetLenIpv6: json["ratelimit_subnet_len_ipv6"],
|
ratelimitSubnetLenIpv6: json["ratelimit_subnet_len_ipv6"],
|
||||||
ratelimitWhitelist: json["ratelimit_whitelist"] != null ? List<String>.from(json["ratelimit_whitelist"].map((x) => x)) : [],
|
ratelimitWhitelist: json["ratelimit_whitelist"] != null ? List<String>.from(json["ratelimit_whitelist"].map((x) => x)) : [],
|
||||||
|
upstreamTimeout: json["upstream_timeout"],
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
|
@ -115,5 +118,6 @@ class DnsInfo {
|
||||||
"ratelimit_subnet_len_ipv4": ratelimitSubnetLenIpv4,
|
"ratelimit_subnet_len_ipv4": ratelimitSubnetLenIpv4,
|
||||||
"ratelimit_subnet_len_ipv6": ratelimitSubnetLenIpv6,
|
"ratelimit_subnet_len_ipv6": ratelimitSubnetLenIpv6,
|
||||||
"ratelimit_whitelist": ratelimitWhitelist != null ? List<String>.from(ratelimitWhitelist!.map((x) => x)) : null,
|
"ratelimit_whitelist": ratelimitWhitelist != null ? List<String>.from(ratelimitWhitelist!.map((x) => x)) : null,
|
||||||
|
"upstream_timeout": upstreamTimeout,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ DnsStatistics dnsStatisticsFromJson(String str) => DnsStatistics.fromJson(json.d
|
||||||
String dnsStatisticsToJson(DnsStatistics data) => json.encode(data.toJson());
|
String dnsStatisticsToJson(DnsStatistics data) => json.encode(data.toJson());
|
||||||
|
|
||||||
class DnsStatistics {
|
class DnsStatistics {
|
||||||
final String timeUnits;
|
final String? timeUnits;
|
||||||
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;
|
||||||
|
@ -43,9 +43,9 @@ class DnsStatistics {
|
||||||
|
|
||||||
factory DnsStatistics.fromJson(Map<String, dynamic> json) => DnsStatistics(
|
factory DnsStatistics.fromJson(Map<String, dynamic> json) => DnsStatistics(
|
||||||
timeUnits: json["time_units"],
|
timeUnits: json["time_units"],
|
||||||
topQueriedDomains: List<Map<String, int>>.from(json["top_queried_domains"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))),
|
topQueriedDomains: json["top_queried_domains"] != null ? 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: json["top_clients"] != null ? 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: json["top_blocked_domains"] != null ? 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,
|
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,
|
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)),
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:install_referrer/install_referrer.dart';
|
|
||||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
|
@ -58,8 +57,6 @@ class AppConfigProvider with ChangeNotifier {
|
||||||
|
|
||||||
GitHubRelease? _appUpdatesAvailable;
|
GitHubRelease? _appUpdatesAvailable;
|
||||||
|
|
||||||
InstallationAppReferrer? _installationSource;
|
|
||||||
|
|
||||||
PackageInfo? get getAppInfo {
|
PackageInfo? get getAppInfo {
|
||||||
return _appInfo;
|
return _appInfo;
|
||||||
}
|
}
|
||||||
|
@ -162,10 +159,6 @@ class AppConfigProvider with ChangeNotifier {
|
||||||
return _appUpdatesAvailable;
|
return _appUpdatesAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
InstallationAppReferrer? get installationSource {
|
|
||||||
return _installationSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<HomeTopItems> get homeTopItemsOrder {
|
List<HomeTopItems> get homeTopItemsOrder {
|
||||||
return _homeTopItemsOrder;
|
return _homeTopItemsOrder;
|
||||||
}
|
}
|
||||||
|
@ -227,11 +220,6 @@ class AppConfigProvider with ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setInstallationSource(InstallationAppReferrer value) {
|
|
||||||
_installationSource = value;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> setOverrideSslCheck(bool status) async {
|
Future<bool> setOverrideSslCheck(bool status) async {
|
||||||
try {
|
try {
|
||||||
sharedPreferencesInstance.setBool('overrideSslCheck', status);
|
sharedPreferencesInstance.setBool('overrideSslCheck', status);
|
||||||
|
|
|
@ -152,19 +152,25 @@ class DnsProvider with ChangeNotifier {
|
||||||
data: value
|
data: value
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void updateValue(dynamic parameter, dynamic value) {
|
||||||
|
if (value != null) {
|
||||||
|
parameter = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (result.successful == true) {
|
if (result.successful == true) {
|
||||||
DnsInfo data = dnsInfo!;
|
DnsInfo data = dnsInfo!;
|
||||||
data.ratelimit = value['ratelimit'];
|
updateValue(data.ratelimit, value['ratelimit']);
|
||||||
data.ednsCsEnabled = value['edns_cs_enabled'];
|
updateValue(data.ednsCsEnabled, value['edns_cs_enabled']);
|
||||||
data.dnssecEnabled = value['dnssec_enabled'];
|
updateValue(data.dnssecEnabled, value['dnssec_enabled']);
|
||||||
data.disableIpv6 = value['disable_ipv6'];
|
updateValue(data.disableIpv6, value['disable_ipv6']);
|
||||||
data.blockingMode = value['blocking_mode'];
|
updateValue(data.blockingMode, value['blocking_mode']);
|
||||||
data.blockingIpv4 = value['blocking_ipv4'];
|
updateValue(data.blockingIpv4, value['blocking_ipv4']);
|
||||||
data.blockingIpv6 = value['blocking_ipv6'];
|
updateValue(data.blockingIpv6, value['blocking_ipv6']);
|
||||||
data.blockedResponseTtl = value['blocked_response_ttl'];
|
updateValue(data.blockedResponseTtl, value['blocked_response_ttl']);
|
||||||
data.ratelimitSubnetLenIpv4 = value['ratelimit_subnet_len_ipv4'];
|
updateValue(data.ratelimitSubnetLenIpv4, value['ratelimit_subnet_len_ipv4']);
|
||||||
data.ratelimitSubnetLenIpv6 = value['ratelimit_subnet_len_ipv6'];
|
updateValue(data.ratelimitSubnetLenIpv6, value['ratelimit_subnet_len_ipv6']);
|
||||||
data.ratelimitWhitelist = value['ratelimit_whitelist'];
|
updateValue(data.ratelimitWhitelist, value['ratelimit_whitelist']);
|
||||||
setDnsInfoData(data);
|
setDnsInfoData(data);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,15 @@ class ClientsFab extends StatelessWidget {
|
||||||
final width = MediaQuery.of(context).size.width;
|
final width = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
void confirmAddClient(Client client) async {
|
void confirmAddClient(Client client) async {
|
||||||
|
if (!context.mounted) return;
|
||||||
|
|
||||||
ProcessModal processModal = ProcessModal();
|
ProcessModal processModal = ProcessModal();
|
||||||
processModal.open(AppLocalizations.of(context)!.addingClient);
|
processModal.open(AppLocalizations.of(context)!.addingClient);
|
||||||
|
|
||||||
final result = await clientsProvider.addClient(client);
|
final result = await clientsProvider.addClient(client);
|
||||||
|
|
||||||
|
if (!context.mounted) return;
|
||||||
|
|
||||||
processModal.close();
|
processModal.close();
|
||||||
|
|
||||||
if (result == true) {
|
if (result == true) {
|
||||||
|
|
|
@ -33,6 +33,8 @@ class AddFiltersButton extends StatelessWidget {
|
||||||
final width = MediaQuery.of(context).size.width;
|
final width = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
void confirmAddRule(String rule) async {
|
void confirmAddRule(String rule) async {
|
||||||
|
if (!context.mounted) return;
|
||||||
|
|
||||||
ProcessModal processModal = ProcessModal();
|
ProcessModal processModal = ProcessModal();
|
||||||
processModal.open(AppLocalizations.of(context)!.addingRule);
|
processModal.open(AppLocalizations.of(context)!.addingRule);
|
||||||
|
|
||||||
|
@ -58,6 +60,8 @@ class AddFiltersButton extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
void confirmEditCustomRules(List<String> rules) async {
|
void confirmEditCustomRules(List<String> rules) async {
|
||||||
|
if (!context.mounted) return;
|
||||||
|
|
||||||
ProcessModal processModal = ProcessModal();
|
ProcessModal processModal = ProcessModal();
|
||||||
processModal.open(AppLocalizations.of(context)!.savingCustomRules);
|
processModal.open(AppLocalizations.of(context)!.savingCustomRules);
|
||||||
|
|
||||||
|
@ -137,6 +141,8 @@ class AddFiltersButton extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
void confirmAddList({required String name, required String url, required String type}) async {
|
void confirmAddList({required String name, required String url, required String type}) async {
|
||||||
|
if (!context.mounted) return;
|
||||||
|
|
||||||
ProcessModal processModal = ProcessModal();
|
ProcessModal processModal = ProcessModal();
|
||||||
processModal.open(AppLocalizations.of(context)!.addingList);
|
processModal.open(AppLocalizations.of(context)!.addingList);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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/filters/add_button.dart';
|
import 'package:adguard_home_manager/screens/filters/add_button.dart';
|
||||||
|
import 'package:adguard_home_manager/screens/filters/modals/custom_rules/sort_rules.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';
|
||||||
|
@ -34,6 +35,8 @@ class CustomRulesList extends StatefulWidget {
|
||||||
class _CustomRulesListState extends State<CustomRulesList> {
|
class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
late bool isVisible;
|
late bool isVisible;
|
||||||
|
|
||||||
|
CustomRulesSorting _sortingMethod = CustomRulesSorting.topBottom;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
initState(){
|
initState(){
|
||||||
super.initState();
|
super.initState();
|
||||||
|
@ -60,6 +63,8 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
final filteringProvider = Provider.of<FilteringProvider>(context);
|
final filteringProvider = Provider.of<FilteringProvider>(context);
|
||||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||||
|
|
||||||
|
final renderData = _sortingMethod == CustomRulesSorting.bottomTop ? widget.data.reversed.toList() : widget.data.toList();
|
||||||
|
|
||||||
bool checkIfComment(String value) {
|
bool checkIfComment(String value) {
|
||||||
final regex = RegExp(r'^(!|#).*$');
|
final regex = RegExp(r'^(!|#).*$');
|
||||||
if (regex.hasMatch(value)) {
|
if (regex.hasMatch(value)) {
|
||||||
|
@ -104,6 +109,16 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showSortingMethodModal() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (ctx) => SortCustomRulesModal(
|
||||||
|
sortingMethod: _sortingMethod,
|
||||||
|
onSelect: (value) => setState(() => _sortingMethod = value),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return CustomTabContentList(
|
return CustomTabContentList(
|
||||||
loadingGenerator: () => SizedBox(
|
loadingGenerator: () => SizedBox(
|
||||||
width: double.maxFinite,
|
width: double.maxFinite,
|
||||||
|
@ -124,10 +139,10 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
itemsCount: widget.data.length,
|
itemsCount: renderData.length,
|
||||||
contentWidget: (index) => ListTile(
|
contentWidget: (index) => ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
widget.data[index],
|
renderData[index],
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: checkIfComment(widget.data[index]) == true
|
color: checkIfComment(widget.data[index]) == true
|
||||||
? Theme.of(context).colorScheme.onSurface.withOpacity(0.6)
|
? Theme.of(context).colorScheme.onSurface.withOpacity(0.6)
|
||||||
|
@ -135,9 +150,9 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: generateSubtitle(widget.data[index]),
|
subtitle: generateSubtitle(renderData[index]),
|
||||||
trailing: IconButton(
|
trailing: IconButton(
|
||||||
onPressed: () => widget.onRemoveCustomRule(widget.data[index]),
|
onPressed: () => widget.onRemoveCustomRule(renderData[index]),
|
||||||
icon: const Icon(Icons.delete)
|
icon: const Icon(Icons.delete)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -162,7 +177,7 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
TextButton.icon(
|
TextButton.icon(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final result = await filteringProvider.fetchFilters();
|
final result = await filteringProvider.fetchFilters();
|
||||||
if (result == false) {
|
if (result == false && context.mounted) {
|
||||||
showSnackbar(
|
showSnackbar(
|
||||||
appConfigProvider: appConfigProvider,
|
appConfigProvider: appConfigProvider,
|
||||||
label: AppLocalizations.of(context)!.errorLoadFilters,
|
label: AppLocalizations.of(context)!.errorLoadFilters,
|
||||||
|
@ -212,6 +227,11 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
},
|
},
|
||||||
fab: Column(
|
fab: Column(
|
||||||
children: [
|
children: [
|
||||||
|
FloatingActionButton.small(
|
||||||
|
onPressed: showSortingMethodModal,
|
||||||
|
child: Icon(Icons.sort_rounded),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
AddFiltersButton(
|
AddFiltersButton(
|
||||||
type: 'edit_custom_rule',
|
type: 'edit_custom_rule',
|
||||||
widget: (fn) => FloatingActionButton.small(
|
widget: (fn) => FloatingActionButton.small(
|
||||||
|
@ -229,7 +249,7 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
heightFabHidden: -120,
|
heightFabHidden: -180,
|
||||||
fabVisible: isVisible,
|
fabVisible: isVisible,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/constants/regexps.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
@ -97,8 +98,7 @@ class _ContentState extends State<_Content> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void validateUrl(String value) {
|
void validateUrl(String value) {
|
||||||
final urlRegex = RegExp(r'^(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})$');
|
if (Regexps.url.hasMatch(value)) {
|
||||||
if (urlRegex.hasMatch(value)) {
|
|
||||||
setState(() => urlError = null);
|
setState(() => urlError = null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/constants/regexps.dart';
|
||||||
import 'package:flutter/material.dart';
|
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';
|
||||||
|
@ -63,8 +64,7 @@ class _ContentState extends State<_Content> {
|
||||||
Widget? resultWidget;
|
Widget? resultWidget;
|
||||||
|
|
||||||
void validateDomain(String value) {
|
void validateDomain(String value) {
|
||||||
final domainRegex = RegExp(r'^([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$');
|
if (Regexps.domain.hasMatch(value)) {
|
||||||
if (domainRegex.hasMatch(value)) {
|
|
||||||
setState(() => domainError = null);
|
setState(() => domainError = null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:adguard_home_manager/constants/regexps.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:segmented_button_slide/segmented_button_slide.dart';
|
import 'package:segmented_button_slide/segmented_button_slide.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
@ -41,8 +42,7 @@ class _AddCustomRuleState extends State<AddCustomRule> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void validateDomain(String value) {
|
void validateDomain(String value) {
|
||||||
final domainRegex = RegExp(r'^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$');
|
if (Regexps.domain.hasMatch(value)) {
|
||||||
if (domainRegex.hasMatch(value)) {
|
|
||||||
setState(() => _domainError = null);
|
setState(() => _domainError = null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
128
lib/screens/filters/modals/custom_rules/sort_rules.dart
Normal file
128
lib/screens/filters/modals/custom_rules/sort_rules.dart
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/constants/enums.dart';
|
||||||
|
|
||||||
|
class SortCustomRulesModal extends StatelessWidget {
|
||||||
|
final CustomRulesSorting sortingMethod;
|
||||||
|
final void Function(CustomRulesSorting) onSelect;
|
||||||
|
|
||||||
|
const SortCustomRulesModal({
|
||||||
|
super.key,
|
||||||
|
required this.sortingMethod,
|
||||||
|
required this.onSelect,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
|
scrollable: true,
|
||||||
|
title: Column(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.sort_rounded,
|
||||||
|
size: 24,
|
||||||
|
color: Theme.of(context).listTileTheme.iconColor
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
AppLocalizations.of(context)!.sortingOptions,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.onSurface
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
content: ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
maxWidth: 500
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
_CustomListTileDialog(
|
||||||
|
title: AppLocalizations.of(context)!.topToBottom,
|
||||||
|
icon: Icons.arrow_downward_rounded,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
onSelect(CustomRulesSorting.topBottom);
|
||||||
|
},
|
||||||
|
isSelected: sortingMethod == CustomRulesSorting.topBottom
|
||||||
|
),
|
||||||
|
_CustomListTileDialog(
|
||||||
|
title: AppLocalizations.of(context)!.bottomToTop,
|
||||||
|
icon: Icons.arrow_upward_rounded,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
onSelect(CustomRulesSorting.bottomTop);
|
||||||
|
},
|
||||||
|
isSelected: sortingMethod == CustomRulesSorting.bottomTop
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: Text(AppLocalizations.of(context)!.close)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CustomListTileDialog extends StatelessWidget {
|
||||||
|
final String title;
|
||||||
|
final IconData? icon;
|
||||||
|
final void Function()? onTap;
|
||||||
|
final bool isSelected;
|
||||||
|
|
||||||
|
const _CustomListTileDialog({
|
||||||
|
required this.title,
|
||||||
|
required this.icon,
|
||||||
|
required this.onTap,
|
||||||
|
required this.isSelected,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: onTap,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
icon,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 24),
|
||||||
|
Flexible(
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 24),
|
||||||
|
Icon(
|
||||||
|
isSelected == true ? Icons.radio_button_checked_rounded : Icons.radio_button_unchecked_rounded,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,6 +34,7 @@ class HomeAppBar extends StatelessWidget {
|
||||||
|
|
||||||
void navigateServers() {
|
void navigateServers() {
|
||||||
Future.delayed(const Duration(milliseconds: 0), (() {
|
Future.delayed(const Duration(milliseconds: 0), (() {
|
||||||
|
if (!context.mounted) return;
|
||||||
Navigator.of(context).push(
|
Navigator.of(context).push(
|
||||||
MaterialPageRoute(builder: (context) => const Servers())
|
MaterialPageRoute(builder: (context) => const Servers())
|
||||||
);
|
);
|
||||||
|
|
|
@ -114,10 +114,12 @@ class _ClientsModalState extends State<ClientsModal> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void searchAddedClient(_ClientLog client) {
|
void searchAddedClient(_ClientLog client) {
|
||||||
final notIps = client.ids?.where((e) => isIpAddress(e) == false).toList();
|
final ips = client.ids?.where((e) => isIpAddress(e) == true).toList();
|
||||||
if (notIps == null) return;
|
if (ips == null || ips.isEmpty) return;
|
||||||
logsProvider.setSearchText('"${notIps[0]}"');
|
logsProvider.setSearchText(ips[0]);
|
||||||
|
logsProvider.filterLogs();
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (widget.dialog == true) {
|
if (widget.dialog == true) {
|
||||||
|
@ -302,7 +304,7 @@ class _ClientsModalState extends State<ClientsModal> {
|
||||||
subtitle: _selectedList == 0 ? _filteredClients[index].name : _filteredClients[index].ids?.join(", "),
|
subtitle: _selectedList == 0 ? _filteredClients[index].name : _filteredClients[index].ids?.join(", "),
|
||||||
checkboxActive: logsProvider.selectedClients.contains(_filteredClients[index].ip),
|
checkboxActive: logsProvider.selectedClients.contains(_filteredClients[index].ip),
|
||||||
isAddedClient: _selectedList == 1,
|
isAddedClient: _selectedList == 1,
|
||||||
onSearchAddedClient: () => searchAddedClient(_filteredClients[index]),
|
onSearchAddedClient: _filteredClients[index].ids != null && _filteredClients[index].ids!.where((e) => isIpAddress(e) == true).isNotEmpty ? () => searchAddedClient(_filteredClients[index]) : null,
|
||||||
onChanged: (isSelected) {
|
onChanged: (isSelected) {
|
||||||
if (isSelected == true) {
|
if (isSelected == true) {
|
||||||
logsProvider.setSelectedClients([
|
logsProvider.setSelectedClients([
|
||||||
|
@ -376,7 +378,7 @@ class _ListItem extends StatelessWidget {
|
||||||
final bool checkboxActive;
|
final bool checkboxActive;
|
||||||
final void Function(bool) onChanged;
|
final void Function(bool) onChanged;
|
||||||
final bool isAddedClient;
|
final bool isAddedClient;
|
||||||
final void Function() onSearchAddedClient;
|
final void Function()? onSearchAddedClient;
|
||||||
|
|
||||||
const _ListItem({
|
const _ListItem({
|
||||||
required this.title,
|
required this.title,
|
||||||
|
|
|
@ -96,6 +96,8 @@ class LogTile extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
void blockUnblock({required String domain, required String newStatus}) async {
|
void blockUnblock({required String domain, required String newStatus}) async {
|
||||||
|
if (!context.mounted) return;
|
||||||
|
|
||||||
final ProcessModal processModal = ProcessModal();
|
final ProcessModal processModal = ProcessModal();
|
||||||
processModal.open(AppLocalizations.of(context)!.savingUserFilters);
|
processModal.open(AppLocalizations.of(context)!.savingUserFilters);
|
||||||
|
|
||||||
|
@ -124,6 +126,8 @@ class LogTile extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
void confirmAddClient(Client client) async {
|
void confirmAddClient(Client client) async {
|
||||||
|
if (!context.mounted) return;
|
||||||
|
|
||||||
ProcessModal processModal = ProcessModal();
|
ProcessModal processModal = ProcessModal();
|
||||||
processModal.open(AppLocalizations.of(context)!.addingClient);
|
processModal.open(AppLocalizations.of(context)!.addingClient);
|
||||||
|
|
||||||
|
@ -150,6 +154,8 @@ class LogTile extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
void blockUnblockRuleClient() async {
|
void blockUnblockRuleClient() async {
|
||||||
|
if (!context.mounted) return;
|
||||||
|
|
||||||
ProcessModal processModal = ProcessModal();
|
ProcessModal processModal = ProcessModal();
|
||||||
processModal.open(AppLocalizations.of(context)!.addingRule);
|
processModal.open(AppLocalizations.of(context)!.addingRule);
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,7 @@ class LogsListAppBar extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
void openLiveLogsScreen() {
|
void openLiveLogsScreen() {
|
||||||
|
if (!context.mounted) return;
|
||||||
Navigator.of(context).push(
|
Navigator.of(context).push(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => MultiProvider(
|
builder: (context) => MultiProvider(
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:adguard_home_manager/constants/regexps.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
@ -67,8 +68,7 @@ class __ContentState extends State<_Content> {
|
||||||
bool validData = false;
|
bool validData = false;
|
||||||
|
|
||||||
void validateMac(String value) {
|
void validateMac(String value) {
|
||||||
final RegExp macRegex = RegExp(r'^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$');
|
if (Regexps.macAddress.hasMatch(value)) {
|
||||||
if (macRegex.hasMatch(value)) {
|
|
||||||
setState(() => macError = null);
|
setState(() => macError = null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -78,8 +78,7 @@ class __ContentState extends State<_Content> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void validateIp(String value) {
|
void validateIp(String value) {
|
||||||
RegExp ipAddress = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$');
|
if (Regexps.ipv4Address.hasMatch(value) == true) {
|
||||||
if (ipAddress.hasMatch(value) == true) {
|
|
||||||
setState(() => ipError = null);
|
setState(() => ipError = null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/constants/regexps.dart';
|
||||||
import 'package:flutter/material.dart';
|
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';
|
||||||
|
@ -100,8 +101,8 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final regex = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$');
|
|
||||||
if (regex.hasMatch(value)) {
|
if (Regexps.ipv4Address.hasMatch(value)) {
|
||||||
setValue(null);
|
setValue(null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -126,8 +127,8 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final regex = RegExp(r'^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$');
|
|
||||||
if (regex.hasMatch(value)) {
|
if (Regexps.ipv6Address.hasMatch(value)) {
|
||||||
setValue(null);
|
setValue(null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/constants/regexps.dart';
|
||||||
import 'package:adguard_home_manager/functions/desktop_mode.dart';
|
import 'package:adguard_home_manager/functions/desktop_mode.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
@ -23,8 +24,7 @@ class _BootstrapDnsScreenState extends State<BootstrapDnsScreen> {
|
||||||
bool validValues = false;
|
bool validValues = false;
|
||||||
|
|
||||||
void validateIp(Map<String, dynamic> field, String value) {
|
void validateIp(Map<String, dynamic> field, String value) {
|
||||||
RegExp ipAddress = RegExp(r'(?:^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$)|(?:^(?:(?:[a-fA-F\d]{1,4}:){7}(?:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,2}|:)|(?:[a-fA-F\d]{1,4}:){4}(?:(?::[a-fA-F\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,3}|:)|(?:[a-fA-F\d]{1,4}:){3}(?:(?::[a-fA-F\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,4}|:)|(?:[a-fA-F\d]{1,4}:){2}(?:(?::[a-fA-F\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,5}|:)|(?:[a-fA-F\d]{1,4}:){1}(?:(?::[a-fA-F\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,6}|:)|(?::(?:(?::[a-fA-F\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?$)');
|
if (Regexps.ipv4Address.hasMatch(value) == true || Regexps.ipv6Address.hasMatch(value) == true) {
|
||||||
if (ipAddress.hasMatch(value) == true) {
|
|
||||||
setState(() => field['error'] = null);
|
setState(() => field['error'] = null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/constants/regexps.dart';
|
||||||
import 'package:adguard_home_manager/screens/settings/dns/comment_modal.dart';
|
import 'package:adguard_home_manager/screens/settings/dns/comment_modal.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
@ -24,9 +25,7 @@ class _FallbackDnsScreenState extends State<FallbackDnsScreen> {
|
||||||
bool validValues = false;
|
bool validValues = false;
|
||||||
|
|
||||||
void validateIp(Map<String, dynamic> field, String value) {
|
void validateIp(Map<String, dynamic> field, String value) {
|
||||||
RegExp ipAddress = RegExp(r'(?:^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$)|(?:^(?:(?:[a-fA-F\d]{1,4}:){7}(?:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,2}|:)|(?:[a-fA-F\d]{1,4}:){4}(?:(?::[a-fA-F\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,3}|:)|(?:[a-fA-F\d]{1,4}:){3}(?:(?::[a-fA-F\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,4}|:)|(?:[a-fA-F\d]{1,4}:){2}(?:(?::[a-fA-F\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,5}|:)|(?:[a-fA-F\d]{1,4}:){1}(?:(?::[a-fA-F\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,6}|:)|(?::(?:(?::[a-fA-F\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?$)');
|
if (Regexps.ipv4Address.hasMatch(value) == true || Regexps.ipv6Address.hasMatch(value) || Regexps.url.hasMatch(value) == true) {
|
||||||
RegExp url = RegExp(r'(https?|tls):\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)');
|
|
||||||
if (ipAddress.hasMatch(value) == true || url.hasMatch(value) == true) {
|
|
||||||
setState(() => field['error'] = null);
|
setState(() => field['error'] = null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:adguard_home_manager/constants/regexps.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
@ -33,8 +34,7 @@ class _RateLimitAllowlistModalState extends State<RateLimitAllowlistModal> {
|
||||||
List<_IpListItemController> _controllersList = [];
|
List<_IpListItemController> _controllersList = [];
|
||||||
|
|
||||||
void _validateIp(String value, _IpListItemController item) {
|
void _validateIp(String value, _IpListItemController item) {
|
||||||
final regexp = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$');
|
if (Regexps.ipv4Address.hasMatch(value)) {
|
||||||
if (regexp.hasMatch(value)) {
|
|
||||||
setState(() => _controllersList = _controllersList.map((e) {
|
setState(() => _controllersList = _controllersList.map((e) {
|
||||||
if (e.id == item.id) {
|
if (e.id == item.id) {
|
||||||
return _IpListItemController(
|
return _IpListItemController(
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -30,6 +28,9 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
||||||
|
|
||||||
bool validValues = false;
|
bool validValues = false;
|
||||||
|
|
||||||
|
final upstreamTimeoutController = TextEditingController();
|
||||||
|
String? upstreamTimeoutError = null;
|
||||||
|
|
||||||
checkValidValues() {
|
checkValidValues() {
|
||||||
if (
|
if (
|
||||||
dnsServers.isNotEmpty &&
|
dnsServers.isNotEmpty &&
|
||||||
|
@ -61,6 +62,7 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
upstreamMode = dnsProvider.dnsInfo!.upstreamMode ?? "";
|
upstreamMode = dnsProvider.dnsInfo!.upstreamMode ?? "";
|
||||||
|
upstreamTimeoutController.text = dnsProvider.dnsInfo!.upstreamTimeout != null ? dnsProvider.dnsInfo!.upstreamTimeout.toString() : "";
|
||||||
validValues = true;
|
validValues = true;
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
@ -72,6 +74,23 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
||||||
|
|
||||||
final width = MediaQuery.of(context).size.width;
|
final width = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
|
void validateTimeout(String value) {
|
||||||
|
if (value != '' && int.tryParse(value) != null && int.parse(value) > 0) {
|
||||||
|
setState(() {
|
||||||
|
upstreamTimeoutError = null;
|
||||||
|
validValues = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setState(() {
|
||||||
|
upstreamTimeoutError = value == ''
|
||||||
|
? AppLocalizations.of(context)!.fieldCannotBeEmpty
|
||||||
|
: AppLocalizations.of(context)!.invalidValue;
|
||||||
|
validValues = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void openAddCommentModal() {
|
void openAddCommentModal() {
|
||||||
if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) {
|
if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) {
|
||||||
showDialog(
|
showDialog(
|
||||||
|
@ -146,11 +165,13 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
||||||
|
|
||||||
final result = await dnsProvider.saveUpstreamDnsConfig({
|
final result = await dnsProvider.saveUpstreamDnsConfig({
|
||||||
"upstream_dns": dnsServers.map((e) => e['controller'] != null ? e['controller'].text : e['comment']).toList(),
|
"upstream_dns": dnsServers.map((e) => e['controller'] != null ? e['controller'].text : e['comment']).toList(),
|
||||||
"upstream_mode": upstreamMode
|
"upstream_mode": upstreamMode,
|
||||||
|
"upstream_timeout": int.tryParse(upstreamTimeoutController.text)
|
||||||
});
|
});
|
||||||
|
|
||||||
processModal.close();
|
processModal.close();
|
||||||
|
|
||||||
|
if (!context.mounted) return;
|
||||||
if (result.successful == true) {
|
if (result.successful == true) {
|
||||||
showSnackbar(
|
showSnackbar(
|
||||||
appConfigProvider: appConfigProvider,
|
appConfigProvider: appConfigProvider,
|
||||||
|
@ -312,6 +333,27 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
||||||
subtitle: AppLocalizations.of(context)!.fastestIpAddressDescription,
|
subtitle: AppLocalizations.of(context)!.fastestIpAddressDescription,
|
||||||
onChanged: (value) => setState(() => upstreamMode = value),
|
onChanged: (value) => setState(() => upstreamMode = value),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
SectionLabel(label: AppLocalizations.of(context)!.others),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: TextFormField(
|
||||||
|
controller: upstreamTimeoutController,
|
||||||
|
onChanged: validateTimeout,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
prefixIcon: const Icon(Icons.timer_rounded),
|
||||||
|
border: const OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(10)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
labelText: AppLocalizations.of(context)!.upstreamTimeout,
|
||||||
|
helperText: AppLocalizations.of(context)!.upstreamTimeoutHelper,
|
||||||
|
helperMaxLines: 2,
|
||||||
|
errorText: upstreamTimeoutError
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/constants/regexps.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
@ -82,8 +83,7 @@ class _ContentState extends State<_Content> {
|
||||||
bool validData = false;
|
bool validData = false;
|
||||||
|
|
||||||
void validateDomain(String value) {
|
void validateDomain(String value) {
|
||||||
final domainRegex = RegExp(r'^([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$');
|
if (Regexps.wildcardDomain.hasMatch(value)) {
|
||||||
if (domainRegex.hasMatch(value)) {
|
|
||||||
setState(() => domainError = null);
|
setState(() => domainError = null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
|
import 'package:adguard_home_manager/constants/regexps.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||||
|
|
||||||
String? validateDomain(BuildContext context, String domain) {
|
String? validateDomain(BuildContext context, String domain) {
|
||||||
RegExp regExp = RegExp(r'^([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$');
|
if (Regexps.domain.hasMatch(domain)) {
|
||||||
if (regExp.hasMatch(domain)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -23,8 +23,7 @@ String? validatePort(BuildContext context, String value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
String? validateCertificate(BuildContext context, String cert) {
|
String? validateCertificate(BuildContext context, String cert) {
|
||||||
final regExp = RegExp(r'(-{3,}(\bBEGIN CERTIFICATE\b))|(-{3,}-{3,}(\END CERTIFICATE\b)-{3,})', multiLine: true);
|
if (Regexps.certificate.hasMatch(cert.replaceAll('\n', ''))) {
|
||||||
if (regExp.hasMatch(cert.replaceAll('\n', ''))) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -33,8 +32,7 @@ String? validateCertificate(BuildContext context, String cert) {
|
||||||
}
|
}
|
||||||
|
|
||||||
String? validatePrivateKey(BuildContext context, String cert) {
|
String? validatePrivateKey(BuildContext context, String cert) {
|
||||||
final regExp = RegExp(r'(-{3,}(\bBEGIN\b).*(PRIVATE KEY\b))|(-{3,}-{3,}(\bEND\b).*(PRIVATE KEY\b)-{3,})', multiLine: true);
|
if (Regexps.privateKey.hasMatch(cert.replaceAll('\n', ''))) {
|
||||||
if (regExp.hasMatch(cert.replaceAll('\n', ''))) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -43,8 +41,7 @@ String? validatePrivateKey(BuildContext context, String cert) {
|
||||||
}
|
}
|
||||||
|
|
||||||
String? validatePath(BuildContext context, String cert) {
|
String? validatePath(BuildContext context, String cert) {
|
||||||
final regExp = RegExp(r'^(\/{0,1}(?!\/))[A-Za-z0-9\/\-_]+(\.([a-zA-Z]+))?$');
|
if (Regexps.path.hasMatch(cert)) {
|
||||||
if (regExp.hasMatch(cert)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:install_referrer/install_referrer.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';
|
||||||
|
|
||||||
|
@ -13,11 +8,8 @@ import 'package:adguard_home_manager/screens/settings/general_settings/top_items
|
||||||
import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
||||||
import 'package:adguard_home_manager/widgets/section_label.dart';
|
import 'package:adguard_home_manager/widgets/section_label.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/functions/check_app_updates.dart';
|
|
||||||
import 'package:adguard_home_manager/functions/desktop_mode.dart';
|
import 'package:adguard_home_manager/functions/desktop_mode.dart';
|
||||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||||
import 'package:adguard_home_manager/functions/open_url.dart';
|
|
||||||
import 'package:adguard_home_manager/functions/app_update_download_link.dart';
|
|
||||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||||
|
|
||||||
class GeneralSettings extends StatefulWidget {
|
class GeneralSettings extends StatefulWidget {
|
||||||
|
@ -48,6 +40,7 @@ class _GeneralSettingsState extends State<GeneralSettings> {
|
||||||
required Future Function(bool) function
|
required Future Function(bool) function
|
||||||
}) async {
|
}) async {
|
||||||
final result = await function(newStatus);
|
final result = await function(newStatus);
|
||||||
|
if (!context.mounted) return;
|
||||||
if (result == true) {
|
if (result == true) {
|
||||||
showSnackbar(
|
showSnackbar(
|
||||||
appConfigProvider: appConfigProvider,
|
appConfigProvider: appConfigProvider,
|
||||||
|
@ -64,60 +57,60 @@ class _GeneralSettingsState extends State<GeneralSettings> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future checkUpdatesAvailable() async {
|
// Future checkUpdatesAvailable() async {
|
||||||
setState(() => appUpdatesStatus = AppUpdatesStatus.checking);
|
// setState(() => appUpdatesStatus = AppUpdatesStatus.checking);
|
||||||
|
|
||||||
final res = await checkAppUpdates(
|
// final res = await checkAppUpdates(
|
||||||
currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber,
|
// currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber,
|
||||||
setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable,
|
// setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable,
|
||||||
installationSource: appConfigProvider.installationSource,
|
// installationSource: appConfigProvider.installationSource,
|
||||||
isBeta: appConfigProvider.getAppInfo!.version.contains('beta'),
|
// isBeta: appConfigProvider.getAppInfo!.version.contains('beta'),
|
||||||
);
|
// );
|
||||||
|
|
||||||
if (!mounted) return;
|
// if (!mounted) return;
|
||||||
if (res != null) {
|
// if (res != null) {
|
||||||
setState(() => appUpdatesStatus = AppUpdatesStatus.available);
|
// setState(() => appUpdatesStatus = AppUpdatesStatus.available);
|
||||||
}
|
// }
|
||||||
else {
|
// else {
|
||||||
setState(() => appUpdatesStatus = AppUpdatesStatus.recheck);
|
// setState(() => appUpdatesStatus = AppUpdatesStatus.recheck);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
Widget generateAppUpdateStatus() {
|
// Widget generateAppUpdateStatus() {
|
||||||
if (appUpdatesStatus == AppUpdatesStatus.available) {
|
// if (appUpdatesStatus == AppUpdatesStatus.available) {
|
||||||
return IconButton(
|
// return IconButton(
|
||||||
onPressed: appConfigProvider.appUpdatesAvailable != null
|
// onPressed: appConfigProvider.appUpdatesAvailable != null
|
||||||
? () async {
|
// ? () async {
|
||||||
final link = getAppUpdateDownloadLink(appConfigProvider.appUpdatesAvailable!);
|
// final link = getAppUpdateDownloadLink(appConfigProvider.appUpdatesAvailable!);
|
||||||
if (link != null) {
|
// if (link != null) {
|
||||||
openUrl(link);
|
// openUrl(link);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
: null,
|
// : null,
|
||||||
icon: const Icon(Icons.download_rounded),
|
// icon: const Icon(Icons.download_rounded),
|
||||||
tooltip: AppLocalizations.of(context)!.downloadUpdate,
|
// tooltip: AppLocalizations.of(context)!.downloadUpdate,
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
else if (appUpdatesStatus == AppUpdatesStatus.checking) {
|
// else if (appUpdatesStatus == AppUpdatesStatus.checking) {
|
||||||
return const Padding(
|
// return const Padding(
|
||||||
padding: EdgeInsets.only(right: 16),
|
// padding: EdgeInsets.only(right: 16),
|
||||||
child: SizedBox(
|
// child: SizedBox(
|
||||||
width: 24,
|
// width: 24,
|
||||||
height: 24,
|
// height: 24,
|
||||||
child: CircularProgressIndicator(
|
// child: CircularProgressIndicator(
|
||||||
strokeWidth: 3,
|
// strokeWidth: 3,
|
||||||
)
|
// )
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
else {
|
// else {
|
||||||
return IconButton(
|
// return IconButton(
|
||||||
onPressed: checkUpdatesAvailable,
|
// onPressed: checkUpdatesAvailable,
|
||||||
icon: const Icon(Icons.refresh_rounded),
|
// icon: const Icon(Icons.refresh_rounded),
|
||||||
tooltip: AppLocalizations.of(context)!.checkUpdates,
|
// tooltip: AppLocalizations.of(context)!.checkUpdates,
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
@ -253,17 +246,17 @@ class _GeneralSettingsState extends State<GeneralSettings> {
|
||||||
right: 10
|
right: 10
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
if (!(Platform.isAndroid || Platform.isIOS) || (Platform.isAndroid && (appConfigProvider.installationSource == InstallationAppReferrer.androidManually ))) ...[
|
// if (!(Platform.isAndroid || Platform.isIOS) || (Platform.isAndroid && (appConfigProvider.installationSource == InstallationAppReferrer.androidManually ))) ...[
|
||||||
SectionLabel(label: AppLocalizations.of(context)!.application),
|
// SectionLabel(label: AppLocalizations.of(context)!.application),
|
||||||
CustomListTile(
|
// CustomListTile(
|
||||||
icon: Icons.system_update_rounded,
|
// icon: Icons.system_update_rounded,
|
||||||
title: AppLocalizations.of(context)!.appUpdates,
|
// title: AppLocalizations.of(context)!.appUpdates,
|
||||||
subtitle: appConfigProvider.appUpdatesAvailable != null
|
// subtitle: appConfigProvider.appUpdatesAvailable != null
|
||||||
? AppLocalizations.of(context)!.updateAvailable
|
// ? AppLocalizations.of(context)!.updateAvailable
|
||||||
: AppLocalizations.of(context)!.usingLatestVersion,
|
// : AppLocalizations.of(context)!.usingLatestVersion,
|
||||||
trailing: generateAppUpdateStatus()
|
// trailing: generateAppUpdateStatus()
|
||||||
)
|
// )
|
||||||
]
|
// ]
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:adguard_home_manager/constants/regexps.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
@ -12,13 +13,16 @@ class LogsConfigOptions extends StatelessWidget {
|
||||||
final void Function(bool) updateGeneralSwitch;
|
final void Function(bool) updateGeneralSwitch;
|
||||||
final bool anonymizeClientIp;
|
final bool anonymizeClientIp;
|
||||||
final void Function(bool) updateAnonymizeClientIp;
|
final void Function(bool) updateAnonymizeClientIp;
|
||||||
final List<int> retentionItems;
|
final List<String> retentionItems;
|
||||||
final double? retentionTime;
|
final String? retentionTime;
|
||||||
final void Function(double?) updateRetentionTime;
|
final void Function(String?) updateRetentionTime;
|
||||||
final void Function() onClear;
|
final void Function() onClear;
|
||||||
final void Function() onConfirm;
|
final void Function() onConfirm;
|
||||||
final List<DomainListItemController> ignoredDomainsControllers;
|
final List<DomainListItemController> ignoredDomainsControllers;
|
||||||
final void Function(List<DomainListItemController>) updateIgnoredDomainsControllers;
|
final void Function(List<DomainListItemController>) updateIgnoredDomainsControllers;
|
||||||
|
final TextEditingController customTimeController;
|
||||||
|
final String? customTimeError;
|
||||||
|
final void Function(String) validateCustomTime;
|
||||||
|
|
||||||
const LogsConfigOptions({
|
const LogsConfigOptions({
|
||||||
super.key,
|
super.key,
|
||||||
|
@ -32,7 +36,10 @@ class LogsConfigOptions extends StatelessWidget {
|
||||||
required this.onClear,
|
required this.onClear,
|
||||||
required this.onConfirm,
|
required this.onConfirm,
|
||||||
required this.ignoredDomainsControllers,
|
required this.ignoredDomainsControllers,
|
||||||
required this.updateIgnoredDomainsControllers
|
required this.updateIgnoredDomainsControllers,
|
||||||
|
required this.customTimeController,
|
||||||
|
required this.customTimeError,
|
||||||
|
required this.validateCustomTime,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -40,6 +47,7 @@ class LogsConfigOptions extends StatelessWidget {
|
||||||
const Uuid uuid = Uuid();
|
const Uuid uuid = Uuid();
|
||||||
|
|
||||||
final List<String> dropdownItemTranslation = [
|
final List<String> dropdownItemTranslation = [
|
||||||
|
AppLocalizations.of(context)!.custom,
|
||||||
AppLocalizations.of(context)!.hours6,
|
AppLocalizations.of(context)!.hours6,
|
||||||
AppLocalizations.of(context)!.hours24,
|
AppLocalizations.of(context)!.hours24,
|
||||||
AppLocalizations.of(context)!.days7,
|
AppLocalizations.of(context)!.days7,
|
||||||
|
@ -48,9 +56,8 @@ class LogsConfigOptions extends StatelessWidget {
|
||||||
];
|
];
|
||||||
|
|
||||||
void validateDomain(String value, String id) {
|
void validateDomain(String value, String id) {
|
||||||
final domainRegex = RegExp(r'^([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$');
|
|
||||||
bool error = false;
|
bool error = false;
|
||||||
if (domainRegex.hasMatch(value)) {
|
if (Regexps.domain.hasMatch(value)) {
|
||||||
error = false;
|
error = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -67,7 +74,7 @@ class LogsConfigOptions extends StatelessWidget {
|
||||||
}).toList()
|
}).toList()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
print(retentionTime);
|
||||||
return ListView(
|
return ListView(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
|
@ -92,7 +99,7 @@ class LogsConfigOptions extends StatelessWidget {
|
||||||
child: Text(dropdownItemTranslation[item.key]),
|
child: Text(dropdownItemTranslation[item.key]),
|
||||||
)).toList(),
|
)).toList(),
|
||||||
value: retentionTime,
|
value: retentionTime,
|
||||||
onChanged: (value) => updateRetentionTime(double.tryParse(value.toString())),
|
onChanged: (value) => updateRetentionTime(value.toString()),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
border: const OutlineInputBorder(
|
border: const OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(
|
borderRadius: BorderRadius.all(
|
||||||
|
@ -104,6 +111,24 @@ class LogsConfigOptions extends StatelessWidget {
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (retentionTime == "custom") Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 24, left: 16, right: 16),
|
||||||
|
child: TextFormField(
|
||||||
|
controller: customTimeController,
|
||||||
|
onChanged: validateCustomTime,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
prefixIcon: const Icon(Icons.schedule_rounded),
|
||||||
|
border: const OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(10)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
labelText: AppLocalizations.of(context)!.customTimeInHours,
|
||||||
|
errorText: customTimeError
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
),
|
||||||
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 24, bottom: 8),
|
padding: const EdgeInsets.only(top: 24, bottom: 8),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|
|
@ -37,15 +37,18 @@ class _LogsSettingsState extends State<LogsSettings> {
|
||||||
|
|
||||||
bool generalSwitch = false;
|
bool generalSwitch = false;
|
||||||
bool anonymizeClientIp = false;
|
bool anonymizeClientIp = false;
|
||||||
double? retentionTime;
|
String? retentionTime;
|
||||||
List<DomainListItemController> _ignoredDomainsControllers = [];
|
List<DomainListItemController> _ignoredDomainsControllers = [];
|
||||||
|
final _customTimeController = TextEditingController();
|
||||||
|
String? _customTimeError = null;
|
||||||
|
|
||||||
List<int> retentionItems = [
|
List<String> retentionItems = [
|
||||||
21600000,
|
"custom",
|
||||||
86400000,
|
"21600000",
|
||||||
604800000,
|
"86400000",
|
||||||
2592000000,
|
"604800000",
|
||||||
7776000000
|
"2592000000",
|
||||||
|
"7776000000"
|
||||||
];
|
];
|
||||||
|
|
||||||
LoadStatus loadStatus = LoadStatus.loading;
|
LoadStatus loadStatus = LoadStatus.loading;
|
||||||
|
@ -61,9 +64,10 @@ class _LogsSettingsState extends State<LogsSettings> {
|
||||||
setState(() {
|
setState(() {
|
||||||
generalSwitch = data.enabled ?? false;
|
generalSwitch = data.enabled ?? false;
|
||||||
anonymizeClientIp = data.anonymizeClientIp ?? false;
|
anonymizeClientIp = data.anonymizeClientIp ?? false;
|
||||||
retentionTime = data.interval != null
|
retentionTime = retentionItems.contains(data.interval.toString()) ? data.interval.toString() : "custom";
|
||||||
? double.parse(data.interval.toString())
|
if (data.interval != null && !retentionItems.contains(data.interval.toString())) {
|
||||||
: null;
|
_customTimeController.text = (data.interval!/3.6e+6).toInt().toString();
|
||||||
|
}
|
||||||
if (data.ignored != null) {
|
if (data.ignored != null) {
|
||||||
_ignoredDomainsControllers = data.ignored!.map((e) => DomainListItemController(
|
_ignoredDomainsControllers = data.ignored!.map((e) => DomainListItemController(
|
||||||
id: uuid.v4(),
|
id: uuid.v4(),
|
||||||
|
@ -79,6 +83,34 @@ class _LogsSettingsState extends State<LogsSettings> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void validateCustomTime(String value) {
|
||||||
|
try {
|
||||||
|
final regex = RegExp(r'^\d+$');
|
||||||
|
final parsed = int.parse(value);
|
||||||
|
if (!regex.hasMatch(value)) {
|
||||||
|
setState(() => _customTimeError = AppLocalizations.of(context)!.invalidTime);
|
||||||
|
}
|
||||||
|
else if (parsed < 1) {
|
||||||
|
setState(() => _customTimeError = AppLocalizations.of(context)!.notLess1Hour);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setState(() => _customTimeError = null);
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
setState(() => _customTimeError = AppLocalizations.of(context)!.invalidTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkValidValues() {
|
||||||
|
if (_ignoredDomainsControllers.where((d) => d.controller.text == "" || d.error == true).isNotEmpty) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (retentionTime == "custom" && (_customTimeError != null || _customTimeController.text == "")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
loadData();
|
loadData();
|
||||||
|
@ -90,9 +122,7 @@ class _LogsSettingsState extends State<LogsSettings> {
|
||||||
final serversProvider = Provider.of<ServersProvider>(context);
|
final serversProvider = Provider.of<ServersProvider>(context);
|
||||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||||
|
|
||||||
final validValues = _ignoredDomainsControllers.where(
|
final validValues = checkValidValues();
|
||||||
(d) => d.controller.text == "" || d.error == true
|
|
||||||
).isEmpty;
|
|
||||||
|
|
||||||
void clearQueries() async {
|
void clearQueries() async {
|
||||||
ProcessModal processModal = ProcessModal();
|
ProcessModal processModal = ProcessModal();
|
||||||
|
@ -127,7 +157,7 @@ class _LogsSettingsState extends State<LogsSettings> {
|
||||||
final result = await serversProvider.apiClient2!.updateQueryLogParameters(
|
final result = await serversProvider.apiClient2!.updateQueryLogParameters(
|
||||||
data: {
|
data: {
|
||||||
"enabled": generalSwitch,
|
"enabled": generalSwitch,
|
||||||
"interval": retentionTime,
|
"interval": retentionTime == "custom" ? int.parse(_customTimeController.text)*3.6e+6 : int.parse(retentionTime!) ,
|
||||||
"anonymize_client_ip": anonymizeClientIp,
|
"anonymize_client_ip": anonymizeClientIp,
|
||||||
"ignored": _ignoredDomainsControllers.map((e) => e.controller.text).toList()
|
"ignored": _ignoredDomainsControllers.map((e) => e.controller.text).toList()
|
||||||
}
|
}
|
||||||
|
@ -198,6 +228,9 @@ class _LogsSettingsState extends State<LogsSettings> {
|
||||||
onConfirm: updateConfig,
|
onConfirm: updateConfig,
|
||||||
ignoredDomainsControllers: _ignoredDomainsControllers,
|
ignoredDomainsControllers: _ignoredDomainsControllers,
|
||||||
updateIgnoredDomainsControllers: (v) => setState(() => _ignoredDomainsControllers = v),
|
updateIgnoredDomainsControllers: (v) => setState(() => _ignoredDomainsControllers = v),
|
||||||
|
customTimeController: _customTimeController,
|
||||||
|
customTimeError: _customTimeError,
|
||||||
|
validateCustomTime: validateCustomTime,
|
||||||
);
|
);
|
||||||
|
|
||||||
case LoadStatus.error:
|
case LoadStatus.error:
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.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/settings/server_info/server_info.dart';
|
import 'package:adguard_home_manager/screens/settings/server_info/server_info.dart';
|
||||||
|
@ -25,7 +23,6 @@ import 'package:adguard_home_manager/widgets/section_label.dart';
|
||||||
import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/functions/desktop_mode.dart';
|
import 'package:adguard_home_manager/functions/desktop_mode.dart';
|
||||||
import 'package:adguard_home_manager/constants/strings.dart';
|
|
||||||
import 'package:adguard_home_manager/functions/open_url.dart';
|
import 'package:adguard_home_manager/functions/open_url.dart';
|
||||||
import 'package:adguard_home_manager/constants/urls.dart';
|
import 'package:adguard_home_manager/constants/urls.dart';
|
||||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||||
|
@ -273,37 +270,18 @@ class _SettingsWidgetState extends State<_SettingsWidget> {
|
||||||
subtitle: appConfigProvider.getAppInfo!.version,
|
subtitle: appConfigProvider.getAppInfo!.version,
|
||||||
),
|
),
|
||||||
CustomListTile(
|
CustomListTile(
|
||||||
title: AppLocalizations.of(context)!.createdBy,
|
title: AppLocalizations.of(context)!.applicationDetails,
|
||||||
subtitle: Strings.createdBy,
|
subtitle: AppLocalizations.of(context)!.applicationDetailsDescription,
|
||||||
|
trailing: Icon(Icons.open_in_new_rounded),
|
||||||
|
onTap: () => openUrl(Urls.appDetailsWebpage),
|
||||||
),
|
),
|
||||||
Padding(
|
CustomListTile(
|
||||||
padding: const EdgeInsets.all(15),
|
title: AppLocalizations.of(context)!.myOtherApps,
|
||||||
child: Row(
|
subtitle: AppLocalizations.of(context)!.myOtherAppsDescription,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
trailing: Icon(Icons.open_in_new_rounded),
|
||||||
children: [
|
onTap: () => openUrl(Urls.jgeek00AppsWebpage),
|
||||||
if (Platform.isAndroid) IconButton(
|
|
||||||
onPressed: () => openUrl(Urls.playStore),
|
|
||||||
icon: SvgPicture.asset(
|
|
||||||
'assets/resources/google-play.svg',
|
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
width: 30,
|
|
||||||
height: 30,
|
|
||||||
),
|
),
|
||||||
tooltip: AppLocalizations.of(context)!.visitGooglePlay,
|
SizedBox(height: 16)
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
onPressed: () => openUrl(Urls.gitHub),
|
|
||||||
icon: SvgPicture.asset(
|
|
||||||
'assets/resources/github.svg',
|
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
width: 30,
|
|
||||||
height: 30,
|
|
||||||
),
|
|
||||||
tooltip: AppLocalizations.of(context)!.gitHub,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:adguard_home_manager/constants/regexps.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
@ -91,9 +92,8 @@ class _StatisticsSettingsState extends State<StatisticsSettings> {
|
||||||
|
|
||||||
|
|
||||||
void validateDomain(String value, String id) {
|
void validateDomain(String value, String id) {
|
||||||
final domainRegex = RegExp(r'^([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$');
|
|
||||||
bool error = false;
|
bool error = false;
|
||||||
if (domainRegex.hasMatch(value)) {
|
if (Regexps.domain.hasMatch(value)) {
|
||||||
error = false;
|
error = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -138,7 +138,7 @@ class _StatisticsSettingsState extends State<StatisticsSettings> {
|
||||||
"enabled": _generalSwitch,
|
"enabled": _generalSwitch,
|
||||||
"interval": _retentionTime == "custom"
|
"interval": _retentionTime == "custom"
|
||||||
? Duration(hours: int.parse(_customTimeController.text)).inMilliseconds
|
? Duration(hours: int.parse(_customTimeController.text)).inMilliseconds
|
||||||
: int.parse(_retentionTime!),
|
: int.parse(_retentionTime ?? _retentionItems[0]),
|
||||||
"ignored": _ignoredDomainsControllers.map((e) => e.controller.text).toList()
|
"ignored": _ignoredDomainsControllers.map((e) => e.controller.text).toList()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -218,9 +218,16 @@ class _Header extends SliverPersistentHeaderDelegate {
|
||||||
final iconBottom = _iconMinBottomPositionExent + (iconMaxBottomPositionExent-iconMinBottomPositionExent)*(1-iconPercentage);
|
final iconBottom = _iconMinBottomPositionExent + (iconMaxBottomPositionExent-iconMinBottomPositionExent)*(1-iconPercentage);
|
||||||
|
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
builder: (context, constraints) => Container(
|
builder: (context, constraints) => Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.surfaceContainerHighest,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surfaceTint.withOpacity(0.075),
|
||||||
),
|
),
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: Alignment.topLeft,
|
alignment: Alignment.topLeft,
|
||||||
|
@ -314,6 +321,8 @@ class _Header extends SliverPersistentHeaderDelegate {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:adguard_home_manager/constants/regexps.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
@ -49,8 +50,7 @@ String? validateSubroute({
|
||||||
required String? value
|
required String? value
|
||||||
}) {
|
}) {
|
||||||
if (value != null && value != '') {
|
if (value != null && value != '') {
|
||||||
RegExp subrouteRegexp = RegExp(r'^\/\b([A-Za-z0-9_\-~/]*)[^\/|\.|\:]$');
|
if (Regexps.subroute.hasMatch(value) == true) {
|
||||||
if (subrouteRegexp.hasMatch(value) == true) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -67,9 +67,7 @@ String? validateAddress({
|
||||||
required String? value
|
required String? value
|
||||||
}) {
|
}) {
|
||||||
if (value != null && value != '') {
|
if (value != null && value != '') {
|
||||||
RegExp ipAddress = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$');
|
if (Regexps.ipv4Address.hasMatch(value) == true || Regexps.domain.hasMatch(value) == true) {
|
||||||
RegExp domain = RegExp(r'^(([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+)$');
|
|
||||||
if (ipAddress.hasMatch(value) == true || domain.hasMatch(value) == true) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -142,6 +142,7 @@ class _AddServerModalState extends State<AddServerModal> {
|
||||||
port: portController.text != '' ? int.parse(portController.text) : null,
|
port: portController.text != '' ? int.parse(portController.text) : null,
|
||||||
user: userController.text != "" ? userController.text : null,
|
user: userController.text != "" ? userController.text : null,
|
||||||
password: passwordController.text != "" ? passwordController.text : null,
|
password: passwordController.text != "" ? passwordController.text : null,
|
||||||
|
path: pathController.text != "" ? pathController.text : null,
|
||||||
defaultServer: defaultServer,
|
defaultServer: defaultServer,
|
||||||
authToken: homeAssistant == true
|
authToken: homeAssistant == true
|
||||||
? encodeBase64UserPass(userController.text, passwordController.text)
|
? encodeBase64UserPass(userController.text, passwordController.text)
|
||||||
|
@ -174,6 +175,8 @@ class _AddServerModalState extends State<AddServerModal> {
|
||||||
final ApiClientV2 apiClient2 = ApiClientV2(server: serverObj);
|
final ApiClientV2 apiClient2 = ApiClientV2(server: serverObj);
|
||||||
final serverStatus = await apiClient2.getServerStatus();
|
final serverStatus = await apiClient2.getServerStatus();
|
||||||
|
|
||||||
|
if (!context.mounted) return;
|
||||||
|
|
||||||
// If something goes wrong when fetching server status
|
// If something goes wrong when fetching server status
|
||||||
if (serverStatus.successful == false) {
|
if (serverStatus.successful == false) {
|
||||||
statusProvider.setServerStatusLoad(LoadStatus.error);
|
statusProvider.setServerStatusLoad(LoadStatus.error);
|
||||||
|
@ -202,16 +205,16 @@ class _AddServerModalState extends State<AddServerModal> {
|
||||||
|
|
||||||
final serverCreated = await serversProvider.createServer(serverObj);
|
final serverCreated = await serversProvider.createServer(serverObj);
|
||||||
|
|
||||||
|
if (!context.mounted) return;
|
||||||
|
|
||||||
// If something goes wrong when saving the connection on the db
|
// If something goes wrong when saving the connection on the db
|
||||||
if (serverCreated != null) {
|
if (serverCreated != null) {
|
||||||
if (mounted) setState(() => isConnecting = false);
|
setState(() => isConnecting = false);
|
||||||
if (mounted) {
|
|
||||||
showSnackbar(
|
showSnackbar(
|
||||||
appConfigProvider: appConfigProvider,
|
appConfigProvider: appConfigProvider,
|
||||||
label: AppLocalizations.of(context)!.connectionNotCreated,
|
label: AppLocalizations.of(context)!.connectionNotCreated,
|
||||||
color: Colors.red
|
color: Colors.red
|
||||||
);
|
);
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,9 +298,11 @@ class _AddServerModalState extends State<AddServerModal> {
|
||||||
|
|
||||||
final serverSaved = await serversProvider.editServer(serverObj);
|
final serverSaved = await serversProvider.editServer(serverObj);
|
||||||
|
|
||||||
|
if (!mounted) return;
|
||||||
|
|
||||||
// If something goes wrong when saving the connection on the db
|
// If something goes wrong when saving the connection on the db
|
||||||
if (serverSaved != null) {
|
if (serverSaved != null) {
|
||||||
if (mounted) setState(() => isConnecting = false);
|
setState(() => isConnecting = false);
|
||||||
appConfigProvider.addLog(
|
appConfigProvider.addLog(
|
||||||
AppLog(
|
AppLog(
|
||||||
type: 'save_connection_db',
|
type: 'save_connection_db',
|
||||||
|
@ -305,13 +310,11 @@ class _AddServerModalState extends State<AddServerModal> {
|
||||||
message: serverSaved.toString()
|
message: serverSaved.toString()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
if (mounted) {
|
|
||||||
showSnackbar(
|
showSnackbar(
|
||||||
appConfigProvider: appConfigProvider,
|
appConfigProvider: appConfigProvider,
|
||||||
label: AppLocalizations.of(context)!.connectionNotCreated,
|
label: AppLocalizations.of(context)!.connectionNotCreated,
|
||||||
color: Colors.red
|
color: Colors.red
|
||||||
);
|
);
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:animations/animations.dart';
|
import 'package:animations/animations.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/widgets/update_modal.dart';
|
|
||||||
import 'package:adguard_home_manager/widgets/system_ui_overlay_style.dart';
|
import 'package:adguard_home_manager/widgets/system_ui_overlay_style.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/providers/app_config_provider.dart';
|
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||||
import 'package:adguard_home_manager/config/app_screens.dart';
|
import 'package:adguard_home_manager/config/app_screens.dart';
|
||||||
import 'package:adguard_home_manager/config/sizes.dart';
|
import 'package:adguard_home_manager/config/sizes.dart';
|
||||||
|
@ -37,23 +33,23 @@ class _LayoutState extends State<Layout> with WidgetsBindingObserver {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
if (kDebugMode) return; // Don't check for app updates on debug mode
|
// if (kDebugMode) return; // Don't check for app updates on debug mode
|
||||||
final appConfigProvider = Provider.of<AppConfigProvider>(context, listen: false);
|
// final appConfigProvider = Provider.of<AppConfigProvider>(context, listen: false);
|
||||||
final result = await checkAppUpdates(
|
// final result = await checkAppUpdates(
|
||||||
currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber,
|
// currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber,
|
||||||
installationSource: appConfigProvider.installationSource,
|
// installationSource: appConfigProvider.installationSource,
|
||||||
setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable,
|
// setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable,
|
||||||
isBeta: appConfigProvider.getAppInfo!.version.contains('beta'),
|
// isBeta: appConfigProvider.getAppInfo!.version.contains('beta'),
|
||||||
);
|
// );
|
||||||
if (result != null && appConfigProvider.doNotRememberVersion != result.tagName && mounted) {
|
// if (result != null && appConfigProvider.doNotRememberVersion != result.tagName && mounted) {
|
||||||
await showDialog(
|
// await showDialog(
|
||||||
context: context,
|
// context: context,
|
||||||
builder: (context) => UpdateModal(
|
// builder: (context) => UpdateModal(
|
||||||
gitHubRelease: result,
|
// gitHubRelease: result,
|
||||||
onDownload: (link, version) => openUrl(link),
|
// onDownload: (link, version) => openUrl(link),
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
#include <dynamic_color/dynamic_color_plugin.h>
|
#include <dynamic_color/dynamic_color_plugin.h>
|
||||||
#include <screen_retriever/screen_retriever_plugin.h>
|
#include <screen_retriever_linux/screen_retriever_linux_plugin.h>
|
||||||
#include <sentry_flutter/sentry_flutter_plugin.h>
|
#include <sentry_flutter/sentry_flutter_plugin.h>
|
||||||
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
||||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||||
|
@ -17,9 +17,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
g_autoptr(FlPluginRegistrar) dynamic_color_registrar =
|
g_autoptr(FlPluginRegistrar) dynamic_color_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin");
|
||||||
dynamic_color_plugin_register_with_registrar(dynamic_color_registrar);
|
dynamic_color_plugin_register_with_registrar(dynamic_color_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) screen_retriever_registrar =
|
g_autoptr(FlPluginRegistrar) screen_retriever_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverLinuxPlugin");
|
||||||
screen_retriever_plugin_register_with_registrar(screen_retriever_registrar);
|
screen_retriever_linux_plugin_register_with_registrar(screen_retriever_linux_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) sentry_flutter_registrar =
|
g_autoptr(FlPluginRegistrar) sentry_flutter_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "SentryFlutterPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "SentryFlutterPlugin");
|
||||||
sentry_flutter_plugin_register_with_registrar(sentry_flutter_registrar);
|
sentry_flutter_plugin_register_with_registrar(sentry_flutter_registrar);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
dynamic_color
|
dynamic_color
|
||||||
screen_retriever
|
screen_retriever_linux
|
||||||
sentry_flutter
|
sentry_flutter
|
||||||
sqlite3_flutter_libs
|
sqlite3_flutter_libs
|
||||||
url_launcher_linux
|
url_launcher_linux
|
||||||
|
|
|
@ -8,10 +8,10 @@ import Foundation
|
||||||
import device_info_plus
|
import device_info_plus
|
||||||
import dynamic_color
|
import dynamic_color
|
||||||
import package_info_plus
|
import package_info_plus
|
||||||
import screen_retriever
|
import screen_retriever_macos
|
||||||
import sentry_flutter
|
import sentry_flutter
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
import sqflite
|
import sqflite_darwin
|
||||||
import sqlite3_flutter_libs
|
import sqlite3_flutter_libs
|
||||||
import url_launcher_macos
|
import url_launcher_macos
|
||||||
import window_manager
|
import window_manager
|
||||||
|
@ -20,7 +20,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||||
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
|
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
|
||||||
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
||||||
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
|
ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin"))
|
||||||
SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin"))
|
SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||||
|
|
|
@ -6,39 +6,38 @@ PODS:
|
||||||
- FlutterMacOS (1.0.0)
|
- FlutterMacOS (1.0.0)
|
||||||
- package_info_plus (0.0.1):
|
- package_info_plus (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- screen_retriever (0.0.1):
|
- screen_retriever_macos (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- Sentry/HybridSDK (8.35.1)
|
- Sentry/HybridSDK (8.44.0)
|
||||||
- sentry_flutter (8.8.0):
|
- sentry_flutter (8.13.2):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- Sentry/HybridSDK (= 8.35.1)
|
- Sentry/HybridSDK (= 8.44.0)
|
||||||
- shared_preferences_foundation (0.0.1):
|
- shared_preferences_foundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- sqflite (0.0.3):
|
- sqflite_darwin (0.0.4):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- "sqlite3 (3.46.1+1)":
|
- sqlite3 (3.49.1):
|
||||||
- "sqlite3/common (= 3.46.1+1)"
|
- sqlite3/common (= 3.49.1)
|
||||||
- "sqlite3/common (3.46.1+1)"
|
- sqlite3/common (3.49.1)
|
||||||
- "sqlite3/dbstatvtab (3.46.1+1)":
|
- sqlite3/dbstatvtab (3.49.1):
|
||||||
- sqlite3/common
|
- sqlite3/common
|
||||||
- "sqlite3/fts5 (3.46.1+1)":
|
- sqlite3/fts5 (3.49.1):
|
||||||
- sqlite3/common
|
- sqlite3/common
|
||||||
- "sqlite3/perf-threadsafe (3.46.1+1)":
|
- sqlite3/perf-threadsafe (3.49.1):
|
||||||
- sqlite3/common
|
- sqlite3/common
|
||||||
- "sqlite3/rtree (3.46.1+1)":
|
- sqlite3/rtree (3.49.1):
|
||||||
- sqlite3/common
|
- sqlite3/common
|
||||||
- sqlite3_flutter_libs (0.0.1):
|
- sqlite3_flutter_libs (0.0.1):
|
||||||
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- "sqlite3 (~> 3.46.0+1)"
|
- sqlite3 (~> 3.49.1)
|
||||||
- sqlite3/dbstatvtab
|
- sqlite3/dbstatvtab
|
||||||
- sqlite3/fts5
|
- sqlite3/fts5
|
||||||
- sqlite3/perf-threadsafe
|
- sqlite3/perf-threadsafe
|
||||||
- sqlite3/rtree
|
- sqlite3/rtree
|
||||||
- store_checker (0.0.1):
|
|
||||||
- FlutterMacOS
|
|
||||||
- url_launcher_macos (0.0.1):
|
- url_launcher_macos (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- window_manager (0.2.0):
|
- window_manager (0.2.0):
|
||||||
|
@ -49,12 +48,11 @@ DEPENDENCIES:
|
||||||
- dynamic_color (from `Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos`)
|
- dynamic_color (from `Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos`)
|
||||||
- FlutterMacOS (from `Flutter/ephemeral`)
|
- FlutterMacOS (from `Flutter/ephemeral`)
|
||||||
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
|
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
|
||||||
- screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`)
|
- screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`)
|
||||||
- sentry_flutter (from `Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos`)
|
- sentry_flutter (from `Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos`)
|
||||||
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
|
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||||
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`)
|
- sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`)
|
||||||
- sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos`)
|
- sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin`)
|
||||||
- store_checker (from `Flutter/ephemeral/.symlinks/plugins/store_checker/macos`)
|
|
||||||
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
||||||
- window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`)
|
- window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`)
|
||||||
|
|
||||||
|
@ -72,37 +70,34 @@ EXTERNAL SOURCES:
|
||||||
:path: Flutter/ephemeral
|
:path: Flutter/ephemeral
|
||||||
package_info_plus:
|
package_info_plus:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
|
||||||
screen_retriever:
|
screen_retriever_macos:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos
|
||||||
sentry_flutter:
|
sentry_flutter:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
|
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
|
||||||
sqflite:
|
sqflite_darwin:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/sqflite/darwin
|
:path: Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin
|
||||||
sqlite3_flutter_libs:
|
sqlite3_flutter_libs:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin
|
||||||
store_checker:
|
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/store_checker/macos
|
|
||||||
url_launcher_macos:
|
url_launcher_macos:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
||||||
window_manager:
|
window_manager:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
device_info_plus: ce1b7762849d3ec103d0e0517299f2db7ad60720
|
device_info_plus: 1b14eed9bf95428983aed283a8d51cce3d8c4215
|
||||||
dynamic_color: 2eaa27267de1ca20d879fbd6e01259773fb1670f
|
dynamic_color: 2eaa27267de1ca20d879fbd6e01259773fb1670f
|
||||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||||
package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c
|
package_info_plus: 12f1c5c2cfe8727ca46cbd0b26677728972d9a5b
|
||||||
screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38
|
screen_retriever_macos: 776e0fa5d42c6163d2bf772d22478df4b302b161
|
||||||
Sentry: 1fe34e9c2cbba1e347623610d26db121dcb569f1
|
Sentry: 0f9bc9adfc0b960e7f3bb5ec67e9a3d8193f3bdb
|
||||||
sentry_flutter: a39c2a2d67d5e5b9cb0b94a4985c76dd5b3fc737
|
sentry_flutter: 64a43fb39ab4c7f67d8a4cad52b49e22439e58b7
|
||||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||||
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
|
||||||
sqlite3: 0bb0e6389d824e40296f531b858a2a0b71c0d2fb
|
sqlite3: fc1400008a9b3525f5914ed715a5d1af0b8f4983
|
||||||
sqlite3_flutter_libs: 5ca46c1a04eddfbeeb5b16566164aa7ad1616e7b
|
sqlite3_flutter_libs: cc304edcb8e1d8c595d1b08c7aeb46a47691d9db
|
||||||
store_checker: 387169de0dffe57b6370d54cc027e9f95051b57f
|
url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404
|
||||||
url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399
|
|
||||||
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8
|
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8
|
||||||
|
|
||||||
PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7
|
PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
debugDocumentVersioning = "YES"
|
debugDocumentVersioning = "YES"
|
||||||
debugServiceExtension = "internal"
|
debugServiceExtension = "internal"
|
||||||
|
enableGPUValidationMode = "1"
|
||||||
allowLocationSimulation = "YES">
|
allowLocationSimulation = "YES">
|
||||||
<BuildableProductRunnable
|
<BuildableProductRunnable
|
||||||
runnableDebuggingMode = "0">
|
runnableDebuggingMode = "0">
|
||||||
|
|
|
@ -6,4 +6,8 @@ class AppDelegate: FlutterAppDelegate {
|
||||||
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
410
pubspec.lock
410
pubspec.lock
|
@ -29,42 +29,42 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: archive
|
name: archive
|
||||||
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
|
sha256: "7dcbd0f87fe5f61cb28da39a1a8b70dbc106e2fe0516f7836eb7bb2948481a12"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.6.1"
|
version: "4.0.5"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
|
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.0"
|
version: "2.7.0"
|
||||||
async:
|
async:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
|
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.11.0"
|
version: "2.12.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
|
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.2"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.4.0"
|
||||||
checked_yaml:
|
checked_yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -77,26 +77,26 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: cli_util
|
name: cli_util
|
||||||
sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19
|
sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.1"
|
version: "0.4.2"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: clock
|
name: clock
|
||||||
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
|
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.2"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.18.0"
|
version: "1.19.1"
|
||||||
contextmenu:
|
contextmenu:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -109,18 +109,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
|
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.5"
|
version: "3.0.6"
|
||||||
csslib:
|
csslib:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: csslib
|
name: csslib
|
||||||
sha256: "831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f"
|
sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.17.3"
|
version: "1.0.2"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -133,18 +133,18 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: device_info_plus
|
name: device_info_plus
|
||||||
sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074
|
sha256: "306b78788d1bb569edb7c55d622953c2414ca12445b41c9117963e03afc5c513"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.1.2"
|
version: "11.3.3"
|
||||||
device_info_plus_platform_interface:
|
device_info_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: device_info_plus_platform_interface
|
name: device_info_plus_platform_interface
|
||||||
sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba"
|
sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.2"
|
||||||
dynamic_color:
|
dynamic_color:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -157,10 +157,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: equatable
|
name: equatable
|
||||||
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
|
sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.5"
|
version: "2.0.7"
|
||||||
expandable:
|
expandable:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -173,42 +173,42 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
|
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.1"
|
version: "1.3.2"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
|
sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.4"
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
|
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "7.0.1"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fixnum
|
name: fixnum
|
||||||
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
|
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.1"
|
||||||
fl_chart:
|
fl_chart:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: fl_chart
|
name: fl_chart
|
||||||
sha256: "94307bef3a324a0d329d3ab77b2f0c6e5ed739185ffc029ed28c0f9b019ea7ef"
|
sha256: "5276944c6ffc975ae796569a826c38a62d2abcf264e26b88fa6f482e107f4237"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.69.0"
|
version: "0.70.2"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -254,46 +254,38 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
flutter_displaymode:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: flutter_displaymode
|
|
||||||
sha256: "42c5e9abd13d28ed74f701b60529d7f8416947e58256e6659c5550db719c57ef"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.6.0"
|
|
||||||
flutter_dotenv:
|
flutter_dotenv:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_dotenv
|
name: flutter_dotenv
|
||||||
sha256: "9357883bdd153ab78cbf9ffa07656e336b8bbb2b5a3ca596b0b27e119f7c7d77"
|
sha256: b7c7be5cd9f6ef7a78429cabd2774d3c4af50e79cb2b7593e3d5d763ef95c61b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.1.0"
|
version: "5.2.1"
|
||||||
flutter_html:
|
flutter_html:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_html
|
name: flutter_html
|
||||||
sha256: "02ad69e813ecfc0728a455e4bf892b9379983e050722b1dce00192ee2e41d1ee"
|
sha256: "38a2fd702ffdf3243fb7441ab58aa1bc7e6922d95a50db76534de8260638558d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0-beta.2"
|
version: "3.0.0"
|
||||||
flutter_launcher_icons:
|
flutter_launcher_icons:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_launcher_icons
|
name: flutter_launcher_icons
|
||||||
sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
|
sha256: bfa04787c85d80ecb3f8777bde5fc10c3de809240c48fa061a2c2bf15ea5211c
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.13.1"
|
version: "0.14.3"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_lints
|
name: flutter_lints
|
||||||
sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c"
|
sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "5.0.0"
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -303,18 +295,18 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_markdown
|
name: flutter_markdown
|
||||||
sha256: a23c41ee57573e62fc2190a1f36a0480c4d90bde3a8a8d7126e5d5992fb53fb7
|
sha256: e7bbc718adc9476aa14cfddc1ef048d2e21e4e8f18311aaac723266db9f9e7b5
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.3+1"
|
version: "0.7.6+2"
|
||||||
flutter_native_splash:
|
flutter_native_splash:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_native_splash
|
name: flutter_native_splash
|
||||||
sha256: aa06fec78de2190f3db4319dd60fdc8d12b2626e93ef9828633928c2dcaea840
|
sha256: edb09c35ee9230c4b03f13dd45bb3a276d0801865f0a4650b7e2a3bba61a803a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.1"
|
version: "2.4.5"
|
||||||
flutter_reorderable_list:
|
flutter_reorderable_list:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -327,10 +319,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_svg
|
name: flutter_svg
|
||||||
sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2"
|
sha256: c200fd79c918a40c5cd50ea0877fa13f81bdaf6f0a5d3dbcc2a13e3285d6aa1b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.10+1"
|
version: "2.0.17"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -345,42 +337,34 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: html
|
name: html
|
||||||
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
|
sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.15.4"
|
version: "0.15.5"
|
||||||
http:
|
http:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.2"
|
version: "1.3.0"
|
||||||
http_parser:
|
http_parser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http_parser
|
name: http_parser
|
||||||
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
|
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.2"
|
version: "4.1.2"
|
||||||
image:
|
image:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: image
|
name: image
|
||||||
sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8"
|
sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.0"
|
version: "4.5.4"
|
||||||
install_referrer:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: install_referrer
|
|
||||||
sha256: "901c56d24ee3c3010dfd0bbebf305ed6b4b0f3fe969192081c167590a64cd78b"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.1"
|
|
||||||
intl:
|
intl:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -401,18 +385,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.5"
|
version: "10.0.8"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.5"
|
version: "3.0.9"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -425,10 +409,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235"
|
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "5.1.1"
|
||||||
list_counter:
|
list_counter:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -441,18 +425,18 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: markdown
|
name: markdown
|
||||||
sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051
|
sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.2.2"
|
version: "7.3.0"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
|
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.16+1"
|
version: "0.12.17"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -465,10 +449,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.15.0"
|
version: "1.16.0"
|
||||||
nested:
|
nested:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -481,34 +465,34 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: package_info_plus
|
name: package_info_plus
|
||||||
sha256: a75164ade98cb7d24cfd0a13c6408927c6b217fa60dee5a7ff5c116a58f28918
|
sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.0.2"
|
version: "8.3.0"
|
||||||
package_info_plus_platform_interface:
|
package_info_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: package_info_plus_platform_interface
|
name: package_info_plus_platform_interface
|
||||||
sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66
|
sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.2.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
|
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.0"
|
version: "1.9.1"
|
||||||
path_parsing:
|
path_parsing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_parsing
|
name: path_parsing
|
||||||
sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
|
sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.1.0"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -537,18 +521,18 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: percent_indicator
|
name: percent_indicator
|
||||||
sha256: c37099ad833a883c9d71782321cb65c3a848c21b6939b6185f0ff6640d05814c
|
sha256: "0d77d5c6fa9b7f60202cedf748b568ba9ba38d3f30405d6ceae4da76f5185462"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.3"
|
version: "4.2.4"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: petitparser
|
name: petitparser
|
||||||
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
|
sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.2"
|
version: "6.1.0"
|
||||||
pie_chart:
|
pie_chart:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -561,10 +545,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
|
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.5"
|
version: "3.1.6"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -573,6 +557,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.8"
|
version: "2.1.8"
|
||||||
|
posix:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: posix
|
||||||
|
sha256: a0117dc2167805aa9125b82eee515cc891819bac2f538c83646d355b16f58b9a
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.0.1"
|
||||||
provider:
|
provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -585,10 +577,42 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: screen_retriever
|
name: screen_retriever
|
||||||
sha256: "6ee02c8a1158e6dae7ca430da79436e3b1c9563c8cf02f524af997c201ac2b90"
|
sha256: "570dbc8e4f70bac451e0efc9c9bb19fa2d6799a11e6ef04f946d7886d2e23d0c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.9"
|
version: "0.2.0"
|
||||||
|
screen_retriever_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: screen_retriever_linux
|
||||||
|
sha256: f7f8120c92ef0784e58491ab664d01efda79a922b025ff286e29aa123ea3dd18
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.0"
|
||||||
|
screen_retriever_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: screen_retriever_macos
|
||||||
|
sha256: "71f956e65c97315dd661d71f828708bd97b6d358e776f1a30d5aa7d22d78a149"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.0"
|
||||||
|
screen_retriever_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: screen_retriever_platform_interface
|
||||||
|
sha256: ee197f4581ff0d5608587819af40490748e1e39e648d7680ecf95c05197240c0
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.0"
|
||||||
|
screen_retriever_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: screen_retriever_windows
|
||||||
|
sha256: "449ee257f03ca98a57288ee526a301a430a344a161f9202b4fcc38576716fe13"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.0"
|
||||||
segmented_button_slide:
|
segmented_button_slide:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -601,42 +625,42 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: sentry
|
name: sentry
|
||||||
sha256: "1af8308298977259430d118ab25be8e1dda626cdefa1e6ce869073d530d39271"
|
sha256: "3a64dd001bff768ce5ab6fc3608deef4dde22acd4b5d947763557b20db9e2a32"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.8.0"
|
version: "8.14.0"
|
||||||
sentry_flutter:
|
sentry_flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: sentry_flutter
|
name: sentry_flutter
|
||||||
sha256: "18fe4d125c2d529bd6127200f0d2895768266a8c60b4fb50b2086fd97e1a4ab2"
|
sha256: "3d361f2d5f805783e2e4ed1bd475ef126b36cf525b359dc3627a765a3fb7424d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.8.0"
|
version: "8.14.0"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051"
|
sha256: "846849e3e9b68f3ef4b60c60cf4b3e02e9321bc7f4d8c4692cf87ffa82fc8a3a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.2"
|
version: "2.5.2"
|
||||||
shared_preferences_android:
|
shared_preferences_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_android
|
name: shared_preferences_android
|
||||||
sha256: "480ba4345773f56acda9abf5f50bd966f581dac5d514e5fc4a18c62976bbba7e"
|
sha256: "3ec7210872c4ba945e3244982918e502fa2bfb5230dff6832459ca0e1879b7ad"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.2"
|
version: "2.4.8"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_foundation
|
name: shared_preferences_foundation
|
||||||
sha256: c4b35f6cb8f63c147312c054ce7c2254c8066745125264f0c88739c417fc9d9f
|
sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.2"
|
version: "2.5.4"
|
||||||
shared_preferences_linux:
|
shared_preferences_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -657,10 +681,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_web
|
name: shared_preferences_web
|
||||||
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
|
sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.2"
|
version: "2.4.3"
|
||||||
shared_preferences_windows:
|
shared_preferences_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -673,15 +697,15 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.99"
|
version: "0.0.0"
|
||||||
source_span:
|
source_span:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
|
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0"
|
version: "1.10.1"
|
||||||
sprintf:
|
sprintf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -694,106 +718,130 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: sqflite
|
name: sqflite
|
||||||
sha256: a43e5a27235518c03ca238e7b4732cf35eabe863a369ceba6cbefa537a66f16d
|
sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.3+1"
|
version: "2.4.2"
|
||||||
|
sqflite_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sqflite_android
|
||||||
|
sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.1"
|
||||||
sqflite_common:
|
sqflite_common:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: sqflite_common
|
name: sqflite_common
|
||||||
sha256: "7b41b6c3507854a159e24ae90a8e3e9cc01eb26a477c118d6dca065b5f55453e"
|
sha256: "84731e8bfd8303a3389903e01fb2141b6e59b5973cacbb0929021df08dddbe8b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.4+2"
|
version: "2.5.5"
|
||||||
sqflite_common_ffi:
|
sqflite_common_ffi:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: sqflite_common_ffi
|
name: sqflite_common_ffi
|
||||||
sha256: "4d6137c29e930d6e4a8ff373989dd9de7bac12e3bc87bce950f6e844e8ad3bb5"
|
sha256: "1f3ef3888d3bfbb47785cc1dda0dc7dd7ebd8c1955d32a9e8e9dae1e38d1c4c1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.3"
|
version: "2.3.5"
|
||||||
|
sqflite_darwin:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sqflite_darwin
|
||||||
|
sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.2"
|
||||||
|
sqflite_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sqflite_platform_interface
|
||||||
|
sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.0"
|
||||||
sqlite3:
|
sqlite3:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: sqlite3
|
name: sqlite3
|
||||||
sha256: "45f168ae2213201b54e09429ed0c593dc2c88c924a1488d6f9c523a255d567cb"
|
sha256: "310af39c40dd0bb2058538333c9d9840a2725ae0b9f77e4fd09ad6696aa8f66e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.6"
|
version: "2.7.5"
|
||||||
sqlite3_flutter_libs:
|
sqlite3_flutter_libs:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: sqlite3_flutter_libs
|
name: sqlite3_flutter_libs
|
||||||
sha256: "62bbb4073edbcdf53f40c80775f33eea01d301b7b81417e5b3fb7395416258c1"
|
sha256: "1a96b59227828d9eb1463191d684b37a27d66ee5ed7597fcf42eee6452c88a14"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.24"
|
version: "0.5.32"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.1"
|
version: "1.12.1"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
|
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.4"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.4.1"
|
||||||
synchronized:
|
synchronized:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: synchronized
|
name: synchronized
|
||||||
sha256: a824e842b8a054f91a728b783c177c1e4731f6b124f9192468457a8913371255
|
sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.0"
|
version: "3.3.1"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: term_glyph
|
name: term_glyph
|
||||||
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
|
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.1"
|
version: "1.2.2"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.2"
|
version: "0.7.4"
|
||||||
timezone:
|
timezone:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: timezone
|
name: timezone
|
||||||
sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d"
|
sha256: ffc9d5f4d1193534ef051f9254063fa53d588609418c84299956c3db9383587d
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.9.4"
|
version: "0.10.0"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.4.0"
|
||||||
universal_io:
|
universal_io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -806,42 +854,42 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: url_launcher
|
name: url_launcher
|
||||||
sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
|
sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.3.0"
|
version: "6.3.1"
|
||||||
url_launcher_android:
|
url_launcher_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_android
|
name: url_launcher_android
|
||||||
sha256: e35a698ac302dd68e41f73250bd9517fe3ab5fa4f18fe4647a0872db61bacbab
|
sha256: "1d0eae19bd7606ef60fe69ef3b312a437a16549476c42321d5dc1506c9ca3bf4"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.3.10"
|
version: "6.3.15"
|
||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_ios
|
name: url_launcher_ios
|
||||||
sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e
|
sha256: "16a513b6c12bb419304e72ea0ae2ab4fed569920d1c7cb850263fe3acc824626"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.3.1"
|
version: "6.3.2"
|
||||||
url_launcher_linux:
|
url_launcher_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_linux
|
name: url_launcher_linux
|
||||||
sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af
|
sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.0"
|
version: "3.2.1"
|
||||||
url_launcher_macos:
|
url_launcher_macos:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_macos
|
name: url_launcher_macos
|
||||||
sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de"
|
sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.0"
|
version: "3.2.2"
|
||||||
url_launcher_platform_interface:
|
url_launcher_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -854,50 +902,50 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_web
|
name: url_launcher_web
|
||||||
sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
|
sha256: "3ba963161bd0fe395917ba881d320b9c4f6dd3c4a233da62ab18a5025c85f1e9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.3"
|
version: "2.4.0"
|
||||||
url_launcher_windows:
|
url_launcher_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_windows
|
name: url_launcher_windows
|
||||||
sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185"
|
sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.1.4"
|
||||||
uuid:
|
uuid:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: uuid
|
name: uuid
|
||||||
sha256: f33d6bb662f0e4f79dcd7ada2e6170f3b3a2530c28fc41f49a411ddedd576a77
|
sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.5.0"
|
version: "4.5.1"
|
||||||
vector_graphics:
|
vector_graphics:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_graphics
|
name: vector_graphics
|
||||||
sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3"
|
sha256: "44cc7104ff32563122a929e4620cf3efd584194eec6d1d913eb5ba593dbcf6de"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.11+1"
|
version: "1.1.18"
|
||||||
vector_graphics_codec:
|
vector_graphics_codec:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_graphics_codec
|
name: vector_graphics_codec
|
||||||
sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da
|
sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.11+1"
|
version: "1.1.13"
|
||||||
vector_graphics_compiler:
|
vector_graphics_compiler:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_graphics_compiler
|
name: vector_graphics_compiler
|
||||||
sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81"
|
sha256: "1b4b9e706a10294258727674a340ae0d6e64a7231980f9f9a3d12e4b42407aad"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.11+1"
|
version: "1.1.16"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -910,50 +958,50 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.2.5"
|
version: "14.3.1"
|
||||||
web:
|
web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web
|
name: web
|
||||||
sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062
|
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.1.1"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32
|
name: win32
|
||||||
sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a"
|
sha256: dc6ecaa00a7c708e5b4d10ee7bec8c270e9276dfcab1783f57e9962d7884305f
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.5.4"
|
version: "5.12.0"
|
||||||
win32_registry:
|
win32_registry:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32_registry
|
name: win32_registry
|
||||||
sha256: "723b7f851e5724c55409bb3d5a32b203b3afe8587eaf5dafb93a5fed8ecda0d6"
|
sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.4"
|
version: "2.1.0"
|
||||||
window_manager:
|
window_manager:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: window_manager
|
name: window_manager
|
||||||
sha256: ab8b2a7f97543d3db2b506c9d875e637149d48ee0c6a5cb5f5fd6e0dac463792
|
sha256: "732896e1416297c63c9e3fb95aea72d0355f61390263982a47fd519169dc5059"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.2"
|
version: "0.4.3"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
|
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.1.0"
|
||||||
xml:
|
xml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -966,10 +1014,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: yaml
|
name: yaml
|
||||||
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.1.3"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.5.0 <4.0.0"
|
dart: ">=3.7.0 <4.0.0"
|
||||||
flutter: ">=3.24.0"
|
flutter: ">=3.27.0"
|
||||||
|
|
14
pubspec.yaml
14
pubspec.yaml
|
@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 2.19.0+143
|
version: 2.20.4+151
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.18.1 <3.0.0'
|
sdk: '>=2.18.1 <3.0.0'
|
||||||
|
@ -42,13 +42,12 @@ dependencies:
|
||||||
provider: ^6.1.1
|
provider: ^6.1.1
|
||||||
sqflite: ^2.3.0
|
sqflite: ^2.3.0
|
||||||
package_info_plus: ^8.0.0
|
package_info_plus: ^8.0.0
|
||||||
flutter_displaymode: ^0.6.0
|
|
||||||
dynamic_color: ^1.7.0
|
dynamic_color: ^1.7.0
|
||||||
animations: ^2.0.10
|
animations: ^2.0.10
|
||||||
device_info_plus: ^10.1.0
|
device_info_plus: ^11.2.1
|
||||||
uuid: ^4.2.1
|
uuid: ^4.2.1
|
||||||
expandable: ^5.0.1
|
expandable: ^5.0.1
|
||||||
fl_chart: ^0.69.0
|
fl_chart: ^0.70.2
|
||||||
flutter_svg: ^2.0.9
|
flutter_svg: ^2.0.9
|
||||||
percent_indicator: ^4.2.3
|
percent_indicator: ^4.2.3
|
||||||
flutter_markdown: ^0.7.1
|
flutter_markdown: ^0.7.1
|
||||||
|
@ -65,12 +64,11 @@ dependencies:
|
||||||
pie_chart: ^5.4.0
|
pie_chart: ^5.4.0
|
||||||
segmented_button_slide: ^2.0.0
|
segmented_button_slide: ^2.0.0
|
||||||
http: ^1.1.2
|
http: ^1.1.2
|
||||||
timezone: ^0.9.2
|
timezone: ^0.10.0
|
||||||
flutter_custom_tabs: ^2.0.0+1
|
flutter_custom_tabs: ^2.0.0+1
|
||||||
url_launcher: ^6.2.4
|
url_launcher: ^6.2.4
|
||||||
shared_preferences: ^2.2.2
|
shared_preferences: ^2.2.2
|
||||||
window_manager: ^0.4.2
|
window_manager: ^0.4.2
|
||||||
install_referrer: ^1.2.1
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -81,8 +79,8 @@ dev_dependencies:
|
||||||
# activated in the `analysis_options.yaml` file located at the root of your
|
# activated in the `analysis_options.yaml` file located at the root of your
|
||||||
# package. See that file for information about deactivating specific lint
|
# package. See that file for information about deactivating specific lint
|
||||||
# rules and activating additional ones.
|
# rules and activating additional ones.
|
||||||
flutter_lints: ^4.0.0
|
flutter_lints: ^5.0.0
|
||||||
flutter_launcher_icons: ^0.13.1
|
flutter_launcher_icons: ^0.14.1
|
||||||
flutter_native_splash: ^2.3.8
|
flutter_native_splash: ^2.3.8
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
#include <dynamic_color/dynamic_color_plugin_c_api.h>
|
#include <dynamic_color/dynamic_color_plugin_c_api.h>
|
||||||
#include <screen_retriever/screen_retriever_plugin.h>
|
#include <screen_retriever_windows/screen_retriever_windows_plugin_c_api.h>
|
||||||
#include <sentry_flutter/sentry_flutter_plugin.h>
|
#include <sentry_flutter/sentry_flutter_plugin.h>
|
||||||
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
||||||
#include <url_launcher_windows/url_launcher_windows.h>
|
#include <url_launcher_windows/url_launcher_windows.h>
|
||||||
|
@ -16,8 +16,8 @@
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
DynamicColorPluginCApiRegisterWithRegistrar(
|
DynamicColorPluginCApiRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
|
registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
|
||||||
ScreenRetrieverPluginRegisterWithRegistrar(
|
ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
|
registry->GetRegistrarForPlugin("ScreenRetrieverWindowsPluginCApi"));
|
||||||
SentryFlutterPluginRegisterWithRegistrar(
|
SentryFlutterPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("SentryFlutterPlugin"));
|
registry->GetRegistrarForPlugin("SentryFlutterPlugin"));
|
||||||
Sqlite3FlutterLibsPluginRegisterWithRegistrar(
|
Sqlite3FlutterLibsPluginRegisterWithRegistrar(
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
dynamic_color
|
dynamic_color
|
||||||
screen_retriever
|
screen_retriever_windows
|
||||||
sentry_flutter
|
sentry_flutter
|
||||||
sqlite3_flutter_libs
|
sqlite3_flutter_libs
|
||||||
url_launcher_windows
|
url_launcher_windows
|
||||||
|
|
|
@ -41,7 +41,6 @@ Source: "..\build\windows\x64\runner\Release\{#MyAppExeName}"; DestDir: "{app}";
|
||||||
Source: "..\build\windows\x64\runner\Release\dynamic_color_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
|
Source: "..\build\windows\x64\runner\Release\dynamic_color_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "..\build\windows\x64\runner\Release\flutter_windows.dll"; DestDir: "{app}"; Flags: ignoreversion
|
Source: "..\build\windows\x64\runner\Release\flutter_windows.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "..\build\windows\x64\runner\Release\screen_retriever_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
|
Source: "..\build\windows\x64\runner\Release\screen_retriever_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "..\build\windows\x64\runner\Release\sentry_flutter_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
|
|
||||||
Source: "..\build\windows\x64\runner\Release\sqlite3.dll"; DestDir: "{app}"; Flags: ignoreversion
|
Source: "..\build\windows\x64\runner\Release\sqlite3.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "..\build\windows\x64\runner\Release\sqlite3_flutter_libs_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
|
Source: "..\build\windows\x64\runner\Release\sqlite3_flutter_libs_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "..\build\windows\x64\runner\Release\url_launcher_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
|
Source: "..\build\windows\x64\runner\Release\url_launcher_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
|
Loading…
Add table
Reference in a new issue