diff --git a/lib/api.dart b/lib/api.dart index e3b7d16e..8f75df30 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -410,7 +410,7 @@ class InvenTreeAPI { * 5. Request information on available plugins */ Future _connectToServer() async { - if (!await _checkServer()) { + if (!await checkServer()) { return false; } @@ -450,8 +450,8 @@ class InvenTreeAPI { * Check that the remote server is available. * Ping the api/ endpoint, which does not require user authentication */ - Future _checkServer() async { - String address = profile?.server ?? ""; + Future checkServer({String? server}) async { + String address = server ?? profile?.server ?? ""; if (address.isEmpty) { showSnackIcon( @@ -462,8 +462,10 @@ class InvenTreeAPI { return false; } - if (!address.endsWith("/")) { - address = address + "/"; + String url = _makeUrl("/api/", base: address); + + if (!url.endsWith("/")) { + url = url + "/"; } // Cache the "strictHttps" setting, so we can use it later without async requirement @@ -473,7 +475,7 @@ class InvenTreeAPI { debug("Connecting to ${apiUrl}"); - APIResponse response = await get("", expectedStatusCode: 200); + APIResponse response = await get(url, expectedStatusCode: 200); if (!response.successful()) { debug("Server returned invalid response: ${response.statusCode}"); diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index cd5faadc..73a37ceb 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -294,6 +294,9 @@ "confirmScanDetail": "Confirm stock transfer details when scanning barcodes", "@confirmScanDetail": {}, + "connectionCheck": "Check Connection", + "@connectionCheck": {}, + "connectionRefused": "Connection Refused", "@connectionRefused": {}, diff --git a/lib/settings/select_server.dart b/lib/settings/select_server.dart index bfeae981..1d378556 100644 --- a/lib/settings/select_server.dart +++ b/lib/settings/select_server.dart @@ -298,6 +298,9 @@ class _ProfileEditState extends State { String name = ""; String server = ""; + bool? serverStatus; + bool serverChecking = false; + @override Widget build(BuildContext context) { return Scaffold( @@ -411,6 +414,49 @@ class _ProfileEditState extends State { return null; }, ), + Divider(), + SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + label: Text(L10().connectionCheck), + icon: serverStatus == true + ? Icon(TablerIcons.circle_check, color: COLOR_SUCCESS) + : serverStatus == false + ? Icon(TablerIcons.circle_x, color: COLOR_DANGER) + : Icon(TablerIcons.question_mark, color: COLOR_WARNING), + onPressed: serverChecking + ? null + : () async { + if (serverChecking) { + return; + } + + if (!formKey.currentState!.validate()) { + return; + } + + if (mounted) { + setState(() { + serverStatus = null; + serverChecking = true; + }); + } + + formKey.currentState!.save(); + + InvenTreeAPI().checkServer(server: server).then(( + result, + ) { + if (mounted) { + setState(() { + serverStatus = result; + serverChecking = false; + }); + } + }); + }, + ), + ), ], ), padding: EdgeInsets.all(16),