2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-04-28 05:26:47 +00:00

Main screen loading indicator (#183)

* Bug fix for login screen

- Prevent setState() from being called if the widget is no longer loaded

* Add callback function when API status changes

- Home screen uses this function to update connection status indicator

* Linting fixes
This commit is contained in:
Oliver 2022-07-19 23:10:06 +10:00 committed by GitHub
parent 7f3dfe7dd7
commit e03a8561b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 5 deletions

View File

@ -9,6 +9,7 @@
- Indicate available quantity in stock detail view
- Adds configurable filtering to various list views
- Allow stock location to be "scanned" into another location using barcode
- Improves server connection status indicator on home screen
### 0.7.3 - June 2022
---

View File

@ -135,6 +135,9 @@ class InvenTreeFileService extends FileService {
*/
/*
* API class which manages all communication with the InvenTree server
*/
class InvenTreeAPI {
factory InvenTreeAPI() {
@ -143,6 +146,19 @@ class InvenTreeAPI {
InvenTreeAPI._internal();
// List of callback functions to trigger when the connection status changes
List<Function()> _statusCallbacks = [];
// Register a callback function to be notified when the connection status changes
void registerCallback(Function() func) => _statusCallbacks.add(func);
void _connectionStatusChanged() {
for (Function() func in _statusCallbacks) {
// Call the function
func();
}
}
// Minimum required API version for server
static const _minApiVersion = 20;
@ -202,6 +218,10 @@ class InvenTreeAPI {
// Authentication token (initially empty, must be requested)
String _token = "";
String? get serverAddress {
return profile?.server;
}
bool get hasToken => _token.isNotEmpty;
/*
@ -457,6 +477,8 @@ class InvenTreeAPI {
// Clear received settings
_globalSettings.clear();
_userSettings.clear();
_connectionStatusChanged();
}
/*
@ -481,6 +503,8 @@ class InvenTreeAPI {
_connecting = true;
_connectionStatusChanged();
_connected = await _connect();
_connecting = false;
@ -493,6 +517,8 @@ class InvenTreeAPI {
);
}
_connectionStatusChanged();
return _connected;
}

View File

@ -908,6 +908,9 @@
"serverNotConnected": "Server not connected",
"@serverNotConnected": {},
"serverNotSelected": "Server not selected",
"@serverNotSelected": {},
"sounds": "Sounds",
"@sounds": {},

View File

@ -29,6 +29,10 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
profiles = await UserProfileDBManager().getAllProfiles();
if (!mounted) {
return;
}
setState(() {
});
}
@ -58,6 +62,10 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
await UserProfileDBManager().selectProfile(key);
if (!mounted) {
return;
}
_reload();
// Attempt server login (this will load the newly selected profile
@ -72,6 +80,10 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
await UserProfileDBManager().deleteProfile(profile);
if (!mounted) {
return;
}
_reload();
if (InvenTreeAPI().isConnected() && profile.key == (InvenTreeAPI().profile?.key ?? "")) {

View File

@ -23,6 +23,7 @@ import "package:inventree/widget/part_list.dart";
import "package:inventree/widget/purchase_order_list.dart";
import "package:inventree/widget/search.dart";
import "package:inventree/widget/snacks.dart";
import "package:inventree/widget/spinner.dart";
class InvenTreeHomePage extends StatefulWidget {
@ -51,6 +52,13 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
), (timer) {
_refreshNotifications();
});
InvenTreeAPI().registerCallback(() {
setState(() {
// Reload the widget
});
});
}
// Index of bottom navigation bar
@ -352,6 +360,24 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
* display a connection status widget
*/
Widget _connectionStatusWidget(BuildContext context) {
String? serverAddress = InvenTreeAPI().serverAddress;
bool validAddress = serverAddress != null;
bool connecting = !InvenTreeAPI().isConnected() && InvenTreeAPI().isConnecting();
Widget leading = FaIcon(FontAwesomeIcons.exclamationCircle, color: COLOR_DANGER);
Widget trailing = FaIcon(FontAwesomeIcons.server, color: COLOR_CLICK);
String title = L10().serverNotConnected;
String subtitle = L10().profileSelectOrCreate;
if (!validAddress) {
title = L10().serverNotSelected;
} else if (connecting) {
title = L10().serverConnecting;
subtitle = serverAddress;
leading = Spinner(icon: FontAwesomeIcons.spinner, color: COLOR_PROGRESS);
}
return Center(
child: Column(
children: [
@ -363,10 +389,10 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
),
Spacer(),
ListTile(
title: Text(L10().serverNotConnected),
subtitle: Text(L10().profileSelectOrCreate),
trailing: FaIcon(FontAwesomeIcons.server, color: COLOR_CLICK),
leading: FaIcon(FontAwesomeIcons.exclamationCircle, color: COLOR_DANGER),
title: Text(title),
subtitle: Text(subtitle),
trailing: trailing,
leading: leading,
onTap: _selectProfile,
)
]
@ -456,6 +482,7 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
Widget build(BuildContext context) {
var connected = InvenTreeAPI().isConnected();
var connecting = !connected && InvenTreeAPI().isConnecting();
return Scaffold(
key: _homeKey,
@ -465,7 +492,7 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
IconButton(
icon: FaIcon(
FontAwesomeIcons.server,
color: connected ? COLOR_SUCCESS : COLOR_DANGER,
color: connected ? COLOR_SUCCESS : (connecting ? COLOR_PROGRESS: COLOR_DANGER),
),
onPressed: _selectProfile,
)