import 'dart:html'; import 'dart:typed_data'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:hive/hive.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:url_launcher/url_launcher.dart'; import '../constants.dart'; import '../events/eventbus.dart'; import '../events/events.dart'; import '../generated/l10n.dart'; import '../models/comment.dart' as mComment; import '../models/order.dart'; import '../models/payment_platform.dart'; import '../models/stripe_payment_method.dart'; import '../models/user.dart'; import '../store/actions.dart'; import '../store/store.dart'; import '../pages/stripe_pay_web.dart'; import 'http_util.dart'; import 'utils.dart'; typedef void OnGotFile(int imageId, String filePath); class Util { static final Util _instance = Util._internal(); factory Util() { return _instance; } Util._internal(); init() { } static Future getBox() async { Hive.initFlutter(); Box box = await Hive.openBox('wisetronic_app_data'); return box; } static Widget showImage(String imageUrl, {double width, double height, BoxFit fit, Widget Function(BuildContext, String, dynamic) errorWidget}) { return Image.network(imageUrl, fit: fit, width: width, height: height, cacheWidth: width != null ? width.round() : null, cacheHeight: height != null ? height.round() : null, loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent loadingProgress) { if (loadingProgress == null) return child; return Center( child: Utils.imageLoadingIndicator(), ); }, errorBuilder: (BuildContext context, Object object, StackTrace stackTrace) { print('StackTrace: $stackTrace'); if (errorWidget != null) { return errorWidget(context, null, null); } return Image.asset( 'assets/images/not_found.png', width: width, height: height, fit: fit, ); }, ); } static void openWebUrl(BuildContext context, String link) async { var url = 'https://${link}'; if (await canLaunch(url)) { await launch('$url'); } else { print('Could not launch $url'); } } AlertDialog getPicture(BuildContext context, User user, {int commentId = -1, int orderId = 0}) { return AlertDialog( title: Text(S.of(context).please_select), content: Text(S.of(context).please_select_an_image), actions: [ TextButton( child: Text(S.of(context).cancel), onPressed: () { Navigator.of(context).pop(); }, ), TextButton( child: Text(S.of(context).select, style: TextStyle(color: Colors.white),), style: TextButton.styleFrom( backgroundColor: Theme.of(context).primaryColor, ), onPressed: () { Navigator.of(context).pop(); startFilePicker(context, user, commentId: commentId, orderId: orderId); }, ), ], ); } void startFilePicker(BuildContext context, User user, {int commentId = -1, int orderId = 0}) async { InputElement uploadInput = FileUploadInputElement(); uploadInput.click(); uploadInput.onChange.listen((e) { final files = uploadInput.files; if (files.length >= 1) { final File file = files[0]; final FileReader reader = new FileReader(); reader.onLoadEnd.listen((e) { uploadPicture(context, reader.result, file.name, user, commentId: commentId, orderId: orderId); }); reader.onError.listen((e) { Fluttertoast.showToast( msg: S.of(context).error_read_file, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, backgroundColor: Colors.black54, textColor: Colors.white ); }); reader.readAsArrayBuffer(file); } }); } void uploadPicture(BuildContext context, Uint8List fileBytes, String fileName, User user, {int commentId = -1, int orderId = 0}) { MultipartFile imageFile = MultipartFile.fromBytes(fileBytes, filename: fileName); Map formMap = { 'id': user.id, 'file': imageFile, }; if (commentId >= 0) { formMap = { 'contact_id': user.id, 'comment_id': commentId, 'order_id': orderId, 'file': imageFile, }; HttpUtil.httpPost( 'v1/upload-comment-image', (response) { eventBus.fire(new OnCommentUpdatedEvent(mComment.Comment.fromJson(response.data))); }, isFormData: true, body: formMap, sendProgress: (int sent, int total) { if (sent == total) { eventBus.fire(OnUploadCommentImageProgressEvent(false, 0.0)); } else { eventBus.fire(OnUploadCommentImageProgressEvent(true, sent / total)); } }, ).catchError((error) { Utils.showMessageDialog(context, error); }); } else { HttpUtil.httpPost( 'v1/upload-avatar', (response) { store.dispatch(new UpdateCurrentUser(User.fromJson(response.data))); eventBus.fire(new OnCurrentUserUpdated()); }, isFormData: true, body: formMap, sendProgress: (int sent, int total) { if (sent == total) { eventBus.fire(OnProgressEvent(false, 0.0)); } else { eventBus.fire(OnProgressEvent(true, sent / total)); } }, ).catchError((error) { Utils.showMessageDialog(context, error); }); } } AlertDialog getPicture2(BuildContext context, int imageId, OnGotFile onGotFile) { return AlertDialog( title: Text(S.of(context).please_select), content: Text(S.of(context).please_select_an_image), actions: [ TextButton( child: Text(S.of(context).cancel), onPressed: () { Navigator.of(context).pop(); }, ), TextButton( child: Text(S.of(context).select, style: TextStyle(color: Colors.white),), style: TextButton.styleFrom( backgroundColor: Theme.of(context).primaryColor, ), onPressed: () { Navigator.of(context).pop(); startFilePicker2(context, imageId, onGotFile); }, ), ], ); } void startFilePicker2(BuildContext context, int imageId, OnGotFile onGotFile) async { final _image = await WebImagePicker().pickImage(); onGotFile(imageId, _image.dataScheme); } void createTicket(BuildContext context, String msg, List> images, OnSuccess onSuccess, OnError onError, {int id}) { var formData = FormData(); formData.fields.add(MapEntry("msg", msg)); formData.fields.add(MapEntry('id', id == null ? '0' : id.toString())); for (int i = 0; i < images.length; i++) { String imagePath = images[i]['path']; if (imagePath.isNotEmpty) { // (formMap['images'] as List).add(imagePath); formData.fields.add(MapEntry('images', imagePath)); } } HttpUtil.httpPost('create-new-ticket-web/', (response) { if (onSuccess != null) { onSuccess(response); } }, isFormData: true, // body: formMap, formData: formData, sendProgress: (int sent, int total) { if (sent == total) { eventBus.fire(OnSubmitProgressEvent(false, 100.0)); } else { eventBus.fire(OnSubmitProgressEvent(true, sent / total * 100.0)); } }, businessId: Constants.BUSINESS_ID, ).catchError((error) { if (onError != null) { onError(error); } }); } static void goPayment(BuildContext context, Order order, PaymentPlatform paymentPlatform, { bool googlePay=false, bool applePay=false, StripePaymentMethod stripePaymentMethod, }) { switch(paymentPlatform.code) { case Constants.PAYMENT_METHOD_CODE_SQUARE: break; case Constants.PAYMENT_METHOD_CODE_CHASE: break; case Constants.PAYMENT_METHOD_CODE_PAYPAL: break; case Constants.PAYMENT_METHOD_CODE_OTT_ALIPAY: break; case Constants.PAYMENT_METHOD_CODE_OTT_WECHATPAY: break; case Constants.PAYMENT_METHOD_CODE_POD: break; case Constants.PAYMENT_METHOD_CODE_STRIPE: Navigator.pushReplacement(context, MaterialPageRoute( builder: (BuildContext context) { return StripePayWeb(order, paymentPlatform, stripePaymentMethod: stripePaymentMethod,); } )); break; } } Widget getNativePay(BuildContext context, Order order, PaymentPlatform paymentPlatform) { return SizedBox.shrink(); } static Future getBytesFromAsset(String path, int width) async { return Uint8List(0); } } class ImageInfo { String name; String data; String dataScheme; String path; } class WebImagePicker { Future pickImage() async { print('pickImage'); final ImageInfo data = ImageInfo(); final FileUploadInputElement input = FileUploadInputElement(); document.body.children.add(input); input..accept = 'image/*'; input.click(); await input.onChange.first; if (input.files.isEmpty) return null; final reader = FileReader(); reader.readAsDataUrl(input.files[0]); await reader.onLoad.first; final encoded = reader.result as String; // remove data:image/*;base64 preambule final stripped = encoded.replaceFirst(RegExp(r'data:image/[^;]+;base64,'), ''); //final imageBase64 = base64.decode(stripped); final imageName = input.files?.first?.name; final imagePath = input.files?.first?.relativePath; data.name = imageName; data.data = stripped; data.dataScheme = encoded; data.path = imagePath; return data; } }