import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:another_flushbar/flushbar.dart'; import 'package:http/io_client.dart'; import 'package:in_app_update/in_app_update.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:location/location.dart'; import 'package:permission_handler/permission_handler.dart' as pHandler; import 'keys.dart'; import 'package:oauth2/oauth2.dart' as oauth2; import '../main.dart'; class Util{ bool tokenValidity = true; bool useLocal = false; showLoading(context,{dissmissable=false,onwillpop}){ showDialog( context: context, builder: (BuildContext context) { return WillPopScope( onWillPop: onwillpop??()async{return true;}, child: const Center( child: CircularProgressIndicator(), ), ); }, barrierDismissible: dissmissable, ); } checkinternet()async{ try { var result = await InternetAddress.lookup('google.com').timeout(const Duration(seconds: 3)); if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) { return true; } return false; } on TimeoutException catch(_){ return false; } on SocketException catch (_) { return false; } } getMinAppVer()async{ var req = await JsonDataGetRaw({},'${prefs.getString(Keys.hostAddress)}/app/min_ver/'); return req; } launchURL(String url) async { if (await canLaunch(url)) { await launch(url); } else { throw 'Could not launch $url'; } } updateDialog(context)async{ WidgetsBinding.instance!.addPostFrameCallback((_) async { await showDialog( context: context, builder: (BuildContext context) { return WillPopScope( onWillPop: ()async{ return false; }, child: AlertDialog( title: const Text('App version is too old'), content: const Text('Please update the application'), actions: [ TextButton( child: const Text('Update',style: TextStyle(color: Colors.blue),), onPressed: ()async{ try{ AppUpdateInfo _updateInfo; _updateInfo = await InAppUpdate.checkForUpdate(); if(_updateInfo.updateAvailability == 2){ await InAppUpdate.performImmediateUpdate(); } else throw {"message":"manual Update"}; } catch(e){ await Future.delayed(const Duration(milliseconds: 500)); await launchURL('https://play.google.com/store/apps/details?id=com.thamringroup.unitstocks'); } }, ), ], ), ); }, barrierDismissible: false, ); }); } getOauth2Client() async { bool resetClient = false; oauth2.Credentials? restData = (prefs.getString(Keys.restData)!=null&&prefs.getString(Keys.restData).contains("accessToken"))?oauth2.Credentials.fromJson(prefs.getString(Keys.restData)):null; if(restData == null)resetClient = true; else{ if(DateTime.now().isAfter(restData.expiration??DateTime.now().subtract(const Duration(hours:1))))resetClient = true; } oauth2.Client client; if(resetClient||!tokenValidity){ final tokenEndpoint = Uri.parse(prefs.getString(Keys.restTokenAddress)); if(prefs.getString(Keys.clientCredential)==null){ client = await initRest(); } else{ var clients = const JsonDecoder().convert(prefs.getString(Keys.clientCredential)); client = await oauth2.clientCredentialsGrant(tokenEndpoint, clients["id"], clients["secret"],httpClient: http); prefs.setString(Keys.restData, client.credentials.toJson()); } } else { if (prefs.getString(Keys.clientCredential) == null) { client = await initRest(); } else { var clients = const JsonDecoder().convert(prefs.getString(Keys.clientCredential)); client = oauth2.Client(restData!, identifier: clients["id"], secret: clients["secret"], httpClient: http); } } return client; } JsonDataPostRaw(Map jsonData, String url,{secure:true,timeout:false}) async{ var httpClient; const JsonDecoder decoder = const JsonDecoder(); var headers = {'Content-type': 'application/json'}; try { var response; if(secure) { httpClient = await getOauth2Client(); oauth2.Credentials tokenRestData = oauth2.Credentials.fromJson(prefs.getString(Keys.restData)); headers["Authorization"] = "bearer ${tokenRestData.accessToken}"; } else { httpClient = http; } if (timeout) response = await httpClient.post( Uri.parse(url), headers: headers, body: json.encode(jsonData)).timeout( const Duration(seconds: 8)); else response = await httpClient.post( Uri.parse(url), headers: {'Content-type': 'application/json'}, body: json.encode(jsonData)); if(response.statusCode == 403) tokenValidity = false; if(htmlErrorTitle(response.body.toString())!=""){ return {"STATUS":(response.statusCode != 200)?0:1,"DATA":htmlErrorTitle(response.body.toString())}; } final Map data = decoder.convert(response.body); try{data["DATA"] = decoder.convert(data["DATA"]);}catch(e){} return data; } on TimeoutException catch(e){ return {"STATUS":0,"DATA":"Request Timeout"}; } on HandshakeException catch(e){ if(useLocal){ return {"STATUS":0,"DATA":"Not Connected to Server. $e"}; } else{ useLocal = true; http = IOClient(HttpClient(context: clientContext)); return await JsonDataPostRaw(jsonData, url,timeout:timeout,secure: secure); } } on Exception catch(exception){ print(url); // Toast("Not Connected to Server", Colors.red); return {"STATUS":0,"DATA":"Not Connected to Server. $exception"}; } } JsonDataGetRaw(Map jsonData, String url,{secure:true,timeout:false}) async{ var httpClient; const JsonDecoder decoder = const JsonDecoder(); var headers = {'Content-type': 'application/json'}; try { var response; if(secure) { httpClient = await getOauth2Client(); oauth2.Credentials tokenRestData = oauth2.Credentials.fromJson(prefs.getString(Keys.restData)); headers["Authorization"] = "bearer ${tokenRestData.accessToken}"; } else { httpClient = http; } if(jsonData!= null&&jsonData.length!=0) { url = url + '?'; for (var i in jsonData.keys) { url = url + i + '=' + jsonData[i] + '&'; } url = url.substring(0, url.length - 1); } if (timeout) response = await httpClient.get( Uri.parse(url), headers: headers, ).timeout(const Duration(seconds: 10)); else response = await httpClient.get( Uri.parse(url), headers: {'Content-type': 'application/json'}, ); if(response.statusCode == 403) tokenValidity = false; if(htmlErrorTitle(response.body.toString())!=""){ return {"STATUS":(response.statusCode != 200)?0:1,"DATA":htmlErrorTitle(response.body.toString())}; } final Map data = decoder.convert(response.body); try{data["DATA"] = decoder.convert(data["DATA"]);}catch(e){} return data; } on TimeoutException catch(e){ return {"STATUS":0,"DATA":"Request Timeout"}; } on HandshakeException catch(e){ if(useLocal){ return {"STATUS":0,"DATA":"Not Connected to Server. $e"}; } else{ useLocal = true; http = IOClient(HttpClient(context: clientContext)); return await JsonDataPostRaw(jsonData, url,timeout:timeout,secure: secure); } } on Exception catch(exception){ print(url); // Toast("Not Connected to Server", Colors.red); return {"STATUS":0,"DATA":"Not Connected to Server. $exception"}; } } JsonDataPutRaw(Map jsonData, String url,{secure:true,timeout:false}) async{ var httpClient; const JsonDecoder decoder = const JsonDecoder(); var headers = {'Content-type': 'application/json'}; try { var response; if(secure) { httpClient = await getOauth2Client(); oauth2.Credentials tokenRestData = oauth2.Credentials.fromJson(prefs.getString(Keys.restData)); headers["Authorization"] = "bearer ${tokenRestData.accessToken}"; } else { httpClient = http; } if (timeout) response = await httpClient.put( Uri.parse(url), headers: headers, body: json.encode(jsonData)).timeout( const Duration(seconds: 10)); else response = await httpClient.put( Uri.parse(url), headers: {'Content-type': 'application/json'}, body: json.encode(jsonData)); if(response.statusCode == 403) tokenValidity = false; if(htmlErrorTitle(response.body.toString())!=""){ return {"STATUS":(response.statusCode != 200)?0:1,"DATA":htmlErrorTitle(response.body.toString())}; } final Map data = decoder.convert(response.body); try{data["DATA"] = decoder.convert(data["DATA"]);}catch(e){} return data; } on TimeoutException catch(e){ return {"STATUS":0,"DATA":"Request Timeout"}; } on HandshakeException catch(e){ if(useLocal){ return {"STATUS":0,"DATA":"Not Connected to Server. $e"}; } else{ useLocal = true; http = IOClient(HttpClient(context: clientContext)); return await JsonDataPostRaw(jsonData, url,timeout:timeout,secure: secure); } } on Exception catch(exception){ print(url); // Toast("Not Connected to Server", Colors.red); return {"STATUS":0,"DATA":"Not Connected to Server. $exception"}; } } htmlErrorTitle(String html){ // FlutterLogs.logInfo("TAG", "subTag", html); try{ if(html.contains('')) { String titleElement = html.substring(html.indexOf("<title>")+7,html.indexOf("<\/title>")); return titleElement; } return ''; } catch(e){ return ''; } } initRest()async{ try{ if(prefs.getString(Keys.clientCredential)==null){ prefs.setString(Keys.clientCredential, json.encode({ "id": "IZ4W8u8YZmLtUV0p1zd-_A..", "secret" : "AQ16v4bzGWm9AsWHvUcu2Q.." }).toString()); } return await getOauth2Client(); } catch(e){ print(e); print("error fetching Rest token"); } } permissionCheck(context,pHandler.Permission permissionType,ifGranted,{customMessage=''})async{ pHandler.PermissionStatus permission = await permissionType.status; if(permission!= pHandler.PermissionStatus.granted){ if(permission== pHandler.PermissionStatus.denied || permission== pHandler.PermissionStatus.restricted){ showFlushbar(context,'${permissionType.toString().substring(permissionType.toString().lastIndexOf('.')+1)} permission is needed$customMessage. Please grant the permission!'); await Future.delayed(const Duration(seconds: 3)); permission = await permissionType.request(); } if(permission== pHandler.PermissionStatus.permanentlyDenied) { showFlushbar(context,'It seems, your system security explicitly denied access to your ${permissionType.toString().substring(permissionType.toString().lastIndexOf('.')+1)} permission. Please MANUALLY enable it in setings!'); await Future.delayed(const Duration(seconds: 3)); pHandler.openAppSettings(); SystemChannels.platform.invokeMethod('SystemNavigator.pop'); } if(permission== pHandler.PermissionStatus.denied || permission== pHandler.PermissionStatus.restricted){ showFlushbar(context,'${permissionType.toString().substring(permissionType.toString().lastIndexOf('.')+1)} permission is needed$customMessage. Please grant the permission!'); await Future.delayed(const Duration(seconds: 3)); permission = await permissionType.request(); } await permissionCheck(context,permissionType,ifGranted); } else{ await ifGranted(); } } showFlushbar(context,text,{color:Colors.grey}){ Flushbar( message: "$text", backgroundColor: color, duration: const Duration(seconds: 5), ).show(context); } streamLocation(context)async{ // print('checking location'); await permissionCheck(context,pHandler.Permission.locationWhenInUse,()async{ location.changeSettings(accuracy: LocationAccuracy.high); bool gpsEnabled = false; if(await location.serviceEnabled()){ gpsEnabled = await location.serviceEnabled(); } else{ // print('requesting gps'); gpsEnabled = await location.requestService(); await streamLocation(context); } // print([gpsEnabled,permissionEnabled]); if(gpsEnabled){ locationStream ??= location.onLocationChanged.listen((LocationData event) { currentPosisiton = event; }); } },customMessage: " to locate your REAL location"); } }