diff --git a/Frontend/android/app/src/main/AndroidManifest.xml b/Frontend/android/app/src/main/AndroidManifest.xml index 6683a646..0c66eab2 100644 --- a/Frontend/android/app/src/main/AndroidManifest.xml +++ b/Frontend/android/app/src/main/AndroidManifest.xml @@ -11,10 +11,17 @@ - + + + + + + + + @@ -99,5 +110,8 @@ + + + diff --git a/Frontend/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png b/Frontend/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png index 149b5936..05feb272 100644 Binary files a/Frontend/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png and b/Frontend/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png differ diff --git a/Frontend/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png b/Frontend/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png index 8fd116f5..64e9ebd5 100644 Binary files a/Frontend/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png and b/Frontend/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png b/Frontend/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png index 0f9afb3e..1b92456d 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png and b/Frontend/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png b/Frontend/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png index 34525e34..ad2ee7cc 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png and b/Frontend/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png differ diff --git a/Frontend/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png b/Frontend/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png index ff60f903..a48bf43b 100644 Binary files a/Frontend/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png and b/Frontend/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png differ diff --git a/Frontend/android/app/src/main/res/drawable/calculator.xml b/Frontend/android/app/src/main/res/drawable/calculator.xml new file mode 100644 index 00000000..24464f94 --- /dev/null +++ b/Frontend/android/app/src/main/res/drawable/calculator.xml @@ -0,0 +1,9 @@ + + + diff --git a/Frontend/android/app/src/main/res/drawable/mih_calculator_sc.xml b/Frontend/android/app/src/main/res/drawable/mih_calculator_sc.xml new file mode 100644 index 00000000..b881d937 --- /dev/null +++ b/Frontend/android/app/src/main/res/drawable/mih_calculator_sc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Frontend/android/app/src/main/res/drawable/mih_home_sc.xml b/Frontend/android/app/src/main/res/drawable/mih_home_sc.xml new file mode 100644 index 00000000..577d6937 --- /dev/null +++ b/Frontend/android/app/src/main/res/drawable/mih_home_sc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Frontend/android/app/src/main/res/drawable/mih_logo.xml b/Frontend/android/app/src/main/res/drawable/mih_logo.xml new file mode 100644 index 00000000..e67a36d8 --- /dev/null +++ b/Frontend/android/app/src/main/res/drawable/mih_logo.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/Frontend/android/app/src/main/res/drawable/mzansi_ai.xml b/Frontend/android/app/src/main/res/drawable/mzansi_ai.xml new file mode 100644 index 00000000..6aa32a86 --- /dev/null +++ b/Frontend/android/app/src/main/res/drawable/mzansi_ai.xml @@ -0,0 +1,9 @@ + + + diff --git a/Frontend/android/app/src/main/res/drawable/mzansi_ai_sc.xml b/Frontend/android/app/src/main/res/drawable/mzansi_ai_sc.xml new file mode 100644 index 00000000..5cce8b99 --- /dev/null +++ b/Frontend/android/app/src/main/res/drawable/mzansi_ai_sc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Frontend/android/app/src/main/res/drawable/mzansi_wallet.xml b/Frontend/android/app/src/main/res/drawable/mzansi_wallet.xml new file mode 100644 index 00000000..c3681bf8 --- /dev/null +++ b/Frontend/android/app/src/main/res/drawable/mzansi_wallet.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/Frontend/android/app/src/main/res/drawable/mzansi_wallet_sc.xml b/Frontend/android/app/src/main/res/drawable/mzansi_wallet_sc.xml new file mode 100644 index 00000000..9d0af1f3 --- /dev/null +++ b/Frontend/android/app/src/main/res/drawable/mzansi_wallet_sc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Frontend/android/app/src/main/res/drawable/test.xml b/Frontend/android/app/src/main/res/drawable/test.xml new file mode 100644 index 00000000..85ad1a93 --- /dev/null +++ b/Frontend/android/app/src/main/res/drawable/test.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/Frontend/android/app/src/main/res/mipmap-hdpi/launcher_icon.png b/Frontend/android/app/src/main/res/mipmap-hdpi/launcher_icon.png index 9eaccf4d..8f34cbf2 100644 Binary files a/Frontend/android/app/src/main/res/mipmap-hdpi/launcher_icon.png and b/Frontend/android/app/src/main/res/mipmap-hdpi/launcher_icon.png differ diff --git a/Frontend/android/app/src/main/res/mipmap-mdpi/launcher_icon.png b/Frontend/android/app/src/main/res/mipmap-mdpi/launcher_icon.png index 3af91ff0..935dc98a 100644 Binary files a/Frontend/android/app/src/main/res/mipmap-mdpi/launcher_icon.png and b/Frontend/android/app/src/main/res/mipmap-mdpi/launcher_icon.png differ diff --git a/Frontend/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png b/Frontend/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png index 1e178c8e..69af77d0 100644 Binary files a/Frontend/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png and b/Frontend/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png differ diff --git a/Frontend/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png b/Frontend/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png index 03e17e9f..7efcae44 100644 Binary files a/Frontend/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png and b/Frontend/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png differ diff --git a/Frontend/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png b/Frontend/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png index 2168f904..4851d018 100644 Binary files a/Frontend/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png and b/Frontend/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png differ diff --git a/Frontend/android/app/src/main/res/values/arrays.xml b/Frontend/android/app/src/main/res/values/arrays.xml new file mode 100644 index 00000000..fb766383 --- /dev/null +++ b/Frontend/android/app/src/main/res/values/arrays.xml @@ -0,0 +1,9 @@ + + + + @drawable/mih_home_sc + @drawable/mzansi_wallet_sc + @drawable/mzansi_ai_sc + @drawable/mih_calculator_sc + + \ No newline at end of file diff --git a/Frontend/android/app/src/main/res/values/colors.xml b/Frontend/android/app/src/main/res/values/colors.xml index 66426078..ebc7fcbd 100644 --- a/Frontend/android/app/src/main/res/values/colors.xml +++ b/Frontend/android/app/src/main/res/values/colors.xml @@ -1,4 +1,10 @@ - #3A4454 + #6641b2 + + #6641b2 + #E0D1FF + + \ No newline at end of file diff --git a/Frontend/android/build/reports/problems/problems-report.html b/Frontend/android/build/reports/problems/problems-report.html new file mode 100644 index 00000000..0784829f --- /dev/null +++ b/Frontend/android/build/reports/problems/problems-report.html @@ -0,0 +1,663 @@ + + + + + + + + + + + + + Gradle Configuration Cache + + + +
+ +
+ Loading... +
+ + + + + + diff --git a/Frontend/flutter_launcher_icons.yaml b/Frontend/flutter_launcher_icons.yaml index ea62ac8f..f9524c8e 100644 --- a/Frontend/flutter_launcher_icons.yaml +++ b/Frontend/flutter_launcher_icons.yaml @@ -1,32 +1,46 @@ # flutter pub run flutter_launcher_icons flutter_launcher_icons: - image_path: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_app_icon.png" + # Original + # image_path: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_app.png" + + # Women For Change + image_path: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_app_w4c.png" android: "launcher_icon" - # image_path_android: "assets/icon/icon.png" min_sdk_android: 21 # android min sdk min:16, default 21 - adaptive_icon_background: "#3A4454" - adaptive_icon_foreground: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_app_icon.png" - # adaptive_icon_monochrome: "assets/icon/monochrome.png" + # Original + # adaptive_icon_background: "#3A4454" + # adaptive_icon_foreground: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_app.png" + + # Women For Change + adaptive_icon_background: "#6641b2" + adaptive_icon_foreground: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_app_w4c.png" ios: true - image_path_ios: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_app_icon.png" + # Original + # image_path_ios: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_app.png" + + # Women For Change + image_path_ios: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_app_w4c.png" remove_alpha_channel_ios: true - # image_path_ios_dark_transparent: "assets/icon/icon_dark.png" - # image_path_ios_tinted_grayscale: "assets/icon/icon_tinted.png" - # desaturate_tinted_to_grayscale_ios: true web: generate: true - image_path: "lib/mih_components/mih_package_components/assets/images/app_icon/circle_logo.png" - background_color: "#3A4454" - theme_color: "#3A4454" + # Original + # image_path: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_web.png" + # background_color: "#3A4454" + # theme_color: "#3A4454" + + # Women For Change + image_path: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_web_w4c.png" + background_color: "#6641b2" + theme_color: "#6641b2" windows: generate: true - image_path: "lib/mih_components/mih_package_components/assets/images/app_icon/circle_logo.png" + image_path: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_web.png" icon_size: 48 # min:48, max:256, default: 48 macos: generate: true - image_path: "lib/mih_components/mih_package_components/assets/images/app_icon/circle_logo.png" + image_path: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_web.png" diff --git a/Frontend/ios/Podfile.lock b/Frontend/ios/Podfile.lock index 3a6b5ba9..5de20c98 100644 --- a/Frontend/ios/Podfile.lock +++ b/Frontend/ios/Podfile.lock @@ -1,6 +1,15 @@ PODS: - app_settings (5.1.1): - Flutter + - AppCheckCore (11.2.0): + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/UserDefaults (~> 8.0) + - PromisesObjC (~> 2.4) + - camera_avfoundation (0.0.1): + - Flutter + - CwlCatchException (2.2.1): + - CwlCatchExceptionSupport (~> 2.2.1) + - CwlCatchExceptionSupport (2.2.1) - device_info_plus (0.0.1): - Flutter - DKImagePickerController/Core (4.3.9): @@ -40,6 +49,50 @@ PODS: - Flutter - file_saver (0.0.1): - Flutter + - file_selector_ios (0.0.1): + - Flutter + - Firebase/Auth (12.4.0): + - Firebase/CoreOnly + - FirebaseAuth (~> 12.4.0) + - Firebase/CoreOnly (12.4.0): + - FirebaseCore (~> 12.4.0) + - firebase_app_check (0.4.1-2): + - Firebase/CoreOnly (~> 12.4.0) + - firebase_core + - FirebaseAppCheck (~> 12.4.0) + - Flutter + - firebase_auth (6.1.2): + - Firebase/Auth (= 12.4.0) + - firebase_core + - Flutter + - firebase_core (4.2.1): + - Firebase/CoreOnly (= 12.4.0) + - Flutter + - FirebaseAppCheck (12.4.0): + - AppCheckCore (~> 11.0) + - FirebaseAppCheckInterop (~> 12.4.0) + - FirebaseCore (~> 12.4.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - FirebaseAppCheckInterop (12.4.0) + - FirebaseAuth (12.4.0): + - FirebaseAppCheckInterop (~> 12.4.0) + - FirebaseAuthInterop (~> 12.4.0) + - FirebaseCore (~> 12.4.0) + - FirebaseCoreExtension (~> 12.4.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/Environment (~> 8.1) + - GTMSessionFetcher/Core (< 6.0, >= 3.4) + - RecaptchaInterop (~> 101.0) + - FirebaseAuthInterop (12.4.0) + - FirebaseCore (12.4.0): + - FirebaseCoreInternal (~> 12.4.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreExtension (12.4.0): + - FirebaseCore (~> 12.4.0) + - FirebaseCoreInternal (12.4.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" - fl_downloader (0.0.1): - Flutter - Flutter (1.0.0) @@ -63,6 +116,33 @@ PODS: - FBAudienceNetwork (= 6.20.1) - Google-Mobile-Ads-SDK (~> 12.0) - GoogleUserMessagingPlatform (3.0.0) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GTMSessionFetcher/Core (5.0.0) + - image_picker_ios (0.0.1): + - Flutter - local_auth_darwin (0.0.1): - Flutter - FlutterMacOS @@ -76,6 +156,12 @@ PODS: - FlutterMacOS - printing (1.0.0): - Flutter + - PromisesObjC (2.4.0) + - quick_actions_ios (0.0.1): + - Flutter + - RecaptchaInterop (101.0.0) + - record_ios (1.1.0): + - Flutter - screen_brightness_ios (0.1.0): - Flutter - SDWebImage (5.20.0): @@ -86,6 +172,10 @@ PODS: - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS + - speech_to_text (7.2.0): + - CwlCatchException + - Flutter + - FlutterMacOS - sqflite_darwin (0.0.4): - Flutter - FlutterMacOS @@ -100,9 +190,14 @@ PODS: DEPENDENCIES: - app_settings (from `.symlinks/plugins/app_settings/ios`) + - camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`) - file_saver (from `.symlinks/plugins/file_saver/ios`) + - file_selector_ios (from `.symlinks/plugins/file_selector_ios/ios`) + - firebase_app_check (from `.symlinks/plugins/firebase_app_check/ios`) + - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`) + - firebase_core (from `.symlinks/plugins/firebase_core/ios`) - fl_downloader (from `.symlinks/plugins/fl_downloader/ios`) - Flutter (from `Flutter`) - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) @@ -110,14 +205,18 @@ DEPENDENCIES: - geolocator_apple (from `.symlinks/plugins/geolocator_apple/darwin`) - gma_mediation_meta (from `.symlinks/plugins/gma_mediation_meta/ios`) - google_mobile_ads (from `.symlinks/plugins/google_mobile_ads/ios`) + - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`) - mobile_scanner (from `.symlinks/plugins/mobile_scanner/darwin`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - printing (from `.symlinks/plugins/printing/ios`) + - quick_actions_ios (from `.symlinks/plugins/quick_actions_ios/ios`) + - record_ios (from `.symlinks/plugins/record_ios/ios`) - screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + - speech_to_text (from `.symlinks/plugins/speech_to_text/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`) @@ -125,24 +224,49 @@ DEPENDENCIES: SPEC REPOS: trunk: + - AppCheckCore + - CwlCatchException + - CwlCatchExceptionSupport - DKImagePickerController - DKPhotoGallery - FBAudienceNetwork + - Firebase + - FirebaseAppCheck + - FirebaseAppCheckInterop + - FirebaseAuth + - FirebaseAuthInterop + - FirebaseCore + - FirebaseCoreExtension + - FirebaseCoreInternal - Google-Mobile-Ads-SDK - GoogleMobileAdsMediationFacebook - GoogleUserMessagingPlatform + - GoogleUtilities + - GTMSessionFetcher + - PromisesObjC + - RecaptchaInterop - SDWebImage - SwiftyGif EXTERNAL SOURCES: app_settings: :path: ".symlinks/plugins/app_settings/ios" + camera_avfoundation: + :path: ".symlinks/plugins/camera_avfoundation/ios" device_info_plus: :path: ".symlinks/plugins/device_info_plus/ios" file_picker: :path: ".symlinks/plugins/file_picker/ios" file_saver: :path: ".symlinks/plugins/file_saver/ios" + file_selector_ios: + :path: ".symlinks/plugins/file_selector_ios/ios" + firebase_app_check: + :path: ".symlinks/plugins/firebase_app_check/ios" + firebase_auth: + :path: ".symlinks/plugins/firebase_auth/ios" + firebase_core: + :path: ".symlinks/plugins/firebase_core/ios" fl_downloader: :path: ".symlinks/plugins/fl_downloader/ios" Flutter: @@ -157,6 +281,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/gma_mediation_meta/ios" google_mobile_ads: :path: ".symlinks/plugins/google_mobile_ads/ios" + image_picker_ios: + :path: ".symlinks/plugins/image_picker_ios/ios" local_auth_darwin: :path: ".symlinks/plugins/local_auth_darwin/darwin" mobile_scanner: @@ -167,12 +293,18 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/path_provider_foundation/darwin" printing: :path: ".symlinks/plugins/printing/ios" + quick_actions_ios: + :path: ".symlinks/plugins/quick_actions_ios/ios" + record_ios: + :path: ".symlinks/plugins/record_ios/ios" screen_brightness_ios: :path: ".symlinks/plugins/screen_brightness_ios/ios" share_plus: :path: ".symlinks/plugins/share_plus/ios" shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + speech_to_text: + :path: ".symlinks/plugins/speech_to_text/darwin" sqflite_darwin: :path: ".symlinks/plugins/sqflite_darwin/darwin" syncfusion_flutter_pdfviewer: @@ -184,12 +316,28 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: app_settings: 5127ae0678de1dcc19f2293271c51d37c89428b2 + AppCheckCore: cc8fd0a3a230ddd401f326489c99990b013f0c4f + camera_avfoundation: be3be85408cd4126f250386828e9b1dfa40ab436 + CwlCatchException: 7acc161b299a6de7f0a46a6ed741eae2c8b4d75a + CwlCatchExceptionSupport: 54ccab8d8c78907b57f99717fb19d4cc3bce02dc device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 FBAudienceNetwork: 08e86d63a05b3a5a59414af12e4af8d756943c80 file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6 + file_selector_ios: f92e583d43608aebc2e4a18daac30b8902845502 + Firebase: f07b15ae5a6ec0f93713e30b923d9970d144af3e + firebase_app_check: 61fb3578a0761c806533482aca240a2d5cc5b5ef + firebase_auth: 9225db04db5d8e3b46dc8940e04bc6aec6833e27 + firebase_core: f1aafb21c14f497e5498f7ffc4dc63cbb52b2594 + FirebaseAppCheck: 73721d98fa29cf199da6004e57715cbaddd49651 + FirebaseAppCheckInterop: f734c802f21fe1da0837708f0f9a27218c8a4ed0 + FirebaseAuth: 4a2aed737c84114a9d9b33d11ae1b147d6b94889 + FirebaseAuthInterop: 858e6b754966e70740a4370dd1503dfffe6dbb49 + FirebaseCore: bb595f3114953664e3c1dc032f008a244147cfd3 + FirebaseCoreExtension: 7e1f7118ee970e001a8013719fb90950ee5e0018 + FirebaseCoreInternal: d7f5a043c2cd01a08103ab586587c1468047bca6 fl_downloader: dc99aa8dd303f862cccb830087f37acc9b0156ee Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf @@ -200,15 +348,23 @@ SPEC CHECKSUMS: google_mobile_ads: 535223588a6791b7a3cc3513a1bc7b89d12f3e62 GoogleMobileAdsMediationFacebook: b11a92ae3bfdae19853b882252b7e62791c18162 GoogleUserMessagingPlatform: f8d0cdad3ca835406755d0a69aa634f00e76d576 + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + GTMSessionFetcher: 02d6e866e90bc236f48a703a041dfe43e6221a29 + image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391 mobile_scanner: 9157936403f5a0644ca3779a38ff8404c5434a93 package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 printing: 54ff03f28fe9ba3aa93358afb80a8595a071dd07 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + quick_actions_ios: 4b07fb49d8d8f3518d7565fbb7a91014067a7d82 + RecaptchaInterop: 11e0b637842dfb48308d242afc3f448062325aba + record_ios: f75fa1d57f840012775c0e93a38a7f3ceea1a374 screen_brightness_ios: 9953fd7da5bd480f1a93990daeec2eb42d4f3b52 SDWebImage: 73c6079366fea25fa4bb9640d5fb58f0893facd8 share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 + speech_to_text: 3b313d98516d3d0406cea424782ec25470c59d19 sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 syncfusion_flutter_pdfviewer: 90dc48305d2e33d4aa20681d1e98ddeda891bc14 diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png index 550c1375..eb0d9681 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png index 5bd61bd4..50448018 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png index 0ea48825..1e83b209 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png index 2d4cbe47..219448ba 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png index d0cf82cb..005256df 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png index 9f709813..cc0e28c6 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png index bebc5023..f3eff92c 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png index 0ea48825..1e83b209 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png index febb81c9..7b301398 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png index fbc70a4f..a4e616cd 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png index e58bbcc8..256a7dcf 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png index 9f1992fb..ed9c8e49 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png index 678e8057..f04afdd6 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png index b3028465..9c8a5ee9 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png index fbc70a4f..a4e616cd 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png index ddd18d00..d66e8d6f 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png index 9eaccf4d..8f34cbf2 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png index 03e17e9f..7efcae44 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png index 993b89b4..97adcb5a 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png index d916fb3b..f5e89303 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png index 92c735a6..5c581327 100644 Binary files a/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and b/Frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/Frontend/ios/Runner/Assets.xcassets/Contents.json b/Frontend/ios/Runner/Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/Frontend/ios/Runner/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Frontend/ios/Runner/Assets.xcassets/mih_calculator_sc.imageset/Contents.json b/Frontend/ios/Runner/Assets.xcassets/mih_calculator_sc.imageset/Contents.json new file mode 100644 index 00000000..76df3ccf --- /dev/null +++ b/Frontend/ios/Runner/Assets.xcassets/mih_calculator_sc.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "calculator.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/Frontend/ios/Runner/Assets.xcassets/mih_calculator_sc.imageset/calculator.svg b/Frontend/ios/Runner/Assets.xcassets/mih_calculator_sc.imageset/calculator.svg new file mode 100644 index 00000000..89048fe6 --- /dev/null +++ b/Frontend/ios/Runner/Assets.xcassets/mih_calculator_sc.imageset/calculator.svg @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/Frontend/ios/Runner/Assets.xcassets/mih_home_sc.imageset/Contents.json b/Frontend/ios/Runner/Assets.xcassets/mih_home_sc.imageset/Contents.json new file mode 100644 index 00000000..2e65911f --- /dev/null +++ b/Frontend/ios/Runner/Assets.xcassets/mih_home_sc.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "mih_logo.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/Frontend/ios/Runner/Assets.xcassets/mih_home_sc.imageset/mih_logo.svg b/Frontend/ios/Runner/Assets.xcassets/mih_home_sc.imageset/mih_logo.svg new file mode 100644 index 00000000..cfcb5a59 --- /dev/null +++ b/Frontend/ios/Runner/Assets.xcassets/mih_home_sc.imageset/mih_logo.svg @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/Frontend/ios/Runner/Assets.xcassets/mzansi_ai_sc.imageset/Contents.json b/Frontend/ios/Runner/Assets.xcassets/mzansi_ai_sc.imageset/Contents.json new file mode 100644 index 00000000..963ed39d --- /dev/null +++ b/Frontend/ios/Runner/Assets.xcassets/mzansi_ai_sc.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "mzansi_ai.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/Frontend/ios/Runner/Assets.xcassets/mzansi_ai_sc.imageset/mzansi_ai.svg b/Frontend/ios/Runner/Assets.xcassets/mzansi_ai_sc.imageset/mzansi_ai.svg new file mode 100644 index 00000000..cbc854f6 --- /dev/null +++ b/Frontend/ios/Runner/Assets.xcassets/mzansi_ai_sc.imageset/mzansi_ai.svg @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/Frontend/ios/Runner/Assets.xcassets/mzansi_wallet_sc.imageset/Contents.json b/Frontend/ios/Runner/Assets.xcassets/mzansi_wallet_sc.imageset/Contents.json new file mode 100644 index 00000000..c5007964 --- /dev/null +++ b/Frontend/ios/Runner/Assets.xcassets/mzansi_wallet_sc.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "mzansi_wallet.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/Frontend/ios/Runner/Assets.xcassets/mzansi_wallet_sc.imageset/mzansi_wallet.svg b/Frontend/ios/Runner/Assets.xcassets/mzansi_wallet_sc.imageset/mzansi_wallet.svg new file mode 100644 index 00000000..dae5170d --- /dev/null +++ b/Frontend/ios/Runner/Assets.xcassets/mzansi_wallet_sc.imageset/mzansi_wallet.svg @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/Frontend/ios/Runner/Info.plist b/Frontend/ios/Runner/Info.plist index 2a54c123..fa3a51d5 100644 --- a/Frontend/ios/Runner/Info.plist +++ b/Frontend/ios/Runner/Info.plist @@ -2,6 +2,16 @@ + NSMicrophoneUsageDescription + This app needs access to your microphone to enable voice input for the chat. + NSSpeechRecognitionUsageDescription + This app uses speech recognition to convert your voice messages into text. + ITSAppUsesNonExemptEncryption + + NSMicrophoneUsageDescription + This app needs access to your microphone to enable voice input for the chat. + NSSpeechRecognitionUsageDescription + This app uses speech recognition to convert your voice messages into text. ITSAppUsesNonExemptEncryption SKAdNetworkItems diff --git a/Frontend/lib/main.dart b/Frontend/lib/main.dart index 783a11a3..9c4153a6 100644 --- a/Frontend/lib/main.dart +++ b/Frontend/lib/main.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; +import 'package:ken_logger/ken_logger.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/about_mih_provider.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_access_controlls_provider.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_authentication_provider.dart'; @@ -12,8 +13,8 @@ import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_direct import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_wallet_provider.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/patient_manager_provider.dart'; -import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:provider/provider.dart'; +import 'package:quick_actions/quick_actions.dart'; import 'package:upgrader/upgrader.dart'; import 'mih_config/mih_env.dart'; import 'mih_config/mih_theme.dart'; @@ -35,41 +36,62 @@ class MzansiInnovationHub extends StatefulWidget { class _MzansiInnovationHubState extends State { late MihTheme theme; + final QuickActions quickActions = QuickActions(); + String shortcut = 'no action set'; - Color getPrimany() { - return MihColors.getPrimaryColor(theme.mode == "Dark"); - } - - String getTitle() { - if (AppEnviroment.getEnv() == "Dev") { - return "Dev | MIH App: Mzansi Innovation Hub"; - } else { - return "MIH App: Mzansi Innovation Hub"; - } - } - - void changeTheme(ThemeMode themeMode) { - setState(() { - if (themeMode == ThemeMode.light) { - setState(() { - theme.mode = "Light"; - }); - } else if (themeMode == ThemeMode.dark) { - setState(() { - theme.mode = "Dark"; - }); - } else { - setState(() { - theme.mode = "Dark"; - }); + void _initializeQuickActions() { + quickActions.initialize((String shortcutType) { + setState(() { + shortcut = shortcutType; + }); + if (shortcutType == 'mihHome') { + KenLogger.success("ShortCut: mihHome"); + widget.router.goNamed("mihHome"); } + if (shortcutType == 'mzansiWallet') { + KenLogger.success("ShortCut: mzansiWallet"); + widget.router.goNamed("mzansiWallet"); + } + if (shortcutType == 'mzansiAi') { + KenLogger.success("ShortCut: mzansiAi"); + widget.router.goNamed("mzansiAi"); + } + if (shortcutType == 'mihCalculator') { + KenLogger.success("ShortCut: mihCalculator"); + widget.router.goNamed("mihCalculator"); + } + }); + // Set the quick actions + quickActions.setShortcutItems([ + const ShortcutItem( + type: 'mzansiWallet', + localizedTitle: 'Mzansi Wallet', + icon: 'mzansi_wallet_sc', + ), + const ShortcutItem( + type: 'mzansiAi', + localizedTitle: 'Mzansi AI', + icon: 'mzansi_ai_sc', + ), + const ShortcutItem( + type: 'mihCalculator', + localizedTitle: 'MIH Calc', + icon: 'mih_calculator_sc', + ), + ]).then((void _) { + setState(() { + if (shortcut == 'no action set') { + shortcut = 'mih_home_sc'; + } + }); }); } @override void initState() { - theme = MihTheme(); super.initState(); + _initializeQuickActions(); + theme = MihTheme(); theme.mode = "Dark"; theme.platform = Theme.of(context).platform; } @@ -78,7 +100,6 @@ class _MzansiInnovationHubState extends State { Widget build(BuildContext context) { double width = MediaQuery.sizeOf(context).width; theme.setScreenType(width); - precacheImage(theme.loadingImage(), context); return MultiProvider( providers: [ ChangeNotifierProvider( @@ -119,7 +140,9 @@ class _MzansiInnovationHubState extends State { ), ], child: MaterialApp.router( - title: getTitle(), + title: AppEnviroment.getEnv() == "Dev" + ? "Dev | MIH App: Mzansi Innovation Hub" + : "MIH App: Mzansi Innovation Hub", themeMode: ThemeMode.dark, theme: theme.getThemeData(), darkTheme: theme.getThemeData(), diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/App_Icon_1.png b/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/App_Icon_1.png deleted file mode 100644 index 39e38c3c..00000000 Binary files a/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/App_Icon_1.png and /dev/null differ diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/App_Icon_2.png b/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/App_Icon_2.png deleted file mode 100644 index 9dfefeeb..00000000 Binary files a/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/App_Icon_2.png and /dev/null differ diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/App_Icon_3.png b/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/App_Icon_3.png deleted file mode 100644 index 048bc741..00000000 Binary files a/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/App_Icon_3.png and /dev/null differ diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_app.png b/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_app.png new file mode 100644 index 00000000..136db5ef Binary files /dev/null and b/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_app.png differ diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_app_w4c.png b/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_app_w4c.png new file mode 100644 index 00000000..dbcffcbf Binary files /dev/null and b/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_app_w4c.png differ diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_web.png b/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_web.png new file mode 100644 index 00000000..8394f8e8 Binary files /dev/null and b/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_web.png differ diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_web_w4c.png b/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_web_w4c.png new file mode 100644 index 00000000..5026c49a Binary files /dev/null and b/Frontend/lib/mih_components/mih_package_components/assets/images/app_icon/mih_logo_web_w4c.png differ diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/loading_dark.gif b/Frontend/lib/mih_components/mih_package_components/assets/images/loading_dark.gif deleted file mode 100644 index 5b9e9d63..00000000 Binary files a/Frontend/lib/mih_components/mih_package_components/assets/images/loading_dark.gif and /dev/null differ diff --git a/Frontend/lib/mih_components/mih_package_components/assets/images/loading_light.gif b/Frontend/lib/mih_components/mih_package_components/assets/images/loading_light.gif deleted file mode 100644 index 52fd224c..00000000 Binary files a/Frontend/lib/mih_components/mih_package_components/assets/images/loading_light.gif and /dev/null differ diff --git a/Frontend/lib/mih_components/mih_pop_up_messages/mih_loading_circle.dart b/Frontend/lib/mih_components/mih_pop_up_messages/mih_loading_circle.dart index 7323d8c2..5172d15f 100644 --- a/Frontend/lib/mih_components/mih_pop_up_messages/mih_loading_circle.dart +++ b/Frontend/lib/mih_components/mih_pop_up_messages/mih_loading_circle.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import '../../main.dart'; -import 'package:gif_view/gif_view.dart'; class Mihloadingcircle extends StatefulWidget { final String? message; @@ -11,8 +11,11 @@ class Mihloadingcircle extends StatefulWidget { State createState() => _MihloadingcircleState(); } -class _MihloadingcircleState extends State { - // final GifController _controller = GifController(); +class _MihloadingcircleState extends State + with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation _animation; + late double popUpPaddingSize; late double popUpWidth; late double? popUpheight; @@ -38,14 +41,26 @@ class _MihloadingcircleState extends State { @override void initState() { - //_controller.animateTo(26); super.initState(); checkScreenSize(); + _controller = AnimationController( + duration: const Duration( + milliseconds: 500), // Duration for one pulse (grow and shrink) + vsync: this, + ); + _animation = Tween( + begin: 200, + end: 200 * 0.5, // Pulse to 50% of the initial size + ).animate(CurvedAnimation( + parent: _controller, + curve: Curves.easeInOut, // Smooth start and end of the pulse + )); + _controller.repeat(reverse: true); } @override void dispose() { - // _controller.dispose(); + _controller.dispose(); super.dispose(); } @@ -70,13 +85,22 @@ class _MihloadingcircleState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ - GifView.asset( - MzansiInnovationHub.of(context)! - .theme - .loadingImageLocation(), - height: 200, + SizedBox( width: 200, - frameRate: 30, + height: 200, + child: AnimatedBuilder( + animation: _animation, + builder: (context, child) { + return Icon( + MihIcons.mihLogo, + size: _animation + .value, // The size changes based on the animation value + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ); + }, + ), ), widget.message != null ? Text( diff --git a/Frontend/lib/mih_components/mih_providers/mzansi_ai_provider.dart b/Frontend/lib/mih_components/mih_providers/mzansi_ai_provider.dart index 1ba96af5..574977a0 100644 --- a/Frontend/lib/mih_components/mih_providers/mzansi_ai_provider.dart +++ b/Frontend/lib/mih_components/mih_providers/mzansi_ai_provider.dart @@ -1,12 +1,55 @@ import 'package:flutter/material.dart'; +import 'package:flutter_ai_toolkit/flutter_ai_toolkit.dart'; +import 'package:flutter_markdown_plus/flutter_markdown_plus.dart'; +import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/ollama_provider.dart'; +import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; +import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; class MzansiAiProvider extends ChangeNotifier { + bool ttsOn; int toolIndex; String? startUpQuestion; + late OllamaProvider ollamaProvider; MzansiAiProvider({ this.toolIndex = 0, - }); + this.ttsOn = false, + }) { + ollamaProvider = OllamaProvider( + baseUrl: "${AppEnviroment.baseAiUrl}/api", + model: AppEnviroment.getEnv() == "Prod" ? 'gemma3n:e4b' : "gemma3:1b", + systemPrompt: "You are Mzansi AI, a helpful and friendly AI assistant running on the 'MIH App'.\n" + + "The MIH App was created by 'Mzansi Innovation Hub', a South African-based startup company." + + "Your primary purpose is to assist users by answering general questions and helping with creative writing tasks or any other task a user might have for you.\n" + + "Maintain a casual and friendly tone, but always remain professional.\n" + + "Strive for a balance between being empathetic and delivering factual information accurately.\n" + + "You may use lighthearted or playful language if the context is appropriate and enhances the user experience.\n" + + "You operate within the knowledge domain of the 'MIH App'.\n" + + "Here is a description of the MIH App and its features:\n" + + "MIH App Description: MIH is the first super app of Mzansi, designed to streamline both personal and business life. It's an all-in-one platform for managing professional profiles, teams, appointments, and quick calculations. \n" + + "Key Features:\n" + + "- Mzansi Profile: Central hub for managing personal and business information, including business team details." + + "- Mzansi Wallet: Digitally store loyalty cards.\n" + + "- Patient Manager (For Medical Practices): Seamless patient appointment scheduling and data management.\n" + + "- Mzansi AI: Your friendly AI assistant for quick answers and support (that's you!).\n" + + "- Mzansi Directory: A place to search and find out more about the people and businesses across Mzansi.\n" + + "- Calendar: Integrated calendar for managing personal and business appointments.\n" + + "- Calculator: Simple calculator with tip and forex calculation functionality.\n" + + "- MIH Minesweeper: The first game from MIH! It's the classic brain-teaser ready to entertain you no matter where you are.\n" + + "- MIH Access: Manage and view profile access security.\n" + + "**Core Rules and Guidelines:**\n" + + "- **Accuracy First:** Always prioritize providing correct information.\n" + + "- **Uncertainty Handling:** If you are unsure about an answer, politely respond with: 'Please bear with us as we are still learning and do not have all the answers.'\n" + + "- **Response Length:** Aim to keep responses under 250 words. If a more comprehensive answer is required, exceed this limit but offer to elaborate further (e.g., 'Would you like me to elaborate on this topic?').\n" + + "- **Language & Safety:** Never use offensive language or generate harmful content. If a user presses for information that is inappropriate or out of bounds, clearly state why you cannot provide it (e.g., 'I cannot assist with that request as it goes against my safety guidelines.').\n" + + "- **Out-of-Scope Questions:** - If a question is unclear, ask the user to rephrase or clarify it. - If a question is entirely out of your scope and you cannot provide a useful answer, admit you don't know. - If a user is unhappy with your response or needs further assistance beyond your capabilities, suggest they visit the 'Mzansi Innovation Hub Social Media Pages' for more direct support. Do not provide specific links, just refer to the pages generally.\n" + + "- **Target Audience:** Adapt your explanations to beginners and intermediate users, but be prepared for more complex questions from expert users. Ensure your language is clear and easy to understand.\n", + )..addListener(() { + notifyListeners(); // Forward OllamaProvider notifications + }); + } void reset() { toolIndex = 0; @@ -19,8 +62,267 @@ class MzansiAiProvider extends ChangeNotifier { notifyListeners(); } + void setTTSstate(bool ttsOn) { + this.ttsOn = ttsOn; + notifyListeners(); + } + void setStartUpQuestion(String? question) { startUpQuestion = question; notifyListeners(); } + + void clearStartUpQuestion() { + startUpQuestion = null; + } + + MarkdownStyleSheet getLlmChatMarkdownStyle(BuildContext context) { + TextStyle body = TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 16, + fontWeight: FontWeight.w400, + ); + TextStyle heading1 = TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 24, + fontWeight: FontWeight.w400, + ); + TextStyle heading2 = TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 20, + fontWeight: FontWeight.w400, + ); + TextStyle code = TextStyle( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + fontSize: 16, + fontWeight: FontWeight.w400, + ); + BoxDecoration codeBlock = BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10), + topRight: Radius.circular(10), + bottomLeft: Radius.circular(10), + bottomRight: Radius.circular(10), + ), + color: MihColors.getHighlightColor( + MzansiInnovationHub.of(context)!.theme.mode != "Dark"), + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(76), + blurRadius: 8, + offset: Offset(2, 2), + ), + ], + ); + return MarkdownStyleSheet( + a: body, + blockquote: body, + checkbox: body, + del: body, + em: body.copyWith(fontStyle: FontStyle.italic), + h1: heading1, + h2: heading2, + h3: body.copyWith(fontWeight: FontWeight.bold), + h4: body, + h5: body, + h6: body, + listBullet: body, + img: body, + strong: body.copyWith(fontWeight: FontWeight.bold), + p: body, + tableBody: body, + tableHead: body, + code: code, + codeblockDecoration: codeBlock, + ); + } + + LlmChatViewStyle? getChatStyle(BuildContext context) { + return LlmChatViewStyle( + backgroundColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + progressIndicatorColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + menuColor: Colors.black, + // MihColors.getGreenColor( + // MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + disabledButtonStyle: ActionButtonStyle( + icon: MihIcons.mzansiAi, + iconColor: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + iconDecoration: BoxDecoration( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + borderRadius: BorderRadius.circular(25), + ), + ), + recordButtonStyle: ActionButtonStyle( + iconColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + iconDecoration: BoxDecoration( + color: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + borderRadius: BorderRadius.circular(25), + ), + textStyle: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ), + submitButtonStyle: ActionButtonStyle( + icon: Icons.send, + iconColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + iconDecoration: BoxDecoration( + color: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + borderRadius: BorderRadius.circular(25), + ), + textStyle: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ), + stopButtonStyle: ActionButtonStyle( + iconColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + iconDecoration: BoxDecoration( + color: MihColors.getRedColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + borderRadius: BorderRadius.circular(25), + ), + textStyle: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ), + actionButtonBarDecoration: BoxDecoration( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + borderRadius: BorderRadius.circular(25), + ), + // Mzansi AI Chat Style + llmMessageStyle: LlmMessageStyle( + icon: MihIcons.mzansiAi, + iconColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + iconDecoration: BoxDecoration( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + borderRadius: BorderRadius.circular(25), + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topRight: Radius.circular(25), + bottomLeft: Radius.circular(25), + bottomRight: Radius.circular(25), + ), + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(76), + blurRadius: 8, + offset: Offset(2, 2), + ), + ], + ), + markdownStyle: getLlmChatMarkdownStyle(context), + ), + // User Chat Style + userMessageStyle: UserMessageStyle( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(25), + bottomLeft: Radius.circular(25), + bottomRight: Radius.circular(25), + ), + color: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(76), + blurRadius: 8, + offset: Offset(2, 2), + ), + ], + ), + textStyle: TextStyle( + fontSize: 16, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ), + // User Input Style + chatInputStyle: ChatInputStyle( + backgroundColor: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + decoration: BoxDecoration( + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + borderRadius: BorderRadius.circular(25), + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(76), + blurRadius: 8, + offset: Offset(2, 2), + ), + ], + ), + hintStyle: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + hintText: "Ask Mzansi AI...", + ), + // Suggestions Style + suggestionStyle: SuggestionStyle( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(25), + bottomLeft: Radius.circular(25), + bottomRight: Radius.circular(25), + ), + color: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(76), + blurRadius: 8, + offset: Offset(2, 2), + ), + ], + ), + textStyle: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ), + copyButtonStyle: ActionButtonStyle( + iconColor: MihColors.getSecondaryInvertedColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + editButtonStyle: ActionButtonStyle( + iconColor: MihColors.getSecondaryInvertedColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + cancelButtonStyle: ActionButtonStyle( + iconDecoration: BoxDecoration( + color: MihColors.getRedColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + borderRadius: BorderRadius.circular(25), + ), + iconColor: MihColors.getSecondaryInvertedColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + textStyle: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ), + ); + } } diff --git a/Frontend/lib/mih_components/mih_providers/ollama_provider.dart b/Frontend/lib/mih_components/mih_providers/ollama_provider.dart new file mode 100644 index 00000000..13d31c69 --- /dev/null +++ b/Frontend/lib/mih_components/mih_providers/ollama_provider.dart @@ -0,0 +1,141 @@ +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter_ai_toolkit/flutter_ai_toolkit.dart'; +import 'package:ken_logger/ken_logger.dart'; +import 'package:ollama_dart/ollama_dart.dart'; + +class OllamaProvider extends LlmProvider with ChangeNotifier { + OllamaProvider({ + String? baseUrl, + Map? headers, + Map? queryParams, + required String model, + String? systemPrompt, + }) : _client = OllamaClient( + baseUrl: baseUrl, + headers: headers, + queryParams: queryParams, + ), + _model = model, + _systemPrompt = systemPrompt, + _history = []; + final OllamaClient _client; + final String _model; + final List _history; + final String? _systemPrompt; + + @override + Stream generateStream( + String prompt, { + Iterable attachments = const [], + }) async* { + final messages = _mapToOllamaMessages([ + ChatMessage.user(prompt, attachments), + ]); + yield* _generateStream(messages); + } + + @override + Stream sendMessageStream( + String prompt, { + Iterable attachments = const [], + }) async* { + KenLogger.success("sendMessageStream called with: $prompt"); + final userMessage = ChatMessage.user(prompt, attachments); + final llmMessage = ChatMessage.llm(); + _history.addAll([userMessage, llmMessage]); + notifyListeners(); + KenLogger.success("History after adding messages: ${_history.length}"); + final messages = _mapToOllamaMessages(_history); + final stream = _generateStream(messages); + yield* stream.map((chunk) { + llmMessage.append(chunk); + notifyListeners(); + return chunk; + }); + KenLogger.success("Stream completed for: $prompt"); + notifyListeners(); + } + + @override + Iterable get history => _history; + + void resetChat() { + _history.clear(); + notifyListeners(); + } + + @override + set history(Iterable history) { + _history.clear(); + _history.addAll(history); + notifyListeners(); + } + + Stream _generateStream(List messages) async* { + final allMessages = []; + if (_systemPrompt != null && _systemPrompt.isNotEmpty) { + allMessages.add(Message( + role: MessageRole.system, + content: _systemPrompt, + )); + } + allMessages.addAll(messages); + + final stream = _client.generateChatCompletionStream( + request: GenerateChatCompletionRequest( + model: _model, + messages: allMessages, + ), + ); + // final stream = _client.generateChatCompletionStream( + // request: GenerateChatCompletionRequest( + // model: _model, + // messages: messages, + // ), + // ); + + yield* stream.map((res) => res.message.content); + } + + List _mapToOllamaMessages(List messages) { + return messages.map((message) { + switch (message.origin) { + case MessageOrigin.user: + if (message.attachments.isEmpty) { + return Message( + role: MessageRole.user, + content: message.text ?? '', + ); + } + + return Message( + role: MessageRole.user, + content: message.text ?? '', + images: [ + for (final attachment in message.attachments) + if (attachment is ImageFileAttachment) + base64Encode(attachment.bytes) + else + throw LlmFailureException( + 'Unsupported attachment type: $attachment', + ), + ], + ); + + case MessageOrigin.llm: + return Message( + role: MessageRole.assistant, + content: message.text ?? '', + ); + } + }).toList(growable: false); + } + + @override + void dispose() { + _client.endSession(); + super.dispose(); + } +} diff --git a/Frontend/lib/mih_config/mih_colors.dart b/Frontend/lib/mih_config/mih_colors.dart index 724868e4..6c21eee8 100644 --- a/Frontend/lib/mih_config/mih_colors.dart +++ b/Frontend/lib/mih_config/mih_colors.dart @@ -1,27 +1,44 @@ import 'package:flutter/material.dart'; class MihColors { + bool women4Change = true; static Color getPrimaryColor(bool darkMode) { if (darkMode == true) { - return const Color(0XFF3A4454); + // return const Color(0XFF3A4454); // Original + return const Color(0XFF6641b2); // Women4change } else { - return const Color(0XFFbedcfe); + // return const Color(0XFFbedcfe); // Original + return const Color(0xFFE0D1FF); // Women4change } } static Color getSecondaryColor(bool darkMode) { if (darkMode == true) { - return const Color(0XFFbedcfe); + // return const Color(0XFFbedcfe); // Original + return const Color(0xFFE0D1FF); // Women4change } else { - return const Color(0XFF3A4454); + // return const Color(0XFF3A4454); // Original + return const Color(0XFF6641b2); // Women4change + } + } + + static Color getSecondaryInvertedColor(bool darkMode) { + if (darkMode == true) { + // return const Color(0XFF412301); // Original + return const Color(0XFF1f2e00); // Women4change + } else { + // return const Color(0XFFc5bbab); // Original + return const Color(0XFF99be4d); // Women4change } } static Color getHighlightColor(bool darkMode) { if (darkMode == true) { - return const Color(0XFF9bc7fa); + // return const Color(0XFF9bc7fa); + return const Color(0xFFC8AFFB); // Women4change } else { - return const Color(0XFF354866); + // return const Color(0XFF354866); + return const Color(0XFF6641b2); // Women4change } } diff --git a/Frontend/lib/mih_config/mih_theme.dart b/Frontend/lib/mih_config/mih_theme.dart index 22436d37..f6fa2ac3 100644 --- a/Frontend/lib/mih_config/mih_theme.dart +++ b/Frontend/lib/mih_config/mih_theme.dart @@ -14,7 +14,7 @@ class MihTheme { late String loadingAssetText; late TargetPlatform platform; bool kIsWeb = const bool.fromEnvironment('dart.library.js_util'); - String latestVersion = "1.2.2"; + String latestVersion = "1.2.3"; // Options:- // f3f9d2 = Cream // f0f0c9 = cream2 @@ -35,48 +35,116 @@ class MihTheme { ThemeData getData(bool bool) { return ThemeData( - fontFamily: 'Segoe UI', - scaffoldBackgroundColor: MihColors.getPrimaryColor(mode == "Dark"), - // pageTransitionsTheme: PageTransitionsTheme( - // builders: Map.fromIterable( - // TargetPlatform.values, - // value: (dynamic _) => const FadeUpwardsPageTransitionsBuilder(), - // ), - // ), - colorScheme: ColorScheme( - brightness: getBritness(), - primary: MihColors.getSecondaryColor(mode == "Dark"), - onPrimary: MihColors.getPrimaryColor(mode == "Dark"), - secondary: MihColors.getPrimaryColor(mode == "Dark"), - onSecondary: MihColors.getSecondaryColor(mode == "Dark"), - error: MihColors.getRedColor(mode == "Dark"), - onError: MihColors.getPrimaryColor(mode == "Dark"), - surface: MihColors.getPrimaryColor(mode == "Dark"), - onSurface: MihColors.getSecondaryColor(mode == "Dark"), + fontFamily: 'Segoe UI', + scaffoldBackgroundColor: MihColors.getPrimaryColor(mode == "Dark"), + // pageTransitionsTheme: PageTransitionsTheme( + // builders: Map.fromIterable( + // TargetPlatform.values, + // value: (dynamic _) => const FadeUpwardsPageTransitionsBuilder(), + // ), + // ), + colorScheme: ColorScheme( + brightness: getBritness(), + primary: MihColors.getSecondaryColor(mode == "Dark"), + onPrimary: MihColors.getPrimaryColor(mode == "Dark"), + secondary: MihColors.getPrimaryColor(mode == "Dark"), + onSecondary: MihColors.getSecondaryColor(mode == "Dark"), + error: MihColors.getRedColor(mode == "Dark"), + onError: MihColors.getPrimaryColor(mode == "Dark"), + surface: MihColors.getPrimaryColor(mode == "Dark"), + onSurface: MihColors.getSecondaryColor(mode == "Dark"), + ), + datePickerTheme: DatePickerThemeData( + backgroundColor: MihColors.getPrimaryColor(mode == "Dark"), + headerBackgroundColor: MihColors.getSecondaryColor(mode == "Dark"), + headerForegroundColor: MihColors.getPrimaryColor(mode == "Dark"), + ), + appBarTheme: AppBarTheme( + color: MihColors.getSecondaryColor(mode == "Dark"), + foregroundColor: MihColors.getPrimaryColor(mode == "Dark"), + titleTextStyle: TextStyle( + color: MihColors.getPrimaryColor(mode == "Dark"), + fontSize: 25, + fontWeight: FontWeight.bold, ), - datePickerTheme: DatePickerThemeData( - backgroundColor: MihColors.getPrimaryColor(mode == "Dark"), - headerBackgroundColor: MihColors.getSecondaryColor(mode == "Dark"), - headerForegroundColor: MihColors.getPrimaryColor(mode == "Dark"), - ), - appBarTheme: AppBarTheme( + ), + floatingActionButtonTheme: FloatingActionButtonThemeData( + backgroundColor: MihColors.getSecondaryColor(mode == "Dark"), + foregroundColor: MihColors.getPrimaryColor(mode == "Dark"), + extendedTextStyle: + TextStyle(color: MihColors.getPrimaryColor(mode == "Dark")), + ), + drawerTheme: DrawerThemeData( + backgroundColor: MihColors.getPrimaryColor(mode == "Dark"), + ), + // Text selection / cursor color + textSelectionTheme: TextSelectionThemeData( + cursorColor: MihColors.getPrimaryColor(mode == "Dark"), + selectionColor: + MihColors.getPrimaryColor(mode == "Dark").withOpacity(0.25), + selectionHandleColor: MihColors.getPrimaryColor(mode == "Dark"), + ), + tooltipTheme: TooltipThemeData( + decoration: BoxDecoration( color: MihColors.getSecondaryColor(mode == "Dark"), - foregroundColor: MihColors.getPrimaryColor(mode == "Dark"), - titleTextStyle: TextStyle( + borderRadius: BorderRadius.circular(6), + border: Border.all( + width: 1.0, color: MihColors.getPrimaryColor(mode == "Dark"), - fontSize: 25, - fontWeight: FontWeight.bold, ), + boxShadow: [ + BoxShadow( + color: + MihColors.getPrimaryColor(mode == "Dark").withOpacity(0.18), + blurRadius: 6, + offset: const Offset(0, 2), + ), + ], ), - floatingActionButtonTheme: FloatingActionButtonThemeData( - backgroundColor: MihColors.getSecondaryColor(mode == "Dark"), - foregroundColor: MihColors.getPrimaryColor(mode == "Dark"), - extendedTextStyle: - TextStyle(color: MihColors.getPrimaryColor(mode == "Dark")), + textStyle: TextStyle( + color: MihColors.getPrimaryColor(mode == "Dark"), + fontSize: 13, + height: 1.2, ), - drawerTheme: DrawerThemeData( - backgroundColor: MihColors.getPrimaryColor(mode == "Dark"), - )); + waitDuration: const Duration(milliseconds: 500), + showDuration: const Duration(seconds: 3), + preferBelow: true, + verticalOffset: 24, + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + triggerMode: TooltipTriggerMode.longPress, + ), + // // Input decoration (text fields) theme + // inputDecorationTheme: InputDecorationTheme( + // filled: true, + // fillColor: mode == "Dark" + // ? MihColors.getPrimaryColor(true).withOpacity(0.06) + // : MihColors.getPrimaryColor(false).withOpacity(0.03), + // contentPadding: + // const EdgeInsets.symmetric(horizontal: 12, vertical: 10), + // border: OutlineInputBorder( + // borderRadius: BorderRadius.circular(8), + // borderSide: + // BorderSide(color: MihColors.getSecondaryColor(mode == "Dark")), + // ), + // enabledBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular(8), + // borderSide: BorderSide( + // color: + // MihColors.getSecondaryColor(mode == "Dark").withOpacity(0.6)), + // ), + // focusedBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular(8), + // borderSide: BorderSide( + // color: MihColors.getSecondaryColor(mode == "Dark"), width: 2), + // ), + // hintStyle: TextStyle( + // color: + // MihColors.getSecondaryColor(mode == "Dark").withOpacity(0.7)), + // labelStyle: + // TextStyle(color: MihColors.getSecondaryColor(mode == "Dark")), + // errorStyle: TextStyle(color: MihColors.getRedColor(mode == "Dark")), + // ), + ); } String getPlatform() { @@ -165,65 +233,65 @@ class MihTheme { // } // } - AssetImage loadingImage() { - if (mode == "Dark") { - loading = const AssetImage( - 'lib/mih_components/mih_package_components/assets/images/loading_light.gif', - ); - } else { - loading = const AssetImage( - 'lib/mih_components/mih_package_components/assets/images/loading_dark.gif', - ); - } - return loading; - } + // AssetImage loadingImage() { + // if (mode == "Dark") { + // loading = const AssetImage( + // 'lib/mih_components/mih_package_components/assets/images/loading_light.gif', + // ); + // } else { + // loading = const AssetImage( + // 'lib/mih_components/mih_package_components/assets/images/loading_dark.gif', + // ); + // } + // return loading; + // } - AssetImage altLoadingImage() { - if (mode == "Dark") { - loading = const AssetImage( - 'lib/mih_components/mih_package_components/assets/images/loading_dark.gif', - ); - } else { - loading = const AssetImage( - 'lib/mih_components/mih_package_components/assets/images/loading_light.gif', - ); - } - return loading; - } + // AssetImage altLoadingImage() { + // if (mode == "Dark") { + // loading = const AssetImage( + // 'lib/mih_components/mih_package_components/assets/images/loading_dark.gif', + // ); + // } else { + // loading = const AssetImage( + // 'lib/mih_components/mih_package_components/assets/images/loading_light.gif', + // ); + // } + // return loading; + // } - String loadingImageLocation() { - if (mode == "Dark") { - loadingAssetText = - 'lib/mih_components/mih_package_components/assets/images/loading_light.gif'; - } else { - loadingAssetText = - 'lib/mih_components/mih_package_components/assets/images/loading_dark.gif'; - } - return loadingAssetText; - } + // String loadingImageLocation() { + // if (mode == "Dark") { + // loadingAssetText = + // 'lib/mih_components/mih_package_components/assets/images/loading_light.gif'; + // } else { + // loadingAssetText = + // 'lib/mih_components/mih_package_components/assets/images/loading_dark.gif'; + // } + // return loadingAssetText; + // } - String altLoadingImageLocation() { - if (mode == "Dark") { - loadingAssetText = - 'lib/mih_components/mih_package_components/assets/images/loading_dark.gif'; - } else { - loadingAssetText = - 'lib/mih_components/mih_package_components/assets/images/loading_light.gif'; - } - return loadingAssetText; - } + // String altLoadingImageLocation() { + // if (mode == "Dark") { + // loadingAssetText = + // 'lib/mih_components/mih_package_components/assets/images/loading_dark.gif'; + // } else { + // loadingAssetText = + // 'lib/mih_components/mih_package_components/assets/images/loading_light.gif'; + // } + // return loadingAssetText; + // } - AssetImage aiLogoImage() { - if (mode == "Dark") { - return const AssetImage( - 'lib/mih_components/mih_package_components/assets/images/mzansi_ai-dark.png', - ); - } else { - return const AssetImage( - 'lib/mih_components/mih_package_components/assets/images/mzansi_ai-light.png', - ); - } - } + // AssetImage aiLogoImage() { + // if (mode == "Dark") { + // return const AssetImage( + // 'lib/mih_components/mih_package_components/assets/images/mzansi_ai-dark.png', + // ); + // } else { + // return const AssetImage( + // 'lib/mih_components/mih_package_components/assets/images/mzansi_ai-light.png', + // ); + // } + // } void setScreenType(double width) { if (width <= 800) { diff --git a/Frontend/lib/mih_packages/about_mih/package_tools/mih_info.dart b/Frontend/lib/mih_packages/about_mih/package_tools/mih_info.dart index d3456a20..6ffa3070 100644 --- a/Frontend/lib/mih_packages/about_mih/package_tools/mih_info.dart +++ b/Frontend/lib/mih_packages/about_mih/package_tools/mih_info.dart @@ -161,7 +161,6 @@ class _MihInfoState extends State { String heading = "Our Mission"; String mission = "Bridge the digital divide in Mzansi, ensuring that everyone can benefit from the power of technology. We empower lives by providing simple, elegant solutions that elevate daily experiences. With our user-friendly approach, we're making the digital world accessible to all, ensuring no one is left behind in the digital revolution."; - return SizedBox( width: 500, child: Column( @@ -191,6 +190,118 @@ class _MihInfoState extends State { ); } + Widget womenForChange() { + String heading = "MIH Stands with Women For Change SA"; + String mission = + "South Africa is facing a devastating crisis of Gender-Based Violence and Femicide (GBVF), with at least 15 women murdered and 117 women reporting rape daily, often at the hands of known individuals, as highlighted by a shocking 33.8% rise in femicide in the last year, despite the existence of the National Strategic Plan on GBVF (NSP GBVF). Due to the government's lack of urgent action and funding for the NSP GBVF's implementation, organizations like Women For Change are urgently calling for the immediate declaration of GBVF as a National Disaster to mobilize resources and political will for decisive action, which must include judicial reforms (like opposing bail and implementing harsher sentences), immediate funding of the NSP GBVF and the new National Council, making the National Sex Offenders Register publicly accessible, and mandating comprehensive GBVF education and continuous public awareness campaigns."; + return SizedBox( + width: 500, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + heading, + textAlign: TextAlign.center, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25, + ), + ), + const SizedBox( + height: 10, + ), + Wrap( + alignment: WrapAlignment.center, + crossAxisAlignment: WrapCrossAlignment.center, + spacing: 10, + runSpacing: 10, + children: [ + MihButton( + onPressed: () { + launchSocialUrl( + Uri.parse( + "https://www.tiktok.com/@womenforchange.sa", + ), + ); + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + width: 300, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + FaIcon( + FontAwesomeIcons.tiktok, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), + const SizedBox(width: 10), + Text( + "@womenforchange.sa", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + MihButton( + onPressed: () { + launchSocialUrl( + Uri.parse( + "https://www.change.org/p/declare-gbvf-a-national-disaster-in-south-africa", + ), + ); + }, + buttonColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + width: 300, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + FaIcon( + Icons.edit, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), + const SizedBox(width: 10), + Text( + "Sign Petition", + style: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ], + ), + const SizedBox( + height: 10, + ), + Text( + mission, + textAlign: TextAlign.center, + style: const TextStyle( + //fontWeight: FontWeight.bold, + fontSize: 17, + ), + ), + ], + ), + ); + } + Widget mihSocials() { String heading = "Follow Our Journey"; return Column( @@ -736,6 +847,7 @@ class _MihInfoState extends State { spacing: 10, runSpacing: 10, children: [ + womenForChange(), ourVision(), ourMission(), ], diff --git a/Frontend/lib/mih_packages/mih_home/package_tools/mih_business_home.dart b/Frontend/lib/mih_packages/mih_home/package_tools/mih_business_home.dart index acfb992f..e1a421ed 100644 --- a/Frontend/lib/mih_packages/mih_home/package_tools/mih_business_home.dart +++ b/Frontend/lib/mih_packages/mih_home/package_tools/mih_business_home.dart @@ -227,11 +227,11 @@ class _MihBusinessHomeState extends State hintColor: MihColors.getPrimaryColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), onPrefixIconTap: () { - mzansiAiProvider - .setStartUpQuestion(searchController.text); - context.goNamed( - "mzansiAi", - ); + if (searchController.text.isNotEmpty) { + mzansiAiProvider + .setStartUpQuestion(searchController.text); + } + context.goNamed("mzansiAi"); searchController.clear(); }, searchFocusNode: _searchFocusNode, diff --git a/Frontend/lib/mih_packages/mih_home/package_tools/mih_personal_home.dart b/Frontend/lib/mih_packages/mih_home/package_tools/mih_personal_home.dart index 6daf28fb..1c3789ed 100644 --- a/Frontend/lib/mih_packages/mih_home/package_tools/mih_personal_home.dart +++ b/Frontend/lib/mih_packages/mih_home/package_tools/mih_personal_home.dart @@ -286,11 +286,11 @@ class _MihPersonalHomeState extends State hintColor: MihColors.getPrimaryColor( MzansiInnovationHub.of(context)!.theme.mode == "Dark"), onPrefixIconTap: () { - mzansiAiProvider - .setStartUpQuestion(searchController.text); - context.goNamed( - "mzansiAi", - ); + if (searchController.text.isNotEmpty) { + mzansiAiProvider + .setStartUpQuestion(searchController.text); + } + context.goNamed("mzansiAi"); searchController.clear(); }, searchFocusNode: _searchFocusNode, diff --git a/Frontend/lib/mih_packages/mzansi_ai/mzansi_ai.dart b/Frontend/lib/mih_packages/mzansi_ai/mzansi_ai.dart index 1d694165..cea2fd78 100644 --- a/Frontend/lib/mih_packages/mzansi_ai/mzansi_ai.dart +++ b/Frontend/lib/mih_packages/mzansi_ai/mzansi_ai.dart @@ -3,8 +3,8 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_ai_provider.dart'; -import 'package:mzansi_innovation_hub/mih_packages/mzansi_ai/package_tools/ai_chat.dart'; import 'package:flutter/material.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_ai/package_tools/mih_ai_chat.dart'; import 'package:provider/provider.dart'; class MzansiAi extends StatefulWidget { @@ -36,6 +36,9 @@ class _MzansiAiState extends State { temp[const Icon(Icons.chat)] = () { context.read().setToolIndex(0); }; + // temp[const Icon(Icons.chat)] = () { + // context.read().setToolIndex(1); + // }; return MihPackageTools( tools: temp, @@ -45,7 +48,8 @@ class _MzansiAiState extends State { List getToolBody() { List toolBodies = [ - AiChat(), + // AiChat(), + MihAiChat(), ]; return toolBodies; } @@ -53,6 +57,7 @@ class _MzansiAiState extends State { List getToolTitle() { List toolTitles = [ "Ask Mzansi", + // "New Chat", ]; return toolTitles; } diff --git a/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart b/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart index 8119d6a2..dd971442 100644 --- a/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart +++ b/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'dart:convert'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; -import 'package:gpt_markdown/gpt_markdown.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_ai_provider.dart'; @@ -223,8 +222,21 @@ class _AiChatState extends State { child: Column( mainAxisSize: MainAxisSize.max, children: [ + // SelectionArea( + // child: GptMarkdown( + // snapshot.requireData, + // textAlign: TextAlign.left, + // style: TextStyle( + // color: MihColors.getSecondaryColor( + // MzansiInnovationHub.of(context)!.theme.mode == + // "Dark"), + // fontSize: _chatFrontSize, + // fontWeight: FontWeight.bold, + // ), + // ), + // ), SelectionArea( - child: GptMarkdown( + child: Text( snapshot.requireData, textAlign: TextAlign.left, style: TextStyle( @@ -600,9 +612,6 @@ class _AiChatState extends State { _voicesString = _voices.map((_voice) => _voice["name"] as String).toList(); _voicesString.sort(); - // print( - // "=================== Voices ===================\n$_voicesString"); - setTtsVoice(_voicesString.first); }); } catch (e) { diff --git a/Frontend/lib/mih_packages/mzansi_ai/package_tools/mih_ai_chat.dart b/Frontend/lib/mih_packages/mzansi_ai/package_tools/mih_ai_chat.dart new file mode 100644 index 00000000..1888a393 --- /dev/null +++ b/Frontend/lib/mih_packages/mzansi_ai/package_tools/mih_ai_chat.dart @@ -0,0 +1,294 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_ai_toolkit/flutter_ai_toolkit.dart'; +import 'package:flutter_speed_dial/flutter_speed_dial.dart'; +import 'package:flutter_tts/flutter_tts.dart'; +import 'package:ken_logger/ken_logger.dart'; +import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_ai_provider.dart'; +import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; +import 'package:provider/provider.dart'; + +class MihAiChat extends StatefulWidget { + const MihAiChat({super.key}); + + @override + State createState() => _MihAiChatState(); +} + +class _MihAiChatState extends State { + final FlutterTts _flutterTts = FlutterTts(); + + Widget noMessagescDisplay() { + return Center( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox(height: 50), + Icon( + MihIcons.mzansiAi, + size: 165, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + const SizedBox(height: 10), + Text( + "Mzansi AI is here to help", + textAlign: TextAlign.center, + overflow: TextOverflow.visible, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ), + const SizedBox(height: 25), + Center( + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.normal, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + children: [ + TextSpan( + text: + "Send us a message and we'll try our best to assist you"), + ], + ), + ), + ), + Center( + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.normal, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + children: [ + TextSpan(text: "Press "), + WidgetSpan( + alignment: PlaceholderAlignment.middle, + child: Icon( + Icons.menu, + size: 20, + color: MihColors.getSecondaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), + ), + TextSpan(text: " to start a new chat or read last message"), + ], + ), + ), + ), + ], + ), + ), + ); + } + + void resetChat(MzansiAiProvider aiProvider) { + aiProvider.ollamaProvider.resetChat(); + } + + void speakLastMessage(MzansiAiProvider aiProvider) { + final history = aiProvider.ollamaProvider.history; + if (history.isNotEmpty) { + final historyList = history.toList(); + for (int i = historyList.length - 1; i >= 0; i--) { + if (historyList[i].origin == MessageOrigin.llm && + historyList[i].text != null && + historyList[i].text!.isNotEmpty) { + _flutterTts.speak(historyList[i].text!); + return; + } + } + } + } + + void stopTTS(MzansiAiProvider aiProvider) { + _flutterTts.stop(); + aiProvider.setTTSstate(false); + } + + Future initTts(MzansiAiProvider aiProvider) async { + try { + await _flutterTts.setSpeechRate(!kIsWeb ? 0.55 : 1); + // await _flutterTts.setLanguage("en-US"); + + // Safer voice selection with error handling + _flutterTts.getVoices.then((data) { + try { + final voices = List.from(data); + final englishVoices = voices.where((voice) { + final name = voice["name"]?.toString().toLowerCase() ?? ''; + final locale = voice["locale"]?.toString().toLowerCase() ?? ''; + return name.contains("en-us") || locale.contains("en_us"); + }).toList(); + + if (englishVoices.isNotEmpty) { + // Use the first available English voice + _flutterTts.setVoice({"name": englishVoices.first["name"]}); + } + // If no voices found, use default + } catch (e) { + KenLogger.error("Error setting TTS voice: $e"); + } + }); + } catch (e) { + KenLogger.error("Error initializing TTS: $e"); + } + + _flutterTts.setStartHandler(() { + if (mounted) { + aiProvider.setTTSstate(true); + } + }); + + _flutterTts.setCompletionHandler(() { + if (mounted) { + aiProvider.setTTSstate(false); + } + }); + + _flutterTts.setErrorHandler((message) { + if (mounted) { + aiProvider.setTTSstate(false); + } + }); + } + + void initStartQuestion() { + WidgetsBinding.instance.addPostFrameCallback((_) async { + final mzansiAiProvider = context.read(); + final startQuestion = mzansiAiProvider.startUpQuestion; + if (startQuestion != null && startQuestion.isNotEmpty) { + final stream = + mzansiAiProvider.ollamaProvider.sendMessageStream(startQuestion); + stream.listen((chunk) {}); + mzansiAiProvider.clearStartUpQuestion(); + } + }); + } + + @override + void initState() { + super.initState(); + MzansiAiProvider aiProvider = context.read(); + initTts(aiProvider); + initStartQuestion(); + } + + @override + void dispose() { + _flutterTts.stop(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Consumer( + builder: + (BuildContext context, MzansiAiProvider aiProvider, Widget? child) { + bool hasHistory = aiProvider.ollamaProvider.history.isNotEmpty; + String? lastMessage; + if (hasHistory) { + final histroyList = aiProvider.ollamaProvider.history.toList(); + lastMessage = histroyList[histroyList.length - 1].text; + } + + return Stack( + children: [ + LlmChatView( + provider: aiProvider.ollamaProvider, + messageSender: aiProvider.ollamaProvider.sendMessageStream, + // welcomeMessage: + // "Mzansi AI is here to help. Send us a messahe and we'll try our best to assist you.", + autofocus: false, + enableAttachments: false, + enableVoiceNotes: false, + style: aiProvider.getChatStyle(context), + suggestions: [ + "What is mih all about?", + "What are the features of MIH?" + ], + ), + if (hasHistory && lastMessage != null) + Positioned( + bottom: 80, + left: 10, + child: MihButton( + width: 35, + height: 35, + onPressed: () { + if (!aiProvider.ttsOn) { + speakLastMessage(aiProvider); + } else { + stopTTS(aiProvider); + } + }, + buttonColor: !aiProvider.ttsOn + ? MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark") + : MihColors.getRedColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + child: Icon( + !aiProvider.ttsOn ? Icons.volume_up : Icons.volume_off, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + ), + ), + ), + Positioned( + right: 10, + bottom: 80, + child: MihFloatingMenu( + animatedIcon: AnimatedIcons.menu_close, + children: [ + SpeedDialChild( + child: Icon( + Icons.refresh, + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + ), + label: "New Chat", + labelBackgroundColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + labelStyle: TextStyle( + color: MihColors.getPrimaryColor( + MzansiInnovationHub.of(context)!.theme.mode == + "Dark"), + fontWeight: FontWeight.bold, + ), + backgroundColor: MihColors.getGreenColor( + MzansiInnovationHub.of(context)!.theme.mode == "Dark"), + onTap: () { + resetChat(aiProvider); + }, + ), + ], + ), + ), + if (!hasHistory) noMessagescDisplay(), + ], + ); + }, + ); + } +} diff --git a/Frontend/linux/flutter/generated_plugin_registrant.cc b/Frontend/linux/flutter/generated_plugin_registrant.cc index 88c7a8bd..4f4c5872 100644 --- a/Frontend/linux/flutter/generated_plugin_registrant.cc +++ b/Frontend/linux/flutter/generated_plugin_registrant.cc @@ -7,16 +7,24 @@ #include "generated_plugin_registrant.h" #include +#include #include +#include #include void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) file_saver_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "FileSaverPlugin"); file_saver_plugin_register_with_registrar(file_saver_registrar); + g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); + file_selector_plugin_register_with_registrar(file_selector_linux_registrar); g_autoptr(FlPluginRegistrar) printing_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "PrintingPlugin"); printing_plugin_register_with_registrar(printing_registrar); + g_autoptr(FlPluginRegistrar) record_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "RecordLinuxPlugin"); + record_linux_plugin_register_with_registrar(record_linux_registrar); g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); diff --git a/Frontend/linux/flutter/generated_plugins.cmake b/Frontend/linux/flutter/generated_plugins.cmake index 561713c0..8ee15a6f 100644 --- a/Frontend/linux/flutter/generated_plugins.cmake +++ b/Frontend/linux/flutter/generated_plugins.cmake @@ -4,7 +4,9 @@ list(APPEND FLUTTER_PLUGIN_LIST file_saver + file_selector_linux printing + record_linux url_launcher_linux ) diff --git a/Frontend/macos/Flutter/GeneratedPluginRegistrant.swift b/Frontend/macos/Flutter/GeneratedPluginRegistrant.swift index d79f29c2..25486c96 100644 --- a/Frontend/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/Frontend/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,6 +9,10 @@ import app_settings import device_info_plus import file_picker import file_saver +import file_selector_macos +import firebase_app_check +import firebase_auth +import firebase_core import flutter_tts import geolocator_apple import local_auth_darwin @@ -16,9 +20,11 @@ import mobile_scanner import package_info_plus import path_provider_foundation import printing +import record_macos import screen_brightness_macos import share_plus import shared_preferences_foundation +import speech_to_text import sqflite_darwin import syncfusion_pdfviewer_macos import url_launcher_macos @@ -29,6 +35,10 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin")) FileSaverPlugin.register(with: registry.registrar(forPlugin: "FileSaverPlugin")) + FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) + FLTFirebaseAppCheckPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAppCheckPlugin")) + FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) + FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) FlutterTtsPlugin.register(with: registry.registrar(forPlugin: "FlutterTtsPlugin")) GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) FLALocalAuthPlugin.register(with: registry.registrar(forPlugin: "FLALocalAuthPlugin")) @@ -36,9 +46,11 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin")) + RecordMacOsPlugin.register(with: registry.registrar(forPlugin: "RecordMacOsPlugin")) ScreenBrightnessMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenBrightnessMacosPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + SpeechToTextPlugin.register(with: registry.registrar(forPlugin: "SpeechToTextPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SyncfusionFlutterPdfViewerPlugin.register(with: registry.registrar(forPlugin: "SyncfusionFlutterPdfViewerPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) diff --git a/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png index 24832016..e7031513 100644 Binary files a/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png and b/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png index e5246083..b5cccd9c 100644 Binary files a/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png and b/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png index 4f4c0c5b..494c06e9 100644 Binary files a/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png and b/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png index 30ae352a..bbcdafc2 100644 Binary files a/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png and b/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png index a97ff5f5..c1a99ac2 100644 Binary files a/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png and b/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png index 68fe215f..d6bb6b00 100644 Binary files a/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png and b/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png index 549aaddf..af4ceef0 100644 Binary files a/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png and b/Frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/Frontend/pubspec.lock b/Frontend/pubspec.lock index 697e5b35..ec7cf4f8 100644 --- a/Frontend/pubspec.lock +++ b/Frontend/pubspec.lock @@ -9,6 +9,14 @@ packages: url: "https://pub.dev" source: hosted version: "82.0.0" + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "8a1f5f3020ef2a74fb93f7ab3ef127a8feea33a7a2276279113660784ee7516a" + url: "https://pub.dev" + source: hosted + version: "1.3.64" analyzer: dependency: transitive description: @@ -201,6 +209,46 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + camera: + dependency: transitive + description: + name: camera + sha256: "87a27e0553e3432119c1c2f6e4b9a1bbf7d2c660552b910bfa59185a9facd632" + url: "https://pub.dev" + source: hosted + version: "0.11.2+1" + camera_android_camerax: + dependency: transitive + description: + name: camera_android_camerax + sha256: "58b8fe843a3c83fd1273c00cb35f5a8ae507f6cc9b2029bcf7e2abba499e28d8" + url: "https://pub.dev" + source: hosted + version: "0.6.19+1" + camera_avfoundation: + dependency: transitive + description: + name: camera_avfoundation + sha256: "951ef122d01ebba68b7a54bfe294e8b25585635a90465c311b2f875ae72c412f" + url: "https://pub.dev" + source: hosted + version: "0.9.21+2" + camera_platform_interface: + dependency: transitive + description: + name: camera_platform_interface + sha256: "98cfc9357e04bad617671b4c1f78a597f25f08003089dd94050709ae54effc63" + url: "https://pub.dev" + source: hosted + version: "2.12.0" + camera_web: + dependency: transitive + description: + name: camera_web + sha256: "595f28c89d1fb62d77c73c633193755b781c6d2e0ebcd8dc25b763b514e6ba8f" + url: "https://pub.dev" + source: hosted + version: "0.3.5" characters: dependency: transitive description: @@ -385,22 +433,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.3" - fetch_api: - dependency: transitive - description: - name: fetch_api - sha256: "24cbd5616f3d4008c335c197bb90bfa0eb43b9e55c6de5c60d1f805092636034" - url: "https://pub.dev" - source: hosted - version: "2.3.1" - fetch_client: - dependency: transitive - description: - name: fetch_client - sha256: "375253f4efe64303c793fb17fe90771c591320b2ae11fb29cb5b406cc8533c00" - url: "https://pub.dev" - source: hosted - version: "1.1.4" ffi: dependency: transitive description: @@ -433,6 +465,150 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.1" + file_selector: + dependency: transitive + description: + name: file_selector + sha256: "5f1d15a7f17115038f433d1b0ea57513cc9e29a9d5338d166cb0bef3fa90a7a0" + url: "https://pub.dev" + source: hosted + version: "1.0.4" + file_selector_android: + dependency: transitive + description: + name: file_selector_android + sha256: "1ce58b609289551f8ec07265476720e77d19764339cc1d8e4df3c4d34dac6499" + url: "https://pub.dev" + source: hosted + version: "0.5.1+17" + file_selector_ios: + dependency: transitive + description: + name: file_selector_ios + sha256: fe9f52123af16bba4ad65bd7e03defbbb4b172a38a8e6aaa2a869a0c56a5f5fb + url: "https://pub.dev" + source: hosted + version: "0.5.3+2" + file_selector_linux: + dependency: transitive + description: + name: file_selector_linux + sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33" + url: "https://pub.dev" + source: hosted + version: "0.9.3+2" + file_selector_macos: + dependency: transitive + description: + name: file_selector_macos + sha256: "19124ff4a3d8864fdc62072b6a2ef6c222d55a3404fe14893a3c02744907b60c" + url: "https://pub.dev" + source: hosted + version: "0.9.4+4" + file_selector_platform_interface: + dependency: transitive + description: + name: file_selector_platform_interface + sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b + url: "https://pub.dev" + source: hosted + version: "2.6.2" + file_selector_web: + dependency: transitive + description: + name: file_selector_web + sha256: c4c0ea4224d97a60a7067eca0c8fd419e708ff830e0c83b11a48faf566cec3e7 + url: "https://pub.dev" + source: hosted + version: "0.9.4+2" + file_selector_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b" + url: "https://pub.dev" + source: hosted + version: "0.9.3+4" + firebase_ai: + dependency: transitive + description: + name: firebase_ai + sha256: "6bffa52bc4b9557b73f59de12ec36349bde76f772431d0702c7ecb4bfeeeb21b" + url: "https://pub.dev" + source: hosted + version: "3.5.0" + firebase_app_check: + dependency: transitive + description: + name: firebase_app_check + sha256: "4d00b502f510ee97cdb395e95a31a8b871fc96cb917ffc60591528d3c9735986" + url: "https://pub.dev" + source: hosted + version: "0.4.1+2" + firebase_app_check_platform_interface: + dependency: transitive + description: + name: firebase_app_check_platform_interface + sha256: "7d104d01b00e5dec367dc79184ad99bd1941f2d839b5ef41156b2330c18af13f" + url: "https://pub.dev" + source: hosted + version: "0.2.1+2" + firebase_app_check_web: + dependency: transitive + description: + name: firebase_app_check_web + sha256: "885a1a7b8e33c52afaf9c5d75eca616ae310d6ea90322e9a462f8c154ad16b64" + url: "https://pub.dev" + source: hosted + version: "0.2.2" + firebase_auth: + dependency: transitive + description: + name: firebase_auth + sha256: e54fb3ba57de041d832574126a37726eedf0f57400869f1942b0ca8ce4a6e209 + url: "https://pub.dev" + source: hosted + version: "6.1.2" + firebase_auth_platform_interface: + dependency: transitive + description: + name: firebase_auth_platform_interface + sha256: "421f95dc553cb283ed9d4d140e719800c0331d49ed37b962e513c9d1d61b090b" + url: "https://pub.dev" + source: hosted + version: "8.1.4" + firebase_auth_web: + dependency: transitive + description: + name: firebase_auth_web + sha256: a064ffee202f7d42d62e2c01775899d4ffcb83c602af07632f206acd46a0964e + url: "https://pub.dev" + source: hosted + version: "6.1.0" + firebase_core: + dependency: transitive + description: + name: firebase_core + sha256: "1f2dfd9f535d81f8b06d7a50ecda6eac1e6922191ed42e09ca2c84bd2288927c" + url: "https://pub.dev" + source: hosted + version: "4.2.1" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: cccb4f572325dc14904c02fcc7db6323ad62ba02536833dddb5c02cac7341c64 + url: "https://pub.dev" + source: hosted + version: "6.0.2" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: ff18fabb0ad0ed3595d2f2c85007ecc794aadecdff5b3bb1460b7ee47cded398 + url: "https://pub.dev" + source: hosted + version: "3.3.0" fixnum: dependency: transitive description: @@ -454,6 +630,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_ai_toolkit: + dependency: "direct main" + description: + name: flutter_ai_toolkit + sha256: b653814f9aac05d84f15db0daf1bf90e9bd9177abeba378c6f1d4a75bb2099a5 + url: "https://pub.dev" + source: hosted + version: "0.10.0" flutter_cache_manager: dependency: transitive description: @@ -478,6 +662,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.6.15" + flutter_context_menu: + dependency: transitive + description: + name: flutter_context_menu + sha256: "79fe00cd7e3ac3840a552cb3e653d8eb61d827b6c04c559e219973a1dc769165" + url: "https://pub.dev" + source: hosted + version: "0.3.0" flutter_launcher_icons: dependency: "direct main" description: @@ -510,14 +702,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.0" - flutter_math_fork: - dependency: transitive + flutter_markdown_plus: + dependency: "direct main" description: - name: flutter_math_fork - sha256: "6d5f2f1aa57ae539ffb0a04bb39d2da67af74601d685a161aff7ce5bda5fa407" + name: flutter_markdown_plus + sha256: "7f349c075157816da399216a4127096108fd08e1ac931e34e72899281db4113c" url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "1.0.5" flutter_native_splash: dependency: "direct main" description: @@ -534,6 +726,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.1" + flutter_picture_taker: + dependency: transitive + description: + name: flutter_picture_taker + sha256: d24d4c10e42324832b550bd59d1fe84129e860b75b4b2d57d6b398a41fd5dc9a + url: "https://pub.dev" + source: hosted + version: "0.2.0" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -588,10 +788,10 @@ packages: dependency: transitive description: name: freezed_annotation - sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 + sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8" url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "3.1.0" frontend_server_client: dependency: transitive description: @@ -648,14 +848,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.5" - gif_view: - dependency: "direct main" - description: - name: gif_view - sha256: "4c7e17c134719531dabab54af121e4600d63283f56f3aff57c16db54766b67bc" - url: "https://pub.dev" - source: hosted - version: "1.0.3" glob: dependency: transitive description: @@ -680,6 +872,14 @@ packages: url: "https://pub.dev" source: hosted version: "16.1.0" + google_fonts: + dependency: transitive + description: + name: google_fonts + sha256: "517b20870220c48752eafa0ba1a797a092fb22df0d89535fd9991e86ee2cdd9c" + url: "https://pub.dev" + source: hosted + version: "6.3.2" google_mobile_ads: dependency: "direct main" description: @@ -688,14 +888,6 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.0" - gpt_markdown: - dependency: "direct main" - description: - name: gpt_markdown - sha256: "68d5337c8a00fc03a37dbddf84a6fd90401c30e99b6baf497ef9522a81fc34ee" - url: "https://pub.dev" - source: hosted - version: "1.1.2" graphs: dependency: transitive description: @@ -744,6 +936,70 @@ packages: url: "https://pub.dev" source: hosted version: "4.5.4" + image_picker: + dependency: transitive + description: + name: image_picker + sha256: "736eb56a911cf24d1859315ad09ddec0b66104bc41a7f8c5b96b4e2620cf5041" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + sha256: "28f3987ca0ec702d346eae1d90eda59603a2101b52f1e234ded62cff1d5cfa6e" + url: "https://pub.dev" + source: hosted + version: "0.8.13+1" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: "40c2a6a0da15556dc0f8e38a3246064a971a9f512386c3339b89f76db87269b6" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: eb06fe30bab4c4497bad449b66448f50edcc695f1c59408e78aa3a8059eb8f0e + url: "https://pub.dev" + source: hosted + version: "0.8.13" + image_picker_linux: + dependency: transitive + description: + name: image_picker_linux + sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4" + url: "https://pub.dev" + source: hosted + version: "0.2.2" + image_picker_macos: + dependency: transitive + description: + name: image_picker_macos + sha256: d58cd9d67793d52beefd6585b12050af0a7663c0c2a6ece0fb110a35d6955e04 + url: "https://pub.dev" + source: hosted + version: "0.2.2" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: "567e056716333a1647c64bb6bd873cff7622233a5c3f694be28a583d4715690c" + url: "https://pub.dev" + source: hosted + version: "2.11.1" + image_picker_windows: + dependency: transitive + description: + name: image_picker_windows + sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae + url: "https://pub.dev" + source: hosted + version: "0.2.2" intl: dependency: "direct main" description: @@ -872,6 +1128,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" + markdown: + dependency: transitive + description: + name: markdown + sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1" + url: "https://pub.dev" + source: hosted + version: "7.3.0" matcher: dependency: transitive description: @@ -956,10 +1220,10 @@ packages: dependency: "direct main" description: name: ollama_dart - sha256: "4e40bc499b6fe46ba54a004d2da601c40bd73d66e3f18cf7b03225ccf3d481a6" + sha256: "55a45e381f3cf24791df510e287f353e776d376f556d34ba49b09bc918eee319" url: "https://pub.dev" source: hosted - version: "0.2.2+1" + version: "0.2.5" os_detect: dependency: transitive description: @@ -1072,6 +1336,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + pedantic: + dependency: transitive + description: + name: pedantic + sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" + url: "https://pub.dev" + source: hosted + version: "1.11.1" petitparser: dependency: transitive description: @@ -1176,6 +1448,102 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + quick_actions: + dependency: "direct main" + description: + name: quick_actions + sha256: "7e35dd6a21f5bbd21acf6899039eaf85001a5ac26d52cbd6a8a2814505b90798" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + quick_actions_android: + dependency: transitive + description: + name: quick_actions_android + sha256: "612c9d53364c641ddcdeafed83c68fc14efb1bf4f686979d755024fc976fc888" + url: "https://pub.dev" + source: hosted + version: "1.0.23" + quick_actions_ios: + dependency: transitive + description: + name: quick_actions_ios + sha256: ee2cd54e3bd674eb031ca195b3b9974583638d141493aec1066dee3b2599ed08 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + quick_actions_platform_interface: + dependency: transitive + description: + name: quick_actions_platform_interface + sha256: "1fec7068db5122cd019e9340d3d7be5d36eab099695ef3402c7059ee058329a4" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + record: + dependency: transitive + description: + name: record + sha256: "6bad72fb3ea6708d724cf8b6c97c4e236cf9f43a52259b654efeb6fd9b737f1f" + url: "https://pub.dev" + source: hosted + version: "6.1.2" + record_android: + dependency: transitive + description: + name: record_android + sha256: fb54ee4e28f6829b8c580252a9ef49d9c549cfd263b0660ad7eeac0908658e9f + url: "https://pub.dev" + source: hosted + version: "1.4.4" + record_ios: + dependency: transitive + description: + name: record_ios + sha256: "765b42ac1be019b1674ddd809b811fc721fe5a93f7bb1da7803f0d16772fd6d7" + url: "https://pub.dev" + source: hosted + version: "1.1.4" + record_linux: + dependency: transitive + description: + name: record_linux + sha256: "235b1f1fb84e810f8149cc0c2c731d7d697f8d1c333b32cb820c449bf7bb72d8" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + record_macos: + dependency: transitive + description: + name: record_macos + sha256: "842ea4b7e95f4dd237aacffc686d1b0ff4277e3e5357865f8d28cd28bc18ed95" + url: "https://pub.dev" + source: hosted + version: "1.1.2" + record_platform_interface: + dependency: transitive + description: + name: record_platform_interface + sha256: b0065fdf1ec28f5a634d676724d388a77e43ce7646fb049949f58c69f3fcb4ed + url: "https://pub.dev" + source: hosted + version: "1.4.0" + record_web: + dependency: transitive + description: + name: record_web + sha256: "20ac10d56514cb9f8cecc8f3579383084fdfb43b0d04e05a95244d0d76091d90" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + record_windows: + dependency: transitive + description: + name: record_windows + sha256: "223258060a1d25c62bae18282c16783f28581ec19401d17e56b5205b9f039d78" + url: "https://pub.dev" + source: hosted + version: "1.0.7" redacted: dependency: "direct main" description: @@ -1389,6 +1757,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.1" + speech_to_text: + dependency: "direct main" + description: + name: speech_to_text + sha256: c07557664974afa061f221d0d4186935bea4220728ea9446702825e8b988db04 + url: "https://pub.dev" + source: hosted + version: "7.3.0" + speech_to_text_platform_interface: + dependency: transitive + description: + name: speech_to_text_platform_interface + sha256: a1935847704e41ee468aad83181ddd2423d0833abe55d769c59afca07adb5114 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + speech_to_text_windows: + dependency: transitive + description: + name: speech_to_text_windows + sha256: "2c9846d18253c7bbe059a276297ef9f27e8a2745dead32192525beb208195072" + url: "https://pub.dev" + source: hosted + version: "1.0.0+beta.8" sprintf: dependency: transitive description: @@ -1581,14 +1973,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.2" - tuple: - dependency: transitive - description: - name: tuple - sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151 - url: "https://pub.dev" - source: hosted - version: "2.0.2" typed_data: dependency: transitive description: @@ -1613,6 +1997,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.2" + universal_platform: + dependency: transitive + description: + name: universal_platform + sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec" + url: "https://pub.dev" + source: hosted + version: "1.1.0" upgrader: dependency: "direct main" description: @@ -1757,6 +2149,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + waveform_flutter: + dependency: transitive + description: + name: waveform_flutter + sha256: "08c9e98d4cf119428d8b3c083ed42c11c468623eaffdf30420ae38e36662922a" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + waveform_recorder: + dependency: transitive + description: + name: waveform_recorder + sha256: "1ca0a19b143d1bdef2adfb3d28f0627c18aee5285235c8cf81a89bf29a0420e1" + url: "https://pub.dev" + source: hosted + version: "1.8.0" web: dependency: transitive description: diff --git a/Frontend/pubspec.yaml b/Frontend/pubspec.yaml index 7eee6769..c0aa09bd 100644 --- a/Frontend/pubspec.yaml +++ b/Frontend/pubspec.yaml @@ -1,7 +1,7 @@ name: mzansi_innovation_hub description: "" publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 1.2.2+103 +version: 1.2.3+112 # version: 1.1.1+97 #--- Updated version for upgrader package testing environment: @@ -22,7 +22,6 @@ dependencies: supertokens_flutter: ^0.6.3 http: ^1.2.1 args: ^2.7.0 - gif_view: ^1.0.3 intl: ^0.20.2 flutter_native_splash: ^2.4.6 printing: ^5.13.3 @@ -54,11 +53,14 @@ dependencies: go_router: ^16.1.0 screen_brightness: ^2.1.6 cached_network_image: ^3.4.1 - gpt_markdown: ^1.1.2 upgrader: ^12.0.0 screenshot: ^3.0.0 file_saver: ^0.3.1 provider: ^6.1.5+1 + flutter_ai_toolkit: ^0.10.0 + flutter_markdown_plus: ^1.0.5 + speech_to_text: ^7.3.0 + quick_actions: ^1.1.0 dev_dependencies: flutter_test: diff --git a/Frontend/web/favicon.png b/Frontend/web/favicon.png index 4f4c0c5b..fac4164f 100644 Binary files a/Frontend/web/favicon.png and b/Frontend/web/favicon.png differ diff --git a/Frontend/web/icons/Icon-192.png b/Frontend/web/icons/Icon-192.png index 3fe523f0..41602f9b 100644 Binary files a/Frontend/web/icons/Icon-192.png and b/Frontend/web/icons/Icon-192.png differ diff --git a/Frontend/web/icons/Icon-512.png b/Frontend/web/icons/Icon-512.png index 68fe215f..d75230b9 100644 Binary files a/Frontend/web/icons/Icon-512.png and b/Frontend/web/icons/Icon-512.png differ diff --git a/Frontend/web/icons/Icon-maskable-192.png b/Frontend/web/icons/Icon-maskable-192.png index 3fe523f0..41602f9b 100644 Binary files a/Frontend/web/icons/Icon-maskable-192.png and b/Frontend/web/icons/Icon-maskable-192.png differ diff --git a/Frontend/web/icons/Icon-maskable-512.png b/Frontend/web/icons/Icon-maskable-512.png index 68fe215f..d75230b9 100644 Binary files a/Frontend/web/icons/Icon-maskable-512.png and b/Frontend/web/icons/Icon-maskable-512.png differ diff --git a/Frontend/web/manifest.json b/Frontend/web/manifest.json index e8ad7e18..fd4b3e17 100644 --- a/Frontend/web/manifest.json +++ b/Frontend/web/manifest.json @@ -3,8 +3,8 @@ "short_name": "MIH", "start_url": ".", "display": "standalone", - "background_color": "#3A4454", - "theme_color": "#3A4454", + "background_color": "#6641b2", + "theme_color": "#6641b2", "description": "Digitizing Mzansi one process at a time. Discover essential Mzansi apps to streamline your personal and professional life. Simplify your daily tasks with our user-friendly solutions.", "orientation": "any", "prefer_related_applications": false, diff --git a/Frontend/windows/flutter/generated_plugin_registrant.cc b/Frontend/windows/flutter/generated_plugin_registrant.cc index 9dbdf6de..f08708cc 100644 --- a/Frontend/windows/flutter/generated_plugin_registrant.cc +++ b/Frontend/windows/flutter/generated_plugin_registrant.cc @@ -7,19 +7,30 @@ #include "generated_plugin_registrant.h" #include +#include +#include +#include #include #include #include #include #include +#include #include #include +#include #include #include void RegisterPlugins(flutter::PluginRegistry* registry) { FileSaverPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("FileSaverPlugin")); + FileSelectorWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FileSelectorWindows")); + FirebaseAuthPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseAuthPluginCApi")); + FirebaseCorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); FlDownloaderPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("FlDownloaderPluginCApi")); FlutterTtsPluginRegisterWithRegistrar( @@ -30,10 +41,14 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("LocalAuthPlugin")); PrintingPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("PrintingPlugin")); + RecordWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("RecordWindowsPluginCApi")); ScreenBrightnessWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ScreenBrightnessWindowsPlugin")); SharePlusWindowsPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); + SpeechToTextWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SpeechToTextWindows")); SyncfusionPdfviewerWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("SyncfusionPdfviewerWindowsPlugin")); UrlLauncherWindowsRegisterWithRegistrar( diff --git a/Frontend/windows/flutter/generated_plugins.cmake b/Frontend/windows/flutter/generated_plugins.cmake index 5d18711f..46e96ea5 100644 --- a/Frontend/windows/flutter/generated_plugins.cmake +++ b/Frontend/windows/flutter/generated_plugins.cmake @@ -4,13 +4,18 @@ list(APPEND FLUTTER_PLUGIN_LIST file_saver + file_selector_windows + firebase_auth + firebase_core fl_downloader flutter_tts geolocator_windows local_auth_windows printing + record_windows screen_brightness_windows share_plus + speech_to_text_windows syncfusion_pdfviewer_windows url_launcher_windows ) diff --git a/Frontend/windows/runner/resources/app_icon.ico b/Frontend/windows/runner/resources/app_icon.ico index e787f95b..af93bd81 100644 Binary files a/Frontend/windows/runner/resources/app_icon.ico and b/Frontend/windows/runner/resources/app_icon.ico differ