Files
flutter_wisetronic/lib/utils/util_io.dart

560 lines
18 KiB
Dart

import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:cached_network_image/cached_network_image.dart';
import 'package:dio/dio.dart';
// import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:hive/hive.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import '../constants.dart';
import '../events/eventbus.dart';
import '../events/events.dart';
import '../generated/l10n.dart';
import '../models/comment.dart';
import '../models/order.dart';
import '../models/payment_platform.dart';
import '../models/user.dart';
import '../routes.dart';
import '../store/actions.dart';
import '../store/store.dart';
import '../widgets/general/e_transfer_pay.dart';
import 'http_util.dart';
import 'utils.dart';
typedef void OnGotFile(int imageId, String filePath);
class Util {
static final Util _util = Util._internal();
factory Util() {
return _util;
}
Util._internal();
// final FirebaseMessaging firebaseMessaging = FirebaseMessaging();
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();
static bool notificationTapped = false;
init() {
// initLocalNotification();
// initFirebaseMessaging();
// ePmqRwRUTmKuFNfbHA-6zq:APA91bEFEQx1YgJqfx0V0VYo86uRDGjG6SP1SPCAZW4OvQ7gMOeKWDQ47bfuEM00YavtKq7ZGpsWfFL7B3ypm00ZA6crjJJLK_-j_H8bS_dnQbLFwyRcW67IXCs5sRkro71bRZv7L1WM
// eventBus.on<SubscribeToTopic>().listen((event) {
// if (firebaseMessaging != null) {
// firebaseMessaging.subscribeToTopic(event.topic);
// }
// });
// eventBus.on<UnSubscribeToTopic>().listen((event) {
// if (firebaseMessaging != null) {
// firebaseMessaging.unsubscribeFromTopic(event.topic);
// }
// });
}
initLocalNotification() async {
var initializationSettingsAndroid = new AndroidInitializationSettings('ic_launcher');
var initializationSettingsIOS = new IOSInitializationSettings(
onDidReceiveLocalNotification: onDidReceiveLocalNotification);
var initializationSettings = new InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: onSelectNotification);
}
Future onSelectNotification(String payload, {bool replace=false}) async {
print('payload: $payload');
if (payload != null && payload.isNotEmpty) {
Routes.router.navigateTo(store.state.context!, payload, replace: replace);
}
}
// initFirebaseMessaging() {
// if (Platform.isIOS) {
// iosPermission();
// }
// firebaseMessaging.getToken().then((token) {
// print('FCM token: $token');
// store.dispatch(UpdateFcmToken(token));
// });
// firebaseMessaging.configure(
// onMessage: (Map<String, dynamic> message) {
// print('FCM onMessage: $message');
// // eventBus.fire(OnFcmReceived(message));
// showNotificationWithDefaultSound(message);
// return;
// },
// onBackgroundMessage: Platform.isIOS ? null : backgroundMessageHandler,
// onResume: (Map<String, dynamic> message) {
// print('FCM onResume: $message');
// if (Platform.isAndroid) {
// if (message != null && message['data'] != null && message['data']['route'] != null) {
// notificationTapped = true;
// onSelectNotification(message['data']['route']);
// }
// } else {
// if (message != null && message['route'] != null) {
// notificationTapped = true;
// onSelectNotification(message['route']);
// }
// }
// return;
// },
// onLaunch: (Map<String, dynamic> message) {
// print('FCM onLaunch: $message');
// if (Platform.isAndroid) {
// if (message != null && message['data'] != null && message['data']['route'] != null) {
// notificationTapped = true;
// onSelectNotification(message['data']['route'], replace: true);
// }
// } else {
// if (message != null && message['route'] != null) {
// notificationTapped = true;
// onSelectNotification(message['route'], replace: true);
// }
// }
// return;
// },
// );
// }
Future onDidReceiveLocalNotification(int id, String title, String body, String payload) async {
showDialog(
context: store.state.context!,
builder: (BuildContext context) => CupertinoAlertDialog(
title: Text(title),
content: Text(body),
actions: [
CupertinoDialogAction(
isDefaultAction: true,
child: Text(S.of(context).ok),
onPressed: () async {
Navigator.of(context, rootNavigator: true).pop();
if (payload != null && payload.isNotEmpty) {
Routes.router.navigateTo(context, payload);
}
},
)
],
),
);
}
Future showNotificationWithDefaultSound(Map<String, dynamic> message) async {
var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
'channelId',
'channelName',
'channelDescription',
importance: Importance.max,
priority: Priority.high,
);
var iOSPlatformChannelSpecifics = new IOSNotificationDetails(presentSound: true, badgeNumber: 1);
var platformChannelSpecifics = new NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: iOSPlatformChannelSpecifics,
);
await flutterLocalNotificationsPlugin.show(
0,
Platform.isAndroid ? message['notification']['title'] : message['title'],
Platform.isAndroid ? message['notification']['body'] : message['body'],
platformChannelSpecifics,
payload: Platform.isAndroid ? message['data']['route'] : message['route'],
);
}
// iosPermission() {
// firebaseMessaging.requestNotificationPermissions(
// const IosNotificationSettings(
// sound: true,
// badge: true,
// alert: true,
// )
// );
// firebaseMessaging.onIosSettingsRegistered.listen((IosNotificationSettings settings) {
// print('IOS settings registered: $settings');
// });
// }
static Future<dynamic> backgroundMessageHandler(Map<String, dynamic> message) {
print('FCM background message handler: $message');
return Future<void>.value();
}
static Future<Box> getBox() async {
final dir = await getApplicationDocumentsDirectory();
Hive.init(dir.path);
Box box = await Hive.openBox('app_data');
return box;
}
static Widget showImage(String imageUrl, {double? width, double? height,
BoxFit? fit, Widget Function(BuildContext, String, dynamic)? errorWidget}) {
if (imageUrl != null && imageUrl.isNotEmpty && imageUrl.startsWith('https:')) {
return CachedNetworkImage(
imageUrl: imageUrl,
width: width,
height: width,
fit: fit,
placeholder: (context, url) => Utils.imageLoadingIndicator(width: width!, height: height!),
errorWidget: errorWidget != null ? errorWidget : (context, url, error) {
return Image.asset(
'assets/images/not_found.png',
width: width,
height: height,
fit: fit,
);
},
);
} else if (imageUrl != null && imageUrl.isNotEmpty) {
return Image.file(
File(imageUrl),
width: width,
height: height,
fit: fit,
errorBuilder: (BuildContext context, Object object, StackTrace stackTrace) {
return Image.asset(
'assets/images/not_found.png',
width: width,
height: height,
fit: fit,
);
},
);
} else {
return Image.asset(
'assets/images/not_found.png',
width: width,
height: height,
fit: fit,
);
}
}
static void openWebUrl(BuildContext context, String link) {
Routes.router.navigateTo(context, '/webview/$link');
}
AlertDialog getPicture(BuildContext context, User user, {int commentId = -1, int orderId = 0}) {
return AlertDialog(
title: Text(
S.of(context).get_picture,
),
content: Container(
height: 130.0,
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 12.0),
child: Text(
S.of(context).get_picture_from,
style: TextStyle(
fontSize: 15.0,
color: Colors.black26,
),
),
),
Container(
child: TextButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(
Icons.photo_library,
),
Container(
margin: EdgeInsets.only(left: 5.0),
child: Text(
S.of(context).gallery,
),
),
],
),
onPressed: () {
getPictureFromGallery(context, user, commentId: commentId, orderId: orderId);
},
),
),
Container(
child: TextButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(
Icons.photo_camera,
),
Container(
margin: EdgeInsets.only(left: 5.0),
child: Text(
S.of(context).camera,
),
),
],
),
onPressed: () {
getPictureFromCamera(context, user, commentId: commentId, orderId: orderId);
},
),
)
],
),
),
);
}
void getPictureFromGallery(BuildContext context, User user, {int commentId = -1, int orderId = 0}) async {
final picker = ImagePicker();
var image = await picker.pickImage(source: ImageSource.gallery);
Navigator.of(context).pop();
uploadPicture(context, File(image!.path), user, commentId: commentId, orderId: orderId);
}
void getPictureFromCamera(BuildContext context, User user, {int commentId = -1, int orderId = 0}) async {
final picker = ImagePicker();
var image = await picker.pickImage(source: ImageSource.camera);
Navigator.of(context).pop();
uploadPicture(context, File(image!.path), user, commentId: commentId, orderId: orderId);
}
void uploadPicture(BuildContext context, File image, User user, {int commentId = -1, int orderId = 0}) async {
if (await image.exists()) {
print('image: ${image.path}');
String imageName = basename(image.path);
MultipartFile imageFile = await MultipartFile.fromFile(image.path, filename: imageName);
Map<String, dynamic> 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(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).get_picture,
),
content: Container(
height: 130.0,
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 12.0),
child: Text(
S.of(context).get_picture_from,
style: TextStyle(
fontSize: 15.0,
color: Colors.black26,
),
),
),
Container(
child: TextButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(
Icons.photo_library,
),
Container(
margin: EdgeInsets.only(left: 5.0),
child: Text(
S.of(context).gallery,
),
),
],
),
onPressed: () {
getPictureFromGallery2(context, imageId, onGotFile);
},
),
),
Container(
child: TextButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(
Icons.photo_camera,
),
Container(
margin: EdgeInsets.only(left: 5.0),
child: Text(
S.of(context).camera,
),
),
],
),
onPressed: () {
getPictureFromCamera2(context, imageId, onGotFile);
},
),
)
],
),
),
);
}
void getPictureFromGallery2(BuildContext context, int imageId, OnGotFile onGotFile) async {
ImagePicker picker = ImagePicker();
var image = await picker.pickImage(source: ImageSource.gallery);
Navigator.of(context).pop();
onGotFile(imageId, image!.path);
}
void getPictureFromCamera2(BuildContext context, int imageId, OnGotFile onGotFile) async {
ImagePicker picker = ImagePicker();
var image = await picker.pickImage(source: ImageSource.camera);
Navigator.of(context).pop();
onGotFile(imageId, image!.path);
}
Future<void> createTicket(BuildContext context, String msg, List<Map<String, dynamic>> 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) {
String imageName = basename(imagePath);
formData.files.add(
MapEntry(
"files",
MultipartFile.fromFileSync(imagePath, filename: imageName)
)
);
}
}
HttpUtil.httpPost('create-new-ticket-app/', (response) {
if (onSuccess != null) {
onSuccess(response);
}
},
isFormData: true,
// body: null,
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);
}
});
}
Widget getNativePay(BuildContext context, Order order, PaymentPlatform paymentPlatform) {
// Native (Apple/Google) pay removed with Stripe. Web uses e-Transfer.
return SizedBox.shrink();
}
static void goPayment(BuildContext context, Order order,
PaymentPlatform paymentPlatform, {
bool googlePay=false,
bool applePay=false,
}) {
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_NATIVE_PAY:
// Native (Apple/Google) pay removed with Stripe; route to e-Transfer.
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (BuildContext context) {
return ETransferPay(order: order);
}
));
break;
case Constants.PAYMENT_METHOD_CODE_STRIPE:
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (BuildContext context) {
return ETransferPay(order: order);
}
));
break;
}
}
static Future<Uint8List> getBytesFromAsset(String path, int width) async {
ByteData data = await rootBundle.load(path);
ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(), targetWidth: width);
ui.FrameInfo fi = await codec.getNextFrame();
return (await fi.image.toByteData(format: ui.ImageByteFormat.png))!.buffer.asUint8List();
}
}