mirror of
https://github.com/JGeek00/adguard-home-manager.git
synced 2025-04-27 01:06:12 +00:00
Merge branch 'beta'
This commit is contained in:
commit
459e67363c
92 changed files with 4895 additions and 4757 deletions
102
.github/workflows/release-beta.yaml
vendored
Normal file
102
.github/workflows/release-beta.yaml
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
name: Compile and release beta build
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: "Version (beta)"
|
||||
required: true
|
||||
default: "1.0.0-beta.1"
|
||||
number:
|
||||
description: "Build number"
|
||||
required: true
|
||||
default: "1"
|
||||
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
|
||||
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: Update version in YAML
|
||||
run: sed -i 's/99.99.99+99/${{ github.event.inputs.version }}+${{ github.event.inputs.number }}/g' pubspec.yaml
|
||||
- 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_${{ github.event.inputs.version }}_Android.apk
|
||||
- name: Rename aab
|
||||
run: mv $ANDROID_AAB_RELEASE_PATH/app-release.aab $ANDROID_AAB_RELEASE_PATH/AdGuardHomeManager_${{ github.event.inputs.version }}_Android.aab
|
||||
- name: Copy apk to project root
|
||||
run: cp $ANDROID_APK_RELEASE_PATH/AdGuardHomeManager_${{ github.event.inputs.version }}_Android.apk AdGuardHomeManager_${{ github.event.inputs.version }}_Android.apk
|
||||
- name: Copy aab to project root
|
||||
run: cp $ANDROID_AAB_RELEASE_PATH/AdGuardHomeManager_${{ github.event.inputs.version }}_Android.aab AdGuardHomeManager_${{ github.event.inputs.version }}_Android.aab
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: android
|
||||
path: |
|
||||
AdGuardHomeManager_${{ github.event.inputs.version }}_Android.aab
|
||||
AdGuardHomeManager_${{ github.event.inputs.version }}_Android.apk
|
||||
release-builds-github:
|
||||
name: Release beta build to GitHub
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build-android]
|
||||
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: Release to GitHub
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
artifacts: "releases/*"
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
tag: '${{ github.event.inputs.version }}_(${{ github.event.inputs.number }})'
|
||||
name: v${{ github.event.inputs.version }}
|
||||
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]
|
||||
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_${{ github.event.inputs.version }}_Android.aab
|
||||
track: beta
|
||||
status: draft
|
||||
releaseName: ${{ github.event.inputs.version }}
|
|
@ -1,15 +1,11 @@
|
|||
// ignore_for_file: use_build_context_synchronously, depend_on_referenced_packages
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:animations/animations.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import 'package:store_checker/store_checker.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:adguard_home_manager/widgets/bottom_nav_bar.dart';
|
||||
|
@ -18,21 +14,14 @@ import 'package:adguard_home_manager/widgets/update_modal.dart';
|
|||
import 'package:adguard_home_manager/widgets/navigation_rail.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||
import 'package:adguard_home_manager/models/github_release.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/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/models/app_screen.dart';
|
||||
import 'package:adguard_home_manager/config/app_screens.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class Base extends StatefulWidget {
|
||||
final AppConfigProvider appConfigProvider;
|
||||
|
||||
const Base({
|
||||
Key? key,
|
||||
required this.appConfigProvider,
|
||||
}) : super(key: key);
|
||||
const Base({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<Base> createState() => _BaseState();
|
||||
|
@ -41,35 +30,6 @@ class Base extends StatefulWidget {
|
|||
class _BaseState extends State<Base> with WidgetsBindingObserver {
|
||||
int selectedScreen = 0;
|
||||
|
||||
Future<GitHubRelease?> checkInstallationSource() async {
|
||||
final result = await checkAppUpdatesGitHub();
|
||||
if (result['result'] == 'success') {
|
||||
final update = gitHubUpdateExists(widget.appConfigProvider.getAppInfo!.version, result['body'].tagName);
|
||||
if (update == true) {
|
||||
widget.appConfigProvider.setAppUpdatesAvailable(result['body']);
|
||||
if (Platform.isAndroid) {
|
||||
if (
|
||||
widget.appConfigProvider.installationSource == Source.IS_INSTALLED_FROM_LOCAL_SOURCE ||
|
||||
widget.appConfigProvider.installationSource == Source.IS_INSTALLED_FROM_PLAY_PACKAGE_INSTALLER ||
|
||||
widget.appConfigProvider.installationSource == Source.UNKNOWN
|
||||
) {
|
||||
return result['body'];
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (Platform.isIOS) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return result['body'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
|
@ -77,9 +37,15 @@ class _BaseState extends State<Base> with WidgetsBindingObserver {
|
|||
super.initState();
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
final result = await checkInstallationSource();
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context, listen: false);
|
||||
final result = await checkAppUpdates(
|
||||
currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber,
|
||||
installationSource: appConfigProvider.installationSource,
|
||||
setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable,
|
||||
isBeta: appConfigProvider.getAppInfo!.version.contains('beta'),
|
||||
);
|
||||
|
||||
if (result != null && widget.appConfigProvider.doNotRememberVersion != result.tagName) {
|
||||
if (result != null && appConfigProvider.doNotRememberVersion != result.tagName) {
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) => UpdateModal(
|
||||
|
|
|
@ -2,6 +2,6 @@ class Urls {
|
|||
static const String playStore = "https://play.google.com/store/apps/details?id=com.jgeek00.adguard_home_manager";
|
||||
static const String gitHub = "https://github.com/JGeek00/adguard-home-manager";
|
||||
static const String customRuleDocs = "https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters";
|
||||
static const String checkLatestReleaseUrl = "https://api.github.com/repos/JGeek00/adguard-home-manager/releases/latest";
|
||||
static const String getReleasesGitHub = "https://api.github.com/repos/JGeek00/adguard-home-manager/releases";
|
||||
static const String adGuardHomeReleasesTags = "https://api.github.com/repos/AdGuardTeam/AdGuardHome/releases/tags";
|
||||
}
|
|
@ -3,19 +3,23 @@ import 'dart:io';
|
|||
import 'package:adguard_home_manager/models/github_release.dart';
|
||||
|
||||
String? getAppUpdateDownloadLink(GitHubRelease gitHubRelease) {
|
||||
if (Platform.isAndroid) {
|
||||
return gitHubRelease.assets.firstWhere((item) => item.browserDownloadUrl.contains('apk')).browserDownloadUrl;
|
||||
}
|
||||
else if (Platform.isMacOS) {
|
||||
return gitHubRelease.assets.firstWhere((item) => item.browserDownloadUrl.contains('macOS')).browserDownloadUrl; // macOS package is a zip
|
||||
}
|
||||
else if (Platform.isWindows) {
|
||||
return gitHubRelease.assets.firstWhere((item) => item.browserDownloadUrl.contains('exe')).browserDownloadUrl;
|
||||
}
|
||||
else if (Platform.isLinux) {
|
||||
return gitHubRelease.assets.firstWhere((item) => item.browserDownloadUrl.contains('deb')).browserDownloadUrl;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
if (Platform.isAndroid) {
|
||||
return gitHubRelease.assets.firstWhere((item) => item.browserDownloadUrl.contains('apk')).browserDownloadUrl;
|
||||
}
|
||||
else if (Platform.isMacOS) {
|
||||
return gitHubRelease.assets.firstWhere((item) => item.browserDownloadUrl.contains('macOS')).browserDownloadUrl;
|
||||
}
|
||||
else if (Platform.isWindows) {
|
||||
return gitHubRelease.assets.firstWhere((item) => item.browserDownloadUrl.contains('exe')).browserDownloadUrl;
|
||||
}
|
||||
else if (Platform.isLinux) {
|
||||
return gitHubRelease.assets.firstWhere((item) => item.browserDownloadUrl.contains('deb')).browserDownloadUrl;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/models/filtering_status.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
|
||||
Future<Map<String, dynamic>> blockUnblock(BuildContext context, String domain, String newStatus) async {
|
||||
final serversProvider = Provider.of<ServersProvider>(context, listen: false);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context, listen: false);
|
||||
|
||||
final ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.savingUserFilters);
|
||||
|
||||
final rules = await getFilteringRules(server: serversProvider.selectedServer!);
|
||||
|
||||
if (rules['result'] == 'success') {
|
||||
FilteringStatus oldStatus = serversProvider.serverStatus.data!.filteringStatus;
|
||||
List<String> newRules = rules['data'].userRules.where((d) => !d.contains(domain)).toList();
|
||||
if (newStatus == 'block') {
|
||||
newRules.add("||$domain^");
|
||||
}
|
||||
else if (newStatus == 'unblock') {
|
||||
newRules.add("@@||$domain^");
|
||||
}
|
||||
FilteringStatus newObj = serversProvider.serverStatus.data!.filteringStatus;
|
||||
newObj.userRules = newRules;
|
||||
serversProvider.setFilteringStatus(newObj);
|
||||
|
||||
final result = await postFilteringRules(server: serversProvider.selectedServer!, data: {'rules': newRules});
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
return {
|
||||
'success': true,
|
||||
'message': AppLocalizations.of(context)!.userFilteringRulesUpdated
|
||||
};
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
serversProvider.setFilteringStatus(oldStatus);
|
||||
return {
|
||||
'success': false,
|
||||
'message': AppLocalizations.of(context)!.userFilteringRulesNotUpdated
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(rules['log']);
|
||||
return {
|
||||
'success': false,
|
||||
'message': AppLocalizations.of(context)!.userFilteringRulesNotUpdated
|
||||
};
|
||||
}
|
||||
}
|
55
lib/functions/check_app_updates.dart
Normal file
55
lib/functions/check_app_updates.dart
Normal file
|
@ -0,0 +1,55 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:store_checker/store_checker.dart';
|
||||
|
||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||
import 'package:adguard_home_manager/models/github_release.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
|
||||
Future<GitHubRelease?> checkAppUpdates({
|
||||
required String currentBuildNumber,
|
||||
required void Function(GitHubRelease?) setUpdateAvailable,
|
||||
required Source installationSource,
|
||||
required bool isBeta
|
||||
}) async {
|
||||
final result = await checkAppUpdatesGitHub();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
final update = gitHubUpdateExists(
|
||||
currentBuildNumber: currentBuildNumber,
|
||||
gitHubReleases: result['body'],
|
||||
isBeta: isBeta
|
||||
);
|
||||
|
||||
if (update == true) {
|
||||
final release = isBeta == true
|
||||
? result['body'].firstWhere((release) => release.prerelease == true)
|
||||
: result['body'].firstWhere((release) => release.prerelease == false);
|
||||
|
||||
setUpdateAvailable(release);
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
if (
|
||||
installationSource == Source.IS_INSTALLED_FROM_LOCAL_SOURCE ||
|
||||
installationSource == Source.IS_INSTALLED_FROM_PLAY_PACKAGE_INSTALLER ||
|
||||
installationSource == Source.UNKNOWN
|
||||
) {
|
||||
return release;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (Platform.isIOS) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return release;
|
||||
}
|
||||
}
|
||||
else {
|
||||
setUpdateAvailable(null);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
|
@ -5,15 +5,17 @@ import 'package:provider/provider.dart';
|
|||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/models/server.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
|
||||
Future<bool> clearDnsCache(BuildContext context, Server server) async {
|
||||
final serversProvider = Provider.of<ServersProvider>(context, listen: false);
|
||||
|
||||
final ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.clearingDnsCache);
|
||||
|
||||
final result = await resetDnsCache(server: server);
|
||||
final result = await serversProvider.apiClient!.resetDnsCache();
|
||||
|
||||
processModal.close();
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
import 'package:adguard_home_manager/models/github_release.dart';
|
||||
|
||||
bool compareVersions({
|
||||
required String currentVersion,
|
||||
required String newVersion
|
||||
|
@ -147,20 +149,36 @@ bool serverVersionIsAhead({
|
|||
}
|
||||
}
|
||||
|
||||
bool gitHubUpdateExists(String appVersion, String gitHubVersion) {
|
||||
final List<int> appVersionSplit = List<int>.from(appVersion.split('.').map((e) => int.parse(e)));
|
||||
final List<int> gitHubVersionSplit = List<int>.from(gitHubVersion.split('.').map((e) => int.parse(e)));
|
||||
bool gitHubUpdateExists({
|
||||
required String currentBuildNumber,
|
||||
required List<GitHubRelease> gitHubReleases,
|
||||
required bool isBeta
|
||||
}) {
|
||||
final release = isBeta == true
|
||||
? gitHubReleases.firstWhere((release) => release.prerelease == true)
|
||||
: gitHubReleases.firstWhere((release) => release.prerelease == false);
|
||||
|
||||
final versionNumberRegex = RegExp(r'\(\d+\)');
|
||||
final releaseNumberExtracted = versionNumberRegex.allMatches(release.tagName).first.group(0);
|
||||
|
||||
if (gitHubVersionSplit[0] > appVersionSplit[0]) {
|
||||
return true;
|
||||
}
|
||||
else if (gitHubVersionSplit[0] == appVersionSplit[0] && gitHubVersionSplit[1] > appVersionSplit[1]) {
|
||||
return true;
|
||||
}
|
||||
else if (gitHubVersionSplit[0] == appVersionSplit[0] && gitHubVersionSplit[1] == appVersionSplit[1] && gitHubVersionSplit[2] > appVersionSplit[2]) {
|
||||
return true;
|
||||
if (releaseNumberExtracted != null) {
|
||||
final releaseNumber = releaseNumberExtracted.replaceAll(RegExp(r'\(|\)'), '');
|
||||
try {
|
||||
final newReleaseParsed = int.parse(releaseNumber);
|
||||
final currentReleaseParsed = int.parse(currentBuildNumber);
|
||||
if (newReleaseParsed > currentReleaseParsed) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
Sentry.captureMessage("Invalid release number. Current release: $currentBuildNumber. New release: $releaseNumber");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Sentry.captureMessage("Invalid release number. Tagname: ${release.tagName}");
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -13,4 +13,17 @@ String convertTimestampLocalTimezone(DateTime timestamp, String format) {
|
|||
String formatTimeOfDay(TimeOfDay timestamp, String format) {
|
||||
DateFormat f = DateFormat(format);
|
||||
return f.format(DateTime(0, 0, 0, timestamp.hour, timestamp.minute));
|
||||
}
|
||||
|
||||
String formatRemainingSeconds(int seconds) {
|
||||
int h, m, s;
|
||||
h = seconds ~/ 3600;
|
||||
m = ((seconds - h * 3600)) ~/ 60;
|
||||
s = seconds - (h * 3600) - (m * 60);
|
||||
|
||||
String hourLeft = h.toString().length < 2 ? "0$h" : h.toString();
|
||||
String minuteLeft = m.toString().length < 2 ? "0$m" : m.toString();
|
||||
String secondsLeft = s.toString().length < 2 ? "0$s" : s.toString();
|
||||
|
||||
return "$hourLeft:$minuteLeft:$secondsLeft";
|
||||
}
|
|
@ -628,5 +628,7 @@
|
|||
"application": "Application",
|
||||
"combinedChart": "Combined chart",
|
||||
"combinedChartDescription": "Combine all charts into one",
|
||||
"statistics": "Statistics"
|
||||
"statistics": "Statistics",
|
||||
"errorLoadFilters": "Error when loading filters.",
|
||||
"clientRemovedSuccessfully": "Client removed successfully."
|
||||
}
|
|
@ -628,5 +628,7 @@
|
|||
"application": "Aplicación",
|
||||
"combinedChart": "Gráfico combinado",
|
||||
"combinedChartDescription": "Combina todos los gráficos en uno solo",
|
||||
"statistics": "Estadísticas"
|
||||
"statistics": "Estadísticas",
|
||||
"errorLoadFilters": "Error al cargar los filtros.",
|
||||
"clientRemovedSuccessfully": "Cliente eliminado correctamente."
|
||||
}
|
146
lib/main.dart
146
lib/main.dart
|
@ -17,15 +17,20 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
|
||||
import 'package:adguard_home_manager/base.dart';
|
||||
|
||||
import 'package:adguard_home_manager/classes/http_override.dart';
|
||||
import 'package:adguard_home_manager/services/db/database.dart';
|
||||
import 'package:adguard_home_manager/constants/colors.dart';
|
||||
import 'package:adguard_home_manager/config/globals.dart';
|
||||
import 'package:adguard_home_manager/providers/logs_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/config/theme.dart';
|
||||
import 'package:adguard_home_manager/providers/clients_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/dns_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/filtering_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/rewrite_rules_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/dhcp_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
import 'package:adguard_home_manager/constants/colors.dart';
|
||||
import 'package:adguard_home_manager/config/globals.dart';
|
||||
import 'package:adguard_home_manager/config/theme.dart';
|
||||
import 'package:adguard_home_manager/classes/http_override.dart';
|
||||
import 'package:adguard_home_manager/services/db/database.dart';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
@ -41,9 +46,15 @@ void main() async {
|
|||
|
||||
await dotenv.load(fileName: '.env');
|
||||
|
||||
AppConfigProvider appConfigProvider = AppConfigProvider();
|
||||
ServersProvider serversProvider = ServersProvider();
|
||||
LogsProvider logsProvider = LogsProvider();
|
||||
final AppConfigProvider appConfigProvider = AppConfigProvider();
|
||||
final ServersProvider serversProvider = ServersProvider();
|
||||
final StatusProvider statusProvider = StatusProvider();
|
||||
final ClientsProvider clientsProvider = ClientsProvider();
|
||||
final FilteringProvider filtersProvider = FilteringProvider();
|
||||
final DhcpProvider dhcpProvider = DhcpProvider();
|
||||
final RewriteRulesProvider rewriteRulesProvider = RewriteRulesProvider();
|
||||
final DnsProvider dnsProvider = DnsProvider();
|
||||
final LogsProvider logsProvider = LogsProvider();
|
||||
|
||||
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
|
||||
if (Platform.isAndroid) {
|
||||
|
@ -73,6 +84,69 @@ void main() async {
|
|||
PackageInfo appInfo = await PackageInfo.fromPlatform();
|
||||
appConfigProvider.setAppInfo(appInfo);
|
||||
|
||||
void startApp() => runApp(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => serversProvider)
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => appConfigProvider)
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => statusProvider)
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => clientsProvider)
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => logsProvider)
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => filtersProvider)
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => dhcpProvider)
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => rewriteRulesProvider)
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => dnsProvider)
|
||||
),
|
||||
ChangeNotifierProxyProvider2<ServersProvider, StatusProvider, ClientsProvider>(
|
||||
create: (context) => clientsProvider,
|
||||
update: (context, servers, status, clients) => clients!..update(servers, status),
|
||||
),
|
||||
ChangeNotifierProxyProvider2<ServersProvider, StatusProvider, FilteringProvider>(
|
||||
create: (context) => filtersProvider,
|
||||
update: (context, servers, status, filtering) => filtering!..update(servers, status),
|
||||
),
|
||||
ChangeNotifierProxyProvider<ServersProvider, StatusProvider>(
|
||||
create: (context) => statusProvider,
|
||||
update: (context, servers, status) => status!..update(servers),
|
||||
),
|
||||
ChangeNotifierProxyProvider<ServersProvider, LogsProvider>(
|
||||
create: (context) => logsProvider,
|
||||
update: (context, servers, logs) => logs!..update(servers),
|
||||
),
|
||||
ChangeNotifierProxyProvider<ServersProvider, DhcpProvider>(
|
||||
create: (context) => dhcpProvider,
|
||||
update: (context, servers, dhcp) => dhcp!..update(servers),
|
||||
),
|
||||
ChangeNotifierProxyProvider<ServersProvider, RewriteRulesProvider>(
|
||||
create: (context) => rewriteRulesProvider,
|
||||
update: (context, servers, rewrite) => rewrite!..update(servers),
|
||||
),
|
||||
ChangeNotifierProxyProvider<ServersProvider, DnsProvider>(
|
||||
create: (context) => dnsProvider,
|
||||
update: (context, servers, dns) => dns!..update(servers),
|
||||
),
|
||||
],
|
||||
child: const Main(),
|
||||
)
|
||||
);
|
||||
|
||||
if (
|
||||
(
|
||||
kReleaseMode &&
|
||||
|
@ -87,41 +161,11 @@ void main() async {
|
|||
options.dsn = dotenv.env['SENTRY_DSN'];
|
||||
options.sendDefaultPii = false;
|
||||
},
|
||||
appRunner: () => runApp(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => serversProvider)
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => appConfigProvider)
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => logsProvider)
|
||||
),
|
||||
],
|
||||
child: const Main(),
|
||||
)
|
||||
)
|
||||
appRunner: () => startApp()
|
||||
);
|
||||
}
|
||||
else {
|
||||
runApp(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => serversProvider)
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => appConfigProvider)
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: ((context) => logsProvider)
|
||||
),
|
||||
],
|
||||
child: const Main(),
|
||||
)
|
||||
);
|
||||
startApp();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,15 +207,15 @@ class _MainState extends State<Main> {
|
|||
builder: (lightDynamic, darkDynamic) => MaterialApp(
|
||||
title: 'AdGuard Home Manager',
|
||||
theme: appConfigProvider.androidDeviceInfo != null && appConfigProvider.androidDeviceInfo!.version.sdkInt >= 31
|
||||
? appConfigProvider.useDynamicColor == true
|
||||
? lightTheme(lightDynamic)
|
||||
: lightThemeOldVersions(colors[appConfigProvider.staticColor])
|
||||
: lightThemeOldVersions(colors[appConfigProvider.staticColor]),
|
||||
darkTheme: appConfigProvider.androidDeviceInfo != null && appConfigProvider.androidDeviceInfo!.version.sdkInt >= 31
|
||||
? appConfigProvider.useDynamicColor == true
|
||||
? darkTheme(darkDynamic)
|
||||
: darkThemeOldVersions(colors[appConfigProvider.staticColor])
|
||||
: darkThemeOldVersions(colors[appConfigProvider.staticColor]),
|
||||
? appConfigProvider.useDynamicColor == true
|
||||
? lightTheme(lightDynamic)
|
||||
: lightThemeOldVersions(colors[appConfigProvider.staticColor])
|
||||
: lightThemeOldVersions(colors[appConfigProvider.staticColor]),
|
||||
darkTheme: appConfigProvider.androidDeviceInfo != null && appConfigProvider.androidDeviceInfo!.version.sdkInt >= 31
|
||||
? appConfigProvider.useDynamicColor == true
|
||||
? darkTheme(darkDynamic)
|
||||
: darkThemeOldVersions(colors[appConfigProvider.staticColor])
|
||||
: darkThemeOldVersions(colors[appConfigProvider.staticColor]),
|
||||
themeMode: appConfigProvider.selectedTheme,
|
||||
debugShowCheckedModeBanner: false,
|
||||
localizationsDelegates: const [
|
||||
|
@ -195,7 +239,7 @@ class _MainState extends State<Main> {
|
|||
child: child!,
|
||||
);
|
||||
},
|
||||
home: Base(appConfigProvider: appConfigProvider),
|
||||
home: const Base(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,12 +11,10 @@ class BlockedServicesFromApi {
|
|||
}
|
||||
|
||||
class BlockedServices {
|
||||
int loadStatus = 0;
|
||||
List<BlockedService>? services;
|
||||
List<BlockedService> services;
|
||||
|
||||
BlockedServices({
|
||||
this.loadStatus = 0,
|
||||
this.services
|
||||
required this.services
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,45 +1,28 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/models/clients_allowed_blocked.dart';
|
||||
import 'package:adguard_home_manager/models/safe_search.dart';
|
||||
|
||||
class Clients {
|
||||
LoadStatus loadStatus;
|
||||
ClientsData? data;
|
||||
|
||||
Clients({
|
||||
required this.loadStatus,
|
||||
this.data
|
||||
});
|
||||
}
|
||||
|
||||
ClientsData clientsFromJson(String str) => ClientsData.fromJson(json.decode(str));
|
||||
|
||||
String clientsToJson(ClientsData data) => json.encode(data.toJson());
|
||||
|
||||
class ClientsData {
|
||||
List<Client> clients;
|
||||
final List<AutoClient> autoClientsData;
|
||||
final List<AutoClient> autoClients;
|
||||
final List<String> supportedTags;
|
||||
ClientsAllowedBlocked? clientsAllowedBlocked;
|
||||
|
||||
ClientsData({
|
||||
Clients({
|
||||
required this.clients,
|
||||
required this.autoClientsData,
|
||||
required this.autoClients,
|
||||
required this.supportedTags,
|
||||
this.clientsAllowedBlocked
|
||||
});
|
||||
|
||||
factory ClientsData.fromJson(Map<String, dynamic> json) => ClientsData(
|
||||
factory Clients.fromJson(Map<String, dynamic> json) => Clients(
|
||||
clients: json["clients"] != null ? List<Client>.from(json["clients"].map((x) => Client.fromJson(x))) : [],
|
||||
autoClientsData: json["auto_clients"] != null ? List<AutoClient>.from(json["auto_clients"].map((x) => AutoClient.fromJson(x))) : [],
|
||||
autoClients: json["auto_clients"] != null ? List<AutoClient>.from(json["auto_clients"].map((x) => AutoClient.fromJson(x))) : [],
|
||||
supportedTags: json["supported_tags"] != null ? List<String>.from(json["supported_tags"].map((x) => x)) : [],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"clients": List<dynamic>.from(clients.map((x) => x.toJson())),
|
||||
"auto_clients": List<dynamic>.from(autoClientsData.map((x) => x.toJson())),
|
||||
"auto_clients": List<dynamic>.from(autoClients.map((x) => x.toJson())),
|
||||
"supported_tags": List<dynamic>.from(supportedTags.map((x) => x)),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,20 +1,9 @@
|
|||
import 'dart:convert';
|
||||
|
||||
class DhcpModel {
|
||||
int loadStatus = 0;
|
||||
DhcpData? data;
|
||||
|
||||
DhcpModel({
|
||||
required this.loadStatus,
|
||||
this.data,
|
||||
});
|
||||
}
|
||||
|
||||
class DhcpData {
|
||||
List<NetworkInterface> networkInterfaces;
|
||||
DhcpStatus dhcpStatus;
|
||||
|
||||
DhcpData({
|
||||
DhcpModel({
|
||||
required this.networkInterfaces,
|
||||
required this.dhcpStatus,
|
||||
});
|
||||
|
|
|
@ -1,20 +1,4 @@
|
|||
import 'dart:convert';
|
||||
|
||||
class DnsInfo {
|
||||
int loadStatus = 0;
|
||||
DnsInfoData? data;
|
||||
|
||||
DnsInfo({
|
||||
required this.loadStatus,
|
||||
this.data
|
||||
});
|
||||
}
|
||||
|
||||
DnsInfoData dnsInfoDataFromJson(String str) => DnsInfoData.fromJson(json.decode(str));
|
||||
|
||||
String dnsInfoDataToJson(DnsInfoData data) => json.encode(data.toJson());
|
||||
|
||||
class DnsInfoData {
|
||||
List<String> upstreamDns;
|
||||
String upstreamDnsFile;
|
||||
List<String> bootstrapDns;
|
||||
|
@ -34,9 +18,9 @@ class DnsInfoData {
|
|||
List<String> localPtrUpstreams;
|
||||
String blockingIpv4;
|
||||
String blockingIpv6;
|
||||
|
||||
List<String> defaultLocalPtrUpstreams;
|
||||
DnsInfoData({
|
||||
|
||||
DnsInfo({
|
||||
required this.upstreamDns,
|
||||
required this.upstreamDnsFile,
|
||||
required this.bootstrapDns,
|
||||
|
@ -59,7 +43,7 @@ class DnsInfoData {
|
|||
required this.defaultLocalPtrUpstreams,
|
||||
});
|
||||
|
||||
factory DnsInfoData.fromJson(Map<String, dynamic> json) => DnsInfoData(
|
||||
factory DnsInfo.fromJson(Map<String, dynamic> json) => DnsInfo(
|
||||
upstreamDns: json["upstream_dns"] != null ? List<String>.from(json["upstream_dns"].map((x) => x)) : [],
|
||||
upstreamDnsFile: json["upstream_dns_file"],
|
||||
bootstrapDns: List<String>.from(json["bootstrap_dns"].map((x) => x)),
|
||||
|
|
|
@ -1,22 +1,4 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
|
||||
FilteringData filteringFromJson(String str) => FilteringData.fromJson(json.decode(str));
|
||||
|
||||
String filteringToJson(FilteringData data) => json.encode(data.toJson());
|
||||
|
||||
class Filtering {
|
||||
LoadStatus loadStatus = LoadStatus.loading;
|
||||
FilteringData? data;
|
||||
|
||||
Filtering({
|
||||
required this.loadStatus,
|
||||
this.data
|
||||
});
|
||||
}
|
||||
|
||||
class FilteringData {
|
||||
final List<Filter> filters;
|
||||
final List<Filter> whitelistFilters;
|
||||
List<String> userRules;
|
||||
|
@ -24,7 +6,7 @@ class FilteringData {
|
|||
int interval;
|
||||
bool enabled;
|
||||
|
||||
FilteringData({
|
||||
Filtering({
|
||||
required this.filters,
|
||||
required this.whitelistFilters,
|
||||
required this.userRules,
|
||||
|
@ -33,7 +15,7 @@ class FilteringData {
|
|||
required this.enabled,
|
||||
});
|
||||
|
||||
factory FilteringData.fromJson(Map<String, dynamic> json) => FilteringData(
|
||||
factory Filtering.fromJson(Map<String, dynamic> json) => Filtering(
|
||||
filters: json["filters"] != null ? List<Filter>.from(json["filters"].map((x) => Filter.fromJson(x))) : [],
|
||||
whitelistFilters: json["whitelist_filters"] != null ? List<Filter>.from(json["whitelist_filters"].map((x) => Filter.fromJson(x))) : [],
|
||||
userRules: json["user_rules"] != null ? List<String>.from(json["user_rules"].map((x) => x)).where((i) => i != '').toList() : [],
|
||||
|
|
|
@ -1,29 +1,13 @@
|
|||
import 'dart:convert';
|
||||
|
||||
class RewriteRules {
|
||||
int loadStatus = 0;
|
||||
List<RewriteRulesData>? data;
|
||||
|
||||
RewriteRules({
|
||||
required this.loadStatus,
|
||||
this.data
|
||||
});
|
||||
}
|
||||
|
||||
List<RewriteRulesData> rewriteRulesDataFromJson(String str) => List<RewriteRulesData>.from(json.decode(str).map((x) => RewriteRulesData.fromJson(x)));
|
||||
|
||||
String rewriteRulesDataToJson(List<RewriteRulesData> data) => json.encode(List<RewriteRulesData>.from(data.map((x) => x.toJson())));
|
||||
|
||||
class RewriteRulesData {
|
||||
final String domain;
|
||||
final String answer;
|
||||
|
||||
RewriteRulesData({
|
||||
RewriteRules({
|
||||
required this.domain,
|
||||
required this.answer,
|
||||
});
|
||||
|
||||
factory RewriteRulesData.fromJson(Map<String, dynamic> json) => RewriteRulesData(
|
||||
factory RewriteRules.fromJson(Map<String, dynamic> json) => RewriteRules(
|
||||
domain: json["domain"],
|
||||
answer: json["answer"],
|
||||
);
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
|
||||
class ServerInfo {
|
||||
int loadStatus = 0;
|
||||
LoadStatus loadStatus = LoadStatus.loading;
|
||||
ServerInfoData? data;
|
||||
|
||||
ServerInfo({
|
||||
|
|
|
@ -4,15 +4,6 @@ import 'package:adguard_home_manager/models/dns_statistics.dart';
|
|||
import 'package:adguard_home_manager/models/filtering_status.dart';
|
||||
|
||||
class ServerStatus {
|
||||
int loadStatus;
|
||||
ServerStatusData? data;
|
||||
|
||||
ServerStatus({
|
||||
required this.loadStatus,
|
||||
this.data
|
||||
});
|
||||
}
|
||||
class ServerStatusData {
|
||||
final DnsStatistics stats;
|
||||
final List<Client> clients;
|
||||
final FilteringStatus filteringStatus;
|
||||
|
@ -31,7 +22,7 @@ class ServerStatusData {
|
|||
bool? safeSearchYandex;
|
||||
bool? safeSearchYoutube;
|
||||
|
||||
ServerStatusData({
|
||||
ServerStatus({
|
||||
required this.stats,
|
||||
required this.clients,
|
||||
required this.filteringStatus,
|
||||
|
@ -51,7 +42,7 @@ class ServerStatusData {
|
|||
required this.safeSearchYoutube
|
||||
});
|
||||
|
||||
factory ServerStatusData.fromJson(Map<String, dynamic> json) => ServerStatusData(
|
||||
factory ServerStatus.fromJson(Map<String, dynamic> json) => ServerStatus(
|
||||
stats: DnsStatistics.fromJson(json['stats']),
|
||||
clients: json["clients"] != null ? List<Client>.from(json["clients"].map((x) => Client.fromJson(x))) : [],
|
||||
generalEnabled: json['status']['protection_enabled'],
|
||||
|
|
|
@ -199,7 +199,7 @@ class AppConfigProvider with ChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
void setAppUpdatesAvailable(GitHubRelease value) {
|
||||
void setAppUpdatesAvailable(GitHubRelease? value) {
|
||||
_appUpdatesAvailable = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
|
285
lib/providers/clients_provider.dart
Normal file
285
lib/providers/clients_provider.dart
Normal file
|
@ -0,0 +1,285 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:adguard_home_manager/models/clients.dart';
|
||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||
import 'package:adguard_home_manager/functions/maps_fns.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/models/clients_allowed_blocked.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
|
||||
class ClientsProvider with ChangeNotifier {
|
||||
ServersProvider? _serversProvider;
|
||||
StatusProvider? _statusProvider;
|
||||
|
||||
update(ServersProvider? servers, StatusProvider? status) {
|
||||
_serversProvider = servers;
|
||||
_statusProvider = status;
|
||||
}
|
||||
|
||||
LoadStatus _loadStatus = LoadStatus.loading;
|
||||
Clients? _clients;
|
||||
String? _searchTermClients;
|
||||
List<AutoClient> _filteredActiveClients = [];
|
||||
List<Client> _filteredAddedClients = [];
|
||||
|
||||
LoadStatus get loadStatus {
|
||||
return _loadStatus;
|
||||
}
|
||||
|
||||
Clients? get clients {
|
||||
return _clients;
|
||||
}
|
||||
|
||||
String? get searchTermClients {
|
||||
return _searchTermClients;
|
||||
}
|
||||
|
||||
List<AutoClient> get filteredActiveClients {
|
||||
return _filteredActiveClients;
|
||||
}
|
||||
|
||||
List<Client> get filteredAddedClients {
|
||||
return _filteredAddedClients;
|
||||
}
|
||||
|
||||
void setClientsLoadStatus(LoadStatus status, bool notify) {
|
||||
_loadStatus = status;
|
||||
if (notify == true) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void setClientsData(Clients data, bool notify) {
|
||||
_clients = data;
|
||||
if (_searchTermClients != null && _searchTermClients != '') {
|
||||
_filteredActiveClients = _clients!.autoClients.where(
|
||||
(client) => client.ip.contains(_searchTermClients!.toLowerCase()) || (client.name != null ? client.name!.contains(_searchTermClients!.toLowerCase()) : false)
|
||||
).toList();
|
||||
_filteredAddedClients = _clients!.clients.where(
|
||||
(client) {
|
||||
isContained(String value) => value.contains(value.toLowerCase());
|
||||
return client.ids.any(isContained);
|
||||
}
|
||||
).toList();
|
||||
}
|
||||
else {
|
||||
_filteredActiveClients = data.autoClients;
|
||||
_filteredAddedClients = data.clients;
|
||||
}
|
||||
if (notify == true) notifyListeners();
|
||||
}
|
||||
|
||||
void setSearchTermClients(String? value) {
|
||||
_searchTermClients = value;
|
||||
if (value != null && value != '') {
|
||||
if (_clients != null) {
|
||||
_filteredActiveClients = _clients!.autoClients.where(
|
||||
(client) => client.ip.contains(value.toLowerCase()) || (client.name != null ? client.name!.contains(value.toLowerCase()) : false)
|
||||
).toList();
|
||||
_filteredAddedClients = _clients!.clients.where(
|
||||
(client) {
|
||||
isContained(String value) => value.contains(value.toLowerCase());
|
||||
return client.ids.any(isContained);
|
||||
}
|
||||
).toList();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (_clients != null) _filteredActiveClients = _clients!.autoClients;
|
||||
if (_clients != null) _filteredAddedClients = _clients!.clients;
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setAllowedDisallowedClientsBlockedDomains(ClientsAllowedBlocked data) {
|
||||
_clients?.clientsAllowedBlocked = data;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<bool> fetchClients({
|
||||
bool? updateLoading
|
||||
}) async {
|
||||
if (updateLoading == true) {
|
||||
_loadStatus = LoadStatus.loading;
|
||||
}
|
||||
final result = await _serversProvider!.apiClient!.getClients();
|
||||
if (result['result'] == 'success') {
|
||||
setClientsData(result['data'], false);
|
||||
_loadStatus = LoadStatus.loaded;
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (updateLoading == true) {
|
||||
_loadStatus = LoadStatus.error;
|
||||
notifyListeners();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> deleteClient(Client client) async {
|
||||
final result = await _serversProvider!.apiClient!.postDeleteClient(name: client.name);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
Clients clientsData = clients!;
|
||||
clientsData.clients = clientsData.clients.where((c) => c.name != client.name).toList();
|
||||
setClientsData(clientsData, false);
|
||||
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> editClient(Client client) async {
|
||||
final result = await _serversProvider!.apiClient!.postUpdateClient(
|
||||
data: {
|
||||
'name': client.name,
|
||||
'data': serverVersionIsAhead(
|
||||
currentVersion: _statusProvider!.serverStatus!.serverVersion,
|
||||
referenceVersion: 'v0.107.28',
|
||||
referenceVersionBeta: 'v0.108.0-b.33'
|
||||
) == false
|
||||
? removePropFromMap(client.toJson(), 'safesearch_enabled')
|
||||
: removePropFromMap(client.toJson(), 'safe_search')
|
||||
}
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
Clients clientsData = clients!;
|
||||
clientsData.clients = clientsData.clients.map((e) {
|
||||
if (e.name == client.name) {
|
||||
return client;
|
||||
}
|
||||
else {
|
||||
return e;
|
||||
}
|
||||
}).toList();
|
||||
setClientsData(clientsData, false);
|
||||
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> addClient(Client client) async {
|
||||
final result = await _serversProvider!.apiClient!.postAddClient(
|
||||
data: serverVersionIsAhead(
|
||||
currentVersion: _statusProvider!.serverStatus!.serverVersion,
|
||||
referenceVersion: 'v0.107.28',
|
||||
referenceVersionBeta: 'v0.108.0-b.33'
|
||||
) == false
|
||||
? removePropFromMap(client.toJson(), 'safesearch_enabled')
|
||||
: removePropFromMap(client.toJson(), 'safe_search')
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
Clients clientsData = clients!;
|
||||
clientsData.clients.add(client);
|
||||
setClientsData(clientsData, false);
|
||||
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> addClientList(String item, String type) async {
|
||||
Map<String, List<String>> body = {
|
||||
"allowed_clients": clients!.clientsAllowedBlocked?.allowedClients ?? [],
|
||||
"disallowed_clients": clients!.clientsAllowedBlocked?.disallowedClients ?? [],
|
||||
"blocked_hosts": clients!.clientsAllowedBlocked?.blockedHosts ?? [],
|
||||
};
|
||||
|
||||
if (type == 'allowed') {
|
||||
body['allowed_clients']!.add(item);
|
||||
}
|
||||
else if (type == 'disallowed') {
|
||||
body['disallowed_clients']!.add(item);
|
||||
}
|
||||
else if (type == 'domains') {
|
||||
body['blocked_hosts']!.add(item);
|
||||
}
|
||||
|
||||
final result = await _serversProvider!.apiClient!.requestAllowedBlockedClientsHosts(body);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_clients?.clientsAllowedBlocked = ClientsAllowedBlocked(
|
||||
allowedClients: body['allowed_clients'] ?? [],
|
||||
disallowedClients: body['disallowed_clients'] ?? [],
|
||||
blockedHosts: body['blocked_hosts'] ?? [],
|
||||
);
|
||||
notifyListeners();
|
||||
return { 'success': true };
|
||||
}
|
||||
else if (result['result'] == 'error' && result['message'] == 'client_another_list') {
|
||||
notifyListeners();
|
||||
return {
|
||||
'success': false,
|
||||
'error': 'client_another_list'
|
||||
};
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return {
|
||||
'success': false,
|
||||
'error': null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> removeClientList(String client, String type) async {
|
||||
Map<String, List<String>> body = {
|
||||
"allowed_clients": clients!.clientsAllowedBlocked?.allowedClients ?? [],
|
||||
"disallowed_clients": clients!.clientsAllowedBlocked?.disallowedClients ?? [],
|
||||
"blocked_hosts": clients!.clientsAllowedBlocked?.blockedHosts ?? [],
|
||||
};
|
||||
|
||||
if (type == 'allowed') {
|
||||
body['allowed_clients'] = body['allowed_clients']!.where((c) => c != client).toList();
|
||||
}
|
||||
else if (type == 'disallowed') {
|
||||
body['disallowed_clients'] = body['disallowed_clients']!.where((c) => c != client).toList();
|
||||
}
|
||||
else if (type == 'domains') {
|
||||
body['blocked_hosts'] = body['blocked_hosts']!.where((c) => c != client).toList();
|
||||
}
|
||||
|
||||
final result = await _serversProvider!.apiClient!.requestAllowedBlockedClientsHosts(body);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_clients?.clientsAllowedBlocked = ClientsAllowedBlocked(
|
||||
allowedClients: body['allowed_clients'] ?? [],
|
||||
disallowedClients: body['disallowed_clients'] ?? [],
|
||||
blockedHosts: body['blocked_hosts'] ?? [],
|
||||
);
|
||||
notifyListeners();
|
||||
return { 'success': true };
|
||||
}
|
||||
else if (result['result'] == 'error' && result['message'] == 'client_another_list') {
|
||||
notifyListeners();
|
||||
return {
|
||||
'success': false,
|
||||
'error': 'client_another_list'
|
||||
};
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return {
|
||||
'success': false,
|
||||
'error': null
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
115
lib/providers/dhcp_provider.dart
Normal file
115
lib/providers/dhcp_provider.dart
Normal file
|
@ -0,0 +1,115 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/models/dhcp.dart';
|
||||
|
||||
class DhcpProvider with ChangeNotifier {
|
||||
ServersProvider? _serversProvider;
|
||||
|
||||
update(ServersProvider? provider) {
|
||||
_serversProvider = provider;
|
||||
}
|
||||
|
||||
LoadStatus _loadStatus = LoadStatus.loading;
|
||||
DhcpModel? _dhcp;
|
||||
|
||||
DhcpModel? get dhcp {
|
||||
return _dhcp;
|
||||
}
|
||||
|
||||
LoadStatus get loadStatus {
|
||||
return _loadStatus;
|
||||
}
|
||||
|
||||
void setDhcpData(DhcpModel data) {
|
||||
_dhcp = data;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setDhcpLoadStatus(LoadStatus status, bool notify) {
|
||||
_loadStatus = status;
|
||||
if (notify == true) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> loadDhcpStatus({
|
||||
bool? showLoading
|
||||
}) async {
|
||||
if (showLoading == true) {
|
||||
_loadStatus = LoadStatus.loading;
|
||||
notifyListeners();
|
||||
}
|
||||
final result = await _serversProvider!.apiClient!.getDhcpData();
|
||||
if (result['result'] == 'success') {
|
||||
_dhcp = result['data'];
|
||||
_loadStatus = LoadStatus.loaded;
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (showLoading == true) {
|
||||
_loadStatus = LoadStatus.error;
|
||||
notifyListeners();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> deleteLease(Lease lease) async {
|
||||
final result = await _serversProvider!.apiClient!.deleteStaticLease(
|
||||
data: {
|
||||
"mac": lease.mac,
|
||||
"ip": lease.ip,
|
||||
"hostname": lease.hostname
|
||||
}
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DhcpModel data = dhcp!;
|
||||
data.dhcpStatus.staticLeases = data.dhcpStatus.staticLeases.where((l) => l.mac != lease.mac).toList();
|
||||
setDhcpData(data);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> createLease(Lease lease) async {
|
||||
final result = await _serversProvider!.apiClient!.createStaticLease(
|
||||
data: {
|
||||
"mac": lease.mac,
|
||||
"ip": lease.ip,
|
||||
"hostname": lease.hostname,
|
||||
}
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DhcpModel data = dhcp!;
|
||||
data.dhcpStatus.staticLeases.add(lease);
|
||||
setDhcpData(data);
|
||||
return { 'success': true };
|
||||
}
|
||||
else if (result['result'] == 'error' && result['message'] == 'already_exists' ) {
|
||||
return {
|
||||
'success': false,
|
||||
'error': 'already_exists'
|
||||
};
|
||||
}
|
||||
else if (result['result'] == 'error' && result['message'] == 'server_not_configured' ) {
|
||||
return {
|
||||
'success': false,
|
||||
'error': 'server_not_configured'
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
'success': false,
|
||||
'error': null
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
199
lib/providers/dns_provider.dart
Normal file
199
lib/providers/dns_provider.dart
Normal file
|
@ -0,0 +1,199 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/models/dns_info.dart';
|
||||
|
||||
class DnsProvider with ChangeNotifier {
|
||||
ServersProvider? _serversProvider;
|
||||
|
||||
update(ServersProvider? provider) {
|
||||
_serversProvider = provider;
|
||||
}
|
||||
|
||||
LoadStatus _loadStatus = LoadStatus.loading;
|
||||
DnsInfo? _dnsInfo;
|
||||
|
||||
LoadStatus get loadStatus {
|
||||
return _loadStatus;
|
||||
}
|
||||
|
||||
DnsInfo? get dnsInfo {
|
||||
return _dnsInfo;
|
||||
}
|
||||
|
||||
void setDnsInfoData(DnsInfo data) {
|
||||
_dnsInfo = data;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setDnsInfoLoadStatus(LoadStatus status, bool notify) {
|
||||
_loadStatus = status;
|
||||
if (notify == true) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> fetchDnsData({
|
||||
bool? showLoading
|
||||
}) async {
|
||||
if (showLoading == true) {
|
||||
_loadStatus = LoadStatus.loading;
|
||||
}
|
||||
|
||||
final result = await _serversProvider!.apiClient!.getDnsInfo();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_dnsInfo = result['data'];
|
||||
_loadStatus = LoadStatus.loaded;
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (showLoading == false) {
|
||||
_loadStatus = LoadStatus.loaded;
|
||||
notifyListeners();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> savePrivateReverseServersConfig(Map<String, dynamic> value) async {
|
||||
final result = await _serversProvider!.apiClient!.setDnsConfig(
|
||||
data: value
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DnsInfo data = dnsInfo!;
|
||||
if (value['local_ptr_upstreams'] != null) {
|
||||
data.localPtrUpstreams = value['local_ptr_upsreams'];
|
||||
}
|
||||
data.usePrivatePtrResolvers = value['use_private_ptr_resolvers'];
|
||||
data.resolveClients = value['resolve_clients'];
|
||||
setDnsInfoData(data);
|
||||
return { 'success': true };
|
||||
}
|
||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
||||
return {
|
||||
'success': false,
|
||||
'error': 400
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
'success': false,
|
||||
'error': null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> saveUpstreamDnsConfig(Map<String, dynamic> value) async {
|
||||
final result = await _serversProvider!.apiClient!.setDnsConfig(
|
||||
data: value
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DnsInfo data = dnsInfo!;
|
||||
data.upstreamDns = List<String>.from(value['upstream_dns']);
|
||||
data.upstreamMode = value['upstream_mode'];
|
||||
setDnsInfoData(data);
|
||||
return { 'success': true };
|
||||
}
|
||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
||||
return {
|
||||
'success': false,
|
||||
'error': 400
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
'success': false,
|
||||
'error': null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> saveBootstrapDnsConfig(Map<String, dynamic> value) async {
|
||||
final result = await _serversProvider!.apiClient!.setDnsConfig(
|
||||
data: value
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DnsInfo data = dnsInfo!;
|
||||
data.bootstrapDns = List<String>.from(value['bootstrap_dns']);
|
||||
setDnsInfoData(data);
|
||||
return { 'success': true };
|
||||
}
|
||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
||||
return {
|
||||
'success': false,
|
||||
'error': 400
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
'success': false,
|
||||
'error': null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> saveCacheCacheConfig(Map<String, dynamic> value) async {
|
||||
final result = await _serversProvider!.apiClient!.setDnsConfig(
|
||||
data: value
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DnsInfo data = dnsInfo!;
|
||||
data.cacheSize = value['cache_size'];
|
||||
data.cacheTtlMin = value['cache_ttl_min'];
|
||||
data.cacheTtlMax = value['cache_ttl_max'];
|
||||
data.cacheOptimistic = value['cache_optimistic'];
|
||||
setDnsInfoData(data);
|
||||
return { 'success': true };
|
||||
}
|
||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
||||
return {
|
||||
'success': false,
|
||||
'error': 400
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
'success': false,
|
||||
'error': null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> saveDnsServerConfig(Map<String, dynamic> value) async {
|
||||
final result = await _serversProvider!.apiClient!.setDnsConfig(
|
||||
data: value
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DnsInfo data = dnsInfo!;
|
||||
data.ratelimit = value['ratelimit'];
|
||||
data.ednsCsEnabled = value['edns_cs_enabled'];
|
||||
data.dnssecEnabled = value['dnssec_enabled'];
|
||||
data.disableIpv6 = value['disable_ipv6'];
|
||||
data.blockingMode = value['blocking_mode'];
|
||||
data.blockingIpv4 = value['blocking_ipv4'];
|
||||
data.blockingIpv6 = value['blocking_ipv6'];
|
||||
setDnsInfoData(data);
|
||||
return { 'success': true };
|
||||
}
|
||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
||||
return {
|
||||
'success': false,
|
||||
'error': 400
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
'success': false,
|
||||
'error': null
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
387
lib/providers/filtering_provider.dart
Normal file
387
lib/providers/filtering_provider.dart
Normal file
|
@ -0,0 +1,387 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/models/blocked_services.dart';
|
||||
import 'package:adguard_home_manager/models/filtering.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
|
||||
enum FilteringListActions { edit, enable, disable }
|
||||
|
||||
class FilteringProvider with ChangeNotifier {
|
||||
StatusProvider? _statusProvider;
|
||||
ServersProvider? _serversProvider;
|
||||
|
||||
update(ServersProvider? servers, StatusProvider? status) {
|
||||
_serversProvider = servers;
|
||||
_statusProvider = status;
|
||||
}
|
||||
|
||||
LoadStatus _loadStatus = LoadStatus.loading;
|
||||
Filtering? _filtering;
|
||||
LoadStatus _blockedServicesLoadStatus = LoadStatus.loading;
|
||||
BlockedServices? _blockedServicesList;
|
||||
|
||||
LoadStatus get loadStatus {
|
||||
return _loadStatus;
|
||||
}
|
||||
|
||||
Filtering? get filtering {
|
||||
return _filtering;
|
||||
}
|
||||
|
||||
LoadStatus get blockedServicesLoadStatus {
|
||||
return _blockedServicesLoadStatus;
|
||||
}
|
||||
|
||||
BlockedServices? get blockedServices {
|
||||
return _blockedServicesList;
|
||||
}
|
||||
|
||||
void setFilteringData(Filtering data) {
|
||||
_filtering = data;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setFilteringLoadStatus(LoadStatus loadStatus, bool notify) {
|
||||
_loadStatus = loadStatus;
|
||||
if (notify == true) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void setFilteringProtectionStatus(bool status, bool notify) {
|
||||
_statusProvider!.setFilteringEnabledStatus(status);
|
||||
_filtering!.enabled = status;
|
||||
if (notify == true) notifyListeners();
|
||||
}
|
||||
|
||||
void setFiltersUpdateFrequency(int frequency) {
|
||||
if (_filtering != null) {
|
||||
_filtering!.interval = frequency;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void setBlockedServices(List<String> blockedServices) {
|
||||
if (_filtering != null) {
|
||||
_filtering!.blockedServices = blockedServices;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void setBlockedServiceListData(List<BlockedService> data) {
|
||||
_blockedServicesList = BlockedServices(services: data);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setBlockedServicesListLoadStatus(LoadStatus status, bool notify) {
|
||||
_blockedServicesLoadStatus = status;
|
||||
if (notify == true) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> getBlockedServices({
|
||||
bool? showLoader
|
||||
}) async {
|
||||
_blockedServicesLoadStatus = LoadStatus.loading;
|
||||
if (showLoader == true) notifyListeners();
|
||||
|
||||
final result = await _serversProvider!.apiClient!.getBlockedServices();
|
||||
if (result['result'] == 'success') {
|
||||
_blockedServicesLoadStatus = LoadStatus.loaded;
|
||||
_blockedServicesList = BlockedServices(services: result['data']);
|
||||
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (showLoader == true) {
|
||||
_blockedServicesLoadStatus = LoadStatus.error;
|
||||
notifyListeners();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> fetchFilters({
|
||||
bool? showLoading
|
||||
}) async {
|
||||
if (showLoading == true) {
|
||||
_loadStatus = LoadStatus.loading;
|
||||
}
|
||||
|
||||
final result = await _serversProvider!.apiClient!.getFiltering();
|
||||
if (result['result'] == 'success') {
|
||||
_filtering = result['data'];
|
||||
_loadStatus = LoadStatus.loaded;
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
_loadStatus = LoadStatus.error;
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> updateLists() async {
|
||||
final result = await _serversProvider!.apiClient!.updateLists();
|
||||
if (result['result'] == 'success') {
|
||||
final result2 = await _serversProvider!.apiClient!.getFiltering();
|
||||
if (result2['result'] == 'success') {
|
||||
_filtering = result2['data'];
|
||||
notifyListeners();
|
||||
return {
|
||||
"success": true,
|
||||
"data": result['data']
|
||||
};
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return { "success": false };
|
||||
}
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return { "success": false };
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> enableDisableFiltering() async {
|
||||
final newValue = !_statusProvider!.serverStatus!.filteringEnabled;
|
||||
final result = await _serversProvider!.apiClient!.updateFiltering(
|
||||
enable: newValue
|
||||
);
|
||||
if (result['result'] == 'success') {
|
||||
setFilteringProtectionStatus(newValue, false);
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> changeUpdateFrequency(int value) async {
|
||||
final result = await _serversProvider!.apiClient!.requestChangeUpdateFrequency(
|
||||
data: {
|
||||
"enabled": filtering!.enabled,
|
||||
"interval": value
|
||||
}
|
||||
);
|
||||
if (result['result'] == 'success') {
|
||||
setFiltersUpdateFrequency(value);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> removeCustomRule(String rule) async {
|
||||
final List<String> newRules = filtering!.userRules.where((r) => r != rule).toList();
|
||||
|
||||
final result = await _serversProvider!.apiClient!.setCustomRules(rules: newRules);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
Filtering filteringData = filtering!;
|
||||
filteringData.userRules = newRules;
|
||||
_filtering = filteringData;
|
||||
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> deleteList({
|
||||
required String listUrl,
|
||||
required String type
|
||||
}) async {
|
||||
final result1 = await _serversProvider!.apiClient!.deleteFilterList(
|
||||
data: {
|
||||
"url": listUrl,
|
||||
"whitelist": type == 'whitelist' ? true : false
|
||||
}
|
||||
);
|
||||
|
||||
if (result1['result'] == 'success') {
|
||||
final result2 = await _serversProvider!.apiClient!.getFiltering();
|
||||
|
||||
if (result2['result'] == 'success') {
|
||||
_filtering = result2['data'];
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> updateList({
|
||||
required Filter list,
|
||||
required String type,
|
||||
required FilteringListActions action
|
||||
}) async {
|
||||
final result1 = await _serversProvider!.apiClient!.updateFilterList(
|
||||
data: {
|
||||
"data": {
|
||||
"enabled": action == FilteringListActions.disable || action == FilteringListActions.enable
|
||||
? !list.enabled
|
||||
: list.enabled,
|
||||
"name": list.name,
|
||||
"url": list.url
|
||||
},
|
||||
"url": list.url,
|
||||
"whitelist": type == 'whitelist' ? true : false
|
||||
}
|
||||
);
|
||||
|
||||
if (result1['result'] == 'success') {
|
||||
final result2 = await _serversProvider!.apiClient!.getFiltering();
|
||||
|
||||
if (result2['result'] == 'success') {
|
||||
_filtering = result2['data'];
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> addCustomRule(String rule) async {
|
||||
final List<String> newRules = filtering!.userRules;
|
||||
newRules.add(rule);
|
||||
|
||||
final result = await _serversProvider!.apiClient!.setCustomRules(rules: newRules);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
Filtering filteringData = filtering!;
|
||||
filteringData.userRules = newRules;
|
||||
_filtering = filteringData;
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Future<Map<String, dynamic>> addList({required String name, required String url, required String type}) async {
|
||||
final result1 = await _serversProvider!.apiClient!.addFilteringList(
|
||||
data: {
|
||||
'name': name,
|
||||
'url': url,
|
||||
'whitelist': type == 'whitelist' ? true : false
|
||||
}
|
||||
);
|
||||
|
||||
if (result1['result'] == 'success') {
|
||||
if (result1['data'].toString().contains("OK")) {
|
||||
final result2 = await _serversProvider!.apiClient!.getFiltering();
|
||||
final items = result1['data'].toString().split(' ')[1];
|
||||
|
||||
if (result2['result'] == 'success') {
|
||||
_filtering = result2['data'];
|
||||
notifyListeners();
|
||||
return {
|
||||
'success': true,
|
||||
'data': items
|
||||
};
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return {
|
||||
'success': false,
|
||||
'error': null
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return {
|
||||
'success': false,
|
||||
'error': null
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (result1['result'] == 'error' && result1['log'].statusCode == '400' && result1['log'].resBody.toString().contains("Couldn't fetch filter from url")) {
|
||||
notifyListeners();
|
||||
return {
|
||||
'success': false,
|
||||
'error': 'invalid_url'
|
||||
};
|
||||
}
|
||||
else if (result1['result'] == 'error' && result1['log'].statusCode == '400' && result1['log'].resBody.toString().contains('Filter URL already added')) {
|
||||
notifyListeners();
|
||||
return {
|
||||
'success': false,
|
||||
'error': 'url_exists'
|
||||
};
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return {
|
||||
'success': false,
|
||||
'error': null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> loadBlockedServices({
|
||||
bool? showLoading
|
||||
}) async {
|
||||
if (showLoading == true) {
|
||||
_blockedServicesLoadStatus = LoadStatus.loading;
|
||||
}
|
||||
|
||||
final result = await _serversProvider!.apiClient!.getBlockedServices();
|
||||
if (result['result'] == 'success') {
|
||||
_blockedServicesList = BlockedServices(services: result['data']);
|
||||
_blockedServicesLoadStatus = LoadStatus.loaded;
|
||||
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (showLoading == true) _blockedServicesLoadStatus = LoadStatus.error;
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> updateBlockedServices(List<String> values) async {
|
||||
final result = await _serversProvider!.apiClient!.setBlockedServices(
|
||||
data: values
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
setBlockedServices(values);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,21 @@
|
|||
import 'package:adguard_home_manager/models/clients.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/models/applied_filters.dart';
|
||||
import 'package:adguard_home_manager/models/clients.dart';
|
||||
import 'package:adguard_home_manager/models/logs.dart';
|
||||
|
||||
class LogsProvider with ChangeNotifier {
|
||||
int _loadStatus = 0;
|
||||
ServersProvider? _serversProvider;
|
||||
|
||||
update(ServersProvider? provider) {
|
||||
_serversProvider = provider;
|
||||
}
|
||||
|
||||
LoadStatus _loadStatus = LoadStatus.loading;
|
||||
LogsData? _logsData;
|
||||
List<AutoClient>? _clients;
|
||||
int _clientsLoadStatus = 0;
|
||||
|
||||
DateTime? _logsOlderThan;
|
||||
String _selectedResultStatus = 'all';
|
||||
|
@ -18,13 +25,15 @@ class LogsProvider with ChangeNotifier {
|
|||
int _logsQuantity = 100;
|
||||
int _offset = 0;
|
||||
|
||||
bool _isLoadingMore = false;
|
||||
|
||||
AppliedFiters _appliedFilters = AppliedFiters(
|
||||
selectedResultStatus: 'all',
|
||||
searchText: null,
|
||||
clients: null
|
||||
);
|
||||
|
||||
int get loadStatus {
|
||||
LoadStatus get loadStatus {
|
||||
return _loadStatus;
|
||||
}
|
||||
|
||||
|
@ -60,16 +69,15 @@ class LogsProvider with ChangeNotifier {
|
|||
return _selectedClients;
|
||||
}
|
||||
|
||||
int get clientsLoadStatus {
|
||||
return _clientsLoadStatus;
|
||||
}
|
||||
|
||||
AppliedFiters get appliedFilters {
|
||||
return _appliedFilters;
|
||||
}
|
||||
|
||||
bool get isLoadingMore {
|
||||
return _isLoadingMore;
|
||||
}
|
||||
|
||||
void setLoadStatus(int value) {
|
||||
void setLoadStatus(LoadStatus value) {
|
||||
_loadStatus = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
@ -83,11 +91,6 @@ class LogsProvider with ChangeNotifier {
|
|||
_clients = clients;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setClientsLoadStatus(int status) {
|
||||
_clientsLoadStatus = status;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setLogsOlderThan(DateTime? value) {
|
||||
_logsOlderThan = value;
|
||||
|
@ -130,4 +133,136 @@ class LogsProvider with ChangeNotifier {
|
|||
_appliedFilters = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setIsLoadingMore(bool status) {
|
||||
_isLoadingMore = status;
|
||||
}
|
||||
|
||||
Future<bool> fetchLogs({
|
||||
int? inOffset,
|
||||
bool? loadingMore,
|
||||
String? responseStatus,
|
||||
String? searchText,
|
||||
}) async {
|
||||
int offst = inOffset ?? offset;
|
||||
|
||||
String resStatus = responseStatus ?? selectedResultStatus;
|
||||
String? search = searchText ?? searchText;
|
||||
|
||||
if (loadingMore != null && loadingMore == true) {
|
||||
_isLoadingMore = true;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
final result = await _serversProvider!.apiClient!.getLogs(
|
||||
count: logsQuantity,
|
||||
offset: offst,
|
||||
olderThan: logsOlderThan,
|
||||
responseStatus: resStatus,
|
||||
search: search
|
||||
);
|
||||
|
||||
if (loadingMore != null && loadingMore == true) {
|
||||
_isLoadingMore = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_offset = inOffset != null ? inOffset+logsQuantity : offset+logsQuantity;
|
||||
if (loadingMore != null && loadingMore == true && logsData != null) {
|
||||
LogsData newLogsData = result['data'];
|
||||
newLogsData.data = [...logsData!.data, ...result['data'].data];
|
||||
if (appliedFilters.clients != null) {
|
||||
newLogsData.data = newLogsData.data.where(
|
||||
(item) => appliedFilters.clients!.contains(item.client)
|
||||
).toList();
|
||||
}
|
||||
_logsData = newLogsData;
|
||||
}
|
||||
else {
|
||||
LogsData newLogsData = result['data'];
|
||||
if (appliedFilters.clients != null) {
|
||||
newLogsData.data = newLogsData.data.where(
|
||||
(item) => appliedFilters.clients!.contains(item.client)
|
||||
).toList();
|
||||
}
|
||||
_logsData = newLogsData;
|
||||
}
|
||||
_loadStatus = LoadStatus.loaded;
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
_loadStatus = LoadStatus.error;
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> requestResetFilters() async {
|
||||
_loadStatus = LoadStatus.loading;
|
||||
notifyListeners();
|
||||
|
||||
resetFilters();
|
||||
|
||||
final result = await _serversProvider!.apiClient!.getLogs(
|
||||
count: logsQuantity
|
||||
);
|
||||
|
||||
_appliedFilters = AppliedFiters(
|
||||
selectedResultStatus: 'all',
|
||||
searchText: null,
|
||||
clients: null
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_logsData = result['data'];
|
||||
_loadStatus = LoadStatus.loaded;
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
_loadStatus = LoadStatus.error;
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> filterLogs() async {
|
||||
_loadStatus = LoadStatus.loading;
|
||||
notifyListeners();
|
||||
|
||||
setOffset(0);
|
||||
|
||||
final result = await _serversProvider!.apiClient!.getLogs(
|
||||
count: logsQuantity,
|
||||
olderThan: logsOlderThan,
|
||||
responseStatus: selectedResultStatus,
|
||||
search: searchText,
|
||||
);
|
||||
|
||||
_appliedFilters = AppliedFiters(
|
||||
selectedResultStatus: selectedResultStatus,
|
||||
searchText: searchText,
|
||||
clients: selectedClients
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
LogsData newLogsData = result['data'];
|
||||
if (appliedFilters.clients != null) {
|
||||
newLogsData.data = newLogsData.data.where(
|
||||
(item) => appliedFilters.clients!.contains(item.client)
|
||||
).toList();
|
||||
}
|
||||
_logsData = newLogsData;
|
||||
_loadStatus = LoadStatus.loaded;
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
_loadStatus = LoadStatus.error;
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
100
lib/providers/rewrite_rules_provider.dart
Normal file
100
lib/providers/rewrite_rules_provider.dart
Normal file
|
@ -0,0 +1,100 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/models/rewrite_rules.dart';
|
||||
|
||||
class RewriteRulesProvider with ChangeNotifier {
|
||||
ServersProvider? _serversProvider;
|
||||
|
||||
update(ServersProvider? provider) {
|
||||
_serversProvider = provider;
|
||||
}
|
||||
|
||||
LoadStatus _loadStatus = LoadStatus.loading;
|
||||
List<RewriteRules>? _rewriteRules;
|
||||
|
||||
LoadStatus get loadStatus {
|
||||
return _loadStatus;
|
||||
}
|
||||
|
||||
List<RewriteRules>? get rewriteRules {
|
||||
return _rewriteRules;
|
||||
}
|
||||
|
||||
void setRewriteRulesData(List<RewriteRules> data) {
|
||||
_rewriteRules = data;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setRewriteRulesLoadStatus(LoadStatus status, bool notify) {
|
||||
_loadStatus = status;
|
||||
if (notify == true) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> addDnsRewrite(RewriteRules rule) async {
|
||||
final result = await _serversProvider!.apiClient!.addDnsRewriteRule(
|
||||
data: {
|
||||
"domain": rule.domain,
|
||||
"answer": rule.answer
|
||||
}
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
List<RewriteRules> data = rewriteRules!;
|
||||
data.add(rule);
|
||||
setRewriteRulesData(data);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> deleteDnsRewrite(RewriteRules rule) async {
|
||||
final result = await _serversProvider!.apiClient!.deleteDnsRewriteRule(
|
||||
data: {
|
||||
"domain": rule.domain,
|
||||
"answer": rule.answer
|
||||
}
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
List<RewriteRules> data = rewriteRules!;
|
||||
data = data.where((item) => item.domain != rule.domain).toList();
|
||||
setRewriteRulesData(data);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> fetchRules({
|
||||
bool? showLoading
|
||||
}) async {
|
||||
if (showLoading == true) {
|
||||
_loadStatus = LoadStatus.loading;
|
||||
}
|
||||
|
||||
final result = await _serversProvider!.apiClient!.getDnsRewriteRules();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_rewriteRules = result['data'];
|
||||
_loadStatus = LoadStatus.loaded;
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (showLoading == true) {
|
||||
_loadStatus = LoadStatus.error;
|
||||
notifyListeners();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +1,9 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
import 'package:adguard_home_manager/models/filtering.dart';
|
||||
import 'package:adguard_home_manager/models/dhcp.dart';
|
||||
import 'package:adguard_home_manager/models/dns_info.dart';
|
||||
import 'package:adguard_home_manager/models/rewrite_rules.dart';
|
||||
import 'package:adguard_home_manager/models/filtering_status.dart';
|
||||
import 'package:adguard_home_manager/models/clients_allowed_blocked.dart';
|
||||
import 'package:adguard_home_manager/models/blocked_services.dart';
|
||||
import 'package:adguard_home_manager/models/clients.dart';
|
||||
import 'package:adguard_home_manager/models/server_status.dart';
|
||||
import 'package:adguard_home_manager/models/server.dart';
|
||||
import 'package:adguard_home_manager/models/update_available.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/functions/time_server_disabled.dart';
|
||||
import 'package:adguard_home_manager/functions/conversions.dart';
|
||||
import 'package:adguard_home_manager/services/db/queries.dart';
|
||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||
|
@ -24,51 +14,16 @@ class ServersProvider with ChangeNotifier {
|
|||
|
||||
List<Server> _serversList = [];
|
||||
Server? _selectedServer;
|
||||
final ServerStatus _serverStatus = ServerStatus(
|
||||
loadStatus: 0, // 0 = loading, 1 = loaded, 2 = error
|
||||
data: null
|
||||
); // serverStatus != null means server is connected
|
||||
List<String> _protectionsManagementProcess = []; // protections that are currenty being enabled or disabled
|
||||
|
||||
final Clients _clients = Clients(
|
||||
loadStatus: LoadStatus.loading,
|
||||
data: null
|
||||
);
|
||||
String? _searchTermClients;
|
||||
List<AutoClient> _filteredActiveClients = [];
|
||||
List<Client> _filteredAddedClients = [];
|
||||
|
||||
final Filtering _filtering = Filtering(
|
||||
loadStatus: LoadStatus.loading,
|
||||
data: null
|
||||
);
|
||||
|
||||
final DhcpModel _dhcp = DhcpModel(
|
||||
loadStatus: 0, // 0 = loading, 1 = loaded, 2 = error
|
||||
data: null
|
||||
);
|
||||
|
||||
final RewriteRules _rewriteRules = RewriteRules(
|
||||
loadStatus: 0, // 0 = loading, 1 = loaded, 2 = error
|
||||
data: null
|
||||
);
|
||||
|
||||
final DnsInfo _dnsInfo = DnsInfo(
|
||||
loadStatus: 0, // 0 = loading, 1 = loaded, 2 = error
|
||||
data: null
|
||||
);
|
||||
|
||||
final BlockedServices _blockedServicesList = BlockedServices(
|
||||
loadStatus: 0,
|
||||
services: null
|
||||
);
|
||||
ApiClient? _apiClient;
|
||||
|
||||
final UpdateAvailable _updateAvailable = UpdateAvailable(
|
||||
loadStatus: LoadStatus.loading,
|
||||
data: null,
|
||||
);
|
||||
|
||||
FilteringStatus? _filteringStatus;
|
||||
ApiClient? get apiClient {
|
||||
return _apiClient;
|
||||
}
|
||||
|
||||
List<Server> get serversList {
|
||||
return _serversList;
|
||||
|
@ -78,54 +33,6 @@ class ServersProvider with ChangeNotifier {
|
|||
return _selectedServer;
|
||||
}
|
||||
|
||||
ServerStatus get serverStatus {
|
||||
return _serverStatus;
|
||||
}
|
||||
|
||||
List<String> get protectionsManagementProcess {
|
||||
return _protectionsManagementProcess;
|
||||
}
|
||||
|
||||
Clients get clients {
|
||||
return _clients;
|
||||
}
|
||||
|
||||
String? get searchTermClients {
|
||||
return _searchTermClients;
|
||||
}
|
||||
|
||||
List<AutoClient> get filteredActiveClients {
|
||||
return _filteredActiveClients;
|
||||
}
|
||||
|
||||
List<Client> get filteredAddedClients {
|
||||
return _filteredAddedClients;
|
||||
}
|
||||
|
||||
FilteringStatus? get filteringStatus {
|
||||
return _filteringStatus;
|
||||
}
|
||||
|
||||
Filtering get filtering {
|
||||
return _filtering;
|
||||
}
|
||||
|
||||
DhcpModel get dhcp {
|
||||
return _dhcp;
|
||||
}
|
||||
|
||||
RewriteRules get rewriteRules {
|
||||
return _rewriteRules;
|
||||
}
|
||||
|
||||
DnsInfo get dnsInfo {
|
||||
return _dnsInfo;
|
||||
}
|
||||
|
||||
BlockedServices get blockedServicesList {
|
||||
return _blockedServicesList;
|
||||
}
|
||||
|
||||
UpdateAvailable get updateAvailable {
|
||||
return _updateAvailable;
|
||||
}
|
||||
|
@ -144,151 +51,6 @@ class ServersProvider with ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
void setServerStatusData(ServerStatusData data) {
|
||||
_serverStatus.data = data;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setServerStatusLoad(int status) {
|
||||
_serverStatus.loadStatus = status;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setClientsLoadStatus(LoadStatus status, bool notify) {
|
||||
_clients.loadStatus = status;
|
||||
if (notify == true) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void setClientsData(ClientsData data) {
|
||||
_clients.data = data;
|
||||
if (_searchTermClients != null && _searchTermClients != '') {
|
||||
_filteredActiveClients = _clients.data!.autoClientsData.where(
|
||||
(client) => client.ip.contains(_searchTermClients!.toLowerCase()) || (client.name != null ? client.name!.contains(_searchTermClients!.toLowerCase()) : false)
|
||||
).toList();
|
||||
_filteredAddedClients = _clients.data!.clients.where(
|
||||
(client) {
|
||||
isContained(String value) => value.contains(value.toLowerCase());
|
||||
return client.ids.any(isContained);
|
||||
}
|
||||
).toList();
|
||||
}
|
||||
else {
|
||||
_filteredActiveClients = data.autoClientsData;
|
||||
_filteredAddedClients = data.clients;
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setSearchTermClients(String? value) {
|
||||
_searchTermClients = value;
|
||||
if (value != null && value != '') {
|
||||
if (_clients.data != null) {
|
||||
_filteredActiveClients = _clients.data!.autoClientsData.where(
|
||||
(client) => client.ip.contains(value.toLowerCase()) || (client.name != null ? client.name!.contains(value.toLowerCase()) : false)
|
||||
).toList();
|
||||
_filteredAddedClients = _clients.data!.clients.where(
|
||||
(client) {
|
||||
isContained(String value) => value.contains(value.toLowerCase());
|
||||
return client.ids.any(isContained);
|
||||
}
|
||||
).toList();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (_clients.data != null) _filteredActiveClients = _clients.data!.autoClientsData;
|
||||
if (_clients.data != null) _filteredAddedClients = _clients.data!.clients;
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setAllowedDisallowedClientsBlockedDomains(ClientsAllowedBlocked data) {
|
||||
_clients.data?.clientsAllowedBlocked = data;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setFilteringStatus(FilteringStatus status) {
|
||||
_filteringStatus = status;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setFilteringData(FilteringData data) {
|
||||
_filtering.data = data;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setFilteringLoadStatus(LoadStatus loadStatus, bool notify) {
|
||||
_filtering.loadStatus = loadStatus;
|
||||
if (notify == true) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void setFilteringProtectionStatus(bool status) {
|
||||
_serverStatus.data!.filteringEnabled = status;
|
||||
_filtering.data!.enabled = status;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setFiltersUpdateFrequency(int frequency) {
|
||||
_filtering.data!.interval = frequency;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setBlockedServices(List<String> blockedServices) {
|
||||
_filtering.data!.blockedServices = blockedServices;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setDhcpData(DhcpData data) {
|
||||
_dhcp.data = data;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setDhcpLoadStatus(int status, bool notify) {
|
||||
_dhcp.loadStatus = status;
|
||||
if (notify == true) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void setRewriteRulesData(List<RewriteRulesData> data) {
|
||||
_rewriteRules.data = data;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setRewriteRulesLoadStatus(int status, bool notify) {
|
||||
_rewriteRules.loadStatus = status;
|
||||
if (notify == true) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void setDnsInfoData(DnsInfoData data) {
|
||||
_dnsInfo.data = data;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setDnsInfoLoadStatus(int status, bool notify) {
|
||||
_dnsInfo.loadStatus = status;
|
||||
if (notify == true) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void setBlockedServiceListData(List<BlockedService> data) {
|
||||
_blockedServicesList.services = data;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setBlockedServicesListLoadStatus(int status, bool notify) {
|
||||
_blockedServicesList.loadStatus = status;
|
||||
if (notify == true) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void setUpdateAvailableLoadStatus(LoadStatus status, bool notify) {
|
||||
_updateAvailable.loadStatus = status;
|
||||
if (notify == true) {
|
||||
|
@ -301,6 +63,11 @@ class ServersProvider with ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
void setApiClient(ApiClient client) {
|
||||
_apiClient = client;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<dynamic> createServer(Server server) async {
|
||||
final saved = await saveServerQuery(_dbInstance!, server);
|
||||
if (saved == null) {
|
||||
|
@ -360,6 +127,11 @@ class ServersProvider with ChangeNotifier {
|
|||
}
|
||||
}).toList();
|
||||
_serversList = newServers;
|
||||
|
||||
if (selectedServer != null &&server.id == selectedServer!.id) {
|
||||
_apiClient = ApiClient(server: server);
|
||||
}
|
||||
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
|
@ -372,6 +144,7 @@ class ServersProvider with ChangeNotifier {
|
|||
final result = await removeServerQuery(_dbInstance!, server.id);
|
||||
if (result == true) {
|
||||
_selectedServer = null;
|
||||
_apiClient = null;
|
||||
List<Server> newServers = _serversList.where((s) => s.id != server.id).toList();
|
||||
_serversList = newServers;
|
||||
notifyListeners();
|
||||
|
@ -382,155 +155,12 @@ class ServersProvider with ChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
Future<dynamic> updateBlocking({
|
||||
required Server server,
|
||||
required String block,
|
||||
required bool newStatus,
|
||||
int? time
|
||||
}) async {
|
||||
switch (block) {
|
||||
case 'general':
|
||||
_protectionsManagementProcess.add('general');
|
||||
notifyListeners();
|
||||
|
||||
final result = await updateGeneralProtection(
|
||||
server: server,
|
||||
enable: newStatus,
|
||||
time: time
|
||||
);
|
||||
|
||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'general').toList();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_serverStatus.data!.generalEnabled = newStatus;
|
||||
if (time != null) {
|
||||
_serverStatus.data!.timeGeneralDisabled = time;
|
||||
_serverStatus.data!.disabledUntil = generateTimeDeadline(time);
|
||||
}
|
||||
else {
|
||||
_serverStatus.data!.timeGeneralDisabled = 0;
|
||||
_serverStatus.data!.disabledUntil = null;
|
||||
}
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return result['log'];
|
||||
}
|
||||
|
||||
case 'general_legacy':
|
||||
_protectionsManagementProcess.add('general');
|
||||
notifyListeners();
|
||||
|
||||
final result = await updateGeneralProtectionLegacy(server, newStatus);
|
||||
|
||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'general').toList();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_serverStatus.data!.generalEnabled = newStatus;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return result['log'];
|
||||
}
|
||||
|
||||
|
||||
case 'filtering':
|
||||
_protectionsManagementProcess.add('filtering');
|
||||
notifyListeners();
|
||||
|
||||
final result = await updateFiltering(
|
||||
server: server,
|
||||
enable: newStatus,
|
||||
);
|
||||
|
||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'filtering').toList();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_serverStatus.data!.filteringEnabled = newStatus;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
|
||||
notifyListeners();
|
||||
return result['log'];
|
||||
}
|
||||
|
||||
case 'safeSearch':
|
||||
_protectionsManagementProcess.add('safeSearch');
|
||||
notifyListeners();
|
||||
|
||||
final result = serverVersionIsAhead(
|
||||
currentVersion: serverStatus.data!.serverVersion,
|
||||
referenceVersion: 'v0.107.28',
|
||||
referenceVersionBeta: 'v0.108.0-b.33'
|
||||
) == true
|
||||
? await updateSafeSearchSettings(server: server, body: { 'enabled': newStatus })
|
||||
: await updateSafeSearchLegacy(server, newStatus);
|
||||
|
||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'safeSearch').toList();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_serverStatus.data!.safeSearchEnabled = newStatus;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return result['log'];
|
||||
}
|
||||
|
||||
case 'safeBrowsing':
|
||||
_protectionsManagementProcess.add('safeBrowsing');
|
||||
notifyListeners();
|
||||
|
||||
final result = await updateSafeBrowsing(server, newStatus);
|
||||
|
||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'safeBrowsing').toList();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_serverStatus.data!.safeBrowsingEnabled = newStatus;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return result['log'];
|
||||
}
|
||||
|
||||
case 'parentalControl':
|
||||
_protectionsManagementProcess.add('parentalControl');
|
||||
notifyListeners();
|
||||
|
||||
final result = await updateParentalControl(server, newStatus);
|
||||
|
||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'parentalControl').toList();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_serverStatus.data!.parentalControlEnabled = newStatus;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return result['log'];
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void checkServerUpdatesAvailable(Server server) async {
|
||||
setUpdateAvailableLoadStatus(LoadStatus.loading, true);
|
||||
final result = await checkServerUpdates(server: server);
|
||||
final result = await _apiClient!.checkServerUpdates();
|
||||
if (result['result'] == 'success') {
|
||||
UpdateAvailableData data = UpdateAvailableData.fromJson(result['data']);
|
||||
final gitHubResult = await getUpdateChangelog(server: server, releaseTag: data.newVersion ?? data.currentVersion);
|
||||
final gitHubResult = await _apiClient!.getUpdateChangelog(releaseTag: data.newVersion ?? data.currentVersion);
|
||||
if (gitHubResult['result'] == 'success') {
|
||||
data.changelog = gitHubResult['body'];
|
||||
}
|
||||
|
@ -556,8 +186,16 @@ class ServersProvider with ChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
void saveFromDb(List<Map<String, dynamic>>? data) async {
|
||||
Future initializateServer(Server server) async {
|
||||
final serverStatus = await _apiClient!.getServerStatus();
|
||||
if (serverStatus['result'] == 'success') {
|
||||
checkServerUpdatesAvailable(server); // Do not await
|
||||
}
|
||||
}
|
||||
|
||||
Future saveFromDb(List<Map<String, dynamic>>? data) async {
|
||||
if (data != null) {
|
||||
Server? defaultServer;
|
||||
for (var server in data) {
|
||||
final Server serverObj = Server(
|
||||
id: server['id'],
|
||||
|
@ -574,20 +212,21 @@ class ServersProvider with ChangeNotifier {
|
|||
);
|
||||
_serversList.add(serverObj);
|
||||
if (convertFromIntToBool(server['defaultServer']) == true) {
|
||||
_selectedServer = serverObj;
|
||||
_serverStatus.loadStatus = 0;
|
||||
final serverStatus = await getServerStatus(serverObj);
|
||||
if (serverStatus['result'] == 'success') {
|
||||
_serverStatus.data = serverStatus['data'];
|
||||
_serverStatus.loadStatus = 1;
|
||||
checkServerUpdatesAvailable(serverObj); // Do not await
|
||||
}
|
||||
else {
|
||||
_serverStatus.loadStatus = 2;
|
||||
}
|
||||
defaultServer = serverObj;
|
||||
}
|
||||
}
|
||||
|
||||
notifyListeners();
|
||||
|
||||
if (defaultServer != null) {
|
||||
_selectedServer = defaultServer;
|
||||
_apiClient = ApiClient(server: defaultServer);
|
||||
initializateServer(defaultServer);
|
||||
}
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
347
lib/providers/status_provider.dart
Normal file
347
lib/providers/status_provider.dart
Normal file
|
@ -0,0 +1,347 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:adguard_home_manager/models/server_status.dart';
|
||||
import 'package:adguard_home_manager/models/filtering_status.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||
import 'package:adguard_home_manager/functions/time_server_disabled.dart';
|
||||
|
||||
class StatusProvider with ChangeNotifier {
|
||||
ServersProvider? _serversProvider;
|
||||
|
||||
update(ServersProvider? provider) {
|
||||
_serversProvider = provider;
|
||||
}
|
||||
|
||||
LoadStatus _loadStatus = LoadStatus.loading;
|
||||
ServerStatus? _serverStatus; // serverStatus != null means server is connected
|
||||
List<String> _protectionsManagementProcess = []; // protections that are currenty being enabled or disabled
|
||||
FilteringStatus? _filteringStatus;
|
||||
|
||||
// Countdown
|
||||
DateTime? _currentDeadline;
|
||||
Timer? _countdown;
|
||||
int _remaining = 0;
|
||||
|
||||
LoadStatus get loadStatus {
|
||||
return _loadStatus;
|
||||
}
|
||||
|
||||
ServerStatus? get serverStatus {
|
||||
return _serverStatus;
|
||||
}
|
||||
|
||||
List<String> get protectionsManagementProcess {
|
||||
return _protectionsManagementProcess;
|
||||
}
|
||||
|
||||
FilteringStatus? get filteringStatus {
|
||||
return _filteringStatus;
|
||||
}
|
||||
|
||||
int get remainingTime {
|
||||
return _remaining;
|
||||
}
|
||||
|
||||
DateTime? get currentDeadline {
|
||||
return _currentDeadline;
|
||||
}
|
||||
|
||||
void setServerStatusData({
|
||||
required ServerStatus data,
|
||||
}) {
|
||||
_serverStatus = data;
|
||||
if (
|
||||
(_countdown == null ||( _countdown != null && _countdown!.isActive == false)) &&
|
||||
data.disabledUntil != null
|
||||
) {
|
||||
startCountdown(data.disabledUntil!);
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setServerStatusLoad(LoadStatus status) {
|
||||
_loadStatus = status;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setFilteringStatus(FilteringStatus status) {
|
||||
_filteringStatus = status;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void startCountdown(DateTime deadline) {
|
||||
stopCountdown();
|
||||
|
||||
_currentDeadline = deadline;
|
||||
_remaining = deadline.difference(DateTime.now()).inSeconds+1;
|
||||
|
||||
_countdown = Timer.periodic(
|
||||
const Duration(seconds: 1),
|
||||
(Timer timer) async {
|
||||
if (_remaining == 0) {
|
||||
timer.cancel();
|
||||
notifyListeners();
|
||||
getServerStatus();
|
||||
}
|
||||
else {
|
||||
_remaining = _remaining - 1;
|
||||
notifyListeners();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void stopCountdown() {
|
||||
if (_countdown != null && _countdown!.isActive) {
|
||||
_countdown!.cancel();
|
||||
_countdown = null;
|
||||
_remaining = 0;
|
||||
_currentDeadline = null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> updateBlocking({
|
||||
required String block,
|
||||
required bool newStatus,
|
||||
int? time
|
||||
}) async {
|
||||
switch (block) {
|
||||
case 'general':
|
||||
_protectionsManagementProcess.add('general');
|
||||
notifyListeners();
|
||||
|
||||
final result = await _serversProvider!.apiClient!.updateGeneralProtection(
|
||||
enable: newStatus,
|
||||
time: time
|
||||
);
|
||||
|
||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'general').toList();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_serverStatus!.generalEnabled = newStatus;
|
||||
if (time != null) {
|
||||
final deadline = generateTimeDeadline(time);
|
||||
_serverStatus!.timeGeneralDisabled = time;
|
||||
_serverStatus!.disabledUntil = deadline;
|
||||
startCountdown(deadline);
|
||||
}
|
||||
else {
|
||||
_serverStatus!.timeGeneralDisabled = 0;
|
||||
_serverStatus!.disabledUntil = null;
|
||||
stopCountdown();
|
||||
}
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return result['log'];
|
||||
}
|
||||
|
||||
case 'general_legacy':
|
||||
_protectionsManagementProcess.add('general');
|
||||
notifyListeners();
|
||||
|
||||
final result = await _serversProvider!.apiClient!.updateGeneralProtectionLegacy(newStatus);
|
||||
|
||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'general').toList();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_serverStatus!.generalEnabled = newStatus;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return result['log'];
|
||||
}
|
||||
|
||||
|
||||
case 'filtering':
|
||||
_protectionsManagementProcess.add('filtering');
|
||||
notifyListeners();
|
||||
|
||||
final result = await _serversProvider!.apiClient!.updateFiltering(
|
||||
enable: newStatus,
|
||||
);
|
||||
|
||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'filtering').toList();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_serverStatus!.filteringEnabled = newStatus;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
|
||||
notifyListeners();
|
||||
return result['log'];
|
||||
}
|
||||
|
||||
case 'safeSearch':
|
||||
_protectionsManagementProcess.add('safeSearch');
|
||||
notifyListeners();
|
||||
|
||||
final result = serverVersionIsAhead(
|
||||
currentVersion: serverStatus!.serverVersion,
|
||||
referenceVersion: 'v0.107.28',
|
||||
referenceVersionBeta: 'v0.108.0-b.33'
|
||||
) == true
|
||||
? await _serversProvider!.apiClient!.updateSafeSearchSettings(body: { 'enabled': newStatus })
|
||||
: await _serversProvider!.apiClient!.updateSafeSearchLegacy(newStatus);
|
||||
|
||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'safeSearch').toList();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_serverStatus!.safeSearchEnabled = newStatus;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return result['log'];
|
||||
}
|
||||
|
||||
case 'safeBrowsing':
|
||||
_protectionsManagementProcess.add('safeBrowsing');
|
||||
notifyListeners();
|
||||
|
||||
final result = await _serversProvider!.apiClient!.updateSafeBrowsing(newStatus);
|
||||
|
||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'safeBrowsing').toList();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_serverStatus!.safeBrowsingEnabled = newStatus;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return result['log'];
|
||||
}
|
||||
|
||||
case 'parentalControl':
|
||||
_protectionsManagementProcess.add('parentalControl');
|
||||
notifyListeners();
|
||||
|
||||
final result = await _serversProvider!.apiClient!.updateParentalControl(newStatus);
|
||||
|
||||
_protectionsManagementProcess = _protectionsManagementProcess.where((e) => e != 'parentalControl').toList();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
_serverStatus!.parentalControlEnabled = newStatus;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return result['log'];
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void setFilteringEnabledStatus(bool status) {
|
||||
_serverStatus!.filteringEnabled = status;
|
||||
}
|
||||
|
||||
Future<bool> getFilteringRules() async {
|
||||
final result = await _serversProvider!.apiClient!.getFilteringRules();
|
||||
if (result['result'] == 'success') {
|
||||
_filteringStatus = result['data'];
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> getServerStatus({
|
||||
bool? withLoadingIndicator
|
||||
}) async {
|
||||
if (withLoadingIndicator == true) {
|
||||
_loadStatus = LoadStatus.loading;
|
||||
}
|
||||
|
||||
final result = await _serversProvider!.apiClient!.getServerStatus();
|
||||
if (result['result'] == 'success') {
|
||||
setServerStatusData(
|
||||
data: result['data']
|
||||
);
|
||||
_loadStatus = LoadStatus.loaded;
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (withLoadingIndicator == true) _loadStatus = LoadStatus.error;
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> blockUnblockDomain({
|
||||
required String domain,
|
||||
required String newStatus
|
||||
}) async {
|
||||
final rules = await _serversProvider!.apiClient!.getFilteringRules();
|
||||
|
||||
if (rules['result'] == 'success') {
|
||||
FilteringStatus oldStatus = serverStatus!.filteringStatus;
|
||||
|
||||
List<String> newRules = rules['data'].userRules.where((d) => !d.contains(domain)).toList();
|
||||
if (newStatus == 'block') {
|
||||
newRules.add("||$domain^");
|
||||
}
|
||||
else if (newStatus == 'unblock') {
|
||||
newRules.add("@@||$domain^");
|
||||
}
|
||||
FilteringStatus newObj = serverStatus!.filteringStatus;
|
||||
newObj.userRules = newRules;
|
||||
_filteringStatus = newObj;
|
||||
|
||||
final result = await _serversProvider!.apiClient!.postFilteringRules(data: {'rules': newRules});
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
_filteringStatus = oldStatus;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> updateSafeSearchConfig(Map<String, bool> status) async {
|
||||
final result = await _serversProvider!.apiClient!.updateSafeSearchSettings(
|
||||
body: status
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
ServerStatus data = serverStatus!;
|
||||
data.safeSearchEnabled = status['enabled'] ?? false;
|
||||
data.safeSeachBing = status['bing'] ?? false;
|
||||
data.safeSearchDuckduckgo = status['duckduckgo'] ?? false;
|
||||
data.safeSearchGoogle = status['google'] ?? false;
|
||||
data.safeSearchPixabay = status['pixabay'] ?? false;
|
||||
data.safeSearchYandex = status['yandex'] ?? false;
|
||||
data.safeSearchYoutube = status['youtube'] ?? false;
|
||||
|
||||
setServerStatusData(data: data);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,20 +17,16 @@ import 'package:adguard_home_manager/screens/clients/options_modal.dart';
|
|||
import 'package:adguard_home_manager/widgets/tab_content_list.dart';
|
||||
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/functions/maps_fns.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/clients_provider.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||
import 'package:adguard_home_manager/models/clients.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class AddedList extends StatefulWidget {
|
||||
final ScrollController scrollController;
|
||||
final LoadStatus loadStatus;
|
||||
final List<Client> data;
|
||||
final Future Function() fetchClients;
|
||||
final void Function(Client) onClientSelected;
|
||||
final Client? selectedClient;
|
||||
final bool splitView;
|
||||
|
@ -38,9 +34,7 @@ class AddedList extends StatefulWidget {
|
|||
const AddedList({
|
||||
Key? key,
|
||||
required this.scrollController,
|
||||
required this.loadStatus,
|
||||
required this.data,
|
||||
required this.fetchClients,
|
||||
required this.onClientSelected,
|
||||
this.selectedClient,
|
||||
required this.splitView
|
||||
|
@ -76,7 +70,8 @@ class _AddedListState extends State<AddedList> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final clientsProvider = Provider.of<ClientsProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
@ -85,31 +80,11 @@ class _AddedListState extends State<AddedList> {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.addingClient);
|
||||
|
||||
final result = await postUpdateClient(server: serversProvider.selectedServer!, data: {
|
||||
'name': client.name,
|
||||
'data': serverVersionIsAhead(
|
||||
currentVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
referenceVersion: 'v0.107.28',
|
||||
referenceVersionBeta: 'v0.108.0-b.33'
|
||||
) == false
|
||||
? removePropFromMap(client.toJson(), 'safesearch_enabled')
|
||||
: removePropFromMap(client.toJson(), 'safe_search')
|
||||
});
|
||||
final result = await clientsProvider.editClient(client);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
ClientsData clientsData = serversProvider.clients.data!;
|
||||
clientsData.clients = clientsData.clients.map((e) {
|
||||
if (e.name == client.name) {
|
||||
return client;
|
||||
}
|
||||
else {
|
||||
return e;
|
||||
}
|
||||
}).toList();
|
||||
serversProvider.setClientsData(clientsData);
|
||||
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientUpdatedSuccessfully,
|
||||
|
@ -117,8 +92,6 @@ class _AddedListState extends State<AddedList> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientNotUpdated,
|
||||
|
@ -131,19 +104,14 @@ class _AddedListState extends State<AddedList> {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.removingClient);
|
||||
|
||||
final result = await postDeleteClient(server: serversProvider.selectedServer!, name: client.name);
|
||||
final result = await clientsProvider.deleteClient(client);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
ClientsData clientsData = serversProvider.clients.data!;
|
||||
clientsData.clients = clientsData.clients.where((c) => c.name != client.name).toList();
|
||||
serversProvider.setClientsData(clientsData);
|
||||
|
||||
if (result == true) {
|
||||
if (widget.splitView == true) {
|
||||
SplitView.of(context).popUntil(0);
|
||||
}
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientDeletedSuccessfully,
|
||||
|
@ -151,15 +119,13 @@ class _AddedListState extends State<AddedList> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientNotDeleted,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void openClientModal(Client client) {
|
||||
if (width > 900 || !(Platform.isAndroid | Platform.isIOS)) {
|
||||
|
@ -168,7 +134,7 @@ class _AddedListState extends State<AddedList> {
|
|||
context: context,
|
||||
builder: (BuildContext context) => ClientScreen(
|
||||
onConfirm: confirmEditClient,
|
||||
serverVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
serverVersion: statusProvider.serverStatus!.serverVersion,
|
||||
onDelete: deleteClient,
|
||||
client: client,
|
||||
dialog: true,
|
||||
|
@ -180,7 +146,7 @@ class _AddedListState extends State<AddedList> {
|
|||
fullscreenDialog: true,
|
||||
builder: (BuildContext context) => ClientScreen(
|
||||
onConfirm: confirmEditClient,
|
||||
serverVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
serverVersion: statusProvider.serverStatus!.serverVersion,
|
||||
onDelete: deleteClient,
|
||||
client: client,
|
||||
dialog: false,
|
||||
|
@ -240,7 +206,7 @@ class _AddedListState extends State<AddedList> {
|
|||
onLongPress: openOptionsModal,
|
||||
onEdit: openClientModal,
|
||||
splitView: widget.splitView,
|
||||
serverVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
serverVersion: statusProvider.serverStatus!.serverVersion,
|
||||
),
|
||||
noData: SizedBox(
|
||||
width: double.maxFinite,
|
||||
|
@ -260,7 +226,7 @@ class _AddedListState extends State<AddedList> {
|
|||
),
|
||||
const SizedBox(height: 30),
|
||||
TextButton.icon(
|
||||
onPressed: widget.fetchClients,
|
||||
onPressed: () => clientsProvider.fetchClients(updateLoading: true),
|
||||
icon: const Icon(Icons.refresh_rounded),
|
||||
label: Text(AppLocalizations.of(context)!.refresh),
|
||||
)
|
||||
|
@ -290,8 +256,10 @@ class _AddedListState extends State<AddedList> {
|
|||
],
|
||||
),
|
||||
),
|
||||
loadStatus: widget.loadStatus,
|
||||
onRefresh: widget.fetchClients,
|
||||
loadStatus: statusProvider.loadStatus == LoadStatus.loading || clientsProvider.loadStatus == LoadStatus.loading
|
||||
? LoadStatus.loading
|
||||
: clientsProvider.loadStatus,
|
||||
onRefresh: () => clientsProvider.fetchClients(updateLoading: false),
|
||||
fab: const ClientsFab(),
|
||||
fabVisible: isVisible,
|
||||
);
|
||||
|
|
|
@ -11,7 +11,8 @@ import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
|||
|
||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||
import 'package:adguard_home_manager/models/safe_search.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/clients_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/models/clients.dart';
|
||||
|
||||
class ClientScreen extends StatefulWidget {
|
||||
|
@ -130,7 +131,8 @@ class _ClientScreenState extends State<ClientScreen> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final clientsProvider = Provider.of<ClientsProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
|
||||
void createClient() {
|
||||
final Client client = Client(
|
||||
|
@ -200,7 +202,7 @@ class _ClientScreenState extends State<ClientScreen> {
|
|||
context: context,
|
||||
builder: (context) => TagsModal(
|
||||
selectedTags: selectedTags,
|
||||
tags: serversProvider.clients.data!.supportedTags,
|
||||
tags: clientsProvider.clients!.supportedTags,
|
||||
onConfirm: (selected) => setState(() => selectedTags = selected),
|
||||
)
|
||||
);
|
||||
|
@ -506,7 +508,7 @@ class _ClientScreenState extends State<ClientScreen> {
|
|||
),
|
||||
if (
|
||||
serverVersionIsAhead(
|
||||
currentVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
currentVersion: statusProvider.serverStatus!.serverVersion,
|
||||
referenceVersion: 'v0.107.28',
|
||||
referenceVersionBeta: 'v0.108.0-b.33'
|
||||
) == true
|
||||
|
@ -531,7 +533,7 @@ class _ClientScreenState extends State<ClientScreen> {
|
|||
),
|
||||
if (
|
||||
serverVersionIsAhead(
|
||||
currentVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
currentVersion: statusProvider.serverStatus!.serverVersion,
|
||||
referenceVersion: 'v0.107.28',
|
||||
referenceVersionBeta: 'v0.108.0-b.33'
|
||||
) == false
|
||||
|
|
|
@ -11,84 +11,40 @@ import 'package:adguard_home_manager/screens/clients/logs_list_client.dart';
|
|||
import 'package:adguard_home_manager/screens/clients/clients_desktop_view.dart';
|
||||
import 'package:adguard_home_manager/screens/clients/added_list.dart';
|
||||
|
||||
import 'package:adguard_home_manager/models/app_log.dart';
|
||||
import 'package:adguard_home_manager/providers/clients_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/models/server.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/models/clients.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class Clients extends StatelessWidget {
|
||||
class Clients extends StatefulWidget {
|
||||
const Clients({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
return ClientsWidget(
|
||||
server: serversProvider.selectedServer!,
|
||||
setLoadingStatus: serversProvider.setClientsLoadStatus,
|
||||
setClientsData: serversProvider.setClientsData,
|
||||
setSelectedClientsTab: appConfigProvider.setSelectedClientsTab,
|
||||
addLog: appConfigProvider.addLog,
|
||||
);
|
||||
}
|
||||
State<Clients> createState() => _ClientsState();
|
||||
}
|
||||
|
||||
class ClientsWidget extends StatefulWidget {
|
||||
final Server server;
|
||||
final void Function(LoadStatus, bool) setLoadingStatus;
|
||||
final void Function(ClientsData) setClientsData;
|
||||
final void Function(int) setSelectedClientsTab;
|
||||
final void Function(AppLog) addLog;
|
||||
|
||||
const ClientsWidget({
|
||||
Key? key,
|
||||
required this.server,
|
||||
required this.setLoadingStatus,
|
||||
required this.setClientsData,
|
||||
required this.setSelectedClientsTab,
|
||||
required this.addLog,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<ClientsWidget> createState() => _ClientsWidgetState();
|
||||
}
|
||||
|
||||
class _ClientsWidgetState extends State<ClientsWidget> with TickerProviderStateMixin {
|
||||
class _ClientsState extends State<Clients> with TickerProviderStateMixin {
|
||||
late TabController tabController;
|
||||
final ScrollController scrollController = ScrollController();
|
||||
|
||||
bool searchMode = false;
|
||||
final TextEditingController searchController = TextEditingController();
|
||||
|
||||
Future fetchClients() async {
|
||||
widget.setLoadingStatus(LoadStatus.loading, false);
|
||||
final result = await getClients(widget.server);
|
||||
if (mounted) {
|
||||
if (result['result'] == 'success') {
|
||||
widget.setClientsData(result['data']);
|
||||
widget.setLoadingStatus(LoadStatus.loaded, true);
|
||||
}
|
||||
else {
|
||||
widget.addLog(result['log']);
|
||||
widget.setLoadingStatus(LoadStatus.error, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
fetchClients();
|
||||
final clientsProvider = Provider.of<ClientsProvider>(context, listen: false);
|
||||
clientsProvider.fetchClients(updateLoading: true);
|
||||
|
||||
super.initState();
|
||||
tabController = TabController(
|
||||
initialIndex: 0,
|
||||
length: 2,
|
||||
vsync: this,
|
||||
);
|
||||
tabController.addListener(() => widget.setSelectedClientsTab(tabController.index));
|
||||
tabController.addListener(
|
||||
() => Provider.of<AppConfigProvider>(context, listen: false).setSelectedClientsTab(tabController.index)
|
||||
);
|
||||
}
|
||||
|
||||
List<AutoClient> generateClientsList(List<AutoClient> clients, List<String> ips) {
|
||||
|
@ -98,6 +54,7 @@ class _ClientsWidgetState extends State<ClientsWidget> with TickerProviderStateM
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final clientsProvider = Provider.of<ClientsProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
@ -137,10 +94,8 @@ class _ClientsWidgetState extends State<ClientsWidget> with TickerProviderStateM
|
|||
children: [
|
||||
ClientsList(
|
||||
scrollController: scrollController,
|
||||
loadStatus: serversProvider.clients.loadStatus,
|
||||
data: serversProvider.clients.loadStatus == LoadStatus.loaded
|
||||
? serversProvider.filteredActiveClients : [],
|
||||
fetchClients: fetchClients,
|
||||
data: clientsProvider.loadStatus == LoadStatus.loaded
|
||||
? clientsProvider.filteredActiveClients : [],
|
||||
onClientSelected: (client) => Navigator.push(context, MaterialPageRoute(
|
||||
builder: (context) => LogsListClient(
|
||||
ip: client.ip,
|
||||
|
@ -153,10 +108,8 @@ class _ClientsWidgetState extends State<ClientsWidget> with TickerProviderStateM
|
|||
),
|
||||
AddedList(
|
||||
scrollController: scrollController,
|
||||
loadStatus: serversProvider.clients.loadStatus,
|
||||
data: serversProvider.clients.loadStatus == LoadStatus.loaded
|
||||
? serversProvider.filteredAddedClients : [],
|
||||
fetchClients: fetchClients,
|
||||
data: clientsProvider.loadStatus == LoadStatus.loaded
|
||||
? clientsProvider.filteredAddedClients : [],
|
||||
onClientSelected: (client) => Navigator.push(context, MaterialPageRoute(
|
||||
builder: (context) => LogsListClient(
|
||||
ip: client.ids[0],
|
||||
|
@ -190,7 +143,6 @@ class _ClientsWidgetState extends State<ClientsWidget> with TickerProviderStateM
|
|||
child: ClientsDesktopView(
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider,
|
||||
fetchClients: fetchClients,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -203,7 +155,7 @@ class _ClientsWidgetState extends State<ClientsWidget> with TickerProviderStateM
|
|||
title: Text(AppLocalizations.of(context)!.clients),
|
||||
centerTitle: false,
|
||||
actions: [
|
||||
if (serversProvider.clients.loadStatus == LoadStatus.loaded) ...[
|
||||
if (clientsProvider.loadStatus == LoadStatus.loaded) ...[
|
||||
IconButton(
|
||||
onPressed: () => {
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
|
@ -240,7 +192,7 @@ class _ClientsWidgetState extends State<ClientsWidget> with TickerProviderStateM
|
|||
setState(() {
|
||||
searchMode = false;
|
||||
searchController.text = "";
|
||||
serversProvider.setSearchTermClients(null);
|
||||
clientsProvider.setSearchTermClients(null);
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back_rounded)
|
||||
|
@ -249,13 +201,13 @@ class _ClientsWidgetState extends State<ClientsWidget> with TickerProviderStateM
|
|||
Expanded(
|
||||
child: TextField(
|
||||
controller: searchController,
|
||||
onChanged: (value) => serversProvider.setSearchTermClients(value),
|
||||
onChanged: (value) => clientsProvider.setSearchTermClients(value),
|
||||
decoration: InputDecoration(
|
||||
suffixIcon: IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
searchController.text = "";
|
||||
serversProvider.setSearchTermClients(null);
|
||||
clientsProvider.setSearchTermClients(null);
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.clear_rounded)
|
||||
|
@ -281,7 +233,7 @@ class _ClientsWidgetState extends State<ClientsWidget> with TickerProviderStateM
|
|||
centerTitle: false,
|
||||
forceElevated: innerBoxIsScrolled,
|
||||
actions: [
|
||||
if (serversProvider.clients.loadStatus == LoadStatus.loaded && searchMode == false) ...[
|
||||
if (clientsProvider.loadStatus == LoadStatus.loaded && searchMode == false) ...[
|
||||
IconButton(
|
||||
onPressed: () => setState(() => searchMode = true),
|
||||
icon: const Icon(Icons.search),
|
||||
|
|
|
@ -10,6 +10,7 @@ import 'package:adguard_home_manager/screens/clients/added_list.dart';
|
|||
import 'package:adguard_home_manager/screens/clients/clients_list.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/clients_provider.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/models/clients.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
@ -18,13 +19,11 @@ import 'package:adguard_home_manager/providers/servers_provider.dart';
|
|||
class ClientsDesktopView extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
final AppConfigProvider appConfigProvider;
|
||||
final Future Function() fetchClients;
|
||||
|
||||
const ClientsDesktopView({
|
||||
Key? key,
|
||||
required this.serversProvider,
|
||||
required this.appConfigProvider,
|
||||
required this.fetchClients
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -55,6 +54,7 @@ class _ClientsDesktopViewState extends State<ClientsDesktopView> with TickerPro
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final clientsProvider = Provider.of<ClientsProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
PreferredSizeWidget tabBar() {
|
||||
|
@ -92,10 +92,8 @@ class _ClientsDesktopViewState extends State<ClientsDesktopView> with TickerPro
|
|||
children: [
|
||||
ClientsList(
|
||||
scrollController: scrollController,
|
||||
loadStatus: serversProvider.clients.loadStatus,
|
||||
data: serversProvider.clients.loadStatus == LoadStatus.loaded
|
||||
? serversProvider.filteredActiveClients : [],
|
||||
fetchClients: widget.fetchClients,
|
||||
data: clientsProvider.loadStatus == LoadStatus.loaded
|
||||
? clientsProvider.filteredActiveClients : [],
|
||||
onClientSelected: (client) => setState(() {
|
||||
selectedAddedClient = null;
|
||||
selectedActiveClient = client;
|
||||
|
@ -114,10 +112,8 @@ class _ClientsDesktopViewState extends State<ClientsDesktopView> with TickerPro
|
|||
),
|
||||
AddedList(
|
||||
scrollController: scrollController,
|
||||
loadStatus: serversProvider.clients.loadStatus,
|
||||
data: serversProvider.clients.loadStatus == LoadStatus.loaded
|
||||
? serversProvider.filteredAddedClients : [],
|
||||
fetchClients: widget.fetchClients,
|
||||
data: clientsProvider.loadStatus == LoadStatus.loaded
|
||||
? clientsProvider.filteredAddedClients : [],
|
||||
onClientSelected: (client) => setState(() {
|
||||
selectedActiveClient = null;
|
||||
selectedAddedClient = client;
|
||||
|
@ -146,7 +142,7 @@ class _ClientsDesktopViewState extends State<ClientsDesktopView> with TickerPro
|
|||
setState(() {
|
||||
searchMode = false;
|
||||
searchController.text = "";
|
||||
serversProvider.setSearchTermClients(null);
|
||||
clientsProvider.setSearchTermClients(null);
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back_rounded)
|
||||
|
@ -155,13 +151,13 @@ class _ClientsDesktopViewState extends State<ClientsDesktopView> with TickerPro
|
|||
Expanded(
|
||||
child: TextField(
|
||||
controller: searchController,
|
||||
onChanged: (value) => serversProvider.setSearchTermClients(value),
|
||||
onChanged: (value) => clientsProvider.setSearchTermClients(value),
|
||||
decoration: InputDecoration(
|
||||
suffixIcon: IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
searchController.text = "";
|
||||
serversProvider.setSearchTermClients(null);
|
||||
clientsProvider.setSearchTermClients(null);
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.clear_rounded)
|
||||
|
@ -195,7 +191,7 @@ class _ClientsDesktopViewState extends State<ClientsDesktopView> with TickerPro
|
|||
title: title(),
|
||||
centerTitle: false,
|
||||
actions: [
|
||||
if (serversProvider.clients.loadStatus == LoadStatus.loaded && searchMode == false) ...[
|
||||
if (clientsProvider.loadStatus == LoadStatus.loaded && searchMode == false) ...[
|
||||
IconButton(
|
||||
onPressed: () => setState(() => searchMode = true),
|
||||
icon: const Icon(Icons.search),
|
||||
|
@ -226,7 +222,7 @@ class _ClientsDesktopViewState extends State<ClientsDesktopView> with TickerPro
|
|||
centerTitle: false,
|
||||
forceElevated: innerBoxIsScrolled,
|
||||
actions: [
|
||||
if (serversProvider.clients.loadStatus == LoadStatus.loaded && searchMode == false) ...[
|
||||
if (clientsProvider.loadStatus == LoadStatus.loaded && searchMode == false) ...[
|
||||
IconButton(
|
||||
onPressed: () => setState(() => searchMode = true),
|
||||
icon: const Icon(Icons.search),
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/screens/clients/active_client_tile.dart';
|
||||
|
||||
import 'package:adguard_home_manager/widgets/tab_content_list.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/clients_provider.dart';
|
||||
import 'package:adguard_home_manager/models/clients.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
|
||||
class ClientsList extends StatelessWidget {
|
||||
final ScrollController scrollController;
|
||||
final LoadStatus loadStatus;
|
||||
final List<AutoClient> data;
|
||||
final Future Function() fetchClients;
|
||||
final void Function(AutoClient) onClientSelected;
|
||||
final AutoClient? selectedClient;
|
||||
final bool splitView;
|
||||
|
@ -21,9 +20,7 @@ class ClientsList extends StatelessWidget {
|
|||
const ClientsList({
|
||||
Key? key,
|
||||
required this.scrollController,
|
||||
required this.loadStatus,
|
||||
required this.data,
|
||||
required this.fetchClients,
|
||||
required this.onClientSelected,
|
||||
this.selectedClient,
|
||||
required this.splitView,
|
||||
|
@ -32,6 +29,8 @@ class ClientsList extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final clientsProvider = Provider.of<ClientsProvider>(context);
|
||||
|
||||
return CustomTabContentList(
|
||||
listPadding: splitView == true
|
||||
? const EdgeInsets.only(top: 8)
|
||||
|
@ -79,7 +78,7 @@ class ClientsList extends StatelessWidget {
|
|||
),
|
||||
const SizedBox(height: 30),
|
||||
TextButton.icon(
|
||||
onPressed: fetchClients,
|
||||
onPressed: () => clientsProvider.fetchClients(updateLoading: false),
|
||||
icon: const Icon(Icons.refresh_rounded),
|
||||
label: Text(AppLocalizations.of(context)!.refresh)
|
||||
)
|
||||
|
@ -110,8 +109,8 @@ class ClientsList extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
),
|
||||
loadStatus: loadStatus,
|
||||
onRefresh: fetchClients
|
||||
loadStatus: clientsProvider.loadStatus,
|
||||
onRefresh: () => clientsProvider.fetchClients(updateLoading: false),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -9,12 +9,10 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
import 'package:adguard_home_manager/screens/clients/client_screen.dart';
|
||||
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||
import 'package:adguard_home_manager/providers/clients_provider.dart';
|
||||
import 'package:adguard_home_manager/models/clients.dart';
|
||||
import 'package:adguard_home_manager/functions/maps_fns.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
|
||||
class ClientsFab extends StatelessWidget {
|
||||
|
@ -22,8 +20,9 @@ class ClientsFab extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final clientsProvider = Provider.of<ClientsProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
||||
|
@ -31,24 +30,11 @@ class ClientsFab extends StatelessWidget {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.addingClient);
|
||||
|
||||
final result = await postAddClient(
|
||||
server: serversProvider.selectedServer!,
|
||||
data: serverVersionIsAhead(
|
||||
currentVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
referenceVersion: 'v0.107.28',
|
||||
referenceVersionBeta: 'v0.108.0-b.33'
|
||||
) == false
|
||||
? removePropFromMap(client.toJson(), 'safesearch_enabled')
|
||||
: removePropFromMap(client.toJson(), 'safe_search')
|
||||
);
|
||||
final result = await clientsProvider.addClient(client);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
ClientsData clientsData = serversProvider.clients.data!;
|
||||
clientsData.clients.add(client);
|
||||
serversProvider.setClientsData(clientsData);
|
||||
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientAddedSuccessfully,
|
||||
|
@ -56,8 +42,6 @@ class ClientsFab extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientNotAdded,
|
||||
|
@ -73,7 +57,7 @@ class ClientsFab extends StatelessWidget {
|
|||
context: context,
|
||||
builder: (BuildContext context) => ClientScreen(
|
||||
onConfirm: confirmAddClient,
|
||||
serverVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
serverVersion: statusProvider.serverStatus!.serverVersion,
|
||||
dialog: true,
|
||||
)
|
||||
);
|
||||
|
@ -83,7 +67,7 @@ class ClientsFab extends StatelessWidget {
|
|||
fullscreenDialog: true,
|
||||
builder: (BuildContext context) => ClientScreen(
|
||||
onConfirm: confirmAddClient,
|
||||
serverVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
serverVersion: statusProvider.serverStatus!.serverVersion,
|
||||
dialog: false,
|
||||
)
|
||||
));
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:io';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:async/async.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/screens/logs/log_tile.dart';
|
||||
|
@ -10,7 +11,6 @@ import 'package:adguard_home_manager/screens/logs/log_details_screen.dart';
|
|||
import 'package:adguard_home_manager/models/logs.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
|
||||
class LogsListClient extends StatefulWidget {
|
||||
final String ip;
|
||||
|
@ -53,6 +53,8 @@ class _LogsListClientState extends State<LogsListClient> {
|
|||
String? responseStatus,
|
||||
String? searchText,
|
||||
}) async {
|
||||
final serversProvider = Provider.of<ServersProvider>(context, listen: false);
|
||||
|
||||
int offst = inOffset ?? offset;
|
||||
|
||||
if (loadingMore != null && loadingMore == true) {
|
||||
|
@ -62,8 +64,7 @@ class _LogsListClientState extends State<LogsListClient> {
|
|||
if (cancelableRequest != null) cancelableRequest!.cancel();
|
||||
|
||||
cancelableRequest = CancelableOperation.fromFuture(
|
||||
getLogs(
|
||||
server: widget.serversProvider.selectedServer!,
|
||||
serversProvider.apiClient!.getLogs(
|
||||
count: logsQuantity,
|
||||
offset: offst,
|
||||
search: '"${widget.ip}"'
|
||||
|
|
|
@ -11,43 +11,25 @@ import 'package:adguard_home_manager/screens/clients/remove_client_modal.dart';
|
|||
import 'package:adguard_home_manager/screens/clients/client_screen.dart';
|
||||
import 'package:adguard_home_manager/screens/clients/options_modal.dart';
|
||||
|
||||
import 'package:adguard_home_manager/widgets/section_label.dart';
|
||||
import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
||||
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/clients_provider.dart';
|
||||
import 'package:adguard_home_manager/models/clients.dart';
|
||||
import 'package:adguard_home_manager/widgets/section_label.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
|
||||
class SearchClients extends StatelessWidget {
|
||||
class SearchClients extends StatefulWidget {
|
||||
const SearchClients({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
|
||||
return SearchClientsWidget(
|
||||
serversProvider: serversProvider,
|
||||
);
|
||||
}
|
||||
State<SearchClients> createState() => _SearchClientsState();
|
||||
}
|
||||
|
||||
class SearchClientsWidget extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
|
||||
const SearchClientsWidget({
|
||||
Key? key,
|
||||
required this.serversProvider,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<SearchClientsWidget> createState() => _SearchClientsWidgetState();
|
||||
}
|
||||
|
||||
class _SearchClientsWidgetState extends State<SearchClientsWidget> {
|
||||
class _SearchClientsState extends State<SearchClients> {
|
||||
late ScrollController scrollController;
|
||||
|
||||
final TextEditingController searchController = TextEditingController();
|
||||
|
@ -86,11 +68,13 @@ class _SearchClientsWidgetState extends State<SearchClientsWidget> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
final clientsProvider = Provider.of<ClientsProvider>(context, listen: false);
|
||||
|
||||
scrollController = ScrollController()..addListener(scrollListener);
|
||||
|
||||
setState(() {
|
||||
clients = widget.serversProvider.clients.data!.clients;
|
||||
autoClients = widget.serversProvider.clients.data!.autoClientsData;
|
||||
clients = clientsProvider.clients!.clients;
|
||||
autoClients = clientsProvider.clients!.autoClients;
|
||||
});
|
||||
|
||||
super.initState();
|
||||
|
@ -98,7 +82,8 @@ class _SearchClientsWidgetState extends State<SearchClientsWidget> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final clientsProvider = Provider.of<ClientsProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
@ -107,19 +92,11 @@ class _SearchClientsWidgetState extends State<SearchClientsWidget> {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.removingClient);
|
||||
|
||||
final result = await postDeleteClient(server: serversProvider.selectedServer!, name: client.name);
|
||||
final result = await clientsProvider.deleteClient(client);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
ClientsData clientsData = serversProvider.clients.data!;
|
||||
clientsData.clients = clientsData.clients.where((c) => c.name != client.name).toList();
|
||||
serversProvider.setClientsData(clientsData);
|
||||
setState(() {
|
||||
clients = clientsData.clients;
|
||||
});
|
||||
search(searchController.text);
|
||||
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientDeletedSuccessfully,
|
||||
|
@ -127,44 +104,23 @@ class _SearchClientsWidgetState extends State<SearchClientsWidget> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientNotDeleted,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void confirmEditClient(Client client) async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.addingClient);
|
||||
|
||||
final result = await postUpdateClient(server: serversProvider.selectedServer!, data: {
|
||||
'name': client.name,
|
||||
'data': client.toJson()
|
||||
});
|
||||
final result = await clientsProvider.editClient(client);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
ClientsData clientsData = serversProvider.clients.data!;
|
||||
clientsData.clients = clientsData.clients.map((e) {
|
||||
if (e.name == client.name) {
|
||||
return client;
|
||||
}
|
||||
else {
|
||||
return e;
|
||||
}
|
||||
}).toList();
|
||||
serversProvider.setClientsData(clientsData);
|
||||
|
||||
setState(() {
|
||||
clients = clientsData.clients;
|
||||
});
|
||||
search(searchController.text);
|
||||
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientUpdatedSuccessfully,
|
||||
|
@ -172,8 +128,6 @@ class _SearchClientsWidgetState extends State<SearchClientsWidget> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientNotUpdated,
|
||||
|
@ -189,7 +143,7 @@ class _SearchClientsWidgetState extends State<SearchClientsWidget> {
|
|||
context: context,
|
||||
builder: (BuildContext context) => ClientScreen(
|
||||
onConfirm: confirmEditClient,
|
||||
serverVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
serverVersion: statusProvider.serverStatus!.serverVersion,
|
||||
onDelete: deleteClient,
|
||||
client: client,
|
||||
dialog: true,
|
||||
|
@ -201,7 +155,7 @@ class _SearchClientsWidgetState extends State<SearchClientsWidget> {
|
|||
fullscreenDialog: true,
|
||||
builder: (BuildContext context) => ClientScreen(
|
||||
onConfirm: confirmEditClient,
|
||||
serverVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
serverVersion: statusProvider.serverStatus!.serverVersion,
|
||||
onDelete: deleteClient,
|
||||
client: client,
|
||||
dialog: false,
|
||||
|
@ -356,7 +310,7 @@ class _SearchClientsWidgetState extends State<SearchClientsWidget> {
|
|||
Icons.search_rounded,
|
||||
size: 19,
|
||||
color: serverVersionIsAhead(
|
||||
currentVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
currentVersion: statusProvider.serverStatus!.serverVersion,
|
||||
referenceVersion: 'v0.107.28',
|
||||
referenceVersionBeta: 'v0.108.0-b.33'
|
||||
) == true
|
||||
|
|
|
@ -2,11 +2,10 @@ import 'package:flutter/material.dart';
|
|||
import 'package:provider/provider.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/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/filtering_provider.dart';
|
||||
|
||||
class ServicesModal extends StatelessWidget {
|
||||
class ServicesModal extends StatefulWidget {
|
||||
final List<String> blockedServices;
|
||||
final void Function(List<String>) onConfirm;
|
||||
|
||||
|
@ -17,56 +16,20 @@ class ServicesModal extends StatelessWidget {
|
|||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
return ServicesModalWidget(
|
||||
blockedServices: blockedServices,
|
||||
onConfirm: onConfirm,
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider,
|
||||
);
|
||||
}
|
||||
State<ServicesModal> createState() => _ServicesModalStateWidget();
|
||||
}
|
||||
|
||||
class ServicesModalWidget extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
final AppConfigProvider appConfigProvider;
|
||||
final List<String> blockedServices;
|
||||
final void Function(List<String>) onConfirm;
|
||||
|
||||
const ServicesModalWidget({
|
||||
Key? key,
|
||||
required this.blockedServices,
|
||||
required this.onConfirm,
|
||||
required this.serversProvider,
|
||||
required this.appConfigProvider
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<ServicesModalWidget> createState() => _ServicesModalStateWidget();
|
||||
}
|
||||
|
||||
class _ServicesModalStateWidget extends State<ServicesModalWidget> {
|
||||
class _ServicesModalStateWidget extends State<ServicesModal> {
|
||||
List<String> blockedServices = [];
|
||||
|
||||
Future loadBlockedServices() async {
|
||||
final result = await getBlockedServices(server: widget.serversProvider.selectedServer!);
|
||||
if (result['result'] == 'success') {
|
||||
widget.serversProvider.setBlockedServicesListLoadStatus(1, true);
|
||||
widget.serversProvider.setBlockedServiceListData(result['data']);
|
||||
}
|
||||
else {
|
||||
widget.serversProvider.setBlockedServicesListLoadStatus(2, true);
|
||||
widget.appConfigProvider.addLog(result['log']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
if (widget.serversProvider.blockedServicesList.loadStatus != 1) {
|
||||
loadBlockedServices();
|
||||
final filteringProvider = Provider.of<FilteringProvider>(context, listen: false);
|
||||
|
||||
if (filteringProvider.blockedServicesLoadStatus != LoadStatus.loaded) {
|
||||
filteringProvider.getBlockedServices();
|
||||
}
|
||||
|
||||
blockedServices = widget.blockedServices;
|
||||
|
@ -88,11 +51,11 @@ class _ServicesModalStateWidget extends State<ServicesModalWidget> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final filteringProvider = Provider.of<FilteringProvider>(context);
|
||||
|
||||
Widget content() {
|
||||
switch (serversProvider.blockedServicesList.loadStatus) {
|
||||
case 0:
|
||||
switch (filteringProvider.blockedServicesLoadStatus) {
|
||||
case LoadStatus.loading:
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: SizedBox(
|
||||
|
@ -116,34 +79,34 @@ class _ServicesModalStateWidget extends State<ServicesModalWidget> {
|
|||
),
|
||||
);
|
||||
|
||||
case 1:
|
||||
case LoadStatus.loaded:
|
||||
return SizedBox(
|
||||
width: double.minPositive,
|
||||
height: MediaQuery.of(context).size.height*0.5,
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: serversProvider.blockedServicesList.services!.length,
|
||||
itemCount: filteringProvider.blockedServices!.services.length,
|
||||
itemBuilder: (context, index) => CheckboxListTile(
|
||||
title: Padding(
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
child: Text(
|
||||
serversProvider.blockedServicesList.services![index].name,
|
||||
filteringProvider.blockedServices!.services[index].name,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).colorScheme.onSurface
|
||||
),
|
||||
),
|
||||
),
|
||||
value: blockedServices.contains(serversProvider.blockedServicesList.services![index].id),
|
||||
value: blockedServices.contains(filteringProvider.blockedServices!.services[index].id),
|
||||
checkboxShape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5)
|
||||
),
|
||||
onChanged: (value) => checkUncheckService(value!, serversProvider.blockedServicesList.services![index].id)
|
||||
onChanged: (value) => checkUncheckService(value!, filteringProvider.blockedServices!.services[index].id)
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
case 2:
|
||||
case LoadStatus.error:
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: SizedBox(
|
||||
|
|
|
@ -9,13 +9,10 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
import 'package:adguard_home_manager/screens/filters/add_custom_rule.dart';
|
||||
import 'package:adguard_home_manager/screens/filters/add_list_modal.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/filtering_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/models/filtering.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class AddFiltersButton extends StatelessWidget {
|
||||
final String type;
|
||||
|
@ -29,7 +26,7 @@ class AddFiltersButton extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final filteringProvider = Provider.of<FilteringProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
@ -38,18 +35,11 @@ class AddFiltersButton extends StatelessWidget {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.addingRule);
|
||||
|
||||
final List<String> newRules = serversProvider.filtering.data!.userRules;
|
||||
newRules.add(rule);
|
||||
|
||||
final result = await setCustomRules(server: serversProvider.selectedServer!, rules: newRules);
|
||||
final result = await filteringProvider.addCustomRule(rule);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
FilteringData filteringData = serversProvider.filtering.data!;
|
||||
filteringData.userRules = newRules;
|
||||
serversProvider.setFilteringData(filteringData);
|
||||
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.ruleAddedSuccessfully,
|
||||
|
@ -57,8 +47,6 @@ class AddFiltersButton extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.ruleNotAdded,
|
||||
|
@ -95,58 +83,25 @@ class AddFiltersButton extends StatelessWidget {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.addingList);
|
||||
|
||||
final result1 = await addFilteringList(server: serversProvider.selectedServer!, data: {
|
||||
'name': name,
|
||||
'url': url,
|
||||
'whitelist': type == 'whitelist' ? true : false
|
||||
});
|
||||
final result = await filteringProvider.addList(name: name, url: url, type: type);
|
||||
|
||||
if (result1['result'] == 'success') {
|
||||
if (result1['data'].toString().contains("OK")) {
|
||||
final result2 = await getFiltering(server: serversProvider.selectedServer!);
|
||||
final items = result1['data'].toString().split(' ')[1];
|
||||
processModal.close();
|
||||
|
||||
if (result2['result'] == 'success') {
|
||||
serversProvider.setFilteringData(result2['data']);
|
||||
serversProvider.setFilteringLoadStatus(LoadStatus.loaded, true);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result2['log']);
|
||||
serversProvider.setFilteringLoadStatus(LoadStatus.error, true);
|
||||
}
|
||||
|
||||
processModal.close();
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: "${AppLocalizations.of(context)!.listAdded} $items.",
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else {
|
||||
processModal.close();
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listNotAdded,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
if (result['success'] == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: "${AppLocalizations.of(context)!.listAdded} ${result['data']}.",
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else if (result1['result'] == 'error' && result1['log'].statusCode == '400' && result1['log'].resBody.toString().contains("Couldn't fetch filter from url")) {
|
||||
processModal.close();
|
||||
appConfigProvider.addLog(result1['log']);
|
||||
|
||||
else if (result['success'] == false && result['error'] == 'invalid_url') {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listUrlInvalid,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
else if (result1['result'] == 'error' && result1['log'].statusCode == '400' && result1['log'].resBody.toString().contains('Filter URL already added')) {
|
||||
processModal.close();
|
||||
appConfigProvider.addLog(result1['log']);
|
||||
|
||||
else if (result['success'] == false && result['error'] == 'url_exists') {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listAlreadyAdded,
|
||||
|
@ -154,9 +109,6 @@ class AddFiltersButton extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
else {
|
||||
processModal.close();
|
||||
appConfigProvider.addLog(result1['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listNotAdded,
|
||||
|
|
|
@ -7,11 +7,11 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
import 'package:adguard_home_manager/models/blocked_services.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/filtering_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class BlockedServicesScreen extends StatelessWidget {
|
||||
class BlockedServicesScreen extends StatefulWidget {
|
||||
final bool dialog;
|
||||
|
||||
const BlockedServicesScreen({
|
||||
|
@ -20,63 +20,28 @@ class BlockedServicesScreen extends StatelessWidget {
|
|||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
return BlockedServicesScreenWidget(
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider,
|
||||
dialog: dialog,
|
||||
);
|
||||
}
|
||||
State<BlockedServicesScreen> createState() => _BlockedServicesScreenStateWidget();
|
||||
}
|
||||
|
||||
class BlockedServicesScreenWidget extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
final AppConfigProvider appConfigProvider;
|
||||
final bool dialog;
|
||||
|
||||
const BlockedServicesScreenWidget({
|
||||
Key? key,
|
||||
required this.serversProvider,
|
||||
required this.appConfigProvider,
|
||||
required this.dialog
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<BlockedServicesScreenWidget> createState() => _BlockedServicesScreenStateWidget();
|
||||
}
|
||||
|
||||
class _BlockedServicesScreenStateWidget extends State<BlockedServicesScreenWidget> {
|
||||
class _BlockedServicesScreenStateWidget extends State<BlockedServicesScreen> {
|
||||
List<String> values = [];
|
||||
|
||||
Future loadBlockedServices() async {
|
||||
final result = await getBlockedServices(server: widget.serversProvider.selectedServer!);
|
||||
if (result['result'] == 'success') {
|
||||
widget.serversProvider.setBlockedServicesListLoadStatus(1, true);
|
||||
widget.serversProvider.setBlockedServiceListData(result['data']);
|
||||
}
|
||||
else {
|
||||
widget.serversProvider.setBlockedServicesListLoadStatus(2, true);
|
||||
widget.appConfigProvider.addLog(result['log']);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
if (widget.serversProvider.blockedServicesList.loadStatus != 1) {
|
||||
loadBlockedServices();
|
||||
final filteringProvider = Provider.of<FilteringProvider>(context, listen: false);
|
||||
|
||||
if (filteringProvider.blockedServicesLoadStatus != LoadStatus.loaded) {
|
||||
filteringProvider.loadBlockedServices(showLoading: true);
|
||||
}
|
||||
|
||||
values = widget.serversProvider.filtering.data!.blockedServices;
|
||||
values = filteringProvider.filtering!.blockedServices;
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final filteringProvider = Provider.of<FilteringProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
void updateValues(bool value, BlockedService item) {
|
||||
|
@ -96,13 +61,11 @@ class _BlockedServicesScreenStateWidget extends State<BlockedServicesScreenWidge
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.updating);
|
||||
|
||||
final result = await setBlockedServices(server: serversProvider.selectedServer!, data: values);
|
||||
final result = await filteringProvider.updateBlockedServices(values);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
serversProvider.setBlockedServices(values);
|
||||
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.blockedServicesUpdated,
|
||||
|
@ -119,8 +82,8 @@ class _BlockedServicesScreenStateWidget extends State<BlockedServicesScreenWidge
|
|||
}
|
||||
|
||||
Widget body() {
|
||||
switch (serversProvider.blockedServicesList.loadStatus) {
|
||||
case 0:
|
||||
switch (filteringProvider.blockedServicesLoadStatus) {
|
||||
case LoadStatus.loading:
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
width: double.maxFinite,
|
||||
|
@ -142,15 +105,15 @@ class _BlockedServicesScreenStateWidget extends State<BlockedServicesScreenWidge
|
|||
),
|
||||
);
|
||||
|
||||
case 1:
|
||||
case LoadStatus.loaded:
|
||||
return ListView.builder(
|
||||
itemCount: serversProvider.blockedServicesList.services!.length,
|
||||
itemCount: filteringProvider.blockedServices!.services.length,
|
||||
itemBuilder: (context, index) => Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () => updateValues(
|
||||
values.contains(serversProvider.blockedServicesList.services![index].id),
|
||||
serversProvider.blockedServicesList.services![index]
|
||||
values.contains(filteringProvider.blockedServices!.services[index].id),
|
||||
filteringProvider.blockedServices!.services[index]
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
|
@ -163,17 +126,17 @@ class _BlockedServicesScreenStateWidget extends State<BlockedServicesScreenWidge
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
serversProvider.blockedServicesList.services![index].name,
|
||||
filteringProvider.blockedServices!.services[index].name,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Theme.of(context).colorScheme.onSurface
|
||||
),
|
||||
),
|
||||
Checkbox(
|
||||
value: values.contains(serversProvider.blockedServicesList.services![index].id),
|
||||
value: values.contains(filteringProvider.blockedServices!.services[index].id),
|
||||
onChanged: (value) => updateValues(
|
||||
value!,
|
||||
serversProvider.blockedServicesList.services![index]
|
||||
filteringProvider.blockedServices!.services[index]
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5)
|
||||
|
@ -186,7 +149,7 @@ class _BlockedServicesScreenStateWidget extends State<BlockedServicesScreenWidge
|
|||
)
|
||||
);
|
||||
|
||||
case 2:
|
||||
case LoadStatus.error:
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
width: double.maxFinite,
|
||||
|
@ -281,7 +244,16 @@ class _BlockedServicesScreenStateWidget extends State<BlockedServicesScreenWidge
|
|||
],
|
||||
),
|
||||
body: RefreshIndicator(
|
||||
onRefresh: loadBlockedServices,
|
||||
onRefresh: () async {
|
||||
final result = await filteringProvider.loadBlockedServices();
|
||||
if (result == false) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.blockedServicesListNotLoaded,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
},
|
||||
child: body()
|
||||
),
|
||||
);
|
||||
|
|
|
@ -6,7 +6,6 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/get_filtered_status.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class CheckHostModal extends StatefulWidget {
|
||||
|
@ -57,11 +56,11 @@ class _CheckHostModalState extends State<CheckHostModal> {
|
|||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
void checkHost() async {
|
||||
setState(() => resultWidget = checking());
|
||||
|
||||
final result = await serversProvider.apiClient!.checkHostFiltered(host: domainController.text);
|
||||
|
||||
if (mounted) {
|
||||
setState(() => resultWidget = checking());
|
||||
|
||||
final result = await checkHostFiltered(server: serversProvider.selectedServer!, host: domainController.text);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
final status = getFilteredStatus(context, appConfigProvider, result['data']['reason'], true);
|
||||
if (mounted) {
|
||||
|
@ -98,26 +97,24 @@ class _CheckHostModalState extends State<CheckHostModal> {
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (mounted) {
|
||||
setState(() => resultWidget = Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.cancel,
|
||||
size: 18,
|
||||
setState(() => resultWidget = Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.cancel,
|
||||
size: 18,
|
||||
color: Colors.red,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
AppLocalizations.of(context)!.check,
|
||||
style: const TextStyle(
|
||||
color: Colors.red,
|
||||
fontWeight: FontWeight.w500
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
AppLocalizations.of(context)!.check,
|
||||
style: const TextStyle(
|
||||
color: Colors.red,
|
||||
fontWeight: FontWeight.w500
|
||||
),
|
||||
)
|
||||
],
|
||||
));
|
||||
}
|
||||
)
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,18 +2,21 @@
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:provider/provider.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/widgets/tab_content_list.dart';
|
||||
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/filtering_provider.dart';
|
||||
|
||||
class CustomRulesList extends StatefulWidget {
|
||||
final LoadStatus loadStatus;
|
||||
final ScrollController scrollController;
|
||||
final List<String> data;
|
||||
final Future<void> Function() fetchData;
|
||||
final void Function(String) onRemoveCustomRule;
|
||||
|
||||
const CustomRulesList({
|
||||
|
@ -21,7 +24,6 @@ class CustomRulesList extends StatefulWidget {
|
|||
required this.loadStatus,
|
||||
required this.scrollController,
|
||||
required this.data,
|
||||
required this.fetchData,
|
||||
required this.onRemoveCustomRule
|
||||
}) : super(key: key);
|
||||
|
||||
|
@ -55,6 +57,9 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final filteringProvider = Provider.of<FilteringProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
bool checkIfComment(String value) {
|
||||
final regex = RegExp(r'^(!|#).*$');
|
||||
if (regex.hasMatch(value)) {
|
||||
|
@ -155,7 +160,16 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
|||
),
|
||||
const SizedBox(height: 30),
|
||||
TextButton.icon(
|
||||
onPressed: widget.fetchData,
|
||||
onPressed: () async {
|
||||
final result = await filteringProvider.fetchFilters();
|
||||
if (result == false) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.errorLoadFilters,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
},
|
||||
icon: const Icon(Icons.refresh_rounded),
|
||||
label: Text(AppLocalizations.of(context)!.refresh),
|
||||
)
|
||||
|
@ -186,7 +200,16 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
|||
),
|
||||
),
|
||||
loadStatus: widget.loadStatus,
|
||||
onRefresh: widget.fetchData,
|
||||
onRefresh: () async {
|
||||
final result = await filteringProvider.fetchFilters();
|
||||
if (result == false) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.errorLoadFilters,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
},
|
||||
fab: AddFiltersButton(
|
||||
type: 'custom_rule',
|
||||
widget: (fn) => FloatingActionButton(
|
||||
|
|
|
@ -15,115 +15,57 @@ import 'package:adguard_home_manager/screens/filters/blocked_services_screen.dar
|
|||
import 'package:adguard_home_manager/screens/filters/update_interval_lists_modal.dart';
|
||||
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/providers/filtering_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/models/filtering.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/models/clients.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class Filters extends StatelessWidget {
|
||||
class Filters extends StatefulWidget {
|
||||
const Filters({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
return FiltersWidget(
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider
|
||||
);
|
||||
}
|
||||
State<Filters> createState() => _FiltersState();
|
||||
}
|
||||
|
||||
class FiltersWidget extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
final AppConfigProvider appConfigProvider;
|
||||
|
||||
const FiltersWidget({
|
||||
Key? key,
|
||||
required this.serversProvider,
|
||||
required this.appConfigProvider
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<FiltersWidget> createState() => _FiltersWidgetState();
|
||||
}
|
||||
|
||||
class _FiltersWidgetState extends State<FiltersWidget> {
|
||||
Future fetchFilters() async {
|
||||
widget.serversProvider.setFilteringLoadStatus(LoadStatus.loading, false);
|
||||
|
||||
final result = await getFiltering(server: widget.serversProvider.selectedServer!);
|
||||
|
||||
if (mounted) {
|
||||
if (result['result'] == 'success') {
|
||||
widget.serversProvider.setFilteringData(result['data']);
|
||||
widget.serversProvider.setFilteringLoadStatus(LoadStatus.loaded, false);
|
||||
}
|
||||
else {
|
||||
widget.appConfigProvider.addLog(result['log']);
|
||||
widget.serversProvider.setFilteringLoadStatus(LoadStatus.error, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _FiltersState extends State<Filters> {
|
||||
List<AutoClient> generateClientsList(List<AutoClient> clients, List<String> ips) {
|
||||
return clients.where((client) => ips.contains(client.ip)).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
fetchFilters();
|
||||
final filteringProvider = Provider.of<FilteringProvider>(context, listen: false);
|
||||
filteringProvider.fetchFilters(showLoading: true);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final filteringProvider = Provider.of<FilteringProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
||||
void fetchUpdateLists() async {
|
||||
void updateLists() async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.updatingLists);
|
||||
|
||||
final result = await updateLists(server: serversProvider.selectedServer!);
|
||||
final result = await filteringProvider.updateLists();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
final result2 = await getFiltering(server: widget.serversProvider.selectedServer!);
|
||||
processModal.close();
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (mounted) {
|
||||
if (result2['result'] == 'success') {
|
||||
widget.serversProvider.setFilteringData(result2['data']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: "${result['data']['updated']} ${AppLocalizations.of(context)!.listsUpdated}",
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else {
|
||||
widget.appConfigProvider.addLog(result2['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listsNotLoaded,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (result['success'] == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: "${result['data']['updated']} ${AppLocalizations.of(context)!.listsUpdated}",
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else {
|
||||
processModal.close();
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listsNotUpdated,
|
||||
|
@ -158,21 +100,16 @@ class _FiltersWidgetState extends State<FiltersWidget> {
|
|||
void enableDisableFiltering() async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(
|
||||
serversProvider.serverStatus.data!.filteringEnabled == true
|
||||
statusProvider.serverStatus!.filteringEnabled == true
|
||||
? AppLocalizations.of(context)!.disableFiltering
|
||||
: AppLocalizations.of(context)!.enableFiltering
|
||||
);
|
||||
|
||||
final result = await updateFiltering(
|
||||
server: serversProvider.selectedServer!,
|
||||
enable: !serversProvider.serverStatus.data!.filteringEnabled
|
||||
);
|
||||
final result = await filteringProvider.enableDisableFiltering();
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
serversProvider.setFilteringProtectionStatus(!serversProvider.serverStatus.data!.filteringEnabled);
|
||||
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.filteringStatusUpdated,
|
||||
|
@ -192,16 +129,11 @@ class _FiltersWidgetState extends State<FiltersWidget> {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.changingUpdateFrequency);
|
||||
|
||||
final result = await requestChangeUpdateFrequency(server: serversProvider.selectedServer!, data: {
|
||||
"enabled": serversProvider.filtering.data!.enabled,
|
||||
"interval": value
|
||||
});
|
||||
final result = await filteringProvider.changeUpdateFrequency(value);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
serversProvider.setFiltersUpdateFrequency(value);
|
||||
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.updateFrequencyChanged,
|
||||
|
@ -244,17 +176,11 @@ class _FiltersWidgetState extends State<FiltersWidget> {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.deletingRule);
|
||||
|
||||
final List<String> newRules = serversProvider.filtering.data!.userRules.where((r) => r != rule).toList();
|
||||
|
||||
final result = await setCustomRules(server: serversProvider.selectedServer!, rules: newRules);
|
||||
final result = await filteringProvider.removeCustomRule(rule);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
FilteringData filteringData = serversProvider.filtering.data!;
|
||||
filteringData.userRules = newRules;
|
||||
serversProvider.setFilteringData(filteringData);
|
||||
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.ruleRemovedSuccessfully,
|
||||
|
@ -262,13 +188,11 @@ class _FiltersWidgetState extends State<FiltersWidget> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.ruleNotRemoved,
|
||||
color: Colors.red
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,11 +231,11 @@ class _FiltersWidgetState extends State<FiltersWidget> {
|
|||
}
|
||||
|
||||
List<Widget> actions() {
|
||||
if (serversProvider.filtering.loadStatus == LoadStatus.loaded) {
|
||||
if (filteringProvider.loadStatus == LoadStatus.loaded) {
|
||||
return [
|
||||
IconButton(
|
||||
if (statusProvider.loadStatus == LoadStatus.loaded) IconButton(
|
||||
onPressed: enableDisableFiltering,
|
||||
tooltip: serversProvider.filtering.data!.enabled == true
|
||||
tooltip: filteringProvider.filtering!.enabled == true
|
||||
? AppLocalizations.of(context)!.disableFiltering
|
||||
: AppLocalizations.of(context)!.enableFiltering,
|
||||
icon: Stack(
|
||||
|
@ -328,11 +252,11 @@ class _FiltersWidgetState extends State<FiltersWidget> {
|
|||
color: Colors.white
|
||||
),
|
||||
child: Icon(
|
||||
serversProvider.filtering.data!.enabled == true
|
||||
filteringProvider.filtering!.enabled == true
|
||||
? Icons.check_circle_rounded
|
||||
: Icons.cancel,
|
||||
size: 12,
|
||||
color: serversProvider.filtering.data!.enabled == true
|
||||
color: filteringProvider.filtering!.enabled == true
|
||||
? appConfigProvider.useThemeColorForStatus == true
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Colors.green
|
||||
|
@ -353,7 +277,7 @@ class _FiltersWidgetState extends State<FiltersWidget> {
|
|||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => UpdateIntervalListsModal(
|
||||
interval: serversProvider.filtering.data!.interval,
|
||||
interval: filteringProvider.filtering!.interval,
|
||||
onChange: setUpdateFrequency,
|
||||
dialog: true,
|
||||
),
|
||||
|
@ -363,7 +287,7 @@ class _FiltersWidgetState extends State<FiltersWidget> {
|
|||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => UpdateIntervalListsModal(
|
||||
interval: serversProvider.filtering.data!.interval,
|
||||
interval: filteringProvider.filtering!.interval,
|
||||
onChange: setUpdateFrequency,
|
||||
dialog: false,
|
||||
),
|
||||
|
@ -378,7 +302,7 @@ class _FiltersWidgetState extends State<FiltersWidget> {
|
|||
PopupMenuButton(
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(
|
||||
onTap: fetchUpdateLists,
|
||||
onTap: updateLists,
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.sync_rounded),
|
||||
|
@ -422,13 +346,11 @@ class _FiltersWidgetState extends State<FiltersWidget> {
|
|||
onRemoveCustomRule: openRemoveCustomRuleModal,
|
||||
onOpenDetailsModal: openListDetails,
|
||||
actions: actions(),
|
||||
refreshData: fetchFilters,
|
||||
);
|
||||
}
|
||||
else {
|
||||
return FiltersTabsView(
|
||||
appConfigProvider: appConfigProvider,
|
||||
fetchFilters: fetchFilters,
|
||||
appConfigProvider: appConfigProvider,
|
||||
actions: actions(),
|
||||
onRemoveCustomRule: openRemoveCustomRuleModal,
|
||||
onOpenDetailsModal: openListDetails,
|
||||
|
|
|
@ -14,6 +14,8 @@ import 'package:adguard_home_manager/widgets/tab_content_list.dart';
|
|||
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/providers/filtering_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/number_format.dart';
|
||||
import 'package:adguard_home_manager/models/filtering.dart';
|
||||
|
||||
|
@ -21,7 +23,6 @@ class FiltersList extends StatefulWidget {
|
|||
final LoadStatus loadStatus;
|
||||
final ScrollController scrollController;
|
||||
final List<Filter> data;
|
||||
final Future<void> Function() fetchData;
|
||||
final String type;
|
||||
final void Function(Filter, String) onOpenDetailsScreen;
|
||||
|
||||
|
@ -30,7 +31,6 @@ class FiltersList extends StatefulWidget {
|
|||
required this.loadStatus,
|
||||
required this.scrollController,
|
||||
required this.data,
|
||||
required this.fetchData,
|
||||
required this.type,
|
||||
required this.onOpenDetailsScreen
|
||||
}) : super(key: key);
|
||||
|
@ -65,6 +65,7 @@ class _FiltersListState extends State<FiltersList> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final filteringProvider = Provider.of<FilteringProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
return CustomTabContentList(
|
||||
|
@ -129,7 +130,16 @@ class _FiltersListState extends State<FiltersList> {
|
|||
),
|
||||
const SizedBox(height: 30),
|
||||
TextButton.icon(
|
||||
onPressed: widget.fetchData,
|
||||
onPressed: () async {
|
||||
final result = await filteringProvider.fetchFilters();
|
||||
if (result == false) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.errorLoadFilters,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
},
|
||||
icon: const Icon(Icons.refresh_rounded),
|
||||
label: Text(AppLocalizations.of(context)!.refresh),
|
||||
)
|
||||
|
@ -160,7 +170,16 @@ class _FiltersListState extends State<FiltersList> {
|
|||
),
|
||||
),
|
||||
loadStatus: widget.loadStatus,
|
||||
onRefresh: widget.fetchData,
|
||||
onRefresh: () async {
|
||||
final result = await filteringProvider.fetchFilters();
|
||||
if (result == false) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.errorLoadFilters,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
},
|
||||
fab: AddFiltersButton(
|
||||
type: widget.type,
|
||||
widget: (fn) => FloatingActionButton(
|
||||
|
|
|
@ -5,14 +5,13 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
import 'package:adguard_home_manager/screens/filters/custom_rules_list.dart';
|
||||
import 'package:adguard_home_manager/screens/filters/filters_list.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/filtering_provider.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/models/filtering.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class FiltersTabsView extends StatefulWidget {
|
||||
final AppConfigProvider appConfigProvider;
|
||||
final Future Function() fetchFilters;
|
||||
final List<Widget> actions;
|
||||
final void Function(String) onRemoveCustomRule;
|
||||
final void Function(Filter, String) onOpenDetailsModal;
|
||||
|
@ -20,7 +19,6 @@ class FiltersTabsView extends StatefulWidget {
|
|||
const FiltersTabsView({
|
||||
Key? key,
|
||||
required this.appConfigProvider,
|
||||
required this.fetchFilters,
|
||||
required this.actions,
|
||||
required this.onOpenDetailsModal,
|
||||
required this.onRemoveCustomRule
|
||||
|
@ -36,7 +34,6 @@ class _FiltersTabsViewState extends State<FiltersTabsView> with TickerProviderSt
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
widget.fetchFilters();
|
||||
super.initState();
|
||||
tabController = TabController(
|
||||
initialIndex: 0,
|
||||
|
@ -48,7 +45,7 @@ class _FiltersTabsViewState extends State<FiltersTabsView> with TickerProviderSt
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final filteringProvider = Provider.of<FilteringProvider>(context);
|
||||
|
||||
return DefaultTabController(
|
||||
length: 3,
|
||||
|
@ -110,29 +107,26 @@ class _FiltersTabsViewState extends State<FiltersTabsView> with TickerProviderSt
|
|||
controller: tabController,
|
||||
children: [
|
||||
FiltersList(
|
||||
loadStatus: serversProvider.filtering.loadStatus,
|
||||
loadStatus: filteringProvider.loadStatus,
|
||||
scrollController: scrollController,
|
||||
type: 'whitelist',
|
||||
data: serversProvider.filtering.loadStatus == LoadStatus.loaded
|
||||
? serversProvider.filtering.data!.whitelistFilters : [],
|
||||
fetchData: widget.fetchFilters,
|
||||
data: filteringProvider.loadStatus == LoadStatus.loaded
|
||||
? filteringProvider.filtering!.whitelistFilters : [],
|
||||
onOpenDetailsScreen: widget.onOpenDetailsModal,
|
||||
),
|
||||
FiltersList(
|
||||
loadStatus: serversProvider.filtering.loadStatus,
|
||||
loadStatus: filteringProvider.loadStatus,
|
||||
scrollController: scrollController,
|
||||
type: 'blacklist',
|
||||
data: serversProvider.filtering.loadStatus == LoadStatus.loaded
|
||||
? serversProvider.filtering.data!.filters : [],
|
||||
fetchData: widget.fetchFilters,
|
||||
data: filteringProvider.loadStatus == LoadStatus.loaded
|
||||
? filteringProvider.filtering!.filters : [],
|
||||
onOpenDetailsScreen: widget.onOpenDetailsModal,
|
||||
),
|
||||
CustomRulesList(
|
||||
loadStatus: serversProvider.filtering.loadStatus,
|
||||
loadStatus: filteringProvider.loadStatus,
|
||||
scrollController: scrollController,
|
||||
data: serversProvider.filtering.loadStatus == LoadStatus.loaded
|
||||
? serversProvider.filtering.data!.userRules : [],
|
||||
fetchData: widget.fetchFilters,
|
||||
data: filteringProvider.loadStatus == LoadStatus.loaded
|
||||
? filteringProvider.filtering!.userRules : [],
|
||||
onRemoveCustomRule: widget.onRemoveCustomRule,
|
||||
),
|
||||
]
|
||||
|
|
|
@ -14,41 +14,30 @@ import 'package:adguard_home_manager/widgets/options_modal.dart';
|
|||
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/models/menu_option.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/functions/copy_clipboard.dart';
|
||||
import 'package:adguard_home_manager/providers/filtering_provider.dart';
|
||||
import 'package:adguard_home_manager/models/filtering.dart';
|
||||
import 'package:adguard_home_manager/functions/number_format.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class FiltersTripleColumn extends StatelessWidget {
|
||||
final void Function(String) onRemoveCustomRule;
|
||||
final void Function(Filter, String) onOpenDetailsModal;
|
||||
final List<Widget> actions;
|
||||
final Future Function() refreshData;
|
||||
|
||||
const FiltersTripleColumn({
|
||||
Key? key,
|
||||
required this.onRemoveCustomRule,
|
||||
required this.onOpenDetailsModal,
|
||||
required this.actions,
|
||||
required this.refreshData
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final filteringProvider = Provider.of<FilteringProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
bool checkIfComment(String value) {
|
||||
final regex = RegExp(r'^(!|#).*$');
|
||||
if (regex.hasMatch(value)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Widget? generateSubtitle(String rule) {
|
||||
final allowRegex = RegExp(r'^@@.*$');
|
||||
final blockRegex = RegExp(r'^\|\|.*$');
|
||||
|
@ -84,7 +73,7 @@ class FiltersTripleColumn extends StatelessWidget {
|
|||
}
|
||||
|
||||
Widget content() {
|
||||
switch (serversProvider.filtering.loadStatus) {
|
||||
switch (filteringProvider.loadStatus) {
|
||||
case LoadStatus.loading:
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
@ -140,18 +129,18 @@ class FiltersTripleColumn extends StatelessWidget {
|
|||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: serversProvider.filtering.data!.whitelistFilters.length,
|
||||
itemCount: filteringProvider.filtering!.whitelistFilters.length,
|
||||
itemBuilder: (context, index) => ListOptionsMenu(
|
||||
list: serversProvider.filtering.data!.whitelistFilters[index],
|
||||
list: filteringProvider.filtering!.whitelistFilters[index],
|
||||
listType: 'whitelist',
|
||||
child: CustomListTile(
|
||||
title: serversProvider.filtering.data!.whitelistFilters[index].name,
|
||||
subtitle: "${intFormat(serversProvider.filtering.data!.whitelistFilters[index].rulesCount, Platform.localeName)} ${AppLocalizations.of(context)!.enabledRules}",
|
||||
title: filteringProvider.filtering!.whitelistFilters[index].name,
|
||||
subtitle: "${intFormat(filteringProvider.filtering!.whitelistFilters[index].rulesCount, Platform.localeName)} ${AppLocalizations.of(context)!.enabledRules}",
|
||||
trailing: Icon(
|
||||
serversProvider.filtering.data!.whitelistFilters[index].enabled == true
|
||||
filteringProvider.filtering!.whitelistFilters[index].enabled == true
|
||||
? Icons.check_circle_rounded
|
||||
: Icons.cancel,
|
||||
color: serversProvider.filtering.data!.whitelistFilters[index].enabled == true
|
||||
color: filteringProvider.filtering!.whitelistFilters[index].enabled == true
|
||||
? appConfigProvider.useThemeColorForStatus == true
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Colors.green
|
||||
|
@ -159,7 +148,7 @@ class FiltersTripleColumn extends StatelessWidget {
|
|||
? Colors.grey
|
||||
: Colors.red
|
||||
),
|
||||
onTap: () => onOpenDetailsModal(serversProvider.filtering.data!.whitelistFilters[index], 'whitelist'),
|
||||
onTap: () => onOpenDetailsModal(filteringProvider.filtering!.whitelistFilters[index], 'whitelist'),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -196,18 +185,18 @@ class FiltersTripleColumn extends StatelessWidget {
|
|||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: serversProvider.filtering.data!.filters.length,
|
||||
itemCount: filteringProvider.filtering!.filters.length,
|
||||
itemBuilder: (context, index) => ListOptionsMenu(
|
||||
list: serversProvider.filtering.data!.filters[index],
|
||||
list: filteringProvider.filtering!.filters[index],
|
||||
listType: 'blacklist',
|
||||
child: CustomListTile(
|
||||
title: serversProvider.filtering.data!.filters[index].name,
|
||||
subtitle: "${intFormat(serversProvider.filtering.data!.filters[index].rulesCount, Platform.localeName)} ${AppLocalizations.of(context)!.enabledRules}",
|
||||
title: filteringProvider.filtering!.filters[index].name,
|
||||
subtitle: "${intFormat(filteringProvider.filtering!.filters[index].rulesCount, Platform.localeName)} ${AppLocalizations.of(context)!.enabledRules}",
|
||||
trailing: Icon(
|
||||
serversProvider.filtering.data!.filters[index].enabled == true
|
||||
filteringProvider.filtering!.filters[index].enabled == true
|
||||
? Icons.check_circle_rounded
|
||||
: Icons.cancel,
|
||||
color: serversProvider.filtering.data!.filters[index].enabled == true
|
||||
color: filteringProvider.filtering!.filters[index].enabled == true
|
||||
? appConfigProvider.useThemeColorForStatus == true
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Colors.green
|
||||
|
@ -215,7 +204,7 @@ class FiltersTripleColumn extends StatelessWidget {
|
|||
? Colors.grey
|
||||
: Colors.red
|
||||
),
|
||||
onTap: () => onOpenDetailsModal(serversProvider.filtering.data!.filters[index], 'blacklist'),
|
||||
onTap: () => onOpenDetailsModal(filteringProvider.filtering!.filters[index], 'blacklist'),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -252,7 +241,7 @@ class FiltersTripleColumn extends StatelessWidget {
|
|||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: serversProvider.filtering.data!.userRules.length,
|
||||
itemCount: filteringProvider.filtering!.userRules.length,
|
||||
itemBuilder: (context, index) => ContextMenuArea(
|
||||
builder: (context) => [
|
||||
CustomListTile(
|
||||
|
@ -261,7 +250,7 @@ class FiltersTripleColumn extends StatelessWidget {
|
|||
onTap: () {
|
||||
copyToClipboard(
|
||||
context: context,
|
||||
value: serversProvider.filtering.data!.userRules[index],
|
||||
value: filteringProvider.filtering!.userRules[index],
|
||||
successMessage: AppLocalizations.of(context)!.copiedClipboard,
|
||||
);
|
||||
Navigator.pop(context);
|
||||
|
@ -278,17 +267,17 @@ class FiltersTripleColumn extends StatelessWidget {
|
|||
icon: Icons.copy_rounded,
|
||||
action: () => copyToClipboard(
|
||||
context: context,
|
||||
value: serversProvider.filtering.data!.userRules[index],
|
||||
value: filteringProvider.filtering!.userRules[index],
|
||||
successMessage: AppLocalizations.of(context)!.copiedClipboard,
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
),
|
||||
title: serversProvider.filtering.data!.userRules[index],
|
||||
subtitleWidget: generateSubtitle(serversProvider.filtering.data!.userRules[index]),
|
||||
title: filteringProvider.filtering!.userRules[index],
|
||||
subtitleWidget: generateSubtitle(filteringProvider.filtering!.userRules[index]),
|
||||
trailing: IconButton(
|
||||
onPressed: () => onRemoveCustomRule(serversProvider.filtering.data!.userRules[index]),
|
||||
onPressed: () => onRemoveCustomRule(filteringProvider.filtering!.userRules[index]),
|
||||
icon: const Icon(Icons.delete)
|
||||
),
|
||||
),
|
||||
|
@ -340,7 +329,16 @@ class FiltersTripleColumn extends StatelessWidget {
|
|||
title: Text(AppLocalizations.of(context)!.filters),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: refreshData,
|
||||
onPressed: () async {
|
||||
final result = await filteringProvider.fetchFilters();
|
||||
if (result == false) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.errorLoadFilters,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
},
|
||||
icon: const Icon(Icons.refresh_rounded),
|
||||
tooltip: AppLocalizations.of(context)!.refresh,
|
||||
),
|
||||
|
|
|
@ -9,13 +9,13 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
|
||||
import 'package:adguard_home_manager/screens/filters/add_list_modal.dart';
|
||||
import 'package:adguard_home_manager/screens/filters/delete_list_modal.dart';
|
||||
import 'package:adguard_home_manager/screens/filters/list_functions.dart';
|
||||
import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
||||
|
||||
import 'package:adguard_home_manager/functions/format_time.dart';
|
||||
import 'package:adguard_home_manager/providers/filtering_provider.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/models/filtering.dart';
|
||||
|
||||
class ListDetailsScreen extends StatefulWidget {
|
||||
|
@ -60,22 +60,51 @@ class _ListDetailsScreenState extends State<ListDetailsScreen> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final filteringProvider = Provider.of<FilteringProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
||||
Filter? list;
|
||||
try {
|
||||
list = serversProvider.filtering.data != null
|
||||
list = filteringProvider.filtering != null
|
||||
? widget.type == 'whitelist'
|
||||
? serversProvider.filtering.data!.whitelistFilters.firstWhere((l) => l.id == widget.listId)
|
||||
: serversProvider.filtering.data!.filters.firstWhere((l) => l.id == widget.listId)
|
||||
? filteringProvider.filtering!.whitelistFilters.firstWhere((l) => l.id == widget.listId)
|
||||
: filteringProvider.filtering!.filters.firstWhere((l) => l.id == widget.listId)
|
||||
: null;
|
||||
} catch (e) {
|
||||
// ------- //
|
||||
}
|
||||
|
||||
void updateList(FilteringListActions action) async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(
|
||||
list!.enabled == true
|
||||
? AppLocalizations.of(context)!.disablingList
|
||||
: AppLocalizations.of(context)!.enablingList,
|
||||
);
|
||||
final result = await filteringProvider.updateList(
|
||||
list: list,
|
||||
type: widget.type,
|
||||
action: action
|
||||
);
|
||||
processModal.close();
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listDataUpdated,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listDataNotUpdated,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
List<Widget> content() {
|
||||
return [
|
||||
CustomListTile(
|
||||
|
@ -174,29 +203,9 @@ class _ListDetailsScreenState extends State<ListDetailsScreen> {
|
|||
builder: (ctx) => AddListModal(
|
||||
list: list,
|
||||
type: widget.type,
|
||||
onEdit: ({required Filter list, required String type}) async {
|
||||
final result = await editList(
|
||||
context: context,
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider,
|
||||
list: list,
|
||||
type: widget.type
|
||||
);
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listDataUpdated,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listDataNotUpdated,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
},
|
||||
onEdit: ({required Filter list, required String type}) async => updateList(
|
||||
FilteringListActions.edit
|
||||
),
|
||||
dialog: true,
|
||||
),
|
||||
)
|
||||
|
@ -207,29 +216,9 @@ class _ListDetailsScreenState extends State<ListDetailsScreen> {
|
|||
builder: (ctx) => AddListModal(
|
||||
list: list,
|
||||
type: widget.type,
|
||||
onEdit: ({required Filter list, required String type}) async {
|
||||
final result = await editList(
|
||||
context: context,
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider,
|
||||
list: list,
|
||||
type: widget.type
|
||||
);
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listDataUpdated,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listDataNotUpdated,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
},
|
||||
onEdit: ({required Filter list, required String type}) async => updateList(
|
||||
FilteringListActions.edit
|
||||
),
|
||||
dialog: false,
|
||||
),
|
||||
isScrollControlled: true,
|
||||
|
@ -246,13 +235,13 @@ class _ListDetailsScreenState extends State<ListDetailsScreen> {
|
|||
context: context,
|
||||
builder: (c) => DeleteListModal(
|
||||
onConfirm: () async {
|
||||
final result = await deleteList(
|
||||
context: context,
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider,
|
||||
list: list!,
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.deletingList);
|
||||
final result = await filteringProvider.deleteList(
|
||||
listUrl: list!.url,
|
||||
type: widget.type,
|
||||
);
|
||||
processModal.close();
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
|
@ -312,29 +301,11 @@ class _ListDetailsScreenState extends State<ListDetailsScreen> {
|
|||
if (list != null) Row(
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
final result = await enableDisableList(
|
||||
context: context,
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider,
|
||||
list: list!,
|
||||
listType: widget.type,
|
||||
);
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listDataUpdated,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listDataNotUpdated,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
},
|
||||
onPressed: () => updateList(
|
||||
list!.enabled == true
|
||||
? FilteringListActions.disable
|
||||
: FilteringListActions.enable
|
||||
),
|
||||
icon: Icon(
|
||||
list.enabled == true
|
||||
? Icons.gpp_bad_rounded
|
||||
|
@ -399,29 +370,11 @@ class _ListDetailsScreenState extends State<ListDetailsScreen> {
|
|||
: -70,
|
||||
right: 20,
|
||||
child: FloatingActionButton(
|
||||
onPressed: () async {
|
||||
final result = await enableDisableList(
|
||||
context: context,
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider,
|
||||
list: list!,
|
||||
listType: widget.type,
|
||||
);
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listDataUpdated,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.listDataNotUpdated,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
},
|
||||
onPressed: () => updateList(
|
||||
list!.enabled == true
|
||||
? FilteringListActions.disable
|
||||
: FilteringListActions.enable
|
||||
),
|
||||
child: Icon(
|
||||
list.enabled == true
|
||||
? Icons.gpp_bad_rounded
|
||||
|
|
|
@ -1,141 +0,0 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/models/filtering.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
|
||||
Future<bool> enableDisableList({
|
||||
required BuildContext context,
|
||||
required ServersProvider serversProvider,
|
||||
required AppConfigProvider appConfigProvider,
|
||||
required Filter list,
|
||||
required String listType,
|
||||
}) async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(
|
||||
list.enabled == true
|
||||
? AppLocalizations.of(context)!.disablingList
|
||||
: AppLocalizations.of(context)!.enablingList,
|
||||
);
|
||||
|
||||
final result = await updateFilterList(server: serversProvider.selectedServer!, data: {
|
||||
"data": {
|
||||
"enabled": !list.enabled,
|
||||
"name": list.name,
|
||||
"url": list.url
|
||||
},
|
||||
"url": list.url,
|
||||
"whitelist": listType == 'whitelist' ? true : false
|
||||
});
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
final result2 = await getFiltering(server: serversProvider.selectedServer!);
|
||||
|
||||
if (result2['result'] == 'success') {
|
||||
serversProvider.setFilteringData(result2['data']);
|
||||
serversProvider.setFilteringLoadStatus(LoadStatus.loaded, true);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result2['log']);
|
||||
serversProvider.setFilteringLoadStatus(LoadStatus.error, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> editList({
|
||||
required BuildContext context,
|
||||
required ServersProvider serversProvider,
|
||||
required AppConfigProvider appConfigProvider,
|
||||
required Filter list,
|
||||
required String type
|
||||
}) async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.updatingListData);
|
||||
|
||||
final result1 = await updateFilterList(server: serversProvider.selectedServer!, data: {
|
||||
"data": {
|
||||
"enabled": list.enabled,
|
||||
"name": list.name,
|
||||
"url": list.url
|
||||
},
|
||||
"url": list.url,
|
||||
"whitelist": type == 'whitelist' ? true : false
|
||||
});
|
||||
|
||||
if (result1['result'] == 'success') {
|
||||
final result2 = await getFiltering(server: serversProvider.selectedServer!);
|
||||
|
||||
if (result2['result'] == 'success') {
|
||||
serversProvider.setFilteringData(result2['data']);
|
||||
serversProvider.setFilteringLoadStatus(LoadStatus.loaded, true);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result2['log']);
|
||||
serversProvider.setFilteringLoadStatus(LoadStatus.error, true);
|
||||
}
|
||||
|
||||
processModal.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
processModal.close();
|
||||
appConfigProvider.addLog(result1['log']);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> deleteList({
|
||||
required BuildContext context,
|
||||
required ServersProvider serversProvider,
|
||||
required AppConfigProvider appConfigProvider,
|
||||
required Filter list,
|
||||
required String type
|
||||
}) async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.deletingList);
|
||||
|
||||
final result1 = await deleteFilterList(server: serversProvider.selectedServer!, data: {
|
||||
"url": list.url,
|
||||
"whitelist": type == 'whitelist' ? true : false
|
||||
});
|
||||
|
||||
if (result1['result'] == 'success') {
|
||||
final result2 = await getFiltering(server: serversProvider.selectedServer!);
|
||||
|
||||
if (result2['result'] == 'success') {
|
||||
serversProvider.setFilteringData(result2['data']);
|
||||
serversProvider.setFilteringLoadStatus(LoadStatus.loaded, true);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result2['log']);
|
||||
serversProvider.setFilteringLoadStatus(LoadStatus.loading, true);
|
||||
}
|
||||
|
||||
processModal.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
processModal.close();
|
||||
appConfigProvider.addLog(result1['log']);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:contextmenu/contextmenu.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/screens/filters/list_functions.dart';
|
||||
import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
||||
import 'package:adguard_home_manager/widgets/options_modal.dart';
|
||||
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/models/filtering.dart';
|
||||
import 'package:adguard_home_manager/providers/filtering_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/copy_clipboard.dart';
|
||||
import 'package:adguard_home_manager/models/menu_option.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class ListOptionsMenu extends StatelessWidget {
|
||||
final Filter list;
|
||||
|
@ -30,17 +30,27 @@ class ListOptionsMenu extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final filteringProvider = Provider.of<FilteringProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
void enableDisable() async {
|
||||
final result = await enableDisableList(
|
||||
context: context,
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider,
|
||||
list: list,
|
||||
listType: listType,
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(
|
||||
list.enabled == true
|
||||
? AppLocalizations.of(context)!.disablingList
|
||||
: AppLocalizations.of(context)!.enablingList
|
||||
);
|
||||
|
||||
final result = await filteringProvider.updateList(
|
||||
list: list,
|
||||
type: listType,
|
||||
action: list.enabled == true
|
||||
? FilteringListActions.disable
|
||||
: FilteringListActions.enable
|
||||
);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
|
|
|
@ -4,6 +4,8 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
|
||||
import 'package:adguard_home_manager/screens/servers/servers.dart';
|
||||
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/open_url.dart';
|
||||
import 'package:adguard_home_manager/models/server.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
@ -20,6 +22,7 @@ class HomeAppBar extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final Server? server = serversProvider.selectedServer;
|
||||
|
@ -37,22 +40,48 @@ class HomeAppBar extends StatelessWidget {
|
|||
floating: true,
|
||||
centerTitle: false,
|
||||
forceElevated: innerBoxScrolled,
|
||||
leading: Icon(
|
||||
serversProvider.selectedServer != null && serversProvider.serverStatus.data != null
|
||||
? serversProvider.serverStatus.data!.generalEnabled == true
|
||||
? Icons.gpp_good_rounded
|
||||
: Icons.gpp_bad_rounded
|
||||
: Icons.shield,
|
||||
size: 30,
|
||||
color: serversProvider.selectedServer != null && serversProvider.serverStatus.data != null
|
||||
? serversProvider.serverStatus.data!.generalEnabled == true
|
||||
? appConfigProvider.useThemeColorForStatus
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Colors.green
|
||||
: appConfigProvider.useThemeColorForStatus == true
|
||||
? Theme.of(context).colorScheme.onSurface.withOpacity(0.38)
|
||||
: Colors.red
|
||||
: Theme.of(context).colorScheme.onSurface.withOpacity(0.38)
|
||||
leading: Stack(
|
||||
children: [
|
||||
Center(
|
||||
child: Icon(
|
||||
serversProvider.selectedServer != null && statusProvider.serverStatus != null
|
||||
? statusProvider.serverStatus!.generalEnabled == true
|
||||
? Icons.gpp_good_rounded
|
||||
: Icons.gpp_bad_rounded
|
||||
: Icons.shield,
|
||||
size: 30,
|
||||
color: serversProvider.selectedServer != null && statusProvider.serverStatus != null
|
||||
? statusProvider.serverStatus!.generalEnabled == true
|
||||
? appConfigProvider.useThemeColorForStatus
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Colors.green
|
||||
: appConfigProvider.useThemeColorForStatus == true
|
||||
? Theme.of(context).colorScheme.onSurface.withOpacity(0.38)
|
||||
: Colors.red
|
||||
: Theme.of(context).colorScheme.onSurface.withOpacity(0.38)
|
||||
),
|
||||
),
|
||||
if (statusProvider.remainingTime > 0) Positioned(
|
||||
bottom: 15,
|
||||
right: 15,
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(1),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
color: Theme.of(context).colorScheme.surface
|
||||
),
|
||||
child: Icon(
|
||||
Icons.timer_rounded,
|
||||
size: 12,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
title: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
@ -95,7 +124,7 @@ class HomeAppBar extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
),
|
||||
if (serversProvider.selectedServer != null && serversProvider.serverStatus.loadStatus == 1) PopupMenuItem(
|
||||
if (serversProvider.selectedServer != null && statusProvider.loadStatus == LoadStatus.loaded) PopupMenuItem(
|
||||
onTap: () => openUrl("${server!.connectionMethod}://${server.domain}${server.path ?? ""}${server.port != null ? ':${server.port}' : ""}"),
|
||||
child: Row(
|
||||
children: [
|
||||
|
|
|
@ -7,7 +7,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
import 'package:adguard_home_manager/widgets/combined_line_chart.dart';
|
||||
|
||||
import 'package:adguard_home_manager/functions/number_format.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
|
||||
class CombinedChartData {
|
||||
|
@ -51,56 +51,56 @@ class CombinedHomeChart extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
||||
if (serversProvider.serverStatus.data != null) {
|
||||
if (statusProvider.serverStatus != null) {
|
||||
final data = CombinedChartData(
|
||||
totalQueries: CombinedChartItem(
|
||||
label: AppLocalizations.of(context)!.dnsQueries,
|
||||
color: Colors.blue,
|
||||
data: serversProvider.serverStatus.data!.stats.dnsQueries
|
||||
data: statusProvider.serverStatus!.stats.dnsQueries
|
||||
),
|
||||
blockedFilters: appConfigProvider.hideZeroValues == true
|
||||
? removeZero(serversProvider.serverStatus.data!.stats.blockedFiltering) != null
|
||||
? removeZero(statusProvider.serverStatus!.stats.blockedFiltering) != null
|
||||
? CombinedChartItem(
|
||||
label: AppLocalizations.of(context)!.blockedFilters,
|
||||
color: Colors.red,
|
||||
data: serversProvider.serverStatus.data!.stats.blockedFiltering
|
||||
data: statusProvider.serverStatus!.stats.blockedFiltering
|
||||
)
|
||||
: null
|
||||
: CombinedChartItem(
|
||||
label: AppLocalizations.of(context)!.blockedFilters,
|
||||
color: Colors.red,
|
||||
data: serversProvider.serverStatus.data!.stats.blockedFiltering
|
||||
data: statusProvider.serverStatus!.stats.blockedFiltering
|
||||
) ,
|
||||
replacedSafeBrowsing: appConfigProvider.hideZeroValues == true
|
||||
? removeZero(serversProvider.serverStatus.data!.stats.replacedSafebrowsing) != null
|
||||
? removeZero(statusProvider.serverStatus!.stats.replacedSafebrowsing) != null
|
||||
? CombinedChartItem(
|
||||
label: AppLocalizations.of(context)!.malwarePhisingBlocked,
|
||||
color: Colors.green,
|
||||
data: serversProvider.serverStatus.data!.stats.replacedSafebrowsing
|
||||
data: statusProvider.serverStatus!.stats.replacedSafebrowsing
|
||||
)
|
||||
: null
|
||||
: CombinedChartItem(
|
||||
label: AppLocalizations.of(context)!.malwarePhisingBlocked,
|
||||
color: Colors.green,
|
||||
data: serversProvider.serverStatus.data!.stats.replacedSafebrowsing
|
||||
data: statusProvider.serverStatus!.stats.replacedSafebrowsing
|
||||
) ,
|
||||
replacedParental: appConfigProvider.hideZeroValues == true
|
||||
? removeZero(serversProvider.serverStatus.data!.stats.replacedParental) != null
|
||||
? removeZero(statusProvider.serverStatus!.stats.replacedParental) != null
|
||||
? CombinedChartItem(
|
||||
label: AppLocalizations.of(context)!.blockedAdultWebsites,
|
||||
color: Colors.orange,
|
||||
data: serversProvider.serverStatus.data!.stats.replacedParental
|
||||
data: statusProvider.serverStatus!.stats.replacedParental
|
||||
)
|
||||
: null
|
||||
: CombinedChartItem(
|
||||
label: AppLocalizations.of(context)!.blockedAdultWebsites,
|
||||
color: Colors.orange,
|
||||
data: serversProvider.serverStatus.data!.stats.replacedParental
|
||||
data: statusProvider.serverStatus!.stats.replacedParental
|
||||
) ,
|
||||
);
|
||||
|
||||
|
@ -184,29 +184,29 @@ class CombinedHomeChart extends StatelessWidget {
|
|||
legend(
|
||||
label: data.totalQueries.label,
|
||||
color: data.totalQueries.color,
|
||||
primaryValue: intFormat(serversProvider.serverStatus.data!.stats.numDnsQueries, Platform.localeName),
|
||||
secondaryValue: "${doubleFormat(serversProvider.serverStatus.data!.stats.avgProcessingTime*1000, Platform.localeName)} ms",
|
||||
primaryValue: intFormat(statusProvider.serverStatus!.stats.numDnsQueries, Platform.localeName),
|
||||
secondaryValue: "${doubleFormat(statusProvider.serverStatus!.stats.avgProcessingTime*1000, Platform.localeName)} ms",
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
if (data.blockedFilters != null) legend(
|
||||
label: data.blockedFilters!.label,
|
||||
color: data.blockedFilters!.color,
|
||||
primaryValue: intFormat(serversProvider.serverStatus.data!.stats.numBlockedFiltering, Platform.localeName),
|
||||
secondaryValue: "${serversProvider.serverStatus.data!.stats.numDnsQueries > 0 ? doubleFormat((serversProvider.serverStatus.data!.stats.numBlockedFiltering/serversProvider.serverStatus.data!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
primaryValue: intFormat(statusProvider.serverStatus!.stats.numBlockedFiltering, Platform.localeName),
|
||||
secondaryValue: "${statusProvider.serverStatus!.stats.numDnsQueries > 0 ? doubleFormat((statusProvider.serverStatus!.stats.numBlockedFiltering/statusProvider.serverStatus!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
if (data.replacedSafeBrowsing != null) legend(
|
||||
label: data.replacedSafeBrowsing!.label,
|
||||
color: data.replacedSafeBrowsing!.color,
|
||||
primaryValue: intFormat(serversProvider.serverStatus.data!.stats.numReplacedSafebrowsing, Platform.localeName),
|
||||
secondaryValue: "${serversProvider.serverStatus.data!.stats.numDnsQueries > 0 ? doubleFormat((serversProvider.serverStatus.data!.stats.numReplacedSafebrowsing/serversProvider.serverStatus.data!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
primaryValue: intFormat(statusProvider.serverStatus!.stats.numReplacedSafebrowsing, Platform.localeName),
|
||||
secondaryValue: "${statusProvider.serverStatus!.stats.numDnsQueries > 0 ? doubleFormat((statusProvider.serverStatus!.stats.numReplacedSafebrowsing/statusProvider.serverStatus!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
if (data.replacedParental != null) legend(
|
||||
label: data.replacedParental!.label,
|
||||
color: data.replacedParental!.color,
|
||||
primaryValue: intFormat(serversProvider.serverStatus.data!.stats.numReplacedParental, Platform.localeName),
|
||||
secondaryValue: "${serversProvider.serverStatus.data!.stats.numDnsQueries > 0 ? doubleFormat((serversProvider.serverStatus.data!.stats.numReplacedParental/serversProvider.serverStatus.data!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
primaryValue: intFormat(statusProvider.serverStatus!.stats.numReplacedParental, Platform.localeName),
|
||||
secondaryValue: "${statusProvider.serverStatus!.stats.numDnsQueries > 0 ? doubleFormat((statusProvider.serverStatus!.stats.numReplacedParental/statusProvider.serverStatus!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -247,29 +247,29 @@ class CombinedHomeChart extends StatelessWidget {
|
|||
legend(
|
||||
label: data.totalQueries.label,
|
||||
color: data.totalQueries.color,
|
||||
primaryValue: intFormat(serversProvider.serverStatus.data!.stats.numDnsQueries, Platform.localeName),
|
||||
secondaryValue: "${doubleFormat(serversProvider.serverStatus.data!.stats.avgProcessingTime*1000, Platform.localeName)} ms",
|
||||
primaryValue: intFormat(statusProvider.serverStatus!.stats.numDnsQueries, Platform.localeName),
|
||||
secondaryValue: "${doubleFormat(statusProvider.serverStatus!.stats.avgProcessingTime*1000, Platform.localeName)} ms",
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
if (data.blockedFilters != null) legend(
|
||||
label: data.blockedFilters!.label,
|
||||
color: data.blockedFilters!.color,
|
||||
primaryValue: intFormat(serversProvider.serverStatus.data!.stats.numBlockedFiltering, Platform.localeName),
|
||||
secondaryValue: "${serversProvider.serverStatus.data!.stats.numDnsQueries > 0 ? doubleFormat((serversProvider.serverStatus.data!.stats.numBlockedFiltering/serversProvider.serverStatus.data!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
primaryValue: intFormat(statusProvider.serverStatus!.stats.numBlockedFiltering, Platform.localeName),
|
||||
secondaryValue: "${statusProvider.serverStatus!.stats.numDnsQueries > 0 ? doubleFormat((statusProvider.serverStatus!.stats.numBlockedFiltering/statusProvider.serverStatus!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
if (data.replacedSafeBrowsing != null) legend(
|
||||
label: data.replacedSafeBrowsing!.label,
|
||||
color: data.replacedSafeBrowsing!.color,
|
||||
primaryValue: intFormat(serversProvider.serverStatus.data!.stats.numReplacedSafebrowsing, Platform.localeName),
|
||||
secondaryValue: "${serversProvider.serverStatus.data!.stats.numDnsQueries > 0 ? doubleFormat((serversProvider.serverStatus.data!.stats.numReplacedSafebrowsing/serversProvider.serverStatus.data!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
primaryValue: intFormat(statusProvider.serverStatus!.stats.numReplacedSafebrowsing, Platform.localeName),
|
||||
secondaryValue: "${statusProvider.serverStatus!.stats.numDnsQueries > 0 ? doubleFormat((statusProvider.serverStatus!.stats.numReplacedSafebrowsing/statusProvider.serverStatus!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
if (data.replacedParental != null) legend(
|
||||
label: data.replacedParental!.label,
|
||||
color: data.replacedParental!.color,
|
||||
primaryValue: intFormat(serversProvider.serverStatus.data!.stats.numReplacedParental, Platform.localeName),
|
||||
secondaryValue: "${serversProvider.serverStatus.data!.stats.numDnsQueries > 0 ? doubleFormat((serversProvider.serverStatus.data!.stats.numReplacedParental/serversProvider.serverStatus.data!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
primaryValue: intFormat(statusProvider.serverStatus!.stats.numReplacedParental, Platform.localeName),
|
||||
secondaryValue: "${statusProvider.serverStatus!.stats.numDnsQueries > 0 ? doubleFormat((statusProvider.serverStatus!.stats.numReplacedParental/statusProvider.serverStatus!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
|
|
|
@ -3,14 +3,15 @@ import 'package:flutter/material.dart';
|
|||
|
||||
import 'package:adguard_home_manager/screens/home/management_modal.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
|
||||
class HomeFab extends StatelessWidget {
|
||||
const HomeFab({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
||||
|
@ -35,7 +36,7 @@ class HomeFab extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
return serversProvider.serverStatus.loadStatus == 1
|
||||
return statusProvider.loadStatus == LoadStatus.loaded
|
||||
? FloatingActionButton(
|
||||
onPressed: openManagementBottomSheet,
|
||||
child: const Icon(Icons.shield_rounded),
|
||||
|
|
|
@ -15,10 +15,10 @@ import 'package:adguard_home_manager/screens/home/top_items.dart';
|
|||
import 'package:adguard_home_manager/screens/home/chart.dart';
|
||||
|
||||
import 'package:adguard_home_manager/functions/number_format.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class Home extends StatefulWidget {
|
||||
const Home({Key? key}) : super(key: key);
|
||||
|
@ -33,6 +33,8 @@ class _HomeState extends State<Home> {
|
|||
|
||||
@override
|
||||
initState(){
|
||||
Provider.of<StatusProvider>(context, listen: false).getServerStatus();
|
||||
|
||||
super.initState();
|
||||
|
||||
isVisible = true;
|
||||
|
@ -54,7 +56,7 @@ class _HomeState extends State<Home> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
@ -109,7 +111,7 @@ class _HomeState extends State<Home> {
|
|||
|
||||
List<Widget> listItems() {
|
||||
return [
|
||||
ServerStatus(serverStatus: serversProvider.serverStatus.data!),
|
||||
ServerStatusWidget(serverStatus: statusProvider.serverStatus!),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Divider(
|
||||
|
@ -124,40 +126,40 @@ class _HomeState extends State<Home> {
|
|||
FractionallySizedBox(
|
||||
widthFactor: width > 700 ? 0.5 : 1,
|
||||
child: HomeChart(
|
||||
data: serversProvider.serverStatus.data!.stats.dnsQueries,
|
||||
data: statusProvider.serverStatus!.stats.dnsQueries,
|
||||
label: AppLocalizations.of(context)!.dnsQueries,
|
||||
primaryValue: intFormat(serversProvider.serverStatus.data!.stats.numDnsQueries, Platform.localeName),
|
||||
secondaryValue: "${doubleFormat(serversProvider.serverStatus.data!.stats.avgProcessingTime*1000, Platform.localeName)} ms",
|
||||
primaryValue: intFormat(statusProvider.serverStatus!.stats.numDnsQueries, Platform.localeName),
|
||||
secondaryValue: "${doubleFormat(statusProvider.serverStatus!.stats.avgProcessingTime*1000, Platform.localeName)} ms",
|
||||
color: Colors.blue,
|
||||
),
|
||||
),
|
||||
FractionallySizedBox(
|
||||
widthFactor: width > 700 ? 0.5 : 1,
|
||||
child: HomeChart(
|
||||
data: serversProvider.serverStatus.data!.stats.blockedFiltering,
|
||||
data: statusProvider.serverStatus!.stats.blockedFiltering,
|
||||
label: AppLocalizations.of(context)!.blockedFilters,
|
||||
primaryValue: intFormat(serversProvider.serverStatus.data!.stats.numBlockedFiltering, Platform.localeName),
|
||||
secondaryValue: "${serversProvider.serverStatus.data!.stats.numDnsQueries > 0 ? doubleFormat((serversProvider.serverStatus.data!.stats.numBlockedFiltering/serversProvider.serverStatus.data!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
primaryValue: intFormat(statusProvider.serverStatus!.stats.numBlockedFiltering, Platform.localeName),
|
||||
secondaryValue: "${statusProvider.serverStatus!.stats.numDnsQueries > 0 ? doubleFormat((statusProvider.serverStatus!.stats.numBlockedFiltering/statusProvider.serverStatus!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
FractionallySizedBox(
|
||||
widthFactor: width > 700 ? 0.5 : 1,
|
||||
child: HomeChart(
|
||||
data: serversProvider.serverStatus.data!.stats.replacedSafebrowsing,
|
||||
data: statusProvider.serverStatus!.stats.replacedSafebrowsing,
|
||||
label: AppLocalizations.of(context)!.malwarePhisingBlocked,
|
||||
primaryValue: intFormat(serversProvider.serverStatus.data!.stats.numReplacedSafebrowsing, Platform.localeName),
|
||||
secondaryValue: "${serversProvider.serverStatus.data!.stats.numDnsQueries > 0 ? doubleFormat((serversProvider.serverStatus.data!.stats.numReplacedSafebrowsing/serversProvider.serverStatus.data!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
primaryValue: intFormat(statusProvider.serverStatus!.stats.numReplacedSafebrowsing, Platform.localeName),
|
||||
secondaryValue: "${statusProvider.serverStatus!.stats.numDnsQueries > 0 ? doubleFormat((statusProvider.serverStatus!.stats.numReplacedSafebrowsing/statusProvider.serverStatus!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
color: Colors.green,
|
||||
),
|
||||
),
|
||||
FractionallySizedBox(
|
||||
widthFactor: width > 700 ? 0.5 : 1,
|
||||
child: HomeChart(
|
||||
data: serversProvider.serverStatus.data!.stats.replacedParental,
|
||||
data: statusProvider.serverStatus!.stats.replacedParental,
|
||||
label: AppLocalizations.of(context)!.blockedAdultWebsites,
|
||||
primaryValue: intFormat(serversProvider.serverStatus.data!.stats.numReplacedParental, Platform.localeName),
|
||||
secondaryValue: "${serversProvider.serverStatus.data!.stats.numDnsQueries > 0 ? doubleFormat((serversProvider.serverStatus.data!.stats.numReplacedParental/serversProvider.serverStatus.data!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
primaryValue: intFormat(statusProvider.serverStatus!.stats.numReplacedParental, Platform.localeName),
|
||||
secondaryValue: "${statusProvider.serverStatus!.stats.numDnsQueries > 0 ? doubleFormat((statusProvider.serverStatus!.stats.numReplacedParental/statusProvider.serverStatus!.stats.numDnsQueries)*100, Platform.localeName) : 0}%",
|
||||
color: Colors.orange,
|
||||
),
|
||||
),
|
||||
|
@ -172,7 +174,7 @@ class _HomeState extends State<Home> {
|
|||
if (width <= 700) ...[
|
||||
TopItems(
|
||||
label: AppLocalizations.of(context)!.topQueriedDomains,
|
||||
data: serversProvider.serverStatus.data!.stats.topQueriedDomains,
|
||||
data: statusProvider.serverStatus!.stats.topQueriedDomains,
|
||||
type: 'topQueriedDomains',
|
||||
),
|
||||
Padding(
|
||||
|
@ -187,7 +189,7 @@ class _HomeState extends State<Home> {
|
|||
|
||||
TopItems(
|
||||
label: AppLocalizations.of(context)!.topBlockedDomains,
|
||||
data: serversProvider.serverStatus.data!.stats.topBlockedDomains,
|
||||
data: statusProvider.serverStatus!.stats.topBlockedDomains,
|
||||
type: 'topBlockedDomains',
|
||||
),
|
||||
Padding(
|
||||
|
@ -201,7 +203,7 @@ class _HomeState extends State<Home> {
|
|||
|
||||
TopItems(
|
||||
label: AppLocalizations.of(context)!.topClients,
|
||||
data: serversProvider.serverStatus.data!.stats.topClients,
|
||||
data: statusProvider.serverStatus!.stats.topClients,
|
||||
type: 'topClients',
|
||||
clients: true,
|
||||
),
|
||||
|
@ -219,7 +221,7 @@ class _HomeState extends State<Home> {
|
|||
),
|
||||
child: TopItems(
|
||||
label: AppLocalizations.of(context)!.topQueriedDomains,
|
||||
data: serversProvider.serverStatus.data!.stats.topQueriedDomains,
|
||||
data: statusProvider.serverStatus!.stats.topQueriedDomains,
|
||||
type: 'topQueriedDomains',
|
||||
),
|
||||
),
|
||||
|
@ -232,7 +234,7 @@ class _HomeState extends State<Home> {
|
|||
),
|
||||
child: TopItems(
|
||||
label: AppLocalizations.of(context)!.topBlockedDomains,
|
||||
data: serversProvider.serverStatus.data!.stats.topBlockedDomains,
|
||||
data: statusProvider.serverStatus!.stats.topBlockedDomains,
|
||||
type: 'topBlockedDomains',
|
||||
),
|
||||
),
|
||||
|
@ -245,7 +247,7 @@ class _HomeState extends State<Home> {
|
|||
),
|
||||
child: TopItems(
|
||||
label: AppLocalizations.of(context)!.topClients,
|
||||
data: serversProvider.serverStatus.data!.stats.topClients,
|
||||
data: statusProvider.serverStatus!.stats.topClients,
|
||||
type: 'topClients',
|
||||
),
|
||||
),
|
||||
|
@ -277,12 +279,8 @@ class _HomeState extends State<Home> {
|
|||
builder: (context) => RefreshIndicator(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
onRefresh: () async {
|
||||
final result = await getServerStatus(serversProvider.selectedServer!);
|
||||
if (result['result'] == 'success') {
|
||||
serversProvider.setServerStatusData(result['data']);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
final result = await statusProvider.getServerStatus();
|
||||
if (result == false) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.serverStatusNotRefreshed,
|
||||
|
@ -295,13 +293,13 @@ class _HomeState extends State<Home> {
|
|||
SliverOverlapInjector(
|
||||
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
|
||||
),
|
||||
if (serversProvider.serverStatus.loadStatus == 0) SliverFillRemaining(
|
||||
if (statusProvider.loadStatus == LoadStatus.loading) SliverFillRemaining(
|
||||
child: loading(),
|
||||
),
|
||||
if (serversProvider.serverStatus.loadStatus == 1) SliverList.list(
|
||||
if (statusProvider.loadStatus == LoadStatus.loaded) SliverList.list(
|
||||
children: listItems()
|
||||
),
|
||||
if (serversProvider.serverStatus.loadStatus == 2) SliverFillRemaining(
|
||||
if (statusProvider.loadStatus == LoadStatus.error) SliverFillRemaining(
|
||||
child: loadError(),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -10,10 +10,9 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||
import 'package:adguard_home_manager/functions/time_server_disabled.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/format_time.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class ManagementModal extends StatefulWidget {
|
||||
final bool dialog;
|
||||
|
@ -32,10 +31,6 @@ class _ManagementModalState extends State<ManagementModal> with SingleTickerProv
|
|||
late Animation<double> animation;
|
||||
final ExpandableController expandableController = ExpandableController();
|
||||
|
||||
DateTime? currentDeadline;
|
||||
Timer? countdown;
|
||||
int start = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
expandableController.addListener(() async {
|
||||
|
@ -66,70 +61,21 @@ class _ManagementModalState extends State<ManagementModal> with SingleTickerProv
|
|||
|
||||
@override
|
||||
void dispose() {
|
||||
if (countdown != null) countdown!.cancel();
|
||||
animationController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
void startTimer(DateTime deadline) {
|
||||
setState(() {
|
||||
currentDeadline = deadline;
|
||||
start = deadline.difference(DateTime.now()).inSeconds+1;
|
||||
});
|
||||
|
||||
const oneSec = Duration(seconds: 1);
|
||||
countdown = Timer.periodic(
|
||||
oneSec,
|
||||
(Timer timer) async {
|
||||
if (start == 0) {
|
||||
setState(() {
|
||||
timer.cancel();
|
||||
});
|
||||
final result = await getServerStatus(serversProvider.selectedServer!);
|
||||
if (result['result'] == 'success') {
|
||||
serversProvider.setServerStatusData(result['data']);
|
||||
}
|
||||
} else {
|
||||
setState(() {
|
||||
start = start - 1;
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
serversProvider.serverStatus.data != null &&
|
||||
serversProvider.serverStatus.data!.disabledUntil != null &&
|
||||
serversProvider.serverStatus.data!.disabledUntil != currentDeadline
|
||||
) {
|
||||
startTimer(serversProvider.serverStatus.data!.disabledUntil!);
|
||||
}
|
||||
|
||||
if (
|
||||
serversProvider.serverStatus.data != null &&
|
||||
serversProvider.serverStatus.data!.generalEnabled == true
|
||||
) {
|
||||
setState(() {
|
||||
start = 0;
|
||||
currentDeadline = null;
|
||||
if (countdown != null) countdown!.cancel();
|
||||
countdown = null;
|
||||
});
|
||||
}
|
||||
|
||||
void updateBlocking({
|
||||
required bool value,
|
||||
required String filter,
|
||||
int? time
|
||||
}) async {
|
||||
final result = await serversProvider.updateBlocking(
|
||||
server: serversProvider.selectedServer!,
|
||||
final result = await statusProvider.updateBlocking(
|
||||
block: filter,
|
||||
newStatus: value,
|
||||
time: time
|
||||
|
@ -164,7 +110,7 @@ class _ManagementModalState extends State<ManagementModal> with SingleTickerProv
|
|||
child: Icon(
|
||||
Icons.keyboard_arrow_down_rounded,
|
||||
size: 26,
|
||||
color: serversProvider.serverStatus.data!.generalEnabled == true
|
||||
color: statusProvider.serverStatus!.generalEnabled == true
|
||||
? Theme.of(context).colorScheme.onSurfaceVariant
|
||||
: Colors.grey,
|
||||
),
|
||||
|
@ -180,10 +126,10 @@ class _ManagementModalState extends State<ManagementModal> with SingleTickerProv
|
|||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
if (serversProvider.serverStatus.data!.timeGeneralDisabled > 0) ...[
|
||||
if (statusProvider.serverStatus!.timeGeneralDisabled > 0) ...[
|
||||
const SizedBox(height: 2),
|
||||
if (currentDeadline != null) Text(
|
||||
"${AppLocalizations.of(context)!.remainingTime}: ${generateRemainingTimeString(currentDeadline!.difference(DateTime.now()))}"
|
||||
if (statusProvider.currentDeadline != null) Text(
|
||||
"${AppLocalizations.of(context)!.remainingTime}: ${formatRemainingSeconds(statusProvider.remainingTime)}"
|
||||
)
|
||||
]
|
||||
],
|
||||
|
@ -191,8 +137,8 @@ class _ManagementModalState extends State<ManagementModal> with SingleTickerProv
|
|||
],
|
||||
),
|
||||
Switch(
|
||||
value: serversProvider.serverStatus.data!.generalEnabled,
|
||||
onChanged: serversProvider.protectionsManagementProcess.contains('general') == false
|
||||
value: statusProvider.serverStatus!.generalEnabled,
|
||||
onChanged: statusProvider.protectionsManagementProcess.contains('general') == false
|
||||
? (value) {
|
||||
if (value == false && expandableController.expanded == true && legacyMode == false) {
|
||||
expandableController.toggle();
|
||||
|
@ -216,35 +162,35 @@ class _ManagementModalState extends State<ManagementModal> with SingleTickerProv
|
|||
children: [
|
||||
ActionChip(
|
||||
label: Text(AppLocalizations.of(context)!.seconds(30)),
|
||||
onPressed: serversProvider.protectionsManagementProcess.contains('general') == false && serversProvider.serverStatus.data!.generalEnabled == true
|
||||
onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true
|
||||
? () => disableWithCountdown(29000)
|
||||
: null,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ActionChip(
|
||||
label: Text(AppLocalizations.of(context)!.minute(1)),
|
||||
onPressed: serversProvider.protectionsManagementProcess.contains('general') == false && serversProvider.serverStatus.data!.generalEnabled == true
|
||||
onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true
|
||||
? () => disableWithCountdown(59000)
|
||||
: null,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ActionChip(
|
||||
label: Text(AppLocalizations.of(context)!.minutes(10)),
|
||||
onPressed: serversProvider.protectionsManagementProcess.contains('general') == false && serversProvider.serverStatus.data!.generalEnabled == true
|
||||
onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true
|
||||
? () => disableWithCountdown(599000)
|
||||
: null,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ActionChip(
|
||||
label: Text(AppLocalizations.of(context)!.hour(1)),
|
||||
onPressed: serversProvider.protectionsManagementProcess.contains('general') == false && serversProvider.serverStatus.data!.generalEnabled == true
|
||||
onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true
|
||||
? () => disableWithCountdown(3599000)
|
||||
: null,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ActionChip(
|
||||
label: Text(AppLocalizations.of(context)!.hours(24)),
|
||||
onPressed: serversProvider.protectionsManagementProcess.contains('general') == false && serversProvider.serverStatus.data!.generalEnabled == true
|
||||
onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true
|
||||
? () => disableWithCountdown(86399000)
|
||||
: null,
|
||||
),
|
||||
|
@ -256,7 +202,7 @@ class _ManagementModalState extends State<ManagementModal> with SingleTickerProv
|
|||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: serverVersionIsAhead(
|
||||
currentVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
currentVersion: statusProvider.serverStatus!.serverVersion,
|
||||
referenceVersion: 'v0.107.28',
|
||||
referenceVersionBeta: 'v0.108.0-b.33'
|
||||
) == true
|
||||
|
@ -266,7 +212,7 @@ class _ManagementModalState extends State<ManagementModal> with SingleTickerProv
|
|||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
child: InkWell(
|
||||
onTap: serversProvider.serverStatus.data!.generalEnabled == true && !serversProvider.protectionsManagementProcess.contains('general')
|
||||
onTap: statusProvider.serverStatus!.generalEnabled == true && !statusProvider.protectionsManagementProcess.contains('general')
|
||||
? () => expandableController.toggle()
|
||||
: null,
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
|
@ -277,7 +223,7 @@ class _ManagementModalState extends State<ManagementModal> with SingleTickerProv
|
|||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
color: Theme.of(context).primaryColor.withOpacity(0.1)
|
||||
color: Theme.of(context).colorScheme.primary.withOpacity(0.1)
|
||||
),
|
||||
child: Expandable(
|
||||
theme: const ExpandableThemeData(
|
||||
|
@ -301,9 +247,9 @@ class _ManagementModalState extends State<ManagementModal> with SingleTickerProv
|
|||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
child: InkWell(
|
||||
onTap: serversProvider.protectionsManagementProcess.contains('general') == false
|
||||
onTap: statusProvider.protectionsManagementProcess.contains('general') == false
|
||||
? () => updateBlocking(
|
||||
value: !serversProvider.serverStatus.data!.generalEnabled,
|
||||
value: !statusProvider.serverStatus!.generalEnabled,
|
||||
filter: 'general_legacy'
|
||||
) : null,
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
|
@ -408,30 +354,30 @@ class _ManagementModalState extends State<ManagementModal> with SingleTickerProv
|
|||
smallSwitch(
|
||||
AppLocalizations.of(context)!.ruleFiltering,
|
||||
Icons.filter_list_rounded,
|
||||
serversProvider.serverStatus.data!.filteringEnabled,
|
||||
statusProvider.serverStatus!.filteringEnabled,
|
||||
(value) => updateBlocking(value: value, filter: 'filtering'),
|
||||
serversProvider.protectionsManagementProcess.contains('filtering')
|
||||
statusProvider.protectionsManagementProcess.contains('filtering')
|
||||
),
|
||||
smallSwitch(
|
||||
AppLocalizations.of(context)!.safeBrowsing,
|
||||
Icons.vpn_lock_rounded,
|
||||
serversProvider.serverStatus.data!.safeBrowsingEnabled,
|
||||
statusProvider.serverStatus!.safeBrowsingEnabled,
|
||||
(value) => updateBlocking(value: value, filter: 'safeBrowsing'),
|
||||
serversProvider.protectionsManagementProcess.contains('safeBrowsing')
|
||||
statusProvider.protectionsManagementProcess.contains('safeBrowsing')
|
||||
),
|
||||
smallSwitch(
|
||||
AppLocalizations.of(context)!.parentalFiltering,
|
||||
Icons.block,
|
||||
serversProvider.serverStatus.data!.parentalControlEnabled,
|
||||
statusProvider.serverStatus!.parentalControlEnabled,
|
||||
(value) => updateBlocking(value: value, filter: 'parentalControl'),
|
||||
serversProvider.protectionsManagementProcess.contains('parentalControl')
|
||||
statusProvider.protectionsManagementProcess.contains('parentalControl')
|
||||
),
|
||||
smallSwitch(
|
||||
AppLocalizations.of(context)!.safeSearch,
|
||||
Icons.search_rounded,
|
||||
serversProvider.serverStatus.data!.safeSearchEnabled,
|
||||
statusProvider.serverStatus!.safeSearchEnabled,
|
||||
(value) => updateBlocking(value: value, filter: 'safeSearch'),
|
||||
serversProvider.protectionsManagementProcess.contains('safeSearch')
|
||||
statusProvider.protectionsManagementProcess.contains('safeSearch')
|
||||
),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@ import 'package:adguard_home_manager/screens/home/status_box.dart';
|
|||
|
||||
import 'package:adguard_home_manager/models/server_status.dart';
|
||||
|
||||
class ServerStatus extends StatelessWidget {
|
||||
final ServerStatusData serverStatus;
|
||||
class ServerStatusWidget extends StatelessWidget {
|
||||
final ServerStatus serverStatus;
|
||||
|
||||
const ServerStatus({
|
||||
const ServerStatusWidget({
|
||||
Key? key,
|
||||
required this.serverStatus,
|
||||
}) : super(key: key);
|
||||
|
|
|
@ -9,16 +9,14 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
|
||||
import 'package:adguard_home_manager/widgets/domain_options.dart';
|
||||
import 'package:adguard_home_manager/screens/top_items/top_items_modal.dart';
|
||||
import 'package:adguard_home_manager/widgets/options_modal.dart';
|
||||
import 'package:adguard_home_manager/screens/top_items/top_items.dart';
|
||||
|
||||
import 'package:adguard_home_manager/models/applied_filters.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/models/menu_option.dart';
|
||||
import 'package:adguard_home_manager/providers/logs_provider.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/models/filtering_status.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
class TopItems extends StatelessWidget {
|
||||
final String type;
|
||||
|
@ -36,7 +34,7 @@ class TopItems extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
final logsProvider = Provider.of<LogsProvider>(context);
|
||||
|
||||
|
@ -58,52 +56,26 @@ class TopItems extends StatelessWidget {
|
|||
final ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.savingUserFilters);
|
||||
|
||||
final rules = await getFilteringRules(server: serversProvider.selectedServer!);
|
||||
final rules = await statusProvider.blockUnblockDomain(
|
||||
domain: domain,
|
||||
newStatus: newStatus
|
||||
);
|
||||
|
||||
if (rules['result'] == 'success') {
|
||||
FilteringStatus oldStatus = serversProvider.serverStatus.data!.filteringStatus;
|
||||
processModal.close();
|
||||
|
||||
List<String> newRules = rules['data'].userRules.where((d) => !d.contains(domain)).toList();
|
||||
if (newStatus == 'block') {
|
||||
newRules.add("||$domain^");
|
||||
}
|
||||
else if (newStatus == 'unblock') {
|
||||
newRules.add("@@||$domain^");
|
||||
}
|
||||
FilteringStatus newObj = serversProvider.serverStatus.data!.filteringStatus;
|
||||
newObj.userRules = newRules;
|
||||
serversProvider.setFilteringStatus(newObj);
|
||||
|
||||
final result = await postFilteringRules(server: serversProvider.selectedServer!, data: {'rules': newRules});
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.userFilteringRulesUpdated),
|
||||
backgroundColor: Colors.green,
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
serversProvider.setFilteringStatus(oldStatus);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.userFilteringRulesNotUpdated),
|
||||
backgroundColor: Colors.red,
|
||||
)
|
||||
);
|
||||
}
|
||||
if (rules == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.userFilteringRulesUpdated,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(rules['log']);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.userFilteringRulesNotUpdated),
|
||||
backgroundColor: Colors.red,
|
||||
)
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.userFilteringRulesNotUpdated,
|
||||
color: Colors.red
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -141,20 +113,11 @@ class TopItems extends StatelessWidget {
|
|||
];
|
||||
}
|
||||
|
||||
void openOptionsModal(String domain, String type) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => OptionsModal(
|
||||
options: generateOptions(domain),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Widget rowItem(Map<String, dynamic> item) {
|
||||
String? name;
|
||||
if (clients != null && clients == true) {
|
||||
try {
|
||||
name = serversProvider.serverStatus.data!.clients.firstWhere((c) => c.ids.contains(item.keys.toList()[0])).name;
|
||||
name = statusProvider.serverStatus!.clients.firstWhere((c) => c.ids.contains(item.keys.toList()[0])).name;
|
||||
} catch (e) {
|
||||
// ---- //
|
||||
}
|
||||
|
@ -241,13 +204,13 @@ class TopItems extends StatelessWidget {
|
|||
List<Map<String, dynamic>> generateData() {
|
||||
switch (type) {
|
||||
case 'topQueriedDomains':
|
||||
return serversProvider.serverStatus.data!.stats.topQueriedDomains;
|
||||
return statusProvider.serverStatus!.stats.topQueriedDomains;
|
||||
|
||||
case 'topBlockedDomains':
|
||||
return serversProvider.serverStatus.data!.stats.topBlockedDomains;
|
||||
return statusProvider.serverStatus!.stats.topBlockedDomains;
|
||||
|
||||
case 'topClients':
|
||||
return serversProvider.serverStatus.data!.stats.topClients;
|
||||
return statusProvider.serverStatus!.stats.topClients;
|
||||
|
||||
default:
|
||||
return [];
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/clients_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/logs_provider.dart';
|
||||
|
||||
class ClientsModal extends StatefulWidget {
|
||||
|
@ -32,6 +33,7 @@ class _ClientsModalState extends State<ClientsModal> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final logsProvider = Provider.of<LogsProvider>(context);
|
||||
final clientsProvider = Provider.of<ClientsProvider>(context);
|
||||
|
||||
final height = MediaQuery.of(context).size.height;
|
||||
|
||||
|
@ -86,7 +88,7 @@ class _ClientsModalState extends State<ClientsModal> {
|
|||
|
||||
void selectAll() {
|
||||
setState(() {
|
||||
selectedClients = logsProvider.clients!.map((item) => item.ip).toList();
|
||||
selectedClients = clientsProvider.clients!.autoClients.map((item) => item.ip).toList();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -126,20 +128,20 @@ class _ClientsModalState extends State<ClientsModal> {
|
|||
),
|
||||
Flexible(
|
||||
child: ListView.builder(
|
||||
itemCount: logsProvider.clients!.length,
|
||||
itemCount: clientsProvider.clients!.autoClients.length,
|
||||
itemBuilder: (context, index) => listItem(
|
||||
label: logsProvider.clients![index].ip,
|
||||
label: clientsProvider.clients!.autoClients[index].ip,
|
||||
onChanged: () {
|
||||
if (selectedClients.contains(logsProvider.clients![index].ip)) {
|
||||
if (selectedClients.contains(clientsProvider.clients!.autoClients[index].ip)) {
|
||||
setState(() {
|
||||
selectedClients = selectedClients.where(
|
||||
(item) => item != logsProvider.clients![index].ip
|
||||
(item) => item != clientsProvider.clients!.autoClients[index].ip
|
||||
).toList();
|
||||
});
|
||||
}
|
||||
else {
|
||||
setState(() {
|
||||
selectedClients.add(logsProvider.clients![index].ip);
|
||||
selectedClients.add(clientsProvider.clients!.autoClients[index].ip);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -152,11 +154,11 @@ class _ClientsModalState extends State<ClientsModal> {
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: selectedClients.length == logsProvider.clients!.length
|
||||
onPressed: selectedClients.length == clientsProvider.clients!.autoClients.length
|
||||
? () => unselectAll()
|
||||
: () => selectAll(),
|
||||
child: Text(
|
||||
selectedClients.length == logsProvider.clients!.length
|
||||
selectedClients.length == clientsProvider.clients!.autoClients.length
|
||||
? AppLocalizations.of(context)!.unselectAll
|
||||
: AppLocalizations.of(context)!.selectAll
|
||||
)
|
||||
|
|
|
@ -10,11 +10,11 @@ import 'package:adguard_home_manager/screens/logs/log_list_tile.dart';
|
|||
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/functions/get_filtered_status.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/models/logs.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/functions/format_time.dart';
|
||||
import 'package:adguard_home_manager/models/filtering_status.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
|
||||
class LogDetailsScreen extends StatelessWidget {
|
||||
|
@ -29,13 +29,13 @@ class LogDetailsScreen extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
|
||||
Filter? getList(int id) {
|
||||
try {
|
||||
return serversProvider.filteringStatus!.filters.firstWhere((filter) => filter.id == id, orElse: () {
|
||||
return serversProvider.filteringStatus!.whitelistFilters.firstWhere((filter) => filter.id == id);
|
||||
return statusProvider.filteringStatus!.filters.firstWhere((filter) => filter.id == id, orElse: () {
|
||||
return statusProvider.filteringStatus!.whitelistFilters.firstWhere((filter) => filter.id == id);
|
||||
});
|
||||
} catch (_) {
|
||||
return null;
|
||||
|
@ -53,56 +53,29 @@ class LogDetailsScreen extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
void blockUnblock(Log log, String newStatus) async {
|
||||
void blockUnblock(String domain, String newStatus) async {
|
||||
final ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.savingUserFilters);
|
||||
|
||||
final rules = await getFilteringRules(server: serversProvider.selectedServer!);
|
||||
final rules = await statusProvider.blockUnblockDomain(
|
||||
domain: domain,
|
||||
newStatus: newStatus
|
||||
);
|
||||
|
||||
if (rules['result'] == 'success') {
|
||||
FilteringStatus oldStatus = serversProvider.filteringStatus!;
|
||||
processModal.close();
|
||||
|
||||
List<String> newRules = rules['data'].userRules.where((domain) => !domain.contains(log.question.name)).toList();
|
||||
if (newStatus == 'block') {
|
||||
newRules.add("||${log.question.name}^");
|
||||
}
|
||||
else if (newStatus == 'unblock') {
|
||||
newRules.add("@@||${log.question.name}^");
|
||||
}
|
||||
FilteringStatus newObj = serversProvider.filteringStatus!;
|
||||
newObj.userRules = newRules;
|
||||
serversProvider.setFilteringStatus(newObj);
|
||||
|
||||
final result = await postFilteringRules(server: serversProvider.selectedServer!, data: {'rules': newRules});
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.userFilteringRulesUpdated),
|
||||
backgroundColor: Colors.green,
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
serversProvider.setFilteringStatus(oldStatus);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.userFilteringRulesNotUpdated),
|
||||
backgroundColor: Colors.red,
|
||||
)
|
||||
);
|
||||
}
|
||||
if (rules == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.userFilteringRulesUpdated,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(rules['log']);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.userFilteringRulesNotUpdated),
|
||||
backgroundColor: Colors.red,
|
||||
)
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.userFilteringRulesNotUpdated,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +239,12 @@ class LogDetailsScreen extends StatelessWidget {
|
|||
Row(
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () => blockUnblock(log, getFilteredStatus(context, appConfigProvider, log.reason, true)['filtered'] == true ? 'unblock' : 'block'),
|
||||
onPressed: log.question.name != null
|
||||
? () => blockUnblock(
|
||||
log.question.name!,
|
||||
getFilteredStatus(context, appConfigProvider, log.reason, true)['filtered'] == true ? 'unblock' : 'block'
|
||||
)
|
||||
: null,
|
||||
icon: Icon(
|
||||
getFilteredStatus(context, appConfigProvider, log.reason, true)['filtered'] == true
|
||||
? Icons.check_circle_rounded
|
||||
|
@ -298,8 +276,13 @@ class LogDetailsScreen extends StatelessWidget {
|
|||
centerTitle: false,
|
||||
title: Text(AppLocalizations.of(context)!.logDetails),
|
||||
actions: [
|
||||
if (serversProvider.filteringStatus != null) IconButton(
|
||||
onPressed: () => blockUnblock(log, getFilteredStatus(context, appConfigProvider, log.reason, true)['filtered'] == true ? 'unblock' : 'block'),
|
||||
if (statusProvider.filteringStatus != null) IconButton(
|
||||
onPressed: log.question.name != null
|
||||
? () => blockUnblock(
|
||||
log.question.name!,
|
||||
getFilteredStatus(context, appConfigProvider, log.reason, true)['filtered'] == true ? 'unblock' : 'block'
|
||||
)
|
||||
: null,
|
||||
icon: Icon(
|
||||
getFilteredStatus(context, appConfigProvider, log.reason, true)['filtered'] == true
|
||||
? Icons.check_circle_rounded
|
||||
|
|
|
@ -15,160 +15,61 @@ import 'package:adguard_home_manager/functions/snackbar.dart';
|
|||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/models/applied_filters.dart';
|
||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||
import 'package:adguard_home_manager/providers/clients_provider.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/logs_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/models/logs.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class Logs extends StatelessWidget {
|
||||
class Logs extends StatefulWidget {
|
||||
const Logs({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
final logsProvider = Provider.of<LogsProvider>(context);
|
||||
|
||||
return LogsWidget(
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider,
|
||||
logsProvider: logsProvider,
|
||||
selectedResultStatus: logsProvider.appliedFilters.selectedResultStatus,
|
||||
searchText: logsProvider.appliedFilters.searchText,
|
||||
);
|
||||
}
|
||||
State<Logs> createState() => _LogsState();
|
||||
}
|
||||
|
||||
class LogsWidget extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
final AppConfigProvider appConfigProvider;
|
||||
final LogsProvider logsProvider;
|
||||
final String selectedResultStatus;
|
||||
final String? searchText;
|
||||
|
||||
const LogsWidget({
|
||||
Key? key,
|
||||
required this.serversProvider,
|
||||
required this.appConfigProvider,
|
||||
required this.logsProvider,
|
||||
required this.selectedResultStatus,
|
||||
required this.searchText,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<LogsWidget> createState() => _LogsWidgetState();
|
||||
}
|
||||
|
||||
class _LogsWidgetState extends State<LogsWidget> {
|
||||
class _LogsState extends State<Logs> {
|
||||
late ScrollController scrollController;
|
||||
|
||||
bool isLoadingMore = false;
|
||||
|
||||
bool showDivider = true;
|
||||
|
||||
Log? selectedLog;
|
||||
|
||||
Future fetchLogs({
|
||||
int? inOffset,
|
||||
bool? loadingMore,
|
||||
String? responseStatus,
|
||||
String? searchText,
|
||||
}) async {
|
||||
int offst = inOffset ?? widget.logsProvider.offset;
|
||||
|
||||
String resStatus = responseStatus ?? widget.selectedResultStatus;
|
||||
String? search = searchText ?? widget.searchText;
|
||||
|
||||
if (loadingMore != null && loadingMore == true) {
|
||||
setState(() => isLoadingMore = true);
|
||||
}
|
||||
|
||||
final result = await getLogs(
|
||||
server: widget.serversProvider.selectedServer!,
|
||||
count: widget.logsProvider.logsQuantity,
|
||||
offset: offst,
|
||||
olderThan: widget.logsProvider.logsOlderThan,
|
||||
responseStatus: resStatus,
|
||||
search: search
|
||||
);
|
||||
|
||||
if (loadingMore != null && loadingMore == true) {
|
||||
setState(() => isLoadingMore = false);
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
if (result['result'] == 'success') {
|
||||
widget.logsProvider.setOffset(inOffset != null ? inOffset+widget.logsProvider.logsQuantity : widget.logsProvider.offset+widget.logsProvider.logsQuantity);
|
||||
if (loadingMore != null && loadingMore == true && widget.logsProvider.logsData != null) {
|
||||
LogsData newLogsData = result['data'];
|
||||
newLogsData.data = [...widget.logsProvider.logsData!.data, ...result['data'].data];
|
||||
if (widget.logsProvider.appliedFilters.clients != null) {
|
||||
newLogsData.data = newLogsData.data.where(
|
||||
(item) => widget.logsProvider.appliedFilters.clients!.contains(item.client)
|
||||
).toList();
|
||||
}
|
||||
widget.logsProvider.setLogsData(newLogsData);
|
||||
}
|
||||
else {
|
||||
LogsData newLogsData = result['data'];
|
||||
if (widget.logsProvider.appliedFilters.clients != null) {
|
||||
newLogsData.data = newLogsData.data.where(
|
||||
(item) => widget.logsProvider.appliedFilters.clients!.contains(item.client)
|
||||
).toList();
|
||||
}
|
||||
widget.logsProvider.setLogsData(newLogsData);
|
||||
}
|
||||
widget.logsProvider.setLoadStatus(1);
|
||||
}
|
||||
else {
|
||||
widget.logsProvider.setLoadStatus(2);
|
||||
widget.appConfigProvider.addLog(result['log']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fetchFilteringRules() async {
|
||||
final result = await getFilteringRules(server: widget.serversProvider.selectedServer!);
|
||||
if (mounted) {
|
||||
if (result['result'] == 'success') {
|
||||
widget.serversProvider.setFilteringStatus(result['data']);
|
||||
}
|
||||
else {
|
||||
widget.appConfigProvider.addLog(result['log']);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.couldntGetFilteringStatus),
|
||||
backgroundColor: Colors.red,
|
||||
)
|
||||
);
|
||||
}
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context, listen: false);
|
||||
final statusProvider = Provider.of<StatusProvider>(context, listen: false);
|
||||
|
||||
final result = await statusProvider.getFilteringRules();
|
||||
if (mounted && result == false) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.couldntGetFilteringStatus,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future fetchClients() async {
|
||||
final result = await getClients(widget.serversProvider.selectedServer!);
|
||||
if (mounted) {
|
||||
if (result['result'] == 'success') {
|
||||
widget.logsProvider.setClientsLoadStatus(1);
|
||||
widget.logsProvider.setClients(result['data'].autoClientsData);
|
||||
}
|
||||
else {
|
||||
widget.logsProvider.setClientsLoadStatus(2);
|
||||
widget.appConfigProvider.addLog(result['log']);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.couldntGetFilteringStatus),
|
||||
backgroundColor: Colors.red,
|
||||
)
|
||||
);
|
||||
}
|
||||
final clientsProvider = Provider.of<ClientsProvider>(context, listen: false);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context, listen: false);
|
||||
|
||||
final result = await clientsProvider.fetchClients();
|
||||
if (mounted && result == false) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.couldntGetFilteringStatus,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void scrollListener() {
|
||||
if (scrollController.position.extentAfter < 500 && isLoadingMore == false) {
|
||||
fetchLogs(loadingMore: true);
|
||||
final logsProvider = Provider.of<LogsProvider>(context, listen: false);
|
||||
|
||||
if (scrollController.position.extentAfter < 500 && logsProvider.isLoadingMore == false) {
|
||||
logsProvider.fetchLogs(loadingMore: true);
|
||||
}
|
||||
if (scrollController.position.pixels > 0) {
|
||||
setState(() => showDivider = false);
|
||||
|
@ -180,8 +81,10 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
final logsProvider = Provider.of<LogsProvider>(context, listen: false);
|
||||
|
||||
scrollController = ScrollController()..addListener(scrollListener);
|
||||
fetchLogs(inOffset: 0);
|
||||
logsProvider.fetchLogs(inOffset: 0);
|
||||
fetchFilteringRules();
|
||||
fetchClients();
|
||||
super.initState();
|
||||
|
@ -190,6 +93,7 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
final logsProvider = Provider.of<LogsProvider>(context);
|
||||
|
||||
|
@ -200,12 +104,12 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
processModal.open(AppLocalizations.of(context)!.updatingSettings);
|
||||
|
||||
final result = serverVersionIsAhead(
|
||||
currentVersion: widget.serversProvider.serverStatus.data!.serverVersion,
|
||||
currentVersion: statusProvider.serverStatus!.serverVersion,
|
||||
referenceVersion: 'v0.107.28',
|
||||
referenceVersionBeta: 'v0.108.0-b.33'
|
||||
) == true
|
||||
? await updateQueryLogParameters(server: serversProvider.selectedServer!, data: data)
|
||||
: await updateQueryLogParametersLegacy(server: serversProvider.selectedServer!, data: data);
|
||||
? await serversProvider.apiClient!.updateQueryLogParameters(data: data)
|
||||
: await serversProvider.apiClient!.updateQueryLogParametersLegacy(data: data);
|
||||
|
||||
processModal.close();
|
||||
|
||||
|
@ -231,7 +135,7 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.updatingSettings);
|
||||
|
||||
final result = await clearLogs(server: serversProvider.selectedServer!);
|
||||
final result = await serversProvider.apiClient!.clearLogs();
|
||||
|
||||
processModal.close();
|
||||
|
||||
|
@ -243,8 +147,6 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.logsNotCleared,
|
||||
|
@ -289,7 +191,7 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
|
||||
Widget generateBody() {
|
||||
switch (logsProvider.loadStatus) {
|
||||
case 0:
|
||||
case LoadStatus.loading:
|
||||
return SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
|
@ -309,20 +211,20 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
),
|
||||
);
|
||||
|
||||
case 1:
|
||||
case LoadStatus.loaded:
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
await fetchLogs(inOffset: 0);
|
||||
await logsProvider.fetchLogs(inOffset: 0);
|
||||
},
|
||||
child: logsProvider.logsData!.data.isNotEmpty
|
||||
? ListView.builder(
|
||||
controller: scrollController,
|
||||
padding: const EdgeInsets.only(top: 0),
|
||||
itemCount: isLoadingMore == true
|
||||
itemCount: logsProvider.isLoadingMore == true
|
||||
? logsProvider.logsData!.data.length+1
|
||||
: logsProvider.logsData!.data.length,
|
||||
itemBuilder: (context, index) {
|
||||
if (isLoadingMore == true && index == logsProvider.logsData!.data.length) {
|
||||
if (logsProvider.isLoadingMore == true && index == logsProvider.logsData!.data.length) {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 20),
|
||||
child: Center(
|
||||
|
@ -385,7 +287,7 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
)
|
||||
);
|
||||
|
||||
case 2:
|
||||
case LoadStatus.error:
|
||||
return SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
|
@ -421,11 +323,11 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
centerTitle: false,
|
||||
actions: [
|
||||
if (!(Platform.isAndroid || Platform.isIOS)) IconButton(
|
||||
onPressed: () => fetchLogs(inOffset: 0),
|
||||
onPressed: () => logsProvider.fetchLogs(inOffset: 0),
|
||||
icon: const Icon(Icons.refresh_rounded),
|
||||
tooltip: AppLocalizations.of(context)!.refresh,
|
||||
),
|
||||
logsProvider.loadStatus == 1
|
||||
logsProvider.loadStatus == LoadStatus.loaded
|
||||
? IconButton(
|
||||
onPressed: openFilersModal,
|
||||
icon: const Icon(Icons.filter_list_rounded),
|
||||
|
@ -442,7 +344,7 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
onConfirm: updateConfig,
|
||||
onClear: clearQueries,
|
||||
dialog: true,
|
||||
serverVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
serverVersion: statusProvider.serverStatus!.serverVersion,
|
||||
),
|
||||
barrierDismissible: false
|
||||
)
|
||||
|
@ -454,7 +356,7 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
onConfirm: updateConfig,
|
||||
onClear: clearQueries,
|
||||
dialog: false,
|
||||
serverVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
serverVersion: statusProvider.serverStatus!.serverVersion,
|
||||
),
|
||||
backgroundColor: Colors.transparent,
|
||||
isScrollControlled: true
|
||||
|
@ -510,7 +412,7 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
)
|
||||
);
|
||||
logsProvider.setSearchText(null);
|
||||
fetchLogs(
|
||||
logsProvider.fetchLogs(
|
||||
inOffset: 0,
|
||||
searchText: ''
|
||||
);
|
||||
|
@ -543,7 +445,7 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
)
|
||||
);
|
||||
logsProvider.setSelectedResultStatus('all');
|
||||
fetchLogs(
|
||||
logsProvider.fetchLogs(
|
||||
inOffset: 0,
|
||||
responseStatus: 'all'
|
||||
);
|
||||
|
@ -578,7 +480,7 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
)
|
||||
);
|
||||
logsProvider.setSelectedClients(null);
|
||||
fetchLogs(
|
||||
logsProvider.fetchLogs(
|
||||
inOffset: 0,
|
||||
responseStatus: logsProvider.appliedFilters.selectedResultStatus
|
||||
);
|
||||
|
|
|
@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
@ -74,13 +73,15 @@ class _LogsConfigModalWidgetState extends State<LogsConfigModalWidget> {
|
|||
int loadStatus = 0;
|
||||
|
||||
void loadData() async {
|
||||
final serversProvider = Provider.of<ServersProvider>(context, listen: false);
|
||||
|
||||
final result = serverVersionIsAhead(
|
||||
currentVersion: widget.serverVersion,
|
||||
referenceVersion: 'v0.107.28',
|
||||
referenceVersionBeta: 'v0.108.0-b.33'
|
||||
) == true
|
||||
? await getQueryLogInfo(server: widget.serversProvider.selectedServer!)
|
||||
: await getQueryLogInfoLegacy(server: widget.serversProvider.selectedServer!);
|
||||
? await serversProvider.apiClient!.getQueryLogInfo()
|
||||
: await serversProvider.apiClient!.getQueryLogInfoLegacy();
|
||||
|
||||
if (mounted) {
|
||||
if (result['result'] == 'success') {
|
||||
|
|
|
@ -10,11 +10,8 @@ import 'package:adguard_home_manager/screens/logs/clients_modal.dart';
|
|||
import 'package:adguard_home_manager/screens/logs/filter_status_modal.dart';
|
||||
import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
||||
|
||||
import 'package:adguard_home_manager/models/logs.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/models/applied_filters.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/clients_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/logs_provider.dart';
|
||||
|
||||
class LogsFiltersModal extends StatelessWidget {
|
||||
|
@ -62,8 +59,7 @@ class _LogsFiltersModalWidgetState extends State<LogsFiltersModalWidget> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final logsProvider = Provider.of<LogsProvider>(context);
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
final clientsProvider = Provider.of<ClientsProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
||||
|
@ -78,38 +74,6 @@ class _LogsFiltersModalWidgetState extends State<LogsFiltersModalWidget> {
|
|||
"safe_search": AppLocalizations.of(context)!.blockedSafeSearchRow,
|
||||
};
|
||||
|
||||
void resetFilters() async {
|
||||
setState(() {
|
||||
searchController.text = '';
|
||||
});
|
||||
|
||||
logsProvider.setLoadStatus(0);
|
||||
|
||||
logsProvider.resetFilters();
|
||||
|
||||
final result = await getLogs(
|
||||
server: serversProvider.selectedServer!,
|
||||
count: logsProvider.logsQuantity
|
||||
);
|
||||
|
||||
logsProvider.setAppliedFilters(
|
||||
AppliedFiters(
|
||||
selectedResultStatus: 'all',
|
||||
searchText: null,
|
||||
clients: null
|
||||
)
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
logsProvider.setLogsData(result['data']);
|
||||
logsProvider.setLoadStatus(1);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
logsProvider.setLoadStatus(2);
|
||||
}
|
||||
}
|
||||
|
||||
void openSelectFilterStatus() {
|
||||
if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) {
|
||||
showDialog(
|
||||
|
@ -158,45 +122,6 @@ class _LogsFiltersModalWidgetState extends State<LogsFiltersModalWidget> {
|
|||
}
|
||||
}
|
||||
|
||||
void filterLogs() async {
|
||||
Navigator.pop(context);
|
||||
|
||||
logsProvider.setLoadStatus(0);
|
||||
|
||||
logsProvider.setOffset(0);
|
||||
|
||||
final result = await getLogs(
|
||||
server: serversProvider.selectedServer!,
|
||||
count: logsProvider.logsQuantity,
|
||||
olderThan: logsProvider.logsOlderThan,
|
||||
responseStatus: logsProvider.selectedResultStatus,
|
||||
search: logsProvider.searchText,
|
||||
);
|
||||
|
||||
logsProvider.setAppliedFilters(
|
||||
AppliedFiters(
|
||||
selectedResultStatus: logsProvider.selectedResultStatus,
|
||||
searchText: logsProvider.searchText,
|
||||
clients: logsProvider.selectedClients
|
||||
)
|
||||
);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
LogsData newLogsData = result['data'];
|
||||
if (widget.logsProvider.appliedFilters.clients != null) {
|
||||
newLogsData.data = newLogsData.data.where(
|
||||
(item) => widget.logsProvider.appliedFilters.clients!.contains(item.client)
|
||||
).toList();
|
||||
}
|
||||
logsProvider.setLogsData(newLogsData);
|
||||
logsProvider.setLoadStatus(1);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
logsProvider.setLoadStatus(2);
|
||||
}
|
||||
}
|
||||
|
||||
Widget content() {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
@ -273,13 +198,13 @@ class _LogsFiltersModalWidgetState extends State<LogsFiltersModalWidget> {
|
|||
subtitle: logsProvider.selectedClients != null
|
||||
? "${logsProvider.selectedClients!.length} ${AppLocalizations.of(context)!.clientsSelected}"
|
||||
: AppLocalizations.of(context)!.all,
|
||||
onTap: logsProvider.clientsLoadStatus == 1
|
||||
onTap: clientsProvider.loadStatus == LoadStatus.loaded
|
||||
? openSelectClients
|
||||
: null,
|
||||
disabled: logsProvider.clientsLoadStatus != 1 ,
|
||||
disabled: clientsProvider.loadStatus != LoadStatus.loaded,
|
||||
icon: Icons.smartphone_rounded,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
trailing: logsProvider.clientsLoadStatus == 0
|
||||
trailing: clientsProvider.loadStatus == LoadStatus.loading
|
||||
? const SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
|
@ -287,7 +212,7 @@ class _LogsFiltersModalWidgetState extends State<LogsFiltersModalWidget> {
|
|||
strokeWidth: 2,
|
||||
),
|
||||
)
|
||||
: logsProvider.clientsLoadStatus == 2
|
||||
: clientsProvider.loadStatus == LoadStatus.error
|
||||
? const Icon(
|
||||
Icons.error_rounded,
|
||||
color: Colors.red,
|
||||
|
@ -311,11 +236,17 @@ class _LogsFiltersModalWidgetState extends State<LogsFiltersModalWidget> {
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: resetFilters,
|
||||
onPressed: () {
|
||||
searchController.text = "";
|
||||
logsProvider.requestResetFilters();
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.resetFilters)
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => filterLogs(),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
logsProvider.filterLogs();
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.apply)
|
||||
),
|
||||
],
|
||||
|
|
|
@ -7,62 +7,22 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
import 'package:adguard_home_manager/screens/settings/access_settings/clients_list.dart';
|
||||
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/clients_provider.dart';
|
||||
|
||||
class AccessSettings extends StatelessWidget {
|
||||
class AccessSettings extends StatefulWidget {
|
||||
const AccessSettings({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
return AccessSettingsWidget(
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider,
|
||||
);
|
||||
}
|
||||
State<AccessSettings> createState() => _AccessSettingsState();
|
||||
}
|
||||
|
||||
class AccessSettingsWidget extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
final AppConfigProvider appConfigProvider;
|
||||
|
||||
const AccessSettingsWidget({
|
||||
Key? key,
|
||||
required this.serversProvider,
|
||||
required this.appConfigProvider,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<AccessSettingsWidget> createState() => _AccessSettingsWidgetState();
|
||||
}
|
||||
|
||||
class _AccessSettingsWidgetState extends State<AccessSettingsWidget> with TickerProviderStateMixin {
|
||||
class _AccessSettingsState extends State<AccessSettings> with TickerProviderStateMixin {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
late TabController tabController;
|
||||
|
||||
Future fetchClients() async {
|
||||
widget.serversProvider.setClientsLoadStatus(LoadStatus.loading, false);
|
||||
final result = await getClients(widget.serversProvider.selectedServer!);
|
||||
if (mounted) {
|
||||
if (result['result'] == 'success') {
|
||||
widget.serversProvider.setClientsData(result['data']);
|
||||
widget.serversProvider.setClientsLoadStatus(LoadStatus.loaded, true);
|
||||
}
|
||||
else {
|
||||
widget.appConfigProvider.addLog(result['log']);
|
||||
widget.serversProvider.setClientsLoadStatus(LoadStatus.error, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
fetchClients();
|
||||
Provider.of<ClientsProvider>(context, listen: false).fetchClients(updateLoading: true);
|
||||
super.initState();
|
||||
tabController = TabController(
|
||||
initialIndex: 0,
|
||||
|
@ -73,7 +33,7 @@ class _AccessSettingsWidgetState extends State<AccessSettingsWidget> with Ticker
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final clientsProvider = Provider.of<ClientsProvider>(context);
|
||||
|
||||
Widget body() {
|
||||
return TabBarView(
|
||||
|
@ -82,26 +42,23 @@ class _AccessSettingsWidgetState extends State<AccessSettingsWidget> with Ticker
|
|||
ClientsList(
|
||||
type: 'allowed',
|
||||
scrollController: scrollController,
|
||||
loadStatus: serversProvider.clients.loadStatus,
|
||||
data: serversProvider.clients.loadStatus == LoadStatus.loaded
|
||||
? serversProvider.clients.data!.clientsAllowedBlocked!.allowedClients : [],
|
||||
fetchClients: fetchClients
|
||||
loadStatus: clientsProvider.loadStatus,
|
||||
data: clientsProvider.loadStatus == LoadStatus.loaded
|
||||
? clientsProvider.clients!.clientsAllowedBlocked!.allowedClients : [],
|
||||
),
|
||||
ClientsList(
|
||||
type: 'disallowed',
|
||||
scrollController: scrollController,
|
||||
loadStatus: serversProvider.clients.loadStatus,
|
||||
data: serversProvider.clients.loadStatus == LoadStatus.loaded
|
||||
? serversProvider.clients.data!.clientsAllowedBlocked!.disallowedClients : [],
|
||||
fetchClients: fetchClients
|
||||
loadStatus: clientsProvider.loadStatus,
|
||||
data: clientsProvider.loadStatus == LoadStatus.loaded
|
||||
? clientsProvider.clients!.clientsAllowedBlocked!.disallowedClients : [],
|
||||
),
|
||||
ClientsList(
|
||||
type: 'domains',
|
||||
scrollController: scrollController,
|
||||
loadStatus: serversProvider.clients.loadStatus,
|
||||
data: serversProvider.clients.loadStatus == LoadStatus.loaded
|
||||
? serversProvider.clients.data!.clientsAllowedBlocked!.blockedHosts : [],
|
||||
fetchClients: fetchClients
|
||||
loadStatus: clientsProvider.loadStatus,
|
||||
data: clientsProvider.loadStatus == LoadStatus.loaded
|
||||
? clientsProvider.clients!.clientsAllowedBlocked!.blockedHosts : [],
|
||||
),
|
||||
]
|
||||
);
|
||||
|
|
|
@ -13,10 +13,8 @@ import 'package:adguard_home_manager/widgets/tab_content_list.dart';
|
|||
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/models/clients_allowed_blocked.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/providers/clients_provider.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
|
||||
class ClientsList extends StatefulWidget {
|
||||
|
@ -24,7 +22,6 @@ class ClientsList extends StatefulWidget {
|
|||
final ScrollController scrollController;
|
||||
final LoadStatus loadStatus;
|
||||
final List<String> data;
|
||||
final Future Function() fetchClients;
|
||||
|
||||
const ClientsList({
|
||||
Key? key,
|
||||
|
@ -32,7 +29,6 @@ class ClientsList extends StatefulWidget {
|
|||
required this.scrollController,
|
||||
required this.loadStatus,
|
||||
required this.data,
|
||||
required this.fetchClients
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -67,16 +63,27 @@ class _ClientsListState extends State<ClientsList> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
final clientsProvider = Provider.of<ClientsProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
||||
Future refetchClients() async {
|
||||
final result = await clientsProvider.fetchClients();
|
||||
if (result == false) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientsNotLoaded,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void confirmRemoveItem(String client, String type) async {
|
||||
Map<String, List<String>> body = {
|
||||
"allowed_clients": serversProvider.clients.data!.clientsAllowedBlocked?.allowedClients ?? [],
|
||||
"disallowed_clients": serversProvider.clients.data!.clientsAllowedBlocked?.disallowedClients ?? [],
|
||||
"blocked_hosts": serversProvider.clients.data!.clientsAllowedBlocked?.blockedHosts ?? [],
|
||||
"allowed_clients": clientsProvider.clients!.clientsAllowedBlocked?.allowedClients ?? [],
|
||||
"disallowed_clients": clientsProvider.clients!.clientsAllowedBlocked?.disallowedClients ?? [],
|
||||
"blocked_hosts": clientsProvider.clients!.clientsAllowedBlocked?.blockedHosts ?? [],
|
||||
};
|
||||
|
||||
if (type == 'allowed') {
|
||||
|
@ -92,20 +99,18 @@ class _ClientsListState extends State<ClientsList> {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.removingClient);
|
||||
|
||||
final result = await requestAllowedBlockedClientsHosts(serversProvider.selectedServer!, body);
|
||||
final result = await clientsProvider.removeClientList(client, type);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
serversProvider.setAllowedDisallowedClientsBlockedDomains(
|
||||
ClientsAllowedBlocked(
|
||||
allowedClients: body['allowed_clients'] ?? [],
|
||||
disallowedClients: body['disallowed_clients'] ?? [],
|
||||
blockedHosts: body['blocked_hosts'] ?? [],
|
||||
)
|
||||
if (result['success'] == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientRemovedSuccessfully,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else if (result['result'] == 'error' && result['message'] == 'client_another_list') {
|
||||
else if (result['success'] == false && result['error'] == 'client_another_list') {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientAnotherList,
|
||||
|
@ -113,50 +118,32 @@ class _ClientsListState extends State<ClientsList> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientNotRemoved,
|
||||
label: type == 'allowed' || type == 'blocked'
|
||||
? AppLocalizations.of(context)!.clientNotRemoved
|
||||
: AppLocalizations.of(context)!.domainNotAdded,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void confirmAddItem(String item, String type) async {
|
||||
Map<String, List<String>> body = {
|
||||
"allowed_clients": serversProvider.clients.data!.clientsAllowedBlocked?.allowedClients ?? [],
|
||||
"disallowed_clients": serversProvider.clients.data!.clientsAllowedBlocked?.disallowedClients ?? [],
|
||||
"blocked_hosts": serversProvider.clients.data!.clientsAllowedBlocked?.blockedHosts ?? [],
|
||||
};
|
||||
|
||||
if (type == 'allowed') {
|
||||
body['allowed_clients']!.add(item);
|
||||
}
|
||||
else if (type == 'disallowed') {
|
||||
body['disallowed_clients']!.add(item);
|
||||
}
|
||||
else if (type == 'domains') {
|
||||
body['blocked_hosts']!.add(item);
|
||||
}
|
||||
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.removingClient);
|
||||
|
||||
final result = await requestAllowedBlockedClientsHosts(serversProvider.selectedServer!, body);
|
||||
final result = await clientsProvider.addClientList(item, type);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
serversProvider.setAllowedDisallowedClientsBlockedDomains(
|
||||
ClientsAllowedBlocked(
|
||||
allowedClients: body['allowed_clients'] ?? [],
|
||||
disallowedClients: body['disallowed_clients'] ?? [],
|
||||
blockedHosts: body['blocked_hosts'] ?? [],
|
||||
)
|
||||
if (result['success'] == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientAddedSuccessfully,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else if (result['result'] == 'error' && result['message'] == 'client_another_list') {
|
||||
else if (result['success'] == false && result['error'] == 'client_another_list') {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.clientAnotherList,
|
||||
|
@ -164,8 +151,6 @@ class _ClientsListState extends State<ClientsList> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: type == 'allowed' || type == 'blocked'
|
||||
|
@ -325,7 +310,7 @@ class _ClientsListState extends State<ClientsList> {
|
|||
),
|
||||
const SizedBox(height: 30),
|
||||
TextButton.icon(
|
||||
onPressed: widget.fetchClients,
|
||||
onPressed: refetchClients,
|
||||
icon: const Icon(Icons.refresh_rounded),
|
||||
label: Text(AppLocalizations.of(context)!.refresh),
|
||||
)
|
||||
|
@ -359,7 +344,7 @@ class _ClientsListState extends State<ClientsList> {
|
|||
),
|
||||
),
|
||||
loadStatus: widget.loadStatus,
|
||||
onRefresh: widget.fetchClients,
|
||||
onRefresh: refetchClients,
|
||||
refreshIndicatorOffset: 0,
|
||||
fab: FloatingActionButton(
|
||||
onPressed: () {
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_split_view/flutter_split_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
||||
import 'package:adguard_home_manager/screens/settings/app_logs/app_logs.dart';
|
||||
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
|
@ -20,8 +16,6 @@ class AdvancedSettings extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
||||
Future updateSettings({
|
||||
required bool newStatus,
|
||||
required Future Function(bool) function
|
||||
|
@ -71,29 +65,6 @@ class AdvancedSettings extends StatelessWidget {
|
|||
right: 10
|
||||
)
|
||||
),
|
||||
CustomListTile(
|
||||
icon: Icons.list_rounded,
|
||||
title: AppLocalizations.of(context)!.logs,
|
||||
subtitle: AppLocalizations.of(context)!.checkAppLogs,
|
||||
onTap: () => {
|
||||
if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) {
|
||||
SplitView.of(context).push(const AppLogs())
|
||||
}
|
||||
else {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const AppLogs()
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
padding: const EdgeInsets.only(
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
left: 20,
|
||||
right: 10
|
||||
)
|
||||
),
|
||||
],
|
||||
)
|
||||
);
|
||||
|
|
|
@ -13,42 +13,21 @@ import 'package:adguard_home_manager/screens/settings/dhcp/dhcp_leases.dart';
|
|||
import 'package:adguard_home_manager/screens/settings/dhcp/select_interface_modal.dart';
|
||||
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/dhcp_provider.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/models/dhcp.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class Dhcp extends StatelessWidget {
|
||||
const Dhcp({Key? key}) : super(key: key);
|
||||
class DhcpScreen extends StatefulWidget {
|
||||
const DhcpScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
return DhcpWidget(
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider
|
||||
);
|
||||
}
|
||||
State<DhcpScreen> createState() => _DhcpScreenState();
|
||||
}
|
||||
|
||||
class DhcpWidget extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
final AppConfigProvider appConfigProvider;
|
||||
|
||||
const DhcpWidget({
|
||||
Key? key,
|
||||
required this.serversProvider,
|
||||
required this.appConfigProvider
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<DhcpWidget> createState() => _DhcpWidgetState();
|
||||
}
|
||||
|
||||
class _DhcpWidgetState extends State<DhcpWidget> {
|
||||
class _DhcpScreenState extends State<DhcpScreen> {
|
||||
NetworkInterface? selectedInterface;
|
||||
|
||||
bool enabled = false;
|
||||
|
@ -74,31 +53,22 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
bool dataValid = false;
|
||||
|
||||
void loadDhcpStatus() async {
|
||||
widget.serversProvider.setDhcpLoadStatus(0, false);
|
||||
|
||||
final result = await getDhcpData(server: widget.serversProvider.selectedServer!);
|
||||
|
||||
if (mounted) {
|
||||
if (result['result'] == 'success') {
|
||||
widget.serversProvider.setDhcpLoadStatus(1, true);
|
||||
widget.serversProvider.setDhcpData(result['data']);
|
||||
final result = await Provider.of<DhcpProvider>(context, listen: false).loadDhcpStatus();
|
||||
if (mounted && result == true) {
|
||||
final dhcpProvider = Provider.of<DhcpProvider>(context, listen: false);
|
||||
if (dhcpProvider.dhcp != null) {
|
||||
setState(() {
|
||||
if (result['data'].dhcpStatus.interfaceName != '') {
|
||||
selectedInterface = result['data'].networkInterfaces.firstWhere((interface) => interface.name == result['data'].dhcpStatus.interfaceName);
|
||||
|
||||
enabled = result['data'].dhcpStatus.enabled;
|
||||
ipv4StartRangeController.text = result['data'].dhcpStatus.v4.rangeStart;
|
||||
ipv4StartRangeController.text = result['data'].dhcpStatus.v4.rangeStart;
|
||||
ipv4EndRangeController.text = result['data'].dhcpStatus.v4.rangeEnd;
|
||||
ipv4SubnetMaskController.text = result['data'].dhcpStatus.v4.subnetMask;
|
||||
ipv4GatewayController.text = result['data'].dhcpStatus.v4.gatewayIp;
|
||||
ipv4LeaseTimeController.text = result['data'].dhcpStatus.v4.leaseDuration.toString();
|
||||
if (dhcpProvider.dhcp!.dhcpStatus.interfaceName != '') {
|
||||
selectedInterface = dhcpProvider.dhcp!.networkInterfaces.firstWhere((iface) => iface.name == dhcpProvider.dhcp!.dhcpStatus.interfaceName);
|
||||
enabled = dhcpProvider.dhcp!.dhcpStatus.enabled;
|
||||
ipv4StartRangeController.text = dhcpProvider.dhcp!.dhcpStatus.v4.rangeStart;
|
||||
ipv4EndRangeController.text = dhcpProvider.dhcp!.dhcpStatus.v4.rangeEnd ?? '';
|
||||
ipv4SubnetMaskController.text = dhcpProvider.dhcp!.dhcpStatus.v4.subnetMask ?? '';
|
||||
ipv4GatewayController.text = dhcpProvider.dhcp!.dhcpStatus.v4.gatewayIp ?? '';
|
||||
ipv4LeaseTimeController.text = dhcpProvider.dhcp!.dhcpStatus.v4.leaseDuration.toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
widget.serversProvider.setDhcpLoadStatus(2, true);
|
||||
}
|
||||
}
|
||||
checkDataValid();
|
||||
}
|
||||
|
@ -213,6 +183,7 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final dhcpProvider = Provider.of<DhcpProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
@ -221,22 +192,24 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.savingSettings);
|
||||
|
||||
final result = await saveDhcpConfig(server: serversProvider.selectedServer!, data: {
|
||||
"enabled": enabled,
|
||||
"interface_name": selectedInterface!.name,
|
||||
if (selectedInterface!.ipv4Addresses.isNotEmpty) "v4": {
|
||||
"gateway_ip": ipv4GatewayController.text,
|
||||
"subnet_mask": ipv4SubnetMaskController.text,
|
||||
"range_start": ipv4StartRangeController.text,
|
||||
"range_end": ipv4EndRangeController.text,
|
||||
"lease_duration": ipv4LeaseTimeController.text != '' ? int.parse(ipv4LeaseTimeController.text) : null
|
||||
},
|
||||
if (selectedInterface!.ipv6Addresses.isNotEmpty) "v6": {
|
||||
"range_start": ipv6StartRangeController.text,
|
||||
"range_end": ipv6EndRangeController.text,
|
||||
"lease_duration": ipv6LeaseTimeController.text != '' ? int.parse(ipv6LeaseTimeController.text) : null
|
||||
final result = await serversProvider.apiClient!.saveDhcpConfig(
|
||||
data: {
|
||||
"enabled": enabled,
|
||||
"interface_name": selectedInterface!.name,
|
||||
if (selectedInterface!.ipv4Addresses.isNotEmpty) "v4": {
|
||||
"gateway_ip": ipv4GatewayController.text,
|
||||
"subnet_mask": ipv4SubnetMaskController.text,
|
||||
"range_start": ipv4StartRangeController.text,
|
||||
"range_end": ipv4EndRangeController.text,
|
||||
"lease_duration": ipv4LeaseTimeController.text != '' ? int.parse(ipv4LeaseTimeController.text) : null
|
||||
},
|
||||
if (selectedInterface!.ipv6Addresses.isNotEmpty) "v6": {
|
||||
"range_start": ipv6StartRangeController.text,
|
||||
"range_end": ipv6EndRangeController.text,
|
||||
"lease_duration": ipv6LeaseTimeController.text != '' ? int.parse(ipv6LeaseTimeController.text) : null
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
processModal.close();
|
||||
|
||||
|
@ -248,8 +221,6 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.settingsNotSaved,
|
||||
|
@ -263,7 +234,7 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.restoringConfig);
|
||||
|
||||
final result = await resetDhcpConfig(server: serversProvider.selectedServer!);
|
||||
final result = await serversProvider.apiClient!.resetDhcpConfig();
|
||||
|
||||
processModal.close();
|
||||
|
||||
|
@ -277,8 +248,6 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.configNotRestored,
|
||||
|
@ -293,15 +262,15 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.restoringLeases);
|
||||
|
||||
final result = await restoreAllLeases(server: serversProvider.selectedServer!);
|
||||
final result = await serversProvider.apiClient!.restoreAllLeases();
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DhcpData data = serversProvider.dhcp.data!;
|
||||
DhcpModel data = dhcpProvider.dhcp!;
|
||||
data.dhcpStatus.staticLeases = [];
|
||||
data.dhcpStatus.leases = [];
|
||||
serversProvider.setDhcpData(data);
|
||||
dhcpProvider.setDhcpData(data);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
|
@ -310,8 +279,6 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.leasesNotRestored,
|
||||
|
@ -356,7 +323,7 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => SelectInterfaceModal(
|
||||
interfaces: serversProvider.dhcp.data!.networkInterfaces,
|
||||
interfaces: dhcpProvider.dhcp!.networkInterfaces,
|
||||
onSelect: (interface) => setState(() {
|
||||
clearAll();
|
||||
selectedInterface = interface;
|
||||
|
@ -369,7 +336,7 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => SelectInterfaceModal(
|
||||
interfaces: serversProvider.dhcp.data!.networkInterfaces,
|
||||
interfaces: dhcpProvider.dhcp!.networkInterfaces,
|
||||
onSelect: (i) => setState(() {
|
||||
clearAll();
|
||||
selectedInterface = i;
|
||||
|
@ -383,8 +350,8 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
}
|
||||
|
||||
Widget generateBody() {
|
||||
switch (serversProvider.dhcp.loadStatus) {
|
||||
case 0:
|
||||
switch (dhcpProvider.loadStatus) {
|
||||
case LoadStatus.loading:
|
||||
return SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
|
@ -404,7 +371,7 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
),
|
||||
);
|
||||
|
||||
case 1:
|
||||
case LoadStatus.loaded:
|
||||
if (selectedInterface != null) {
|
||||
return SingleChildScrollView(
|
||||
child: Wrap(
|
||||
|
@ -683,7 +650,7 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
builder: (context) => DhcpLeases(
|
||||
items: serversProvider.dhcp.data!.dhcpStatus.leases,
|
||||
items: dhcpProvider.dhcp!.dhcpStatus.leases,
|
||||
staticLeases: false,
|
||||
)
|
||||
));
|
||||
|
@ -716,7 +683,7 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
builder: (context) => DhcpLeases(
|
||||
items: serversProvider.dhcp.data!.dhcpStatus.staticLeases,
|
||||
items: dhcpProvider.dhcp!.dhcpStatus.staticLeases,
|
||||
staticLeases: true,
|
||||
)
|
||||
));
|
||||
|
@ -751,7 +718,7 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
if (!(Platform.isAndroid || Platform.isIOS)) {
|
||||
SplitView.of(context).push(
|
||||
DhcpLeases(
|
||||
items: serversProvider.dhcp.data!.dhcpStatus.leases,
|
||||
items: dhcpProvider.dhcp!.dhcpStatus.leases,
|
||||
staticLeases: false,
|
||||
)
|
||||
);
|
||||
|
@ -759,7 +726,7 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
else {
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
builder: (context) => DhcpLeases(
|
||||
items: serversProvider.dhcp.data!.dhcpStatus.leases,
|
||||
items: dhcpProvider.dhcp!.dhcpStatus.leases,
|
||||
staticLeases: false,
|
||||
)
|
||||
));
|
||||
|
@ -778,7 +745,7 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
if (!(Platform.isAndroid || Platform.isIOS)) {
|
||||
SplitView.of(context).push(
|
||||
DhcpLeases(
|
||||
items: serversProvider.dhcp.data!.dhcpStatus.staticLeases,
|
||||
items: dhcpProvider.dhcp!.dhcpStatus.staticLeases,
|
||||
staticLeases: true,
|
||||
)
|
||||
);
|
||||
|
@ -786,7 +753,7 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
else {
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
builder: (context) => DhcpLeases(
|
||||
items: serversProvider.dhcp.data!.dhcpStatus.staticLeases,
|
||||
items: dhcpProvider.dhcp!.dhcpStatus.staticLeases,
|
||||
staticLeases: true,
|
||||
)
|
||||
));
|
||||
|
@ -840,7 +807,7 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
);
|
||||
}
|
||||
|
||||
case 2:
|
||||
case LoadStatus.error:
|
||||
return SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
|
|
|
@ -10,12 +10,11 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
import 'package:adguard_home_manager/screens/settings/dhcp/delete_static_lease_modal.dart';
|
||||
import 'package:adguard_home_manager/screens/settings/dhcp/add_static_lease_modal.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/dhcp_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/models/dhcp.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class DhcpLeases extends StatelessWidget {
|
||||
final List<Lease> items;
|
||||
|
@ -29,7 +28,7 @@ class DhcpLeases extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final dhcpProvider = Provider.of<DhcpProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
@ -38,19 +37,11 @@ class DhcpLeases extends StatelessWidget {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.deleting);
|
||||
|
||||
final result = await deleteStaticLease(server: serversProvider.selectedServer!, data: {
|
||||
"mac": lease.mac,
|
||||
"ip": lease.ip,
|
||||
"hostname": lease.hostname
|
||||
});
|
||||
final result = await dhcpProvider.deleteLease(lease);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DhcpData data = serversProvider.dhcp.data!;
|
||||
data.dhcpStatus.staticLeases = data.dhcpStatus.staticLeases.where((l) => l.mac != lease.mac).toList();
|
||||
serversProvider.setDhcpData(data);
|
||||
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.staticLeaseDeleted,
|
||||
|
@ -58,7 +49,6 @@ class DhcpLeases extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.staticLeaseNotDeleted,
|
||||
|
@ -71,35 +61,25 @@ class DhcpLeases extends StatelessWidget {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.creating);
|
||||
|
||||
final result = await createStaticLease(server: serversProvider.selectedServer!, data: {
|
||||
"mac": lease.mac,
|
||||
"ip": lease.ip,
|
||||
"hostname": lease.hostname,
|
||||
});
|
||||
final result = await dhcpProvider.createLease(lease);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DhcpData data = serversProvider.dhcp.data!;
|
||||
data.dhcpStatus.staticLeases.add(lease);
|
||||
serversProvider.setDhcpData(data);
|
||||
|
||||
if (result['success'] == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.staticLeaseCreated,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else if (result['result'] == 'error' && result['message'] == 'already_exists' ) {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
else if (result['success'] == false && result['error'] == 'already_exists' ) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.staticLeaseExists,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
else if (result['result'] == 'error' && result['message'] == 'server_not_configured' ) {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
else if (result['success'] == false && result['error'] == 'server_not_configured' ) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.serverNotConfigured,
|
||||
|
@ -107,7 +87,6 @@ class DhcpLeases extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.staticLeaseNotCreated,
|
||||
|
|
|
@ -4,20 +4,13 @@ import 'package:flutter/material.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/providers/dns_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/models/dns_info.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
|
||||
class BootstrapDnsScreen extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
|
||||
const BootstrapDnsScreen({
|
||||
Key? key,
|
||||
required this.serversProvider,
|
||||
}) : super(key: key);
|
||||
const BootstrapDnsScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<BootstrapDnsScreen> createState() => _BootstrapDnsScreenState();
|
||||
|
@ -54,7 +47,9 @@ class _BootstrapDnsScreenState extends State<BootstrapDnsScreen> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
for (var item in widget.serversProvider.dnsInfo.data!.bootstrapDns) {
|
||||
final dnsProvider = Provider.of<DnsProvider>(context, listen: false);
|
||||
|
||||
for (var item in dnsProvider.dnsInfo!.bootstrapDns) {
|
||||
final controller = TextEditingController();
|
||||
controller.text = item;
|
||||
bootstrapControllers.add({
|
||||
|
@ -68,33 +63,27 @@ class _BootstrapDnsScreenState extends State<BootstrapDnsScreen> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final dnsProvider = Provider.of<DnsProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
void saveData() async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.savingConfig);
|
||||
|
||||
final result = await setDnsConfig(server: serversProvider.selectedServer!, data: {
|
||||
final result = await dnsProvider.saveBootstrapDnsConfig({
|
||||
"bootstrap_dns": bootstrapControllers.map((e) => e['controller'].text).toList(),
|
||||
});
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DnsInfoData data = serversProvider.dnsInfo.data!;
|
||||
data.bootstrapDns = List<String>.from(bootstrapControllers.map((e) => e['controller'].text));
|
||||
serversProvider.setDnsInfoData(data);
|
||||
|
||||
if (result['success'] == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.dnsConfigSaved,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
else if (result['success'] == false && result['error'] == 400) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.someValueNotValid,
|
||||
|
@ -102,8 +91,6 @@ class _BootstrapDnsScreenState extends State<BootstrapDnsScreen> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.dnsConfigNotSaved,
|
||||
|
|
|
@ -8,21 +8,14 @@ import 'package:adguard_home_manager/widgets/custom_switch_list_tile.dart';
|
|||
import 'package:adguard_home_manager/screens/settings/dns/clear_dns_cache_dialog.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/dns_provider.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/functions/clear_dns_cache.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/models/dns_info.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
|
||||
class CacheConfigDnsScreen extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
|
||||
const CacheConfigDnsScreen({
|
||||
Key? key,
|
||||
required this.serversProvider
|
||||
}) : super(key: key);
|
||||
const CacheConfigDnsScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<CacheConfigDnsScreen> createState() => _CacheConfigDnsScreenState();
|
||||
|
@ -60,10 +53,12 @@ class _CacheConfigDnsScreenState extends State<CacheConfigDnsScreen> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
cacheSizeController.text = widget.serversProvider.dnsInfo.data!.cacheSize.toString();
|
||||
overrideMinTtlController.text = widget.serversProvider.dnsInfo.data!.cacheTtlMin.toString();
|
||||
overrideMaxTtlController.text = widget.serversProvider.dnsInfo.data!.cacheTtlMax.toString();
|
||||
optimisticCache = widget.serversProvider.dnsInfo.data!.cacheOptimistic;
|
||||
final dnsProvider = Provider.of<DnsProvider>(context, listen: false);
|
||||
|
||||
cacheSizeController.text = dnsProvider.dnsInfo!.cacheSize.toString();
|
||||
overrideMinTtlController.text = dnsProvider.dnsInfo!.cacheTtlMin.toString();
|
||||
overrideMaxTtlController.text = dnsProvider.dnsInfo!.cacheTtlMax.toString();
|
||||
optimisticCache = dnsProvider.dnsInfo!.cacheOptimistic;
|
||||
validData = true;
|
||||
super.initState();
|
||||
}
|
||||
|
@ -71,13 +66,14 @@ class _CacheConfigDnsScreenState extends State<CacheConfigDnsScreen> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final dnsProvider = Provider.of<DnsProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
void saveData() async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.savingConfig);
|
||||
|
||||
final result = await setDnsConfig(server: serversProvider.selectedServer!, data: {
|
||||
final result = await dnsProvider.saveCacheCacheConfig({
|
||||
"cache_size": int.parse(cacheSizeController.text),
|
||||
"cache_ttl_min": int.parse(overrideMinTtlController.text),
|
||||
"cache_ttl_max": int.parse(overrideMaxTtlController.text),
|
||||
|
@ -86,23 +82,14 @@ class _CacheConfigDnsScreenState extends State<CacheConfigDnsScreen> {
|
|||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DnsInfoData data = serversProvider.dnsInfo.data!;
|
||||
data.cacheSize = int.parse(cacheSizeController.text);
|
||||
data.cacheTtlMin = int.parse(overrideMinTtlController.text);
|
||||
data.cacheTtlMax = int.parse(overrideMaxTtlController.text);
|
||||
data.cacheOptimistic = optimisticCache;
|
||||
serversProvider.setDnsInfoData(data);
|
||||
|
||||
if (result['success'] == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.dnsConfigSaved,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
else if (result['success'] == false && result['error'] == 400) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.someValueNotValid,
|
||||
|
@ -110,8 +97,6 @@ class _CacheConfigDnsScreenState extends State<CacheConfigDnsScreen> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.dnsConfigNotSaved,
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/dns_provider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_split_view/flutter_split_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
@ -19,64 +21,25 @@ import 'package:adguard_home_manager/functions/clear_dns_cache.dart';
|
|||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
|
||||
class DnsSettings extends StatelessWidget {
|
||||
class DnsSettings extends StatefulWidget {
|
||||
const DnsSettings({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
return DnsSettingsWidget(
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider,
|
||||
);
|
||||
}
|
||||
}
|
||||
class DnsSettingsWidget extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
final AppConfigProvider appConfigProvider;
|
||||
|
||||
const DnsSettingsWidget({
|
||||
required this.serversProvider,
|
||||
required this.appConfigProvider,
|
||||
Key? key
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<DnsSettingsWidget> createState() => _DnsSettingsWidgetState();
|
||||
State<DnsSettings> createState() => _DnsSettingsState();
|
||||
}
|
||||
|
||||
class _DnsSettingsWidgetState extends State<DnsSettingsWidget> {
|
||||
|
||||
void fetchData({bool? showRefreshIndicator}) async {
|
||||
widget.serversProvider.setDnsInfoLoadStatus(0, showRefreshIndicator ?? false);
|
||||
|
||||
final result = await getDnsInfo(server: widget.serversProvider.selectedServer!);
|
||||
|
||||
if (mounted) {
|
||||
if (result['result'] == 'success') {
|
||||
widget.serversProvider.setDnsInfoData(result['data']);
|
||||
widget.serversProvider.setDnsInfoLoadStatus(1, true);
|
||||
}
|
||||
else {
|
||||
widget.appConfigProvider.addLog(result['log']);
|
||||
widget.serversProvider.setDnsInfoLoadStatus(2, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _DnsSettingsState extends State<DnsSettings> {
|
||||
@override
|
||||
void initState() {
|
||||
fetchData();
|
||||
Provider.of<DnsProvider>(context, listen: false).fetchDnsData(showLoading: true);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final dnsProvider = Provider.of<DnsProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
@ -93,8 +56,8 @@ class _DnsSettingsWidgetState extends State<DnsSettingsWidget> {
|
|||
}
|
||||
|
||||
Widget generateBody() {
|
||||
switch (widget.serversProvider.dnsInfo.loadStatus) {
|
||||
case 0:
|
||||
switch (dnsProvider.loadStatus) {
|
||||
case LoadStatus.loading:
|
||||
return SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
|
@ -115,63 +78,43 @@ class _DnsSettingsWidgetState extends State<DnsSettingsWidget> {
|
|||
)
|
||||
);
|
||||
|
||||
case 1:
|
||||
case LoadStatus.loaded:
|
||||
return ListView(
|
||||
children: [
|
||||
CustomListTile(
|
||||
title: AppLocalizations.of(context)!.upstreamDns,
|
||||
subtitle: AppLocalizations.of(context)!.upstreamDnsDescription,
|
||||
onTap: () => navigate(
|
||||
UpstreamDnsScreen(
|
||||
serversProvider: serversProvider
|
||||
)
|
||||
),
|
||||
onTap: () => navigate(const UpstreamDnsScreen()),
|
||||
icon: Icons.upload_rounded,
|
||||
),
|
||||
CustomListTile(
|
||||
title: AppLocalizations.of(context)!.bootstrapDns,
|
||||
subtitle: AppLocalizations.of(context)!.bootstrapDnsDescription,
|
||||
onTap: () => navigate(
|
||||
BootstrapDnsScreen(
|
||||
serversProvider: serversProvider
|
||||
)
|
||||
),
|
||||
onTap: () => navigate(const BootstrapDnsScreen()),
|
||||
icon: Icons.dns_rounded,
|
||||
),
|
||||
CustomListTile(
|
||||
title: AppLocalizations.of(context)!.privateReverseDnsServers,
|
||||
subtitle: AppLocalizations.of(context)!.privateReverseDnsDescription,
|
||||
onTap: () => navigate(
|
||||
PrivateReverseDnsServersScreen(
|
||||
serversProvider: serversProvider
|
||||
)
|
||||
),
|
||||
onTap: () => navigate(const PrivateReverseDnsServersScreen()),
|
||||
icon: Icons.person_rounded,
|
||||
),
|
||||
CustomListTile(
|
||||
title: AppLocalizations.of(context)!.dnsServerSettings,
|
||||
subtitle: AppLocalizations.of(context)!.dnsServerSettingsDescription,
|
||||
onTap: () => navigate(
|
||||
DnsServerSettingsScreen(
|
||||
serversProvider: serversProvider
|
||||
)
|
||||
),
|
||||
onTap: () => navigate(const DnsServerSettingsScreen()),
|
||||
icon: Icons.settings,
|
||||
),
|
||||
CustomListTile(
|
||||
title: AppLocalizations.of(context)!.dnsCacheConfig,
|
||||
subtitle: AppLocalizations.of(context)!.dnsCacheConfigDescription,
|
||||
onTap: () => navigate(
|
||||
CacheConfigDnsScreen(
|
||||
serversProvider: serversProvider
|
||||
)
|
||||
),
|
||||
onTap: () => navigate(const CacheConfigDnsScreen()),
|
||||
icon: Icons.storage_rounded,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
case 2:
|
||||
case LoadStatus.error:
|
||||
return SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
|
@ -226,7 +169,7 @@ class _DnsSettingsWidgetState extends State<DnsSettingsWidget> {
|
|||
PopupMenuButton(
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(
|
||||
onTap: () => fetchData(showRefreshIndicator: true),
|
||||
onTap: () => dnsProvider.fetchDnsData(),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.refresh_rounded),
|
||||
|
|
|
@ -8,20 +8,13 @@ import 'package:adguard_home_manager/widgets/custom_radio_list_tile.dart';
|
|||
import 'package:adguard_home_manager/widgets/section_label.dart';
|
||||
import 'package:adguard_home_manager/widgets/custom_switch_list_tile.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/providers/dns_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/models/dns_info.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
|
||||
class DnsServerSettingsScreen extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
|
||||
const DnsServerSettingsScreen({
|
||||
Key? key,
|
||||
required this.serversProvider
|
||||
}) : super(key: key);
|
||||
const DnsServerSettingsScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<DnsServerSettingsScreen> createState() => _DnsServerSettingsScreenState();
|
||||
|
@ -89,56 +82,48 @@ class _DnsServerSettingsScreenState extends State<DnsServerSettingsScreen> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
limitRequestsController.text = widget.serversProvider.dnsInfo.data!.ratelimit.toString();
|
||||
enableEdns = widget.serversProvider.dnsInfo.data!.ednsCsEnabled;
|
||||
enableDnssec = widget.serversProvider.dnsInfo.data!.dnssecEnabled;
|
||||
disableIpv6Resolving = widget.serversProvider.dnsInfo.data!.disableIpv6;
|
||||
blockingMode = widget.serversProvider.dnsInfo.data!.blockingMode;
|
||||
ipv4controller.text = widget.serversProvider.dnsInfo.data!.blockingIpv4;
|
||||
ipv6controller.text = widget.serversProvider.dnsInfo.data!.blockingIpv6;
|
||||
final dnsProvider = Provider.of<DnsProvider>(context, listen: false);
|
||||
|
||||
limitRequestsController.text = dnsProvider.dnsInfo!.ratelimit.toString();
|
||||
enableEdns = dnsProvider.dnsInfo!.ednsCsEnabled;
|
||||
enableDnssec = dnsProvider.dnsInfo!.dnssecEnabled;
|
||||
disableIpv6Resolving = dnsProvider.dnsInfo!.disableIpv6;
|
||||
blockingMode = dnsProvider.dnsInfo!.blockingMode;
|
||||
ipv4controller.text = dnsProvider.dnsInfo!.blockingIpv4;
|
||||
ipv6controller.text = dnsProvider.dnsInfo!.blockingIpv6;
|
||||
isDataValid = true;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final dnsProvider = Provider.of<DnsProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
void saveData() async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.savingConfig);
|
||||
|
||||
final result = await setDnsConfig(server: serversProvider.selectedServer!, data: {
|
||||
final result = await dnsProvider.saveDnsServerConfig({
|
||||
"ratelimit": int.parse(limitRequestsController.text),
|
||||
"edns_cs_enabled": enableEdns,
|
||||
"dnssec_enabled": enableDnssec,
|
||||
"disable_ipv6": disableIpv6Resolving,
|
||||
"blocking_mode": blockingMode
|
||||
"blocking_mode": blockingMode,
|
||||
"blocking_ipv4": ipv4controller.text,
|
||||
"blocking_ipv6": ipv6controller.text
|
||||
});
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DnsInfoData data = serversProvider.dnsInfo.data!;
|
||||
data.ratelimit = int.parse(limitRequestsController.text);
|
||||
data.ednsCsEnabled = enableEdns;
|
||||
data.dnssecEnabled = enableDnssec;
|
||||
data.disableIpv6 = disableIpv6Resolving;
|
||||
data.blockingMode = blockingMode;
|
||||
data.blockingIpv4 = ipv4controller.text;
|
||||
data.blockingIpv6 = ipv6controller.text;
|
||||
serversProvider.setDnsInfoData(data);
|
||||
|
||||
if (result['success'] == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.dnsConfigSaved,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
else if (result['success'] == false && result['error'] == 400) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.someValueNotValid,
|
||||
|
@ -146,8 +131,6 @@ class _DnsServerSettingsScreenState extends State<DnsServerSettingsScreen> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.dnsConfigNotSaved,
|
||||
|
|
|
@ -6,20 +6,13 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
|
||||
import 'package:adguard_home_manager/widgets/custom_switch_list_tile.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/dns_provider.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/models/dns_info.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
|
||||
class PrivateReverseDnsServersScreen extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
|
||||
const PrivateReverseDnsServersScreen({
|
||||
Key? key,
|
||||
required this.serversProvider,
|
||||
}) : super(key: key);
|
||||
const PrivateReverseDnsServersScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<PrivateReverseDnsServersScreen> createState() => _PrivateReverseDnsServersScreenState();
|
||||
|
@ -69,10 +62,12 @@ class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServer
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
for (var item in widget.serversProvider.dnsInfo.data!.defaultLocalPtrUpstreams) {
|
||||
final dnsProvider = Provider.of<DnsProvider>(context, listen: false);
|
||||
|
||||
for (var item in dnsProvider.dnsInfo!.defaultLocalPtrUpstreams) {
|
||||
defaultReverseResolvers.add(item);
|
||||
}
|
||||
for (var item in widget.serversProvider.dnsInfo.data!.localPtrUpstreams) {
|
||||
for (var item in dnsProvider.dnsInfo!.localPtrUpstreams) {
|
||||
final controller = TextEditingController();
|
||||
controller.text = item;
|
||||
reverseResolversControllers = [{
|
||||
|
@ -80,54 +75,46 @@ class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServer
|
|||
'error': null
|
||||
}];
|
||||
}
|
||||
if (widget.serversProvider.dnsInfo.data!.localPtrUpstreams.isNotEmpty) {
|
||||
if (dnsProvider.dnsInfo!.localPtrUpstreams.isNotEmpty) {
|
||||
editReverseResolvers = true;
|
||||
}
|
||||
usePrivateReverseDnsResolvers = widget.serversProvider.dnsInfo.data!.usePrivatePtrResolvers;
|
||||
enableReverseResolve = widget.serversProvider.dnsInfo.data!.resolveClients;
|
||||
usePrivateReverseDnsResolvers = dnsProvider.dnsInfo!.usePrivatePtrResolvers;
|
||||
enableReverseResolve = dnsProvider.dnsInfo!.resolveClients;
|
||||
validValues = true;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final dnsProvider = Provider.of<DnsProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
void saveData() async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.savingConfig);
|
||||
|
||||
final result = await setDnsConfig(server: serversProvider.selectedServer!, data: editReverseResolvers == true
|
||||
? {
|
||||
"local_ptr_upstreams": List<String>.from(reverseResolversControllers.map((e) => e['controller'].text)),
|
||||
"use_private_ptr_resolvers": usePrivateReverseDnsResolvers,
|
||||
"resolve_clients": enableReverseResolve
|
||||
} : {
|
||||
"use_private_ptr_resolvers": usePrivateReverseDnsResolvers,
|
||||
"resolve_clients": enableReverseResolve
|
||||
});
|
||||
final result = await dnsProvider.savePrivateReverseServersConfig(
|
||||
editReverseResolvers == true
|
||||
? {
|
||||
"local_ptr_upstreams": List<String>.from(reverseResolversControllers.map((e) => e['controller'].text)),
|
||||
"use_private_ptr_resolvers": usePrivateReverseDnsResolvers,
|
||||
"resolve_clients": enableReverseResolve
|
||||
} : {
|
||||
"use_private_ptr_resolvers": usePrivateReverseDnsResolvers,
|
||||
"resolve_clients": enableReverseResolve
|
||||
}
|
||||
);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DnsInfoData data = serversProvider.dnsInfo.data!;
|
||||
if (editReverseResolvers == true) {
|
||||
data.localPtrUpstreams = List<String>.from(reverseResolversControllers.map((e) => e['controller'].text));
|
||||
}
|
||||
data.usePrivatePtrResolvers = usePrivateReverseDnsResolvers;
|
||||
data.resolveClients = enableReverseResolve;
|
||||
serversProvider.setDnsInfoData(data);
|
||||
|
||||
if (result['success'] == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.dnsConfigSaved,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
else if (result['success'] == false && result['error'] == 400) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.someValueNotValid,
|
||||
|
@ -135,8 +122,6 @@ class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServer
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.dnsConfigNotSaved,
|
||||
|
|
|
@ -10,20 +10,13 @@ import 'package:adguard_home_manager/widgets/section_label.dart';
|
|||
import 'package:adguard_home_manager/screens/settings/dns/comment_modal.dart';
|
||||
import 'package:adguard_home_manager/widgets/custom_radio_list_tile.dart';
|
||||
|
||||
import 'package:adguard_home_manager/models/dns_info.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/providers/dns_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class UpstreamDnsScreen extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
|
||||
const UpstreamDnsScreen({
|
||||
Key? key,
|
||||
required this.serversProvider,
|
||||
}) : super(key: key);
|
||||
const UpstreamDnsScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<UpstreamDnsScreen> createState() => _UpstreamDnsScreenState();
|
||||
|
@ -50,7 +43,9 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
for (var item in widget.serversProvider.dnsInfo.data!.upstreamDns) {
|
||||
final dnsProvider = Provider.of<DnsProvider>(context, listen: false);
|
||||
|
||||
for (var item in dnsProvider.dnsInfo!.upstreamDns) {
|
||||
if (item == '#') {
|
||||
dnsServers.add({
|
||||
'comment': item
|
||||
|
@ -64,14 +59,14 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
|||
});
|
||||
}
|
||||
}
|
||||
upstreamMode = widget.serversProvider.dnsInfo.data!.upstreamMode;
|
||||
upstreamMode = dnsProvider.dnsInfo!.upstreamMode;
|
||||
validValues = true;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final dnsProvider = Provider.of<DnsProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
@ -146,28 +141,21 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.savingConfig);
|
||||
|
||||
final result = await setDnsConfig(server: serversProvider.selectedServer!, data: {
|
||||
final result = await dnsProvider.saveUpstreamDnsConfig({
|
||||
"upstream_dns": dnsServers.map((e) => e['controller'] != null ? e['controller'].text : e['comment']).toList(),
|
||||
"upstream_mode": upstreamMode
|
||||
});
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
DnsInfoData data = serversProvider.dnsInfo.data!;
|
||||
data.upstreamDns = List<String>.from(dnsServers.map((e) => e['controller'] != null ? e['controller'].text : e['comment']));
|
||||
data.upstreamMode = upstreamMode;
|
||||
serversProvider.setDnsInfoData(data);
|
||||
|
||||
if (result['success'] == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.dnsConfigSaved,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else if (result['log'] != null && result['log'].statusCode == '400') {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
else if (result['success'] == false && result['error'] == 400) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.someValueNotValid,
|
||||
|
@ -175,8 +163,6 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.dnsConfigNotSaved,
|
||||
|
|
|
@ -6,7 +6,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
import 'package:adguard_home_manager/models/rewrite_rules.dart';
|
||||
|
||||
class AddDnsRewriteModal extends StatefulWidget {
|
||||
final void Function(RewriteRulesData) onConfirm;
|
||||
final void Function(RewriteRules) onConfirm;
|
||||
final bool dialog;
|
||||
|
||||
const AddDnsRewriteModal({
|
||||
|
@ -143,7 +143,7 @@ class _AddDnsRewriteModalState extends State<AddDnsRewriteModal> {
|
|||
? () {
|
||||
Navigator.pop(context);
|
||||
widget.onConfirm(
|
||||
RewriteRulesData(
|
||||
RewriteRules(
|
||||
domain: domainController.text,
|
||||
answer: answerController.text
|
||||
)
|
||||
|
|
|
@ -9,87 +9,43 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
import 'package:adguard_home_manager/screens/settings/dns_rewrites/add_dns_rewrite_modal.dart';
|
||||
import 'package:adguard_home_manager/screens/settings/dns_rewrites/delete_dns_rewrite.dart';
|
||||
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/rewrite_rules_provider.dart';
|
||||
import 'package:adguard_home_manager/models/rewrite_rules.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
|
||||
class DnsRewrites extends StatelessWidget {
|
||||
const DnsRewrites({Key? key}) : super(key: key);
|
||||
class DnsRewritesScreen extends StatefulWidget {
|
||||
const DnsRewritesScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
return DnsRewritesWidget(
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider,
|
||||
);
|
||||
}
|
||||
State<DnsRewritesScreen> createState() => _DnsRewritesScreenState();
|
||||
}
|
||||
|
||||
class DnsRewritesWidget extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
final AppConfigProvider appConfigProvider;
|
||||
|
||||
const DnsRewritesWidget({
|
||||
Key? key,
|
||||
required this.serversProvider,
|
||||
required this.appConfigProvider
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<DnsRewritesWidget> createState() => _DnsRewritesWidgetState();
|
||||
}
|
||||
|
||||
class _DnsRewritesWidgetState extends State<DnsRewritesWidget> {
|
||||
Future fetchData() async {
|
||||
widget.serversProvider.setRewriteRulesLoadStatus(0, false);
|
||||
|
||||
final result = await getDnsRewriteRules(server: widget.serversProvider.selectedServer!);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
widget.serversProvider.setRewriteRulesData(result['data']);
|
||||
widget.serversProvider.setRewriteRulesLoadStatus(1, true);
|
||||
}
|
||||
else {
|
||||
widget.appConfigProvider.addLog(result['log']);
|
||||
widget.serversProvider.setRewriteRulesLoadStatus(2, true);
|
||||
}
|
||||
}
|
||||
|
||||
class _DnsRewritesScreenState extends State<DnsRewritesScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
fetchData();
|
||||
Provider.of<RewriteRulesProvider>(context, listen: false).fetchRules();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final rewriteRulesProvider = Provider.of<RewriteRulesProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
||||
void deleteDnsRewrite(RewriteRulesData rule) async {
|
||||
void deleteDnsRewrite(RewriteRules rule) async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.deleting);
|
||||
|
||||
final result = await deleteDnsRewriteRule(server: serversProvider.selectedServer!, data: {
|
||||
"domain": rule.domain,
|
||||
"answer": rule.answer
|
||||
});
|
||||
final result = await rewriteRulesProvider.deleteDnsRewrite(rule);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
List<RewriteRulesData> data = serversProvider.rewriteRules.data!;
|
||||
data = data.where((item) => item.domain != rule.domain).toList();
|
||||
serversProvider.setRewriteRulesData(data);
|
||||
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.dnsRewriteRuleDeleted,
|
||||
|
@ -97,7 +53,6 @@ class _DnsRewritesWidgetState extends State<DnsRewritesWidget> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.dnsRewriteRuleNotDeleted,
|
||||
|
@ -106,22 +61,15 @@ class _DnsRewritesWidgetState extends State<DnsRewritesWidget> {
|
|||
}
|
||||
}
|
||||
|
||||
void addDnsRewrite(RewriteRulesData rule) async {
|
||||
void addDnsRewrite(RewriteRules rule) async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.addingRewrite);
|
||||
|
||||
final result = await addDnsRewriteRule(server: serversProvider.selectedServer!, data: {
|
||||
"domain": rule.domain,
|
||||
"answer": rule.answer
|
||||
});
|
||||
final result = await rewriteRulesProvider.addDnsRewrite(rule);
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
List<RewriteRulesData> data = serversProvider.rewriteRules.data!;
|
||||
data.add(rule);
|
||||
serversProvider.setRewriteRulesData(data);
|
||||
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.dnsRewriteRuleAdded,
|
||||
|
@ -129,7 +77,6 @@ class _DnsRewritesWidgetState extends State<DnsRewritesWidget> {
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.dnsRewriteRuleNotAdded,
|
||||
|
@ -139,8 +86,8 @@ class _DnsRewritesWidgetState extends State<DnsRewritesWidget> {
|
|||
}
|
||||
|
||||
Widget generateBody() {
|
||||
switch (serversProvider.rewriteRules.loadStatus) {
|
||||
case 0:
|
||||
switch (rewriteRulesProvider.loadStatus) {
|
||||
case LoadStatus.loading:
|
||||
return SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
|
@ -160,15 +107,22 @@ class _DnsRewritesWidgetState extends State<DnsRewritesWidget> {
|
|||
),
|
||||
);
|
||||
|
||||
case 1:
|
||||
if (serversProvider.rewriteRules.data!.isNotEmpty) {
|
||||
case LoadStatus.loaded:
|
||||
if (rewriteRulesProvider.rewriteRules!.isNotEmpty) {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
await fetchData();
|
||||
final result = await rewriteRulesProvider.fetchRules();
|
||||
if (result == false) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.rewriteRulesNotLoaded,
|
||||
color: Colors.red
|
||||
);
|
||||
}
|
||||
},
|
||||
child: ListView.builder(
|
||||
padding: const EdgeInsets.only(top: 0),
|
||||
itemCount: serversProvider.rewriteRules.data!.length,
|
||||
itemCount: rewriteRulesProvider.rewriteRules!.length,
|
||||
itemBuilder: (context, index) => Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
|
@ -195,7 +149,7 @@ class _DnsRewritesWidgetState extends State<DnsRewritesWidget> {
|
|||
),
|
||||
),
|
||||
Text(
|
||||
serversProvider.rewriteRules.data![index].domain,
|
||||
rewriteRulesProvider.rewriteRules![index].domain,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface
|
||||
),
|
||||
|
@ -213,7 +167,7 @@ class _DnsRewritesWidgetState extends State<DnsRewritesWidget> {
|
|||
),
|
||||
),
|
||||
Text(
|
||||
serversProvider.rewriteRules.data![index].answer,
|
||||
rewriteRulesProvider.rewriteRules![index].answer,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface
|
||||
),
|
||||
|
@ -227,7 +181,7 @@ class _DnsRewritesWidgetState extends State<DnsRewritesWidget> {
|
|||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => DeleteDnsRewrite(
|
||||
onConfirm: () => deleteDnsRewrite(serversProvider.rewriteRules.data![index])
|
||||
onConfirm: () => deleteDnsRewrite(rewriteRulesProvider.rewriteRules![index])
|
||||
)
|
||||
)
|
||||
},
|
||||
|
@ -251,7 +205,7 @@ class _DnsRewritesWidgetState extends State<DnsRewritesWidget> {
|
|||
);
|
||||
}
|
||||
|
||||
case 2:
|
||||
case LoadStatus.error:
|
||||
return SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
|
|
|
@ -16,7 +16,6 @@ import 'package:adguard_home_manager/screens/settings/encryption/error_message.d
|
|||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/functions/base64.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
|
@ -98,7 +97,7 @@ class _EncryptionSettingsWidgetState extends State<EncryptionSettingsWidget> {
|
|||
void fetchData({bool? showRefreshIndicator}) async {
|
||||
setState(() => loadStatus = 0);
|
||||
|
||||
final result = await getEncryptionSettings(server: widget.serversProvider.selectedServer!);
|
||||
final result = await Provider.of<ServersProvider>(context, listen: false).apiClient!.getEncryptionSettings();
|
||||
|
||||
if (mounted) {
|
||||
if (result['result'] == 'success') {
|
||||
|
@ -141,19 +140,21 @@ class _EncryptionSettingsWidgetState extends State<EncryptionSettingsWidget> {
|
|||
Future checkValidDataApi({Map<String, dynamic>? data}) async {
|
||||
setState(() => certKeyValidApi = 0);
|
||||
|
||||
final result = await checkEncryptionSettings(server: widget.serversProvider.selectedServer!, data: data ?? {
|
||||
"enabled": enabled,
|
||||
"server_name": domainNameController.text,
|
||||
"force_https": redirectHttps,
|
||||
"port_https": httpsPortController.text != '' ? int.parse(httpsPortController.text) : null,
|
||||
"port_dns_over_tls": tlsPortController.text != '' ? int.parse(tlsPortController.text) : null,
|
||||
"port_dns_over_quic": dnsOverQuicPortController.text != '' ? int.parse(dnsOverQuicPortController.text) : null,
|
||||
if (certificateOption == 1) "certificate_chain": encodeBase64(certificateContentController.text),
|
||||
if (privateKeyOption == 1 && usePreviouslySavedKey == false) "private_key": encodeBase64(pastePrivateKeyController.text),
|
||||
"private_key_saved": usePreviouslySavedKey,
|
||||
if (certificateOption == 0) "certificate_path": certificatePathController.text,
|
||||
if (privateKeyOption == 0) "private_key_path": privateKeyPathController.text,
|
||||
});
|
||||
final result = await Provider.of<ServersProvider>(context, listen: false).apiClient!.checkEncryptionSettings(
|
||||
data: data ?? {
|
||||
"enabled": enabled,
|
||||
"server_name": domainNameController.text,
|
||||
"force_https": redirectHttps,
|
||||
"port_https": httpsPortController.text != '' ? int.parse(httpsPortController.text) : null,
|
||||
"port_dns_over_tls": tlsPortController.text != '' ? int.parse(tlsPortController.text) : null,
|
||||
"port_dns_over_quic": dnsOverQuicPortController.text != '' ? int.parse(dnsOverQuicPortController.text) : null,
|
||||
if (certificateOption == 1) "certificate_chain": encodeBase64(certificateContentController.text),
|
||||
if (privateKeyOption == 1 && usePreviouslySavedKey == false) "private_key": encodeBase64(pastePrivateKeyController.text),
|
||||
"private_key_saved": usePreviouslySavedKey,
|
||||
if (certificateOption == 0) "certificate_path": certificatePathController.text,
|
||||
if (privateKeyOption == 0) "private_key_path": privateKeyPathController.text,
|
||||
}
|
||||
);
|
||||
|
||||
if (mounted) {
|
||||
if (result['result'] == 'success') {
|
||||
|
@ -224,19 +225,21 @@ class _EncryptionSettingsWidgetState extends State<EncryptionSettingsWidget> {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.savingConfig);
|
||||
|
||||
final result = await saveEncryptionSettings(server: serversProvider.selectedServer!, data: {
|
||||
"enabled": enabled,
|
||||
"server_name": domainNameController.text,
|
||||
"force_https": redirectHttps,
|
||||
"port_https": int.tryParse(httpsPortController.text),
|
||||
"port_dns_over_tls": int.tryParse(tlsPortController.text),
|
||||
"port_dns_over_quic": int.tryParse(dnsOverQuicPortController.text),
|
||||
"certificate_chain": encodeBase64(certificateContentController.text),
|
||||
"private_key": encodeBase64(pastePrivateKeyController.text),
|
||||
"private_key_saved": usePreviouslySavedKey,
|
||||
"certificate_path": certificatePathController.text,
|
||||
"private_key_path": privateKeyPathController.text,
|
||||
});
|
||||
final result = await serversProvider.apiClient!.saveEncryptionSettings(
|
||||
data: {
|
||||
"enabled": enabled,
|
||||
"server_name": domainNameController.text,
|
||||
"force_https": redirectHttps,
|
||||
"port_https": int.tryParse(httpsPortController.text),
|
||||
"port_dns_over_tls": int.tryParse(tlsPortController.text),
|
||||
"port_dns_over_quic": int.tryParse(dnsOverQuicPortController.text),
|
||||
"certificate_chain": encodeBase64(certificateContentController.text),
|
||||
"private_key": encodeBase64(pastePrivateKeyController.text),
|
||||
"private_key_saved": usePreviouslySavedKey,
|
||||
"certificate_path": certificatePathController.text,
|
||||
"private_key_path": privateKeyPathController.text,
|
||||
}
|
||||
);
|
||||
|
||||
processModal.close();
|
||||
|
||||
|
|
|
@ -2,20 +2,19 @@
|
|||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/widgets/section_label.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:store_checker/store_checker.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.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/functions/check_app_updates.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/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||
|
||||
class GeneralSettings extends StatefulWidget {
|
||||
const GeneralSettings({Key? key}) : super(key: key);
|
||||
|
@ -56,16 +55,16 @@ class _GeneralSettingsState extends State<GeneralSettings> {
|
|||
|
||||
Future checkUpdatesAvailable() async {
|
||||
setState(() => appUpdatesStatus = AppUpdatesStatus.checking);
|
||||
final result = await checkAppUpdatesGitHub();
|
||||
if (result['result'] == 'success') {
|
||||
final update = gitHubUpdateExists(appConfigProvider.getAppInfo!.version, result['body'].tagName);
|
||||
if (update == true) {
|
||||
appConfigProvider.setAppUpdatesAvailable(result['body']);
|
||||
setState(() => appUpdatesStatus = AppUpdatesStatus.available);
|
||||
}
|
||||
else {
|
||||
setState(() => appUpdatesStatus = AppUpdatesStatus.recheck);
|
||||
}
|
||||
|
||||
final res = await checkAppUpdates(
|
||||
currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber,
|
||||
setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable,
|
||||
installationSource: appConfigProvider.installationSource,
|
||||
isBeta: appConfigProvider.getAppInfo!.version.contains('beta'),
|
||||
);
|
||||
|
||||
if (res != null) {
|
||||
setState(() => appUpdatesStatus = AppUpdatesStatus.available);
|
||||
}
|
||||
else {
|
||||
setState(() => appUpdatesStatus = AppUpdatesStatus.recheck);
|
||||
|
|
|
@ -7,42 +7,19 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
import 'package:adguard_home_manager/widgets/custom_checkbox_list_tile.dart';
|
||||
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/models/server_status.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class SafeSearchSettingsScreen extends StatelessWidget {
|
||||
class SafeSearchSettingsScreen extends StatefulWidget {
|
||||
const SafeSearchSettingsScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
return SafeSearchSettingsScreenWidget(
|
||||
serversProvider: serversProvider,
|
||||
appConfigProvider: appConfigProvider,
|
||||
);
|
||||
}
|
||||
State<SafeSearchSettingsScreen> createState() => _SafeSearchSettingsScreenState();
|
||||
}
|
||||
|
||||
class SafeSearchSettingsScreenWidget extends StatefulWidget {
|
||||
final ServersProvider serversProvider;
|
||||
final AppConfigProvider appConfigProvider;
|
||||
|
||||
const SafeSearchSettingsScreenWidget({
|
||||
Key? key,
|
||||
required this.serversProvider,
|
||||
required this.appConfigProvider
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<SafeSearchSettingsScreenWidget> createState() => _SafeSearchSettingsScreenWidgetState();
|
||||
}
|
||||
|
||||
class _SafeSearchSettingsScreenWidgetState extends State<SafeSearchSettingsScreenWidget> {
|
||||
class _SafeSearchSettingsScreenState extends State<SafeSearchSettingsScreen> {
|
||||
bool generalEnabled = false;
|
||||
bool bingEnabled = false;
|
||||
bool duckduckgoEnabled = false;
|
||||
|
@ -50,85 +27,66 @@ class _SafeSearchSettingsScreenWidgetState extends State<SafeSearchSettingsScree
|
|||
bool pixabayEnabled = false;
|
||||
bool yandexEnabled = false;
|
||||
bool youtubeEnabled = false;
|
||||
|
||||
|
||||
Future requestSafeSearchSettings() async {
|
||||
if (mounted) {
|
||||
final result = await getServerStatus(widget.serversProvider.selectedServer!);
|
||||
if (mounted) {
|
||||
if (result['result'] == 'success') {
|
||||
widget.serversProvider.setServerStatusData(result['data']);
|
||||
widget.serversProvider.setServerStatusLoad(1);
|
||||
setState(() {
|
||||
generalEnabled = result['data'].safeSearchEnabled;
|
||||
bingEnabled = result['data'].safeSeachBing;
|
||||
duckduckgoEnabled = result['data'].safeSearchDuckduckgo;
|
||||
googleEnabled = result['data'].safeSearchGoogle;
|
||||
pixabayEnabled = result['data'].safeSearchPixabay;
|
||||
yandexEnabled = result['data'].safeSearchYandex;
|
||||
youtubeEnabled = result['data'].safeSearchYoutube;
|
||||
});
|
||||
}
|
||||
else {
|
||||
widget.appConfigProvider.addLog(result['log']);
|
||||
widget.serversProvider.setServerStatusLoad(2);
|
||||
}
|
||||
final result = await Provider.of<StatusProvider>(context, listen: false).getServerStatus();
|
||||
if (mounted && result == true) {
|
||||
final statusProvider = Provider.of<StatusProvider>(context, listen: false);
|
||||
if (statusProvider.serverStatus != null) {
|
||||
setState(() {
|
||||
generalEnabled = statusProvider.serverStatus!.safeSearchEnabled;
|
||||
bingEnabled = statusProvider.serverStatus!.safeSeachBing ?? false;
|
||||
duckduckgoEnabled = statusProvider.serverStatus!.safeSearchDuckduckgo ?? false;
|
||||
googleEnabled = statusProvider.serverStatus!.safeSearchGoogle ?? false;
|
||||
pixabayEnabled = statusProvider.serverStatus!.safeSearchPixabay ?? false;
|
||||
yandexEnabled = statusProvider.serverStatus!.safeSearchYandex ?? false;
|
||||
youtubeEnabled = statusProvider.serverStatus!.safeSearchYoutube ?? false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
if (widget.serversProvider.serverStatus.loadStatus == 0) {
|
||||
final statusProvider = Provider.of<StatusProvider>(context, listen: false);
|
||||
|
||||
if (statusProvider.loadStatus == LoadStatus.loading) {
|
||||
requestSafeSearchSettings();
|
||||
}
|
||||
else if (widget.serversProvider.serverStatus.loadStatus == 1) {
|
||||
generalEnabled = widget.serversProvider.serverStatus.data!.safeSearchEnabled;
|
||||
bingEnabled = widget.serversProvider.serverStatus.data!.safeSeachBing!;
|
||||
duckduckgoEnabled = widget.serversProvider.serverStatus.data!.safeSearchDuckduckgo!;
|
||||
googleEnabled = widget.serversProvider.serverStatus.data!.safeSearchGoogle!;
|
||||
pixabayEnabled = widget.serversProvider.serverStatus.data!.safeSearchPixabay!;
|
||||
yandexEnabled = widget.serversProvider.serverStatus.data!.safeSearchYandex!;
|
||||
youtubeEnabled = widget.serversProvider.serverStatus.data!.safeSearchYoutube!;
|
||||
else if (statusProvider.loadStatus == LoadStatus.loaded) {
|
||||
generalEnabled = statusProvider.serverStatus!.safeSearchEnabled;
|
||||
bingEnabled = statusProvider.serverStatus!.safeSeachBing!;
|
||||
duckduckgoEnabled = statusProvider.serverStatus!.safeSearchDuckduckgo!;
|
||||
googleEnabled = statusProvider.serverStatus!.safeSearchGoogle!;
|
||||
pixabayEnabled = statusProvider.serverStatus!.safeSearchPixabay!;
|
||||
yandexEnabled = statusProvider.serverStatus!.safeSearchYandex!;
|
||||
youtubeEnabled = statusProvider.serverStatus!.safeSearchYoutube!;
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
void saveConfig() async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.savingSettings);
|
||||
|
||||
final result = await updateSafeSearchSettings(
|
||||
server: serversProvider.selectedServer!,
|
||||
body: {
|
||||
"enabled": generalEnabled,
|
||||
"bing": bingEnabled,
|
||||
"duckduckgo": duckduckgoEnabled,
|
||||
"google": googleEnabled,
|
||||
"pixabay": pixabayEnabled,
|
||||
"yandex": yandexEnabled,
|
||||
"youtube": youtubeEnabled
|
||||
}
|
||||
);
|
||||
final result = await statusProvider.updateSafeSearchConfig({
|
||||
"enabled": generalEnabled,
|
||||
"bing": bingEnabled,
|
||||
"duckduckgo": duckduckgoEnabled,
|
||||
"google": googleEnabled,
|
||||
"pixabay": pixabayEnabled,
|
||||
"yandex": yandexEnabled,
|
||||
"youtube": youtubeEnabled
|
||||
});
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
ServerStatusData data = serversProvider.serverStatus.data!;
|
||||
data.safeSearchEnabled = generalEnabled;
|
||||
data.safeSeachBing = bingEnabled;
|
||||
data.safeSearchDuckduckgo = duckduckgoEnabled;
|
||||
data.safeSearchGoogle = googleEnabled;
|
||||
data.safeSearchPixabay = pixabayEnabled;
|
||||
data.safeSearchYandex = yandexEnabled;
|
||||
data.safeSearchYoutube = youtubeEnabled;
|
||||
|
||||
serversProvider.setServerStatusData(data);
|
||||
|
||||
if (result == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.settingsUpdatedSuccessfully,
|
||||
|
@ -137,7 +95,6 @@ class _SafeSearchSettingsScreenWidgetState extends State<SafeSearchSettingsScree
|
|||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.settingsNotSaved,
|
||||
|
@ -148,8 +105,8 @@ class _SafeSearchSettingsScreenWidgetState extends State<SafeSearchSettingsScree
|
|||
}
|
||||
|
||||
Widget body() {
|
||||
switch (serversProvider.serverStatus.loadStatus) {
|
||||
case 0:
|
||||
switch (statusProvider.loadStatus) {
|
||||
case LoadStatus.loading:
|
||||
return SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
|
@ -170,7 +127,7 @@ class _SafeSearchSettingsScreenWidgetState extends State<SafeSearchSettingsScree
|
|||
),
|
||||
);
|
||||
|
||||
case 1:
|
||||
case LoadStatus.loaded:
|
||||
return RefreshIndicator(
|
||||
onRefresh: requestSafeSearchSettings,
|
||||
child: ListView(
|
||||
|
@ -274,7 +231,7 @@ class _SafeSearchSettingsScreenWidgetState extends State<SafeSearchSettingsScree
|
|||
),
|
||||
);
|
||||
|
||||
case 2:
|
||||
case LoadStatus.error:
|
||||
return SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
|
@ -311,7 +268,7 @@ class _SafeSearchSettingsScreenWidgetState extends State<SafeSearchSettingsScree
|
|||
centerTitle: false,
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: serversProvider.serverStatus.loadStatus == 1
|
||||
onPressed: statusProvider.loadStatus == LoadStatus.loaded
|
||||
? () => saveConfig()
|
||||
: null,
|
||||
icon: const Icon(Icons.save_rounded),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:animations/animations.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
@ -7,7 +8,6 @@ import 'package:adguard_home_manager/screens/settings/server_info/dns_addresses_
|
|||
import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/models/server_info.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
|
@ -41,20 +41,19 @@ class ServerInformationWidget extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _ServerInformationWidgetState extends State<ServerInformationWidget> {
|
||||
ServerInfo serverInfo = ServerInfo(loadStatus: 0);
|
||||
ServerInfo serverInfo = ServerInfo(loadStatus: LoadStatus.loading);
|
||||
|
||||
void fetchServerInfo() async {
|
||||
final result = await getServerInfo(server: widget.serversProvider.selectedServer!);
|
||||
final result = await Provider.of<ServersProvider>(context, listen: false).apiClient!.getServerInfo();
|
||||
if (mounted) {
|
||||
if (result['result'] == 'success') {
|
||||
setState(() {
|
||||
serverInfo.loadStatus = 1;
|
||||
serverInfo.loadStatus = LoadStatus.loaded;
|
||||
serverInfo.data = result['data'];
|
||||
});
|
||||
}
|
||||
else {
|
||||
widget.appConfigProvider.addLog(result['log']);
|
||||
setState(() => serverInfo.loadStatus = 2);
|
||||
setState(() => serverInfo.loadStatus = LoadStatus.loaded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +68,7 @@ class _ServerInformationWidgetState extends State<ServerInformationWidget> {
|
|||
Widget build(BuildContext context) {
|
||||
Widget generateBody() {
|
||||
switch (serverInfo.loadStatus) {
|
||||
case 0:
|
||||
case LoadStatus.loading:
|
||||
return SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
|
@ -93,7 +92,7 @@ class _ServerInformationWidgetState extends State<ServerInformationWidget> {
|
|||
),
|
||||
);
|
||||
|
||||
case 1:
|
||||
case LoadStatus.loaded:
|
||||
return ListView(
|
||||
children: [
|
||||
CustomListTile(
|
||||
|
@ -145,7 +144,7 @@ class _ServerInformationWidgetState extends State<ServerInformationWidget> {
|
|||
]
|
||||
);
|
||||
|
||||
case 2:
|
||||
case LoadStatus.error:
|
||||
return SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
|
|
|
@ -27,6 +27,7 @@ import 'package:adguard_home_manager/constants/strings.dart';
|
|||
import 'package:adguard_home_manager/functions/open_url.dart';
|
||||
import 'package:adguard_home_manager/functions/compare_versions.dart';
|
||||
import 'package:adguard_home_manager/constants/urls.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
|
||||
|
@ -67,8 +68,9 @@ class SettingsWidget extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
||||
|
@ -129,10 +131,14 @@ class SettingsWidget extends StatelessWidget {
|
|||
],
|
||||
body: ListView(
|
||||
children: [
|
||||
if (serversProvider.selectedServer != null && serversProvider.serverStatus.data != null) ...[
|
||||
if (
|
||||
serversProvider.selectedServer != null &&
|
||||
statusProvider.serverStatus != null &&
|
||||
serversProvider.apiClient != null
|
||||
) ...[
|
||||
SectionLabel(label: AppLocalizations.of(context)!.serverSettings),
|
||||
if (serverVersionIsAhead(
|
||||
currentVersion: serversProvider.serverStatus.data!.serverVersion,
|
||||
currentVersion: statusProvider.serverStatus!.serverVersion,
|
||||
referenceVersion: 'v0.107.28',
|
||||
referenceVersionBeta: 'v0.108.0-b.33'
|
||||
) == true) settingsTile(
|
||||
|
@ -154,7 +160,7 @@ class SettingsWidget extends StatelessWidget {
|
|||
title: AppLocalizations.of(context)!.dhcpSettings,
|
||||
subtitle: AppLocalizations.of(context)!.dhcpSettingsDescription,
|
||||
thisItem: 2,
|
||||
screenToNavigate: const Dhcp(),
|
||||
screenToNavigate: const DhcpScreen(),
|
||||
),
|
||||
settingsTile(
|
||||
icon: Icons.dns_rounded,
|
||||
|
@ -175,7 +181,7 @@ class SettingsWidget extends StatelessWidget {
|
|||
title: AppLocalizations.of(context)!.dnsRewrites,
|
||||
subtitle: AppLocalizations.of(context)!.dnsRewritesDescription,
|
||||
thisItem: 5,
|
||||
screenToNavigate: const DnsRewrites(),
|
||||
screenToNavigate: const DnsRewritesScreen(),
|
||||
),
|
||||
if (serversProvider.updateAvailable.data != null) settingsTile(
|
||||
icon: Icons.system_update_rounded,
|
||||
|
@ -217,7 +223,7 @@ class SettingsWidget extends StatelessWidget {
|
|||
icon: Icons.storage_rounded,
|
||||
title: AppLocalizations.of(context)!.servers,
|
||||
subtitle: serversProvider.selectedServer != null
|
||||
? serversProvider.serverStatus.data != null
|
||||
? statusProvider.serverStatus != null
|
||||
? "${AppLocalizations.of(context)!.connectedTo} ${serversProvider.selectedServer!.name}"
|
||||
: "${AppLocalizations.of(context)!.selectedServer} ${serversProvider.selectedServer!.name}"
|
||||
: AppLocalizations.of(context)!.noServerSelected,
|
||||
|
|
|
@ -10,7 +10,6 @@ import 'package:provider/provider.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/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/functions/open_url.dart';
|
||||
|
@ -36,7 +35,7 @@ class UpdateScreen extends StatelessWidget {
|
|||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.requestingUpdate);
|
||||
|
||||
final result = await requestUpdateServer(server: serversProvider.selectedServer!);
|
||||
final result = await serversProvider.apiClient!.requestUpdateServer();
|
||||
|
||||
processModal.close();
|
||||
|
||||
|
@ -56,7 +55,6 @@ class UpdateScreen extends StatelessWidget {
|
|||
color: Colors.red,
|
||||
labelColor: Colors.white,
|
||||
);
|
||||
appConfigProvider.addLog(result['log']);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,8 +90,8 @@ class UpdateScreen extends StatelessWidget {
|
|||
child: Column(
|
||||
children: [
|
||||
serversProvider.updateAvailable.loadStatus == LoadStatus.loading
|
||||
? Column(
|
||||
children: const [
|
||||
? const Column(
|
||||
children: [
|
||||
CircularProgressIndicator(),
|
||||
SizedBox(height: 4)
|
||||
],
|
||||
|
|
|
@ -12,11 +12,10 @@ import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
|||
|
||||
import 'package:adguard_home_manager/models/applied_filters.dart';
|
||||
import 'package:adguard_home_manager/providers/logs_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/functions/number_format.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
|
||||
class TopItemsScreen extends StatefulWidget {
|
||||
final String type;
|
||||
|
@ -57,7 +56,7 @@ class _TopItemsScreenState extends State<TopItemsScreen> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
final logsProvider = Provider.of<LogsProvider>(context);
|
||||
|
||||
|
@ -130,12 +129,8 @@ class _TopItemsScreenState extends State<TopItemsScreen> {
|
|||
),
|
||||
body: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
final result = await getServerStatus(serversProvider.selectedServer!);
|
||||
if (result['result'] == 'success') {
|
||||
serversProvider.setServerStatusData(result['data']);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
final result = await statusProvider.getServerStatus();
|
||||
if (result == false) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.serverStatusNotRefreshed,
|
||||
|
@ -150,7 +145,7 @@ class _TopItemsScreenState extends State<TopItemsScreen> {
|
|||
String? name;
|
||||
if (widget.isClient != null && widget.isClient == true) {
|
||||
try {
|
||||
name = serversProvider.serverStatus.data!.clients.firstWhere((c) => c.ids.contains(screenData[index].keys.toList()[0])).name;
|
||||
name = statusProvider.serverStatus!.clients.firstWhere((c) => c.ids.contains(screenData[index].keys.toList()[0])).name;
|
||||
} catch (e) {
|
||||
// ---- //
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@ import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
|||
import 'package:adguard_home_manager/models/applied_filters.dart';
|
||||
import 'package:adguard_home_manager/providers/logs_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/number_format.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class TopItemsModal extends StatefulWidget {
|
||||
final String type;
|
||||
|
@ -55,7 +55,7 @@ class _TopItemsModalState extends State<TopItemsModal> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
final logsProvider = Provider.of<LogsProvider>(context);
|
||||
|
||||
|
@ -122,7 +122,7 @@ class _TopItemsModalState extends State<TopItemsModal> {
|
|||
String? name;
|
||||
if (widget.isClient != null && widget.isClient == true) {
|
||||
try {
|
||||
name = serversProvider.serverStatus.data!.clients.firstWhere((c) => c.ids.contains(screenData[index].keys.toList()[0])).name;
|
||||
name = statusProvider.serverStatus!.clients.firstWhere((c) => c.ids.contains(screenData[index].keys.toList()[0])).name;
|
||||
} catch (e) {
|
||||
// ---- //
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -7,6 +7,8 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/functions/base64.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/models/app_log.dart';
|
||||
|
@ -217,6 +219,7 @@ class _AddServerModalState extends State<AddServerModal> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context, listen: false);
|
||||
final statusProvider = Provider.of<StatusProvider>(context, listen: false);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context, listen: false);
|
||||
|
||||
final mediaQuery = MediaQuery.of(context);
|
||||
|
@ -257,13 +260,18 @@ class _AddServerModalState extends State<AddServerModal> {
|
|||
}
|
||||
final serverCreated = await serversProvider.createServer(serverObj);
|
||||
if (serverCreated == null) {
|
||||
serversProvider.setServerStatusLoad(0);
|
||||
statusProvider.setServerStatusLoad(LoadStatus.loading);
|
||||
|
||||
final ApiClient apiClient = ApiClient(server: serverObj);
|
||||
|
||||
final serverStatus = await getServerStatus(serverObj);
|
||||
final serverStatus = await apiClient.getServerStatus();
|
||||
|
||||
if (serverStatus['result'] == 'success') {
|
||||
serversProvider.setServerStatusData(serverStatus['data']);
|
||||
serversProvider.setServerStatusLoad(1);
|
||||
statusProvider.setServerStatusData(
|
||||
data: serverStatus['data']
|
||||
);
|
||||
serversProvider.setApiClient(apiClient);
|
||||
statusProvider.setServerStatusLoad(LoadStatus.loaded);
|
||||
if (serverStatus['data'].serverVersion.contains('a') || serverStatus['data'].serverVersion.contains('b')) {
|
||||
Navigator.pop(context);
|
||||
widget.onUnsupportedVersion(serverStatus['data'].serverVersion);
|
||||
|
@ -274,7 +282,7 @@ class _AddServerModalState extends State<AddServerModal> {
|
|||
}
|
||||
else {
|
||||
appConfigProvider.addLog(serverStatus['log']);
|
||||
serversProvider.setServerStatusLoad(2);
|
||||
statusProvider.setServerStatusLoad(LoadStatus.error);
|
||||
Navigator.pop(context);
|
||||
}
|
||||
}
|
||||
|
@ -377,7 +385,8 @@ class _AddServerModalState extends State<AddServerModal> {
|
|||
final serverSaved = await serversProvider.editServer(serverObj);
|
||||
|
||||
if (serverSaved == null) {
|
||||
final version = await getServerVersion(serverObj);
|
||||
final ApiClient apiClient = ApiClient(server: serverObj);
|
||||
final version = await apiClient.getServerVersion();
|
||||
if (
|
||||
version['result'] == 'success' &&
|
||||
(version['data'].contains('a') || version['data'].contains('b')) // alpha or beta
|
||||
|
|
|
@ -17,11 +17,10 @@ class BottomNavBar extends StatelessWidget {
|
|||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
final logsProvider = Provider.of<LogsProvider>(context);
|
||||
|
||||
List<AppScreen> screens = serversProvider.selectedServer != null
|
||||
List<AppScreen> screens = serversProvider.selectedServer != null && serversProvider.apiClient != null
|
||||
? screensServerConnected
|
||||
: screensSelectServer;
|
||||
|
||||
|
||||
String translatedName(String key) {
|
||||
switch (key) {
|
||||
case 'home':
|
||||
|
@ -47,8 +46,14 @@ class BottomNavBar extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
if ((serversProvider.selectedServer == null || serversProvider.apiClient == null) && appConfigProvider.selectedScreen > 1) {
|
||||
appConfigProvider.setSelectedScreen(0);
|
||||
}
|
||||
|
||||
return NavigationBar(
|
||||
selectedIndex: appConfigProvider.selectedScreen,
|
||||
selectedIndex: (serversProvider.selectedServer == null || serversProvider.apiClient == null) && appConfigProvider.selectedScreen > 1
|
||||
? 0
|
||||
: appConfigProvider.selectedScreen,
|
||||
destinations: screens.map((screen) => NavigationDestination(
|
||||
icon: Stack(
|
||||
children: [
|
||||
|
|
|
@ -9,11 +9,10 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
import 'package:adguard_home_manager/widgets/options_modal.dart';
|
||||
import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
||||
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/models/filtering_status.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:adguard_home_manager/models/menu_option.dart';
|
||||
|
||||
class DomainOptions extends StatelessWidget {
|
||||
|
@ -36,59 +35,33 @@ class DomainOptions extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
void blockUnblock(String domain, String newStatus) async {
|
||||
final ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.savingUserFilters);
|
||||
|
||||
final rules = await getFilteringRules(server: serversProvider.selectedServer!);
|
||||
final rules = await statusProvider.blockUnblockDomain(
|
||||
domain: domain,
|
||||
newStatus: newStatus
|
||||
);
|
||||
|
||||
if (rules['result'] == 'success') {
|
||||
FilteringStatus oldStatus = serversProvider.serverStatus.data!.filteringStatus;
|
||||
processModal.close();
|
||||
|
||||
List<String> newRules = rules['data'].userRules.where((d) => !d.contains(domain)).toList();
|
||||
if (newStatus == 'block') {
|
||||
newRules.add("||$domain^");
|
||||
}
|
||||
else if (newStatus == 'unblock') {
|
||||
newRules.add("@@||$domain^");
|
||||
}
|
||||
FilteringStatus newObj = serversProvider.serverStatus.data!.filteringStatus;
|
||||
newObj.userRules = newRules;
|
||||
serversProvider.setFilteringStatus(newObj);
|
||||
|
||||
final result = await postFilteringRules(server: serversProvider.selectedServer!, data: {'rules': newRules});
|
||||
|
||||
processModal.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.userFilteringRulesUpdated),
|
||||
backgroundColor: Colors.green,
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(result['log']);
|
||||
serversProvider.setFilteringStatus(oldStatus);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.userFilteringRulesNotUpdated),
|
||||
backgroundColor: Colors.red,
|
||||
)
|
||||
);
|
||||
}
|
||||
if (rules == true) {
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.userFilteringRulesUpdated,
|
||||
color: Colors.green
|
||||
);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(rules['log']);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.userFilteringRulesNotUpdated),
|
||||
backgroundColor: Colors.red,
|
||||
)
|
||||
showSnacbkar(
|
||||
appConfigProvider: appConfigProvider,
|
||||
label: AppLocalizations.of(context)!.userFilteringRulesNotUpdated,
|
||||
color: Colors.red
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,8 +46,14 @@ class SideNavigationRail extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
if ((serversProvider.selectedServer == null || serversProvider.apiClient == null) && appConfigProvider.selectedScreen > 1) {
|
||||
appConfigProvider.setSelectedScreen(0);
|
||||
}
|
||||
|
||||
return NavigationRail(
|
||||
selectedIndex: appConfigProvider.selectedScreen,
|
||||
selectedIndex: (serversProvider.selectedServer == null || serversProvider.apiClient == null) && appConfigProvider.selectedScreen > 1
|
||||
? 0
|
||||
: appConfigProvider.selectedScreen,
|
||||
destinations: screens.map((screen) => NavigationRailDestination(
|
||||
icon: Icon(
|
||||
screen.icon,
|
||||
|
|
|
@ -11,6 +11,8 @@ import 'package:adguard_home_manager/widgets/servers_list/delete_modal.dart';
|
|||
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/models/app_log.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
|
@ -69,6 +71,7 @@ class _ServersListItemState extends State<ServersListItem> with SingleTickerProv
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
@ -132,18 +135,22 @@ class _ServersListItemState extends State<ServersListItem> with SingleTickerProv
|
|||
: await login(server);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
final ApiClient apiClient = ApiClient(server: server);
|
||||
serversProvider.setApiClient(apiClient);
|
||||
serversProvider.setSelectedServer(server);
|
||||
|
||||
serversProvider.setServerStatusLoad(0);
|
||||
final serverStatus = await getServerStatus(server);
|
||||
statusProvider.setServerStatusLoad(LoadStatus.loading);
|
||||
final serverStatus = await apiClient.getServerStatus();
|
||||
if (serverStatus['result'] == 'success') {
|
||||
serversProvider.setServerStatusData(serverStatus['data']);
|
||||
statusProvider.setServerStatusData(
|
||||
data: serverStatus['data']
|
||||
);
|
||||
serversProvider.checkServerUpdatesAvailable(server);
|
||||
serversProvider.setServerStatusLoad(1);
|
||||
statusProvider.setServerStatusLoad(LoadStatus.loaded);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(serverStatus['log']);
|
||||
serversProvider.setServerStatusLoad(2);
|
||||
statusProvider.setServerStatusLoad(LoadStatus.error);
|
||||
}
|
||||
|
||||
process.close();
|
||||
|
@ -192,7 +199,7 @@ class _ServersListItemState extends State<ServersListItem> with SingleTickerProv
|
|||
Icon(
|
||||
Icons.storage_rounded,
|
||||
color: serversProvider.selectedServer != null && serversProvider.selectedServer?.id == server.id
|
||||
? serversProvider.serverStatus.data != null
|
||||
? statusProvider.serverStatus != null
|
||||
? Colors.green
|
||||
: Colors.orange
|
||||
: null,
|
||||
|
@ -225,7 +232,7 @@ class _ServersListItemState extends State<ServersListItem> with SingleTickerProv
|
|||
return Icon(
|
||||
Icons.storage_rounded,
|
||||
color: serversProvider.selectedServer != null && serversProvider.selectedServer?.id == server.id
|
||||
? serversProvider.serverStatus.data != null
|
||||
? statusProvider.serverStatus != null
|
||||
? Colors.green
|
||||
: Colors.orange
|
||||
: null,
|
||||
|
@ -344,7 +351,7 @@ class _ServersListItemState extends State<ServersListItem> with SingleTickerProv
|
|||
margin: const EdgeInsets.only(right: 12),
|
||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: serversProvider.serverStatus.data != null
|
||||
color: statusProvider.serverStatus != null
|
||||
? Colors.green
|
||||
: Colors.orange,
|
||||
borderRadius: BorderRadius.circular(30)
|
||||
|
@ -352,14 +359,14 @@ class _ServersListItemState extends State<ServersListItem> with SingleTickerProv
|
|||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
serversProvider.serverStatus.data != null
|
||||
statusProvider.serverStatus != null
|
||||
? Icons.check
|
||||
: Icons.warning,
|
||||
color: Colors.white,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
serversProvider.serverStatus.data != null
|
||||
statusProvider.serverStatus != null
|
||||
? AppLocalizations.of(context)!.connected
|
||||
: AppLocalizations.of(context)!.selectedDisconnected,
|
||||
style: const TextStyle(
|
||||
|
|
|
@ -10,6 +10,8 @@ import 'package:adguard_home_manager/widgets/servers_list/delete_modal.dart';
|
|||
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||
import 'package:adguard_home_manager/constants/enums.dart';
|
||||
import 'package:adguard_home_manager/providers/status_provider.dart';
|
||||
import 'package:adguard_home_manager/models/app_log.dart';
|
||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
|
@ -36,6 +38,7 @@ class _ServersTileItemState extends State<ServersTileItem> with SingleTickerProv
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final statusProvider = Provider.of<StatusProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
@ -99,18 +102,22 @@ class _ServersTileItemState extends State<ServersTileItem> with SingleTickerProv
|
|||
: await login(server);
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
final ApiClient apiClient = ApiClient(server: server);
|
||||
serversProvider.setApiClient(apiClient);
|
||||
serversProvider.setSelectedServer(server);
|
||||
|
||||
serversProvider.setServerStatusLoad(0);
|
||||
final serverStatus = await getServerStatus(server);
|
||||
statusProvider.setServerStatusLoad(LoadStatus.loading);
|
||||
final serverStatus = await apiClient.getServerStatus();
|
||||
if (serverStatus['result'] == 'success') {
|
||||
serversProvider.setServerStatusData(serverStatus['data']);
|
||||
statusProvider.setServerStatusData(
|
||||
data: serverStatus['data']
|
||||
);
|
||||
serversProvider.checkServerUpdatesAvailable(server);
|
||||
serversProvider.setServerStatusLoad(1);
|
||||
statusProvider.setServerStatusLoad(LoadStatus.loaded);
|
||||
}
|
||||
else {
|
||||
appConfigProvider.addLog(serverStatus['log']);
|
||||
serversProvider.setServerStatusLoad(2);
|
||||
statusProvider.setServerStatusLoad(LoadStatus.error);
|
||||
}
|
||||
|
||||
process.close();
|
||||
|
@ -159,7 +166,7 @@ class _ServersTileItemState extends State<ServersTileItem> with SingleTickerProv
|
|||
Icon(
|
||||
Icons.storage_rounded,
|
||||
color: serversProvider.selectedServer != null && serversProvider.selectedServer?.id == server.id
|
||||
? serversProvider.serverStatus.data != null
|
||||
? statusProvider.serverStatus != null
|
||||
? Colors.green
|
||||
: Colors.orange
|
||||
: null,
|
||||
|
@ -192,7 +199,7 @@ class _ServersTileItemState extends State<ServersTileItem> with SingleTickerProv
|
|||
return Icon(
|
||||
Icons.storage_rounded,
|
||||
color: serversProvider.selectedServer != null && serversProvider.selectedServer?.id == server.id
|
||||
? serversProvider.serverStatus.data != null
|
||||
? statusProvider.serverStatus != null
|
||||
? Colors.green
|
||||
: Colors.orange
|
||||
: null,
|
||||
|
@ -305,13 +312,13 @@ class _ServersTileItemState extends State<ServersTileItem> with SingleTickerProv
|
|||
),
|
||||
SizedBox(
|
||||
child: serversProvider.selectedServer != null &&
|
||||
serversProvider.selectedServer != null && serversProvider.selectedServer?.id == server.id && serversProvider.serverStatus.data != null &&
|
||||
serversProvider.selectedServer != null && serversProvider.selectedServer?.id == server.id && statusProvider.serverStatus != null &&
|
||||
serversProvider.selectedServer?.id == server.id
|
||||
? Container(
|
||||
margin: const EdgeInsets.only(right: 12),
|
||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: serversProvider.selectedServer != null && serversProvider.selectedServer?.id == server.id && serversProvider.serverStatus.data != null
|
||||
color: serversProvider.selectedServer != null && serversProvider.selectedServer?.id == server.id && statusProvider.serverStatus != null
|
||||
? Colors.green
|
||||
: Colors.orange,
|
||||
borderRadius: BorderRadius.circular(30)
|
||||
|
@ -319,14 +326,14 @@ class _ServersTileItemState extends State<ServersTileItem> with SingleTickerProv
|
|||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
serversProvider.selectedServer != null && serversProvider.selectedServer?.id == server.id && serversProvider.serverStatus.data != null
|
||||
serversProvider.selectedServer != null && serversProvider.selectedServer?.id == server.id && statusProvider.serverStatus != null
|
||||
? Icons.check
|
||||
: Icons.warning,
|
||||
color: Colors.white,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
serversProvider.selectedServer != null && serversProvider.selectedServer?.id == server.id && serversProvider.serverStatus.data != null
|
||||
serversProvider.selectedServer != null && serversProvider.selectedServer?.id == server.id && statusProvider.serverStatus != null
|
||||
? AppLocalizations.of(context)!.connected
|
||||
: AppLocalizations.of(context)!.selectedDisconnected,
|
||||
style: const TextStyle(
|
||||
|
|
|
@ -60,7 +60,7 @@ class _UpdateModalState extends State<UpdateModal> {
|
|||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"${AppLocalizations.of(context)!.newVersion}: ${widget.gitHubRelease.tagName}",
|
||||
"${AppLocalizations.of(context)!.newVersion}: ${widget.gitHubRelease.name.replaceAll('v', '')}",
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant
|
||||
),
|
||||
|
@ -101,7 +101,9 @@ class _UpdateModalState extends State<UpdateModal> {
|
|||
),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisAlignment: downloadLink != null
|
||||
? MainAxisAlignment.spaceBetween
|
||||
: MainAxisAlignment.end,
|
||||
children: [
|
||||
if (downloadLink != null) TextButton(
|
||||
onPressed: () {
|
||||
|
|
|
@ -421,7 +421,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 61;
|
||||
CURRENT_PROJECT_VERSION = 63;
|
||||
DEVELOPMENT_TEAM = 38Z3B9TJTR;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "AdGuard Home Manager";
|
||||
|
@ -429,7 +429,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.3.2;
|
||||
MARKETING_VERSION = 2.4.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.jgeek00.adguard-home-manager";
|
||||
PRODUCT_COPYRIGHT = "Copyright © 2023 JGeek00. All rights reserved.";
|
||||
PRODUCT_NAME = "AdGuard Home Manager";
|
||||
|
@ -554,7 +554,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 61;
|
||||
CURRENT_PROJECT_VERSION = 63;
|
||||
DEVELOPMENT_TEAM = 38Z3B9TJTR;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "AdGuard Home Manager";
|
||||
|
@ -562,7 +562,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.3.2;
|
||||
MARKETING_VERSION = 2.4.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.jgeek00.adguard-home-manager";
|
||||
PRODUCT_COPYRIGHT = "Copyright © 2023 JGeek00. All rights reserved.";
|
||||
PRODUCT_NAME = "AdGuard Home Manager";
|
||||
|
@ -581,7 +581,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 61;
|
||||
CURRENT_PROJECT_VERSION = 63;
|
||||
DEVELOPMENT_TEAM = 38Z3B9TJTR;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "AdGuard Home Manager";
|
||||
|
@ -589,7 +589,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.3.2;
|
||||
MARKETING_VERSION = 2.4.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.jgeek00.adguard-home-manager";
|
||||
PRODUCT_COPYRIGHT = "Copyright © 2023 JGeek00. All rights reserved.";
|
||||
PRODUCT_NAME = "AdGuard Home Manager";
|
||||
|
|
Loading…
Add table
Reference in a new issue