mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-28 05:26:47 +00:00
Refactor API connection code
This commit is contained in:
parent
1c0b469020
commit
7373805ea7
87
lib/api.dart
87
lib/api.dart
@ -109,13 +109,11 @@ class InvenTreeAPI {
|
||||
|
||||
String makeUrl(String endpoint) => _makeUrl(endpoint);
|
||||
|
||||
UserProfile _profile;
|
||||
UserProfile profile;
|
||||
|
||||
// Authentication token (initially empty, must be requested)
|
||||
String _token = "";
|
||||
|
||||
bool isConnected() => _token.isNotEmpty;
|
||||
|
||||
/*
|
||||
* Check server connection and display messages if not connected.
|
||||
* Useful as a precursor check before performing operations.
|
||||
@ -154,8 +152,14 @@ class InvenTreeAPI {
|
||||
// Connection status flag - set once connection has been validated
|
||||
bool _connected = false;
|
||||
|
||||
bool get connected {
|
||||
return _connected && baseUrl.isNotEmpty && _token.isNotEmpty;
|
||||
bool _connecting = true;
|
||||
|
||||
bool isConnected() {
|
||||
return profile != null && _connected && baseUrl.isNotEmpty && _token.isNotEmpty;
|
||||
}
|
||||
|
||||
bool isConnecting() {
|
||||
return !isConnected() && _connecting;
|
||||
}
|
||||
|
||||
// Ensure we only ever create a single instance of the API class
|
||||
@ -167,35 +171,15 @@ class InvenTreeAPI {
|
||||
|
||||
InvenTreeAPI._internal();
|
||||
|
||||
Future<bool> connect(BuildContext context) async {
|
||||
|
||||
_profile = await UserProfileDBManager().getSelectedProfile();
|
||||
|
||||
if (_profile == null) {
|
||||
await showErrorDialog(
|
||||
context,
|
||||
"Select Profile",
|
||||
"User profile not selected"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return connectToServer(context);
|
||||
}
|
||||
|
||||
Future<bool> connectToServer(BuildContext context) async {
|
||||
Future<bool> _connect(BuildContext context) async {
|
||||
|
||||
/* Address is the base address for the InvenTree server,
|
||||
* e.g. http://127.0.0.1:8000
|
||||
*/
|
||||
|
||||
if (_profile == null) return false;
|
||||
|
||||
String errorMessage = "";
|
||||
|
||||
String address = _profile.server.trim();
|
||||
String username = _profile.username.trim();
|
||||
String password = _profile.password.trim();
|
||||
String address = profile.server.trim();
|
||||
String username = profile.username.trim();
|
||||
String password = profile.password.trim();
|
||||
|
||||
if (address.isEmpty || username.isEmpty || password.isEmpty) {
|
||||
await showErrorDialog(
|
||||
@ -220,19 +204,18 @@ class InvenTreeAPI {
|
||||
*/
|
||||
|
||||
_BASE_URL = address;
|
||||
_connected = false;
|
||||
|
||||
print("Connecting to " + apiUrl + " -> " + username + ":" + password);
|
||||
print("Connecting to ${apiUrl} -> ${username}:${password}");
|
||||
|
||||
var response = await get("").timeout(Duration(seconds: 5)).catchError((error) {
|
||||
|
||||
print("Error connecting to server: ${error.toString()}");
|
||||
|
||||
if (error is SocketException) {
|
||||
errorMessage = "Could not connect to server";
|
||||
showServerError(context, "Connection Refused");
|
||||
return null;
|
||||
} else if (error is TimeoutException) {
|
||||
errorMessage = "Server timeout";
|
||||
showTimeoutDialog(context);
|
||||
return null;
|
||||
} else {
|
||||
// Unknown error type - re-throw the error and Sentry will catch it
|
||||
@ -242,8 +225,6 @@ class InvenTreeAPI {
|
||||
|
||||
if (response == null) {
|
||||
// Null (or error) response: Show dialog and exit
|
||||
|
||||
await showServerError(context, errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -322,6 +303,38 @@ class InvenTreeAPI {
|
||||
};
|
||||
}
|
||||
|
||||
Future<bool> connectToServer(BuildContext context) async {
|
||||
print("InvenTreeAPI().connectToServer()");
|
||||
|
||||
// Clear connection flag
|
||||
_connected = false;
|
||||
|
||||
// Clear token
|
||||
_token = '';
|
||||
|
||||
// Load selected profile
|
||||
profile = await UserProfileDBManager().getSelectedProfile();
|
||||
|
||||
if (profile == null) {
|
||||
await showErrorDialog(
|
||||
context,
|
||||
"Select Profile",
|
||||
"User profile not selected"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
_connecting = true;
|
||||
|
||||
_connect(context).then((result) {
|
||||
|
||||
print("_connect() returned result: ${result}");
|
||||
_connecting = false;
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
// Perform a PATCH request
|
||||
Future<http.Response> patch(String url, {Map<String, String> body}) async {
|
||||
var _url = makeApiUrl(url);
|
||||
@ -405,7 +418,9 @@ class InvenTreeAPI {
|
||||
Map<String, String> defaultHeaders() {
|
||||
var headers = Map<String, String>();
|
||||
|
||||
headers[HttpHeaders.authorizationHeader] = _authorizationHeader(_profile.username, _profile.password);
|
||||
if (profile != null) {
|
||||
headers[HttpHeaders.authorizationHeader] = _authorizationHeader(profile.username, profile.password);
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
||||
_reload();
|
||||
|
||||
// Attempt server login (this will load the newly selected profile
|
||||
InvenTreeAPI().connect(context);
|
||||
InvenTreeAPI().connectToServer(context);
|
||||
}
|
||||
|
||||
void _deleteProfile(UserProfile profile) async {
|
||||
@ -220,7 +220,7 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
||||
|
||||
List<Widget> children = [];
|
||||
|
||||
if (profiles.length > 0) {
|
||||
if (profiles != null && profiles.length > 0) {
|
||||
for (int idx = 0; idx < profiles.length; idx++) {
|
||||
UserProfile profile = profiles[idx];
|
||||
|
||||
|
@ -44,109 +44,7 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
|
||||
// Selected user profile
|
||||
UserProfile _profile;
|
||||
|
||||
void _loadProfile() async {
|
||||
|
||||
final profile = await UserProfileDBManager().getSelectedProfile();
|
||||
|
||||
print("Loaded selected profile");
|
||||
|
||||
// If a different profile is selected, re-connect
|
||||
if (_profile == null || (_profile.key != profile.key)) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
_profile = profile;
|
||||
|
||||
setState(() {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
ListTile _serverTile() {
|
||||
|
||||
// No profile selected
|
||||
// Tap to select / create a profile
|
||||
if (_profile == null) {
|
||||
return ListTile(
|
||||
title: Text("No Profile Selected"),
|
||||
subtitle: Text("Tap to create or select a profile"),
|
||||
leading: FaIcon(FontAwesomeIcons.user),
|
||||
onTap: () {
|
||||
_selectProfile();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Profile is selected ...
|
||||
if (InvenTreeAPI().isConnected()) {
|
||||
return ListTile(
|
||||
title: Text("Connected to ${_profile.server}"),
|
||||
);
|
||||
} else {
|
||||
return ListTile(
|
||||
title: Text("Could not connect to server"),
|
||||
subtitle: Text("Error connecting to ${_profile.server}"),
|
||||
leading: FaIcon(FontAwesomeIcons.times),
|
||||
onTap: () {
|
||||
_selectProfile();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void onConnectSuccess(String msg) async {
|
||||
|
||||
final profile = await UserProfileDBManager().getSelectedProfile();
|
||||
|
||||
String address = profile?.server ?? 'unknown server address';
|
||||
|
||||
_serverConnection = true;
|
||||
_serverMessage = msg;
|
||||
_serverStatus = "Connected to ${address}";
|
||||
_serverStatusColor = Color.fromARGB(255, 50, 250, 50);
|
||||
_serverIcon = new FaIcon(FontAwesomeIcons.checkCircle, color: _serverStatusColor);
|
||||
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
void onConnectFailure(String msg) async {
|
||||
|
||||
final profile = await UserProfileDBManager().getSelectedProfile();
|
||||
|
||||
_serverConnection = false;
|
||||
_serverMessage = msg;
|
||||
_serverStatus = "Could not connect to ${profile?.server}";
|
||||
_serverStatusColor = Color.fromARGB(255, 250, 50, 50);
|
||||
_serverIcon = new FaIcon(FontAwesomeIcons.timesCircle, color: _serverStatusColor);
|
||||
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the server connection
|
||||
*/
|
||||
void _checkServerConnection(BuildContext context) async {
|
||||
|
||||
// Reset the connection status variables
|
||||
_serverStatus = "Connecting to server";
|
||||
_serverMessage = "";
|
||||
_serverConnection = false;
|
||||
_serverIcon = new FaIcon(FontAwesomeIcons.spinner);
|
||||
_serverStatusColor = Color.fromARGB(255, 50, 50, 250);
|
||||
|
||||
InvenTreeAPI().connect(context).then((bool result) {
|
||||
|
||||
if (result) {
|
||||
onConnectSuccess("");
|
||||
} else {
|
||||
onConnectFailure("Could not connect to server");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Update widget state
|
||||
setState(() {});
|
||||
}
|
||||
BuildContext _context;
|
||||
|
||||
void _search() {
|
||||
if (!InvenTreeAPI().checkConnection(context)) return;
|
||||
@ -210,8 +108,130 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void _loadProfile() async {
|
||||
|
||||
final profile = await UserProfileDBManager().getSelectedProfile();
|
||||
|
||||
// If a different profile is selected, re-connect
|
||||
if (_profile == null || (_profile.key != profile.key)) {
|
||||
|
||||
if (_context != null) {
|
||||
print("Connecting Profile: ${profile.name} - ${profile.server}");
|
||||
|
||||
InvenTreeAPI().connectToServer(_context).then((result) {
|
||||
setState(() {
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
setState(() {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_profile = profile;
|
||||
|
||||
setState(() {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
ListTile _serverTile() {
|
||||
|
||||
// No profile selected
|
||||
// Tap to select / create a profile
|
||||
if (_profile == null) {
|
||||
return ListTile(
|
||||
title: Text("No Profile Selected"),
|
||||
subtitle: Text("Tap to create or select a profile"),
|
||||
leading: FaIcon(FontAwesomeIcons.server),
|
||||
trailing: FaIcon(
|
||||
FontAwesomeIcons.user,
|
||||
color: Color.fromRGBO(250, 50, 50, 1),
|
||||
),
|
||||
onTap: () {
|
||||
_selectProfile();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Profile is selected ...
|
||||
if (InvenTreeAPI().isConnecting()) {
|
||||
return ListTile(
|
||||
title: Text("Connecting to server..."),
|
||||
subtitle: Text("${InvenTreeAPI().baseUrl}"),
|
||||
leading: FaIcon(FontAwesomeIcons.server),
|
||||
trailing: FaIcon(
|
||||
FontAwesomeIcons.spinner,
|
||||
color: Color.fromRGBO(50, 50, 250, 1),
|
||||
)
|
||||
);
|
||||
} else if (InvenTreeAPI().isConnected()) {
|
||||
return ListTile(
|
||||
title: Text("Connected to server"),
|
||||
subtitle: Text("${InvenTreeAPI().baseUrl}"),
|
||||
leading: FaIcon(FontAwesomeIcons.server),
|
||||
trailing: FaIcon(
|
||||
FontAwesomeIcons.checkCircle,
|
||||
color: Color.fromRGBO(50, 250, 50, 1)
|
||||
),
|
||||
onTap: () {
|
||||
_selectProfile();
|
||||
},
|
||||
);
|
||||
} else {
|
||||
return ListTile(
|
||||
title: Text("Could not connect to server"),
|
||||
subtitle: Text("${_profile.server}"),
|
||||
leading: FaIcon(FontAwesomeIcons.server),
|
||||
trailing: FaIcon(
|
||||
FontAwesomeIcons.timesCircle,
|
||||
color: Color.fromRGBO(250, 50, 50, 1),
|
||||
),
|
||||
onTap: () {
|
||||
_selectProfile();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void onConnectSuccess(String msg) async {
|
||||
|
||||
final profile = await UserProfileDBManager().getSelectedProfile();
|
||||
|
||||
String address = profile?.server ?? 'unknown server address';
|
||||
|
||||
_serverConnection = true;
|
||||
_serverMessage = msg;
|
||||
_serverStatus = "Connected to ${address}";
|
||||
_serverStatusColor = Color.fromARGB(255, 50, 250, 50);
|
||||
_serverIcon = new FaIcon(FontAwesomeIcons.checkCircle, color: _serverStatusColor);
|
||||
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
void onConnectFailure(String msg) async {
|
||||
|
||||
final profile = await UserProfileDBManager().getSelectedProfile();
|
||||
|
||||
_serverConnection = false;
|
||||
_serverMessage = msg;
|
||||
_serverStatus = "Could not connect to ${profile?.server}";
|
||||
_serverStatusColor = Color.fromARGB(255, 250, 50, 50);
|
||||
_serverIcon = new FaIcon(FontAwesomeIcons.timesCircle, color: _serverStatusColor);
|
||||
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
_context = context;
|
||||
|
||||
_loadProfile();
|
||||
|
||||
// This method is rerun every time setState is called, for instance as done
|
||||
// by the _incrementCounter method above.
|
||||
//
|
||||
@ -369,6 +389,7 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
|
||||
),
|
||||
Spacer(),
|
||||
*/
|
||||
Spacer(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
|
Loading…
x
Reference in New Issue
Block a user