mirror of
				https://github.com/inventree/inventree-app.git
				synced 2025-10-30 21:05:42 +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:
		| @@ -9,6 +9,7 @@ | |||||||
| - Indicate available quantity in stock detail view | - Indicate available quantity in stock detail view | ||||||
| - Adds configurable filtering to various list views | - Adds configurable filtering to various list views | ||||||
| - Allow stock location to be "scanned" into another location using barcode | - Allow stock location to be "scanned" into another location using barcode | ||||||
|  | - Improves server connection status indicator on home screen | ||||||
|  |  | ||||||
| ### 0.7.3 - June 2022 | ### 0.7.3 - June 2022 | ||||||
| --- | --- | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								lib/api.dart
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								lib/api.dart
									
									
									
									
									
								
							| @@ -135,6 +135,9 @@ class InvenTreeFileService extends FileService { | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * API class which manages all communication with the InvenTree server | ||||||
|  |  */ | ||||||
| class InvenTreeAPI { | class InvenTreeAPI { | ||||||
|  |  | ||||||
|   factory InvenTreeAPI() { |   factory InvenTreeAPI() { | ||||||
| @@ -143,6 +146,19 @@ class InvenTreeAPI { | |||||||
|  |  | ||||||
|   InvenTreeAPI._internal(); |   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 |   // Minimum required API version for server | ||||||
|   static const _minApiVersion = 20; |   static const _minApiVersion = 20; | ||||||
|  |  | ||||||
| @@ -202,6 +218,10 @@ class InvenTreeAPI { | |||||||
|   // Authentication token (initially empty, must be requested) |   // Authentication token (initially empty, must be requested) | ||||||
|   String _token = ""; |   String _token = ""; | ||||||
|  |  | ||||||
|  |   String? get serverAddress { | ||||||
|  |     return profile?.server; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   bool get hasToken => _token.isNotEmpty; |   bool get hasToken => _token.isNotEmpty; | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
| @@ -457,6 +477,8 @@ class InvenTreeAPI { | |||||||
|     // Clear received settings |     // Clear received settings | ||||||
|     _globalSettings.clear(); |     _globalSettings.clear(); | ||||||
|     _userSettings.clear(); |     _userSettings.clear(); | ||||||
|  |  | ||||||
|  |     _connectionStatusChanged(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
| @@ -481,6 +503,8 @@ class InvenTreeAPI { | |||||||
|  |  | ||||||
|     _connecting = true; |     _connecting = true; | ||||||
|  |  | ||||||
|  |     _connectionStatusChanged(); | ||||||
|  |  | ||||||
|     _connected = await _connect(); |     _connected = await _connect(); | ||||||
|  |  | ||||||
|     _connecting = false; |     _connecting = false; | ||||||
| @@ -493,6 +517,8 @@ class InvenTreeAPI { | |||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     _connectionStatusChanged(); | ||||||
|  |  | ||||||
|     return _connected; |     return _connected; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -908,6 +908,9 @@ | |||||||
|   "serverNotConnected": "Server not connected", |   "serverNotConnected": "Server not connected", | ||||||
|   "@serverNotConnected": {}, |   "@serverNotConnected": {}, | ||||||
|  |  | ||||||
|  |   "serverNotSelected": "Server not selected", | ||||||
|  |   "@serverNotSelected": {}, | ||||||
|  |  | ||||||
|   "sounds": "Sounds", |   "sounds": "Sounds", | ||||||
|   "@sounds": {}, |   "@sounds": {}, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -29,6 +29,10 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> { | |||||||
|  |  | ||||||
|     profiles = await UserProfileDBManager().getAllProfiles(); |     profiles = await UserProfileDBManager().getAllProfiles(); | ||||||
|  |  | ||||||
|  |     if (!mounted) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     setState(() { |     setState(() { | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| @@ -58,6 +62,10 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> { | |||||||
|  |  | ||||||
|     await UserProfileDBManager().selectProfile(key); |     await UserProfileDBManager().selectProfile(key); | ||||||
|  |  | ||||||
|  |     if (!mounted) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     _reload(); |     _reload(); | ||||||
|  |  | ||||||
|     // Attempt server login (this will load the newly selected profile |     // Attempt server login (this will load the newly selected profile | ||||||
| @@ -72,6 +80,10 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> { | |||||||
|  |  | ||||||
|     await UserProfileDBManager().deleteProfile(profile); |     await UserProfileDBManager().deleteProfile(profile); | ||||||
|  |  | ||||||
|  |     if (!mounted) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     _reload(); |     _reload(); | ||||||
|  |  | ||||||
|     if (InvenTreeAPI().isConnected() && profile.key == (InvenTreeAPI().profile?.key ?? "")) { |     if (InvenTreeAPI().isConnected() && profile.key == (InvenTreeAPI().profile?.key ?? "")) { | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ import "package:inventree/widget/part_list.dart"; | |||||||
| import "package:inventree/widget/purchase_order_list.dart"; | import "package:inventree/widget/purchase_order_list.dart"; | ||||||
| import "package:inventree/widget/search.dart"; | import "package:inventree/widget/search.dart"; | ||||||
| import "package:inventree/widget/snacks.dart"; | import "package:inventree/widget/snacks.dart"; | ||||||
|  | import "package:inventree/widget/spinner.dart"; | ||||||
|  |  | ||||||
|  |  | ||||||
| class InvenTreeHomePage extends StatefulWidget { | class InvenTreeHomePage extends StatefulWidget { | ||||||
| @@ -51,6 +52,13 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> { | |||||||
|         ), (timer) { |         ), (timer) { | ||||||
|       _refreshNotifications(); |       _refreshNotifications(); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     InvenTreeAPI().registerCallback(() { | ||||||
|  |       setState(() { | ||||||
|  |         // Reload the widget | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Index of bottom navigation bar |   // Index of bottom navigation bar | ||||||
| @@ -352,6 +360,24 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> { | |||||||
|    * display a connection status widget |    * display a connection status widget | ||||||
|    */ |    */ | ||||||
|   Widget _connectionStatusWidget(BuildContext context) { |   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( |     return Center( | ||||||
|       child: Column( |       child: Column( | ||||||
|         children: [ |         children: [ | ||||||
| @@ -363,10 +389,10 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> { | |||||||
|           ), |           ), | ||||||
|           Spacer(), |           Spacer(), | ||||||
|           ListTile( |           ListTile( | ||||||
|             title: Text(L10().serverNotConnected), |             title: Text(title), | ||||||
|             subtitle: Text(L10().profileSelectOrCreate), |             subtitle: Text(subtitle), | ||||||
|             trailing: FaIcon(FontAwesomeIcons.server, color: COLOR_CLICK), |             trailing: trailing, | ||||||
|             leading: FaIcon(FontAwesomeIcons.exclamationCircle, color: COLOR_DANGER), |             leading: leading, | ||||||
|             onTap: _selectProfile, |             onTap: _selectProfile, | ||||||
|           ) |           ) | ||||||
|         ] |         ] | ||||||
| @@ -456,6 +482,7 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> { | |||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|  |  | ||||||
|     var connected = InvenTreeAPI().isConnected(); |     var connected = InvenTreeAPI().isConnected(); | ||||||
|  |     var connecting = !connected && InvenTreeAPI().isConnecting(); | ||||||
|  |  | ||||||
|     return Scaffold( |     return Scaffold( | ||||||
|       key: _homeKey, |       key: _homeKey, | ||||||
| @@ -465,7 +492,7 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> { | |||||||
|           IconButton( |           IconButton( | ||||||
|             icon: FaIcon( |             icon: FaIcon( | ||||||
|               FontAwesomeIcons.server, |               FontAwesomeIcons.server, | ||||||
|               color: connected ? COLOR_SUCCESS : COLOR_DANGER, |               color: connected ? COLOR_SUCCESS : (connecting ? COLOR_PROGRESS: COLOR_DANGER), | ||||||
|             ), |             ), | ||||||
|             onPressed: _selectProfile, |             onPressed: _selectProfile, | ||||||
|           ) |           ) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user