diff --git a/mih_ui/lib/main_dev.dart b/mih_ui/lib/main_dev.dart index 03080447..05ee8385 100644 --- a/mih_ui/lib/main_dev.dart +++ b/mih_ui/lib/main_dev.dart @@ -18,7 +18,6 @@ import 'package:mzansi_innovation_hub/mih_objects/business_user.dart'; import 'package:mzansi_innovation_hub/mih_objects/loyalty_card.dart'; import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart'; import 'package:mzansi_innovation_hub/mih_objects/user_consent.dart'; -import 'package:pwa_install/pwa_install.dart'; import 'mih_config/mih_env.dart'; import 'package:supertokens_flutter/supertokens.dart'; import 'package:hive_ce_flutter/hive_ce_flutter.dart'; @@ -70,9 +69,6 @@ void main() async { } else { usePathUrlStrategy(); } - PWAInstall().setup(installCallback: () { - debugPrint('APP INSTALLED!'); - }); final GoRouter appRouter = MihGoRouter().mihRouter; runApp(MzansiInnovationHub( router: appRouter, diff --git a/mih_ui/lib/main_prod.dart b/mih_ui/lib/main_prod.dart index 1ccdd2d4..8c7a98da 100644 --- a/mih_ui/lib/main_prod.dart +++ b/mih_ui/lib/main_prod.dart @@ -18,7 +18,6 @@ import 'package:mzansi_innovation_hub/mih_objects/business_user.dart'; import 'package:mzansi_innovation_hub/mih_objects/loyalty_card.dart'; import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart'; import 'package:mzansi_innovation_hub/mih_objects/user_consent.dart'; -import 'package:pwa_install/pwa_install.dart'; import 'mih_config/mih_env.dart'; import 'package:supertokens_flutter/supertokens.dart'; import 'package:hive_ce_flutter/hive_ce_flutter.dart'; @@ -70,9 +69,6 @@ void main() async { } else { usePathUrlStrategy(); } - PWAInstall().setup(installCallback: () { - debugPrint('APP INSTALLED!'); - }); final GoRouter appRouter = MihGoRouter().mihRouter; runApp(MzansiInnovationHub( router: appRouter, diff --git a/mih_ui/lib/mih_config/mih_theme.dart b/mih_ui/lib/mih_config/mih_theme.dart index aeb468be..7a8ed3bb 100644 --- a/mih_ui/lib/mih_config/mih_theme.dart +++ b/mih_ui/lib/mih_config/mih_theme.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:mih_package_toolkit/mih_package_toolkit.dart'; -import "package:universal_html/html.dart" as html; +import 'package:mzansi_innovation_hub/mih_helpers/mih_utils_stub.dart' + if (dart.library.js_interop) 'package:mzansi_innovation_hub/mih_helpers/mih_utils_web.dart'; class MihTheme { late String mode; @@ -107,7 +108,7 @@ class MihTheme { } bool isPwa() { - return html.window.matchMedia('(display-mode: standalone)').matches; + return isWebStandalone(); } void setMode(String m) { diff --git a/mih_ui/lib/mih_helpers/mih_install_stub.dart b/mih_ui/lib/mih_helpers/mih_install_stub.dart new file mode 100644 index 00000000..bfabdacc --- /dev/null +++ b/mih_ui/lib/mih_helpers/mih_install_stub.dart @@ -0,0 +1,3 @@ +void triggerWebInstall() { + // Safe no-op on Linux/Mobile +} diff --git a/mih_ui/lib/mih_helpers/mih_install_web.dart b/mih_ui/lib/mih_helpers/mih_install_web.dart new file mode 100644 index 00000000..d4e28096 --- /dev/null +++ b/mih_ui/lib/mih_helpers/mih_install_web.dart @@ -0,0 +1,13 @@ +import 'dart:js_interop'; + +@JS('promptInstall') +external void jsPromptInstall(); + +@JS('isInstallPromptAvailable') +external bool jsIsInstallPromptAvailable(); + +void triggerWebInstall() { + if (jsIsInstallPromptAvailable()) { + jsPromptInstall(); + } +} diff --git a/mih_ui/lib/mih_helpers/mih_utils_stub.dart b/mih_ui/lib/mih_helpers/mih_utils_stub.dart new file mode 100644 index 00000000..4f4f521c --- /dev/null +++ b/mih_ui/lib/mih_helpers/mih_utils_stub.dart @@ -0,0 +1,8 @@ +// Create this file anywhere, e.g., lib/mih_config/mih_web_utils_stub.dart +void openWebWindow(String url, [String? target]) { + // Safe no-op or fallback on Linux (e.g., could use url_launcher if needed) +} + +bool isWebStandalone() { + return false; // Always false on native Linux app +} diff --git a/mih_ui/lib/mih_helpers/mih_utils_web.dart b/mih_ui/lib/mih_helpers/mih_utils_web.dart new file mode 100644 index 00000000..d92d40f4 --- /dev/null +++ b/mih_ui/lib/mih_helpers/mih_utils_web.dart @@ -0,0 +1,13 @@ +import 'package:web/web.dart' as web; + +void openWebWindow(String url, [String? target]) { + if (target != null) { + web.window.open(url, target); + } else { + web.window.open(url); + } +} + +bool isWebStandalone() { + return web.window.matchMedia('(display-mode: standalone)').matches; +} diff --git a/mih_ui/lib/mih_packages/mih_authentication/package_tools/mih_sign_in.dart b/mih_ui/lib/mih_packages/mih_authentication/package_tools/mih_sign_in.dart index 1c7ecdeb..c164c7da 100644 --- a/mih_ui/lib/mih_packages/mih_authentication/package_tools/mih_sign_in.dart +++ b/mih_ui/lib/mih_packages/mih_authentication/package_tools/mih_sign_in.dart @@ -58,10 +58,13 @@ class _MihSignInState extends State { void submitSignInForm() async { await signUserIn(); if (successfulSignIn) { + TextInput.finishAutofillContext(); context.goNamed( 'mihHome', extra: true, ); + } else { + TextInput.finishAutofillContext(shouldSave: false); } } diff --git a/mih_ui/lib/mih_packages/mih_file_viewer/package_tools/mih_expanded_file_view.dart b/mih_ui/lib/mih_packages/mih_file_viewer/package_tools/mih_expanded_file_view.dart index 14beaa06..1c7c9098 100644 --- a/mih_ui/lib/mih_packages/mih_file_viewer/package_tools/mih_expanded_file_view.dart +++ b/mih_ui/lib/mih_packages/mih_file_viewer/package_tools/mih_expanded_file_view.dart @@ -7,7 +7,8 @@ import 'package:mzansi_innovation_hub/mih_providers/mih_file_viewer_provider.dar import 'package:provider/provider.dart'; import 'package:syncfusion_flutter_core/theme.dart'; import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart'; -import "package:universal_html/html.dart" as html; +import 'package:mzansi_innovation_hub/mih_helpers/mih_utils_stub.dart' + if (dart.library.js_interop) 'package:mzansi_innovation_hub/mih_helpers/mih_utils_web.dart'; import 'package:fl_downloader/fl_downloader.dart'; class MihExpandedFileView extends StatefulWidget { @@ -227,7 +228,7 @@ class _MihExpandedFileViewState extends State { padding: const EdgeInsets.all(0), onPressed: () { if (kIsWeb) { - html.window.open( + openWebWindow( fileViewerProvider.fileLink, 'download'); } else { nativeFileDownload( diff --git a/mih_ui/lib/mih_packages/patient_manager/pat_profile/list_builders/build_claim_statement_files_list.dart b/mih_ui/lib/mih_packages/patient_manager/pat_profile/list_builders/build_claim_statement_files_list.dart index 59e75895..65583e19 100644 --- a/mih_ui/lib/mih_packages/patient_manager/pat_profile/list_builders/build_claim_statement_files_list.dart +++ b/mih_ui/lib/mih_packages/patient_manager/pat_profile/list_builders/build_claim_statement_files_list.dart @@ -16,7 +16,8 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:supertokens_flutter/http.dart' as http; import 'package:http/http.dart' as http2; -import "package:universal_html/html.dart" as html; +import 'package:mzansi_innovation_hub/mih_helpers/mih_utils_stub.dart' + if (dart.library.js_interop) 'package:mzansi_innovation_hub/mih_helpers/mih_utils_web.dart'; class BuildClaimStatementFileList extends StatefulWidget { const BuildClaimStatementFileList({ @@ -110,7 +111,7 @@ class _BuildClaimStatementFileListState backgroundColor: MihColors.green(), onTap: () { if (MzansiInnovationHub.of(context)!.theme.getPlatform() == "Web") { - html.window.open(url, 'download'); + openWebWindow(url, 'download'); } else { nativeFileDownload(url); } diff --git a/mih_ui/lib/mih_packages/patient_manager/pat_profile/list_builders/build_files_list.dart b/mih_ui/lib/mih_packages/patient_manager/pat_profile/list_builders/build_files_list.dart index 5737ac80..98ef07f4 100644 --- a/mih_ui/lib/mih_packages/patient_manager/pat_profile/list_builders/build_files_list.dart +++ b/mih_ui/lib/mih_packages/patient_manager/pat_profile/list_builders/build_files_list.dart @@ -18,7 +18,8 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:supertokens_flutter/http.dart' as http; import 'package:http/http.dart' as http2; -import "package:universal_html/html.dart" as html; +import 'package:mzansi_innovation_hub/mih_helpers/mih_utils_stub.dart' + if (dart.library.js_interop) 'package:mzansi_innovation_hub/mih_helpers/mih_utils_web.dart'; class BuildFilesList extends StatefulWidget { const BuildFilesList({ @@ -103,7 +104,7 @@ class _BuildFilesListState extends State { backgroundColor: MihColors.green(), onTap: () { if (MzansiInnovationHub.of(context)!.theme.getPlatform() == "Web") { - html.window.open(url, 'download'); + openWebWindow(url, 'download'); } else { nativeFileDownload(url); } diff --git a/mih_ui/lib/mih_services/mih_authentication_services.dart b/mih_ui/lib/mih_services/mih_authentication_services.dart index 2bf3302d..c5521688 100644 --- a/mih_ui/lib/mih_services/mih_authentication_services.dart +++ b/mih_ui/lib/mih_services/mih_authentication_services.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:go_router/go_router.dart'; import 'package:mih_package_toolkit/mih_package_toolkit.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; @@ -59,6 +60,7 @@ class MihAuthenticationServices { if (response2.statusCode == 200) { var userCreated = jsonDecode(response2.body); if (userCreated["status"] == "OK") { + TextInput.finishAutofillContext(); String uid = await SuperTokens.getUserId(); await MihUserServices().createUser( email, @@ -72,6 +74,7 @@ class MihAuthenticationServices { } else { context.pop(); MihAlertServices().internetConnectionAlert(context); + TextInput.finishAutofillContext(shouldSave: false); } } } diff --git a/mih_ui/lib/mih_services/mih_install_services.dart b/mih_ui/lib/mih_services/mih_install_services.dart index f8aafa28..7a59bfe1 100644 --- a/mih_ui/lib/mih_services/mih_install_services.dart +++ b/mih_ui/lib/mih_services/mih_install_services.dart @@ -1,9 +1,9 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:mzansi_innovation_hub/main.dart'; -import 'package:pwa_install/pwa_install.dart'; -// import 'package:universal_html/js.dart' as js; import 'package:url_launcher/url_launcher.dart'; +import 'package:mzansi_innovation_hub/mih_helpers/mih_install_stub.dart' + if (dart.library.js_interop) 'package:mzansi_innovation_hub/mih_helpers/mih_install_web.dart'; class MihInstallServices { String? errorMessage; @@ -45,20 +45,11 @@ class MihInstallServices { "https://apps.apple.com/za/app/mzansi-innovation-hub/id6743310890", ), ); + } else if (MzansiInnovationHub.of(context)!.theme.getPlatform() == + "Linux") { } else { //Web - if (PWAInstall().installPromptEnabled) { - try { - PWAInstall().promptInstall_(); - } catch (e) { - errorMessage = e.toString(); - debugPrint('Error prompting install: $e'); - } - } else { - // Fallback for unsupported platforms - debugPrint('Install prompt not available for this platform.'); - } - // js.context.callMethod("presentAddToHome"); + triggerWebInstall(); } } } diff --git a/mih_ui/pubspec.lock b/mih_ui/pubspec.lock index e3e48834..c9599d10 100644 --- a/mih_ui/pubspec.lock +++ b/mih_ui/pubspec.lock @@ -233,14 +233,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" - charcode: - dependency: transitive - description: - name: charcode - sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a - url: "https://pub.dev" - source: hosted - version: "1.4.0" checked_yaml: dependency: transitive description: @@ -1080,14 +1072,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" - js: - dependency: transitive - description: - name: js - sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" - url: "https://pub.dev" - source: hosted - version: "0.7.2" json_annotation: dependency: transitive description: @@ -1488,14 +1472,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.0" - pwa_install: - dependency: "direct main" - description: - name: pwa_install - sha256: "77fbb93d064d0cda0657f61386958562a13a7e57a2ce2a8b6da707d3bcef43c5" - url: "https://pub.dev" - source: hosted - version: "0.0.6" qr: dependency: transitive description: @@ -2037,14 +2013,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" - universal_html: - dependency: "direct main" - description: - name: universal_html - sha256: c0bcae5c733c60f26c7dfc88b10b0fd27cbcc45cb7492311cdaa6067e21c9cd4 - url: "https://pub.dev" - source: hosted - version: "2.3.0" universal_io: dependency: transitive description: @@ -2214,7 +2182,7 @@ packages: source: hosted version: "1.8.0" web: - dependency: transitive + dependency: "direct main" description: name: web sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" diff --git a/mih_ui/pubspec.yaml b/mih_ui/pubspec.yaml index 83c44df2..a733bb82 100644 --- a/mih_ui/pubspec.yaml +++ b/mih_ui/pubspec.yaml @@ -15,7 +15,8 @@ dependencies: font_awesome_flutter: ^11.0.0 syncfusion_flutter_core: ^33.2.15 syncfusion_flutter_pdfviewer: ^33.2.15 - universal_html: ^2.2.4 + # universal_html: ^2.2.4 + web: ^1.1.1 file_picker: ^12.0.0-beta.7 supertokens_flutter: ^0.6.3 http: ^1.2.1 @@ -38,7 +39,6 @@ dependencies: flutter_tts: ^4.2.3 flutter_speed_dial: ^7.0.0 share_plus: ^13.2.0 - pwa_install: ^0.0.6 google_mobile_ads: ^8.0.0 gma_mediation_meta: ^1.5.2 redacted: ^1.0.13 diff --git a/mih_ui/web/index.html b/mih_ui/web/index.html index fad795ab..a19d58b0 100644 --- a/mih_ui/web/index.html +++ b/mih_ui/web/index.html @@ -30,46 +30,32 @@ - - - - - - - - + + // Helper to safely check from Dart if prompt is ready + function isInstallPromptAvailable() { + return deferredPrompt !== undefined && deferredPrompt !== null; + }