added scrollbars'n'stuff. logout timeout configurable
This commit is contained in:
parent
1a7d96efa5
commit
f5bf6cfda0
|
@ -1,20 +1,32 @@
|
|||
PODS:
|
||||
- Flutter (1.0.0)
|
||||
- package_info (0.0.1):
|
||||
- Flutter
|
||||
- screen_state (0.0.1):
|
||||
- Flutter
|
||||
- shared_preferences_ios (0.0.1):
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- Flutter (from `Flutter`)
|
||||
- package_info (from `.symlinks/plugins/package_info/ios`)
|
||||
- screen_state (from `.symlinks/plugins/screen_state/ios`)
|
||||
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
package_info:
|
||||
:path: ".symlinks/plugins/package_info/ios"
|
||||
screen_state:
|
||||
:path: ".symlinks/plugins/screen_state/ios"
|
||||
shared_preferences_ios:
|
||||
:path: ".symlinks/plugins/shared_preferences_ios/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
||||
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
|
||||
screen_state: a7ae251997e97f3f001839df09b57313b0ddef18
|
||||
shared_preferences_ios: aef470a42dc4675a1cdd50e3158b42e3d1232b32
|
||||
|
||||
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 50;
|
||||
objectVersion = 51;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
|
@ -68,7 +68,6 @@
|
|||
05F015517AA39E6E653CAEB9 /* Pods-Runner.release.xcconfig */,
|
||||
168F2D3694321E0C4AC1CFC0 /* Pods-Runner.profile.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
|
@ -356,13 +355,14 @@
|
|||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = GGPL7UH958;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.snipeScanner;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.itcreatesmedia.snipe-scanner";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
@ -484,13 +484,14 @@
|
|||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = GGPL7UH958;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.snipeScanner;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.itcreatesmedia.snipe-scanner";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
|
@ -506,13 +507,14 @@
|
|||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = GGPL7UH958;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.snipeScanner;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.itcreatesmedia.snipe-scanner";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
@ -546,4 +548,4 @@
|
|||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 97C146E61CF9000F007C117D /* Project object */;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
|
|
|
@ -4,98 +4,106 @@ import 'package:snipe_scanner/model/asset.dart';
|
|||
Widget searchItemRow(Asset asset, BuildContext context,
|
||||
{Function(Asset asset)? cb}) {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
width: size.width,
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
if (asset.image != null)
|
||||
Container(
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
height: 50,
|
||||
width: 50,
|
||||
child: Image(image: NetworkImage(asset.image!)),
|
||||
),
|
||||
SizedBox(
|
||||
width: asset.image != null ? size.width - 120 : size.width - 70,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.only(left: 20, bottom: 10),
|
||||
width: 90,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"Tag",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(asset.assetTag!)
|
||||
],
|
||||
)),
|
||||
if (asset.name != null)
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 10, bottom: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"Name",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Wrap(
|
||||
direction: Axis.horizontal,
|
||||
children: [Text(asset.name!)],
|
||||
)
|
||||
],
|
||||
)),
|
||||
)
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
if (asset.assignedTo != null)
|
||||
Container(
|
||||
padding: const EdgeInsets.only(left: 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"Checked out to",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
asset.assignedTo!.name!,
|
||||
)
|
||||
],
|
||||
))
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
if (cb != null)
|
||||
Container(
|
||||
width: 50,
|
||||
color: Colors.black12,
|
||||
child: IconButton(
|
||||
icon: const Icon(Icons.arrow_right_alt),
|
||||
tooltip: 'Manual Tag entry',
|
||||
onPressed: () => cb(asset),
|
||||
return Card(
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: size.width,
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
if (asset.image != null)
|
||||
Container(
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
height: 50,
|
||||
width: 50,
|
||||
child: Image(image: NetworkImage(asset.image!)),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider()
|
||||
],
|
||||
SizedBox(
|
||||
width: asset.image != null ? size.width - 120 : size.width - 70,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 20, bottom: 10),
|
||||
width: 90,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"Tag",
|
||||
style:
|
||||
TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(asset.assetTag!)
|
||||
],
|
||||
)),
|
||||
if (asset.name != null)
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 10, bottom: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"Name",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
Wrap(
|
||||
direction: Axis.horizontal,
|
||||
children: [Text(asset.name!)],
|
||||
)
|
||||
],
|
||||
)),
|
||||
)
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
if (asset.assignedTo != null)
|
||||
Container(
|
||||
padding: const EdgeInsets.only(left: 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"Checked out to",
|
||||
style:
|
||||
TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
asset.assignedTo!.name!,
|
||||
)
|
||||
],
|
||||
))
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
if (cb != null)
|
||||
Container(
|
||||
width: 50,
|
||||
color: Colors.black12,
|
||||
child: IconButton(
|
||||
icon: const Icon(Icons.arrow_right_alt),
|
||||
tooltip: 'Manual Tag entry',
|
||||
onPressed: () => cb(asset),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
|
|
@ -19,7 +19,6 @@ import 'package:snipe_scanner/widgets/user_detail.dart';
|
|||
|
||||
import 'model/app_state.dart';
|
||||
|
||||
const logoutTimeout = Duration(hours: 1);
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
|
||||
|
||||
|
@ -33,6 +32,8 @@ Future main() async {
|
|||
'use_custom_user_url': false,
|
||||
'tag_prefix': '',
|
||||
'use_tag': true,
|
||||
'auto_logout': false,
|
||||
'auto_logout_time': 60
|
||||
});
|
||||
ZebraScan.init();
|
||||
runApp(PrefService(
|
||||
|
@ -55,18 +56,25 @@ class _MyAppState extends State<MyApp> {
|
|||
@override
|
||||
void initState() {
|
||||
try {
|
||||
_screen.screenStateStream!.listen((ScreenStateEvent e) => {
|
||||
if (e == ScreenStateEvent.SCREEN_OFF && logoutTimer == null)
|
||||
{
|
||||
logoutTimer = Timer(logoutTimeout, () {
|
||||
Provider.of<AppState>(context, listen: false).setToken("");
|
||||
navigatorKey.currentState?.popUntil((route) => route.isFirst);
|
||||
})
|
||||
}
|
||||
else if (e == ScreenStateEvent.SCREEN_UNLOCKED &&
|
||||
logoutTimer != null)
|
||||
{logoutTimer!.cancel(), logoutTimer = null, log("unlocked")}
|
||||
_screen.screenStateStream!.listen((ScreenStateEvent e) {
|
||||
log((logoutTimer == null).toString());
|
||||
if (e == ScreenStateEvent.SCREEN_OFF &&
|
||||
logoutTimer == null &&
|
||||
PrefService.of(context).get('auto_logout')) {
|
||||
Duration duration = Duration(
|
||||
minutes: PrefService.of(context).get('auto_logout_time'));
|
||||
logoutTimer = Timer(duration, () {
|
||||
Provider.of<AppState>(context, listen: false).setToken("");
|
||||
navigatorKey.currentState?.popUntil((route) => route.isFirst);
|
||||
});
|
||||
log("Locking in ${duration.toString()} minutes");
|
||||
} else if (e == ScreenStateEvent.SCREEN_UNLOCKED &&
|
||||
logoutTimer != null) {
|
||||
logoutTimer!.cancel();
|
||||
logoutTimer = null;
|
||||
log("unlocked");
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
log(err.toString());
|
||||
}
|
||||
|
|
|
@ -155,16 +155,18 @@ class _BulkCheckinState extends State<BulkCheckin> with RouteAware {
|
|||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: _history.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var i = _history.length - (index + 1);
|
||||
return itemRow(_history[i]["barcode"], context,
|
||||
name: _history[i]["name"],
|
||||
note: _history[i]["note"],
|
||||
status: _history[i]["status"],
|
||||
checkinFrom: _history[i]["checkinFrom"]);
|
||||
}))
|
||||
child: Scrollbar(
|
||||
child: ListView.builder(
|
||||
itemCount: _history.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var i = _history.length - (index + 1);
|
||||
return itemRow(_history[i]["barcode"], context,
|
||||
name: _history[i]["name"],
|
||||
note: _history[i]["note"],
|
||||
status: _history[i]["status"],
|
||||
checkinFrom: _history[i]["checkinFrom"]);
|
||||
})),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -164,15 +164,17 @@ class _BulkCheckoutState extends State<BulkCheckout> with RouteAware {
|
|||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: _history.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var i = _history.length - (index + 1);
|
||||
return itemRow(_history[i]["barcode"], context,
|
||||
name: _history[i]["name"],
|
||||
note: _history[i]["note"],
|
||||
status: _history[i]["status"]);
|
||||
}))
|
||||
child: Scrollbar(
|
||||
child: ListView.builder(
|
||||
itemCount: _history.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var i = _history.length - (index + 1);
|
||||
return itemRow(_history[i]["barcode"], context,
|
||||
name: _history[i]["name"],
|
||||
note: _history[i]["note"],
|
||||
status: _history[i]["status"]);
|
||||
})),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -11,7 +11,6 @@ import 'package:snipe_scanner/main.dart';
|
|||
import 'package:snipe_scanner/model/app_state.dart';
|
||||
import 'package:snipe_scanner/service/login_user.dart';
|
||||
import 'package:snipe_scanner/utils/zebra_scan.dart';
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
|
||||
class DashboardWidget extends StatefulWidget {
|
||||
const DashboardWidget({Key? key}) : super(key: key);
|
||||
|
|
|
@ -29,13 +29,15 @@ class ItemHistoryView extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: history.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var i = history.length - (index + 1);
|
||||
return historyRow(history[i], context);
|
||||
}))
|
||||
child: Scrollbar(
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: history.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var i = history.length - (index + 1);
|
||||
return historyRow(history[i], context);
|
||||
})),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,24 @@ class PreferencesWidgetState extends State<PreferencesWidget> {
|
|||
),
|
||||
], pref: 'use_custom_user_url'),
|
||||
const PrefText(pref: 'tag_prefix', label: 'Tag Prefix'),
|
||||
PrefCheckbox(
|
||||
pref: 'auto_logout',
|
||||
title: const Text("Auto Logout"),
|
||||
onChange: (value) {
|
||||
if (!value) {
|
||||
PrefService.of(context).set('auto_logout_time', 0);
|
||||
}
|
||||
},
|
||||
),
|
||||
PrefHider(children: [
|
||||
PrefSlider(
|
||||
pref: 'auto_logout_time',
|
||||
title: const Text('Auto logout timeout'),
|
||||
min: 0,
|
||||
max: 300,
|
||||
trailing: (num v) => Text('$v minutes'),
|
||||
),
|
||||
], pref: 'auto_logout')
|
||||
],
|
||||
));
|
||||
}
|
||||
|
|
|
@ -70,15 +70,17 @@ class _SearchAssetState extends State<SearchAsset> {
|
|||
TextStyle(fontSize: 20, fontWeight: FontWeight.bold))),
|
||||
if (_assets.isNotEmpty)
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: _assets.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var i = _assets.length - (index + 1);
|
||||
return searchItemRow(_assets[i], context,
|
||||
cb: (Asset asset) {
|
||||
Navigator.pop(context, asset.assetTag);
|
||||
});
|
||||
}))
|
||||
child: Scrollbar(
|
||||
child: ListView.builder(
|
||||
itemCount: _assets.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var i = _assets.length - (index + 1);
|
||||
return searchItemRow(_assets[i], context,
|
||||
cb: (Asset asset) {
|
||||
Navigator.pop(context, asset.assetTag);
|
||||
});
|
||||
})),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -26,7 +26,7 @@ class UserGeneralView extends StatelessWidget {
|
|||
radius: 60, backgroundImage: NetworkImage(user.avatar))),
|
||||
),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Scrollbar(
|
||||
child: Column(
|
||||
children: [
|
||||
TextRow(title: "Name", text: user.name),
|
||||
|
@ -66,16 +66,18 @@ class UserAssetsView extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: assets.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var i = assets.length - (index + 1);
|
||||
return searchItemRow(assets[i], context,
|
||||
cb: (asset) => Navigator.pushNamed(
|
||||
context, "/assetDetail",
|
||||
arguments: asset.assetTag));
|
||||
}))
|
||||
child: Scrollbar(
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: assets.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var i = assets.length - (index + 1);
|
||||
return searchItemRow(assets[i], context,
|
||||
cb: (asset) => Navigator.pushNamed(
|
||||
context, "/assetDetail",
|
||||
arguments: asset.assetTag));
|
||||
})),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue