Added unsupported version warning and handle alpha versions

This commit is contained in:
Juan Gilsanz Polo 2023-05-13 18:33:09 +02:00
parent 3e281095cd
commit 3f0997f5d6
11 changed files with 234 additions and 72 deletions

View file

@ -5,44 +5,18 @@ bool compareVersions({
required String newVersion required String newVersion
}) { }) {
try { try {
final currentSplit = currentVersion.split('.').map((e) => int.parse(e)).toList(); if (currentVersion.contains('a')) { // alpha
final newSplit = newVersion.split('.').map((e) => int.parse(e)).toList();
if (newSplit[0] > currentSplit[0]) {
return true; return true;
} }
else if (newSplit[1] > currentSplit[1]) { else if (currentVersion.contains('b')) { // beta
return true; final current = currentVersion.replaceAll('v', '');
} final newV = currentVersion.replaceAll('v', '');
else if (newSplit[2] > currentSplit[2]) {
return true;
}
else {
return false;
}
} catch (e) {
Sentry.captureException(e);
Sentry.captureMessage("compareVersions error", params: [
{
"fn": "compareVersions",
"currentVersion": currentVersion,
"newVersion": newVersion,
}.toString()
]);
return false;
}
}
bool compareBetaVersions({ final currentSplit = current.split('-')[0].split('.').map((e) => int.parse(e)).toList();
required String currentVersion, final newSplit = newV.split('-')[0].split('.').map((e) => int.parse(e)).toList();
required String newVersion
}) {
try {
final currentSplit = currentVersion.split('-')[0].split('.').map((e) => int.parse(e)).toList();
final newSplit = newVersion.split('-')[0].split('.').map((e) => int.parse(e)).toList();
final currentBeta = int.parse(currentVersion.split('-')[1].replaceAll('b.', '')); final currentBeta = int.parse(current.split('-')[1].replaceAll('b.', ''));
final newBeta = int.parse(newVersion.split('-')[1].replaceAll('b.', '')); final newBeta = int.parse(newV.split('-')[1].replaceAll('b.', ''));
if (newSplit[0] > currentSplit[0]) { if (newSplit[0] > currentSplit[0]) {
return true; return true;
@ -59,11 +33,32 @@ bool compareBetaVersions({
else { else {
return false; return false;
} }
}
else { // stable
final current = currentVersion.replaceAll('v', '');
final newV = currentVersion.replaceAll('v', '');
final currentSplit = current.split('.').map((e) => int.parse(e)).toList();
final newSplit = newV.split('.').map((e) => int.parse(e)).toList();
if (newSplit[0] > currentSplit[0]) {
return true;
}
else if (newSplit[1] > currentSplit[1]) {
return true;
}
else if (newSplit[2] > currentSplit[2]) {
return true;
}
else {
return false;
}
}
} catch (e) { } catch (e) {
Sentry.captureException(e); Sentry.captureException(e);
Sentry.captureMessage("compareBetaVersions error", params: [ Sentry.captureMessage("compareVersions error", params: [
{ {
"fn": "compareBetaVersions", "fn": "compareVersions",
"currentVersion": currentVersion, "currentVersion": currentVersion,
"newVersion": newVersion, "newVersion": newVersion,
}.toString() }.toString()
@ -82,7 +77,10 @@ bool serverVersionIsAhead({
final reference = referenceVersion.replaceAll('v', ''); final reference = referenceVersion.replaceAll('v', '');
final referenceBeta = referenceVersionBeta?.replaceAll('v', ''); final referenceBeta = referenceVersionBeta?.replaceAll('v', '');
if (current.contains('b')) { if (currentVersion.contains('a')) { // alpha
return true;
}
else if (current.contains('b')) { // beta
if (referenceBeta != null) { if (referenceBeta != null) {
final currentSplit = current.split('-')[0].split('.').map((e) => int.parse(e)).toList(); final currentSplit = current.split('-')[0].split('.').map((e) => int.parse(e)).toList();
final newSplit = referenceBeta.split('-')[0].split('.').map((e) => int.parse(e)).toList(); final newSplit = referenceBeta.split('-')[0].split('.').map((e) => int.parse(e)).toList();
@ -113,7 +111,7 @@ bool serverVersionIsAhead({
return false; return false;
} }
} }
else { else { // stable
final currentSplit = current.split('.').map((e) => int.parse(e)).toList(); final currentSplit = current.split('.').map((e) => int.parse(e)).toList();
final newSplit = reference.split('.').map((e) => int.parse(e)).toList(); final newSplit = reference.split('.').map((e) => int.parse(e)).toList();

View file

@ -617,5 +617,8 @@
"seeDetails": "See details", "seeDetails": "See details",
"listNotAvailable": "List not available", "listNotAvailable": "List not available",
"copyListUrl": "Copy list URL", "copyListUrl": "Copy list URL",
"listUrlCopied": "List URL copied to the clipboard" "listUrlCopied": "List URL copied to the clipboard",
"unsupportedVersion": "Unsupported version",
"unsupprtedVersionMessage": "The support for your server version {version} is not guaranteed. This application may have some issues working with that server version.\n\nAdGuard Home Manager is designed to work with the stable releases of the AdGuard Home server. It may work with alpha and beta releases, but the compatibility is not guaranteed and the app may have some issues working with that versions.",
"iUnderstand": "I understand"
} }

View file

@ -617,5 +617,8 @@
"seeDetails": "Ver los detalles", "seeDetails": "Ver los detalles",
"listNotAvailable": "Lista no disponible", "listNotAvailable": "Lista no disponible",
"copyListUrl": "Copiar URL de lista", "copyListUrl": "Copiar URL de lista",
"listUrlCopied": "URL de la lista copiada al portapapeles" "listUrlCopied": "URL de la lista copiada al portapapeles",
"unsupportedVersion": "Versión no soportada",
"unsupprtedVersionMessage": "El soporte para la versión del servidor {version} no está garantizada. Esta aplicación puede tener problemas al trabajar con esa versión del servidor.\n\nAdGuard Home Manager está diseñado para trabajar con las versiones estables del servidor AdGuard Home. Puede funcionar con versiones alpha y beta, pero la compatibilidad no está asegurada y la aplicación puede tener problemas para trabajar con esas versiones.",
"iUnderstand": "Lo entiendo"
} }

View file

@ -535,14 +535,9 @@ class ServersProvider with ChangeNotifier {
data.changelog = gitHubResult['body']; data.changelog = gitHubResult['body'];
} }
data.updateAvailable = data.newVersion != null data.updateAvailable = data.newVersion != null
? data.newVersion!.contains('b') ? compareVersions(
? compareBetaVersions( currentVersion: data.currentVersion,
currentVersion: data.currentVersion.replaceAll('v', ''), newVersion: data.newVersion!,
newVersion: data.newVersion!.replaceAll('v', ''),
)
: compareVersions(
currentVersion: data.currentVersion.replaceAll('v', ''),
newVersion: data.newVersion!.replaceAll('v', ''),
) )
: false; : false;
setUpdateAvailableData(data); setUpdateAvailableData(data);

View file

@ -1,6 +1,8 @@
import 'package:adguard_home_manager/widgets/add_server_modal.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:adguard_home_manager/widgets/add_server_modal.dart';
import 'package:adguard_home_manager/widgets/version_warning_modal.dart';
class FabConnect extends StatelessWidget { class FabConnect extends StatelessWidget {
const FabConnect({Key? key}) : super(key: key); const FabConnect({Key? key}) : super(key: key);
@ -14,16 +16,30 @@ class FabConnect extends StatelessWidget {
showDialog( showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
builder: (context) => const AddServerModal( builder: (context) => AddServerModal(
window: true, window: true,
onUnsupportedVersion: (version) => showDialog(
context: context,
builder: (ctx) => VersionWarningModal(
version: version
),
barrierDismissible: false
),
), ),
) )
} }
else { else {
Navigator.push(context, MaterialPageRoute( Navigator.push(context, MaterialPageRoute(
fullscreenDialog: true, fullscreenDialog: true,
builder: (BuildContext context) => const AddServerModal( builder: (BuildContext context) => AddServerModal(
window: false, window: false,
onUnsupportedVersion: (version) => showDialog(
context: context,
builder: (ctx) => VersionWarningModal(
version: version
),
barrierDismissible: false
),
) )
)) ))
} }

View file

@ -6,6 +6,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:adguard_home_manager/widgets/version_warning_modal.dart';
import 'package:adguard_home_manager/widgets/servers_list/servers_list.dart'; import 'package:adguard_home_manager/widgets/servers_list/servers_list.dart';
import 'package:adguard_home_manager/widgets/add_server_modal.dart'; import 'package:adguard_home_manager/widgets/add_server_modal.dart';
@ -72,16 +73,30 @@ class _ServersState extends State<Servers> {
showDialog( showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
builder: (context) => const AddServerModal( builder: (context) => AddServerModal(
window: true, window: true,
onUnsupportedVersion: (version) => showDialog(
context: context,
builder: (ctx) => VersionWarningModal(
version: version
),
barrierDismissible: false
),
), ),
) )
} }
else { else {
Navigator.push(context, MaterialPageRoute( Navigator.push(context, MaterialPageRoute(
fullscreenDialog: true, fullscreenDialog: true,
builder: (BuildContext context) => const AddServerModal( builder: (BuildContext context) => AddServerModal(
window: false, window: false,
onUnsupportedVersion: (version) => showDialog(
context: context,
builder: (ctx) => VersionWarningModal(
version: version
),
barrierDismissible: false
),
) )
)) ))
} }

View file

@ -263,6 +263,40 @@ Future loginHA(Server server) async {
} }
} }
Future getServerVersion(Server server) async {
final result = await apiRequest(
server: server,
method: 'get',
urlPath: '/status',
type: 'get_server_version'
);
if (result['hasResponse'] == true) {
if (result['statusCode'] == 200 && result['body'] != null) {
print( result['body']['version']);
return {
'result': 'success',
'data': result['body']['version']
};
}
else {
return {
'result': 'error',
'log': AppLog(
type: 'get_server_version',
dateTime: DateTime.now(),
message: 'error_code_not_expected',
statusCode: result['statusCode'].toString(),
resBody: result['body']
)
};
}
}
else {
return result;
}
}
Future getServerStatus(Server server) async { Future getServerStatus(Server server) async {
final result = await Future.wait([ final result = await Future.wait([
apiRequest(server: server, method: 'get', urlPath: '/stats', type: 'server_status'), apiRequest(server: server, method: 'get', urlPath: '/stats', type: 'server_status'),

View file

@ -18,11 +18,13 @@ enum ConnectionType { http, https}
class AddServerModal extends StatefulWidget { class AddServerModal extends StatefulWidget {
final Server? server; final Server? server;
final bool window; final bool window;
final void Function(String version) onUnsupportedVersion;
const AddServerModal({ const AddServerModal({
Key? key, Key? key,
this.server, this.server,
required this.window required this.window,
required this.onUnsupportedVersion
}) : super(key: key); }) : super(key: key);
@override @override
@ -256,17 +258,26 @@ class _AddServerModalState extends State<AddServerModal> {
final serverCreated = await serversProvider.createServer(serverObj); final serverCreated = await serversProvider.createServer(serverObj);
if (serverCreated == null) { if (serverCreated == null) {
serversProvider.setServerStatusLoad(0); serversProvider.setServerStatusLoad(0);
final serverStatus = await getServerStatus(serverObj); final serverStatus = await getServerStatus(serverObj);
if (serverStatus['result'] == 'success') { if (serverStatus['result'] == 'success') {
serversProvider.setServerStatusData(serverStatus['data']); serversProvider.setServerStatusData(serverStatus['data']);
serversProvider.setServerStatusLoad(1); serversProvider.setServerStatusLoad(1);
if (serverStatus['data'].serverVersion.contains('a') || serverStatus['data'].serverVersion.contains('b')) {
Navigator.pop(context);
widget.onUnsupportedVersion(serverStatus['data'].serverVersion);
}
else {
Navigator.pop(context);
}
} }
else { else {
appConfigProvider.addLog(serverStatus['log']); appConfigProvider.addLog(serverStatus['log']);
serversProvider.setServerStatusLoad(2); serversProvider.setServerStatusLoad(2);
}
Navigator.pop(context); Navigator.pop(context);
} }
}
else { else {
setState(() => isConnecting = false); setState(() => isConnecting = false);
appConfigProvider.addLog( appConfigProvider.addLog(
@ -364,8 +375,19 @@ class _AddServerModalState extends State<AddServerModal> {
serverObj.authToken = encodeBase64UserPass(serverObj.user!, serverObj.password!); serverObj.authToken = encodeBase64UserPass(serverObj.user!, serverObj.password!);
} }
final serverSaved = await serversProvider.editServer(serverObj); final serverSaved = await serversProvider.editServer(serverObj);
if (serverSaved == null) { if (serverSaved == null) {
final version = await getServerVersion(serverObj);;
if (
version['result'] == 'success' &&
(version['data'].contains('a') || version['data'].contains('b')) // alpha or beta
) {
Navigator.pop(context); Navigator.pop(context);
widget.onUnsupportedVersion(version);
}
else {
Navigator.pop(context);
}
} }
else { else {
appConfigProvider.addLog( appConfigProvider.addLog(

View file

@ -5,6 +5,7 @@ import 'package:expandable/expandable.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:adguard_home_manager/widgets/version_warning_modal.dart';
import 'package:adguard_home_manager/widgets/add_server_modal.dart'; import 'package:adguard_home_manager/widgets/add_server_modal.dart';
import 'package:adguard_home_manager/widgets/servers_list/delete_modal.dart'; import 'package:adguard_home_manager/widgets/servers_list/delete_modal.dart';
@ -93,6 +94,13 @@ class _ServersListItemState extends State<ServersListItem> with SingleTickerProv
builder: (context) => AddServerModal( builder: (context) => AddServerModal(
server: server, server: server,
window: true, window: true,
onUnsupportedVersion: (version) => showDialog(
context: context,
builder: (ctx) => VersionWarningModal(
version: version
),
barrierDismissible: false
),
), ),
) )
} }
@ -102,6 +110,13 @@ class _ServersListItemState extends State<ServersListItem> with SingleTickerProv
builder: (BuildContext context) => AddServerModal( builder: (BuildContext context) => AddServerModal(
server: server, server: server,
window: false, window: false,
onUnsupportedVersion: (version) => showDialog(
context: context,
builder: (ctx) => VersionWarningModal(
version: version
),
barrierDismissible: false
),
) )
)) ))
} }

View file

@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:adguard_home_manager/widgets/version_warning_modal.dart';
import 'package:adguard_home_manager/widgets/add_server_modal.dart'; import 'package:adguard_home_manager/widgets/add_server_modal.dart';
import 'package:adguard_home_manager/widgets/servers_list/delete_modal.dart'; import 'package:adguard_home_manager/widgets/servers_list/delete_modal.dart';
@ -60,6 +61,13 @@ class _ServersTileItemState extends State<ServersTileItem> with SingleTickerProv
builder: (context) => AddServerModal( builder: (context) => AddServerModal(
server: server, server: server,
window: true, window: true,
onUnsupportedVersion: (version) => showDialog(
context: context,
builder: (ctx) => VersionWarningModal(
version: version
),
barrierDismissible: false
),
), ),
) )
} }
@ -69,6 +77,13 @@ class _ServersTileItemState extends State<ServersTileItem> with SingleTickerProv
builder: (BuildContext context) => AddServerModal( builder: (BuildContext context) => AddServerModal(
server: server, server: server,
window: false, window: false,
onUnsupportedVersion: (version) => showDialog(
context: context,
builder: (ctx) => VersionWarningModal(
version: version
),
barrierDismissible: false
),
) )
)) ))
} }

View file

@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class VersionWarningModal extends StatelessWidget {
final String version;
const VersionWarningModal({
Key? key,
required this.version,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return AlertDialog(
scrollable: true,
title: Column(
children: [
Icon(
Icons.warning_rounded,
size: 24,
color: Theme.of(context).listTileTheme.iconColor
),
const SizedBox(height: 16),
Text(
AppLocalizations.of(context)!.unsupportedVersion,
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface
),
)
],
),
content: Text(AppLocalizations.of(context)!.unsupprtedVersionMessage(version)),
actions: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text(AppLocalizations.of(context)!.iUnderstand)
)
],
)
],
);
}
}