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

User configurable home screen actions

This commit is contained in:
Oliver 2022-01-05 14:00:38 +11:00
parent fd54b20b92
commit 2788ed5bd7
8 changed files with 256 additions and 102 deletions

View File

@ -1,11 +1,12 @@
## InvenTree App Release Notes ## InvenTree App Release Notes
--- ---
### 0.x.x - January 2022 ### 0.5.4 - January 2022
--- ---
- Enable usage of camera flash when scanning barcodes - Enable usage of camera flash when scanning barcodes
- Enable camera toggle when scanning barcodes - Enable camera toggle when scanning barcodes
- Configurable home screen actions
- Updated icon set - Updated icon set
- Removed "upload error report" functionality (instead link to GitHub issues) - Removed "upload error report" functionality (instead link to GitHub issues)
- Updated multiple language translations - Updated multiple language translations

View File

@ -488,9 +488,7 @@ class InvenTreeAPI {
List<String> perms = List.from(roles[role] as List<dynamic>); List<String> perms = List.from(roles[role] as List<dynamic>);
return perms.contains(permission); return perms.contains(permission);
} catch (error, stackTrace) { } catch (error, stackTrace) {
if (error is CastError) { if (error is TypeError) {
// Ignore CastError
} else if (error is TypeError) {
// Ignore TypeError // Ignore TypeError
} else { } else {
// Unknown error - report it! // Unknown error - report it!

View File

@ -5,6 +5,21 @@
import "package:sembast/sembast.dart"; import "package:sembast/sembast.dart";
import "package:inventree/preferences.dart"; import "package:inventree/preferences.dart";
// Settings key values
const String INV_HOME_SHOW_SUBSCRIBED = "homeShowSubscribed";
const String INV_HOME_SHOW_PO = "homeShowPo";
const String INV_HOME_SHOW_MANUFACTURERS = "homeShowManufacturers";
const String INV_HOME_SHOW_CUSTOMERS = "homeShowCustomers";
const String INV_HOME_SHOW_SUPPLIERS = "homeShowSuppliers";
const String INV_SOUNDS_BARCODE = "barcodeSounds";
const String INV_SOUNDS_SERVER = "serverSounds";
const String INV_PART_SUBCATEGORY = "partSubcategory";
const String INV_STOCK_SUBLOCATION = "stockSublocation";
class InvenTreeSettingsManager { class InvenTreeSettingsManager {
factory InvenTreeSettingsManager() { factory InvenTreeSettingsManager() {

View File

@ -18,7 +18,7 @@ String simpleNumberString(double number) {
Future<void> successTone() async { Future<void> successTone() async {
final bool en = await InvenTreeSettingsManager().getValue("barcodeSounds", true) as bool; final bool en = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool;
if (en) { if (en) {
final player = AudioCache(); final player = AudioCache();
@ -28,7 +28,7 @@ Future<void> successTone() async {
Future <void> failureTone() async { Future <void> failureTone() async {
final bool en = await InvenTreeSettingsManager().getValue("barcodeSounds", true) as bool; final bool en = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool;
if (en) { if (en) {
final player = AudioCache(); final player = AudioCache();

@ -1 +1 @@
Subproject commit 08bfb71daa2f4cd0780708bf3553ff2b1e2adc50 Subproject commit feae1bee4275544b1571a37273b0e8113622eb2c

View File

@ -19,9 +19,21 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
final GlobalKey<_InvenTreeAppSettingsState> _settingsKey = GlobalKey<_InvenTreeAppSettingsState>(); final GlobalKey<_InvenTreeAppSettingsState> _settingsKey = GlobalKey<_InvenTreeAppSettingsState>();
// Home screen settings
bool homeShowSubscribed = true;
bool homeShowPo = true;
bool homeShowSuppliers = true;
bool homeShowManufacturers = true;
bool homeShowCustomers = true;
// Sound settings
bool barcodeSounds = true; bool barcodeSounds = true;
bool serverSounds = true; bool serverSounds = true;
// Part settings
bool partSubcategory = false; bool partSubcategory = false;
// Stock settings
bool stockSublocation = false; bool stockSublocation = false;
@override @override
@ -32,45 +44,21 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
} }
Future <void> loadSettings() async { Future <void> loadSettings() async {
barcodeSounds = await InvenTreeSettingsManager().getValue("barcodeSounds", true) as bool;
serverSounds = await InvenTreeSettingsManager().getValue("serverSounds", true) as bool;
partSubcategory = await InvenTreeSettingsManager().getValue("partSubcategory", true) as bool; // Load initial settings
stockSublocation = await InvenTreeSettingsManager().getValue("stockSublocation", true) as bool;
setState(() { homeShowSubscribed = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_SUBSCRIBED, true) as bool;
}); homeShowPo = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_PO, true) as bool;
} homeShowManufacturers = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_MANUFACTURERS, true) as bool;
homeShowCustomers = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_CUSTOMERS, true) as bool;
homeShowSuppliers = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_SUPPLIERS, true) as bool;
Future <void> setBarcodeSounds(bool en) async { barcodeSounds = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool;
serverSounds = await InvenTreeSettingsManager().getValue(INV_SOUNDS_SERVER, true) as bool;
await InvenTreeSettingsManager().setValue("barcodeSounds", en); partSubcategory = await InvenTreeSettingsManager().getValue(INV_PART_SUBCATEGORY, true) as bool;
barcodeSounds = await InvenTreeSettingsManager().getBool("barcodeSounds", true);
setState(() { stockSublocation = await InvenTreeSettingsManager().getValue(INV_STOCK_SUBLOCATION, true) as bool;
});
}
Future <void> setServerSounds(bool en) async {
await InvenTreeSettingsManager().setValue("serverSounds", en);
serverSounds = await InvenTreeSettingsManager().getBool("serverSounds", true);
setState(() {
});
}
Future <void> setPartSubcategory(bool en) async {
await InvenTreeSettingsManager().setValue("partSubcategory", en);
partSubcategory = await InvenTreeSettingsManager().getBool("partSubcategory", true);
setState(() {
});
}
Future <void> setStockSublocation(bool en) async {
await InvenTreeSettingsManager().setValue("stockSublocation", en);
stockSublocation = await InvenTreeSettingsManager().getBool("stockSublocation", true);
setState(() { setState(() {
}); });
@ -87,12 +75,90 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
body: Container( body: Container(
child: ListView( child: ListView(
children: [ children: [
/* Home Screen Settings */
ListTile(
title: Text(
L10().homeScreen,
style: TextStyle(fontWeight: FontWeight.bold)
),
),
ListTile(
title: Text(L10().homeShowSubscribed),
subtitle: Text(L10().homeShowSubscribedDescription),
leading: FaIcon(FontAwesomeIcons.bell),
trailing: Switch(
value: homeShowSubscribed,
onChanged: (bool value) {
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_SUBSCRIBED, value);
setState(() {
homeShowSubscribed = value;
});
},
)
),
ListTile(
title: Text(L10().homeShowPo),
subtitle: Text(L10().homeShowPoDescription),
leading: FaIcon(FontAwesomeIcons.shoppingCart),
trailing: Switch(
value: homeShowPo,
onChanged: (bool value) {
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_PO, value);
setState(() {
homeShowPo = value;
});
},
),
),
ListTile(
title: Text(L10().homeShowSuppliers),
subtitle: Text(L10().homeShowSuppliersDescription),
leading: FaIcon(FontAwesomeIcons.building),
trailing: Switch(
value: homeShowSuppliers,
onChanged: (bool value) {
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_SUPPLIERS, value);
setState(() {
homeShowSuppliers = value;
});
},
),
),
ListTile(
title: Text(L10().homeShowManufacturers),
subtitle: Text(L10().homeShowManufacturersDescription),
leading: FaIcon(FontAwesomeIcons.industry),
trailing: Switch(
value: homeShowManufacturers,
onChanged: (bool value) {
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_MANUFACTURERS, value);
setState(() {
homeShowManufacturers = value;
});
},
),
),
ListTile(
title: Text(L10().homeShowCustomers),
subtitle: Text(L10().homeShowCustomersDescription),
leading: FaIcon(FontAwesomeIcons.userTie),
trailing: Switch(
value: homeShowCustomers,
onChanged: (bool value) {
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_CUSTOMERS, value);
setState(() {
homeShowCustomers = value;
});
},
),
),
/* Part Settings */
Divider(height: 3),
ListTile( ListTile(
title: Text( title: Text(
L10().parts, L10().parts,
style: TextStyle(fontWeight: FontWeight.bold), style: TextStyle(fontWeight: FontWeight.bold),
), ),
leading: FaIcon(FontAwesomeIcons.shapes),
), ),
ListTile( ListTile(
title: Text(L10().includeSubcategories), title: Text(L10().includeSubcategories),
@ -100,15 +166,20 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
leading: FaIcon(FontAwesomeIcons.sitemap), leading: FaIcon(FontAwesomeIcons.sitemap),
trailing: Switch( trailing: Switch(
value: partSubcategory, value: partSubcategory,
onChanged: setPartSubcategory, onChanged: (bool value) {
InvenTreeSettingsManager().setValue(INV_PART_SUBCATEGORY, value);
setState(() {
partSubcategory = value;
});
},
), ),
), ),
/* Stock Settings */
Divider(height: 3), Divider(height: 3),
ListTile( ListTile(
title: Text(L10().stock, title: Text(L10().stock,
style: TextStyle(fontWeight: FontWeight.bold), style: TextStyle(fontWeight: FontWeight.bold),
), ),
leading: FaIcon(FontAwesomeIcons.boxes),
), ),
ListTile( ListTile(
title: Text(L10().includeSublocations), title: Text(L10().includeSublocations),
@ -116,9 +187,15 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
leading: FaIcon(FontAwesomeIcons.sitemap), leading: FaIcon(FontAwesomeIcons.sitemap),
trailing: Switch( trailing: Switch(
value: stockSublocation, value: stockSublocation,
onChanged: setStockSublocation, onChanged: (bool value) {
InvenTreeSettingsManager().setValue(INV_STOCK_SUBLOCATION, value);
setState(() {
stockSublocation = value;
});
},
), ),
), ),
/* Sound Settings */
Divider(height: 3), Divider(height: 3),
ListTile( ListTile(
title: Text( title: Text(
@ -133,7 +210,12 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
leading: FaIcon(FontAwesomeIcons.server), leading: FaIcon(FontAwesomeIcons.server),
trailing: Switch( trailing: Switch(
value: serverSounds, value: serverSounds,
onChanged: setServerSounds, onChanged: (bool value) {
InvenTreeSettingsManager().setValue(INV_SOUNDS_SERVER, value);
setState(() {
serverSounds = value;
});
},
), ),
), ),
ListTile( ListTile(
@ -142,7 +224,12 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
leading: Icon(Icons.qr_code), leading: Icon(Icons.qr_code),
trailing: Switch( trailing: Switch(
value: barcodeSounds, value: barcodeSounds,
onChanged: setBarcodeSounds, onChanged: (bool value) {
InvenTreeSettingsManager().setValue(INV_SOUNDS_BARCODE, value);
setState(() {
barcodeSounds = value;
});
},
), ),
), ),
Divider(height: 1), Divider(height: 1),

View File

@ -106,7 +106,7 @@ Future<void> showServerError(String title, String description) async {
} }
// Play a sound // Play a sound
final bool tones = await InvenTreeSettingsManager().getValue("serverSounds", true) as bool; final bool tones = await InvenTreeSettingsManager().getValue(INV_SOUNDS_SERVER, true) as bool;
if (tones) { if (tones) {
final player = AudioCache(); final player = AudioCache();

View File

@ -19,6 +19,8 @@ import "package:inventree/widget/search.dart";
import "package:inventree/widget/snacks.dart"; import "package:inventree/widget/snacks.dart";
import "package:inventree/widget/drawer.dart"; import "package:inventree/widget/drawer.dart";
import "../app_settings.dart";
class InvenTreeHomePage extends StatefulWidget { class InvenTreeHomePage extends StatefulWidget {
@ -32,10 +34,20 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
_InvenTreeHomePageState() : super() { _InvenTreeHomePageState() : super() {
// Load display settings
_loadSettings();
// Initially load the profile and attempt server connection // Initially load the profile and attempt server connection
_loadProfile(); _loadProfile();
} }
bool homeShowPo = true;
bool homeShowSubscribed = true;
bool homeShowManufacturers = true;
bool homeShowCustomers = true;
bool homeShowSuppliers = true;
final GlobalKey<_InvenTreeHomePageState> _homeKey = GlobalKey<_InvenTreeHomePageState>(); final GlobalKey<_InvenTreeHomePageState> _homeKey = GlobalKey<_InvenTreeHomePageState>();
// Selected user profile // Selected user profile
@ -127,6 +139,22 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
}); });
} }
Future <void> _loadSettings() async {
print("_loadSettings");
homeShowSubscribed = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_SUBSCRIBED, true) as bool;
homeShowPo = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_PO, true) as bool;
homeShowManufacturers = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_MANUFACTURERS, true) as bool;
homeShowCustomers = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_CUSTOMERS, true) as bool;
homeShowSuppliers = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_SUPPLIERS, true) as bool;
print("suppliers: ${homeShowSuppliers}");
setState(() {
});
}
Future <void> _loadProfile() async { Future <void> _loadProfile() async {
_profile = await UserProfileDBManager().getSelectedProfile(); _profile = await UserProfileDBManager().getSelectedProfile();
@ -201,95 +229,120 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
} }
List<Widget> getGridTiles(BuildContext context) { List<Widget> getGridTiles(BuildContext context) {
return [
_iconButton( List<Widget> tiles = [];
context,
L10().scanBarcode, // Barcode scanner
Icons.qr_code_scanner, tiles.add(_iconButton(
callback: () { context,
_scan(context); L10().scanBarcode,
} Icons.qr_code_scanner,
), callback: () {
_iconButton( _scan(context);
context, }
L10().search, ));
FontAwesomeIcons.search,
callback: () { // Search widget
_search(context); tiles.add(_iconButton(
} context,
), L10().search,
_iconButton( FontAwesomeIcons.search,
context, callback: () {
L10().parts, _search(context);
FontAwesomeIcons.shapes, }
callback: () { ));
_showParts(context);
} // Parts
), tiles.add(_iconButton(
_iconButton( context,
L10().parts,
FontAwesomeIcons.shapes,
callback: () {
_showParts(context);
}
));
// Starred parts
if (homeShowSubscribed) {
tiles.add(_iconButton(
context, context,
L10().partsStarred, L10().partsStarred,
FontAwesomeIcons.solidStar, FontAwesomeIcons.bell,
callback: () { callback: () {
_showStarredParts(context); _showStarredParts(context);
} }
), ));
_iconButton( }
context,
L10().stock, // Stock button
FontAwesomeIcons.boxes, tiles.add(_iconButton(
callback: () { context,
_showStock(context); L10().stock,
} FontAwesomeIcons.boxes,
), callback: () {
_iconButton( _showStock(context);
}
));
// Purchase orderes
if (homeShowPo) {
tiles.add(_iconButton(
context, context,
L10().purchaseOrders, L10().purchaseOrders,
FontAwesomeIcons.shoppingCart, FontAwesomeIcons.shoppingCart,
callback: () { callback: () {
_showPurchaseOrders(context); _showPurchaseOrders(context);
} }
), ));
/* }
_iconButton(
context, // Suppliers
L10().salesOrders, if (homeShowSuppliers) {
FontAwesomeIcons.truck, tiles.add(_iconButton(
),
*/
_iconButton(
context, context,
L10().suppliers, L10().suppliers,
FontAwesomeIcons.building, FontAwesomeIcons.building,
callback: () { callback: () {
_showSuppliers(context); _showSuppliers(context);
} }
), ));
_iconButton( }
// Manufacturers
if (homeShowManufacturers) {
tiles.add(_iconButton(
context, context,
L10().manufacturers, L10().manufacturers,
FontAwesomeIcons.industry, FontAwesomeIcons.industry,
callback: () { callback: () {
_showManufacturers(context); _showManufacturers(context);
} }
), ));
_iconButton( }
// Customers
if (homeShowCustomers) {
tiles.add(_iconButton(
context, context,
L10().customers, L10().customers,
FontAwesomeIcons.userTie, FontAwesomeIcons.userTie,
callback: () { callback: () {
_showCustomers(context); _showCustomers(context);
} }
), ));
_iconButton( }
// Settings
tiles.add(_iconButton(
context, context,
L10().settings, L10().settings,
FontAwesomeIcons.cogs, FontAwesomeIcons.cogs,
callback: () { callback: () {
_showSettings(context); _showSettings(context);
} }
) ));
];
return tiles;
} }
@override @override