Commit f7b0d1aa authored by Sai Srinivas's avatar Sai Srinivas
Browse files

ios changes

parent 64c42cd9
...@@ -56,6 +56,8 @@ PODS: ...@@ -56,6 +56,8 @@ PODS:
- Flutter - Flutter
- flutter_local_notifications (0.0.1): - flutter_local_notifications (0.0.1):
- Flutter - Flutter
- flutter_pdfview (1.0.2):
- Flutter
- flutter_ringtone_player (0.0.1): - flutter_ringtone_player (0.0.1):
- Flutter - Flutter
- fluttertoast (0.0.2): - fluttertoast (0.0.2):
...@@ -136,6 +138,8 @@ PODS: ...@@ -136,6 +138,8 @@ PODS:
- FlutterMacOS - FlutterMacOS
- permission_handler_apple (9.3.0): - permission_handler_apple (9.3.0):
- Flutter - Flutter
- printing (1.0.0):
- Flutter
- PromisesObjC (2.4.0) - PromisesObjC (2.4.0)
- qr_code_scanner (0.2.0): - qr_code_scanner (0.2.0):
- Flutter - Flutter
...@@ -154,6 +158,8 @@ PODS: ...@@ -154,6 +158,8 @@ PODS:
- sqflite_darwin (0.0.4): - sqflite_darwin (0.0.4):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- syncfusion_flutter_pdfviewer (0.0.1):
- Flutter
- url_launcher_ios (0.0.1): - url_launcher_ios (0.0.1):
- Flutter - Flutter
- webview_flutter_wkwebview (0.0.1): - webview_flutter_wkwebview (0.0.1):
...@@ -172,6 +178,7 @@ DEPENDENCIES: ...@@ -172,6 +178,7 @@ DEPENDENCIES:
- flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`) - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`) - flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- flutter_pdfview (from `.symlinks/plugins/flutter_pdfview/ios`)
- flutter_ringtone_player (from `.symlinks/plugins/flutter_ringtone_player/ios`) - flutter_ringtone_player (from `.symlinks/plugins/flutter_ringtone_player/ios`)
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- geocoding_ios (from `.symlinks/plugins/geocoding_ios/ios`) - geocoding_ios (from `.symlinks/plugins/geocoding_ios/ios`)
...@@ -182,10 +189,12 @@ DEPENDENCIES: ...@@ -182,10 +189,12 @@ DEPENDENCIES:
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- printing (from `.symlinks/plugins/printing/ios`)
- qr_code_scanner (from `.symlinks/plugins/qr_code_scanner/ios`) - qr_code_scanner (from `.symlinks/plugins/qr_code_scanner/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`) - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
- syncfusion_flutter_pdfviewer (from `.symlinks/plugins/syncfusion_flutter_pdfviewer/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`) - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`)
...@@ -232,6 +241,8 @@ EXTERNAL SOURCES: ...@@ -232,6 +241,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios" :path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
flutter_local_notifications: flutter_local_notifications:
:path: ".symlinks/plugins/flutter_local_notifications/ios" :path: ".symlinks/plugins/flutter_local_notifications/ios"
flutter_pdfview:
:path: ".symlinks/plugins/flutter_pdfview/ios"
flutter_ringtone_player: flutter_ringtone_player:
:path: ".symlinks/plugins/flutter_ringtone_player/ios" :path: ".symlinks/plugins/flutter_ringtone_player/ios"
fluttertoast: fluttertoast:
...@@ -252,6 +263,8 @@ EXTERNAL SOURCES: ...@@ -252,6 +263,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/path_provider_foundation/darwin" :path: ".symlinks/plugins/path_provider_foundation/darwin"
permission_handler_apple: permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios" :path: ".symlinks/plugins/permission_handler_apple/ios"
printing:
:path: ".symlinks/plugins/printing/ios"
qr_code_scanner: qr_code_scanner:
:path: ".symlinks/plugins/qr_code_scanner/ios" :path: ".symlinks/plugins/qr_code_scanner/ios"
share_plus: share_plus:
...@@ -260,6 +273,8 @@ EXTERNAL SOURCES: ...@@ -260,6 +273,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin" :path: ".symlinks/plugins/shared_preferences_foundation/darwin"
sqflite_darwin: sqflite_darwin:
:path: ".symlinks/plugins/sqflite_darwin/darwin" :path: ".symlinks/plugins/sqflite_darwin/darwin"
syncfusion_flutter_pdfviewer:
:path: ".symlinks/plugins/syncfusion_flutter_pdfviewer/ios"
url_launcher_ios: url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios" :path: ".symlinks/plugins/url_launcher_ios/ios"
webview_flutter_wkwebview: webview_flutter_wkwebview:
...@@ -282,6 +297,7 @@ SPEC CHECKSUMS: ...@@ -282,6 +297,7 @@ SPEC CHECKSUMS:
flutter_inappwebview_ios: 8d8d2c6290a3c4787cad303603662fac9a788f75 flutter_inappwebview_ios: 8d8d2c6290a3c4787cad303603662fac9a788f75
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069 flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
flutter_local_notifications: ff50f8405aaa0ccdc7dcfb9022ca192e8ad9688f flutter_local_notifications: ff50f8405aaa0ccdc7dcfb9022ca192e8ad9688f
flutter_pdfview: 2e4d13ffb774858562ffbdfdb61b40744b191adc
flutter_ringtone_player: 15eba85187230b87b2512f0e1b92225618bc03e7 flutter_ringtone_player: 15eba85187230b87b2512f0e1b92225618bc03e7
fluttertoast: 21eecd6935e7064cc1fcb733a4c5a428f3f24f0f fluttertoast: 21eecd6935e7064cc1fcb733a4c5a428f3f24f0f
geocoding_ios: d7460f56e80e118d57678efe5c2cdc888739ff18 geocoding_ios: d7460f56e80e118d57678efe5c2cdc888739ff18
...@@ -301,6 +317,7 @@ SPEC CHECKSUMS: ...@@ -301,6 +317,7 @@ SPEC CHECKSUMS:
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4 package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2 permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
printing: 233e1b73bd1f4a05615548e9b5a324c98588640b
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e
SDWebImage: f84b0feeb08d2d11e6a9b843cb06d75ebf5b8868 SDWebImage: f84b0feeb08d2d11e6a9b843cb06d75ebf5b8868
...@@ -308,6 +325,7 @@ SPEC CHECKSUMS: ...@@ -308,6 +325,7 @@ SPEC CHECKSUMS:
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
syncfusion_flutter_pdfviewer: cfcf23c03816192575902e615fa50adc9f95b724
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
webview_flutter_wkwebview: ab1e58b71690b7e61b58eae7a963b68ee286a146 webview_flutter_wkwebview: ab1e58b71690b7e61b58eae7a963b68ee286a146
......
import 'dart:async'; import 'dart:async';
import 'dart:io';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
...@@ -10,6 +11,7 @@ import 'package:generp/Notifiers/LogoutNotifier.dart'; ...@@ -10,6 +11,7 @@ import 'package:generp/Notifiers/LogoutNotifier.dart';
import 'package:generp/Notifiers/ProfileNotifier.dart'; import 'package:generp/Notifiers/ProfileNotifier.dart';
import 'package:generp/screens/LoginScreen.dart'; import 'package:generp/screens/LoginScreen.dart';
import 'package:generp/screens/ScannerLogin.dart'; import 'package:generp/screens/ScannerLogin.dart';
import 'package:generp/screens/WebERPIOS.dart';
import 'package:generp/screens/WebERPScreen.dart'; import 'package:generp/screens/WebERPScreen.dart';
import 'package:generp/screens/WebWhizzdomScreen.dart'; import 'package:generp/screens/WebWhizzdomScreen.dart';
import 'package:generp/screens/finance/financeDashboard.dart'; import 'package:generp/screens/finance/financeDashboard.dart';
...@@ -127,8 +129,8 @@ class _MyHomePageState extends State<MyHomePage> { ...@@ -127,8 +129,8 @@ class _MyHomePageState extends State<MyHomePage> {
"Nearby", "Nearby",
"Inventory", "Inventory",
"Whizzdom", "Whizzdom",
"CRM", // "CRM",
"Finance", // "Finance",
]; ];
final icons = [ final icons = [
"assets/svg/home_icons_1.svg", "assets/svg/home_icons_1.svg",
...@@ -138,8 +140,8 @@ class _MyHomePageState extends State<MyHomePage> { ...@@ -138,8 +140,8 @@ class _MyHomePageState extends State<MyHomePage> {
"assets/svg/home_icons_5.svg", "assets/svg/home_icons_5.svg",
"assets/svg/home_icons_6.svg", "assets/svg/home_icons_6.svg",
"assets/svg/home_icons_81.svg", "assets/svg/home_icons_81.svg",
"assets/svg/home_icons_8.svg", // "assets/svg/home_icons_8.svg",
"assets/svg/home_icons_8.svg", // "assets/svg/home_icons_8.svg",
]; ];
final requiredRoles = [ final requiredRoles = [
"430", "430",
...@@ -149,8 +151,8 @@ class _MyHomePageState extends State<MyHomePage> { ...@@ -149,8 +151,8 @@ class _MyHomePageState extends State<MyHomePage> {
"433", "433",
"432", "432",
"431", "431",
"431", // "431",
"431", // "431",
]; ];
final filteredItems = <Map<String, String>>[]; final filteredItems = <Map<String, String>>[];
...@@ -372,15 +374,28 @@ class _MyHomePageState extends State<MyHomePage> { ...@@ -372,15 +374,28 @@ class _MyHomePageState extends State<MyHomePage> {
bool isGpsEnabled = bool isGpsEnabled =
await Geolocator.isLocationServiceEnabled(); await Geolocator.isLocationServiceEnabled();
if (isGpsEnabled) { if (isGpsEnabled) {
if (Platform.isAndroid) {
res = await Navigator.push( res = await Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: builder:
(context) => WebErpScreen( (context) => WebErpScreen(
erp_url: homescreen.webPageUrl, erp_url:
homescreen.webPageUrl,
), ),
), ),
); );
} else {
res = await Navigator.push(
context,
MaterialPageRoute(
builder:
(context) => WebERPIOS(
url: homescreen.webPageUrl,
),
),
);
}
} else { } else {
requestGpsPermission(); requestGpsPermission();
} }
...@@ -445,13 +460,13 @@ class _MyHomePageState extends State<MyHomePage> { ...@@ -445,13 +460,13 @@ class _MyHomePageState extends State<MyHomePage> {
//res = await Navigator.push(context, MaterialPageRoute(builder: (context)=>CRMScreen())); //res = await Navigator.push(context, MaterialPageRoute(builder: (context)=>CRMScreen()));
break; break;
case "Finance": case "Finance":
res = await Navigator.push( // res = await Navigator.push(
context, // context,
MaterialPageRoute( // MaterialPageRoute(
builder: // builder:
(context) => Financedashboard(), // (context) => Financedashboard(),
), // ),
); // );
break; break;
default: default:
print("111"); print("111");
......
import 'dart:async';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_download_manager/flutter_download_manager.dart';
import 'package:flutter_svg/svg.dart';
import 'package:generp/Utils/app_colors.dart';
import 'package:generp/Utils/commonWidgets.dart';
import 'package:generp/screens/WebERPScreen.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:url_launcher/url_launcher.dart';
const MAX_PROGRESS = 100;
Future main() async {
await FlutterDownloader.initialize(
debug: true, // optional: set false to disable printing logs to console
);
await Permission.storage.request();
}
class WebERPIOS extends StatefulWidget {
final String url;
const WebERPIOS({Key? key, required this.url}) : super(key: key);
@override
State<WebERPIOS> createState() => _WebERPIOSState();
}
class _WebERPIOSState extends State<WebERPIOS> {
final Completer<InAppWebViewController> _controller =
Completer<InAppWebViewController>();
var empId = "";
var sessionId = "";
bool isLoading = true;
InAppWebViewController? webViewController;
PullToRefreshController? pullToRefreshController;
PullToRefreshSettings pullToRefreshSettings = PullToRefreshSettings(
color: AppColors.app_blue,
);
bool pullToRefreshEnabled = true;
final GlobalKey webViewKey = GlobalKey();
var dl = DownloadManager();
@override
void initState() {
// loadData();
pullToRefreshController =
kIsWeb
? null
: PullToRefreshController(
settings: pullToRefreshSettings,
onRefresh: () async {
if (defaultTargetPlatform == Platform.isAndroid) {
webViewController?.reload();
} else if (defaultTargetPlatform == Platform.isIOS) {
webViewController?.loadUrl(
urlRequest: URLRequest(
url: await webViewController?.getUrl(),
),
);
}
},
);
print("WebURL:${widget.url}");
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
if (await webViewController!.canGoBack()) {
webViewController!.goBack();
return false; // Prevent default back button behavior
}
return true; // Allow default back button behavior
},
child: Scaffold(
appBar: appbar(context, "Web ERP"),
body: Container(
child: Column(
children: <Widget>[
Expanded(
child: Stack(
children: [
InAppWebView(
initialUrlRequest: URLRequest(
url: WebUri(widget.url.toString()),
),
androidOnGeolocationPermissionsShowPrompt: (
InAppWebViewController controller,
String origin,
) async {
return GeolocationPermissionShowPromptResponse(
origin: origin,
allow: true,
retain: true,
);
},
initialOptions: InAppWebViewGroupOptions(
android: AndroidInAppWebViewOptions(
useWideViewPort: true,
loadWithOverviewMode: true,
allowContentAccess: true,
geolocationEnabled: true,
allowFileAccess: true,
databaseEnabled: true, // Enables the WebView database
domStorageEnabled: true, // Enables DOM storage
builtInZoomControls:
true, // Enables the built-in zoom controls
displayZoomControls:
false, // Disables displaying zoom controls
safeBrowsingEnabled: true, // Enables Safe Browsing
),
ios: IOSInAppWebViewOptions(
allowsInlineMediaPlayback: true,
allowsLinkPreview: true,
allowsBackForwardNavigationGestures: true,
),
),
androidOnPermissionRequest: (
InAppWebViewController controller,
String origin,
List<String> resources,
) async {
return PermissionRequestResponse(
resources: resources,
action: PermissionRequestResponseAction.GRANT,
);
},
initialSettings: InAppWebViewSettings(
javaScriptEnabled: true,
allowFileAccess: true,
allowContentAccess: true,
clearCache: true,
blockNetworkLoads: false,
networkAvailable: true,
useOnLoadResource: true,
thirdPartyCookiesEnabled: true,
supportZoom: false,
geolocationEnabled: true,
safeBrowsingEnabled: false,
saveFormData: true,
allowFileAccessFromFileURLs: true,
useWideViewPort: true,
databaseEnabled: true,
domStorageEnabled: true,
allowsBackForwardNavigationGestures: true,
allowUniversalAccessFromFileURLs: true,
allowsLinkPreview: true,
),
onPermissionRequest: (controller, request) async {
return PermissionResponse(
resources: request.resources,
action: PermissionResponseAction.GRANT,
);
},
keepAlive: InAppWebViewKeepAlive(),
// initialData:
// InAppWebViewInitialData(baseUrl: WebUri(widget.url),data: ),
onWebViewCreated: (controller) {
webViewController = controller;
_controller.complete(controller);
},
pullToRefreshController: pullToRefreshController,
shouldOverrideUrlLoading: (
controller,
navigationAction,
) async {
var uri = navigationAction.request.url!;
print("urib scgefes");
print(uri);
print(uri.scheme);
if (uri.scheme == "tel") {
// Launch the phone dialer app with the specified phone number
if (await canLaunch(uri.toString())) {
await launch(uri.toString());
return NavigationActionPolicy.CANCEL;
}
} else if (uri.scheme == "mailto") {
if (await canLaunch(uri.toString())) {
await launch(uri.toString());
return NavigationActionPolicy.CANCEL;
}
} else if (uri.scheme == "whatsapp") {
// Launch WhatsApp with the specified chat or phone number
if (await canLaunch(uri.toString())) {
await launch(uri.toString());
return NavigationActionPolicy.CANCEL;
}
}
// // Check if the URL is trying to access the camera for image upload
// if (uri.scheme == 'camera' && uri.path.contains('/camera/')) {
// // Handle camera image upload here
// // You might want to display a custom UI for image selection or directly trigger the camera
// // You can use platform-specific plugins like image_picker for this purpose
// // Once the image is selected, you can pass it to the web view using JavaScript injection
// if (await canLaunch(uri.toString())) {
// await launch(uri.toString());
// return NavigationActionPolicy.CANCEL;
// }
// }
return NavigationActionPolicy.ALLOW;
},
onLoadStart: (controller, url) {
return setState(() {
isLoading = true;
});
},
onLoadStop: (controller, url) {
pullToRefreshController?.endRefreshing();
return setState(() {
isLoading = false;
});
},
onReceivedError: (controller, request, error) {
pullToRefreshController?.endRefreshing();
},
onProgressChanged: (controller, progress) {
if (progress == 100) {
pullToRefreshController?.endRefreshing();
}
},
),
if (isLoading) ...[
Container(
color: Colors.white.withOpacity(0.7),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SpinKitRing(
color: AppColors.app_blue,
lineWidth: 4,
// duration: Duration(seconds: 2),
size: 50,
),
const SizedBox(height: 15),
SizedBox(
width: 200,
child: Text(
"Please wait.......",
textAlign: TextAlign.center,
style: TextStyle(
decorationThickness: 0,
fontSize: 15,
fontWeight: FontWeight.normal,
color: AppColors.app_blue,
),
),
),
// SvgPicture.asset("/assets/images/NutsLoader.gif")
],
),
),
],
],
),
),
],
),
),
),
);
}
}
...@@ -19,17 +19,19 @@ import 'dart:math'; ...@@ -19,17 +19,19 @@ import 'dart:math';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
const MAX_PROGRESS = 100; const MAX_PROGRESS = 100;
Future main() async { Future main() async {
await FlutterDownloader.initialize( await FlutterDownloader.initialize(
debug: true // optional: set false to disable printing logs to console debug: true, // optional: set false to disable printing logs to console
); );
await Permission.storage.request(); await Permission.storage.request();
} }
class WebErpScreen extends StatefulWidget { class WebErpScreen extends StatefulWidget {
final String erp_url; final String erp_url;
const WebErpScreen({super.key,required this.erp_url}); const WebErpScreen({super.key, required this.erp_url});
@override @override
State<WebErpScreen> createState() => _WebErpScreenState(); State<WebErpScreen> createState() => _WebErpScreenState();
...@@ -47,7 +49,8 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -47,7 +49,8 @@ class _WebErpScreenState extends State<WebErpScreen> {
color: AppColors.app_blue, color: AppColors.app_blue,
); );
bool pullToRefreshEnabled = true; bool pullToRefreshEnabled = true;
final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin(); final FlutterLocalNotificationsPlugin _notificationsPlugin =
FlutterLocalNotificationsPlugin();
static const platform = MethodChannel('in.webgrid.generp/download'); static const platform = MethodChannel('in.webgrid.generp/download');
final GlobalKey webViewKey = GlobalKey(); final GlobalKey webViewKey = GlobalKey();
...@@ -56,7 +59,8 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -56,7 +59,8 @@ class _WebErpScreenState extends State<WebErpScreen> {
void initState() { void initState() {
// loadData(); // loadData();
super.initState(); super.initState();
pullToRefreshController = kIsWeb pullToRefreshController =
kIsWeb
? null ? null
: PullToRefreshController( : PullToRefreshController(
settings: pullToRefreshSettings, settings: pullToRefreshSettings,
...@@ -65,21 +69,22 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -65,21 +69,22 @@ class _WebErpScreenState extends State<WebErpScreen> {
_webViewController?.reload(); _webViewController?.reload();
} else if (defaultTargetPlatform == TargetPlatform.iOS) { } else if (defaultTargetPlatform == TargetPlatform.iOS) {
_webViewController?.loadUrl( _webViewController?.loadUrl(
urlRequest: urlRequest: URLRequest(
URLRequest(url: await _webViewController?.getUrl())); url: await _webViewController?.getUrl(),
),
);
} }
}, },
); );
// print("URL:${widget.url}"); // print("URL:${widget.url}");
_initializeNotifications(); _initializeNotifications();
} }
Future<void> _initializeNotifications() async { Future<void> _initializeNotifications() async {
const AndroidInitializationSettings initializationSettingsAndroid = const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher'); AndroidInitializationSettings('@mipmap/ic_launcher');
final InitializationSettings initializationSettings = InitializationSettings( final InitializationSettings initializationSettings =
android: initializationSettingsAndroid, InitializationSettings(android: initializationSettingsAndroid);
);
await _notificationsPlugin.initialize(initializationSettings); await _notificationsPlugin.initialize(initializationSettings);
// Create a notification channel for Android // Create a notification channel for Android
...@@ -90,7 +95,9 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -90,7 +95,9 @@ class _WebErpScreenState extends State<WebErpScreen> {
importance: Importance.high, importance: Importance.high,
); );
await _notificationsPlugin await _notificationsPlugin
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>() .resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin
>()
?.createNotificationChannel(channel); ?.createNotificationChannel(channel);
} }
...@@ -98,6 +105,7 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -98,6 +105,7 @@ class _WebErpScreenState extends State<WebErpScreen> {
void dispose() { void dispose() {
super.dispose(); super.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return WillPopScope( return WillPopScope(
...@@ -110,9 +118,10 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -110,9 +118,10 @@ class _WebErpScreenState extends State<WebErpScreen> {
}, },
child: Scaffold( child: Scaffold(
resizeToAvoidBottomInset: true, resizeToAvoidBottomInset: true,
appBar:appbar(context, "Web ERP"), appBar: appbar(context, "Web ERP"),
body: Container( body: Container(
child: Column(children: <Widget>[ child: Column(
children: <Widget>[
Expanded( Expanded(
child: Stack( child: Stack(
children: [ children: [
...@@ -122,17 +131,19 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -122,17 +131,19 @@ class _WebErpScreenState extends State<WebErpScreen> {
allowsCellularAccess: true, allowsCellularAccess: true,
allowsConstrainedNetworkAccess: true, allowsConstrainedNetworkAccess: true,
allowsExpensiveNetworkAccess: true, allowsExpensiveNetworkAccess: true,
), ),
androidOnGeolocationPermissionsShowPrompt: androidOnGeolocationPermissionsShowPrompt: (
(InAppWebViewController controller, String origin) async { InAppWebViewController controller,
String origin,
) async {
return GeolocationPermissionShowPromptResponse( return GeolocationPermissionShowPromptResponse(
origin: origin, allow: true, retain: true); origin: origin,
allow: true,
retain: true,
);
}, },
initialOptions: InAppWebViewGroupOptions( initialOptions: InAppWebViewGroupOptions(
android: AndroidInAppWebViewOptions( android: AndroidInAppWebViewOptions(
useWideViewPort: true, useWideViewPort: true,
loadWithOverviewMode: true, loadWithOverviewMode: true,
allowContentAccess: true, allowContentAccess: true,
...@@ -152,10 +163,11 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -152,10 +163,11 @@ class _WebErpScreenState extends State<WebErpScreen> {
supportMultipleWindows: true, supportMultipleWindows: true,
// Enable camera access // Enable camera access
), ),
ios: IOSInAppWebViewOptions( ios: IOSInAppWebViewOptions(
allowsInlineMediaPlayback: true, allowsInlineMediaPlayback: true,
allowsLinkPreview: true,
allowsBackForwardNavigationGestures: true,
), ),
crossPlatform: InAppWebViewOptions( crossPlatform: InAppWebViewOptions(
javaScriptEnabled: true, javaScriptEnabled: true,
...@@ -163,32 +175,50 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -163,32 +175,50 @@ class _WebErpScreenState extends State<WebErpScreen> {
allowFileAccessFromFileURLs: true, allowFileAccessFromFileURLs: true,
allowUniversalAccessFromFileURLs: true, allowUniversalAccessFromFileURLs: true,
mediaPlaybackRequiresUserGesture: true, mediaPlaybackRequiresUserGesture: true,
), ),
), ),
androidOnPermissionRequest: (
androidOnPermissionRequest: (InAppWebViewController controller, InAppWebViewController controller,
String origin, List<String> resources) async { String origin,
List<String> resources,
) async {
return PermissionRequestResponse( return PermissionRequestResponse(
resources: resources, resources: resources,
action: PermissionRequestResponseAction.GRANT); action: PermissionRequestResponseAction.GRANT,
);
},
onPermissionRequest: (controller, request) async {
return PermissionResponse(
resources: request.resources,
action: PermissionResponseAction.GRANT,
);
}, },
keepAlive: InAppWebViewKeepAlive(),
onWebViewCreated: (controller) { onWebViewCreated: (controller) {
_webViewController = controller; _webViewController = controller;
_controller.complete(controller); _controller.complete(controller);
_webViewController!.addJavaScriptHandler( _webViewController!.addJavaScriptHandler(
handlerName: 'MobileAppJavascriptInterface', handlerName: 'MobileAppJavascriptInterface',
callback: (args) { callback: (args) {
print("JavaScript called MobileAppJavascriptInterface with args: $args"); print(
"JavaScript called MobileAppJavascriptInterface with args: $args",
);
return {'status': 'success'}; return {'status': 'success'};
}, },
); );
_webViewController!.addJavaScriptHandler( _webViewController!.addJavaScriptHandler(
handlerName: 'downloadFile', handlerName: 'downloadFile',
callback: (args) async { callback: (args) async {
if (Platform.isAndroid) {
final url = args[0] as String; final url = args[0] as String;
await _handleDownload(url, '', 'application/octet-stream',''); await _handleDownload(
url,
'',
'application/octet-stream',
'',
);
}
}, },
); );
}, },
...@@ -225,11 +255,12 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -225,11 +255,12 @@ class _WebErpScreenState extends State<WebErpScreen> {
allowsLinkPreview: true, allowsLinkPreview: true,
databaseEnabled: true, // Enables the WebView database databaseEnabled: true, // Enables the WebView database
clearSessionCache: true, clearSessionCache: true,
mediaType:"image/*", mediaType: "image/*",
), ),
shouldOverrideUrlLoading: shouldOverrideUrlLoading: (
(controller, navigationAction) async { controller,
navigationAction,
) async {
var uri = navigationAction.request.url!; var uri = navigationAction.request.url!;
print("urib scgefes"); print("urib scgefes");
print(uri); print(uri);
...@@ -274,6 +305,9 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -274,6 +305,9 @@ class _WebErpScreenState extends State<WebErpScreen> {
}, },
onReceivedError: (controller, request, error) { onReceivedError: (controller, request, error) {
pullToRefreshController?.endRefreshing(); pullToRefreshController?.endRefreshing();
return setState(() {
isLoading = false;
});
}, },
onProgressChanged: (controller, progress) { onProgressChanged: (controller, progress) {
if (progress == 100) { if (progress == 100) {
...@@ -285,7 +319,8 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -285,7 +319,8 @@ class _WebErpScreenState extends State<WebErpScreen> {
debugPrint("consoleMessage${consoleMessage}"); debugPrint("consoleMessage${consoleMessage}");
} }
debugPrint( debugPrint(
"JavaScript console message: ${consoleMessage.message}"); "JavaScript console message: ${consoleMessage.message}",
);
}, },
// onDownloadStartRequest: (controller, url) async { // onDownloadStartRequest: (controller, url) async {
// await ApiCalling.download_files( // await ApiCalling.download_files(
...@@ -293,24 +328,41 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -293,24 +328,41 @@ class _WebErpScreenState extends State<WebErpScreen> {
// .then((data) => {debugPrint(data)}); // .then((data) => {debugPrint(data)});
// //
// }, // },
onDownloadStartRequest: (controller, downloadStartRequest) async { onDownloadStartRequest: (
controller,
downloadStartRequest,
) async {
if (Platform.isAndroid) {
await _handleDownload( await _handleDownload(
downloadStartRequest.url.toString(), downloadStartRequest.url.toString(),
downloadStartRequest.suggestedFilename!, downloadStartRequest.suggestedFilename!,
downloadStartRequest.mimeType ?? 'application/octet-stream', downloadStartRequest.mimeType ??
'application/octet-stream',
downloadStartRequest.suggestedFilename ?? '', downloadStartRequest.suggestedFilename ?? '',
); );
}
}, },
shouldInterceptAjaxRequest: (controller, ajaxRequest) async { shouldInterceptAjaxRequest: (
controller,
ajaxRequest,
) async {
if (Platform.isAndroid) {
if (ajaxRequest.url.toString().contains('download')) { if (ajaxRequest.url.toString().contains('download')) {
await _handleDownload(ajaxRequest.url.toString(), '', 'application/octet-stream',''); await _handleDownload(
ajaxRequest.url.toString(),
'',
'application/octet-stream',
'',
);
}
return ajaxRequest; return ajaxRequest;
} }
return ajaxRequest; return ajaxRequest;
}, },
), ),
if (isLoading) ...[Container( if (isLoading) ...[
Container(
color: Colors.white.withOpacity(0.7), color: Colors.white.withOpacity(0.7),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
...@@ -322,9 +374,7 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -322,9 +374,7 @@ class _WebErpScreenState extends State<WebErpScreen> {
// duration: Duration(seconds: 2), // duration: Duration(seconds: 2),
size: 50, size: 50,
), ),
const SizedBox( const SizedBox(height: 15),
height: 15,
),
SizedBox( SizedBox(
width: 200, width: 200,
child: Text( child: Text(
...@@ -334,28 +384,41 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -334,28 +384,41 @@ class _WebErpScreenState extends State<WebErpScreen> {
decorationThickness: 0, decorationThickness: 0,
fontSize: 15, fontSize: 15,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
color: AppColors.app_blue), color: AppColors.app_blue,
),
), ),
), ),
// SvgPicture.asset("/assets/images/NutsLoader.gif") // SvgPicture.asset("/assets/images/NutsLoader.gif")
], ],
), ),
)] ),
],
], ],
)) ),
])), ),
],
),
),
), ),
); );
} }
Future<void> _handleDownload(String url, String contentDisposition, String mimeType,String suggestedFilename) async { Future<void> _handleDownload(
String url,
String contentDisposition,
String mimeType,
String suggestedFilename,
) async {
// Request notification permission for Android 13+ // Request notification permission for Android 13+
if (Platform.isIOS) {
_handleIOSDownload(url, suggestedFilename);
} else if (Platform.isAndroid) {
if (await Permission.notification.request().isGranted) { if (await Permission.notification.request().isGranted) {
try { try {
// Show custom notification (optional, since DownloadManager shows its own) // Show custom notification (optional, since DownloadManager shows its own)
if (Platform.isAndroid) {
// Call native Android Download Manager // Call native Android Download Manager
final userAgent = 'Flutter InAppWebView'; final userAgent = 'Flutter InAppWebView';
await platform.invokeMethod('startDownload', { await platform.invokeMethod('startDownload', {
...@@ -365,7 +428,9 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -365,7 +428,9 @@ class _WebErpScreenState extends State<WebErpScreen> {
'mimeType': mimeType, 'mimeType': mimeType,
'suggestedFilename': suggestedFilename, 'suggestedFilename': suggestedFilename,
}); });
} else if (Platform.isIOS) {
_handleIOSDownload(url, suggestedFilename);
}
} catch (e) { } catch (e) {
print("Download Error $e"); print("Download Error $e");
} }
...@@ -373,9 +438,108 @@ class _WebErpScreenState extends State<WebErpScreen> { ...@@ -373,9 +438,108 @@ class _WebErpScreenState extends State<WebErpScreen> {
toast(context, "Notification Permission Denied"); toast(context, "Notification Permission Denied");
} }
} }
}
} Future<void> _handleIOSDownload(String url, String suggestedFilename) async {
try {
// Show initial download notification
await _showDownloadNotification(0, suggestedFilename, isComplete: false);
// Get the temporary directory for iOS
final tempDir = await getTemporaryDirectory();
final fileName =
suggestedFilename.isNotEmpty
? suggestedFilename
: url.split('/').last;
final filePath = '${tempDir.path}/$fileName';
// Download the file using http
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
// Save the file
final file = File(filePath);
await file.writeAsBytes(response.bodyBytes);
// Show completion notification
await _showDownloadNotification(100, fileName, isComplete: true);
// Optionally, open the file or notify the user
toast(context, "File downloaded to $filePath");
} else {
throw Exception("Failed to download file: HTTP ${response.statusCode}");
}
} catch (e) {
print("iOS Download Error: $e");
await _showDownloadNotification(
0,
suggestedFilename,
isComplete: false,
isError: true,
);
toast(context, "Failed to download file: $e");
}
}
Future<void> _showDownloadNotification(
int progress,
String fileName, {
bool isComplete = false,
bool isError = false,
}) async {
final androidDetails = AndroidNotificationDetails(
'download_channel',
'Downloads',
channelDescription: 'Notifications for file downloads',
importance: Importance.high,
priority: Priority.high,
showProgress: !isComplete && !isError,
maxProgress: 100,
progress: progress,
ongoing: !isComplete && !isError,
playSound: isComplete || isError,
styleInformation: BigTextStyleInformation(
isError
? 'Download failed for $fileName'
: isComplete
? 'Download complete: $fileName'
: 'Downloading $fileName...',
),
);
final iosDetails = DarwinNotificationDetails(
presentAlert: true,
presentBadge: true,
presentSound: isComplete || isError,
subtitle:
isError
? 'Download failed'
: isComplete
? 'Download complete'
: 'Downloading...',
threadIdentifier: 'download_thread',
);
final notificationDetails = NotificationDetails(
android: androidDetails,
iOS: iosDetails,
);
await _notificationsPlugin.show(
fileName.hashCode, // Unique ID for the notification
isError
? 'Download Failed'
: isComplete
? 'Download Complete'
: 'Downloading File',
isError
? 'Failed to download $fileName'
: isComplete
? 'Successfully downloaded $fileName'
: 'Downloading $fileName ($progress%)',
notificationDetails,
);
}
}
class SpinKitRing extends StatefulWidget { class SpinKitRing extends StatefulWidget {
const SpinKitRing({ const SpinKitRing({
...@@ -397,7 +561,8 @@ class SpinKitRing extends StatefulWidget { ...@@ -397,7 +561,8 @@ class SpinKitRing extends StatefulWidget {
State<SpinKitRing> createState() => _SpinKitRingState(); State<SpinKitRing> createState() => _SpinKitRingState();
} }
class _SpinKitRingState extends State<SpinKitRing> with SingleTickerProviderStateMixin { class _SpinKitRingState extends State<SpinKitRing>
with SingleTickerProviderStateMixin {
late AnimationController _controller; late AnimationController _controller;
late Animation<double> _animation1; late Animation<double> _animation1;
late Animation<double> _animation2; late Animation<double> _animation2;
...@@ -407,7 +572,9 @@ class _SpinKitRingState extends State<SpinKitRing> with SingleTickerProviderStat ...@@ -407,7 +572,9 @@ class _SpinKitRingState extends State<SpinKitRing> with SingleTickerProviderStat
void initState() { void initState() {
super.initState(); super.initState();
_controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration)) _controller =
(widget.controller ??
AnimationController(vsync: this, duration: widget.duration))
..addListener(() { ..addListener(() {
if (mounted) { if (mounted) {
setState(() {}); setState(() {});
...@@ -446,7 +613,8 @@ class _SpinKitRingState extends State<SpinKitRing> with SingleTickerProviderStat ...@@ -446,7 +613,8 @@ class _SpinKitRingState extends State<SpinKitRing> with SingleTickerProviderStat
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Center( return Center(
child: Transform( child: Transform(
transform: Matrix4.identity()..rotateZ((_animation1.value) * 5 * pi / 6), transform:
Matrix4.identity()..rotateZ((_animation1.value) * 5 * pi / 6),
alignment: FractionalOffset.center, alignment: FractionalOffset.center,
child: SizedBox.fromSize( child: SizedBox.fromSize(
size: Size.square(widget.size), size: Size.square(widget.size),
...@@ -470,7 +638,8 @@ class RingPainter extends CustomPainter { ...@@ -470,7 +638,8 @@ class RingPainter extends CustomPainter {
this.progressPercent, this.progressPercent,
this.startAngle, this.startAngle,
required this.trackColor, required this.trackColor,
}) : trackPaint = Paint() }) : trackPaint =
Paint()
..color = trackColor ..color = trackColor
..style = PaintingStyle.stroke ..style = PaintingStyle.stroke
..strokeWidth = paintWidth ..strokeWidth = paintWidth
......
...@@ -37,10 +37,10 @@ packages: ...@@ -37,10 +37,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: async name: async
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.12.0" version: "2.13.0"
barcode: barcode:
dependency: transitive dependency: transitive
description: description:
...@@ -285,10 +285,10 @@ packages: ...@@ -285,10 +285,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: fake_async name: fake_async
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.2" version: "1.3.3"
ffi: ffi:
dependency: transitive dependency: transitive
description: description:
...@@ -924,26 +924,26 @@ packages: ...@@ -924,26 +924,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker name: leak_tracker
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "10.0.8" version: "11.0.1"
leak_tracker_flutter_testing: leak_tracker_flutter_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_flutter_testing name: leak_tracker_flutter_testing
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.9" version: "3.0.10"
leak_tracker_testing: leak_tracker_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_testing name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.1" version: "3.0.2"
lints: lints:
dependency: transitive dependency: transitive
description: description:
...@@ -1641,10 +1641,10 @@ packages: ...@@ -1641,10 +1641,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vm_service name: vm_service
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.3.1" version: "15.0.0"
web: web:
dependency: transitive dependency: transitive
description: description:
......
...@@ -180,3 +180,4 @@ flutter: ...@@ -180,3 +180,4 @@ flutter:
# For details regarding fonts from package dependencies, # For details regarding fonts from package dependencies,
# see https://flutter.dev/to/font-from-package # see https://flutter.dev/to/font-from-package
generate: true
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment