diff --git a/lib/ui/screens/items_for_sale/fragments/add_details_fragment.dart b/lib/ui/screens/items_for_sale/fragments/add_details_fragment.dart index 5e3f749..75d1da2 100644 --- a/lib/ui/screens/items_for_sale/fragments/add_details_fragment.dart +++ b/lib/ui/screens/items_for_sale/fragments/add_details_fragment.dart @@ -18,7 +18,7 @@ import 'package:mohem_flutter_app/ui/screens/items_for_sale/fragments/select_cat import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/button/simple_button.dart'; import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart'; -import 'package:mohem_flutter_app/widgets/image_picker.dart'; +import 'package:mohem_flutter_app/widgets/image_picker.dart' as imagePicker; import 'package:mohem_flutter_app/widgets/radio/show_radio.dart'; class AddItemDetailsFragment extends StatefulWidget { @@ -200,14 +200,22 @@ class _AddItemDetailsFragmentState extends State { children: [ title.toText16().expanded, 6.width, - SimpleButton(LocaleKeys.add.tr(), () { - ImageOptions.showImageOptionsNew(context, false, (String image, File file) { - setState(() { - images.add(image); - Navigator.of(context).pop(); - }); - }); - }, fontSize: 14), + SimpleButton( + LocaleKeys.add.tr(), + () { + if (images.length < 3) { + imagePicker.ImageOptions.showImageOptionsNew(context, false, (String image, File file) { + setState(() { + images.add(image); + Navigator.of(context).pop(); + }); + }); + } else { + Utils.showToast("The maximum no. of images allowed is 3."); + } + }, + fontSize: 14, + ), ], ), if (images.isNotEmpty) 12.height, diff --git a/lib/ui/screens/items_for_sale/item_for_sale_detail.dart b/lib/ui/screens/items_for_sale/item_for_sale_detail.dart index ee76943..ce1809a 100644 --- a/lib/ui/screens/items_for_sale/item_for_sale_detail.dart +++ b/lib/ui/screens/items_for_sale/item_for_sale_detail.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:carousel_slider/carousel_slider.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; @@ -24,6 +25,7 @@ class ItemForSaleDetailPage extends StatefulWidget { class _ItemForSaleDetailPageState extends State { late GetItemsForSaleList getItemsForSaleList; + int _current = 0; @override Widget build(BuildContext context) { @@ -46,15 +48,32 @@ class _ItemForSaleDetailPageState extends State { transitionOnUserGestures: true, child: AspectRatio( aspectRatio: 322 / 261, - child: ClipRRect( - borderRadius: BorderRadius.circular(6), - child: Image.memory( - base64Decode(getItemsForSaleList.itemAttachments![0].content!), - fit: BoxFit.cover, - ), + child: CarouselSlider( + items: getItemImages(), + options: CarouselOptions( + enableInfiniteScroll: false, + onPageChanged: (index, reason) { + setState(() { + _current = index; + }); + }), ), ), ).paddingAll(8), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: getItemImages().asMap().entries.map((entry) { + return Container( + width: 8.0, + height: 8.0, + margin: const EdgeInsets.symmetric(horizontal: 4.0), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: (Theme.of(context).brightness == Brightness.dark ? Colors.white : Colors.black).withOpacity(_current == entry.key ? 0.9 : 0.4), + ), + ); + }).toList(), + ), Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -111,4 +130,23 @@ class _ItemForSaleDetailPageState extends State { ), ); } + + List getItemImages() { + List itemImages = []; + getItemsForSaleList.itemAttachments!.forEach((element) { + itemImages.add( + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: ClipRRect( + borderRadius: BorderRadius.circular(6), + child: Image.memory( + base64Decode(element.content!), + fit: BoxFit.cover, + ), + ), + ), + ); + }); + return itemImages; + } } diff --git a/lib/widgets/Updater.dart b/lib/widgets/Updater.dart index 82cc172..3042dbb 100644 --- a/lib/widgets/Updater.dart +++ b/lib/widgets/Updater.dart @@ -1,18 +1,20 @@ /* ZiK */ import 'dart:async'; + import 'package:flutter/cupertino.dart'; typedef ChildProvider = Widget Function(BuildContext context, E? data); -class Updater extends StatelessWidget{ +class Updater extends StatelessWidget { final ChildProvider childProvider; StreamController? sink; T? initialData; List _history = []; Stream? _stream; - Updater({T? initialData, required this.childProvider}){ + + Updater({T? initialData, required this.childProvider}) { this.sink = StreamController(); this.initialData = initialData; _stream = this.sink?.stream; @@ -23,17 +25,17 @@ class Updater extends StatelessWidget{ return StreamBuilder( initialData: this.initialData, stream: _stream, - builder: (ctx, snapshot){ - return childProvider(context, snapshot.data); - }); + builder: (ctx, snapshot) { + return childProvider(context, snapshot.data); + }); } void pushData(T? data) { _history.add(data); sink?.sink.add(data); } - + List getDataHistory() => _history; - T? getLatestData() => _history.last; -} \ No newline at end of file + T? getLatestData() => _history.last; +} diff --git a/lib/widgets/app_bar_widget.dart b/lib/widgets/app_bar_widget.dart index 1096f24..6f9898e 100644 --- a/lib/widgets/app_bar_widget.dart +++ b/lib/widgets/app_bar_widget.dart @@ -1,13 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; -import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; -import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; -import 'package:provider/provider.dart'; AppBar AppBarWidget(BuildContext context, {required String title, diff --git a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart index b20674e..d810457 100644 --- a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart +++ b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart @@ -1,5 +1,3 @@ -import 'dart:convert'; - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -26,7 +24,6 @@ import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart'; import 'package:provider/provider.dart'; -import 'package:pull_to_refresh/pull_to_refresh.dart'; class SearchEmployeeBottomSheet extends StatefulWidget { int? notificationID; @@ -243,11 +240,11 @@ class _SearchEmployeeBottomSheetState extends State { children: [ Stack( children: [ - SvgPicture.asset( - "assets/images/user.svg", - height: 48, - width: 48, - ), + SvgPicture.asset( + "assets/images/user.svg", + height: 48, + width: 48, + ), Positioned( right: 5, bottom: 1, @@ -307,13 +304,7 @@ class _SearchEmployeeBottomSheetState extends State { ).onPress( () { if (provider.chatUsersList![index].isFav == null || provider.chatUsersList![index].isFav == false) { - provider - .favoriteUser( - userID: AppState().chatDetails!.response!.id!, - targetUserID: provider.chatUsersList![index].id!, - fromSearch: true - ) - .then((value) { + provider.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: provider.chatUsersList![index].id!, fromSearch: true).then((value) { setState(() {}); }); } else if (provider.chatUsersList![index].isFav == true) { @@ -326,13 +317,7 @@ class _SearchEmployeeBottomSheetState extends State { setState(() {}); }); } else { - provider - .favoriteUser( - userID: AppState().chatDetails!.response!.id!, - targetUserID: provider.chatUsersList![index].id!, - fromSearch: true - ) - .then((value) { + provider.favoriteUser(userID: AppState().chatDetails!.response!.id!, targetUserID: provider.chatUsersList![index].id!, fromSearch: true).then((value) { setState(() {}); }); } diff --git a/lib/widgets/button/default_button.dart b/lib/widgets/button/default_button.dart index 71de642..338a13d 100644 --- a/lib/widgets/button/default_button.dart +++ b/lib/widgets/button/default_button.dart @@ -5,8 +5,7 @@ import 'package:mohem_flutter_app/classes/colors.dart'; extension WithContainer on Widget { Widget get insideContainer => Container( color: Colors.white, - padding: - const EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + padding: const EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), child: this, ); } @@ -76,8 +75,7 @@ class DefaultButton extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ if (iconData != null) Icon(iconData, color: textColor), - if (svgIcon != null) - SvgPicture.asset(svgIcon ?? "", color: textColor), + if (svgIcon != null) SvgPicture.asset(svgIcon ?? "", color: textColor), if (!isTextExpanded) Padding( padding: EdgeInsets.only( diff --git a/lib/widgets/chat_app_bar_widge.dart b/lib/widgets/chat_app_bar_widge.dart index 25ed34c..cc252ec 100644 --- a/lib/widgets/chat_app_bar_widge.dart +++ b/lib/widgets/chat_app_bar_widge.dart @@ -7,7 +7,6 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; -import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; import 'package:provider/provider.dart'; AppBar ChatAppBarWidget(BuildContext context, diff --git a/lib/widgets/dialogs/dialogs.dart b/lib/widgets/dialogs/dialogs.dart index debb147..6765e38 100644 --- a/lib/widgets/dialogs/dialogs.dart +++ b/lib/widgets/dialogs/dialogs.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -void showMDialog(context, {Widget? child,Color? backgroundColor,bool isDismissable=true}) async { +void showMDialog(context, {Widget? child, Color? backgroundColor, bool isDismissable = true}) async { return showDialog( context: context, barrierDismissible: isDismissable, diff --git a/lib/widgets/dynamic_forms/dynamic_textfield_widget.dart b/lib/widgets/dynamic_forms/dynamic_textfield_widget.dart index ec4146b..cc710fe 100644 --- a/lib/widgets/dynamic_forms/dynamic_textfield_widget.dart +++ b/lib/widgets/dynamic_forms/dynamic_textfield_widget.dart @@ -68,7 +68,9 @@ class DynamicTextFieldWidget extends StatelessWidget { enabled: isEnable, scrollPadding: EdgeInsets.zero, readOnly: isReadOnly, - keyboardType: (isInputTypeNum) ? (isInputTypeNumSigned ? const TextInputType.numberWithOptions(signed: true, decimal: true) : TextInputType.numberWithOptions(signed: true, decimal: true)) : TextInputType.text, + keyboardType: (isInputTypeNum) + ? (isInputTypeNumSigned ? const TextInputType.numberWithOptions(signed: true, decimal: true) : TextInputType.numberWithOptions(signed: true, decimal: true)) + : TextInputType.text, textInputAction: TextInputAction.done, //controller: controller, maxLines: lines, diff --git a/lib/widgets/image_picker.dart b/lib/widgets/image_picker.dart index 834695b..ef04f84 100644 --- a/lib/widgets/image_picker.dart +++ b/lib/widgets/image_picker.dart @@ -45,7 +45,19 @@ class ImageOptions { onFilesTap: () async { FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.custom, - allowedExtensions: ['jpg', 'jpeg ', 'pdf', 'txt', 'docx', 'doc', 'pptx', 'xlsx', 'png', 'rar', 'zip',], + allowedExtensions: [ + 'jpg', + 'jpeg ', + 'pdf', + 'txt', + 'docx', + 'doc', + 'pptx', + 'xlsx', + 'png', + 'rar', + 'zip', + ], ); List files = result!.paths.map((path) => File(path!)).toList(); image(result.files.first.path.toString(), files.first); @@ -54,67 +66,68 @@ class ImageOptions { ); } - static void showImageOptions(BuildContext context, Function(String, File) image) { - showModalBottomSheet( - backgroundColor: Colors.transparent, - context: context, - builder: (BuildContext bc) { - return _BottomSheet( - children: [ - _BottomSheetItem( - title: "Select File Source", - onTap: () {}, - icon: Icons.file_present, - color: MyColors.black, - ), - _BottomSheetItem( - title: "Gallery", - icon: Icons.image, - onTap: () async { - if (Platform.isAndroid) { - galleryImageAndroid(image); - } else { - File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 10))?.path ?? ""); - String fileName = _image.path; - var bytes = File(fileName).readAsBytesSync(); - String base64Encode = base64.encode(bytes); - if (base64Encode != null) { - image(base64Encode, _image); - } - } - }, - ), - _BottomSheetItem( - title: "Camera", - icon: Icons.camera_alt, - onTap: () async { - if (Platform.isAndroid) { - cameraImageAndroid(image); - } else { - File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 10))?.path ?? ""); - String fileName = _image.path; - var bytes = File(fileName).readAsBytesSync(); - String base64Encode = base64.encode(bytes); - if (base64Encode != null) { - image(base64Encode, _image); - } - } - }, - ), - _BottomSheetItem( - title: "Cancel", - onTap: () {}, - icon: Icons.cancel, - color: MyColors.redColor, - ) - ], - ); - }); - } +// static void showImageOptions(BuildContext context, Function(String, File) image) { +// showModalBottomSheet( +// backgroundColor: Colors.transparent, +// context: context, +// builder: (BuildContext bc) { +// return _BottomSheet( +// children: [ +// _BottomSheetItem( +// title: "Select File Source", +// onTap: () {}, +// icon: Icons.file_present, +// color: MyColors.black, +// ), +// _BottomSheetItem( +// title: "Gallery", +// icon: Icons.image, +// onTap: () async { +// if (Platform.isAndroid) { +// galleryImageAndroid(image); +// } else { +// File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 10))?.path ?? ""); +// String fileName = _image.path; +// var bytes = File(fileName).readAsBytesSync(); +// String base64Encode = base64.encode(bytes); +// if (base64Encode != null) { +// image(base64Encode, _image); +// } +// } +// }, +// ), +// _BottomSheetItem( +// title: "Camera", +// icon: Icons.camera_alt, +// onTap: () async { +// if (Platform.isAndroid) { +// cameraImageAndroid(image); +// } else { +// File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 10))?.path ?? ""); +// String fileName = _image.path; +// var bytes = File(fileName).readAsBytesSync(); +// String base64Encode = base64.encode(bytes); +// if (base64Encode != null) { +// image(base64Encode, _image); +// } +// } +// }, +// ), +// _BottomSheetItem( +// title: "Cancel", +// onTap: () {}, +// icon: Icons.cancel, +// color: MyColors.redColor, +// ) +// ], +// ); +// }); +// } } void galleryImageAndroid(Function(String, File) image) async { File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 20))?.path ?? ""); + String fileName = _image.path; var bytes = File(fileName).readAsBytesSync(); String base64Encode = base64.encode(bytes); diff --git a/lib/widgets/mark_attendance_widget.dart b/lib/widgets/mark_attendance_widget.dart index d6d111a..7c7e672 100644 --- a/lib/widgets/mark_attendance_widget.dart +++ b/lib/widgets/mark_attendance_widget.dart @@ -164,7 +164,6 @@ class _MarkAttendanceWidgetState extends State { } else { performWifiAttendance(widget.model); } - // connectWifi(); }), if (isQrEnabled) attendanceMethod("QR", "assets/images/ic_qr.svg", isQrEnabled, () async { diff --git a/lib/widgets/otp_widget.dart b/lib/widgets/otp_widget.dart index e90308d..7994b1e 100644 --- a/lib/widgets/otp_widget.dart +++ b/lib/widgets/otp_widget.dart @@ -108,7 +108,7 @@ class OTPWidgetState extends State with SingleTickerProviderStateMixi } } - void calculateStrList() { + void calculateStrList() { if (strList.length > widget.maxLength) { strList.length = widget.maxLength; } diff --git a/lib/widgets/qr_scanner_dialog.dart b/lib/widgets/qr_scanner_dialog.dart index 1889616..11e2601 100644 --- a/lib/widgets/qr_scanner_dialog.dart +++ b/lib/widgets/qr_scanner_dialog.dart @@ -1,9 +1,8 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; -import 'package:qr_code_scanner/qr_code_scanner.dart'; - import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:qr_code_scanner/qr_code_scanner.dart'; class QrScannerDialog extends StatefulWidget { @override diff --git a/pubspec.yaml b/pubspec.yaml index cd264ad..138fb63 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 3.2.6+300026 +version: 3.2.8+300028 environment: sdk: ">=2.16.0 <3.0.0" @@ -107,6 +107,9 @@ dependencies: huawei_push: ^6.7.0+300 firebase_crashlytics: ^2.9.0 + #Items for sale Image Carousel Slider + carousel_slider: ^4.2.1 + dependency_overrides: firebase_core_platform_interface: 4.5.1