From 08c90fce7497493ee21567d0c0e3852ed3c6bb9f Mon Sep 17 00:00:00 2001 From: Sai Naw Wun Date: Mon, 9 Nov 2020 05:53:25 +0630 Subject: [PATCH] add version text --- assets/local/localization_en.json | 4 +- lib/data/provider/auth_fb.dart | 2 - lib/domain/constants.dart | 2 + lib/domain/entities/package.dart | 5 +- lib/pages/main/home_page.dart | 1 + lib/pages/main/splash_page.dart | 7 +- lib/pages/package/model/package_model.dart | 49 +++- lib/pages/receiving/receiving_editor.dart | 13 ++ lib/pages/widgets/barcode_scanner.dart | 8 + lib/pages/widgets/bottom_widgets.dart | 48 ++-- lib/pages/widgets/multi_img_file.dart | 255 ++++++++++++--------- pubspec.yaml | 2 +- 12 files changed, 258 insertions(+), 138 deletions(-) diff --git a/assets/local/localization_en.json b/assets/local/localization_en.json index c60d571..4365bd3 100644 --- a/assets/local/localization_en.json +++ b/assets/local/localization_en.json @@ -511,14 +511,14 @@ "receiving.info":"Receiving", "receiving.new":"New receiving", "receiving.create":"New Receiving", - "receiving.update":"Update Reveiving", + "receiving.update":"Update Receiving", "receiving.tracking.id":"Tracking ID", "receiving.remark":"Remark", "receiving.fcs.id":"FCS ID", "receiving.name":"Customer name", "receiving.phone":"Phone number", "receiving.create_btn":"Complete receiving", - "receiving.update_btn":"Update reveiving", + "receiving.update_btn":"Update receiving", "receiving.delete.confirm":"Delete this receiving?", "receiving.return.btn":"Return package", "receiving.return.confirm":"Return package?", diff --git a/lib/data/provider/auth_fb.dart b/lib/data/provider/auth_fb.dart index 1eaa500..15d9dc1 100644 --- a/lib/data/provider/auth_fb.dart +++ b/lib/data/provider/auth_fb.dart @@ -88,7 +88,6 @@ class AuthFb { } Future signInWithPhoneNumber(String smsCode) async { - User user; try { final AuthCredential credential = PhoneAuthProvider.getCredential( verificationId: _verificationId, @@ -102,7 +101,6 @@ class AuthFb { } on Exception catch (e) { return Future.error(SigninException(e.toString())); } - if (user == null) Future.error(SigninException("No current user!")); return Future.value(fcs.AuthResult(authStatus: AuthStatus.AUTH_VERIFIED)); } diff --git a/lib/domain/constants.dart b/lib/domain/constants.dart index fe1d6e4..a5ba92b 100644 --- a/lib/domain/constants.dart +++ b/lib/domain/constants.dart @@ -1,3 +1,5 @@ +const uploadPhotoLimit = 10; + const config_collection = "configs"; const user_collection = "users"; const invitations_collection = "invitations"; diff --git a/lib/domain/entities/package.dart b/lib/domain/entities/package.dart index 7a606d6..70f9af2 100644 --- a/lib/domain/entities/package.dart +++ b/lib/domain/entities/package.dart @@ -96,8 +96,9 @@ class Package { desc: map['desc'], status: map['status'], deliveryAddress: _da, - currentStatusDate: - _currentStatusDate != null ? _currentStatusDate.toDate() : null, + currentStatusDate: _currentStatusDate != null + ? _currentStatusDate.toDate().toLocal() + : null, photoUrls: _photoUrls, shipmentHistory: _shipmentStatus); } diff --git a/lib/pages/main/home_page.dart b/lib/pages/main/home_page.dart index 13529e7..237a20f 100644 --- a/lib/pages/main/home_page.dart +++ b/lib/pages/main/home_page.dart @@ -204,6 +204,7 @@ class _HomePageState extends State { @override Widget build(BuildContext context) { User user = Provider.of(context).user; + if (user == null) { Future.microtask( () => Navigator.pushNamedAndRemoveUntil(context, "/", (r) => false)); diff --git a/lib/pages/main/splash_page.dart b/lib/pages/main/splash_page.dart index 4651fc0..eb5edfb 100644 --- a/lib/pages/main/splash_page.dart +++ b/lib/pages/main/splash_page.dart @@ -66,9 +66,12 @@ class _SplashScreenState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - new Image.asset( - "assets/logo.jpg", + Container( + height: 180, width: 180, + child: new Image.asset( + "assets/logo.jpg", + ), ), SizedBox(height: 50), Column( diff --git a/lib/pages/package/model/package_model.dart b/lib/pages/package/model/package_model.dart index efa1134..8d44707 100644 --- a/lib/pages/package/model/package_model.dart +++ b/lib/pages/package/model/package_model.dart @@ -108,7 +108,7 @@ class PackageModel extends BaseModel { if (forCustomer) { q = q.where("user_id", isEqualTo: user.id); } - q = q.orderBy("tracking_id", descending: false); + q = q.orderBy("update_time", descending: true); listener = q.snapshots().listen((QuerySnapshot snapshot) { _packages.clear(); _packages = snapshot.documents.map((documentSnapshot) { @@ -139,6 +139,25 @@ class PackageModel extends BaseModel { return null; } + Future getPackageByTrackingID(String trackingID) async { + if (user == null) return null; + String path = "/$packages_collection"; + try { + var snaps = await Firestore.instance + .collection("$path") + .where("tracking_id", isEqualTo: trackingID) + .getDocuments(source: Source.server); + if (snaps.documents.length == 1) { + var snap = snaps.documents[0]; + var package = Package.fromMap(snap.data, snap.documentID); + return package; + } + } catch (e) { + log.warning("Error!! $e"); + } + return null; + } + Future lookupPackage(String trackingID) async { if (user == null) return null; String path = "/$packages_collection"; @@ -201,8 +220,15 @@ class PackageModel extends BaseModel { return Services.instance.userService.searchUser(term); } - Future> searchPackage(String term) { - return Services.instance.packageService.searchPackage(term); + Future> searchPackage(String term) async { + List packages = + await Services.instance.packageService.searchPackage(term); + + Package pkg = await getPackageByTrackingID(term); + if (pkg != null && !packages.contains(pkg)) { + packages.insert(0, pkg); + } + return packages; } Future createPackages(User user, List packages) { @@ -216,7 +242,8 @@ class PackageModel extends BaseModel { package.fcsID = user.fcsID; } if (files != null) { - if (files.length > 5) throw Exception("Exceed number of file upload"); + if (files.length > uploadPhotoLimit) + throw Exception("Exceed number of file upload"); package.photoUrls = package.photoUrls == null ? [] : package.photoUrls; for (File f in files) { String path = Path.join(pkg_files_path); @@ -240,7 +267,12 @@ class PackageModel extends BaseModel { } if (files != null) { - if (files.length > 5) throw Exception("Exceed number of file upload"); + var count = (package.photoUrls?.length ?? 0) + + files.length - + (deletedUrls?.length ?? 0); + + if (count > uploadPhotoLimit) + throw Exception("Exceed number of file upload"); package.photoUrls = package.photoUrls == null ? [] : package.photoUrls; for (File f in files) { String path = Path.join(pkg_files_path); @@ -265,7 +297,12 @@ class PackageModel extends BaseModel { } if (files != null) { - if (files.length > 5) throw Exception("Exceed number of file upload"); + var count = (package.photoUrls?.length ?? 0) + + files.length - + (deletedUrls?.length ?? 0); + + if (count > uploadPhotoLimit) + throw Exception("Exceed number of file upload"); package.photoUrls = package.photoUrls == null ? [] : package.photoUrls; for (File f in files) { String path = Path.join(pkg_files_path); diff --git a/lib/pages/receiving/receiving_editor.dart b/lib/pages/receiving/receiving_editor.dart index e0dd8ad..305ab6a 100644 --- a/lib/pages/receiving/receiving_editor.dart +++ b/lib/pages/receiving/receiving_editor.dart @@ -52,6 +52,17 @@ class _ReceivingEditorState extends State { } else { package = new Package(); } + _trackingIDCtl.addListener(() { + var text = _trackingIDCtl.text; + if (text.contains(RegExp(r'[a-z ]'))) { + text = text.toUpperCase().replaceAll(" ", ""); + _trackingIDCtl.value = _trackingIDCtl.value.copyWith( + text: text, + selection: + TextSelection(baseOffset: text.length, extentOffset: text.length), + ); + } + }); } @override @@ -158,7 +169,9 @@ class _ReceivingEditorState extends State { height: 10, ), remarkBox, + Divider(), img, + Divider(), SizedBox( height: 10, ), diff --git a/lib/pages/widgets/barcode_scanner.dart b/lib/pages/widgets/barcode_scanner.dart index 3bbed5d..2706a21 100644 --- a/lib/pages/widgets/barcode_scanner.dart +++ b/lib/pages/widgets/barcode_scanner.dart @@ -9,6 +9,14 @@ Future scanBarcode() async { if (barcode.contains(gs)) { var codes = barcode.split(gs); barcode = codes.length >= 2 ? codes[1] : barcode; + } else if (barcode.startsWith("96")) { + if (barcode.length == 34) { + int start = barcode.length - 12; + barcode = barcode.substring(start); + } else if (barcode.length == 22) { + int start = barcode.length - 15; + barcode = barcode.substring(start); + } } return barcode; } catch (e) { diff --git a/lib/pages/widgets/bottom_widgets.dart b/lib/pages/widgets/bottom_widgets.dart index e5c9710..c64ff11 100644 --- a/lib/pages/widgets/bottom_widgets.dart +++ b/lib/pages/widgets/bottom_widgets.dart @@ -1,32 +1,46 @@ import 'package:fcs/pages/contact/contact_page.dart'; +import 'package:fcs/pages/main/model/main_model.dart'; import 'package:fcs/pages/term/term_page.dart'; -import 'package:fcs/pages/widgets/bottom_up_page_route.dart'; import 'package:fcs/pages/widgets/local_text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_icons/flutter_icons.dart'; +import 'package:provider/provider.dart'; class BottomWidgets extends StatelessWidget { @override Widget build(BuildContext context) { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - InkWell( - onTap: () { - Navigator.of(context) - .push(CupertinoPageRoute(builder: (context) => ContactPage())); - }, - child: _buildSmallButton( - context, "contact.btn", SimpleLineIcons.support), + var pkgInfo = Provider.of(context).packageInfo; + final versionBox = Text( + "v${pkgInfo.version}+${pkgInfo.buildNumber}", + style: TextStyle(color: Colors.white30), + ); + return Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + InkWell( + onTap: () { + Navigator.of(context).push( + CupertinoPageRoute(builder: (context) => ContactPage())); + }, + child: _buildSmallButton( + context, "contact.btn", SimpleLineIcons.support), + ), + InkWell( + onTap: () { + Navigator.of(context) + .push(CupertinoPageRoute(builder: (context) => TermPage())); + }, + child: _buildSmallButton(context, "term.btn", Icons.info_outline), + ), + ], ), - InkWell( - onTap: () { - Navigator.of(context) - .push(CupertinoPageRoute(builder: (context) => TermPage())); - }, - child: _buildSmallButton(context, "term.btn", Icons.info_outline), + Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: versionBox, ), ], ); diff --git a/lib/pages/widgets/multi_img_file.dart b/lib/pages/widgets/multi_img_file.dart index fb85cd4..70d7cb4 100644 --- a/lib/pages/widgets/multi_img_file.dart +++ b/lib/pages/widgets/multi_img_file.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:fcs/helpers/theme.dart'; +import 'package:fcs/pages/widgets/callbacks.dart'; import 'package:fcs/pages/widgets/right_left_page_rout.dart'; import 'package:fcs/pages/widgets/show_img.dart'; import 'package:fcs/pages/widgets/show_multiple_img.dart'; @@ -48,117 +49,142 @@ class _MultiImageFileState extends State { @override Widget build(BuildContext context) { - return Container( - height: 130, - width: 500, - child: ListView.separated( - separatorBuilder: (context, index) => Divider( - color: Colors.black, - ), - itemCount: - widget.enabled ? fileContainers.length + 1 : fileContainers.length, - scrollDirection: Axis.horizontal, - itemBuilder: (context, index) { - if (index == fileContainers.length) { - return InkWell( - onTap: () async { - bool camera = false, gallery = false; - await _dialog( - context, () => camera = true, () => gallery = true); - if (camera || gallery) { - var selectedFile = await ImagePicker().getImage( - source: camera ? ImageSource.camera : ImageSource.gallery, - imageQuality: 80, - maxWidth: 1000); - if (selectedFile != null) { - _fileAdded(DisplayImageSource(), File(selectedFile.path)); - } - } - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - width: 200, - height: 130, - decoration: BoxDecoration( - border: Border.all( - color: primaryColor, - width: 2.0, - ), - ), - child: Icon(SimpleLineIcons.plus), - ), - ), - ); - } else { - return InkWell( - onTap: () => Navigator.push( - context, - RightLeftPageRoute(ShowMultiImage( - displayImageSources: fileContainers, - initialPage: index, - ))), - child: Stack(alignment: Alignment.topLeft, children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - width: 200, - height: 130, - decoration: BoxDecoration( - border: Border.all( - color: primaryColor, - width: 2.0, - ), - ), - child: fileContainers[index].file == null - ? CachedNetworkImage( - width: 50, - height: 50, - imageUrl: fileContainers[index].url, - placeholder: (context, url) => Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - width: 30, - height: 30, - child: CircularProgressIndicator()), - ], - ), - errorWidget: (context, url, error) => - Icon(Icons.error), - ) - // Image.network(fileContainers[index].url, - // width: 50, height: 50) - : Image.file(fileContainers[index].file, - width: 50, height: 50), - ), - ), - widget.enabled - ? Positioned( - top: 0, - right: 0, - child: Container( - height: 50, + return Column( + children: [ + widget.enabled + ? Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + InkWell( + onTap: () => {_openImagePicker(false)}, + child: Stack( + children: [ + Container( width: 50, - child: IconButton( - icon: Icon( - Icons.close, - color: primaryColor, - ), - onPressed: () => - {_fileRemove(fileContainers[index])}), + height: 50, + child: Icon( + MaterialCommunityIcons.image, + color: primaryColor, + size: 35, + ), ), - ) - : Container(), - ]), - ); - } - }, - ), + Positioned( + right: 0, + top: 0, + child: actionIcon( + color: Colors.green, iconData: Icons.add)) + ], + ), + ), + InkWell( + onTap: () => {_openImagePicker(true)}, + child: Stack( + children: [ + Container( + width: 50, + height: 50, + child: Icon( + MaterialCommunityIcons.camera, + color: primaryColor, + size: 35, + ), + ), + Positioned( + right: 0, + top: 0, + child: actionIcon( + color: Colors.green, iconData: Icons.add)) + ], + ), + ), + ], + ) + : Container(), + Container( + height: 100, + child: ListView.separated( + separatorBuilder: (context, index) => Divider( + color: Colors.black, + ), + itemCount: fileContainers.length, + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + return InkWell( + onTap: () => Navigator.push( + context, + RightLeftPageRoute(ShowMultiImage( + displayImageSources: fileContainers, + initialPage: index, + ))), + child: Stack(alignment: Alignment.topLeft, children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + width: 100, + height: 100, + decoration: BoxDecoration( + border: Border.all( + color: primaryColor, + width: 1.0, + ), + ), + child: fileContainers[index].file == null + ? CachedNetworkImage( + fit: BoxFit.cover, + width: 50, + height: 50, + imageUrl: fileContainers[index].url, + placeholder: (context, url) => Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + width: 30, + height: 30, + child: CircularProgressIndicator()), + ], + ), + errorWidget: (context, url, error) => + Icon(Icons.error), + ) + : FittedBox( + fit: BoxFit.cover, + child: Image.file( + fileContainers[index].file, + ), + ), + ), + ), + widget.enabled + ? Positioned( + top: 10, + right: 0, + child: actionIcon( + color: Colors.red, + iconData: Icons.remove, + onTap: () => + {_fileRemove(fileContainers[index])}), + ) + : Container(), + ]), + ); + }, + ), + ), + ], ); } + _openImagePicker(bool camera) async { + var selectedFile = await ImagePicker().getImage( + source: camera ? ImageSource.camera : ImageSource.gallery, + imageQuality: 80, + maxWidth: 1000); + if (selectedFile != null) { + _fileAdded(DisplayImageSource(), File(selectedFile.path)); + } + } + _fileAdded(DisplayImageSource fileContainer, File selectedFile) { fileContainer.file = selectedFile; setState(() { @@ -281,4 +307,21 @@ class _MultiImageFileState extends State { }, ); } + + Widget actionIcon({OnTap onTap, Color color, IconData iconData}) { + return InkWell( + onTap: onTap, + child: ClipOval( + child: Container( + color: color, + height: 20, + width: 20, + child: Icon( + iconData, + color: Colors.white, + size: 15, + )), + ), + ); + } } diff --git a/pubspec.yaml b/pubspec.yaml index a4fcf54..3e93c9f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: fcs description: FCS Logistics publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 1.0.0+4 +version: 1.0.5+7 environment: sdk: ">=2.7.0 <3.0.0"