mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-28 13:36:50 +00:00
Refactoring / fixing
This commit is contained in:
parent
7373805ea7
commit
4080b4177b
30
lib/api.dart
30
lib/api.dart
@ -177,6 +177,8 @@ class InvenTreeAPI {
|
|||||||
* e.g. http://127.0.0.1:8000
|
* e.g. http://127.0.0.1:8000
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (profile == null) return false;
|
||||||
|
|
||||||
String address = profile.server.trim();
|
String address = profile.server.trim();
|
||||||
String username = profile.username.trim();
|
String username = profile.username.trim();
|
||||||
String password = profile.password.trim();
|
String password = profile.password.trim();
|
||||||
@ -212,10 +214,13 @@ class InvenTreeAPI {
|
|||||||
print("Error connecting to server: ${error.toString()}");
|
print("Error connecting to server: ${error.toString()}");
|
||||||
|
|
||||||
if (error is SocketException) {
|
if (error is SocketException) {
|
||||||
showServerError(context, "Connection Refused");
|
print("Error: socket exception: ${error.toString()}");
|
||||||
|
// TODO - Display error dialog!!
|
||||||
|
//showServerError(context, "Connection Refused");
|
||||||
return null;
|
return null;
|
||||||
} else if (error is TimeoutException) {
|
} else if (error is TimeoutException) {
|
||||||
showTimeoutDialog(context);
|
// TODO - Display timeout dialog here
|
||||||
|
//showTimeoutDialog(context);
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
// Unknown error type - re-throw the error and Sentry will catch it
|
// Unknown error type - re-throw the error and Sentry will catch it
|
||||||
@ -303,18 +308,25 @@ class InvenTreeAPI {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> connectToServer(BuildContext context) async {
|
bool disconnectFromServer() {
|
||||||
print("InvenTreeAPI().connectToServer()");
|
print("InvenTreeAPI().disconnectFromServer()");
|
||||||
|
|
||||||
// Clear connection flag
|
|
||||||
_connected = false;
|
_connected = false;
|
||||||
|
_connecting = false;
|
||||||
// Clear token
|
|
||||||
_token = '';
|
_token = '';
|
||||||
|
profile = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> connectToServer(BuildContext context) async {
|
||||||
|
|
||||||
|
// Ensure server is first disconnected
|
||||||
|
disconnectFromServer();
|
||||||
|
|
||||||
// Load selected profile
|
// Load selected profile
|
||||||
profile = await UserProfileDBManager().getSelectedProfile();
|
profile = await UserProfileDBManager().getSelectedProfile();
|
||||||
|
|
||||||
|
print("API Profile: ${profile.toString()}");
|
||||||
|
|
||||||
if (profile == null) {
|
if (profile == null) {
|
||||||
await showErrorDialog(
|
await showErrorDialog(
|
||||||
context,
|
context,
|
||||||
@ -326,13 +338,13 @@ class InvenTreeAPI {
|
|||||||
|
|
||||||
_connecting = true;
|
_connecting = true;
|
||||||
|
|
||||||
_connect(context).then((result) {
|
bool result = await _connect(context);
|
||||||
|
|
||||||
print("_connect() returned result: ${result}");
|
print("_connect() returned result: ${result}");
|
||||||
|
|
||||||
_connecting = false;
|
_connecting = false;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform a PATCH request
|
// Perform a PATCH request
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import 'package:InvenTree/widget/dialogs.dart';
|
import 'package:InvenTree/widget/dialogs.dart';
|
||||||
import 'package:InvenTree/widget/fields.dart';
|
import 'package:InvenTree/widget/fields.dart';
|
||||||
|
import 'package:InvenTree/widget/spinner.dart';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
@ -166,21 +168,20 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
|||||||
|
|
||||||
void _selectProfile(BuildContext context, UserProfile profile) async {
|
void _selectProfile(BuildContext context, UserProfile profile) async {
|
||||||
|
|
||||||
// Mark currently selected profile as unselected
|
// Disconnect InvenTree
|
||||||
final selected = await UserProfileDBManager().getSelectedProfile();
|
InvenTreeAPI().disconnectFromServer();
|
||||||
|
|
||||||
selected.selected = false;
|
await UserProfileDBManager().selectProfile(profile.key);
|
||||||
|
|
||||||
await UserProfileDBManager().updateProfile(selected);
|
|
||||||
|
|
||||||
profile.selected = true;
|
|
||||||
|
|
||||||
await UserProfileDBManager().updateProfile(profile);
|
|
||||||
|
|
||||||
_reload();
|
_reload();
|
||||||
|
|
||||||
|
print("CONNECT FROM A");
|
||||||
// Attempt server login (this will load the newly selected profile
|
// Attempt server login (this will load the newly selected profile
|
||||||
InvenTreeAPI().connectToServer(context);
|
InvenTreeAPI().connectToServer(context).then((result) {
|
||||||
|
_reload();
|
||||||
|
});
|
||||||
|
|
||||||
|
_reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _deleteProfile(UserProfile profile) async {
|
void _deleteProfile(UserProfile profile) async {
|
||||||
@ -191,6 +192,10 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
|
|
||||||
_reload();
|
_reload();
|
||||||
|
|
||||||
|
if (InvenTreeAPI().isConnected() && profile.key == InvenTreeAPI().profile.key) {
|
||||||
|
InvenTreeAPI().disconnectFromServer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateProfile(UserProfile profile) async {
|
void _updateProfile(UserProfile profile) async {
|
||||||
@ -201,6 +206,15 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
|
|
||||||
_reload();
|
_reload();
|
||||||
|
|
||||||
|
if (InvenTreeAPI().isConnected() && profile.key == InvenTreeAPI().profile.key) {
|
||||||
|
// Attempt server login (this will load the newly selected profile
|
||||||
|
|
||||||
|
print("Connect froM A");
|
||||||
|
InvenTreeAPI().connectToServer(context).then((result) {
|
||||||
|
_reload();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _addProfile(UserProfile profile) async {
|
void _addProfile(UserProfile profile) async {
|
||||||
@ -213,11 +227,45 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
|||||||
_reload();
|
_reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _getProfileIcon(UserProfile profile) {
|
||||||
|
|
||||||
|
// Not selected? No icon for you!
|
||||||
|
if (profile == null || !profile.selected) return null;
|
||||||
|
|
||||||
|
// Selected, but (for some reason) not the same as the API...
|
||||||
|
if (InvenTreeAPI().profile == null || InvenTreeAPI().profile.key != profile.key) {
|
||||||
|
return FaIcon(
|
||||||
|
FontAwesomeIcons.questionCircle,
|
||||||
|
color: Color.fromRGBO(250, 150, 50, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reflect the connection status of the server
|
||||||
|
if (InvenTreeAPI().isConnected()) {
|
||||||
|
return FaIcon(
|
||||||
|
FontAwesomeIcons.checkCircle,
|
||||||
|
color: Color.fromRGBO(50, 250, 50, 1)
|
||||||
|
);
|
||||||
|
} else if (InvenTreeAPI().isConnecting()) {
|
||||||
|
return Spinner(
|
||||||
|
icon: FontAwesomeIcons.spinner,
|
||||||
|
color: Color.fromRGBO(50, 50, 250, 1),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return FaIcon(
|
||||||
|
FontAwesomeIcons.timesCircle,
|
||||||
|
color: Color.fromRGBO(250, 50, 50, 1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
final Size screenSize = MediaQuery.of(context).size;
|
final Size screenSize = MediaQuery.of(context).size;
|
||||||
|
|
||||||
|
print("Building!");
|
||||||
|
|
||||||
List<Widget> children = [];
|
List<Widget> children = [];
|
||||||
|
|
||||||
if (profiles != null && profiles.length > 0) {
|
if (profiles != null && profiles.length > 0) {
|
||||||
@ -228,10 +276,12 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
|||||||
title: Text(
|
title: Text(
|
||||||
profile.name,
|
profile.name,
|
||||||
),
|
),
|
||||||
subtitle: Text(profile.server),
|
tileColor: profile.selected ? Color.fromRGBO(0, 0, 0, 0.05) : null,
|
||||||
trailing: profile.selected
|
subtitle: Text("${profile.server}"),
|
||||||
? FaIcon(FontAwesomeIcons.checkCircle)
|
trailing: _getProfileIcon(profile),
|
||||||
: null,
|
onTap: () {
|
||||||
|
_selectProfile(context, profile);
|
||||||
|
},
|
||||||
onLongPress: () {
|
onLongPress: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
@ -239,50 +289,40 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
|||||||
return SimpleDialog(
|
return SimpleDialog(
|
||||||
title: Text(profile.name),
|
title: Text(profile.name),
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
Divider(),
|
||||||
SimpleDialogOption(
|
SimpleDialogOption(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
_selectProfile(context, profile);
|
_selectProfile(context, profile);
|
||||||
},
|
},
|
||||||
child: Text(I18N
|
child: Text(I18N.of(context).profileSelect),
|
||||||
.of(context)
|
|
||||||
.profileSelect),
|
|
||||||
),
|
),
|
||||||
SimpleDialogOption(
|
SimpleDialogOption(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
_editProfile(context, userProfile: profile);
|
_editProfile(context, userProfile: profile);
|
||||||
},
|
},
|
||||||
child: Text(I18N
|
child: Text(I18N.of(context).profileEdit),
|
||||||
.of(context)
|
|
||||||
.profileEdit),
|
|
||||||
),
|
),
|
||||||
SimpleDialogOption(
|
SimpleDialogOption(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
// Navigator.of(context, rootNavigator: true).pop();
|
// Navigator.of(context, rootNavigator: true).pop();
|
||||||
confirmationDialog(
|
confirmationDialog(
|
||||||
context,
|
context,
|
||||||
I18N
|
I18N.of(context).delete,
|
||||||
.of(context)
|
|
||||||
.delete,
|
|
||||||
"Delete this profile?",
|
"Delete this profile?",
|
||||||
onAccept: () {
|
onAccept: () {
|
||||||
_deleteProfile(profile);
|
_deleteProfile(profile);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Text(I18N
|
child: Text(I18N.of(context).profileDelete),
|
||||||
.of(context)
|
|
||||||
.profileDelete),
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onTap: () {
|
|
||||||
|
|
||||||
},
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -36,13 +36,13 @@ class UserProfile {
|
|||||||
// User ID (will be provided by the server on log-in)
|
// User ID (will be provided by the server on log-in)
|
||||||
int user_id;
|
int user_id;
|
||||||
|
|
||||||
factory UserProfile.fromJson(int key, Map<String, dynamic> json) => UserProfile(
|
factory UserProfile.fromJson(int key, Map<String, dynamic> json, bool isSelected) => UserProfile(
|
||||||
key: key,
|
key: key,
|
||||||
name: json['name'],
|
name: json['name'],
|
||||||
server: json['server'],
|
server: json['server'],
|
||||||
username: json['username'],
|
username: json['username'],
|
||||||
password: json['password'],
|
password: json['password'],
|
||||||
selected: json['selected'] ?? false,
|
selected: isSelected,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
@ -50,33 +50,40 @@ class UserProfile {
|
|||||||
"server": server,
|
"server": server,
|
||||||
"username": username,
|
"username": username,
|
||||||
"password": password,
|
"password": password,
|
||||||
"selected": selected,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return "${server} - ${username}:${password}";
|
return "<${key}> ${name} : ${server} - ${username}:${password}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class UserProfileDBManager {
|
class UserProfileDBManager {
|
||||||
|
|
||||||
static const String folder_name = "profiles";
|
final store = StoreRef("profiles");
|
||||||
|
|
||||||
final _folder = intMapStoreFactory.store(folder_name);
|
|
||||||
|
|
||||||
Future<Database> get _db async => await InvenTreePreferencesDB.instance.database;
|
Future<Database> get _db async => await InvenTreePreferencesDB.instance.database;
|
||||||
|
|
||||||
|
Future<bool> profileNameExists(String name) async {
|
||||||
|
|
||||||
|
final finder = Finder(filter: Filter.equals("name", name));
|
||||||
|
|
||||||
|
final profiles = await store.find(await _db, finder: finder);
|
||||||
|
|
||||||
|
return profiles.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
Future addProfile(UserProfile profile) async {
|
Future addProfile(UserProfile profile) async {
|
||||||
|
|
||||||
UserProfile existingProfile = await getProfile(profile.name);
|
// Check if a profile already exists with the name
|
||||||
|
final bool exists = await profileNameExists(profile.name);
|
||||||
|
|
||||||
if (existingProfile != null) {
|
if (exists) {
|
||||||
print("UserProfile '${profile.name}' already exists");
|
print("UserProfile '${profile.name}' already exists");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int key = await _folder.add(await _db, profile.toJson());
|
int key = await store.add(await _db, profile.toJson());
|
||||||
|
|
||||||
print("Added user profile <${key}> - '${profile.name}'");
|
print("Added user profile <${key}> - '${profile.name}'");
|
||||||
|
|
||||||
@ -84,23 +91,34 @@ class UserProfileDBManager {
|
|||||||
profile.key = key;
|
profile.key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future selectProfile(int key) async {
|
||||||
|
/*
|
||||||
|
* Mark the particular profile as selected
|
||||||
|
*/
|
||||||
|
|
||||||
|
final result = await store.record("selected").put(await _db, key);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Future updateProfile(UserProfile profile) async {
|
Future updateProfile(UserProfile profile) async {
|
||||||
|
|
||||||
if (profile.key == null) {
|
if (profile.key == null) {
|
||||||
addProfile(profile);
|
await addProfile(profile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final finder = Finder(filter: Filter.byKey(profile.key));
|
final result = await store.record(profile.key).update(await _db, profile.toJson());
|
||||||
await _folder.update(await _db, profile.toJson(), finder: finder);
|
|
||||||
|
|
||||||
print("Updated user profile <${profile.key}> - '${profile.name}");
|
print("Updated user profile <${profile.key}> - '${profile.name}'");
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future deleteProfile(UserProfile profile) async {
|
Future deleteProfile(UserProfile profile) async {
|
||||||
final finder = Finder(filter: Filter.equals("name", profile.name));
|
final finder = Finder(filter: Filter.equals("name", profile.name));
|
||||||
await _folder.delete(await _db, finder: finder);
|
|
||||||
|
|
||||||
|
await store.record(profile.key).delete(await _db);
|
||||||
print("Deleted user profile <${profile.key}> - '${profile.name}'");
|
print("Deleted user profile <${profile.key}> - '${profile.name}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,78 +126,50 @@ class UserProfileDBManager {
|
|||||||
/*
|
/*
|
||||||
* Return the currently selected profile.
|
* Return the currently selected profile.
|
||||||
*
|
*
|
||||||
* If multiple profiles are selected,
|
* key should match the "selected" property
|
||||||
* mark all but the first as unselected
|
|
||||||
*
|
|
||||||
* If no profile is currently selected,
|
|
||||||
* then force the first profile to be selected.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
final selected_finder = Finder(filter: Filter.equals("selected", true));
|
final selected = await store.record("selected").get(await _db);
|
||||||
|
|
||||||
final selected_profiles = await _folder.find(await _db, finder: selected_finder);
|
final profiles = await store.find(await _db);
|
||||||
|
|
||||||
if (selected_profiles.length == 1) {
|
List<UserProfile> profileList = new List<UserProfile>();
|
||||||
// A single profile is selected
|
|
||||||
return UserProfile.fromJson(selected_profiles[0].key, selected_profiles[0].value);
|
|
||||||
} else if (selected_profiles.length > 1) {
|
|
||||||
// Multiple selected profiles - de-select others
|
|
||||||
for (int idx = 1; idx < selected_profiles.length; idx++) {
|
|
||||||
UserProfile profile = UserProfile.fromJson(selected_profiles[idx].key, selected_profiles[idx].value);
|
|
||||||
|
|
||||||
profile.selected = false;
|
for (int idx = 0; idx < profiles.length; idx++) {
|
||||||
updateProfile(profile);
|
|
||||||
|
if (profiles[idx].key is int && profiles[idx].key == selected) {
|
||||||
|
return UserProfile.fromJson(
|
||||||
|
profiles[idx].key,
|
||||||
|
profiles[idx].value,
|
||||||
|
profiles[idx].key == selected,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// And return the first profile
|
|
||||||
return UserProfile.fromJson(selected_profiles[0].key, selected_profiles[0].value);
|
|
||||||
} else {
|
|
||||||
// No profiles selected!
|
|
||||||
|
|
||||||
final all_profiles = await getAllProfiles();
|
|
||||||
|
|
||||||
if (all_profiles.length == 0) {
|
|
||||||
// No profiles available
|
|
||||||
return null;
|
return null;
|
||||||
} else {
|
|
||||||
UserProfile prf = all_profiles[0];
|
|
||||||
prf.selected = true;
|
|
||||||
updateProfile(prf);
|
|
||||||
|
|
||||||
// Return the selected profile
|
|
||||||
return prf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<UserProfile> getProfile(String name) async {
|
|
||||||
|
|
||||||
print("Looking for user profile '${name}'");
|
|
||||||
|
|
||||||
// Lookup profile by name (or return null if does not exist)
|
|
||||||
final finder = Finder(filter: Filter.equals("name", name));
|
|
||||||
|
|
||||||
final profiles = await _folder.find(await _db, finder: finder);
|
|
||||||
|
|
||||||
if (profiles.length == 0) {
|
|
||||||
print("No matching profiles found");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the first matching profile object
|
|
||||||
return UserProfile.fromJson(profiles[0].key, profiles[0].value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return all user profile objects
|
* Return all user profile objects
|
||||||
*/
|
*/
|
||||||
Future<List<UserProfile>> getAllProfiles() async {
|
Future<List<UserProfile>> getAllProfiles() async {
|
||||||
final profiles = await _folder.find(await _db);
|
|
||||||
|
final selected = await store.record("selected").get(await _db);
|
||||||
|
|
||||||
|
final profiles = await store.find(await _db);
|
||||||
|
|
||||||
List<UserProfile> profileList = new List<UserProfile>();
|
List<UserProfile> profileList = new List<UserProfile>();
|
||||||
|
|
||||||
for (int idx = 0; idx < profiles.length; idx++) {
|
for (int idx = 0; idx < profiles.length; idx++) {
|
||||||
profileList.add(UserProfile.fromJson(profiles[idx].key, profiles[idx].value));
|
|
||||||
|
if (profiles[idx].key is int) {
|
||||||
|
profileList.add(
|
||||||
|
UserProfile.fromJson(
|
||||||
|
profiles[idx].key,
|
||||||
|
profiles[idx].value,
|
||||||
|
profiles[idx].key == selected,
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return profileList;
|
return profileList;
|
||||||
|
@ -15,6 +15,7 @@ import 'package:InvenTree/widget/category_display.dart';
|
|||||||
import 'package:InvenTree/widget/company_list.dart';
|
import 'package:InvenTree/widget/company_list.dart';
|
||||||
import 'package:InvenTree/widget/location_display.dart';
|
import 'package:InvenTree/widget/location_display.dart';
|
||||||
import 'package:InvenTree/widget/search.dart';
|
import 'package:InvenTree/widget/search.dart';
|
||||||
|
import 'package:InvenTree/widget/spinner.dart';
|
||||||
import 'package:InvenTree/widget/drawer.dart';
|
import 'package:InvenTree/widget/drawer.dart';
|
||||||
|
|
||||||
class InvenTreeHomePage extends StatefulWidget {
|
class InvenTreeHomePage extends StatefulWidget {
|
||||||
@ -28,19 +29,10 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
|
|||||||
|
|
||||||
_InvenTreeHomePageState() : super() {
|
_InvenTreeHomePageState() : super() {
|
||||||
|
|
||||||
|
// Initially load the profile and attempt server connection
|
||||||
_loadProfile();
|
_loadProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
String _serverStatus = "Connecting to server";
|
|
||||||
|
|
||||||
String _serverMessage = "";
|
|
||||||
|
|
||||||
bool _serverConnection = false;
|
|
||||||
|
|
||||||
FaIcon _serverIcon = new FaIcon(FontAwesomeIcons.spinner);
|
|
||||||
|
|
||||||
Color _serverStatusColor = Color.fromARGB(255, 50, 50, 250);
|
|
||||||
|
|
||||||
// Selected user profile
|
// Selected user profile
|
||||||
UserProfile _profile;
|
UserProfile _profile;
|
||||||
|
|
||||||
@ -111,30 +103,20 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
|
|||||||
|
|
||||||
void _loadProfile() async {
|
void _loadProfile() async {
|
||||||
|
|
||||||
final profile = await UserProfileDBManager().getSelectedProfile();
|
_profile = await UserProfileDBManager().getSelectedProfile();
|
||||||
|
|
||||||
// If a different profile is selected, re-connect
|
// A valid profile was loaded!
|
||||||
if (_profile == null || (_profile.key != profile.key)) {
|
if (_profile != null) {
|
||||||
|
if (!InvenTreeAPI().isConnected() && !InvenTreeAPI().isConnecting()) {
|
||||||
if (_context != null) {
|
|
||||||
print("Connecting Profile: ${profile.name} - ${profile.server}");
|
|
||||||
|
|
||||||
|
print("Connect from C");
|
||||||
InvenTreeAPI().connectToServer(_context).then((result) {
|
InvenTreeAPI().connectToServer(_context).then((result) {
|
||||||
setState(() {
|
setState(() {});
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_profile = profile;
|
setState(() {});
|
||||||
|
|
||||||
setState(() {
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ListTile _serverTile() {
|
ListTile _serverTile() {
|
||||||
@ -162,10 +144,13 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
|
|||||||
title: Text("Connecting to server..."),
|
title: Text("Connecting to server..."),
|
||||||
subtitle: Text("${InvenTreeAPI().baseUrl}"),
|
subtitle: Text("${InvenTreeAPI().baseUrl}"),
|
||||||
leading: FaIcon(FontAwesomeIcons.server),
|
leading: FaIcon(FontAwesomeIcons.server),
|
||||||
trailing: FaIcon(
|
trailing: Spinner(
|
||||||
FontAwesomeIcons.spinner,
|
icon: FontAwesomeIcons.spinner,
|
||||||
color: Color.fromRGBO(50, 50, 250, 1),
|
color: Color.fromRGBO(50, 50, 250, 1),
|
||||||
)
|
),
|
||||||
|
onTap: () {
|
||||||
|
_selectProfile();
|
||||||
|
}
|
||||||
);
|
);
|
||||||
} else if (InvenTreeAPI().isConnected()) {
|
} else if (InvenTreeAPI().isConnected()) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
@ -196,42 +181,11 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
_context = context;
|
_context = context;
|
||||||
|
|
||||||
_loadProfile();
|
|
||||||
|
|
||||||
// This method is rerun every time setState is called, for instance as done
|
// This method is rerun every time setState is called, for instance as done
|
||||||
// by the _incrementCounter method above.
|
// by the _incrementCounter method above.
|
||||||
//
|
//
|
||||||
|
54
lib/widget/spinner.dart
Normal file
54
lib/widget/spinner.dart
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
||||||
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
|
||||||
|
class Spinner extends StatefulWidget {
|
||||||
|
final IconData icon;
|
||||||
|
final Duration duration;
|
||||||
|
final Color color;
|
||||||
|
|
||||||
|
const Spinner({
|
||||||
|
this.color = const Color.fromRGBO(150, 150, 150, 1),
|
||||||
|
Key key,
|
||||||
|
@required this.icon,
|
||||||
|
this.duration = const Duration(milliseconds: 1800),
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_SpinnerState createState() => _SpinnerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SpinnerState extends State<Spinner> with SingleTickerProviderStateMixin {
|
||||||
|
AnimationController _controller;
|
||||||
|
Widget _child;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_controller = AnimationController(
|
||||||
|
vsync: this,
|
||||||
|
duration: Duration(milliseconds: 2000),
|
||||||
|
)
|
||||||
|
..repeat();
|
||||||
|
_child = FaIcon(
|
||||||
|
widget.icon,
|
||||||
|
color: widget.color
|
||||||
|
);
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return RotationTransition(
|
||||||
|
turns: _controller,
|
||||||
|
child: _child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user