From b6134c55064357cbd478eeed00ae246141116c89 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Fri, 29 Aug 2025 23:24:27 +0200 Subject: [PATCH 01/16] upgrade mapbox --- covas_mobile_new/.gitignore | 45 + covas_mobile_new/.metadata | 45 + covas_mobile_new/README.md | 16 + covas_mobile_new/analysis_options.yaml | 28 + covas_mobile_new/android/.gitignore | 14 + covas_mobile_new/android/app/build.gradle.kts | 44 + .../android/app/src/debug/AndroidManifest.xml | 7 + .../android/app/src/main/AndroidManifest.xml | 45 + .../example/covas_mobile_new/MainActivity.kt | 5 + .../res/drawable-v21/launch_background.xml | 12 + .../main/res/drawable/launch_background.xml | 12 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 544 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 442 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 721 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 1031 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 1443 bytes .../app/src/main/res/values-night/styles.xml | 18 + .../app/src/main/res/values/styles.xml | 18 + .../app/src/profile/AndroidManifest.xml | 7 + covas_mobile_new/android/build.gradle.kts | 24 + .../reports/problems/problems-report.html | 663 ++++++++++ covas_mobile_new/android/gradle.properties | 3 + .../gradle/wrapper/gradle-wrapper.properties | 5 + covas_mobile_new/android/settings.gradle.kts | 26 + covas_mobile_new/ios/.gitignore | 34 + .../ios/Flutter/AppFrameworkInfo.plist | 26 + covas_mobile_new/ios/Flutter/Debug.xcconfig | 1 + covas_mobile_new/ios/Flutter/Release.xcconfig | 1 + .../ios/Runner.xcodeproj/project.pbxproj | 616 +++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + .../xcshareddata/xcschemes/Runner.xcscheme | 101 ++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + covas_mobile_new/ios/Runner/AppDelegate.swift | 13 + .../AppIcon.appiconset/Contents.json | 122 ++ .../Icon-App-1024x1024@1x.png | Bin 0 -> 10932 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 295 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 406 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 450 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 282 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 0 -> 462 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 0 -> 704 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 406 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 0 -> 586 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 862 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 862 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 1674 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 762 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 1226 bytes .../Icon-App-83.5x83.5@2x.png | Bin 0 -> 1418 bytes .../LaunchImage.imageset/Contents.json | 23 + .../LaunchImage.imageset/LaunchImage.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/README.md | 5 + .../Runner/Base.lproj/LaunchScreen.storyboard | 37 + .../ios/Runner/Base.lproj/Main.storyboard | 26 + covas_mobile_new/ios/Runner/Info.plist | 49 + .../ios/Runner/Runner-Bridging-Header.h | 1 + .../ios/RunnerTests/RunnerTests.swift | 12 + covas_mobile_new/lib/classes/MyDrawer.dart | 209 ++++ covas_mobile_new/lib/classes/ad_helper.dart | 27 + .../lib/classes/addEventImage.dart | 67 + covas_mobile_new/lib/classes/alert.dart | 29 + .../lib/classes/auth_service.dart | 141 +++ covas_mobile_new/lib/classes/eventAdded.dart | 34 + covas_mobile_new/lib/classes/events.dart | 54 + .../lib/classes/getEventImage.dart | 67 + .../lib/classes/notification_service.dart | 91 ++ covas_mobile_new/lib/l10n/app_de.arb | 143 +++ covas_mobile_new/lib/l10n/app_en.arb | 145 +++ covas_mobile_new/lib/l10n/app_fr.arb | 146 +++ .../lib/l10n/app_localizations.dart | 977 +++++++++++++++ .../lib/l10n/app_localizations_de.dart | 434 +++++++ .../lib/l10n/app_localizations_en.dart | 434 +++++++ .../lib/l10n/app_localizations_fr.dart | 437 +++++++ covas_mobile_new/lib/locale_provider.dart | 41 + covas_mobile_new/lib/main.dart | 36 + covas_mobile_new/lib/pages/AddProfile.dart | 335 +++++ covas_mobile_new/lib/pages/Camera.dart | 163 +++ covas_mobile_new/lib/pages/CameraEdit.dart | 166 +++ .../lib/pages/DisplayPictureScreen.dart | 268 ++++ covas_mobile_new/lib/pages/EditEvent.dart | 921 ++++++++++++++ covas_mobile_new/lib/pages/EditProfile.dart | 396 ++++++ covas_mobile_new/lib/pages/EditSettings.dart | 170 +++ .../lib/pages/ForgotPassword.dart | 176 +++ covas_mobile_new/lib/pages/ItemMenu.dart | 455 +++++++ .../lib/pages/ListItemByOrganizers.dart | 275 ++++ .../lib/pages/ListItemByTags.dart | 277 ++++ covas_mobile_new/lib/pages/ListItemMenu.dart | 954 ++++++++++++++ covas_mobile_new/lib/pages/LoginDemo.dart | 169 +++ covas_mobile_new/lib/pages/MapboxPages.dart | 452 +++++++ .../lib/pages/UpdateEventImage.dart | 815 ++++++++++++ covas_mobile_new/lib/variable/globals.dart | 1 + covas_mobile_new/linux/.gitignore | 1 + covas_mobile_new/linux/CMakeLists.txt | 128 ++ covas_mobile_new/linux/flutter/CMakeLists.txt | 88 ++ .../flutter/generated_plugin_registrant.cc | 19 + .../flutter/generated_plugin_registrant.h | 15 + .../linux/flutter/generated_plugins.cmake | 25 + covas_mobile_new/linux/runner/CMakeLists.txt | 26 + covas_mobile_new/linux/runner/main.cc | 6 + .../linux/runner/my_application.cc | 144 +++ .../linux/runner/my_application.h | 18 + covas_mobile_new/macos/.gitignore | 7 + .../macos/Flutter/Flutter-Debug.xcconfig | 1 + .../macos/Flutter/Flutter-Release.xcconfig | 1 + .../Flutter/GeneratedPluginRegistrant.swift | 24 + .../macos/Runner.xcodeproj/project.pbxproj | 705 +++++++++++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/xcschemes/Runner.xcscheme | 99 ++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../macos/Runner/AppDelegate.swift | 13 + .../AppIcon.appiconset/Contents.json | 68 + .../AppIcon.appiconset/app_icon_1024.png | Bin 0 -> 102994 bytes .../AppIcon.appiconset/app_icon_128.png | Bin 0 -> 5680 bytes .../AppIcon.appiconset/app_icon_16.png | Bin 0 -> 520 bytes .../AppIcon.appiconset/app_icon_256.png | Bin 0 -> 14142 bytes .../AppIcon.appiconset/app_icon_32.png | Bin 0 -> 1066 bytes .../AppIcon.appiconset/app_icon_512.png | Bin 0 -> 36406 bytes .../AppIcon.appiconset/app_icon_64.png | Bin 0 -> 2218 bytes .../macos/Runner/Base.lproj/MainMenu.xib | 343 +++++ .../macos/Runner/Configs/AppInfo.xcconfig | 14 + .../macos/Runner/Configs/Debug.xcconfig | 2 + .../macos/Runner/Configs/Release.xcconfig | 2 + .../macos/Runner/Configs/Warnings.xcconfig | 13 + .../macos/Runner/DebugProfile.entitlements | 12 + covas_mobile_new/macos/Runner/Info.plist | 32 + .../macos/Runner/MainFlutterWindow.swift | 15 + .../macos/Runner/Release.entitlements | 8 + .../macos/RunnerTests/RunnerTests.swift | 12 + covas_mobile_new/pubspec.lock | 1111 +++++++++++++++++ covas_mobile_new/pubspec.yaml | 117 ++ covas_mobile_new/test/widget_test.dart | 30 + covas_mobile_new/web/favicon.png | Bin 0 -> 917 bytes covas_mobile_new/web/icons/Icon-192.png | Bin 0 -> 5292 bytes covas_mobile_new/web/icons/Icon-512.png | Bin 0 -> 8252 bytes .../web/icons/Icon-maskable-192.png | Bin 0 -> 5594 bytes .../web/icons/Icon-maskable-512.png | Bin 0 -> 20998 bytes covas_mobile_new/web/index.html | 38 + covas_mobile_new/web/manifest.json | 35 + covas_mobile_new/windows/.gitignore | 17 + covas_mobile_new/windows/CMakeLists.txt | 108 ++ .../windows/flutter/CMakeLists.txt | 109 ++ .../flutter/generated_plugin_registrant.cc | 23 + .../flutter/generated_plugin_registrant.h | 15 + .../windows/flutter/generated_plugins.cmake | 27 + .../windows/runner/CMakeLists.txt | 40 + covas_mobile_new/windows/runner/Runner.rc | 121 ++ .../windows/runner/flutter_window.cpp | 71 ++ .../windows/runner/flutter_window.h | 33 + covas_mobile_new/windows/runner/main.cpp | 43 + covas_mobile_new/windows/runner/resource.h | 16 + .../windows/runner/resources/app_icon.ico | Bin 0 -> 33772 bytes .../windows/runner/runner.exe.manifest | 14 + covas_mobile_new/windows/runner/utils.cpp | 65 + covas_mobile_new/windows/runner/utils.h | 19 + .../windows/runner/win32_window.cpp | 288 +++++ .../windows/runner/win32_window.h | 102 ++ 163 files changed, 15961 insertions(+) create mode 100644 covas_mobile_new/.gitignore create mode 100644 covas_mobile_new/.metadata create mode 100644 covas_mobile_new/README.md create mode 100644 covas_mobile_new/analysis_options.yaml create mode 100644 covas_mobile_new/android/.gitignore create mode 100644 covas_mobile_new/android/app/build.gradle.kts create mode 100644 covas_mobile_new/android/app/src/debug/AndroidManifest.xml create mode 100644 covas_mobile_new/android/app/src/main/AndroidManifest.xml create mode 100644 covas_mobile_new/android/app/src/main/kotlin/com/example/covas_mobile_new/MainActivity.kt create mode 100644 covas_mobile_new/android/app/src/main/res/drawable-v21/launch_background.xml create mode 100644 covas_mobile_new/android/app/src/main/res/drawable/launch_background.xml create mode 100644 covas_mobile_new/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 covas_mobile_new/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 covas_mobile_new/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 covas_mobile_new/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 covas_mobile_new/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 covas_mobile_new/android/app/src/main/res/values-night/styles.xml create mode 100644 covas_mobile_new/android/app/src/main/res/values/styles.xml create mode 100644 covas_mobile_new/android/app/src/profile/AndroidManifest.xml create mode 100644 covas_mobile_new/android/build.gradle.kts create mode 100644 covas_mobile_new/android/build/reports/problems/problems-report.html create mode 100644 covas_mobile_new/android/gradle.properties create mode 100644 covas_mobile_new/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 covas_mobile_new/android/settings.gradle.kts create mode 100644 covas_mobile_new/ios/.gitignore create mode 100644 covas_mobile_new/ios/Flutter/AppFrameworkInfo.plist create mode 100644 covas_mobile_new/ios/Flutter/Debug.xcconfig create mode 100644 covas_mobile_new/ios/Flutter/Release.xcconfig create mode 100644 covas_mobile_new/ios/Runner.xcodeproj/project.pbxproj create mode 100644 covas_mobile_new/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 covas_mobile_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 covas_mobile_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 covas_mobile_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 covas_mobile_new/ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 covas_mobile_new/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 covas_mobile_new/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 covas_mobile_new/ios/Runner/AppDelegate.swift create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png create mode 100644 covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md create mode 100644 covas_mobile_new/ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 covas_mobile_new/ios/Runner/Base.lproj/Main.storyboard create mode 100644 covas_mobile_new/ios/Runner/Info.plist create mode 100644 covas_mobile_new/ios/Runner/Runner-Bridging-Header.h create mode 100644 covas_mobile_new/ios/RunnerTests/RunnerTests.swift create mode 100644 covas_mobile_new/lib/classes/MyDrawer.dart create mode 100644 covas_mobile_new/lib/classes/ad_helper.dart create mode 100644 covas_mobile_new/lib/classes/addEventImage.dart create mode 100644 covas_mobile_new/lib/classes/alert.dart create mode 100644 covas_mobile_new/lib/classes/auth_service.dart create mode 100644 covas_mobile_new/lib/classes/eventAdded.dart create mode 100644 covas_mobile_new/lib/classes/events.dart create mode 100644 covas_mobile_new/lib/classes/getEventImage.dart create mode 100644 covas_mobile_new/lib/classes/notification_service.dart create mode 100644 covas_mobile_new/lib/l10n/app_de.arb create mode 100644 covas_mobile_new/lib/l10n/app_en.arb create mode 100644 covas_mobile_new/lib/l10n/app_fr.arb create mode 100644 covas_mobile_new/lib/l10n/app_localizations.dart create mode 100644 covas_mobile_new/lib/l10n/app_localizations_de.dart create mode 100644 covas_mobile_new/lib/l10n/app_localizations_en.dart create mode 100644 covas_mobile_new/lib/l10n/app_localizations_fr.dart create mode 100644 covas_mobile_new/lib/locale_provider.dart create mode 100644 covas_mobile_new/lib/main.dart create mode 100644 covas_mobile_new/lib/pages/AddProfile.dart create mode 100644 covas_mobile_new/lib/pages/Camera.dart create mode 100644 covas_mobile_new/lib/pages/CameraEdit.dart create mode 100644 covas_mobile_new/lib/pages/DisplayPictureScreen.dart create mode 100644 covas_mobile_new/lib/pages/EditEvent.dart create mode 100644 covas_mobile_new/lib/pages/EditProfile.dart create mode 100644 covas_mobile_new/lib/pages/EditSettings.dart create mode 100644 covas_mobile_new/lib/pages/ForgotPassword.dart create mode 100644 covas_mobile_new/lib/pages/ItemMenu.dart create mode 100644 covas_mobile_new/lib/pages/ListItemByOrganizers.dart create mode 100644 covas_mobile_new/lib/pages/ListItemByTags.dart create mode 100644 covas_mobile_new/lib/pages/ListItemMenu.dart create mode 100644 covas_mobile_new/lib/pages/LoginDemo.dart create mode 100644 covas_mobile_new/lib/pages/MapboxPages.dart create mode 100644 covas_mobile_new/lib/pages/UpdateEventImage.dart create mode 100644 covas_mobile_new/lib/variable/globals.dart create mode 100644 covas_mobile_new/linux/.gitignore create mode 100644 covas_mobile_new/linux/CMakeLists.txt create mode 100644 covas_mobile_new/linux/flutter/CMakeLists.txt create mode 100644 covas_mobile_new/linux/flutter/generated_plugin_registrant.cc create mode 100644 covas_mobile_new/linux/flutter/generated_plugin_registrant.h create mode 100644 covas_mobile_new/linux/flutter/generated_plugins.cmake create mode 100644 covas_mobile_new/linux/runner/CMakeLists.txt create mode 100644 covas_mobile_new/linux/runner/main.cc create mode 100644 covas_mobile_new/linux/runner/my_application.cc create mode 100644 covas_mobile_new/linux/runner/my_application.h create mode 100644 covas_mobile_new/macos/.gitignore create mode 100644 covas_mobile_new/macos/Flutter/Flutter-Debug.xcconfig create mode 100644 covas_mobile_new/macos/Flutter/Flutter-Release.xcconfig create mode 100644 covas_mobile_new/macos/Flutter/GeneratedPluginRegistrant.swift create mode 100644 covas_mobile_new/macos/Runner.xcodeproj/project.pbxproj create mode 100644 covas_mobile_new/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 covas_mobile_new/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 covas_mobile_new/macos/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 covas_mobile_new/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 covas_mobile_new/macos/Runner/AppDelegate.swift create mode 100644 covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png create mode 100644 covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png create mode 100644 covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png create mode 100644 covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png create mode 100644 covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png create mode 100644 covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png create mode 100644 covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png create mode 100644 covas_mobile_new/macos/Runner/Base.lproj/MainMenu.xib create mode 100644 covas_mobile_new/macos/Runner/Configs/AppInfo.xcconfig create mode 100644 covas_mobile_new/macos/Runner/Configs/Debug.xcconfig create mode 100644 covas_mobile_new/macos/Runner/Configs/Release.xcconfig create mode 100644 covas_mobile_new/macos/Runner/Configs/Warnings.xcconfig create mode 100644 covas_mobile_new/macos/Runner/DebugProfile.entitlements create mode 100644 covas_mobile_new/macos/Runner/Info.plist create mode 100644 covas_mobile_new/macos/Runner/MainFlutterWindow.swift create mode 100644 covas_mobile_new/macos/Runner/Release.entitlements create mode 100644 covas_mobile_new/macos/RunnerTests/RunnerTests.swift create mode 100644 covas_mobile_new/pubspec.lock create mode 100644 covas_mobile_new/pubspec.yaml create mode 100644 covas_mobile_new/test/widget_test.dart create mode 100644 covas_mobile_new/web/favicon.png create mode 100644 covas_mobile_new/web/icons/Icon-192.png create mode 100644 covas_mobile_new/web/icons/Icon-512.png create mode 100644 covas_mobile_new/web/icons/Icon-maskable-192.png create mode 100644 covas_mobile_new/web/icons/Icon-maskable-512.png create mode 100644 covas_mobile_new/web/index.html create mode 100644 covas_mobile_new/web/manifest.json create mode 100644 covas_mobile_new/windows/.gitignore create mode 100644 covas_mobile_new/windows/CMakeLists.txt create mode 100644 covas_mobile_new/windows/flutter/CMakeLists.txt create mode 100644 covas_mobile_new/windows/flutter/generated_plugin_registrant.cc create mode 100644 covas_mobile_new/windows/flutter/generated_plugin_registrant.h create mode 100644 covas_mobile_new/windows/flutter/generated_plugins.cmake create mode 100644 covas_mobile_new/windows/runner/CMakeLists.txt create mode 100644 covas_mobile_new/windows/runner/Runner.rc create mode 100644 covas_mobile_new/windows/runner/flutter_window.cpp create mode 100644 covas_mobile_new/windows/runner/flutter_window.h create mode 100644 covas_mobile_new/windows/runner/main.cpp create mode 100644 covas_mobile_new/windows/runner/resource.h create mode 100644 covas_mobile_new/windows/runner/resources/app_icon.ico create mode 100644 covas_mobile_new/windows/runner/runner.exe.manifest create mode 100644 covas_mobile_new/windows/runner/utils.cpp create mode 100644 covas_mobile_new/windows/runner/utils.h create mode 100644 covas_mobile_new/windows/runner/win32_window.cpp create mode 100644 covas_mobile_new/windows/runner/win32_window.h diff --git a/covas_mobile_new/.gitignore b/covas_mobile_new/.gitignore new file mode 100644 index 0000000..3820a95 --- /dev/null +++ b/covas_mobile_new/.gitignore @@ -0,0 +1,45 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ +/coverage/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/covas_mobile_new/.metadata b/covas_mobile_new/.metadata new file mode 100644 index 0000000..05a8ab4 --- /dev/null +++ b/covas_mobile_new/.metadata @@ -0,0 +1,45 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "05db9689081f091050f01aed79f04dce0c750154" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 05db9689081f091050f01aed79f04dce0c750154 + base_revision: 05db9689081f091050f01aed79f04dce0c750154 + - platform: android + create_revision: 05db9689081f091050f01aed79f04dce0c750154 + base_revision: 05db9689081f091050f01aed79f04dce0c750154 + - platform: ios + create_revision: 05db9689081f091050f01aed79f04dce0c750154 + base_revision: 05db9689081f091050f01aed79f04dce0c750154 + - platform: linux + create_revision: 05db9689081f091050f01aed79f04dce0c750154 + base_revision: 05db9689081f091050f01aed79f04dce0c750154 + - platform: macos + create_revision: 05db9689081f091050f01aed79f04dce0c750154 + base_revision: 05db9689081f091050f01aed79f04dce0c750154 + - platform: web + create_revision: 05db9689081f091050f01aed79f04dce0c750154 + base_revision: 05db9689081f091050f01aed79f04dce0c750154 + - platform: windows + create_revision: 05db9689081f091050f01aed79f04dce0c750154 + base_revision: 05db9689081f091050f01aed79f04dce0c750154 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/covas_mobile_new/README.md b/covas_mobile_new/README.md new file mode 100644 index 0000000..5d96d02 --- /dev/null +++ b/covas_mobile_new/README.md @@ -0,0 +1,16 @@ +# covas_mobile_new + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/covas_mobile_new/analysis_options.yaml b/covas_mobile_new/analysis_options.yaml new file mode 100644 index 0000000..0d29021 --- /dev/null +++ b/covas_mobile_new/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/covas_mobile_new/android/.gitignore b/covas_mobile_new/android/.gitignore new file mode 100644 index 0000000..be3943c --- /dev/null +++ b/covas_mobile_new/android/.gitignore @@ -0,0 +1,14 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java +.cxx/ + +# Remember to never publicly share your keystore. +# See https://flutter.dev/to/reference-keystore +key.properties +**/*.keystore +**/*.jks diff --git a/covas_mobile_new/android/app/build.gradle.kts b/covas_mobile_new/android/app/build.gradle.kts new file mode 100644 index 0000000..5bd1701 --- /dev/null +++ b/covas_mobile_new/android/app/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + id("com.android.application") + id("kotlin-android") + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id("dev.flutter.flutter-gradle-plugin") +} + +android { + namespace = "com.example.covas_mobile_new" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_11.toString() + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId = "com.example.covas_mobile_new" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + minSdk = flutter.minSdkVersion + targetSdk = flutter.targetSdkVersion + versionCode = flutter.versionCode + versionName = flutter.versionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig = signingConfigs.getByName("debug") + } + } +} + +flutter { + source = "../.." +} diff --git a/covas_mobile_new/android/app/src/debug/AndroidManifest.xml b/covas_mobile_new/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/covas_mobile_new/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/covas_mobile_new/android/app/src/main/AndroidManifest.xml b/covas_mobile_new/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..42ed197 --- /dev/null +++ b/covas_mobile_new/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/covas_mobile_new/android/app/src/main/kotlin/com/example/covas_mobile_new/MainActivity.kt b/covas_mobile_new/android/app/src/main/kotlin/com/example/covas_mobile_new/MainActivity.kt new file mode 100644 index 0000000..d1df550 --- /dev/null +++ b/covas_mobile_new/android/app/src/main/kotlin/com/example/covas_mobile_new/MainActivity.kt @@ -0,0 +1,5 @@ +package com.example.covas_mobile_new + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity : FlutterActivity() diff --git a/covas_mobile_new/android/app/src/main/res/drawable-v21/launch_background.xml b/covas_mobile_new/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/covas_mobile_new/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/covas_mobile_new/android/app/src/main/res/drawable/launch_background.xml b/covas_mobile_new/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/covas_mobile_new/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/covas_mobile_new/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/covas_mobile_new/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..db77bb4b7b0906d62b1847e87f15cdcacf6a4f29 GIT binary patch literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ literal 0 HcmV?d00001 diff --git a/covas_mobile_new/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/covas_mobile_new/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..17987b79bb8a35cc66c3c1fd44f5a5526c1b78be GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ literal 0 HcmV?d00001 diff --git a/covas_mobile_new/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/covas_mobile_new/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f1c8d34e7a88e3f88bea192c3a370d44689c3c GIT binary patch literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof literal 0 HcmV?d00001 diff --git a/covas_mobile_new/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/covas_mobile_new/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6372eebdb28e45604e46eeda8dd24651419bc0 GIT binary patch literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` literal 0 HcmV?d00001 diff --git a/covas_mobile_new/android/app/src/main/res/values-night/styles.xml b/covas_mobile_new/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/covas_mobile_new/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/covas_mobile_new/android/app/src/main/res/values/styles.xml b/covas_mobile_new/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..cb1ef88 --- /dev/null +++ b/covas_mobile_new/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/covas_mobile_new/android/app/src/profile/AndroidManifest.xml b/covas_mobile_new/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/covas_mobile_new/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/covas_mobile_new/android/build.gradle.kts b/covas_mobile_new/android/build.gradle.kts new file mode 100644 index 0000000..dbee657 --- /dev/null +++ b/covas_mobile_new/android/build.gradle.kts @@ -0,0 +1,24 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +val newBuildDir: Directory = + rootProject.layout.buildDirectory + .dir("../../build") + .get() +rootProject.layout.buildDirectory.value(newBuildDir) + +subprojects { + val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) + project.layout.buildDirectory.value(newSubprojectBuildDir) +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean") { + delete(rootProject.layout.buildDirectory) +} diff --git a/covas_mobile_new/android/build/reports/problems/problems-report.html b/covas_mobile_new/android/build/reports/problems/problems-report.html new file mode 100644 index 0000000..24fcec2 --- /dev/null +++ b/covas_mobile_new/android/build/reports/problems/problems-report.html @@ -0,0 +1,663 @@ + + + + + + + + + + + + + Gradle Configuration Cache + + + +
+ +
+ Loading... +
+ + + + + + diff --git a/covas_mobile_new/android/gradle.properties b/covas_mobile_new/android/gradle.properties new file mode 100644 index 0000000..f018a61 --- /dev/null +++ b/covas_mobile_new/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true +android.enableJetifier=true diff --git a/covas_mobile_new/android/gradle/wrapper/gradle-wrapper.properties b/covas_mobile_new/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..ac3b479 --- /dev/null +++ b/covas_mobile_new/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/covas_mobile_new/android/settings.gradle.kts b/covas_mobile_new/android/settings.gradle.kts new file mode 100644 index 0000000..fb605bc --- /dev/null +++ b/covas_mobile_new/android/settings.gradle.kts @@ -0,0 +1,26 @@ +pluginManagement { + val flutterSdkPath = + run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id("dev.flutter.flutter-plugin-loader") version "1.0.0" + id("com.android.application") version "8.9.1" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false +} + +include(":app") diff --git a/covas_mobile_new/ios/.gitignore b/covas_mobile_new/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/covas_mobile_new/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/covas_mobile_new/ios/Flutter/AppFrameworkInfo.plist b/covas_mobile_new/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..1dc6cf7 --- /dev/null +++ b/covas_mobile_new/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 13.0 + + diff --git a/covas_mobile_new/ios/Flutter/Debug.xcconfig b/covas_mobile_new/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/covas_mobile_new/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/covas_mobile_new/ios/Flutter/Release.xcconfig b/covas_mobile_new/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/covas_mobile_new/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/covas_mobile_new/ios/Runner.xcodeproj/project.pbxproj b/covas_mobile_new/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..f6be446 --- /dev/null +++ b/covas_mobile_new/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,616 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/covas_mobile_new/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/covas_mobile_new/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/covas_mobile_new/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/covas_mobile_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/covas_mobile_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/covas_mobile_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/covas_mobile_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/covas_mobile_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/covas_mobile_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/covas_mobile_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/covas_mobile_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..e3773d4 --- /dev/null +++ b/covas_mobile_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/covas_mobile_new/ios/Runner.xcworkspace/contents.xcworkspacedata b/covas_mobile_new/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/covas_mobile_new/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/covas_mobile_new/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/covas_mobile_new/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/covas_mobile_new/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/covas_mobile_new/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/covas_mobile_new/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/covas_mobile_new/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/covas_mobile_new/ios/Runner/AppDelegate.swift b/covas_mobile_new/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..6266644 --- /dev/null +++ b/covas_mobile_new/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import Flutter +import UIKit + +@main +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..dc9ada4725e9b0ddb1deab583e5b5102493aa332 GIT binary patch literal 10932 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 literal 0 HcmV?d00001 diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..797d452e458972bab9d994556c8305db4c827017 GIT binary patch literal 406 zcmV;H0crk;P))>cdjpWt&rLJgVp-t?DREyuq1A%0Z4)6_WsQ7{nzjN zo!X zGXV)2i3kcZIL~_j>uIKPK_zib+3T+Nt3Mb&Br)s)UIaA}@p{wDda>7=Q|mGRp7pqY zkJ!7E{MNz$9nOwoVqpFb)}$IP24Wn2JJ=Cw(!`OXJBr45rP>>AQr$6c7slJWvbpNW z@KTwna6d?PP>hvXCcp=4F;=GR@R4E7{4VU^0p4F>v^#A|>07*qoM6N<$f*5nx ACIA2c literal 0 HcmV?d00001 diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed2d933e1120817fe9182483a228007b18ab6ae GIT binary patch literal 450 zcmV;z0X_bSP)iGWQ_5NJQ_~rNh*z)}eT%KUb z`7gNk0#AwF^#0T0?hIa^`~Ck;!}#m+_uT050aTR(J!bU#|IzRL%^UsMS#KsYnTF*!YeDOytlP4VhV?b} z%rz_<=#CPc)tU1MZTq~*2=8~iZ!lSa<{9b@2Jl;?IEV8)=fG217*|@)CCYgFze-x? zIFODUIA>nWKpE+bn~n7;-89sa>#DR>TSlqWk*!2hSN6D~Qb#VqbP~4Fk&m`@1$JGr zXPIdeRE&b2Thd#{MtDK$px*d3-Wx``>!oimf%|A-&-q*6KAH)e$3|6JV%HX{Hig)k suLT-RhftRq8b9;(V=235Wa|I=027H2wCDra;{X5v07*qoM6N<$f;9x^2LJ#7 literal 0 HcmV?d00001 diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..4cd7b0099ca80c806f8fe495613e8d6c69460d76 GIT binary patch literal 282 zcmV+#0p(^bcu7P-R4C8Q z&e;xxFbF_Vrezo%_kH*OKhshZ6BFpG-Y1e10`QXJKbND7AMQ&cMj60B5TNObaZxYybcN07*qoM6N<$g3m;S%K!iX literal 0 HcmV?d00001 diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..fe730945a01f64a61e2235dbe3f45b08f7729182 GIT binary patch literal 462 zcmV;<0WtoGP)-}iV`2<;=$?g5M=KQbZ{F&YRNy7Nn@%_*5{gvDM0aKI4?ESmw z{NnZg)A0R`+4?NF_RZexyVB&^^ZvN!{I28tr{Vje;QNTz`dG&Jz0~Ek&f2;*Z7>B|cg}xYpxEFY+0YrKLF;^Q+-HreN0P{&i zK~zY`?b7ECf-n?@;d<&orQ*Q7KoR%4|C>{W^h6@&01>0SKS`dn{Q}GT%Qj_{PLZ_& zs`MFI#j-(>?bvdZ!8^xTwlY{qA)T4QLbY@j(!YJ7aXJervHy6HaG_2SB`6CC{He}f zHVw(fJWApwPq!6VY7r1w-Fs)@ox~N+q|w~e;JI~C4Vf^@d>Wvj=fl`^u9x9wd9 zR%3*Q+)t%S!MU_`id^@&Y{y7-r98lZX0?YrHlfmwb?#}^1b{8g&KzmkE(L>Z&)179 zp<)v6Y}pRl100G2FL_t(o!|l{-Q-VMg#&MKg7c{O0 z2wJImOS3Gy*Z2Qifdv~JYOp;v+U)a|nLoc7hNH;I$;lzDt$}rkaFw1mYK5_0Q(Sut zvbEloxON7$+HSOgC9Z8ltuC&0OSF!-mXv5caV>#bc3@hBPX@I$58-z}(ZZE!t-aOG zpjNkbau@>yEzH(5Yj4kZiMH32XI!4~gVXNnjAvRx;Sdg^`>2DpUEwoMhTs_st8pKG z(%SHyHdU&v%f36~uERh!bd`!T2dw;z6PrOTQ7Vt*#9F2uHlUVnb#ev_o^fh}Dzmq} zWtlk35}k=?xj28uO|5>>$yXadTUE@@IPpgH`gJ~Ro4>jd1IF|(+IX>8M4Ps{PNvmI zNj4D+XgN83gPt_Gm}`Ybv{;+&yu-C(Grdiahmo~BjG-l&mWM+{e5M1sm&=xduwgM9 z`8OEh`=F3r`^E{n_;%9weN{cf2%7=VzC@cYj+lg>+3|D|_1C@{hcU(DyQG_BvBWe? zvTv``=%b1zrol#=R`JB)>cdjpWt&rLJgVp-t?DREyuq1A%0Z4)6_WsQ7{nzjN zo!X zGXV)2i3kcZIL~_j>uIKPK_zib+3T+Nt3Mb&Br)s)UIaA}@p{wDda>7=Q|mGRp7pqY zkJ!7E{MNz$9nOwoVqpFb)}$IP24Wn2JJ=Cw(!`OXJBr45rP>>AQr$6c7slJWvbpNW z@KTwna6d?PP>hvXCcp=4F;=GR@R4E7{4VU^0p4F>v^#A|>07*qoM6N<$f*5nx ACIA2c literal 0 HcmV?d00001 diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..502f463a9bc882b461c96aadf492d1729e49e725 GIT binary patch literal 586 zcmV-Q0=4~#P)+}#`wDE{8-2Mebf5<{{PqV{TgVcv*r8?UZ3{-|G?_}T*&y;@cqf{ z{Q*~+qr%%p!1pS*_Uicl#q9lc(D`!D`LN62sNwq{oYw(Wmhk)k<@f$!$@ng~_5)Ru z0Z)trIA5^j{DIW^c+vT2%lW+2<(RtE2wR;4O@)Tm`Xr*?A(qYoM}7i5Yxw>D(&6ou zxz!_Xr~yNF+waPe00049Nkl*;a!v6h%{rlvIH#gW3s8p;bFr=l}mRqpW2h zw=OA%hdyL~z+UHOzl0eKhEr$YYOL-c-%Y<)=j?(bzDweB7{b+%_ypvm_cG{SvM=DK zhv{K@m>#Bw>2W$eUI#iU)Wdgs8Y3U+A$Gd&{+j)d)BmGKx+43U_!tik_YlN)>$7G! zhkE!s;%oku3;IwG3U^2kw?z+HM)jB{@zFhK8P#KMSytSthr+4!c(5c%+^UBn`0X*2 zy3(k600_CSZj?O$Qu%&$;|TGUJrptR(HzyIx>5E(2r{eA(<6t3e3I0B)7d6s7?Z5J zZ!rtKvA{MiEBm&KFtoifx>5P^Z=vl)95XJn()aS5%ad(s?4-=Tkis9IGu{`Fy8r+H07*qoM6N<$f20Z)wqMt%V?S?~D#06};F zA3KcL`Wb+>5ObvgQIG&ig8(;V04hz?@cqy3{mSh8o!|U|)cI!1_+!fWH@o*8vh^CU z^ws0;(c$gI+2~q^tO#GDHf@=;DncUw00J^eL_t(&-tE|HQ`%4vfZ;WsBqu-$0nu1R zq^Vj;p$clf^?twn|KHO+IGt^q#a3X?w9dXC@*yxhv&l}F322(8Y1&=P&I}~G@#h6; z1CV9ecD9ZEe87{{NtI*)_aJ<`kJa z?5=RBtFF50s;jQLFil-`)m2wrb=6h(&brpj%nG_U&ut~$?8Rokzxi8zJoWr#2dto5 zOX_URcc<1`Iky+jc;A%Vzx}1QU{2$|cKPom2Vf1{8m`vja4{F>HS?^Nc^rp}xo+Nh zxd}eOm`fm3@MQC1< zIk&aCjb~Yh%5+Yq0`)D;q{#-Uqlv*o+Oor zE!I71Z@ASH3grl8&P^L0WpavHoP|UX4e?!igT`4?AZk$hu*@%6WJ;zDOGlw7kj@ zY5!B-0ft0f?Lgb>C;$Ke07*qoM6N<$f~t1N9smFU literal 0 HcmV?d00001 diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0ec303439225b78712f49115768196d8d76f6790 GIT binary patch literal 862 zcmV-k1EKthP)20Z)wqMt%V?S?~D#06};F zA3KcL`Wb+>5ObvgQIG&ig8(;V04hz?@cqy3{mSh8o!|U|)cI!1_+!fWH@o*8vh^CU z^ws0;(c$gI+2~q^tO#GDHf@=;DncUw00J^eL_t(&-tE|HQ`%4vfZ;WsBqu-$0nu1R zq^Vj;p$clf^?twn|KHO+IGt^q#a3X?w9dXC@*yxhv&l}F322(8Y1&=P&I}~G@#h6; z1CV9ecD9ZEe87{{NtI*)_aJ<`kJa z?5=RBtFF50s;jQLFil-`)m2wrb=6h(&brpj%nG_U&ut~$?8Rokzxi8zJoWr#2dto5 zOX_URcc<1`Iky+jc;A%Vzx}1QU{2$|cKPom2Vf1{8m`vja4{F>HS?^Nc^rp}xo+Nh zxd}eOm`fm3@MQC1< zIk&aCjb~Yh%5+Yq0`)D;q{#-Uqlv*o+Oor zE!I71Z@ASH3grl8&P^L0WpavHoP|UX4e?!igT`4?AZk$hu*@%6WJ;zDOGlw7kj@ zY5!B-0ft0f?Lgb>C;$Ke07*qoM6N<$f~t1N9smFU literal 0 HcmV?d00001 diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..e9f5fea27c705180eb716271f41b582e76dcbd90 GIT binary patch literal 1674 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 literal 0 HcmV?d00001 diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/covas_mobile_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0467bf12aa4d28f374bb26596605a46dcbb3e7c8 GIT binary patch literal 1418 zcmV;51$Fv~P)q zKfU)WzW*n(@|xWGCA9ScMt*e9`2kdxPQ&&>|-UCa7_51w+ zLUsW@ZzZSW0y$)Hp~e9%PvP|a03ks1`~K?q{u;6NC8*{AOqIUq{CL&;p56Lf$oQGq z^={4hPQv)y=I|4n+?>7Fim=dxt1 z2H+Dm+1+fh+IF>G0SjJMkQQre1x4|G*Z==(Ot&kCnUrL4I(rf(ucITwmuHf^hXiJT zkdTm&kdTm&kdTm&kdP`esgWG0BcWCVkVZ&2dUwN`cgM8QJb`Z7Z~e<&Yj2(}>Tmf` zm1{eLgw!b{bXkjWbF%dTkTZEJWyWOb##Lfw4EK2}<0d6%>AGS{po>WCOy&f$Tay_> z?NBlkpo@s-O;0V%Y_Xa-G#_O08q5LR*~F%&)}{}r&L%Sbs8AS4t7Y0NEx*{soY=0MZExqA5XHQkqi#4gW3 zqODM^iyZl;dvf)-bOXtOru(s)Uc7~BFx{w-FK;2{`VA?(g&@3z&bfLFyctOH!cVsF z7IL=fo-qBndRUm;kAdXR4e6>k-z|21AaN%ubeVrHl*<|s&Ax@W-t?LR(P-24A5=>a z*R9#QvjzF8n%@1Nw@?CG@6(%>+-0ASK~jEmCV|&a*7-GKT72W<(TbSjf)&Eme6nGE z>Gkj4Sq&2e+-G%|+NM8OOm5zVl9{Z8Dd8A5z3y8mZ=4Bv4%>as_{9cN#bm~;h>62( zdqY93Zy}v&c4n($Vv!UybR8ocs7#zbfX1IY-*w~)p}XyZ-SFC~4w>BvMVr`dFbelV{lLL0bx7@*ZZdebr3`sP;? zVImji)kG)(6Juv0lz@q`F!k1FE;CQ(D0iG$wchPbKZQELlsZ#~rt8#90Y_Xh&3U-< z{s<&cCV_1`^TD^ia9!*mQDq& zn2{r`j};V|uV%_wsP!zB?m%;FeaRe+X47K0e+KE!8C{gAWF8)lCd1u1%~|M!XNRvw zvtqy3iz0WSpWdhn6$hP8PaRBmp)q`#PCA`Vd#Tc$@f1tAcM>f_I@bC)hkI9|o(Iqv zo}Piadq!j76}004RBio<`)70k^`K1NK)q>w?p^C6J2ZC!+UppiK6&y3Kmbv&O!oYF z34$0Z;QO!JOY#!`qyGH<3Pd}Pt@q*A0V=3SVtWKRR8d8Z&@)3qLPA19LPA19LPEUC YUoZo%k(ykuW&i*H07*qoM6N<$f+CH{y8r+H literal 0 HcmV?d00001 diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/covas_mobile_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/covas_mobile_new/ios/Runner/Base.lproj/LaunchScreen.storyboard b/covas_mobile_new/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/covas_mobile_new/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/covas_mobile_new/ios/Runner/Base.lproj/Main.storyboard b/covas_mobile_new/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/covas_mobile_new/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/covas_mobile_new/ios/Runner/Info.plist b/covas_mobile_new/ios/Runner/Info.plist new file mode 100644 index 0000000..55b44c4 --- /dev/null +++ b/covas_mobile_new/ios/Runner/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Covas Mobile New + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + covas_mobile_new + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + + diff --git a/covas_mobile_new/ios/Runner/Runner-Bridging-Header.h b/covas_mobile_new/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/covas_mobile_new/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/covas_mobile_new/ios/RunnerTests/RunnerTests.swift b/covas_mobile_new/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..86a7c3b --- /dev/null +++ b/covas_mobile_new/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/covas_mobile_new/lib/classes/MyDrawer.dart b/covas_mobile_new/lib/classes/MyDrawer.dart new file mode 100644 index 0000000..8fcf62c --- /dev/null +++ b/covas_mobile_new/lib/classes/MyDrawer.dart @@ -0,0 +1,209 @@ +import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:http/http.dart' as http; +import 'dart:io'; +import '../pages/EditProfile.dart'; +import '../pages/EditSettings.dart'; +import '../pages/ListItemMenu.dart'; +import 'alert.dart'; + +import '../variable/globals.dart' as globals; + +import '../pages/LoginDemo.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; // Import dotenv +import 'package:encrypt_shared_preferences/provider.dart'; + +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +class MyDrawer extends StatelessWidget with ShowAlertDialog { + Future logout(BuildContext context) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + + if (accessToken.isNotEmpty) { + var url = Uri.parse("${globals.api}/token"); + + try { + var response = await http.delete(url, headers: { + "Content-Type": "application/json", + HttpHeaders.cookieHeader: "access_token=${accessToken}" + }); + + print("Status code logout ${response.statusCode}"); + + if (response.statusCode == 200) { + await prefs.remove("access_token"); + await dotenv.load(fileName: ".env"); // Load .env file + + final keyEncrypt = dotenv.env['KEY_ENCRYPT'] ?? ''; + if (keyEncrypt.isNotEmpty) { + await EncryptedSharedPreferences.initialize(keyEncrypt); + var sharedPref = EncryptedSharedPreferences.getInstance(); + String username = sharedPref.getString("username") ?? ""; + String password = sharedPref.getString("password") ?? ""; + if ((username.isEmpty) || (password.isEmpty)) { + sharedPref.remove("username"); + sharedPref.remove("password"); + } + } + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (_) => LoginDemo()), + (route) => false, // Remove all previous routes + ); + } else { + String errorMessage; + switch (response.statusCode) { + case 400: + errorMessage = "Bad Request: Please check your input."; + break; + case 401: + errorMessage = "Unauthorized: Invalid credentials."; + break; + case 403: + errorMessage = "Forbidden: You don't have permission."; + break; + case 404: + errorMessage = "Not Found: The resource was not found."; + break; + case 500: + errorMessage = + "Server Error: Something went wrong on the server."; + break; + default: + errorMessage = "Unexpected Error: ${response.statusCode}"; + break; + } + print(errorMessage); + showAlertDialog(context, "Error", errorMessage); + } + } catch (e) { + print("Error: $e"); + showAlertDialog( + context, "Error", "An error occurred. Please try again."); + } + } else { + showAlertDialog(context, "Error", "Invalid token."); + } + } + + @override + Widget build(BuildContext context) { + final loc = AppLocalizations.of(context); + final localeProvider = Provider.of(context); + return Drawer( + child: ListView( + padding: EdgeInsets.zero, + children: [ + // Drawer Header + DrawerHeader( + decoration: BoxDecoration( + color: Colors.blue, + ), + child: Text( + 'Menu', + style: TextStyle( + color: Colors.white, + fontSize: 24, + ), + ), + ), + // Drawer Items + ListTile( + leading: Icon(Icons.home), + title: Text(loc?.home ?? "Home"), + onTap: () { + Navigator.pushReplacement( + context, MaterialPageRoute(builder: (_) => ListItemMenu())); + + /// Close the drawer + }, + ), + ListTile( + leading: Icon(Icons.settings), + title: Text(loc?.settings ?? 'Settings'), + onTap: () { + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (_) => EditSettings())); // Close the drawer + }, + ), + ListTile( + leading: Icon(Icons.account_circle), + title: Text(loc?.update_profile ?? 'Update profile'), + onTap: () { + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (_) => EditProfile())); // Close the drawer + }, + ), + ListTile( + leading: Icon(Icons.language), + title: Text(loc?.language ?? 'Language'), + onTap: () { + showDialog( + context: context, + builder: (_) => AlertDialog( + title: Text(loc?.select_language ?? 'Select Language'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + leading: Icon(Icons.flag), + title: Text(loc?.french ?? 'Français'), + onTap: () { + Provider.of(context, listen: false) + .setLocale(const Locale('fr')); + Navigator.of(context).pop(); + }, + ), + ListTile( + leading: Icon(Icons.flag_outlined), + title: Text(loc?.english ?? 'English'), + onTap: () { + Provider.of(context, listen: false) + .setLocale(const Locale('en')); + Navigator.of(context).pop(); + }, + ), + ListTile( + leading: Icon(Icons.flag_outlined), + title: Text(loc?.german ?? 'German'), + onTap: () { + Provider.of(context, listen: false) + .setLocale(const Locale('de')); + Navigator.of(context).pop(); + }, + ), + ], + ), + ), + ); + }, + ), + + ListTile( + leading: Icon(Icons.info), + title: Text(loc?.about ?? 'About'), + onTap: () { + showAlertDialog(context, loc?.about ?? 'About', + "Version 0.0.1"); // Close the drawer + }, + ), + ListTile( + leading: Icon(Icons.logout), + title: Text(loc?.log_out ?? 'Log out'), + onTap: () async { + logout(context); +// Close the drawer + }, + ), + ], + ), + ); + } +} diff --git a/covas_mobile_new/lib/classes/ad_helper.dart b/covas_mobile_new/lib/classes/ad_helper.dart new file mode 100644 index 0000000..61bd66c --- /dev/null +++ b/covas_mobile_new/lib/classes/ad_helper.dart @@ -0,0 +1,27 @@ +import 'package:google_mobile_ads/google_mobile_ads.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; + +class AdHelper { + static Future createBannerAd(Function setStateCallback) async { + await dotenv.load(fileName: ".env"); + final adUnitId = dotenv.env['AD_UNIT_ID'] ?? ''; + + BannerAd bannerAd = BannerAd( + adUnitId: adUnitId, + size: AdSize.banner, + request: AdRequest(), + listener: BannerAdListener( + onAdLoaded: (ad) { + setStateCallback(() {}); + }, + onAdFailedToLoad: (ad, error) { + print('Banner Ad failed to load: $error'); + ad.dispose(); + }, + ), + ); + + bannerAd.load(); + return bannerAd; + } +} diff --git a/covas_mobile_new/lib/classes/addEventImage.dart b/covas_mobile_new/lib/classes/addEventImage.dart new file mode 100644 index 0000000..f55f3ce --- /dev/null +++ b/covas_mobile_new/lib/classes/addEventImage.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; +import 'events.dart'; +import '../variable/globals.dart' as globals; +import 'package:http/http.dart' as http; +import 'dart:io'; +import 'dart:convert'; + +import 'package:shared_preferences/shared_preferences.dart'; + +mixin ShowDescImageAdd on State { + Future addEvents(var events) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + List send = ["toto"]; + + if (accessToken.isNotEmpty) { + var urlPut = Uri.parse("${globals.api}/events"); + print("start date : ${events["start_date"]}"); + var responsePut = await http.put(urlPut, + headers: { + HttpHeaders.cookieHeader: 'access_token=${accessToken}', + HttpHeaders.acceptHeader: 'application/json, text/plain, */*', + HttpHeaders.contentTypeHeader: 'application/json' + }, + body: jsonEncode({ + 'name': events["name"], + 'place': events["place"], + 'start_date': events['date'], + 'end_date': events['date'], + 'organizers': send, + 'latitude': '0.0', + 'longitude': '0.0', + })); + + print("http put code status : ${responsePut.statusCode}"); + print("http put body : ${responsePut.body}"); + } + } + + void showDescImageAddDialog(BuildContext context, var events) { + // Create AlertDialog + String name = events['name']; + AlertDialog dialog = AlertDialog( + title: Text("Ajouter un evenement"), + content: Text("${name} n'a pas été trouvé. Voulez-vous l'ajouter ? "), + actions: [ + TextButton( + child: Text("Annuler"), + onPressed: () { + Navigator.of(context).pop("Yes, Of course!"); // Return value + }), + TextButton( + child: Text("Oui"), + onPressed: () { + addEvents(events); // Return value + }), + ], + ); + + // Call showDialog function to show dialog. + Future futureValue = showDialog( + context: context, + builder: (BuildContext context) { + return dialog; + }); + } +} diff --git a/covas_mobile_new/lib/classes/alert.dart b/covas_mobile_new/lib/classes/alert.dart new file mode 100644 index 0000000..ed83093 --- /dev/null +++ b/covas_mobile_new/lib/classes/alert.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; + +mixin ShowAlertDialog { + void showAlertDialog(BuildContext context, String title, String text) { + // Create AlertDialog + AlertDialog dialog = AlertDialog( + title: Text(title), + content: Text(text), + actions: [ + ElevatedButton( + child: Text("OK"), + style: ElevatedButton.styleFrom( + padding: EdgeInsets.symmetric(horizontal: 50, vertical: 20), + textStyle: + TextStyle(fontSize: 15, fontWeight: FontWeight.normal)), + onPressed: () { + Navigator.of(context).pop("Yes, Of course!"); // Return value + }), + ], + ); + + // Call showDialog function to show dialog. + Future futureValue = showDialog( + context: context, + builder: (BuildContext context) { + return dialog; + }); + } +} diff --git a/covas_mobile_new/lib/classes/auth_service.dart b/covas_mobile_new/lib/classes/auth_service.dart new file mode 100644 index 0000000..2cd7a8c --- /dev/null +++ b/covas_mobile_new/lib/classes/auth_service.dart @@ -0,0 +1,141 @@ +import 'dart:convert'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:http/http.dart' as http; +import '../variable/globals.dart' as globals; +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:encrypt_shared_preferences/provider.dart'; +import '../pages/LoginDemo.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; // Import dotenv + +class AuthService { + // Login with username and password + Future login(String username, String password, + {bool rememberMe = false}) async { + final url = Uri.parse("${globals.api}/token"); + + try { + final response = await http.post( + url, + headers: { + 'accept': 'application/json', + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: {"username": username, "password": password}, + ); + + if (response.statusCode == 200 || response.statusCode == 201) { + final prefs = await SharedPreferences.getInstance(); + if (rememberMe) { + await dotenv.load(fileName: ".env"); // Load .env file + + final keyEncrypt = dotenv.env['KEY_ENCRYPT'] ?? ''; + if (keyEncrypt.isNotEmpty) { + await EncryptedSharedPreferences.initialize(keyEncrypt); + var sharedPref = EncryptedSharedPreferences.getInstance(); + sharedPref.setString("username", username); + sharedPref.setString("password", password); + } + } + final cookies = response.headers["set-cookie"]?.split(";") ?? []; + + for (final cookie in cookies) { + final cookieParts = cookie.split(","); + for (final part in cookieParts) { + final keyValue = part.split("="); + if (keyValue.length == 2 && keyValue[0] == "access_token") { + prefs.setString("access_token", keyValue[1]); + } + } + } + return true; + } else { + return false; + } + } catch (e) { + print("Login error: $e"); + return false; + } + } + + // Logout + Future logout() async { + final prefs = await SharedPreferences.getInstance(); + await prefs.remove("access_token"); + } + + Future isLoggedIn() async { + final prefs = await SharedPreferences.getInstance(); + final accessToken = prefs.getString("access_token"); + + if (accessToken == null || accessToken.isEmpty) { + print("No access token found."); + return false; + } + + print("Checking token validity..."); + var url = Uri.parse("${globals.api}/token"); + + try { + final response = await http.get( + url, + headers: { + HttpHeaders.cookieHeader: "access_token=$accessToken", + "Content-Type": "application/json", + }, + ); + + if (response.statusCode == 200) { + print("Token is valid."); + return true; + } else { + print("Token is invalid. Status code: ${response.statusCode}"); + await dotenv.load(fileName: ".env"); // Load .env file + + final keyEncrypt = dotenv.env['KEY_ENCRYPT'] ?? ''; + if (keyEncrypt.isNotEmpty) { + await EncryptedSharedPreferences.initialize(keyEncrypt); + var sharedPref = EncryptedSharedPreferences.getInstance(); + String username = sharedPref.getString("username") ?? ""; + String password = sharedPref.getString("password") ?? ""; + if ((username.isEmpty) || (password.isEmpty)) { + sharedPref.remove("username"); + sharedPref.remove("password"); + await prefs.remove("access_token"); // Clear invalid token + return false; + } else { + return login(username, password); + } + } else { + return false; + } + } + } catch (e) { + print("Error while checking token: $e"); + return false; + } + } + + Future checkTokenStatus(context) async { + bool loggedIn = await isLoggedIn(); + SharedPreferences prefs = await SharedPreferences.getInstance(); + + if (!loggedIn) { + await prefs.remove("access_token"); // Correctly remove the token + + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (_) => LoginDemo()), + (route) => false, // Remove all previous routes + ); + } + } + + // Get stored access token + Future getAccessToken() async { + final prefs = await SharedPreferences.getInstance(); + return prefs.getString("access_token"); + } + + // Login with Google +} diff --git a/covas_mobile_new/lib/classes/eventAdded.dart b/covas_mobile_new/lib/classes/eventAdded.dart new file mode 100644 index 0000000..d2c75b7 --- /dev/null +++ b/covas_mobile_new/lib/classes/eventAdded.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; + +import '../pages/ListItemMenu.dart'; + +mixin ShowEventDialog on State { + void showEventDialog(BuildContext context, String text) { + // Create AlertDialog + AlertDialog dialog = AlertDialog( + title: Text("Evenement ajoute"), + content: Text(text), + actions: [ + ElevatedButton( + child: Text("OK"), + style: ElevatedButton.styleFrom( + padding: EdgeInsets.symmetric(horizontal: 50, vertical: 20), + textStyle: + TextStyle(fontSize: 15, fontWeight: FontWeight.normal)), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => ListItemMenu())); // Return value + }), + ], + ); + + // Call showDialog function to show dialog. + Future futureValue = showDialog( + context: context, + builder: (BuildContext context) { + return dialog; + }); + } +} diff --git a/covas_mobile_new/lib/classes/events.dart b/covas_mobile_new/lib/classes/events.dart new file mode 100644 index 0000000..8df086e --- /dev/null +++ b/covas_mobile_new/lib/classes/events.dart @@ -0,0 +1,54 @@ +class Events { + String? id; + String? name; + String? place; + String? startDate; + String? endDate; + String? description; + String? link; + String? ticket; + double? latitude; + double? longitude; + List? tags; + List? organizers; + String? imgUrl; + int? interestedCount; + bool? interested; + Events( + {this.place, + this.id, + this.name, + this.startDate, + this.description, + this.endDate, + this.tags, + this.latitude, + this.longitude, + this.organizers, + this.link, + this.ticket, + this.imgUrl, + this.interestedCount, + this.interested}); + + Events.fromJson(Map json) { + id = json['id'] as String?; + name = json['name'] as String?; + place = json['place'] as String?; + startDate = json['start_date'] as String?; + endDate = json['end_date'] as String?; + description = json['description'] as String?; + latitude = (json['latitude'] as num?)?.toDouble(); // Safely cast to double + longitude = + (json['longitude'] as num?)?.toDouble(); // Safely cast to double + tags = (json['tags'] as List?) + ?.cast(); // Convert List to List + organizers = (json['organizers'] as List?) + ?.cast(); // Convert List to List + imgUrl = json['imgUrl'] as String?; + link = json['link'] as String?; + ticket = json['ticket'] as String?; + interested = json['interested'] as bool?; + interestedCount = json['interested_count'] as int?; + } +} diff --git a/covas_mobile_new/lib/classes/getEventImage.dart b/covas_mobile_new/lib/classes/getEventImage.dart new file mode 100644 index 0000000..a0db5dc --- /dev/null +++ b/covas_mobile_new/lib/classes/getEventImage.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; +import 'events.dart'; +import '../variable/globals.dart' as globals; +import 'package:http/http.dart' as http; +import 'dart:io'; +import 'dart:convert'; + +import 'package:shared_preferences/shared_preferences.dart'; + +mixin ShowDescImageGet on State { + Future getEvents(var events) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + List send = ["toto"]; + + if (accessToken.isNotEmpty) { + var urlPut = Uri.parse("${globals.api}/events"); + print("start date : ${events["start_date"]}"); + var responsePut = await http.put(urlPut, + headers: { + HttpHeaders.cookieHeader: 'access_token=${accessToken}', + HttpHeaders.acceptHeader: 'application/json, text/plain, */*', + HttpHeaders.contentTypeHeader: 'application/json' + }, + body: jsonEncode({ + 'name': events["name"], + 'place': events["place"], + 'start_date': events['date'], + 'end_date': events['date'], + 'organizers': send, + 'latitude': '0.0', + 'longitude': '0.0', + })); + + print("http put code status : ${responsePut.statusCode}"); + print("http put body : ${responsePut.body}"); + } + } + + void showDescImageGetDialog(BuildContext context, var events) { + // Create AlertDialog + String name = events['name']; + AlertDialog dialog = AlertDialog( + title: Text("Voir la description de l'evenement"), + content: Text("${name} a été trouvé. Voulez-vous voir sa description ? "), + actions: [ + TextButton( + child: Text("Annuler"), + onPressed: () { + Navigator.of(context).pop("Yes, Of course!"); // Return value + }), + TextButton( + child: Text("Oui"), + onPressed: () { + getEvents(events); // Return value + }), + ], + ); + + // Call showDialog function to show dialog. + Future futureValue = showDialog( + context: context, + builder: (BuildContext context) { + return dialog; + }); + } +} diff --git a/covas_mobile_new/lib/classes/notification_service.dart b/covas_mobile_new/lib/classes/notification_service.dart new file mode 100644 index 0000000..4ff081e --- /dev/null +++ b/covas_mobile_new/lib/classes/notification_service.dart @@ -0,0 +1,91 @@ +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:timezone/timezone.dart' as tz; +import 'package:timezone/data/latest_all.dart' as tz; + +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; + +class NotificationService { + static final FlutterLocalNotificationsPlugin _notificationsPlugin = + FlutterLocalNotificationsPlugin(); + + /// Initialisation (à appeler dans main()) + static Future initialize() async { + tz.initializeTimeZones(); + + const AndroidInitializationSettings androidInitSettings = + AndroidInitializationSettings('@mipmap/ic_launcher'); + + const InitializationSettings initSettings = InitializationSettings( + android: androidInitSettings, + iOS: DarwinInitializationSettings(), + ); + + await _notificationsPlugin.initialize(initSettings); + + // Demande les permissions au lancement + await requestPermissions(); + } + + /// Demander les permissions (Android 13+ et iOS) + static Future requestPermissions() async { + // Android 13+ + final androidImplementation = + _notificationsPlugin.resolvePlatformSpecificImplementation< + AndroidFlutterLocalNotificationsPlugin>(); + await androidImplementation?.requestNotificationsPermission(); + + // iOS + final iosImplementation = + _notificationsPlugin.resolvePlatformSpecificImplementation< + IOSFlutterLocalNotificationsPlugin>(); + await iosImplementation?.requestPermissions( + alert: true, + badge: true, + sound: true, + ); + } + + /// Planifie une notification 1h avant l’évènement + static Future scheduleEventNotification({ + required String eventId, + required String title, + required String body, + required DateTime eventDate, + }) async { + final scheduledDate = eventDate.subtract(const Duration(hours: 1)); + + if (scheduledDate.isBefore(DateTime.now())) { + // Trop tard pour notifier + return; + } + + await _notificationsPlugin.zonedSchedule( + eventId.hashCode, // identifiant unique pour l’évènement + title, + body, + tz.TZDateTime.from(scheduledDate, tz.local), + const NotificationDetails( + android: AndroidNotificationDetails( + 'events_channel', + 'Events', + channelDescription: 'Favorite event notifications ', + importance: Importance.high, + priority: Priority.high, + ), + iOS: DarwinNotificationDetails(), + ), + androidScheduleMode: AndroidScheduleMode + .inexactAllowWhileIdle, // évite l'erreur Exact Alarm + uiLocalNotificationDateInterpretation: + UILocalNotificationDateInterpretation.absoluteTime, + matchDateTimeComponents: DateTimeComponents.dateAndTime, + ); + } + + /// Annule une notification planifiée + static Future cancel(String eventId) async { + await _notificationsPlugin.cancel(eventId.hashCode); + } +} diff --git a/covas_mobile_new/lib/l10n/app_de.arb b/covas_mobile_new/lib/l10n/app_de.arb new file mode 100644 index 0000000..c6c07b1 --- /dev/null +++ b/covas_mobile_new/lib/l10n/app_de.arb @@ -0,0 +1,143 @@ +{ + "@@locale": "de", + "menu_list": "Veranstaltungsmenü", + "language": "Sprache", + "home": "Startseite", + "settings": "Einstellungen", + "update_profile": "Profil aktualisieren", + "about": "Über", + "log_out": "Abmelden", + "french": "Französisch", + "english": "Englisch", + "german": "Deutsch", + "select_language": "Sprache auswählen", + "search_item": "Nach Element suchen", + "search_tag": "Nach Schlagwörtern suchen", + "search_geographical": "Nach geografischer Zone suchen", + "show_date_field": "Datumsfelder anzeigen", + "hide_date_field": "Datumsfelder ausblenden", + "no_data": "Keine Daten verfügbar", + "search": "Suchen", + "no_events": "Keine Veranstaltungen für diesen Ort verfügbar.", + "start_date": "Anfangsdatum", + "end_date": "Enddatum", + "failed_suggestions": "Vorschläge konnten nicht geladen werden", + "error": "Fehler", + "password_different": "Ein anderes Passwort eingeben", + "create": "Erstellung", + "user_create": "Benutzer wurde erstellt", + "user_update": "Benutzer wurde aktualisiert", + "request_error": "Fehlerhafte Anfrage", + "incorrect_password": "Falsches Passwort", + "unknown_user": "Unbekannter Benutzer", + "disabled_user": "Benutzer deaktiviert", + "invalid_token": "Ungültiger Token", + "internal_error_server": "Interner Serverfehler", + "unknown_error_auth": "Unbekannter Authentifizierungsfehler", + "required_input": "Pflichtfeld", + "create_profile": "Profil erstellen", + "edit_pseudo": "Benutzernamen bearbeiten", + "password": "Passwort", + "enter_password": "Passwort eingeben", + "password_confirmed": "Passwort bestätigt", + "last_name": "Nachname", + "first_name": "Vorname", + "email": "E-Mail", + "edit_last_name": "Nachnamen bearbeiten", + "edit_first_name": "Vornamen bearbeiten", + "edit_email": "E-Mail-Adresse bearbeiten", + "birth_date": "Geburtsdatum", + "edit_birth": "Geburtsdatum bearbeiten", + "create_profile_button": "Profil erstellen", + "take_picture": "Foto aufnehmen", + "error_ia": "Google KI konnte das Bild nicht analysieren. Bitte ein anderes versuchen.", + "no_data_geo": "Keine geografischen Daten", + "response_status_update": "Statuscode-Antwort aktualisieren", + "error_token": "Token-Fehler", + "error_format": "Vom KI geliefertes Datenformat ist fehlerhaft", + "display_picture": "Bild anzeigen", + "analyze_image": "Bildanalyse läuft", + "loading_progress": "Ladefortschritt", + "error_event": "Veranstaltungsfehler", + "no_future_event": "Keine zukünftigen Veranstaltungen", + "error_user": "Benutzerfehler", + "empty_input": "Eingabefeld leer", + "info_event": "Veranstaltungsinfo", + "event_already": "Veranstaltung existiert bereits", + "picture_error": "Bildfehler", + "no_picture_published": "Kein Bild veröffentlicht", + "event_update": "Veranstaltung aktualisiert", + "location": "Ort", + "add_event": "Veranstaltung hinzufügen oder aktualisieren", + "edit_image": "Bilder bearbeiten", + "name": "Name", + "edit_event_name": "Veranstaltungsname bearbeiten", + "start_time": "Startzeit", + "end_time": "Endzeit", + "select_date": "Zum Auswählen eines Datums klicken", + "select_time": "Zum Auswählen einer Uhrzeit klicken", + "tag": "Schlagwörter", + "already_tag": "Dieses Schlagwort ist bereits vorhanden", + "enter_tag": "Ein Schlagwort eingeben", + "organizer": "Veranstalter", + "already_organiser": "Veranstalter bereits vorhanden", + "enter_organizer": "Veranstalter eingeben", + "description": "Beschreibung", + "describe_event": "Veranstaltung beschreiben", + "add": "Hinzufügen", + "different_password_error": "Passwörter stimmen nicht überein", + "update": "Aktualisieren", + "updated": "Aktualisiert", + "settings_updated": "Einstellungen aktualisiert", + "define_kilometer": "Kilometer definieren", + "email_sent": "E-Mail wurde gesendet", + "forgot_password": "Passwort vergessen", + "enter_email": "E-Mail eingeben", + "send_email": "E-Mail senden", + "invalid_cache": "Ungültiger Cache", + "item_date": "Datum : ", + "item_maps": "Karte : ", + "item_organizer": "Veranstalter : ", + "item_description": "Beschreibung : ", + "item_tags": "Schlagwörter : ", + "failed_auth": "Authentifizierung fehlgeschlagen", + "login_page": "Anmeldeseite", + "pseudo": "Benutzername", + "enter_existing_pseudo": "Vorhandenen Benutzernamen eingeben", + "remembr_me": "Angemeldet bleiben", + "new_user": "Neuer Benutzer? Konto erstellen", + "sign_in": "Anmelden", + "map_token": "Mapbox-Zugangstoken ist nicht verfügbar", + "geo_disabled": "Standortdienste sind deaktiviert.", + "permission_denied": "Standortberechtigungen wurden verweigert.", + "enable_permission": "Standortberechtigungen dauerhaft verweigert. Bitte in den Einstellungen aktivieren.", + "no_last_position": "Keine letzte bekannte Position verfügbar.", + "failed_location": "Standort konnte nicht ermittelt werden", + "failed_fetch": "Route konnte nicht abgerufen werden", + "invalid_coordinates_symbol": "Ungültige Koordinaten, Symbol kann nicht hinzugefügt werden.", + "error_symbol": "Fehler beim Hinzufügen des Symbols.", + "position_not_init": "Benutzerposition noch nicht initialisiert. Erneut versuchen.", + "invalid_coordinates": "Ungültige Koordinaten.", + "walking": "Zu Fuß", + "cycling": "Mit dem Fahrrad", + "driving": "Mit dem Auto", + "get_direction": "Wegbeschreibung und Markierungen anzeigen", + "missing_token": "Zugangstoken fehlt", + "geocoding_error": "Fehler bei der Geokodierung", + "no_found_place": "Kein Ort gefunden", + "upload_error": "Fehler beim Hochladen des Bildes", + "event_added": "Veranstaltung hinzugefügt", + "unknown_error": "Unbekannter Fehler", + "app_error": "Anwendungsfehler", + "at": "um", + "to_date": "bis", + "item_link": "Link : ", + "item_ticket": "Abendkarte : ", + "link": "Link", + "edit_link": "Linkereignis bearbeiten", +"ticket": "Abendkarte", +"edit_ticket": "Ticketlink bearbeiten", +"toogle_interest": "Fehler beim Umschalten des Interesses", +"error_update": "Fehler beim Update", +"count_interested": "Anzahl der Interessenten" +} diff --git a/covas_mobile_new/lib/l10n/app_en.arb b/covas_mobile_new/lib/l10n/app_en.arb new file mode 100644 index 0000000..3a1fd28 --- /dev/null +++ b/covas_mobile_new/lib/l10n/app_en.arb @@ -0,0 +1,145 @@ +{ + "@@locale": "en", +"menu_list": "Event list menu", +"language": "Language", +"home": "Home", +"settings": "Settings", +"update_profile": "Update profile", +"about": "About", +"log_out": "Log out", +"french": "French", +"english": "English", +"german": "German", +"select_language": "Select language", +"search_item": "Search by item", +"search_tag": "Search by tags", +"search_geographical": "Search by geographical zone", +"show_date_field": "Show Date Fields", +"hide_date_field": "Hide Date Fields", +"no_data": "No data available", +"search": "Search", +"no_events": "No events available for this location.", +"start_date": "Start date", +"end_date": "End date", +"failed_suggestions": "Failed to load suggestions", +"error":"Error", +"password_different":"Must write a different password", +"create": "Creation", +"user_create": "Your user created", +"user_update": "Your user updated", +"request_error": "Poorly constructed query", +"incorrect_password": "Incorrect password", +"unknown_user": "Unknown user", +"disabled_user": "User disabled", +"invalid_token": "Invalid token", +"internal_error_server": "Internal error server", +"unknown_error_auth": "Unknown error authentification", +"required_input": "Required input", +"create_profile": "Create profile", +"edit_pseudo": "Edit pseudo", +"password":"Password", +"enter_password": "Enter the passord", + "password_confirmed": "Password confirmed", + "last_name": "Last name", +"first_name": "First name", +"email": "Mail", +"edit_last_name": "Edit name", +"edit_first_name": "Edit first name", +"edit_email": "Edit email address", +"birth_date": "Birth date", +"edit_birth": "Edit birth date", +"create_profile_button": "Create profile", +"take_picture": "Take a picture", +"error_ia": "Google AI failed to analyze picture. Retry with another one", +"no_data_geo": "No geographical data", +"response_status_update": "response status code update", +"error_token": "Token error", +"error_format": "Data format error given by AI", +"display_picture": "Display the Picture", +"analyze_image": "Image Analyze in progress", +"loading_progress": "Loading progress", +"error_event": "Event error", +"no_future_event": "No future event", +"error_user": "Error user", +"empty_input": "Empty input", +"info_event": "Event info", +"event_already": "Event already exists", +"picture_error": "Picture error", +"no_picture_published": "No picture published", +"event_update": "Event updated", +"location": "Location", +"add_event": "Add or Update a event", +"edit_image": "Edit pictures", +"name": "Name", +"edit_event_name": "Edit event name", +"start_time": "Start time", +"end_time": "End time", +"select_date": "Click to select a date", +"select_time": "Click to select a time", +"tag": "Tags", +"already_tag": "You have already this tags", +"enter_tag": "Enter a tag", +"organizer": "Organizer", +"already_organiser": "You have already a organizer", +"enter_organizer": "Enter a organizer", +"description": "Description", +"describe_event": "Describe event", +"add": "Add", +"update_profile": "Update profile", +"different_password_error": "Different password", +"update": "Update", +"updated": "Updated", +"settings_updated": "Settings updated", +"define_kilometer": "Define Kilometer", +"settings": "Settings", +"email_sent": "Email has been sent", +"forgot_password": "Forgot password", +"enter_email": "Enter the email", +"send_email": "Send email", +"invalid_cache": "Invalid cache", +"item_date": "Date : ", +"item_maps": "Maps : ", +"item_organizer": "Organizer : ", +"item_description": "Description : ", +"item_tags": "Tags : ", +"failed_auth": "Authentification failed", +"login_page": "Login page", +"pseudo": "Pseudo", +"enter_existing_pseudo": "Enter a existing pseudo", +"remembr_me": "Remember me", +"new_user": "New User? Create Account", +"sign_in": "Sign in", +"map_token": "Mapbox Access Token is not available", +"geo_disabled": "Location services are disabled.", +"permission_denied":"Location permissions are denied.", +"enable_permission": "Location permissions are permanently denied. Enable them in settings.", +"no_last_position": "No last known position available.", +"failed_location": "Failed to get user location", +"failed_fetch": "Failed to fetch the route", +"invalid_coordinates_symbol": "Invalid coordinates, cannot add symbol.", +"error_symbol": "Error when adding symbol.", +"position_not_init": "User position is not yet initialized. Try again.", +"invalid_coordinates": "Invalid coordinates.", +"walking": "Walking", +"cycling": "Cycling", +"driving": "Driving", +"get_direction": "Get Directions and Markers", +"missing_token": "Missing access token", +"geocoding_error": "Error when geocoding", +"no_found_place": "No found place", +"upload_error": "Error when image uploading", +"event_added": "Event added", +"unknown_error": "Unknown error", +"app_error": "Application error", +"at": "at", +"to_date": "to", +"item_link": "Link : ", +"item_ticket": "Ticket : ", +"link": "Link", +"edit_link": "Edit link name", +"ticket": "Ticket", +"edit_ticket": "Edit ticket link", +"toogle_interest": "Error toggle interest", +"error_update": "Error when updating", +"count_interested": "Interested people number" +} \ No newline at end of file diff --git a/covas_mobile_new/lib/l10n/app_fr.arb b/covas_mobile_new/lib/l10n/app_fr.arb new file mode 100644 index 0000000..c8003a3 --- /dev/null +++ b/covas_mobile_new/lib/l10n/app_fr.arb @@ -0,0 +1,146 @@ +{ + "@@locale": "fr", +"menu_list": "Liste d'évènement", +"language": "Langue", +"home": "Accueil", +"settings": "Paramètres", +"update_profile": "Modifier profil", +"about": "À propos", +"log_out": "Se déconnecter", +"french": "Français", +"english": "Anglais", +"german": "Allemand", +"select_language": "Selectionne la langue", +"search_item": "Recherche par item", +"search_tag": "Recherche par tags", +"search_geographical": "Recherche par zone géographique", +"show_date_field": "Afficher champ date", +"hide_date_field": "Cacher Date Fields", +"no_data": "Aucune donnée disponible", +"search": "Recherche", +"no_events": "Pas d'évènements dans cette localisation", +"start_date": "Date de début", +"end_date": "Date de fin", +"failed_suggestions": "Echec de chargement des suggestions", +"error":"Erreur", +"password_different":"Tu dois écrire un mot de passe different", +"create": "Création", +"user_create": "Votre utilisateur a été créé", +"user_update": "Votre utilisateur a été modifié", +"request_error": "Requête mal construite", +"incorrect_password": "Mot de passe incorrect", +"unknown_user": "Utilisateur inconnu", +"disabled_user": "Utilisateur désactivé", +"invalid_token": "Token invalide", +"internal_error_server": "Erreur interne de serveur", +"unknown_error_auth": "Problème d'authentification inconnu", +"required_input": "Champ requis", +"create_profile": "Creation profil", +"edit_pseudo": "Modifier le pseudo", +"password":"Mot de passe", +"enter_password": "Entrez le password", +"password_confirmed": "Confirmez le mot de passe", +"last_name": "Nom", +"first_name": "Prénom", +"email": "Email", +"edit_last_name": "Modifier le nom", +"edit_first_name": "Modifier le prénom", +"edit_email": "Modifier l'email", +"birth_date": "Date de naissance", +"edit_birth": "Modifier la date de naissance", +"create_profile_button": "Créer le profil", +"take_picture": "Take a picture", +"error_ia": "L'IA de Google n'a pas su analyser l'image. Recommencer avec une autre", +"no_data_geo": "Aucune donnée géographique", +"response_status_update": "Code du statut de réponse de la modification", +"error_token": "Erreur de token", +"error_format": "Erreur de format de donnée fourni par l'IA", +"display_picture": "Display the Picture", +"analyze_image": "Analyse de l'image en cours", +"loading_progress": "Chargement en cours", +"error_event": "Erreur de l'évènement", +"no_future_event": "Évènement non futur", +"error_user": "Erreur de l'utilisateur", +"empty_input": "Champ vide", +"info_event": "Event info", +"event_already": "Event already exists", +"picture_error": "Erreur image", +"no_picture_published": "Image non publiée", +"event_update": "Évènement modifié", +"location": "Lieu", +"add_event": "Ajouter ou modifier un évènement", +"edit_image": "Changer la photo", +"name": "Nom", +"edit_event_name": "Changer le nom de l'évènement", +"start_time": "Heure de début", +"end_time": "Heure de fin", +"select_date": "Cliquer pour selectionner une date", +"select_time": "Cliquer pour selectionner une heure", +"tag": "Tags", +"already_tag": "Tu as déjà entré ce tag", +"enter_tag": "Entrer un tag", +"organizer": "Organisateur", +"already_organiser": "Tu as déjà rentré cet organisateur", +"enter_organizer": "Entrer un organisateur", +"description": "Description", +"describe_event": "Décrire l'évènement", +"add": "Ajouter", +"update_profile": "Modifier le profil", +"different_password_error": "Mot de passe différent", +"update": "Mettre à jour", +"updated": "Mis à jour", +"settings_updated": "Paramètre mis à jour", +"define_kilometer": "Definir un kilomètre", +"settings": "Paramètres", +"email_sent": "Email a été envoyé", +"forgot_password": "Mot de passe oublié", +"enter_email": "Entrez l'email", +"send_email": "Send email", +"invalid_cache": "Cache invalide", +"item_date": "Date : ", +"item_maps": "Carte : ", +"item_organizer": "Organisateurs : ", +"item_description": "Description : ", +"item_tags": "Tags : ", +"failed_auth": "Échec de l'authenticaton", +"login_page": "Page d'authentification", +"pseudo": "Pseudo", +"enter_existing_pseudo": "Entrez un pseudo existant", +"remembr_me": "Se souvenir de moi", +"new_user": "Nouvel utilisateur ? Créer un compte", +"sign_in": "Se connecter", +"map_token": "Token d'accès de Mapbox n'est pas disponible", +"geo_disabled": "Les services de localisation sont désactivés.", +"permission_denied":"Les permissions de localisation sont refusées.", +"enable_permission": "Les permissions de localisation sont toujours désactivés. Il faut les désactiver", +"no_last_position": "Aucune position n'est pas disponible.", +"failed_location": "Échec de récupération des données geographique", +"failed_fetch": "Échec de récupération des routes", +"invalid_coordinates_symbol": "Coordonnées invalides. On ne peut pas ajouter le symbole", +"error_symbol": "Erreur lors de l'ajout du symbole", +"position_not_init": "Coordonnées non initialisées. Essaye encore.", +"invalid_coordinates": "Coordonnées invalides", +"walking": "Marche", +"cycling": "Vélo", +"driving": "Voiture", +"get_direction": "Get Directions and Markers", +"missing_token": "Token d'accès manquant", +"geocoding_error": "Erreur lors du geocodage", +"no_found_place": "Lieu introuvable", +"upload_error": "Erreur lors de l'upload d'image", +"event_added": "Évènement ajouté", +"unknown_error": "Erreur inconnue", +"app_error": "Erreur d'application", +"at": "à", +"to_date": "jusqu'à", +"item_link": "Lien : ", +"item_ticket": "Billet : ", +"link": "Lien", +"edit_link": "Editer le lien", +"ticket": "Billet", +"edit_ticket": "Editer le lien du billet", +"toogle_interest": "Erreur de bouton de changement", +"error_update": "Erreur lors de la mise à jour", +"count_interested": "Nombre de personne interessé" + +} \ No newline at end of file diff --git a/covas_mobile_new/lib/l10n/app_localizations.dart b/covas_mobile_new/lib/l10n/app_localizations.dart new file mode 100644 index 0000000..502fa07 --- /dev/null +++ b/covas_mobile_new/lib/l10n/app_localizations.dart @@ -0,0 +1,977 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:intl/intl.dart' as intl; + +import 'app_localizations_de.dart'; +import 'app_localizations_en.dart'; +import 'app_localizations_fr.dart'; + +// ignore_for_file: type=lint + +/// Callers can lookup localized strings with an instance of AppLocalizations +/// returned by `AppLocalizations.of(context)`. +/// +/// Applications need to include `AppLocalizations.delegate()` in their app's +/// `localizationDelegates` list, and the locales they support in the app's +/// `supportedLocales` list. For example: +/// +/// ```dart +/// import 'l10n/app_localizations.dart'; +/// +/// return MaterialApp( +/// localizationsDelegates: AppLocalizations.localizationsDelegates, +/// supportedLocales: AppLocalizations.supportedLocales, +/// home: MyApplicationHome(), +/// ); +/// ``` +/// +/// ## Update pubspec.yaml +/// +/// Please make sure to update your pubspec.yaml to include the following +/// packages: +/// +/// ```yaml +/// dependencies: +/// # Internationalization support. +/// flutter_localizations: +/// sdk: flutter +/// intl: any # Use the pinned version from flutter_localizations +/// +/// # Rest of dependencies +/// ``` +/// +/// ## iOS Applications +/// +/// iOS applications define key application metadata, including supported +/// locales, in an Info.plist file that is built into the application bundle. +/// To configure the locales supported by your app, you’ll need to edit this +/// file. +/// +/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file. +/// Then, in the Project Navigator, open the Info.plist file under the Runner +/// project’s Runner folder. +/// +/// Next, select the Information Property List item, select Add Item from the +/// Editor menu, then select Localizations from the pop-up menu. +/// +/// Select and expand the newly-created Localizations item then, for each +/// locale your application supports, add a new item and select the locale +/// you wish to add from the pop-up menu in the Value field. This list should +/// be consistent with the languages listed in the AppLocalizations.supportedLocales +/// property. +abstract class AppLocalizations { + AppLocalizations(String locale) + : localeName = intl.Intl.canonicalizedLocale(locale.toString()); + + final String localeName; + + static AppLocalizations? of(BuildContext context) { + return Localizations.of(context, AppLocalizations); + } + + static const LocalizationsDelegate delegate = + _AppLocalizationsDelegate(); + + /// A list of this localizations delegate along with the default localizations + /// delegates. + /// + /// Returns a list of localizations delegates containing this delegate along with + /// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, + /// and GlobalWidgetsLocalizations.delegate. + /// + /// Additional delegates can be added by appending to this list in + /// MaterialApp. This list does not have to be used at all if a custom list + /// of delegates is preferred or required. + static const List> localizationsDelegates = + >[ + delegate, + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ]; + + /// A list of this localizations delegate's supported locales. + static const List supportedLocales = [ + Locale('de'), + Locale('en'), + Locale('fr') + ]; + + /// No description provided for @menu_list. + /// + /// In en, this message translates to: + /// **'Event list menu'** + String get menu_list; + + /// No description provided for @language. + /// + /// In en, this message translates to: + /// **'Language'** + String get language; + + /// No description provided for @home. + /// + /// In en, this message translates to: + /// **'Home'** + String get home; + + /// No description provided for @settings. + /// + /// In en, this message translates to: + /// **'Settings'** + String get settings; + + /// No description provided for @update_profile. + /// + /// In en, this message translates to: + /// **'Update profile'** + String get update_profile; + + /// No description provided for @about. + /// + /// In en, this message translates to: + /// **'About'** + String get about; + + /// No description provided for @log_out. + /// + /// In en, this message translates to: + /// **'Log out'** + String get log_out; + + /// No description provided for @french. + /// + /// In en, this message translates to: + /// **'French'** + String get french; + + /// No description provided for @english. + /// + /// In en, this message translates to: + /// **'English'** + String get english; + + /// No description provided for @german. + /// + /// In en, this message translates to: + /// **'German'** + String get german; + + /// No description provided for @select_language. + /// + /// In en, this message translates to: + /// **'Select language'** + String get select_language; + + /// No description provided for @search_item. + /// + /// In en, this message translates to: + /// **'Search by item'** + String get search_item; + + /// No description provided for @search_tag. + /// + /// In en, this message translates to: + /// **'Search by tags'** + String get search_tag; + + /// No description provided for @search_geographical. + /// + /// In en, this message translates to: + /// **'Search by geographical zone'** + String get search_geographical; + + /// No description provided for @show_date_field. + /// + /// In en, this message translates to: + /// **'Show Date Fields'** + String get show_date_field; + + /// No description provided for @hide_date_field. + /// + /// In en, this message translates to: + /// **'Hide Date Fields'** + String get hide_date_field; + + /// No description provided for @no_data. + /// + /// In en, this message translates to: + /// **'No data available'** + String get no_data; + + /// No description provided for @search. + /// + /// In en, this message translates to: + /// **'Search'** + String get search; + + /// No description provided for @no_events. + /// + /// In en, this message translates to: + /// **'No events available for this location.'** + String get no_events; + + /// No description provided for @start_date. + /// + /// In en, this message translates to: + /// **'Start date'** + String get start_date; + + /// No description provided for @end_date. + /// + /// In en, this message translates to: + /// **'End date'** + String get end_date; + + /// No description provided for @failed_suggestions. + /// + /// In en, this message translates to: + /// **'Failed to load suggestions'** + String get failed_suggestions; + + /// No description provided for @error. + /// + /// In en, this message translates to: + /// **'Error'** + String get error; + + /// No description provided for @password_different. + /// + /// In en, this message translates to: + /// **'Must write a different password'** + String get password_different; + + /// No description provided for @create. + /// + /// In en, this message translates to: + /// **'Creation'** + String get create; + + /// No description provided for @user_create. + /// + /// In en, this message translates to: + /// **'Your user created'** + String get user_create; + + /// No description provided for @user_update. + /// + /// In en, this message translates to: + /// **'Your user updated'** + String get user_update; + + /// No description provided for @request_error. + /// + /// In en, this message translates to: + /// **'Poorly constructed query'** + String get request_error; + + /// No description provided for @incorrect_password. + /// + /// In en, this message translates to: + /// **'Incorrect password'** + String get incorrect_password; + + /// No description provided for @unknown_user. + /// + /// In en, this message translates to: + /// **'Unknown user'** + String get unknown_user; + + /// No description provided for @disabled_user. + /// + /// In en, this message translates to: + /// **'User disabled'** + String get disabled_user; + + /// No description provided for @invalid_token. + /// + /// In en, this message translates to: + /// **'Invalid token'** + String get invalid_token; + + /// No description provided for @internal_error_server. + /// + /// In en, this message translates to: + /// **'Internal error server'** + String get internal_error_server; + + /// No description provided for @unknown_error_auth. + /// + /// In en, this message translates to: + /// **'Unknown error authentification'** + String get unknown_error_auth; + + /// No description provided for @required_input. + /// + /// In en, this message translates to: + /// **'Required input'** + String get required_input; + + /// No description provided for @create_profile. + /// + /// In en, this message translates to: + /// **'Create profile'** + String get create_profile; + + /// No description provided for @edit_pseudo. + /// + /// In en, this message translates to: + /// **'Edit pseudo'** + String get edit_pseudo; + + /// No description provided for @password. + /// + /// In en, this message translates to: + /// **'Password'** + String get password; + + /// No description provided for @enter_password. + /// + /// In en, this message translates to: + /// **'Enter the passord'** + String get enter_password; + + /// No description provided for @password_confirmed. + /// + /// In en, this message translates to: + /// **'Password confirmed'** + String get password_confirmed; + + /// No description provided for @last_name. + /// + /// In en, this message translates to: + /// **'Last name'** + String get last_name; + + /// No description provided for @first_name. + /// + /// In en, this message translates to: + /// **'First name'** + String get first_name; + + /// No description provided for @email. + /// + /// In en, this message translates to: + /// **'Mail'** + String get email; + + /// No description provided for @edit_last_name. + /// + /// In en, this message translates to: + /// **'Edit name'** + String get edit_last_name; + + /// No description provided for @edit_first_name. + /// + /// In en, this message translates to: + /// **'Edit first name'** + String get edit_first_name; + + /// No description provided for @edit_email. + /// + /// In en, this message translates to: + /// **'Edit email address'** + String get edit_email; + + /// No description provided for @birth_date. + /// + /// In en, this message translates to: + /// **'Birth date'** + String get birth_date; + + /// No description provided for @edit_birth. + /// + /// In en, this message translates to: + /// **'Edit birth date'** + String get edit_birth; + + /// No description provided for @create_profile_button. + /// + /// In en, this message translates to: + /// **'Create profile'** + String get create_profile_button; + + /// No description provided for @take_picture. + /// + /// In en, this message translates to: + /// **'Take a picture'** + String get take_picture; + + /// No description provided for @error_ia. + /// + /// In en, this message translates to: + /// **'Google AI failed to analyze picture. Retry with another one'** + String get error_ia; + + /// No description provided for @no_data_geo. + /// + /// In en, this message translates to: + /// **'No geographical data'** + String get no_data_geo; + + /// No description provided for @response_status_update. + /// + /// In en, this message translates to: + /// **'response status code update'** + String get response_status_update; + + /// No description provided for @error_token. + /// + /// In en, this message translates to: + /// **'Token error'** + String get error_token; + + /// No description provided for @error_format. + /// + /// In en, this message translates to: + /// **'Data format error given by AI'** + String get error_format; + + /// No description provided for @display_picture. + /// + /// In en, this message translates to: + /// **'Display the Picture'** + String get display_picture; + + /// No description provided for @analyze_image. + /// + /// In en, this message translates to: + /// **'Image Analyze in progress'** + String get analyze_image; + + /// No description provided for @loading_progress. + /// + /// In en, this message translates to: + /// **'Loading progress'** + String get loading_progress; + + /// No description provided for @error_event. + /// + /// In en, this message translates to: + /// **'Event error'** + String get error_event; + + /// No description provided for @no_future_event. + /// + /// In en, this message translates to: + /// **'No future event'** + String get no_future_event; + + /// No description provided for @error_user. + /// + /// In en, this message translates to: + /// **'Error user'** + String get error_user; + + /// No description provided for @empty_input. + /// + /// In en, this message translates to: + /// **'Empty input'** + String get empty_input; + + /// No description provided for @info_event. + /// + /// In en, this message translates to: + /// **'Event info'** + String get info_event; + + /// No description provided for @event_already. + /// + /// In en, this message translates to: + /// **'Event already exists'** + String get event_already; + + /// No description provided for @picture_error. + /// + /// In en, this message translates to: + /// **'Picture error'** + String get picture_error; + + /// No description provided for @no_picture_published. + /// + /// In en, this message translates to: + /// **'No picture published'** + String get no_picture_published; + + /// No description provided for @event_update. + /// + /// In en, this message translates to: + /// **'Event updated'** + String get event_update; + + /// No description provided for @location. + /// + /// In en, this message translates to: + /// **'Location'** + String get location; + + /// No description provided for @add_event. + /// + /// In en, this message translates to: + /// **'Add or Update a event'** + String get add_event; + + /// No description provided for @edit_image. + /// + /// In en, this message translates to: + /// **'Edit pictures'** + String get edit_image; + + /// No description provided for @name. + /// + /// In en, this message translates to: + /// **'Name'** + String get name; + + /// No description provided for @edit_event_name. + /// + /// In en, this message translates to: + /// **'Edit event name'** + String get edit_event_name; + + /// No description provided for @start_time. + /// + /// In en, this message translates to: + /// **'Start time'** + String get start_time; + + /// No description provided for @end_time. + /// + /// In en, this message translates to: + /// **'End time'** + String get end_time; + + /// No description provided for @select_date. + /// + /// In en, this message translates to: + /// **'Click to select a date'** + String get select_date; + + /// No description provided for @select_time. + /// + /// In en, this message translates to: + /// **'Click to select a time'** + String get select_time; + + /// No description provided for @tag. + /// + /// In en, this message translates to: + /// **'Tags'** + String get tag; + + /// No description provided for @already_tag. + /// + /// In en, this message translates to: + /// **'You have already this tags'** + String get already_tag; + + /// No description provided for @enter_tag. + /// + /// In en, this message translates to: + /// **'Enter a tag'** + String get enter_tag; + + /// No description provided for @organizer. + /// + /// In en, this message translates to: + /// **'Organizer'** + String get organizer; + + /// No description provided for @already_organiser. + /// + /// In en, this message translates to: + /// **'You have already a organizer'** + String get already_organiser; + + /// No description provided for @enter_organizer. + /// + /// In en, this message translates to: + /// **'Enter a organizer'** + String get enter_organizer; + + /// No description provided for @description. + /// + /// In en, this message translates to: + /// **'Description'** + String get description; + + /// No description provided for @describe_event. + /// + /// In en, this message translates to: + /// **'Describe event'** + String get describe_event; + + /// No description provided for @add. + /// + /// In en, this message translates to: + /// **'Add'** + String get add; + + /// No description provided for @different_password_error. + /// + /// In en, this message translates to: + /// **'Different password'** + String get different_password_error; + + /// No description provided for @update. + /// + /// In en, this message translates to: + /// **'Update'** + String get update; + + /// No description provided for @updated. + /// + /// In en, this message translates to: + /// **'Updated'** + String get updated; + + /// No description provided for @settings_updated. + /// + /// In en, this message translates to: + /// **'Settings updated'** + String get settings_updated; + + /// No description provided for @define_kilometer. + /// + /// In en, this message translates to: + /// **'Define Kilometer'** + String get define_kilometer; + + /// No description provided for @email_sent. + /// + /// In en, this message translates to: + /// **'Email has been sent'** + String get email_sent; + + /// No description provided for @forgot_password. + /// + /// In en, this message translates to: + /// **'Forgot password'** + String get forgot_password; + + /// No description provided for @enter_email. + /// + /// In en, this message translates to: + /// **'Enter the email'** + String get enter_email; + + /// No description provided for @send_email. + /// + /// In en, this message translates to: + /// **'Send email'** + String get send_email; + + /// No description provided for @invalid_cache. + /// + /// In en, this message translates to: + /// **'Invalid cache'** + String get invalid_cache; + + /// No description provided for @item_date. + /// + /// In en, this message translates to: + /// **'Date : '** + String get item_date; + + /// No description provided for @item_maps. + /// + /// In en, this message translates to: + /// **'Maps : '** + String get item_maps; + + /// No description provided for @item_organizer. + /// + /// In en, this message translates to: + /// **'Organizer : '** + String get item_organizer; + + /// No description provided for @item_description. + /// + /// In en, this message translates to: + /// **'Description : '** + String get item_description; + + /// No description provided for @item_tags. + /// + /// In en, this message translates to: + /// **'Tags : '** + String get item_tags; + + /// No description provided for @failed_auth. + /// + /// In en, this message translates to: + /// **'Authentification failed'** + String get failed_auth; + + /// No description provided for @login_page. + /// + /// In en, this message translates to: + /// **'Login page'** + String get login_page; + + /// No description provided for @pseudo. + /// + /// In en, this message translates to: + /// **'Pseudo'** + String get pseudo; + + /// No description provided for @enter_existing_pseudo. + /// + /// In en, this message translates to: + /// **'Enter a existing pseudo'** + String get enter_existing_pseudo; + + /// No description provided for @remembr_me. + /// + /// In en, this message translates to: + /// **'Remember me'** + String get remembr_me; + + /// No description provided for @new_user. + /// + /// In en, this message translates to: + /// **'New User? Create Account'** + String get new_user; + + /// No description provided for @sign_in. + /// + /// In en, this message translates to: + /// **'Sign in'** + String get sign_in; + + /// No description provided for @map_token. + /// + /// In en, this message translates to: + /// **'Mapbox Access Token is not available'** + String get map_token; + + /// No description provided for @geo_disabled. + /// + /// In en, this message translates to: + /// **'Location services are disabled.'** + String get geo_disabled; + + /// No description provided for @permission_denied. + /// + /// In en, this message translates to: + /// **'Location permissions are denied.'** + String get permission_denied; + + /// No description provided for @enable_permission. + /// + /// In en, this message translates to: + /// **'Location permissions are permanently denied. Enable them in settings.'** + String get enable_permission; + + /// No description provided for @no_last_position. + /// + /// In en, this message translates to: + /// **'No last known position available.'** + String get no_last_position; + + /// No description provided for @failed_location. + /// + /// In en, this message translates to: + /// **'Failed to get user location'** + String get failed_location; + + /// No description provided for @failed_fetch. + /// + /// In en, this message translates to: + /// **'Failed to fetch the route'** + String get failed_fetch; + + /// No description provided for @invalid_coordinates_symbol. + /// + /// In en, this message translates to: + /// **'Invalid coordinates, cannot add symbol.'** + String get invalid_coordinates_symbol; + + /// No description provided for @error_symbol. + /// + /// In en, this message translates to: + /// **'Error when adding symbol.'** + String get error_symbol; + + /// No description provided for @position_not_init. + /// + /// In en, this message translates to: + /// **'User position is not yet initialized. Try again.'** + String get position_not_init; + + /// No description provided for @invalid_coordinates. + /// + /// In en, this message translates to: + /// **'Invalid coordinates.'** + String get invalid_coordinates; + + /// No description provided for @walking. + /// + /// In en, this message translates to: + /// **'Walking'** + String get walking; + + /// No description provided for @cycling. + /// + /// In en, this message translates to: + /// **'Cycling'** + String get cycling; + + /// No description provided for @driving. + /// + /// In en, this message translates to: + /// **'Driving'** + String get driving; + + /// No description provided for @get_direction. + /// + /// In en, this message translates to: + /// **'Get Directions and Markers'** + String get get_direction; + + /// No description provided for @missing_token. + /// + /// In en, this message translates to: + /// **'Missing access token'** + String get missing_token; + + /// No description provided for @geocoding_error. + /// + /// In en, this message translates to: + /// **'Error when geocoding'** + String get geocoding_error; + + /// No description provided for @no_found_place. + /// + /// In en, this message translates to: + /// **'No found place'** + String get no_found_place; + + /// No description provided for @upload_error. + /// + /// In en, this message translates to: + /// **'Error when image uploading'** + String get upload_error; + + /// No description provided for @event_added. + /// + /// In en, this message translates to: + /// **'Event added'** + String get event_added; + + /// No description provided for @unknown_error. + /// + /// In en, this message translates to: + /// **'Unknown error'** + String get unknown_error; + + /// No description provided for @app_error. + /// + /// In en, this message translates to: + /// **'Application error'** + String get app_error; + + /// No description provided for @at. + /// + /// In en, this message translates to: + /// **'at'** + String get at; + + /// No description provided for @to_date. + /// + /// In en, this message translates to: + /// **'to'** + String get to_date; + + /// No description provided for @item_link. + /// + /// In en, this message translates to: + /// **'Link : '** + String get item_link; + + /// No description provided for @item_ticket. + /// + /// In en, this message translates to: + /// **'Ticket : '** + String get item_ticket; + + /// No description provided for @link. + /// + /// In en, this message translates to: + /// **'Link'** + String get link; + + /// No description provided for @edit_link. + /// + /// In en, this message translates to: + /// **'Edit link name'** + String get edit_link; + + /// No description provided for @ticket. + /// + /// In en, this message translates to: + /// **'Ticket'** + String get ticket; + + /// No description provided for @edit_ticket. + /// + /// In en, this message translates to: + /// **'Edit ticket link'** + String get edit_ticket; + + /// No description provided for @toogle_interest. + /// + /// In en, this message translates to: + /// **'Error toggle interest'** + String get toogle_interest; + + /// No description provided for @error_update. + /// + /// In en, this message translates to: + /// **'Error when updating'** + String get error_update; + + /// No description provided for @count_interested. + /// + /// In en, this message translates to: + /// **'Interested people number'** + String get count_interested; +} + +class _AppLocalizationsDelegate + extends LocalizationsDelegate { + const _AppLocalizationsDelegate(); + + @override + Future load(Locale locale) { + return SynchronousFuture(lookupAppLocalizations(locale)); + } + + @override + bool isSupported(Locale locale) => + ['de', 'en', 'fr'].contains(locale.languageCode); + + @override + bool shouldReload(_AppLocalizationsDelegate old) => false; +} + +AppLocalizations lookupAppLocalizations(Locale locale) { + // Lookup logic when only language code is specified. + switch (locale.languageCode) { + case 'de': + return AppLocalizationsDe(); + case 'en': + return AppLocalizationsEn(); + case 'fr': + return AppLocalizationsFr(); + } + + throw FlutterError( + 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.'); +} diff --git a/covas_mobile_new/lib/l10n/app_localizations_de.dart b/covas_mobile_new/lib/l10n/app_localizations_de.dart new file mode 100644 index 0000000..46d179a --- /dev/null +++ b/covas_mobile_new/lib/l10n/app_localizations_de.dart @@ -0,0 +1,434 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for German (`de`). +class AppLocalizationsDe extends AppLocalizations { + AppLocalizationsDe([String locale = 'de']) : super(locale); + + @override + String get menu_list => 'Veranstaltungsmenü'; + + @override + String get language => 'Sprache'; + + @override + String get home => 'Startseite'; + + @override + String get settings => 'Einstellungen'; + + @override + String get update_profile => 'Profil aktualisieren'; + + @override + String get about => 'Über'; + + @override + String get log_out => 'Abmelden'; + + @override + String get french => 'Französisch'; + + @override + String get english => 'Englisch'; + + @override + String get german => 'Deutsch'; + + @override + String get select_language => 'Sprache auswählen'; + + @override + String get search_item => 'Nach Element suchen'; + + @override + String get search_tag => 'Nach Schlagwörtern suchen'; + + @override + String get search_geographical => 'Nach geografischer Zone suchen'; + + @override + String get show_date_field => 'Datumsfelder anzeigen'; + + @override + String get hide_date_field => 'Datumsfelder ausblenden'; + + @override + String get no_data => 'Keine Daten verfügbar'; + + @override + String get search => 'Suchen'; + + @override + String get no_events => 'Keine Veranstaltungen für diesen Ort verfügbar.'; + + @override + String get start_date => 'Anfangsdatum'; + + @override + String get end_date => 'Enddatum'; + + @override + String get failed_suggestions => 'Vorschläge konnten nicht geladen werden'; + + @override + String get error => 'Fehler'; + + @override + String get password_different => 'Ein anderes Passwort eingeben'; + + @override + String get create => 'Erstellung'; + + @override + String get user_create => 'Benutzer wurde erstellt'; + + @override + String get user_update => 'Benutzer wurde aktualisiert'; + + @override + String get request_error => 'Fehlerhafte Anfrage'; + + @override + String get incorrect_password => 'Falsches Passwort'; + + @override + String get unknown_user => 'Unbekannter Benutzer'; + + @override + String get disabled_user => 'Benutzer deaktiviert'; + + @override + String get invalid_token => 'Ungültiger Token'; + + @override + String get internal_error_server => 'Interner Serverfehler'; + + @override + String get unknown_error_auth => 'Unbekannter Authentifizierungsfehler'; + + @override + String get required_input => 'Pflichtfeld'; + + @override + String get create_profile => 'Profil erstellen'; + + @override + String get edit_pseudo => 'Benutzernamen bearbeiten'; + + @override + String get password => 'Passwort'; + + @override + String get enter_password => 'Passwort eingeben'; + + @override + String get password_confirmed => 'Passwort bestätigt'; + + @override + String get last_name => 'Nachname'; + + @override + String get first_name => 'Vorname'; + + @override + String get email => 'E-Mail'; + + @override + String get edit_last_name => 'Nachnamen bearbeiten'; + + @override + String get edit_first_name => 'Vornamen bearbeiten'; + + @override + String get edit_email => 'E-Mail-Adresse bearbeiten'; + + @override + String get birth_date => 'Geburtsdatum'; + + @override + String get edit_birth => 'Geburtsdatum bearbeiten'; + + @override + String get create_profile_button => 'Profil erstellen'; + + @override + String get take_picture => 'Foto aufnehmen'; + + @override + String get error_ia => + 'Google KI konnte das Bild nicht analysieren. Bitte ein anderes versuchen.'; + + @override + String get no_data_geo => 'Keine geografischen Daten'; + + @override + String get response_status_update => 'Statuscode-Antwort aktualisieren'; + + @override + String get error_token => 'Token-Fehler'; + + @override + String get error_format => 'Vom KI geliefertes Datenformat ist fehlerhaft'; + + @override + String get display_picture => 'Bild anzeigen'; + + @override + String get analyze_image => 'Bildanalyse läuft'; + + @override + String get loading_progress => 'Ladefortschritt'; + + @override + String get error_event => 'Veranstaltungsfehler'; + + @override + String get no_future_event => 'Keine zukünftigen Veranstaltungen'; + + @override + String get error_user => 'Benutzerfehler'; + + @override + String get empty_input => 'Eingabefeld leer'; + + @override + String get info_event => 'Veranstaltungsinfo'; + + @override + String get event_already => 'Veranstaltung existiert bereits'; + + @override + String get picture_error => 'Bildfehler'; + + @override + String get no_picture_published => 'Kein Bild veröffentlicht'; + + @override + String get event_update => 'Veranstaltung aktualisiert'; + + @override + String get location => 'Ort'; + + @override + String get add_event => 'Veranstaltung hinzufügen oder aktualisieren'; + + @override + String get edit_image => 'Bilder bearbeiten'; + + @override + String get name => 'Name'; + + @override + String get edit_event_name => 'Veranstaltungsname bearbeiten'; + + @override + String get start_time => 'Startzeit'; + + @override + String get end_time => 'Endzeit'; + + @override + String get select_date => 'Zum Auswählen eines Datums klicken'; + + @override + String get select_time => 'Zum Auswählen einer Uhrzeit klicken'; + + @override + String get tag => 'Schlagwörter'; + + @override + String get already_tag => 'Dieses Schlagwort ist bereits vorhanden'; + + @override + String get enter_tag => 'Ein Schlagwort eingeben'; + + @override + String get organizer => 'Veranstalter'; + + @override + String get already_organiser => 'Veranstalter bereits vorhanden'; + + @override + String get enter_organizer => 'Veranstalter eingeben'; + + @override + String get description => 'Beschreibung'; + + @override + String get describe_event => 'Veranstaltung beschreiben'; + + @override + String get add => 'Hinzufügen'; + + @override + String get different_password_error => 'Passwörter stimmen nicht überein'; + + @override + String get update => 'Aktualisieren'; + + @override + String get updated => 'Aktualisiert'; + + @override + String get settings_updated => 'Einstellungen aktualisiert'; + + @override + String get define_kilometer => 'Kilometer definieren'; + + @override + String get email_sent => 'E-Mail wurde gesendet'; + + @override + String get forgot_password => 'Passwort vergessen'; + + @override + String get enter_email => 'E-Mail eingeben'; + + @override + String get send_email => 'E-Mail senden'; + + @override + String get invalid_cache => 'Ungültiger Cache'; + + @override + String get item_date => 'Datum : '; + + @override + String get item_maps => 'Karte : '; + + @override + String get item_organizer => 'Veranstalter : '; + + @override + String get item_description => 'Beschreibung : '; + + @override + String get item_tags => 'Schlagwörter : '; + + @override + String get failed_auth => 'Authentifizierung fehlgeschlagen'; + + @override + String get login_page => 'Anmeldeseite'; + + @override + String get pseudo => 'Benutzername'; + + @override + String get enter_existing_pseudo => 'Vorhandenen Benutzernamen eingeben'; + + @override + String get remembr_me => 'Angemeldet bleiben'; + + @override + String get new_user => 'Neuer Benutzer? Konto erstellen'; + + @override + String get sign_in => 'Anmelden'; + + @override + String get map_token => 'Mapbox-Zugangstoken ist nicht verfügbar'; + + @override + String get geo_disabled => 'Standortdienste sind deaktiviert.'; + + @override + String get permission_denied => 'Standortberechtigungen wurden verweigert.'; + + @override + String get enable_permission => + 'Standortberechtigungen dauerhaft verweigert. Bitte in den Einstellungen aktivieren.'; + + @override + String get no_last_position => 'Keine letzte bekannte Position verfügbar.'; + + @override + String get failed_location => 'Standort konnte nicht ermittelt werden'; + + @override + String get failed_fetch => 'Route konnte nicht abgerufen werden'; + + @override + String get invalid_coordinates_symbol => + 'Ungültige Koordinaten, Symbol kann nicht hinzugefügt werden.'; + + @override + String get error_symbol => 'Fehler beim Hinzufügen des Symbols.'; + + @override + String get position_not_init => + 'Benutzerposition noch nicht initialisiert. Erneut versuchen.'; + + @override + String get invalid_coordinates => 'Ungültige Koordinaten.'; + + @override + String get walking => 'Zu Fuß'; + + @override + String get cycling => 'Mit dem Fahrrad'; + + @override + String get driving => 'Mit dem Auto'; + + @override + String get get_direction => 'Wegbeschreibung und Markierungen anzeigen'; + + @override + String get missing_token => 'Zugangstoken fehlt'; + + @override + String get geocoding_error => 'Fehler bei der Geokodierung'; + + @override + String get no_found_place => 'Kein Ort gefunden'; + + @override + String get upload_error => 'Fehler beim Hochladen des Bildes'; + + @override + String get event_added => 'Veranstaltung hinzugefügt'; + + @override + String get unknown_error => 'Unbekannter Fehler'; + + @override + String get app_error => 'Anwendungsfehler'; + + @override + String get at => 'um'; + + @override + String get to_date => 'bis'; + + @override + String get item_link => 'Link : '; + + @override + String get item_ticket => 'Abendkarte : '; + + @override + String get link => 'Link'; + + @override + String get edit_link => 'Linkereignis bearbeiten'; + + @override + String get ticket => 'Abendkarte'; + + @override + String get edit_ticket => 'Ticketlink bearbeiten'; + + @override + String get toogle_interest => 'Fehler beim Umschalten des Interesses'; + + @override + String get error_update => 'Fehler beim Update'; + + @override + String get count_interested => 'Anzahl der Interessenten'; +} diff --git a/covas_mobile_new/lib/l10n/app_localizations_en.dart b/covas_mobile_new/lib/l10n/app_localizations_en.dart new file mode 100644 index 0000000..59d7a22 --- /dev/null +++ b/covas_mobile_new/lib/l10n/app_localizations_en.dart @@ -0,0 +1,434 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for English (`en`). +class AppLocalizationsEn extends AppLocalizations { + AppLocalizationsEn([String locale = 'en']) : super(locale); + + @override + String get menu_list => 'Event list menu'; + + @override + String get language => 'Language'; + + @override + String get home => 'Home'; + + @override + String get settings => 'Settings'; + + @override + String get update_profile => 'Update profile'; + + @override + String get about => 'About'; + + @override + String get log_out => 'Log out'; + + @override + String get french => 'French'; + + @override + String get english => 'English'; + + @override + String get german => 'German'; + + @override + String get select_language => 'Select language'; + + @override + String get search_item => 'Search by item'; + + @override + String get search_tag => 'Search by tags'; + + @override + String get search_geographical => 'Search by geographical zone'; + + @override + String get show_date_field => 'Show Date Fields'; + + @override + String get hide_date_field => 'Hide Date Fields'; + + @override + String get no_data => 'No data available'; + + @override + String get search => 'Search'; + + @override + String get no_events => 'No events available for this location.'; + + @override + String get start_date => 'Start date'; + + @override + String get end_date => 'End date'; + + @override + String get failed_suggestions => 'Failed to load suggestions'; + + @override + String get error => 'Error'; + + @override + String get password_different => 'Must write a different password'; + + @override + String get create => 'Creation'; + + @override + String get user_create => 'Your user created'; + + @override + String get user_update => 'Your user updated'; + + @override + String get request_error => 'Poorly constructed query'; + + @override + String get incorrect_password => 'Incorrect password'; + + @override + String get unknown_user => 'Unknown user'; + + @override + String get disabled_user => 'User disabled'; + + @override + String get invalid_token => 'Invalid token'; + + @override + String get internal_error_server => 'Internal error server'; + + @override + String get unknown_error_auth => 'Unknown error authentification'; + + @override + String get required_input => 'Required input'; + + @override + String get create_profile => 'Create profile'; + + @override + String get edit_pseudo => 'Edit pseudo'; + + @override + String get password => 'Password'; + + @override + String get enter_password => 'Enter the passord'; + + @override + String get password_confirmed => 'Password confirmed'; + + @override + String get last_name => 'Last name'; + + @override + String get first_name => 'First name'; + + @override + String get email => 'Mail'; + + @override + String get edit_last_name => 'Edit name'; + + @override + String get edit_first_name => 'Edit first name'; + + @override + String get edit_email => 'Edit email address'; + + @override + String get birth_date => 'Birth date'; + + @override + String get edit_birth => 'Edit birth date'; + + @override + String get create_profile_button => 'Create profile'; + + @override + String get take_picture => 'Take a picture'; + + @override + String get error_ia => + 'Google AI failed to analyze picture. Retry with another one'; + + @override + String get no_data_geo => 'No geographical data'; + + @override + String get response_status_update => 'response status code update'; + + @override + String get error_token => 'Token error'; + + @override + String get error_format => 'Data format error given by AI'; + + @override + String get display_picture => 'Display the Picture'; + + @override + String get analyze_image => 'Image Analyze in progress'; + + @override + String get loading_progress => 'Loading progress'; + + @override + String get error_event => 'Event error'; + + @override + String get no_future_event => 'No future event'; + + @override + String get error_user => 'Error user'; + + @override + String get empty_input => 'Empty input'; + + @override + String get info_event => 'Event info'; + + @override + String get event_already => 'Event already exists'; + + @override + String get picture_error => 'Picture error'; + + @override + String get no_picture_published => 'No picture published'; + + @override + String get event_update => 'Event updated'; + + @override + String get location => 'Location'; + + @override + String get add_event => 'Add or Update a event'; + + @override + String get edit_image => 'Edit pictures'; + + @override + String get name => 'Name'; + + @override + String get edit_event_name => 'Edit event name'; + + @override + String get start_time => 'Start time'; + + @override + String get end_time => 'End time'; + + @override + String get select_date => 'Click to select a date'; + + @override + String get select_time => 'Click to select a time'; + + @override + String get tag => 'Tags'; + + @override + String get already_tag => 'You have already this tags'; + + @override + String get enter_tag => 'Enter a tag'; + + @override + String get organizer => 'Organizer'; + + @override + String get already_organiser => 'You have already a organizer'; + + @override + String get enter_organizer => 'Enter a organizer'; + + @override + String get description => 'Description'; + + @override + String get describe_event => 'Describe event'; + + @override + String get add => 'Add'; + + @override + String get different_password_error => 'Different password'; + + @override + String get update => 'Update'; + + @override + String get updated => 'Updated'; + + @override + String get settings_updated => 'Settings updated'; + + @override + String get define_kilometer => 'Define Kilometer'; + + @override + String get email_sent => 'Email has been sent'; + + @override + String get forgot_password => 'Forgot password'; + + @override + String get enter_email => 'Enter the email'; + + @override + String get send_email => 'Send email'; + + @override + String get invalid_cache => 'Invalid cache'; + + @override + String get item_date => 'Date : '; + + @override + String get item_maps => 'Maps : '; + + @override + String get item_organizer => 'Organizer : '; + + @override + String get item_description => 'Description : '; + + @override + String get item_tags => 'Tags : '; + + @override + String get failed_auth => 'Authentification failed'; + + @override + String get login_page => 'Login page'; + + @override + String get pseudo => 'Pseudo'; + + @override + String get enter_existing_pseudo => 'Enter a existing pseudo'; + + @override + String get remembr_me => 'Remember me'; + + @override + String get new_user => 'New User? Create Account'; + + @override + String get sign_in => 'Sign in'; + + @override + String get map_token => 'Mapbox Access Token is not available'; + + @override + String get geo_disabled => 'Location services are disabled.'; + + @override + String get permission_denied => 'Location permissions are denied.'; + + @override + String get enable_permission => + 'Location permissions are permanently denied. Enable them in settings.'; + + @override + String get no_last_position => 'No last known position available.'; + + @override + String get failed_location => 'Failed to get user location'; + + @override + String get failed_fetch => 'Failed to fetch the route'; + + @override + String get invalid_coordinates_symbol => + 'Invalid coordinates, cannot add symbol.'; + + @override + String get error_symbol => 'Error when adding symbol.'; + + @override + String get position_not_init => + 'User position is not yet initialized. Try again.'; + + @override + String get invalid_coordinates => 'Invalid coordinates.'; + + @override + String get walking => 'Walking'; + + @override + String get cycling => 'Cycling'; + + @override + String get driving => 'Driving'; + + @override + String get get_direction => 'Get Directions and Markers'; + + @override + String get missing_token => 'Missing access token'; + + @override + String get geocoding_error => 'Error when geocoding'; + + @override + String get no_found_place => 'No found place'; + + @override + String get upload_error => 'Error when image uploading'; + + @override + String get event_added => 'Event added'; + + @override + String get unknown_error => 'Unknown error'; + + @override + String get app_error => 'Application error'; + + @override + String get at => 'at'; + + @override + String get to_date => 'to'; + + @override + String get item_link => 'Link : '; + + @override + String get item_ticket => 'Ticket : '; + + @override + String get link => 'Link'; + + @override + String get edit_link => 'Edit link name'; + + @override + String get ticket => 'Ticket'; + + @override + String get edit_ticket => 'Edit ticket link'; + + @override + String get toogle_interest => 'Error toggle interest'; + + @override + String get error_update => 'Error when updating'; + + @override + String get count_interested => 'Interested people number'; +} diff --git a/covas_mobile_new/lib/l10n/app_localizations_fr.dart b/covas_mobile_new/lib/l10n/app_localizations_fr.dart new file mode 100644 index 0000000..8f1750b --- /dev/null +++ b/covas_mobile_new/lib/l10n/app_localizations_fr.dart @@ -0,0 +1,437 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for French (`fr`). +class AppLocalizationsFr extends AppLocalizations { + AppLocalizationsFr([String locale = 'fr']) : super(locale); + + @override + String get menu_list => 'Liste d\'évènement'; + + @override + String get language => 'Langue'; + + @override + String get home => 'Accueil'; + + @override + String get settings => 'Paramètres'; + + @override + String get update_profile => 'Modifier le profil'; + + @override + String get about => 'À propos'; + + @override + String get log_out => 'Se déconnecter'; + + @override + String get french => 'Français'; + + @override + String get english => 'Anglais'; + + @override + String get german => 'Allemand'; + + @override + String get select_language => 'Selectionne la langue'; + + @override + String get search_item => 'Recherche par item'; + + @override + String get search_tag => 'Recherche par tags'; + + @override + String get search_geographical => 'Recherche par zone géographique'; + + @override + String get show_date_field => 'Afficher champ date'; + + @override + String get hide_date_field => 'Cacher Date Fields'; + + @override + String get no_data => 'Aucune donnée disponible'; + + @override + String get search => 'Recherche'; + + @override + String get no_events => 'Pas d\'évènements dans cette localisation'; + + @override + String get start_date => 'Date de début'; + + @override + String get end_date => 'Date de fin'; + + @override + String get failed_suggestions => 'Echec de chargement des suggestions'; + + @override + String get error => 'Erreur'; + + @override + String get password_different => 'Tu dois écrire un mot de passe different'; + + @override + String get create => 'Création'; + + @override + String get user_create => 'Votre utilisateur a été créé'; + + @override + String get user_update => 'Votre utilisateur a été modifié'; + + @override + String get request_error => 'Requête mal construite'; + + @override + String get incorrect_password => 'Mot de passe incorrect'; + + @override + String get unknown_user => 'Utilisateur inconnu'; + + @override + String get disabled_user => 'Utilisateur désactivé'; + + @override + String get invalid_token => 'Token invalide'; + + @override + String get internal_error_server => 'Erreur interne de serveur'; + + @override + String get unknown_error_auth => 'Problème d\'authentification inconnu'; + + @override + String get required_input => 'Champ requis'; + + @override + String get create_profile => 'Creation profil'; + + @override + String get edit_pseudo => 'Modifier le pseudo'; + + @override + String get password => 'Mot de passe'; + + @override + String get enter_password => 'Entrez le password'; + + @override + String get password_confirmed => 'Confirmez le mot de passe'; + + @override + String get last_name => 'Nom'; + + @override + String get first_name => 'Prénom'; + + @override + String get email => 'Email'; + + @override + String get edit_last_name => 'Modifier le nom'; + + @override + String get edit_first_name => 'Modifier le prénom'; + + @override + String get edit_email => 'Modifier l\'email'; + + @override + String get birth_date => 'Date de naissance'; + + @override + String get edit_birth => 'Modifier la date de naissance'; + + @override + String get create_profile_button => 'Créer le profil'; + + @override + String get take_picture => 'Take a picture'; + + @override + String get error_ia => + 'L\'IA de Google n\'a pas su analyser l\'image. Recommencer avec une autre'; + + @override + String get no_data_geo => 'Aucune donnée géographique'; + + @override + String get response_status_update => + 'Code du statut de réponse de la modification'; + + @override + String get error_token => 'Erreur de token'; + + @override + String get error_format => 'Erreur de format de donnée fourni par l\'IA'; + + @override + String get display_picture => 'Display the Picture'; + + @override + String get analyze_image => 'Analyse de l\'image en cours'; + + @override + String get loading_progress => 'Chargement en cours'; + + @override + String get error_event => 'Erreur de l\'évènement'; + + @override + String get no_future_event => 'Évènement non futur'; + + @override + String get error_user => 'Erreur de l\'utilisateur'; + + @override + String get empty_input => 'Champ vide'; + + @override + String get info_event => 'Event info'; + + @override + String get event_already => 'Event already exists'; + + @override + String get picture_error => 'Erreur image'; + + @override + String get no_picture_published => 'Image non publiée'; + + @override + String get event_update => 'Évènement modifié'; + + @override + String get location => 'Lieu'; + + @override + String get add_event => 'Ajouter ou modifier un évènement'; + + @override + String get edit_image => 'Changer la photo'; + + @override + String get name => 'Nom'; + + @override + String get edit_event_name => 'Changer le nom de l\'évènement'; + + @override + String get start_time => 'Heure de début'; + + @override + String get end_time => 'Heure de fin'; + + @override + String get select_date => 'Cliquer pour selectionner une date'; + + @override + String get select_time => 'Cliquer pour selectionner une heure'; + + @override + String get tag => 'Tags'; + + @override + String get already_tag => 'Tu as déjà entré ce tag'; + + @override + String get enter_tag => 'Entrer un tag'; + + @override + String get organizer => 'Organisateur'; + + @override + String get already_organiser => 'Tu as déjà rentré cet organisateur'; + + @override + String get enter_organizer => 'Entrer un organisateur'; + + @override + String get description => 'Description'; + + @override + String get describe_event => 'Décrire l\'évènement'; + + @override + String get add => 'Ajouter'; + + @override + String get different_password_error => 'Mot de passe différent'; + + @override + String get update => 'Mettre à jour'; + + @override + String get updated => 'Mis à jour'; + + @override + String get settings_updated => 'Paramètre mis à jour'; + + @override + String get define_kilometer => 'Definir un kilomètre'; + + @override + String get email_sent => 'Email a été envoyé'; + + @override + String get forgot_password => 'Mot de passe oublié'; + + @override + String get enter_email => 'Entrez l\'email'; + + @override + String get send_email => 'Send email'; + + @override + String get invalid_cache => 'Cache invalide'; + + @override + String get item_date => 'Date : '; + + @override + String get item_maps => 'Carte : '; + + @override + String get item_organizer => 'Organisateurs : '; + + @override + String get item_description => 'Description : '; + + @override + String get item_tags => 'Tags : '; + + @override + String get failed_auth => 'Échec de l\'authenticaton'; + + @override + String get login_page => 'Page d\'authentification'; + + @override + String get pseudo => 'Pseudo'; + + @override + String get enter_existing_pseudo => 'Entrez un pseudo existant'; + + @override + String get remembr_me => 'Se souvenir de moi'; + + @override + String get new_user => 'Nouvel utilisateur ? Créer un compte'; + + @override + String get sign_in => 'Se connecter'; + + @override + String get map_token => 'Token d\'accès de Mapbox n\'est pas disponible'; + + @override + String get geo_disabled => 'Les services de localisation sont désactivés.'; + + @override + String get permission_denied => + 'Les permissions de localisation sont refusées.'; + + @override + String get enable_permission => + 'Les permissions de localisation sont toujours désactivés. Il faut les désactiver'; + + @override + String get no_last_position => 'Aucune position n\'est pas disponible.'; + + @override + String get failed_location => + 'Échec de récupération des données geographique'; + + @override + String get failed_fetch => 'Échec de récupération des routes'; + + @override + String get invalid_coordinates_symbol => + 'Coordonnées invalides. On ne peut pas ajouter le symbole'; + + @override + String get error_symbol => 'Erreur lors de l\'ajout du symbole'; + + @override + String get position_not_init => + 'Coordonnées non initialisées. Essaye encore.'; + + @override + String get invalid_coordinates => 'Coordonnées invalides'; + + @override + String get walking => 'Marche'; + + @override + String get cycling => 'Vélo'; + + @override + String get driving => 'Voiture'; + + @override + String get get_direction => 'Get Directions and Markers'; + + @override + String get missing_token => 'Token d\'accès manquant'; + + @override + String get geocoding_error => 'Erreur lors du geocodage'; + + @override + String get no_found_place => 'Lieu introuvable'; + + @override + String get upload_error => 'Erreur lors de l\'upload d\'image'; + + @override + String get event_added => 'Évènement ajouté'; + + @override + String get unknown_error => 'Erreur inconnue'; + + @override + String get app_error => 'Erreur d\'application'; + + @override + String get at => 'à'; + + @override + String get to_date => 'jusqu\'à'; + + @override + String get item_link => 'Lien : '; + + @override + String get item_ticket => 'Billet : '; + + @override + String get link => 'Lien'; + + @override + String get edit_link => 'Editer le lien'; + + @override + String get ticket => 'Billet'; + + @override + String get edit_ticket => 'Editer le lien du billet'; + + @override + String get toogle_interest => 'Erreur de bouton de changement'; + + @override + String get error_update => 'Erreur lors de la mise à jour'; + + @override + String get count_interested => 'Nombre de personne interessé'; +} diff --git a/covas_mobile_new/lib/locale_provider.dart b/covas_mobile_new/lib/locale_provider.dart new file mode 100644 index 0000000..0d90807 --- /dev/null +++ b/covas_mobile_new/lib/locale_provider.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class LocaleProvider with ChangeNotifier { + static const _localeKey = 'locale_code'; + + Locale _locale = const Locale('en'); + + Locale get locale => _locale; + + LocaleProvider() { + _loadLocale(); + } + + Future _loadLocale() async { + final prefs = await SharedPreferences.getInstance(); + final code = prefs.getString(_localeKey); + if (code != null && L10n.all.contains(Locale(code))) { + _locale = Locale(code); + notifyListeners(); + } + } + + void setLocale(Locale locale) async { + if (!L10n.all.contains(locale)) return; + + _locale = locale; + notifyListeners(); + + final prefs = await SharedPreferences.getInstance(); + await prefs.setString(_localeKey, locale.languageCode); + } +} + +class L10n { + static final all = [ + const Locale('en'), + const Locale('fr'), + const Locale('de') + ]; +} diff --git a/covas_mobile_new/lib/main.dart b/covas_mobile_new/lib/main.dart new file mode 100644 index 0000000..cba36b6 --- /dev/null +++ b/covas_mobile_new/lib/main.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:google_mobile_ads/google_mobile_ads.dart'; +import 'package:provider/provider.dart'; + +import 'pages/LoginDemo.dart'; +import 'locale_provider.dart'; // <-- à adapter selon ton arborescence +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'classes/notification_service.dart'; + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await MobileAds.instance.initialize(); + await NotificationService.initialize(); + + runApp( + ChangeNotifierProvider( + create: (_) => LocaleProvider(), + child: MyApp(), + ), + ); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + final localeProvider = Provider.of( + context); // écoute les changements de langue + return MaterialApp( + debugShowCheckedModeBanner: false, + locale: localeProvider.locale, // <-- utilise la locale courante + supportedLocales: L10n.all, + localizationsDelegates: AppLocalizations.localizationsDelegates, + home: LoginDemo(), + ); + } +} diff --git a/covas_mobile_new/lib/pages/AddProfile.dart b/covas_mobile_new/lib/pages/AddProfile.dart new file mode 100644 index 0000000..5888f57 --- /dev/null +++ b/covas_mobile_new/lib/pages/AddProfile.dart @@ -0,0 +1,335 @@ +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; +import 'package:intl/intl.dart'; + +import 'dart:convert'; +import 'dart:io'; + +import '../pages/LoginDemo.dart'; + +import '../classes/alert.dart'; + +import '../variable/globals.dart' as globals; + +import '../classes/ad_helper.dart'; +import 'package:google_mobile_ads/google_mobile_ads.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // Créé plus loin + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await MobileAds.instance.initialize(); + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: AddProfile(), + ); + } +} + +class AddProfile extends StatefulWidget { + const AddProfile({super.key}); + + @override + _AddProfileState createState() => _AddProfileState(); +} + +class _AddProfileState extends State with ShowAlertDialog { + BannerAd? _bannerAd; + + TextEditingController inputUserName = TextEditingController(); + + TextEditingController inputName = TextEditingController(); + + TextEditingController inputFirstName = TextEditingController(); + TextEditingController inputEmail = TextEditingController(); + TextEditingController inputBirth = TextEditingController(); + TextEditingController inputPassword = TextEditingController(); + TextEditingController inputPasswordConfirmed = TextEditingController(); + + onTapFunctionDatePicker({required BuildContext context}) async { + DateTime? pickedDate = await showDatePicker( + context: context, + firstDate: DateTime(1900), + initialDate: DateTime.now(), + lastDate: DateTime(2104)); + if (pickedDate == null) return; + inputBirth.text = DateFormat("dd/MM/yyyy").format(pickedDate); + } + + convertNulltoEmptyString(var check) { + if (check == null) { + return ""; + } + return check; + } + + convertNulltoArray(List check) { + if (check == null) { + return []; + } + return check; + } + + String formatDate(String date) { + var splitedDate = date.split("/"); + + var day = splitedDate[0]; + var month = splitedDate[1]; + var year = splitedDate[2]; + + return "${year}-${month}-${day}"; + } + + Future _createProfile(BuildContext context) async { + var username = inputUserName.text; + var firstName = inputFirstName.text; + var name = inputName.text; + var email = inputEmail.text; + var password = inputPassword.text; + var confirmedPassword = inputPasswordConfirmed.text; + var birth = DateTime.parse(formatDate(inputBirth.text)); + + if ((password.isNotEmpty) && (confirmedPassword.isNotEmpty)) { + if (password != confirmedPassword) { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.password_different ?? + "Must write a different password"); + return; + } + } + + var urlPut = Uri.parse("${globals.api}/mail"); + + var responsePost = await http.post(urlPut, + headers: { + HttpHeaders.acceptHeader: 'application/json, text/plain, */*', + HttpHeaders.contentTypeHeader: 'application/json' + }, + body: jsonEncode({ + 'name': name, + 'username': username, + 'firstName': firstName, + 'password': password, + 'email': email, + 'birth': birth.toString() + })); + print(responsePost.statusCode); + if (responsePost.statusCode == 200) { + showAlertDialog( + context, + AppLocalizations.of(context)?.create ?? "Creation", + AppLocalizations.of(context)?.user_create ?? "Your user created"); + Navigator.pushReplacement( + context, MaterialPageRoute(builder: (_) => LoginDemo())); + return; + } + + final errorMessages = { + 400: AppLocalizations.of(context)?.request_error ?? + "Poorly constructed query", + 406: AppLocalizations.of(context)?.incorrect_password ?? + "Incorrect password", + 404: AppLocalizations.of(context)?.unknown_user ?? "Unknown user", + 403: AppLocalizations.of(context)?.disabled_user ?? "Disabled user", + 410: AppLocalizations.of(context)?.invalid_token ?? "Invalid token", + 500: AppLocalizations.of(context)?.internal_error_server ?? + "Internal error server" + }; + + final text = errorMessages[responsePost.statusCode] ?? + AppLocalizations.of(context)?.unknown_error_auth ?? + "Unknown error auth"; + showAlertDialog( + context, AppLocalizations.of(context)?.error ?? "Error", text); + } + + @override + void initState() { + super.initState(); + + AdHelper.createBannerAd(() => setState(() {})).then((ad) { + setState(() { + _bannerAd = ad; + }); + }); + } + + final _formKey = GlobalKey(); + String? _validateField(String? value) { + return value!.isEmpty + ? AppLocalizations.of(context)?.required_input ?? 'Required input' + : null; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + title: Text( + AppLocalizations.of(context)?.create_profile ?? "Create profile"), + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + ), + body: Form( + key: _formKey, + child: SingleChildScrollView( + child: Column( + children: [ + _bannerAd == null + ? SizedBox.shrink() + : SizedBox( + height: _bannerAd!.size.height.toDouble(), + width: _bannerAd!.size.width.toDouble(), + child: AdWidget(ad: _bannerAd!)), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputUserName, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Pseudo', + hintText: AppLocalizations.of(context)?.edit_pseudo ?? + 'Edit pseudo'), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputPassword, + validator: (value) => _validateField(value), + obscureText: true, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.password ?? + 'Password', + hintText: + AppLocalizations.of(context)?.enter_password ?? + 'Enter the password'), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputPasswordConfirmed, + validator: (value) => _validateField(value), + obscureText: true, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: + AppLocalizations.of(context)?.password_confirmed ?? + 'Password confirmed', + hintText: + AppLocalizations.of(context)?.password_confirmed ?? + 'Password confirmed', + ), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputName, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.last_name ?? + 'Last name', + hintText: + AppLocalizations.of(context)?.edit_last_name ?? + 'Edit last name'), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputFirstName, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.first_name ?? + 'First name', + hintText: + AppLocalizations.of(context)?.edit_first_name ?? + 'Edit first name'), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputEmail, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: + AppLocalizations.of(context)?.email ?? 'Email', + hintText: AppLocalizations.of(context)?.edit_email ?? + 'Edit email'), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputBirth, + readOnly: true, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.birth_date ?? + 'Birth date', + hintText: AppLocalizations.of(context)?.edit_birth ?? + 'Edit birth date'), + onTap: () => onTapFunctionDatePicker(context: context)), + ), + SizedBox( + height: 30, + ), + Container( + height: 50, + width: 250, + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.circular(20)), + child: TextButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + _createProfile(context); + } + }, + child: Text( + AppLocalizations.of(context)?.create_profile_button ?? + "Create profile", + style: TextStyle(color: Colors.white, fontSize: 25), + ), + ), + ) + ], + ), + ), + )); + } +} diff --git a/covas_mobile_new/lib/pages/Camera.dart b/covas_mobile_new/lib/pages/Camera.dart new file mode 100644 index 0000000..0189dc0 --- /dev/null +++ b/covas_mobile_new/lib/pages/Camera.dart @@ -0,0 +1,163 @@ +import 'dart:async'; + +import 'package:image_picker/image_picker.dart'; +import '../classes/MyDrawer.dart'; + +import 'DisplayPictureScreen.dart'; +import 'package:camera/camera.dart'; +import 'package:flutter/material.dart'; +import '../classes/auth_service.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // Créé plus loin + +Future main() async { + // Ensure that plugin services are initialized so that `availableCameras()` + // can be called before `runApp()` + WidgetsFlutterBinding.ensureInitialized(); + + // Obtain a list of the available cameras on the device. + final cameras = await availableCameras(); + + // Get a specific camera from the list of available cameras. + final firstCamera = cameras.first; + + runApp( + MaterialApp( + theme: ThemeData.dark(), + home: Camera( + // Pass the appropriate camera to the TakePictureScreen widget. + camera: firstCamera, + ), + ), + ); +} + +// A screen that allows users to take a picture using a given camera. +class Camera extends StatefulWidget { + const Camera({ + super.key, + required this.camera, + }); + + final CameraDescription camera; + + @override + CameraState createState() => CameraState(); +} + +class CameraState extends State { + late CameraController _controller; + late Future _initializeControllerFuture; + final AuthService _authService = AuthService(); + + @override + void initState() { + super.initState(); + // To display the current output from the Camera, + // create a CameraController. + _authService.checkTokenStatus(context); + + _controller = CameraController( + // Get a specific camera from the list of available cameras. + widget.camera, + // Define the resolution to use. + ResolutionPreset.medium, + ); + + // Next, initialize the controller. This returns a Future. + _initializeControllerFuture = _controller.initialize(); + } + + Future pickImage() async { + final imagePicker = ImagePicker(); + final pickedFile = await imagePicker.pickImage(source: ImageSource.gallery); + if (pickedFile != null) { + await Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => DisplayPictureScreen( + // Pass the automatically generated path to + // the DisplayPictureScreen widget. + imagePath: pickedFile.path, + ), + ), + ); + } + } + + @override + void dispose() { + // Dispose of the controller when the widget is disposed. + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(AppLocalizations.of(context)?.take_picture ?? + "Take a picture")), + // You must wait until the controller is initialized before displaying the + // camera preview. Use a FutureBuilder to display a loading spinner until the + // controller has finished initializing. + drawer: MyDrawer(), + body: FutureBuilder( + future: _initializeControllerFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + // If the Future is complete, display the preview. + return CameraPreview(_controller); + } else { + // Otherwise, display a loading indicator. + return const Center(child: CircularProgressIndicator()); + } + }, + ), + floatingActionButton: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + FloatingActionButton( + onPressed: pickImage, + child: Icon(Icons.photo_library), + ), + SizedBox(width: 40), + FloatingActionButton( + // Provide an onPressed callback. + onPressed: () async { + // Take the Picture in a try / catch block. If anything goes wrong, + // catch the error. + try { + // Ensure that the camera is initialized. + await _initializeControllerFuture; + + // Attempt to take a picture and get the file `image` + // where it was saved. + final image = await _controller.takePicture(); + + if (!context.mounted) return; + + // If the picture was taken, display it on a new screen. + await Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => DisplayPictureScreen( + // Pass the automatically generated path to + // the DisplayPictureScreen widget. + imagePath: image.path, + ), + ), + ); + } catch (e) { + // If an error occurs, log the error to the console. + print(e); + } + }, + child: const Icon(Icons.camera_alt), + ) + ], + ))); + } +} diff --git a/covas_mobile_new/lib/pages/CameraEdit.dart b/covas_mobile_new/lib/pages/CameraEdit.dart new file mode 100644 index 0000000..408e8fc --- /dev/null +++ b/covas_mobile_new/lib/pages/CameraEdit.dart @@ -0,0 +1,166 @@ +import 'dart:async'; +import 'dart:io'; + +import '../classes/events.dart'; +import '../classes/MyDrawer.dart'; +import 'package:image_picker/image_picker.dart'; +import 'EditEvent.dart'; +import 'package:camera/camera.dart'; +import 'package:flutter/material.dart'; +import '../classes/auth_service.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // Créé + +Future main() async { + // Ensure that plugin services are initialized so that `availableCameras()` + // can be called before `runApp()` + WidgetsFlutterBinding.ensureInitialized(); + + // Obtain a list of the available cameras on the device. + final cameras = await availableCameras(); + + // Get a specific camera from the list of available cameras. + final firstCamera = cameras.first; + Events? events; + + runApp( + MaterialApp( + theme: ThemeData.dark(), + home: CameraEdit( + // Pass the appropriate camera to the TakePictureScreen widget. + camera: firstCamera, + events: events), + ), + ); +} + +// A screen that allows users to take a picture using a given camera. +class CameraEdit extends StatefulWidget { + const CameraEdit({super.key, required this.camera, required this.events}); + final Events? events; + + final CameraDescription camera; + + @override + CameraEditState createState() => CameraEditState(); +} + +class CameraEditState extends State { + late CameraController _controller; + late Future _initializeControllerFuture; + final AuthService _authService = AuthService(); + + @override + void initState() { + super.initState(); + _authService.checkTokenStatus(context); + + // To display the current output from the Camera, + // create a CameraController. + + _controller = CameraController( + // Get a specific camera from the list of available cameras. + widget.camera, + // Define the resolution to use. + ResolutionPreset.medium, + ); + + // Next, initialize the controller. This returns a Future. + _initializeControllerFuture = _controller.initialize(); + } + + Future pickImage() async { + final imagePicker = ImagePicker(); + final pickedFile = await imagePicker.pickImage(source: ImageSource.gallery); + if (pickedFile != null) { + await Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => EditEvent( + // Pass the automatically generated path to + // the DisplayPictureScreen widget. + events: widget.events, + imgPath: pickedFile.path, + ), + ), + ); + } + } + + @override + void dispose() { + // Dispose of the controller when the widget is disposed. + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(AppLocalizations.of(context)?.take_picture ?? + 'Take a picture')), + // You must wait until the controller is initialized before displaying the + // camera preview. Use a FutureBuilder to display a loading spinner until the + // controller has finished initializing. + drawer: MyDrawer(), + body: FutureBuilder( + future: _initializeControllerFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + // If the Future is complete, display the preview. + return CameraPreview(_controller); + } else { + // Otherwise, display a loading indicator. + return const Center(child: CircularProgressIndicator()); + } + }, + ), + floatingActionButton: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + FloatingActionButton( + onPressed: pickImage, + child: Icon(Icons.photo_library), + ), + SizedBox(width: 40), + FloatingActionButton( + // Provide an onPressed callback. + onPressed: () async { + // Take the Picture in a try / catch block. If anything goes wrong, + // catch the error. + try { + // Ensure that the camera is initialized. + await _initializeControllerFuture; + + // Attempt to take a picture and get the file `image` + // where it was saved. + final image = await _controller.takePicture(); + + if (!context.mounted) return; + + // If the picture was taken, display it on a new screen. + await Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => EditEvent( + // Pass the automatically generated path to + // the DisplayPictureScreen widget. + events: widget.events, + imgPath: image.path, + ), + ), + ); + } catch (e) { + // If an error occurs, log the error to the console. + print(e); + } + }, + child: const Icon(Icons.camera_alt), + ) + ], + ))); + } +} diff --git a/covas_mobile_new/lib/pages/DisplayPictureScreen.dart b/covas_mobile_new/lib/pages/DisplayPictureScreen.dart new file mode 100644 index 0000000..aea3380 --- /dev/null +++ b/covas_mobile_new/lib/pages/DisplayPictureScreen.dart @@ -0,0 +1,268 @@ +import 'package:flutter/material.dart'; +import 'dart:io'; +import '../classes/addEventImage.dart'; +import '../classes/alert.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:flutter_gemini/flutter_gemini.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:http/http.dart' as http; +import "ItemMenu.dart"; +import 'UpdateEventImage.dart'; + +import 'dart:convert'; + +import '../variable/globals.dart' as globals; +import '../classes/MyDrawer.dart'; + +import '../classes/ad_helper.dart'; +import 'package:google_mobile_ads/google_mobile_ads.dart'; +import '../classes/auth_service.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // Créé + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await MobileAds.instance.initialize(); + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + + // This widget is the root of your application. + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + // This is the theme of your application. + // + // Try running your application with "flutter run". You'll see the + // application has a blue toolbar. Then, without quitting the app, try + // changing the primarySwatch below to Colors.green and then invoke + // "hot reload" (press "r" in the console where you ran "flutter run", + // or simply save your changes to "hot reload" in a Flutter IDE). + // Notice that the counter didn't reset back to zero; the application + // is not restarted. + primarySwatch: Colors.blue, + ), + ); + } +} + +// A screen that allows users to take a picture using a given camera. +class DisplayPictureScreen extends StatefulWidget { + final String imagePath; + + const DisplayPictureScreen({super.key, required this.imagePath}); + + @override + DisplayPictureScreenState createState() => DisplayPictureScreenState(); +} + +// A widget that displays the picture taken by the user. +class DisplayPictureScreenState extends State + with ShowDescImageAdd, ShowAlertDialog, TickerProviderStateMixin { + BannerAd? _bannerAd; + final AuthService _authService = AuthService(); + + late AnimationController controller; + @override + void initState() { + super.initState(); + _authService.checkTokenStatus(context); + + AdHelper.createBannerAd(() => setState(() {})).then((ad) { + setState(() { + _bannerAd = ad; + }); + }); + + controller = AnimationController( + /// [AnimationController]s can be created with `vsync: this` because of + /// [TickerProviderStateMixin]. + vsync: this, + duration: const Duration(seconds: 5), + )..addListener(() { + setState(() {}); + }); + controller.repeat(reverse: false); + + _getEventInfosFromImage(); + } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + + Future displayError(String e) async { + print("problem gemini : ${e}"); + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? 'Error', + AppLocalizations.of(context)?.error_ia ?? + 'Google AI failed to analyze picture. Retry with another one'); + } + + void _showErrorDialog(BuildContext context, String title, String message) { + showAlertDialog(context, title, message); + } + + Future?> _fetchGeolocation(String place) async { + final apiKey = dotenv.env['PLACE_API_KEY'] ?? ''; + final response = await http.get(Uri.parse( + 'https://maps.googleapis.com/maps/api/place/textsearch/json?query=${place}}&key=$apiKey')); + + if (response.statusCode == 200) { + final data = json.decode(response.body); + if (data['results'].isNotEmpty) { + return data['results'][0]['geometry']['location']; + } + } + return null; + } + + Future _isDuplicateEvent(String accessToken, + Map jsonData, Map location) async { + final url = Uri.parse( + "${globals.api}/events/search?item=${jsonData["name"]}&date_event=${jsonData["start_date"]}" + "&min_lat=${location['lat']}&max_lat=${location['lat']}" + "&min_lon=${location['lng']}&max_lon=${location['lng']}"); + + final response = await http.get(url, + headers: {HttpHeaders.cookieHeader: 'access_token=$accessToken'}); + + if (response.statusCode == 200) { + final events = jsonDecode(utf8.decode(response.bodyBytes)); + return events.isNotEmpty; + } + return false; + } + + Future searchEvents(String json, String imagePath) async { + print(json.replaceAll("'''json", '').replaceAll("'''", "")); + SharedPreferences prefs = await SharedPreferences.getInstance(); + try { + Map jsonData = + jsonDecode(json.replaceAll("```json", '').replaceAll("```", "")); + print("json : ${jsonData}"); + var name = jsonData["name"]; + print("name : ${name}"); + var place = jsonData["place"]; + var date = jsonData["start_date"]; + var accessToken = prefs.getString("access_token") ?? ""; + + if (accessToken.isNotEmpty) { + final location = await _fetchGeolocation(place); + if (location == null) { + _showErrorDialog( + context, + AppLocalizations.of(context)?.error ?? 'Error', + AppLocalizations.of(context)?.no_data_geo ?? + 'No geographical data'); + return; + } + + final url = Uri.parse( + "${globals.api}/events/search?item=${name}&date_event=${date}" + "&min_lat=${location['lat']}&max_lat=${location['lat']}" + "&min_lon=${location['lng']}&max_lon=${location['lng']}"); + + final response = await http.get(url, + headers: {HttpHeaders.cookieHeader: 'access_token=$accessToken'}); + if (response.statusCode == 200) { + var events = jsonDecode(utf8.decode(response.bodyBytes)); + print("reponse http : ${events.length}"); + if (events.length == 0) { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => UpdateeventImage( + events: jsonData, imagePath: imagePath))); + } else { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => ItemMenu(title: events[0]["id"]))); + } + } else { + String error = AppLocalizations.of(context)?.response_status_update ?? + 'Response status update : ${response.statusCode}'; + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? 'Error', + "${error} : ${response.statusCode}"); + } + } else { + showAlertDialog(context, AppLocalizations.of(context)?.error ?? 'Error', + AppLocalizations.of(context)?.error_token ?? "Token error"); + } + } catch (e) { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.error_format ?? + "Data format error given by AI"); + } + + //showDescImageAddDialog(context, message); + } + + Future _getEventInfosFromImage() async { + await dotenv.load(); + + final gemini = Gemini.init( + apiKey: dotenv.env['GEMINI_API_KEY']!, enableDebugging: true); + + final file = File(widget.imagePath); + + gemini + .textAndImage( + text: + "Peux-tu donner le nom, la date (si l'année n'est pas précisé, mettez l'année actuelle ou future) et le lieu de l'évènement sous format JSON (sans le caratère json au début de la chaine de caractère) avec les valeurs suivantes : name, place, description, tags (tableau sans espace), organizers (tableau), start_date et end_date (si le end_date est vide, alors donnez une valeur de six de plus par rapport à start_date) sous le format en YYYY-MM-DD HH:mm:ssZ", + images: [file.readAsBytesSync()], + modelName: "models/gemini-1.5-pro-latest") + .then((value) => searchEvents( + value?.content?.parts?.last.text ?? '', widget.imagePath)) + .catchError((e) => displayError); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(AppLocalizations.of(context)?.display_picture ?? + "Display The Picture")), + // The image is stored as a file on the device. Use the `Image.file` + // constructor with the given path to display the image. + drawer: MyDrawer(), + body: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + _bannerAd == null + ? SizedBox.shrink() + : SizedBox( + height: _bannerAd!.size.height.toDouble(), + width: _bannerAd!.size.width.toDouble(), + child: AdWidget(ad: _bannerAd!)), + Text( + AppLocalizations.of(context)?.analyze_image ?? + 'Image analyze in progress', + style: Theme.of(context).textTheme.titleLarge, + ), + CircularProgressIndicator( + value: controller.value, + semanticsLabel: + AppLocalizations.of(context)?.loading_progress ?? + 'Loading progress', + ), + ]))); + } +} diff --git a/covas_mobile_new/lib/pages/EditEvent.dart b/covas_mobile_new/lib/pages/EditEvent.dart new file mode 100644 index 0000000..d0519c3 --- /dev/null +++ b/covas_mobile_new/lib/pages/EditEvent.dart @@ -0,0 +1,921 @@ +import 'package:covas_mobile/pages/CameraEdit.dart'; +import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:http/http.dart' as http; +import 'package:intl/intl.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:textfield_tags/textfield_tags.dart'; + +import 'dart:convert'; +import 'dart:io'; + +import '../classes/events.dart'; +import '../classes/MyDrawer.dart'; + +import 'package:camera/camera.dart'; + +import '../classes/alert.dart'; +import '../classes/eventAdded.dart'; + +import '../variable/globals.dart' as globals; + +import '../classes/ad_helper.dart'; +import 'package:google_mobile_ads/google_mobile_ads.dart'; +import '../classes/auth_service.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // Créé + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await MobileAds.instance.initialize(); + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + Events? events; + + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: EditEvent( + events: events, + imgPath: "", + ), + ); + } +} + +class EditEvent extends StatefulWidget { + const EditEvent({Key? key, required this.events, required this.imgPath}) + : super(key: key); + final Events? events; + + final String imgPath; + + @override + _EditEventState createState() => _EditEventState(); +} + +class _EditEventState extends State + with ShowAlertDialog, ShowEventDialog { + BannerAd? _bannerAd; + final AuthService _authService = AuthService(); + + TextEditingController inputName = TextEditingController(); + + TextEditingController inputTicket = TextEditingController(); + TextEditingController inputLink = TextEditingController(); + TextEditingController inputDate = TextEditingController(); + TextEditingController inputDesc = TextEditingController(); + + TextEditingController inputGeo = TextEditingController(); + + TextEditingController startDatepicker = TextEditingController(); + TextEditingController startTimepicker = TextEditingController(); + TextEditingController endDatepicker = TextEditingController(); + TextEditingController endTimepicker = TextEditingController(); + final _stringTagController = StringTagController(); + + DateTime startDate = DateTime.now(); + DateTime endDate = DateTime.now(); + List> suggestions = []; + String geographicalZone = ""; + String imgUrl = ""; + + List initialTags = []; + + final _stringOrgaController = StringTagController(); + List initialOrga = []; + + onTapFunctionDatePicker( + {required BuildContext context, required String position}) async { + DateTime date; + if ((startDatepicker.text.isEmpty) || (endDatepicker.text.isEmpty)) { + date = DateTime.now(); + } else { + date = DateTime.parse(formatDate(startDatepicker.text)); + if (position == "end") { + date = DateTime.parse(formatDate(endDatepicker.text)); + } + } + DateTime? pickedDate = await showDatePicker( + context: context, + firstDate: date, + initialDate: date, + lastDate: DateTime(2104)); + if (pickedDate == null) return; + if (position == "start") { + startDatepicker.text = DateFormat("dd/MM/yyyy").format(pickedDate); + } + if (position == "end") { + endDatepicker.text = DateFormat("dd/MM/yyyy").format(pickedDate); + } + } + + onTapFunctionTimePicker( + {required BuildContext context, required String position}) async { + TimeOfDay time; + + if ((startTimepicker.text.isEmpty) || (endTimepicker.text.isEmpty)) { + time = TimeOfDay.now(); + } else { + DateTime date = new DateTime.now(); + date = date.copyWith( + hour: int.parse(startTimepicker.text.split(":")[0]), + minute: int.parse(startTimepicker.text.split(":")[1])); + time = TimeOfDay.fromDateTime(date); + if (position == "end") { + date = date.copyWith( + hour: int.parse(endTimepicker.text.split(":")[0]), + minute: int.parse(endTimepicker.text.split(":")[1])); + time = TimeOfDay.fromDateTime(date); + } + } + + TimeOfDay? pickedDate = + await showTimePicker(context: context, initialTime: time); + if (pickedDate == null) return; + if (position == "start") { + startTimepicker.text = pickedDate.format(context); + } + if (position == "end") { + endTimepicker.text = pickedDate.format(context); + } + } + + convertNulltoEmptyString(var check) { + if (check == null) { + return ""; + } + return check; + } + + convertNulltoArray(List check) { + if (check == null) { + return []; + } + return check; + } + + String formatDate(String date) { + var splitedDate = date.split("/"); + + var day = splitedDate[0]; + var month = splitedDate[1]; + var year = splitedDate[2]; + + return "${year}-${month}-${day}"; + } + + Future _updateEvent(BuildContext context) async { + if (!_isEventInFuture()) { + _showErrorDialog( + context, + AppLocalizations.of(context)?.error_event ?? "Event error", + AppLocalizations.of(context)?.no_future_event ?? "No future event"); + return; + } + + final accessToken = await _getAccessToken(); + if (accessToken.isEmpty) { + _showErrorDialog( + context, + AppLocalizations.of(context)?.error_user ?? "User error", + AppLocalizations.of(context)?.empty_input ?? "Empty input"); + return; + } + + try { + await dotenv.load(); + final geolocation = await _fetchGeolocation(); + if (geolocation == null) { + _showErrorDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.no_data_geo ?? + "No geographical data"); + return; + } + + if (await _isDuplicateEvent(accessToken, geolocation)) { + _showErrorDialog( + context, + AppLocalizations.of(context)?.info_event ?? "Event info", + AppLocalizations.of(context)?.event_already ?? + "Event already exists"); + return; + } + + if (widget.imgPath.isNotEmpty) { + imgUrl = await _uploadImage(widget.imgPath); + if (imgUrl.isEmpty) { + _showErrorDialog( + context, + AppLocalizations.of(context)?.picture_error ?? "Error picture", + AppLocalizations.of(context)?.no_picture_published ?? + "No picture published"); + return; + } + } + + await _updateEventData(accessToken, geolocation); + String message = + AppLocalizations.of(context)?.event_update ?? "Event updated"; + showEventDialog(context, "${message} : ${inputName.text}"); + } catch (e) { + _showErrorDialog( + context, AppLocalizations.of(context)?.error ?? "Error", "$e"); + } + } + + bool _isEventInFuture() { + DateTime startDateCompare = DateTime.parse( + "${formatDate(startDatepicker.text)}T${startTimepicker.text.replaceAll('-', ':')}"); + return startDateCompare.isAfter(DateTime.now()); + } + + Future _getAccessToken() async { + final prefs = await SharedPreferences.getInstance(); + return prefs.getString("access_token") ?? ""; + } + + Future?> _fetchGeolocation() async { + final apiKey = dotenv.env['PLACE_API_KEY'] ?? ''; + final response = await http.get(Uri.parse( + 'https://maps.googleapis.com/maps/api/place/textsearch/json?query=${inputGeo.text}&key=$apiKey')); + + if (response.statusCode == 200) { + final data = json.decode(response.body); + if (data['results'].isNotEmpty) { + return data['results'][0]['geometry']['location']; + } + } + return null; + } + + Future _isDuplicateEvent( + String accessToken, Map location) async { + final url = Uri.parse( + "${globals.api}/events/search?item=${inputName.text}&date_event=${formatDate(startDatepicker.text)}" + "&min_lat=${location['lat']}&max_lat=${location['lat']}" + "&min_lon=${location['lng']}&max_lon=${location['lng']}"); + + final response = await http.get(url, + headers: {HttpHeaders.cookieHeader: 'access_token=$accessToken'}); + + if (response.statusCode == 200) { + final events = jsonDecode(utf8.decode(response.bodyBytes)); + return events.isNotEmpty && events[0]["id"] != widget.events!.id; + } + return false; + } + + Future _uploadImage(String imagePath) async { + final params = { + 'expiration': '15552000', + 'key': dotenv.env["IMGBB_API_KEY"] + }; + final url = Uri.parse('https://api.imgbb.com/1/upload') + .replace(queryParameters: params); + + final image = File(imagePath); + final req = http.MultipartRequest('POST', url) + ..fields['image'] = base64.encode(await image.readAsBytes()); + + final response = await http.Response.fromStream(await req.send()); + return response.statusCode == 200 + ? json.decode(response.body)["data"]["url"] + : ""; + } + + Future _updateEventData( + String accessToken, Map location) async { + final url = Uri.parse("${globals.api}/events/${widget.events!.id}"); + final response = await http.put(url, + headers: { + HttpHeaders.cookieHeader: 'access_token=$accessToken', + HttpHeaders.acceptHeader: 'application/json, text/plain, */*', + HttpHeaders.contentTypeHeader: 'application/json' + }, + body: jsonEncode({ + 'name': inputName.text, + 'place': inputGeo.text, + 'start_date': + "${formatDate(startDatepicker.text)}T${startTimepicker.text.replaceAll('-', ':')}", + 'end_date': + "${formatDate(endDatepicker.text)}T${endTimepicker.text.replaceAll('-', ':')}", + 'organizers': + List.from(_stringOrgaController.getTags as List), + 'latitude': location['lat'], + 'longitude': location['lng'], + 'description': inputDesc.text, + "imgUrl": imgUrl, + 'link': inputLink.text, + 'ticket': inputTicket.text, + "tags": List.from(_stringTagController.getTags as List) + })); + + if (response.statusCode != 200 && response.statusCode != 201) { + _handleErrorResponse(context, response.statusCode); + } + } + + void _handleErrorResponse(BuildContext context, int statusCode) { + final messages = { + 400: AppLocalizations.of(context)?.request_error ?? + "Poorly constructed query", + 406: AppLocalizations.of(context)?.incorrect_password ?? + "Incorrect password", + 404: AppLocalizations.of(context)?.unknown_user ?? "Unknown user", + 403: AppLocalizations.of(context)?.disabled_user ?? "Disabled user", + 410: AppLocalizations.of(context)?.invalid_token ?? "Invalid token", + 500: AppLocalizations.of(context)?.internal_error_server ?? + "Internal error server" + }; + _showErrorDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + messages[statusCode] ?? + AppLocalizations.of(context)?.unknown_error_auth ?? + "Unknown error auth"); + } + + void _showErrorDialog(BuildContext context, String title, String message) { + showAlertDialog(context, title, message); + } + + @override + void initState() { + super.initState(); + _authService.checkTokenStatus(context); + + AdHelper.createBannerAd(() => setState(() {})).then((ad) { + setState(() { + _bannerAd = ad; + }); + }); + inputName.text = widget.events!.name ?? ""; + inputTicket.text = widget.events!.ticket ?? ""; + inputLink.text = widget.events!.link ?? ""; + startDatepicker.text = DateFormat("dd/MM/yyyy") + .format(DateTime.parse( + widget.events!.startDate ?? DateTime.now().toString())) + .toString(); + startTimepicker.text = DateFormat("HH:mm") + .format(DateTime.parse( + widget.events!.startDate ?? DateTime.now().toString())) + .toString(); + endDatepicker.text = DateFormat("dd/MM/yyyy") + .format( + DateTime.parse(widget.events!.endDate ?? DateTime.now().toString())) + .toString(); + endTimepicker.text = DateFormat("HH:mm") + .format( + DateTime.parse(widget.events!.endDate ?? DateTime.now().toString())) + .toString(); + inputGeo.text = widget.events!.place ?? ""; + + imgUrl = widget.events!.imgUrl ?? ""; + inputDesc.text = widget.events!.description ?? ""; + initialTags = List.from(widget.events!.tags as List); + initialOrga = List.from(widget.events!.organizers as List); + } + + final _formKey = GlobalKey(); + String? _validateField(String? value) { + return value!.isEmpty + ? AppLocalizations.of(context)?.required_input ?? "Required input" + : null; + } + + Future searchSuggestions(String input) async { + await dotenv.load(fileName: ".env"); // Load .env file + + final mapboxAccessToken = dotenv.env['MAPBOX_ACCESS_TOKEN'] ?? ''; + final url = + 'https://api.mapbox.com/geocoding/v5/mapbox.places/${input}.json?access_token=${mapboxAccessToken}&types=poi,address,place'; + var encoded = Uri.encodeFull(url); + final response = await http.get(Uri.parse(encoded)); + + if (response.statusCode == 200) { + final data = json.decode(response.body); + setState(() { + suggestions = (data['features'] as List) + .map((feature) => { + 'place_name': feature['place_name'], + 'text': feature['text'], + 'geometry': feature[ + 'geometry'], // Include geometry for latitude/longitude + }) + .toList(); + }); + } else { + throw Exception('Failed to load suggestions'); + } + } + + Padding _buildGeographicalZoneSearchField() { + return Padding( + padding: + const EdgeInsets.only(left: 15.0, right: 15.0, top: 15, bottom: 0), + child: Column( + children: [ + TextField( + controller: inputGeo, + decoration: InputDecoration( + labelText: AppLocalizations.of(context)?.location ?? "Location", + border: OutlineInputBorder(), + suffixIcon: IconButton( + icon: const Icon(Icons.clear), + onPressed: () { + setState(() { + inputGeo.clear(); // Clear the text field + geographicalZone = ''; // Reset the geographical zone state + suggestions.clear(); // Optionally clear suggestions + }); + }, + ), + ), + onChanged: (value) { + setState(() { + geographicalZone = value; + searchSuggestions(value); + }); + }, + ), + if (suggestions.isNotEmpty) + Container( + height: 200, + decoration: BoxDecoration( + border: Border.all(color: Colors.blue), + borderRadius: BorderRadius.circular(8), + ), + child: ListView.builder( + shrinkWrap: true, + itemCount: suggestions.length, + itemBuilder: (context, index) { + return ListTile( + title: Text(suggestions[index]['text']), + subtitle: Text(suggestions[index]['place_name']), + onTap: () async { + print("suggestion tapped : ${suggestions[index]}"); + final latitude = + suggestions[index]['geometry']['coordinates'][1]; + final longitude = + suggestions[index]['geometry']['coordinates'][0]; + + setState(() { + geographicalZone = suggestions[index]['text']; + inputGeo.text = geographicalZone; + suggestions.clear(); + }); + }, + ); + }, + ), + ), + ], + ), + ); + } + + Future popCamera() async { + await availableCameras().then((value) => Navigator.push( + context, + MaterialPageRoute( + builder: (_) => + CameraEdit(camera: value.first, events: widget.events)))); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + drawer: MyDrawer(), + appBar: AppBar( + title: Text(AppLocalizations.of(context)?.add_event ?? + "Add or Update a event"), + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + ), + body: Form( + key: _formKey, + child: SingleChildScrollView( + child: Column( + children: [ + _bannerAd == null + ? SizedBox.shrink() + : SizedBox( + height: _bannerAd!.size.height.toDouble(), + width: _bannerAd!.size.width.toDouble(), + child: AdWidget(ad: _bannerAd!)), + if (widget.imgPath.isNotEmpty) + Padding( + padding: const EdgeInsets.only(top: 60.0), + child: Center( + child: Container( + width: 200, + height: 150, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(100.0)), + child: Image.file(File(widget.imgPath))), + ), + ), + if (widget.imgPath.isEmpty) + Padding( + padding: const EdgeInsets.only(top: 60.0), + child: Image.network( + imgUrl, + width: MediaQuery.of(context).size.width * + 0.5, // 50% of screen width + height: MediaQuery.of(context).size.height * 0.5, + loadingBuilder: (BuildContext context, Widget child, + ImageChunkEvent? loadingProgress) { + if (loadingProgress == null) { + return child; // The image has finished loading + } + return Center( + child: CircularProgressIndicator(), + ); + }, + errorBuilder: (BuildContext context, Object error, + StackTrace? stackTrace) { + return Center( + child: Icon(Icons.error, + size: MediaQuery.of(context).size.width * 0.1), + ); + }, + )), + Padding( + padding: EdgeInsets.symmetric(horizontal: 15), + child: ElevatedButton.icon( + onPressed: popCamera, + icon: Icon(Icons.edit, size: 16), // Edit icon + label: Text(AppLocalizations.of(context)?.edit_image ?? + "Edit pictures"), // Button text + style: ElevatedButton.styleFrom( + backgroundColor: Colors.blue, // Button color + foregroundColor: Colors.white, // Text color + padding: + EdgeInsets.symmetric(horizontal: 10, vertical: 5), + ), + ), + ), + Padding( + //padding: const EdgeInsets.only(left:15.0,right: 15.0,top:0,bottom: 0), + padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputName, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.name ?? "Name", + hintText: + AppLocalizations.of(context)?.edit_event_name ?? + "Edit event name"), + ), + ), + _buildGeographicalZoneSearchField(), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: startDatepicker, + readOnly: true, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.start_date ?? + "Start date", + hintText: AppLocalizations.of(context)?.select_date ?? + "Click to select a date"), + onTap: () => onTapFunctionDatePicker( + context: context, position: "start")), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: startTimepicker, + readOnly: true, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.start_time ?? + "Start time", + hintText: AppLocalizations.of(context)?.select_time ?? + "Click to select a time"), + onTap: () => onTapFunctionTimePicker( + context: context, position: "start")), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: endDatepicker, + readOnly: true, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.end_date ?? + "End date", + hintText: AppLocalizations.of(context)?.select_time ?? + "Click to select a date"), + onTap: () => onTapFunctionDatePicker( + context: context, position: "end")), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: endTimepicker, + readOnly: true, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.end_time ?? + "End time", + hintText: AppLocalizations.of(context)?.select_time ?? + "Click to select a time"), + onTap: () => onTapFunctionTimePicker( + context: context, position: "end")), + ), + Padding( + //padding: const EdgeInsets.only(left:15.0,right: 15.0,top:0,bottom: 0), + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + child: TextFormField( + controller: inputLink, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.link ?? "Link", + hintText: AppLocalizations.of(context)?.edit_link ?? + "Edit link event"), + ), + ), + Padding( + //padding: const EdgeInsets.only(left:15.0,right: 15.0,top:0,bottom: 0), + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + child: TextFormField( + controller: inputTicket, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: + AppLocalizations.of(context)?.ticket ?? "Ticket", + hintText: AppLocalizations.of(context)?.edit_ticket ?? + "Edit ticket link"), + ), + ), + TextFieldTags( + textfieldTagsController: _stringTagController, + initialTags: initialTags, + textSeparators: const [' ', ','], + validator: (String tag) { + if (_stringTagController.getTags!.contains(tag)) { + return AppLocalizations.of(context)?.already_tag ?? + "You have already entered this tag"; + } + return null; + }, + inputFieldBuilder: (context, inputFieldValues) { + return Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + child: TextField( + controller: inputFieldValues.textEditingController, + focusNode: inputFieldValues.focusNode, + onChanged: inputFieldValues.onTagChanged, + onSubmitted: inputFieldValues.onTagSubmitted, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: + AppLocalizations.of(context)?.tag ?? 'Tags', + hintText: inputFieldValues.tags.isNotEmpty + ? '' + : AppLocalizations.of(context)?.enter_tag ?? + "Enter tag...", + errorText: inputFieldValues.error, + prefixIcon: inputFieldValues.tags.isNotEmpty + ? SingleChildScrollView( + controller: + inputFieldValues.tagScrollController, + scrollDirection: Axis.vertical, + child: Padding( + padding: const EdgeInsets.only( + top: 8, + bottom: 8, + left: 8, + ), + child: Wrap( + runSpacing: 4.0, + spacing: 4.0, + children: inputFieldValues.tags + .map((String tag) { + return Container( + decoration: const BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(20.0), + ), + color: Colors.blue, + ), + margin: + const EdgeInsets.symmetric( + horizontal: 5.0), + padding: + const EdgeInsets.symmetric( + horizontal: 10.0, + vertical: 5.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + InkWell( + child: Text( + '$tag', + style: const TextStyle( + color: Colors.white), + ), + onTap: () { + //print("$tag selected"); + }, + ), + const SizedBox(width: 4.0), + InkWell( + child: const Icon( + Icons.cancel, + size: 14.0, + color: Color.fromARGB( + 255, 233, 233, 233), + ), + onTap: () { + inputFieldValues + .onTagRemoved(tag); + }, + ) + ], + ), + ); + }).toList()), + ), + ) + : null, + ), + ), + ); + }), + TextFieldTags( + textfieldTagsController: _stringOrgaController, + initialTags: initialOrga, + textSeparators: const [','], + validator: (String tag) { + if (_stringOrgaController.getTags!.contains(tag)) { + return AppLocalizations.of(context) + ?.already_organiser ?? + "You have already entered this organizer"; + } + return null; + }, + inputFieldBuilder: (context, inputFieldValues) { + return Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + child: TextField( + controller: inputFieldValues.textEditingController, + focusNode: inputFieldValues.focusNode, + onChanged: inputFieldValues.onTagChanged, + onSubmitted: inputFieldValues.onTagSubmitted, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: + AppLocalizations.of(context)?.organizer ?? + "Organizer", + hintText: inputFieldValues.tags.isNotEmpty + ? '' + : AppLocalizations.of(context) + ?.enter_organizer ?? + "Enter a organizer", + errorText: inputFieldValues.error, + prefixIcon: inputFieldValues.tags.isNotEmpty + ? SingleChildScrollView( + controller: + inputFieldValues.tagScrollController, + scrollDirection: Axis.vertical, + child: Padding( + padding: const EdgeInsets.only( + top: 8, + bottom: 8, + left: 8, + ), + child: Wrap( + runSpacing: 4.0, + spacing: 4.0, + children: inputFieldValues.tags + .map((String tag) { + return Container( + decoration: const BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(20.0), + ), + color: Colors.blue, + ), + margin: + const EdgeInsets.symmetric( + horizontal: 5.0), + padding: + const EdgeInsets.symmetric( + horizontal: 10.0, + vertical: 5.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + InkWell( + child: Text( + '$tag', + style: const TextStyle( + color: Colors.white), + ), + onTap: () { + //print("$tag selected"); + }, + ), + const SizedBox(width: 4.0), + InkWell( + child: const Icon( + Icons.cancel, + size: 14.0, + color: Color.fromARGB( + 255, 233, 233, 233), + ), + onTap: () { + inputFieldValues + .onTagRemoved(tag); + }, + ) + ], + ), + ); + }).toList()), + ), + ) + : null, + ), + ), + ); + }), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextField( + controller: inputDesc, + keyboardType: TextInputType.multiline, + maxLines: 10, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.description ?? + 'Description', + hintText: + AppLocalizations.of(context)?.describe_event ?? + 'Describe event'), + ), + ), + SizedBox( + height: 30, + ), + Container( + height: 50, + width: 250, + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.circular(20)), + child: TextButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + _updateEvent(context); + } + }, + child: Text( + AppLocalizations.of(context)?.add ?? 'Add', + style: TextStyle(color: Colors.white, fontSize: 25), + ), + ), + ) + ], + ), + ), + )); + } +} diff --git a/covas_mobile_new/lib/pages/EditProfile.dart b/covas_mobile_new/lib/pages/EditProfile.dart new file mode 100644 index 0000000..ff62847 --- /dev/null +++ b/covas_mobile_new/lib/pages/EditProfile.dart @@ -0,0 +1,396 @@ +import 'package:covas_mobile/classes/MyDrawer.dart'; +import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:http/http.dart' as http; +import 'package:intl/intl.dart'; + +import 'dart:convert'; +import 'dart:io'; + +import '../classes/MyDrawer.dart'; +import '../pages/LoginDemo.dart'; + +import '../classes/alert.dart'; +import '../classes/eventAdded.dart'; + +import '../variable/globals.dart' as globals; + +import '../classes/ad_helper.dart'; +import 'package:google_mobile_ads/google_mobile_ads.dart'; +import '../classes/auth_service.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // Créé + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await MobileAds.instance.initialize(); + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: EditProfile(), + ); + } +} + +class EditProfile extends StatefulWidget { + const EditProfile({super.key}); + + @override + _EditProfileState createState() => _EditProfileState(); +} + +class _EditProfileState extends State + with ShowAlertDialog, ShowEventDialog { + BannerAd? _bannerAd; + final AuthService _authService = AuthService(); + + TextEditingController inputUserName = TextEditingController(); + + TextEditingController inputName = TextEditingController(); + + TextEditingController inputFirstName = TextEditingController(); + TextEditingController inputEmail = TextEditingController(); + TextEditingController inputBirth = TextEditingController(); + TextEditingController inputPassword = TextEditingController(); + TextEditingController inputPasswordConfirmed = TextEditingController(); + + onTapFunctionDatePicker({required BuildContext context}) async { + DateTime initialDate = DateTime.parse(formatDate(inputBirth.text)); + + DateTime? pickedDate = await showDatePicker( + context: context, + firstDate: DateTime(1900), + initialDate: initialDate, + lastDate: DateTime(2104)); + if (pickedDate == null) return; + inputBirth.text = DateFormat("dd/MM/yyyy").format(pickedDate); + } + + convertNulltoEmptyString(var check) { + if (check == null) { + return ""; + } + return check; + } + + convertNulltoArray(List check) { + if (check == null) { + return []; + } + return check; + } + + String formatDate(String date) { + var splitedDate = date.split("/"); + + var day = splitedDate[0]; + var month = splitedDate[1]; + var year = splitedDate[2]; + + return "${year}-${month}-${day}"; + } + + Future _updateProfile(BuildContext context) async { + var username = inputUserName.text; + var firstName = inputFirstName.text; + var name = inputName.text; + var email = inputEmail.text; + var password = inputPassword.text; + var confirmedPassword = inputPasswordConfirmed.text; + var birth = DateTime.parse(formatDate(inputBirth.text)); + + if ((password.isNotEmpty) && (confirmedPassword.isNotEmpty)) { + if (password != confirmedPassword) { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.different_password_error ?? + "Different password"); + return; + } + } + + var urlPut = Uri.parse("${globals.api}/users/me"); + + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + if (accessToken.isNotEmpty) { + var responsePut = await http.put(urlPut, + headers: { + HttpHeaders.cookieHeader: 'access_token=${accessToken}', + HttpHeaders.acceptHeader: 'application/json, text/plain, */*', + HttpHeaders.contentTypeHeader: 'application/json' + }, + body: jsonEncode({ + 'name': name, + 'username': username, + 'firstName': firstName, + 'password': password, + 'email': email, + 'roles': '', + 'birth': birth.toString() + })); + print(responsePut.statusCode); + if (responsePut.statusCode == 200) { + showEventDialog(context, + AppLocalizations.of(context)?.user_update ?? "Your user updated"); + Navigator.pushReplacement( + context, MaterialPageRoute(builder: (_) => EditProfile())); + return; + } + + final messages = { + 400: AppLocalizations.of(context)?.request_error ?? + "Poorly constructed query", + 406: AppLocalizations.of(context)?.incorrect_password ?? + "Incorrect password", + 404: AppLocalizations.of(context)?.unknown_user ?? "Unknown user", + 403: AppLocalizations.of(context)?.disabled_user ?? "Disabled user", + 410: AppLocalizations.of(context)?.invalid_token ?? "Invalid token", + 500: AppLocalizations.of(context)?.internal_error_server ?? + "Internal error server" + }; + final text = messages[responsePut.statusCode] ?? + AppLocalizations.of(context)?.unknown_error_auth ?? + "Unknown error auth"; + showAlertDialog( + context, AppLocalizations.of(context)?.error ?? "Error", text); + } else { + Navigator.pushReplacement( + context, MaterialPageRoute(builder: (_) => LoginDemo())); + } + } + + Future _getInfoProfile() async { + var urlGet = Uri.parse("${globals.api}/users/me"); + + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + if (accessToken.isNotEmpty) { + var responseGet = await http.get(urlGet, headers: { + HttpHeaders.cookieHeader: 'access_token=${accessToken}', + HttpHeaders.acceptHeader: 'application/json, text/plain, */*', + HttpHeaders.contentTypeHeader: 'application/json' + }); + print(responseGet.statusCode); + if (responseGet.statusCode == 200) { + var body = json.decode(utf8.decode(responseGet.bodyBytes)); + setState(() { + inputName.text = body["name"]; + inputFirstName.text = body["firstName"]; + inputUserName.text = body["username"]; + inputEmail.text = body["email"]; + inputBirth.text = + DateFormat("dd/MM/yyyy").format(DateTime.parse(body["birth"])); + }); + return; + } + + final messages = { + 400: AppLocalizations.of(context)?.request_error ?? + "Poorly constructed query", + 406: AppLocalizations.of(context)?.incorrect_password ?? + "Incorrect password", + 404: AppLocalizations.of(context)?.unknown_user ?? "Unknown user", + 403: AppLocalizations.of(context)?.disabled_user ?? "Disabled user", + 410: AppLocalizations.of(context)?.invalid_token ?? "Invalid token", + 500: AppLocalizations.of(context)?.internal_error_server ?? + "Internal error server" + }; + final text = messages[responseGet.statusCode] ?? + AppLocalizations.of(context)?.unknown_error_auth ?? + "Unknown error auth"; + showAlertDialog( + context, AppLocalizations.of(context)?.error ?? "Error", text); + } else { + Navigator.pushReplacement( + context, MaterialPageRoute(builder: (_) => LoginDemo())); + } + } + + @override + void initState() { + super.initState(); + _authService.checkTokenStatus(context); + + AdHelper.createBannerAd(() => setState(() {})).then((ad) { + setState(() { + _bannerAd = ad; + }); + }); + _getInfoProfile(); + } + + final _formKey = GlobalKey(); + String? _validateField(String? value) { + return value!.isEmpty + ? AppLocalizations.of(context)?.required_input ?? "Required input" + : null; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + title: Text( + AppLocalizations.of(context)?.update_profile ?? "Update profile"), + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + ), + drawer: MyDrawer(), + body: Form( + key: _formKey, + child: SingleChildScrollView( + child: Column( + children: [ + _bannerAd == null + ? SizedBox.shrink() + : SizedBox( + height: _bannerAd!.size.height.toDouble(), + width: _bannerAd!.size.width.toDouble(), + child: AdWidget(ad: _bannerAd!)), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputUserName, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.name, + hintText: AppLocalizations.of(context)?.edit_pseudo ?? + "Edit pseudo"), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputPassword, + obscureText: true, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.password ?? + "Password", + hintText: + AppLocalizations.of(context)?.enter_password ?? + "Enter a password"), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputPasswordConfirmed, + obscureText: true, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: + AppLocalizations.of(context)?.password_confirmed ?? + "Must confirm password", + hintText: + AppLocalizations.of(context)?.password_confirmed ?? + "Must confirm password"), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputName, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.last_name ?? + "Last name", + hintText: + AppLocalizations.of(context)?.edit_last_name ?? + "Edit last name"), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputFirstName, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.first_name ?? + "First name", + hintText: + AppLocalizations.of(context)?.edit_first_name ?? + "Edit first name"), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputEmail, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: + AppLocalizations.of(context)?.email ?? "Email", + hintText: AppLocalizations.of(context)?.edit_email ?? + "Edit email"), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputBirth, + readOnly: true, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.birth_date, + hintText: AppLocalizations.of(context)?.edit_birth ?? + "Click to select a birth date"), + onTap: () => onTapFunctionDatePicker(context: context)), + ), + SizedBox( + height: 30, + ), + Container( + height: 50, + width: 250, + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.circular(20)), + child: TextButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + _updateProfile(context); + } + }, + child: Text( + AppLocalizations.of(context)?.update_profile ?? + "Update profile ", + style: TextStyle(color: Colors.white, fontSize: 25), + ), + ), + ) + ], + ), + ), + )); + } +} diff --git a/covas_mobile_new/lib/pages/EditSettings.dart b/covas_mobile_new/lib/pages/EditSettings.dart new file mode 100644 index 0000000..c6e36f9 --- /dev/null +++ b/covas_mobile_new/lib/pages/EditSettings.dart @@ -0,0 +1,170 @@ +import 'package:covas_mobile/classes/MyDrawer.dart'; +import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import 'dart:convert'; +import 'dart:io'; + +import '../classes/MyDrawer.dart'; + +import '../classes/alert.dart'; +import '../classes/eventAdded.dart'; + +import '../classes/ad_helper.dart'; +import 'package:google_mobile_ads/google_mobile_ads.dart'; +import '../classes/auth_service.dart'; + +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // Créé + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await MobileAds.instance.initialize(); + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: EditSettings(), + ); + } +} + +class EditSettings extends StatefulWidget { + const EditSettings({super.key}); + + @override + _EditProfileState createState() => _EditProfileState(); +} + +class _EditProfileState extends State + with ShowAlertDialog, ShowEventDialog { + BannerAd? _bannerAd; + final AuthService _authService = AuthService(); + + TextEditingController inputUserName = TextEditingController(); + int? kilometer; + + Future getParameter() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + setState(() { + var kilometer = prefs.getDouble("kilometer")?.toInt() ?? null; + }); + } + + Future setParameter() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + if (kilometer != null) { + prefs.setDouble("kilometer", kilometer?.toDouble() ?? 50); + showAlertDialog( + context, + AppLocalizations.of(context)?.updated ?? "Updated", + AppLocalizations.of(context)?.settings_updated ?? "Settings updated"); + } + } + + @override + void initState() { + super.initState(); + _authService.checkTokenStatus(context); + + AdHelper.createBannerAd(() => setState(() {})).then((ad) { + setState(() { + _bannerAd = ad; + }); + }); + getParameter(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + title: Text(AppLocalizations.of(context)?.settings ?? "Settings"), + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + ), + drawer: MyDrawer(), + body: Form( + child: SingleChildScrollView( + child: Column( + children: [ + _bannerAd == null + ? SizedBox.shrink() + : SizedBox( + height: _bannerAd!.size.height.toDouble(), + width: _bannerAd!.size.width.toDouble(), + child: AdWidget(ad: _bannerAd!)), + Padding( + padding: const EdgeInsets.only( + left: 15.0, + right: 15.0, + top: 15.0, + bottom: 0.0, + ), + child: DropdownButtonFormField( + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: + AppLocalizations.of(context)?.define_kilometer ?? + 'Define kilometer', + ), + value: + kilometer, // Set the initial selected value here, or leave as `null` if unselected. + items: [ + DropdownMenuItem( + value: 5, + child: Text('5km'), + ), + DropdownMenuItem( + value: 25, + child: Text('25km'), + ), + DropdownMenuItem( + value: 50, + child: Text('50km'), + ), + DropdownMenuItem( + value: 75, + child: Text('75km'), + ), + DropdownMenuItem( + value: 100, + child: Text('100km'), + ), + ], + onChanged: (int? newValue) { + // Handle selection + kilometer = newValue; + }, + ), + ), + SizedBox( + height: 30, + ), + Container( + height: 50, + width: 250, + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.circular(20)), + child: TextButton( + onPressed: () {}, + child: Text( + AppLocalizations.of(context)?.update ?? "Update", + style: TextStyle(color: Colors.white, fontSize: 25), + ), + ), + ) + ], + ), + ), + )); + } +} diff --git a/covas_mobile_new/lib/pages/ForgotPassword.dart b/covas_mobile_new/lib/pages/ForgotPassword.dart new file mode 100644 index 0000000..fb216c1 --- /dev/null +++ b/covas_mobile_new/lib/pages/ForgotPassword.dart @@ -0,0 +1,176 @@ +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; +import 'package:intl/intl.dart'; + +import 'dart:convert'; +import 'dart:io'; + +import '../main.dart'; + +import '../classes/alert.dart'; + +import '../variable/globals.dart' as globals; + +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // + +void main() { + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: PasswordForgot(), + ); + } +} + +class PasswordForgot extends StatefulWidget { + const PasswordForgot({super.key}); + + @override + _PasswordForgotState createState() => _PasswordForgotState(); +} + +class _PasswordForgotState extends State with ShowAlertDialog { + TextEditingController inputEmail = TextEditingController(); + + convertNulltoEmptyString(var check) { + if (check == null) { + return ""; + } + return check; + } + + convertNulltoArray(List check) { + if (check == null) { + return []; + } + return check; + } + + String formatDate(String date) { + var splitedDate = date.split("/"); + + var day = splitedDate[0]; + var month = splitedDate[1]; + var year = splitedDate[2]; + + return "${year}-${month}-${day}"; + } + + Future _forgotPassword(BuildContext context) async { + var email = inputEmail.text; + + var urlPut = Uri.parse("${globals.api}/password/forgot"); + + var responsePost = await http.post(urlPut, + headers: { + HttpHeaders.acceptHeader: 'application/json, text/plain, */*', + HttpHeaders.contentTypeHeader: 'application/json' + }, + body: jsonEncode({ + 'email': email, + })); + print(responsePost.statusCode); + if (responsePost.statusCode == 200) { + String message = + AppLocalizations.of(context)?.email_sent ?? "Email has been sent"; + showAlertDialog( + context, + AppLocalizations.of(context)?.create ?? "Creation", + "${message} : ${email}"); + return; + } + + final messages = { + 400: AppLocalizations.of(context)?.request_error ?? + "Poorly constructed query", + 406: AppLocalizations.of(context)?.incorrect_password ?? + "Incorrect password", + 404: AppLocalizations.of(context)?.unknown_user ?? "Unknown user", + 403: AppLocalizations.of(context)?.disabled_user ?? "Disabled user", + 410: AppLocalizations.of(context)?.invalid_token ?? "Invalid token", + 500: AppLocalizations.of(context)?.internal_error_server ?? + "Internal error server" + }; + + final text = messages[responsePost.statusCode] ?? + AppLocalizations.of(context)?.unknown_error_auth ?? + "Unknown error auth"; + showAlertDialog( + context, AppLocalizations.of(context)?.error ?? "Error", text); + } + + @override + void initState() { + super.initState(); + } + + final _formKey = GlobalKey(); + String? _validateField(String? value) { + return value!.isEmpty ? 'Champ requis' : null; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + title: Text(AppLocalizations.of(context)?.forgot_password ?? + "Forgot password"), + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + ), + body: Form( + key: _formKey, + child: SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputEmail, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: + AppLocalizations.of(context)?.email ?? 'Email', + hintText: AppLocalizations.of(context)?.enter_email ?? + 'Enter the email'), + ), + ), + SizedBox( + height: 30, + ), + Container( + height: 50, + width: 250, + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.circular(20)), + child: TextButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + _forgotPassword(context); + } + }, + child: Text( + AppLocalizations.of(context)?.send_email ?? 'Send email', + style: TextStyle(color: Colors.white, fontSize: 25), + ), + ), + ) + ], + ), + ), + )); + } +} diff --git a/covas_mobile_new/lib/pages/ItemMenu.dart b/covas_mobile_new/lib/pages/ItemMenu.dart new file mode 100644 index 0000000..def7c59 --- /dev/null +++ b/covas_mobile_new/lib/pages/ItemMenu.dart @@ -0,0 +1,455 @@ +// ignore_for_file: unnecessary_brace_in_string_interps + +import 'dart:io'; +import 'dart:convert'; + +import 'package:covas_mobile/classes/alert.dart'; +import 'package:covas_mobile/pages/ListItemByTags.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:intl/intl.dart'; +import 'package:intl/date_symbol_data_local.dart'; + +import '../variable/globals.dart' as globals; + +import '../classes/events.dart'; +import '../classes/MyDrawer.dart'; + +import 'ListItemMenu.dart'; +import 'MapboxPages.dart'; +import 'ListItemByOrganizers.dart'; +import 'EditEvent.dart'; + +import '../classes/ad_helper.dart'; +import 'package:google_mobile_ads/google_mobile_ads.dart'; +import '../classes/auth_service.dart'; + +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await MobileAds.instance.initialize(); + initializeDateFormatting("fr_FR", null).then((_) => (const MyApp())); +} + +class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + + // This widget is the root of your application. + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + // This is the theme of your application. + // + // Try running your application with "flutter run". You'll see the + // application has a blue toolbar. Then, without quitting the app, try + // changing the primarySwatch below to Colors.green and then invoke + // "hot reload" (press "r" in the console where you ran "flutter run", + // or simply save your changes to "hot reload" in a Flutter IDE). + // Notice that the counter didn't reset back to zero; the application + // is not restarted. + primarySwatch: Colors.blue, + ), + home: const ItemMenu(title: 'Flutter Demo Home Page'), + ); + } +} + +class ItemMenu extends StatefulWidget { + const ItemMenu({Key? key, required this.title}) : super(key: key); + + // This widget is the home page of your application. It is stateful, meaning + // that it has a State object (defined below) that contains fields that affect + // how it looks. + + // This class is the configuration for the state. It holds the values (in this + // case the title) provided by the parent (in this case the App widget) and + // used by the build method of the State. Fields in a Widget subclass are + // always marked "final". + + final String title; + @override + State createState() => _ItemMenuState(); +} + +class _ItemMenuState extends State with ShowAlertDialog { + BannerAd? _bannerAd; + final AuthService _authService = AuthService(); + + String listUser = ""; + String eventName = ""; + String eventStartDate = ""; + String eventDescription = ""; + String eventTicket = ""; + String eventLink = ""; + String place = ""; + String imgUrl = ""; + List tags = []; + List organizers = []; + + String id = ""; + + Events? events; + @override + void initState() { + super.initState(); + _authService.checkTokenStatus(context); + + AdHelper.createBannerAd(() => setState(() {})).then((ad) { + setState(() { + _bannerAd = ad; + }); + }); + + _getEventInfos(); + } + + Future _getEventInfos() async { + final prefs = await SharedPreferences.getInstance(); + final accessToken = prefs.getString("access_token") ?? ""; + + if (accessToken.isEmpty) { + showAlertDialog(context, AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.invalid_cache ?? "Invalid cache"); + return; + } + + final urlGet = Uri.parse("${globals.api}/events/${widget.title}"); + final responseGet = await http.get( + urlGet, + headers: {HttpHeaders.cookieHeader: 'access_token=$accessToken'}, + ); + + if (responseGet.statusCode == 200) { + final responseBody = utf8.decode(responseGet.bodyBytes); + + events = Events.fromJson(jsonDecode(responseBody)); + final locale = Provider.of(context, listen: false) + .locale + ?.toString() ?? + 'en_US'; + final startDate = + DateTime.parse(events?.startDate ?? DateTime.now().toString()); + //final date = DateFormat.yMd().format(startDate); + //final time = DateFormat.Hm().format(startDate); + final endDate = + DateTime.parse(events?.endDate ?? DateTime.now().toString()); + String separator = AppLocalizations.of(context)?.at ?? "at"; + final formattedStartDate = + DateFormat("EEEE d MMMM y '${separator}' HH:mm", locale) + .format(startDate); + + final formattedEndDate = + DateFormat("EEEE d MMMM y '${separator}' HH:mm", locale) + .format(endDate); + + String link = AppLocalizations.of(context)?.to_date ?? "to"; + + setState(() { + eventName = events?.name ?? ""; + + eventStartDate = "$formattedStartDate ${link} $formattedEndDate"; + organizers = List.from(events?.organizers ?? []); + place = events?.place ?? ""; + imgUrl = events?.imgUrl ?? ""; + eventLink = events?.link ?? ""; + eventTicket = events?.ticket ?? ""; + eventDescription = events?.description ?? ""; + tags = List.from(events?.tags ?? []); + }); + } else { + final messages = { + 400: AppLocalizations.of(context)?.request_error ?? + "Poorly constructed query", + 406: AppLocalizations.of(context)?.incorrect_password ?? + "Incorrect password", + 404: AppLocalizations.of(context)?.unknown_user ?? "Unknown user", + 403: AppLocalizations.of(context)?.disabled_user ?? "Disabled user", + 410: AppLocalizations.of(context)?.invalid_token ?? "Invalid token", + 500: AppLocalizations.of(context)?.internal_error_server ?? + "Internal error server" + }; + + final errorMessage = messages[responseGet.statusCode] ?? + AppLocalizations.of(context)?.unknown_error_auth ?? + "Unknown error auth"; + showAlertDialog(context, AppLocalizations.of(context)?.error ?? "Error", + errorMessage); + } + } + + final _formKey = GlobalKey(); + + @override + Widget build(BuildContext context) { + // This method is rerun every time setState is called, for instance as done + // by the _incrementCounter method above. + // + // The Flutter framework has been optimized to make rerunning build methods + // fast, so that you can just rebuild anything that needs updating rather + // than having to individually change instances of widgets. + return Scaffold( + appBar: AppBar( + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text("${eventName}", overflow: TextOverflow.ellipsis), + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + leading: IconButton( + icon: Icon(Icons.arrow_back), + onPressed: () { + Navigator.push( + context, MaterialPageRoute(builder: (_) => ListItemMenu())); + }, + )), + drawer: MyDrawer(), + body: SingleChildScrollView( + child: Column( + children: [ + _bannerAd == null + ? SizedBox.shrink() + : SizedBox( + height: _bannerAd!.size.height.toDouble(), + width: _bannerAd!.size.width.toDouble(), + child: AdWidget(ad: _bannerAd!)), + Padding( + padding: const EdgeInsets.only(top: 60.0), + child: Image.network( + imgUrl, + width: MediaQuery.of(context).size.width * + 0.5, // 50% of screen width + height: MediaQuery.of(context).size.height * 0.5, + loadingBuilder: (BuildContext context, Widget child, + ImageChunkEvent? loadingProgress) { + if (loadingProgress == null) { + return child; // The image has finished loading + } + return Center( + child: CircularProgressIndicator(), + ); + }, + errorBuilder: (BuildContext context, Object error, + StackTrace? stackTrace) { + return Center( + child: Icon(Icons.error, + size: MediaQuery.of(context).size.width * 0.1), + ); + }, + )), + Row(children: [ + Icon(Icons.event), + Text( + AppLocalizations.of(context)?.item_date ?? "Date : ", + style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold), + ) + ]), + Row( + children: [ + Flexible( + child: Text("${eventStartDate}", + style: TextStyle(fontSize: 15.0))) + ], + ), + Row(children: [ + Icon(Icons.explore), + Text( + AppLocalizations.of(context)?.item_maps ?? "Maps : ", + style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold), + ) + ]), + Row(children: [ + Flexible( + child: InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => MapboxPages( + title: '${widget.title}', + place: '${place}'))); + }, + child: Text("${place}", + style: TextStyle(fontSize: 15.0), + maxLines: 3, + overflow: TextOverflow.ellipsis))) + ]), + Row(children: [ + Icon(Icons.link), + Text( + AppLocalizations.of(context)?.item_link ?? "Link : ", + style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold), + ) + ]), + Row( + children: [ + Flexible( + child: + Text("${eventLink}", style: TextStyle(fontSize: 15.0))) + ], + ), + Row(children: [ + Icon(Icons.add_shopping_cart), + Text( + AppLocalizations.of(context)?.item_ticket ?? "Ticket : ", + style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold), + ) + ]), + Row( + children: [ + Flexible( + child: Text("${eventTicket}", + style: TextStyle(fontSize: 15.0))) + ], + ), + Row(children: [ + Icon(Icons.group), + Text( + AppLocalizations.of(context)?.item_organizer ?? "Organizers : ", + style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold), + ) + ]), + Row(children: [ + Flexible( + flex: 3, + fit: FlexFit.tight, + child: Padding( + padding: const EdgeInsets.only( + top: 8, + bottom: 8, + left: 8, + ), + child: Wrap( + runSpacing: 2.0, + spacing: 2.0, + children: organizers.map((String tag) { + return Container( + decoration: const BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(20.0), + ), + color: Colors.blue, + ), + margin: const EdgeInsets.symmetric(horizontal: 5.0), + padding: const EdgeInsets.symmetric( + horizontal: 10.0, vertical: 5.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => ListItemOrganizers( + organizer: '$tag'))); + }, + child: Text( + '$tag', + style: const TextStyle(color: Colors.white), + ), + ), + ], + ), + ); + }).toList()), + )), + ]), + Row(children: [ + Icon(Icons.description), + Text( + AppLocalizations.of(context)?.item_description ?? + "Description : ", + style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold)) + ]), + Row(children: [ + Flexible( + child: Text("${eventDescription}", + style: TextStyle(fontSize: 15.0), + maxLines: 3, + overflow: TextOverflow.ellipsis)) + ]), + Row(children: [ + Icon(Icons.category), + Text(AppLocalizations.of(context)?.item_tags ?? "Tags : ", + style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold)) + ]), + Row( + children: [ + Flexible( + flex: 3, + fit: FlexFit.tight, + child: Padding( + padding: const EdgeInsets.only( + top: 8, + bottom: 8, + left: 8, + ), + child: Wrap( + runSpacing: 2.0, + spacing: 2.0, + children: tags.map((String tag) { + return Container( + decoration: const BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(20.0), + ), + color: Colors.blue, + ), + margin: + const EdgeInsets.symmetric(horizontal: 5.0), + padding: const EdgeInsets.symmetric( + horizontal: 10.0, vertical: 5.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => + ListItemTags(tags: '$tag'))); + }, + child: Text( + '$tag', + style: + const TextStyle(color: Colors.white), + ), + ), + ], + ), + ); + }).toList()), + )), + ], + ) + ], + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => EditEvent( + events: events, + imgPath: "", + )), + ); + }, + backgroundColor: Colors.blue, + tooltip: AppLocalizations.of(context)?.search ?? 'Search', + child: const Icon(Icons.edit, color: Colors.white), + ), + ); + } +} diff --git a/covas_mobile_new/lib/pages/ListItemByOrganizers.dart b/covas_mobile_new/lib/pages/ListItemByOrganizers.dart new file mode 100644 index 0000000..65bc4f7 --- /dev/null +++ b/covas_mobile_new/lib/pages/ListItemByOrganizers.dart @@ -0,0 +1,275 @@ +import 'dart:convert'; +import 'dart:io'; +import "ItemMenu.dart"; + +import 'package:http/http.dart' as http; +import 'package:flutter/material.dart'; +import '../classes/events.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:intl/intl.dart'; +import 'package:intl/date_symbol_data_local.dart'; + +import '../variable/globals.dart' as globals; +import '../classes/MyDrawer.dart'; +import '../classes/auth_service.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; + +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // +import '../classes/notification_service.dart'; + +// app starting point +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + + await initializeDateFormatting("fr_FR", null); + + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return MaterialApp( + localizationsDelegates: [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: [ + const Locale('fr', 'FR'), + ], + home: const ListItemOrganizers(organizer: "default"), + debugShowCheckedModeBanner: false, + ); + } +} + +// homepage class +class ListItemOrganizers extends StatefulWidget { + const ListItemOrganizers({Key? key, required this.organizer}) + : super(key: key); + + final String organizer; + @override + State createState() => _MyHomePageState(); +} + +// homepage state +class _MyHomePageState extends State { + int _fetchCount = 0; + bool _isLoading = false; + late ScrollController _scrollController; + + final AuthService _authService = AuthService(); + + void _incrementFetchCount() { + setState(() { + _fetchCount++; + }); + } + + void _scrollListener() { + if (_scrollController.position.pixels == + _scrollController.position.maxScrollExtent) { + _incrementFetchCount(); + _fetchData(); + } + } + + Future _fetchData() async { + if (_isLoading) return; + setState(() { + _isLoading = true; + }); + + await Future.delayed(Duration(seconds: 2)); + getPosts(widget.organizer, count: _fetchCount); + + setState(() { + _isLoading = false; + }); + } + + Future> toggleInterested(String eventId) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + final url = Uri.parse("${globals.api}/events/${eventId}/interest"); + if (accessToken.isNotEmpty) { + final response = await http.post( + url, + headers: { + "Content-Type": "application/json", + HttpHeaders.cookieHeader: "access_token=$accessToken" + }, + ); + + if (response.statusCode != 200) { + throw (AppLocalizations.of(context)?.toogle_interest ?? + "Error toogle interest: ${response.statusCode}"); + } + + var event = json.decode(response.body); + return event; + } + return {"interested": false, "interested_count": 0}; + } + + // variable to call and store future list of posts + + // function to fetch data from api and return future list of posts + static Future> getPosts(organizer, {count = 0}) async { + await initializeDateFormatting("fr_FR", null); + + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + final List body = []; + if (accessToken.isNotEmpty) { + DateTime currentDatetime = DateTime.now(); + num limit = 20 * (count + 1); + var url = Uri.parse( + "${globals.api}/events?organizers=${organizer}&limit=${limit}¤t_datetime=${currentDatetime.toString()}"); + final response = await http.get(url, headers: { + "Content-Type": "application/json", + HttpHeaders.cookieHeader: "access_token=${accessToken}" + }); + final List body = json.decode(utf8.decode(response.bodyBytes)); + return body.map((e) => Events.fromJson(e)).toList(); + } + return body; + } + + @override + void initState() { + super.initState(); + _authService.checkTokenStatus(context); + _scrollController = ScrollController(); + _scrollController.addListener(_scrollListener); + } + + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + + // build function + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: MyDrawer(), + body: Center( + // FutureBuilder + child: FutureBuilder>( + future: getPosts(widget.organizer), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + // until data is fetched, show loader + return const CircularProgressIndicator(); + } else if (snapshot.hasData) { + // once data is fetched, display it on screen (call buildPosts()) + final posts = snapshot.data!; + return buildPosts(posts); + } else { + // if no data, show simple Text + return Text( + AppLocalizations.of(context)?.no_data ?? "No data available"); + } + }, + ), + ), + ); + } + + // function to display fetched data on screen + Widget buildPosts(List posts) { + String organizer = + AppLocalizations.of(context)?.item_organizer ?? "Organizer : "; + // ListView Builder to show data in a list + return Scaffold( + appBar: AppBar( + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text("${organizer}${widget.organizer}", + overflow: TextOverflow.ellipsis), + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + ), + body: ListView.separated( + controller: _scrollController, + itemCount: posts.isNotEmpty + ? posts.length + (_isLoading ? 1 : 0) // Add 1 only if loading + : 0, + itemBuilder: (context, index) { + final post = posts[index]; + final startDate = DateTime.parse(post.startDate!); + + final locale = Provider.of(context, listen: false) + .locale + ?.toString() ?? + 'en_US'; + + final dateLongue = + DateFormat('EEEE d MMMM y', locale).format(startDate); + final countInterestedString = + AppLocalizations.of(context)?.count_interested ?? + "Interested people number"; + final countInterested = + "${countInterestedString} : ${post.interestedCount}"; + + return ListTile( + title: Text('${post.name!}'), + subtitle: + Text('${post.place!}\n${dateLongue}\n${countInterested}'), + trailing: IconButton( + onPressed: () async { + try { + final result = await toggleInterested(post.id!); + setState(() { + post.interested = result["interested"]; + post.interestedCount = result["interested_count"]; + }); + if (result["interested"] == true) { + NotificationService.scheduleEventNotification( + eventId: post.id!, + title: "Rappel évènement", + body: + "Ton évènement '${post.name}' commence dans 1 heure !", + eventDate: DateTime.parse(post.startDate!), + ); + } else { + NotificationService.cancel(post.id!); + } + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + AppLocalizations.of(context)?.error_update ?? + "Error when updating")), + ); + } + }, + icon: Icon( + post.interested ?? false + ? Icons.favorite + : Icons.favorite_border, + color: + post.interested ?? false ? Colors.red : Colors.grey)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => ItemMenu(title: post.id!))); + }); + }, + separatorBuilder: (context, index) { + return Divider(); + }, + ), + ); + } +} diff --git a/covas_mobile_new/lib/pages/ListItemByTags.dart b/covas_mobile_new/lib/pages/ListItemByTags.dart new file mode 100644 index 0000000..1dbd8df --- /dev/null +++ b/covas_mobile_new/lib/pages/ListItemByTags.dart @@ -0,0 +1,277 @@ +import 'dart:convert'; +import 'dart:io'; +import "ItemMenu.dart"; + +import 'package:http/http.dart' as http; +import 'package:flutter/material.dart'; +import '../classes/events.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:intl/intl.dart'; +import 'package:intl/date_symbol_data_local.dart'; + +import '../variable/globals.dart' as globals; + +import '../classes/MyDrawer.dart'; +import '../classes/auth_service.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; + +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // +import '../classes/notification_service.dart'; + +// app starting point +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + + await initializeDateFormatting("fr_FR", null); + + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return MaterialApp( + localizationsDelegates: [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: [ + const Locale('fr', 'FR'), + ], + home: const ListItemTags(tags: "default"), + debugShowCheckedModeBanner: false, + ); + } +} + +// homepage class +class ListItemTags extends StatefulWidget { + const ListItemTags({Key? key, required this.tags}) : super(key: key); + + final String tags; + @override + State createState() => _MyHomePageState(); +} + +// homepage state +class _MyHomePageState extends State { + // variable to call and store future list of posts + + int _fetchCount = 0; + bool _isLoading = false; + late ScrollController _scrollController; + + final AuthService _authService = AuthService(); + + void _incrementFetchCount() { + setState(() { + _fetchCount++; + }); + } + + void _scrollListener() { + if (_scrollController.position.pixels == + _scrollController.position.maxScrollExtent) { + _incrementFetchCount(); + + _fetchData(); + } + } + + Future _fetchData() async { + print("Counter : ${_fetchCount}"); + if (_isLoading) return; + setState(() { + _isLoading = true; + }); + + await Future.delayed(Duration(seconds: 2)); + getPosts(widget.tags, count: _fetchCount); + + setState(() { + _isLoading = false; + }); + } + + // function to fetch data from api and return future list of posts + static Future> getPosts(tags, {count = 0}) async { + await initializeDateFormatting("fr_FR", null); + + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + final List body = []; + if (accessToken.isNotEmpty) { + DateTime currentDatetime = DateTime.now(); + num limit = 20 * (count + 1); + + var url = Uri.parse( + "${globals.api}/events?tags=${tags}&limit=${limit}¤t_datetime=${currentDatetime.toString()}"); + final response = await http.get(url, headers: { + "Content-Type": "application/json", + HttpHeaders.cookieHeader: "access_token=${accessToken}" + }); + final List body = json.decode(utf8.decode(response.bodyBytes)); + return body.map((e) => Events.fromJson(e)).toList(); + } + return body; + } + + Future> toggleInterested(String eventId) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + final url = Uri.parse("${globals.api}/events/${eventId}/interest"); + if (accessToken.isNotEmpty) { + final response = await http.post( + url, + headers: { + "Content-Type": "application/json", + HttpHeaders.cookieHeader: "access_token=$accessToken" + }, + ); + + if (response.statusCode != 200) { + throw (AppLocalizations.of(context)?.toogle_interest ?? + "Error toogle interest: ${response.statusCode}"); + } + + var event = json.decode(response.body); + return event; + } + return {"interested": false, "interested_count": 0}; + } + + @override + void initState() { + super.initState(); + _authService.checkTokenStatus(context); + _authService.checkTokenStatus(context); + _scrollController = ScrollController(); + _scrollController.addListener(_scrollListener); + } + + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + + // build function + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: MyDrawer(), + body: Center( + // FutureBuilder + child: FutureBuilder>( + future: getPosts(widget.tags), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + // until data is fetched, show loader + return const CircularProgressIndicator(); + } else if (snapshot.hasData) { + // once data is fetched, display it on screen (call buildPosts()) + final posts = snapshot.data!; + return buildPosts(posts); + } else { + // if no data, show simple Text + return Text( + AppLocalizations.of(context)?.no_data ?? "No data available"); + } + }, + ), + ), + ); + } + + // function to display fetched data on screen + Widget buildPosts(List posts) { + // ListView Builder to show data in a list + String tag = AppLocalizations.of(context)?.item_tags ?? "Tags : "; + + return Scaffold( + appBar: AppBar( + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text("${tag}${widget.tags}", overflow: TextOverflow.ellipsis), + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + ), + body: ListView.separated( + controller: _scrollController, + itemCount: posts.isNotEmpty + ? posts.length + (_isLoading ? 1 : 0) // Add 1 only if loading + : 0, + itemBuilder: (context, index) { + final post = posts[index]; + final startDate = DateTime.parse(post.startDate!); + final locale = Provider.of(context, listen: false) + .locale + ?.toString() ?? + 'en_US'; + final dateLongue = + DateFormat('EEEE d MMMM y', locale).format(startDate); + + final countInterestedString = + AppLocalizations.of(context)?.count_interested ?? + "Interested people number"; + final countInterested = + "${countInterestedString} : ${post.interestedCount}"; + + return ListTile( + title: Text('${post.name!}'), + subtitle: + Text('${post.place!}\n${dateLongue}\n${countInterested}'), + trailing: IconButton( + onPressed: () async { + try { + final result = await toggleInterested(post.id!); + setState(() { + post.interested = result["interested"]; + post.interestedCount = result["interested_count"]; + }); + if (result["interested"] == true) { + NotificationService.scheduleEventNotification( + eventId: post.id!, + title: "Rappel évènement", + body: + "Ton évènement '${post.name}' commence dans 1 heure !", + eventDate: DateTime.parse(post.startDate!), + ); + } else { + NotificationService.cancel(post.id!); + } + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + AppLocalizations.of(context)?.error_update ?? + "Error when updating")), + ); + } + }, + icon: Icon( + post.interested ?? false + ? Icons.favorite + : Icons.favorite_border, + color: + post.interested ?? false ? Colors.red : Colors.grey)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => ItemMenu(title: post.id!))); + }); + }, + separatorBuilder: (context, index) { + return Divider(); + }, + ), + ); + } +} diff --git a/covas_mobile_new/lib/pages/ListItemMenu.dart b/covas_mobile_new/lib/pages/ListItemMenu.dart new file mode 100644 index 0000000..7ce2daf --- /dev/null +++ b/covas_mobile_new/lib/pages/ListItemMenu.dart @@ -0,0 +1,954 @@ +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; +import 'package:flutter_dotenv/flutter_dotenv.dart'; // Import dotenv +import 'dart:convert'; +import 'dart:io'; +import 'ItemMenu.dart'; +import '../classes/events.dart'; +import '../classes/MyDrawer.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:intl/intl.dart'; +import 'package:intl/date_symbol_data_local.dart'; +import 'dart:math'; +import 'package:geolocator/geolocator.dart'; +import '../variable/globals.dart' as globals; +import 'package:permission_handler/permission_handler.dart'; +import "Camera.dart"; +import 'package:camera/camera.dart'; + +import '../classes/ad_helper.dart'; +import 'package:google_mobile_ads/google_mobile_ads.dart'; +import '../classes/auth_service.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // Créé plus loin +import '../classes/notification_service.dart'; + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + + await MobileAds.instance.initialize(); + await initializeDateFormatting("fr_FR", null); + + runApp(ChangeNotifierProvider( + create: (_) => LocaleProvider(), + child: const MyApp(), + )); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + final localeProvider = Provider.of(context); + return MaterialApp( + localizationsDelegates: [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: [const Locale('fr', 'FR'), const Locale('en')], + locale: localeProvider.locale, + home: Builder(builder: (context) => ListItemMenu()), + debugShowCheckedModeBanner: false, + ); + } +} + +class ListItemMenu extends StatefulWidget { + const ListItemMenu({super.key}); + + @override + State createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + BannerAd? _bannerAd; + final AuthService _authService = AuthService(); + late ScrollController _scrollController; + int _fetchCount = 0; + bool _isLoading = false; + + Future> postsFuture = getPosts(); + List filteredPosts = []; + String geographicalZone = ''; + String itemName = ''; + String itemTags = ''; + String query = ''; + List> suggestionsGeo = []; + List> suggestionsItem = []; + List> suggestionsTags = []; + TextEditingController inputGeo = TextEditingController(); + TextEditingController startDatepicker = TextEditingController(); + TextEditingController endDatepicker = TextEditingController(); + TextEditingController inputItem = TextEditingController(); + TextEditingController inputTags = TextEditingController(); + + bool showDateFields = false; // State to toggle date fields + bool showArrow = true; + bool showInputSearch = true; + bool showInputGeo = true; + bool showInputTag = true; + // Fetching events from API + static Future> getPosts() async { + await initializeDateFormatting("fr_FR"); + PermissionStatus status = await Permission.location.status; + final List body = []; + var url = Uri.parse("${globals.api}/events"); + if (status.isGranted) { + print("Location permission granted"); + + // Get the current position with high accuracy + + const LocationSettings locationSettings = LocationSettings( + accuracy: LocationAccuracy.medium, + timeLimit: Duration(seconds: 5), + ); + Position? position; + try { + position = await Geolocator.getCurrentPosition( + locationSettings: locationSettings); + } on LocationServiceDisabledException { + // Handle location services disabled + print('Location services are disabled.'); + position = await Geolocator.getLastKnownPosition(); + if (position == null) { + print('No last known position available.'); + } + } catch (e) { + // Handle other errors + print('Failed to get location: $e'); + position = await Geolocator.getLastKnownPosition(); + if (position == null) { + print('No last known position available.'); + } + } + SharedPreferences prefs = await SharedPreferences.getInstance(); + + if (position != null) { + // Calculate the boundaries + double radiusInKm = prefs.getDouble("kilometer") ?? 50.0; + double latDistance = radiusInKm / 111.0; + double lonDistance = + radiusInKm / (111.0 * cos(position.latitude * pi / 180)); + + double minLat = position.latitude - latDistance; + double maxLat = position.latitude + latDistance; + double minLon = position.longitude - lonDistance; + double maxLon = position.longitude + lonDistance; + DateTime currentDatetime = DateTime.now(); + url = Uri.parse("${globals.api}/events/search" + "?min_lat=$minLat&max_lat=$maxLat" + "&min_lon=$minLon&max_lon=$maxLon¤t_datetime=${currentDatetime.toString()}"); + } + + var accessToken = prefs.getString("access_token") ?? ""; + + if (accessToken.isNotEmpty) { + final response = await http.get(url, headers: { + "Content-Type": "application/json", + HttpHeaders.cookieHeader: "access_token=${accessToken}" + }); + final List body = json.decode(utf8.decode(response.bodyBytes)); + return body.map((e) => Events.fromJson(e)).toList(); + } + } + return body; + } + + String formatDate(String date) { + var splitedDate = date.split("-"); + var day = splitedDate[0]; + var month = splitedDate[1]; + var year = splitedDate[2]; + + return "${year}-${month}-${day}"; + } + + void _incrementFetchCount() { + setState(() { + _fetchCount++; + }); + _fetchData(); + } + + void _scrollListener() { + if (_scrollController.position.pixels == + _scrollController.position.maxScrollExtent) { + _incrementFetchCount(); + } + + // Scroll to top + } + + Future _fetchData() async { + print("Counter : ${_fetchCount}"); + if (_isLoading) return; + setState(() { + _isLoading = true; + }); + + await Future.delayed(Duration(seconds: 2)); + fetchPostsByLocation(); + + setState(() { + _isLoading = false; + }); + } + + @override + void initState() { + super.initState(); + _authService.checkTokenStatus(context); + AdHelper.createBannerAd(() => setState(() {})).then((ad) { + setState(() { + _bannerAd = ad; + }); + }); + _scrollController = ScrollController(); + _scrollController.addListener(_scrollListener); + + // Initialize data fetch when the page loads + _getCurrentLocation(); + } + + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + + // Get the device's current location + Future _getCurrentLocation() async { + PermissionStatus status = await Permission.location.status; + + if (status.isGranted) { + print("Location permission granted"); + + // Get the current position with high accuracy + const LocationSettings locationSettings = LocationSettings( + accuracy: LocationAccuracy.medium, timeLimit: Duration(seconds: 5)); + Position? position; + try { + position = await Geolocator.getCurrentPosition( + locationSettings: locationSettings); + } on LocationServiceDisabledException { + // Handle location services disabled + print('Location services are disabled.'); + position = await Geolocator.getLastKnownPosition(); + if (position == null) { + print('No last known position available.'); + } + } catch (e) { + // Handle other errors + print('Failed to get location: $e'); + position = await Geolocator.getLastKnownPosition(); + if (position == null) { + print('No last known position available.'); + } + } + + // Reverse geocode: Get city and country from latitude and longitude using Mapbox Search API + if (position != null) { + _getCityAndCountry(position!.latitude, position!.longitude); + } + } + } + + // Method to get city and country from latitude and longitude using Mapbox API + Future _getCityAndCountry(double latitude, double longitude) async { + await dotenv.load(fileName: ".env"); // Load .env file + + final mapboxAccessToken = dotenv.env['MAPBOX_ACCESS_TOKEN'] ?? ''; + final url = Uri.parse( + 'https://api.mapbox.com/geocoding/v5/mapbox.places/$longitude,$latitude.json?access_token=$mapboxAccessToken', + ); + + try { + // Send GET request to Mapbox API + final response = await http.get(url); + + // If the request is successful (HTTP status 200) + print("status mapbox : ${response.statusCode}"); + if (response.statusCode == 200) { + // Parse the response body + final data = json.decode(response.body); + + // Extract the city and country from the response + final features = data['features']; + + if (features.isNotEmpty) { + String city = _getCityFromFeatures(features); + String country = _getCountryFromFeatures(features); + print("city : ${city} ${country}"); + if (city.isNotEmpty && country.isNotEmpty) { + SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setDouble("city_lat", latitude); + prefs.setDouble("city_long", longitude); + fetchPostsByLocation(); + setState(() { + inputGeo.text = "${city}, ${country}"; + }); + } else { + fetchPostsByLocation(); + } + } else { + fetchPostsByLocation(); + } + } else { + fetchPostsByLocation(); + throw Exception('Failed to load location data'); + } + } catch (e) { + fetchPostsByLocation(); + } + } + + // Helper function to extract the city from the Mapbox features array + String _getCityFromFeatures(List features) { + for (var feature in features) { + if (feature['place_type'] != null && + feature['place_type'].contains('place')) { + return feature['text'] ?? ''; + } + } + return ''; + } + + // Helper function to extract the country from the Mapbox features array + String _getCountryFromFeatures(List features) { + for (var feature in features) { + if (feature['place_type'] != null && + feature['place_type'].contains('country')) { + return feature['text'] ?? ''; + } + } + return ''; + } + + Future searchSuggestionsGeo(String input) async { + await dotenv.load(fileName: ".env"); // Load .env file + + final mapboxAccessToken = dotenv.env['MAPBOX_ACCESS_TOKEN'] ?? ''; + final url = + 'https://api.mapbox.com/geocoding/v5/mapbox.places/${input}.json?access_token=${mapboxAccessToken}&proximity=ip'; + final response = await http.get(Uri.parse(url)); + + if (response.statusCode == 200) { + final data = json.decode(response.body); + setState(() { + suggestionsGeo = (data['features'] as List) + .map((feature) => { + 'place_name': feature['place_name'], + 'geometry': feature[ + 'geometry'], // Include geometry for latitude/longitude + }) + .toList(); + if (suggestionsGeo.isNotEmpty) { + showArrow = false; + showInputSearch = false; + showInputTag = false; + } + }); + } else { + throw Exception(AppLocalizations.of(context)?.failed_suggestions ?? + 'Failed to load suggestions'); + } + } + + Future getUrlForEvents() async { + final prefs = await SharedPreferences.getInstance(); + final latitude = prefs.getDouble("city_lat") ?? 0.0; + final longitude = prefs.getDouble("city_long") ?? 0.0; + + final radiusInKm = prefs.getDouble("kilometer") ?? 50.0; + String endpoint = "events"; + String queryParameters = ""; + + if (latitude != 0.0 && longitude != 0.0) { + final latDistance = radiusInKm / 111.0; + final lonDistance = radiusInKm / (111.0 * cos(latitude * pi / 180)); + + final minLat = latitude - latDistance; + final maxLat = latitude + latDistance; + final minLon = longitude - lonDistance; + final maxLon = longitude + lonDistance; + + endpoint = "events/search"; + queryParameters = + "min_lat=$minLat&max_lat=$maxLat&min_lon=$minLon&max_lon=$maxLon"; + } + + final currentDate = DateTime.now(); + String dateParameter = "current_datetime=${currentDate.toIso8601String()}"; + + if (startDatepicker.text.isNotEmpty || endDatepicker.text.isNotEmpty) { + endpoint = "events/search"; + if (startDatepicker.text.isNotEmpty) { + final startDate = DateTime.parse(formatDate(startDatepicker.text)); + dateParameter = "start_date=${startDate.toIso8601String()}"; + } + if (endDatepicker.text.isNotEmpty) { + final endDate = DateTime.parse(formatDate(endDatepicker.text)); + dateParameter += "&end_date=${endDate.toIso8601String()}"; + } + } + + if (inputItem.text.isNotEmpty) { + queryParameters += "&item=${inputItem.text}"; + } + + if (inputTags.text.isNotEmpty) { + queryParameters += "&tags=${inputTags.text}"; + } + + if (queryParameters.isNotEmpty) { + queryParameters = "$queryParameters&$dateParameter"; + } else { + queryParameters = dateParameter; + } + int limit = 20 * (_fetchCount + 1); + + return Uri.parse( + "${globals.api}/$endpoint?$queryParameters&limit=${limit}"); + } + + Future searchSuggestionsByItem(String input) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + + if (accessToken.isNotEmpty) { + var url = await getUrlForEvents(); + final response = await http.get(url, headers: { + "Content-Type": "application/json", + HttpHeaders.cookieHeader: "access_token=$accessToken" + }); + + if (response.statusCode == 200) { + final data = json.decode(utf8.decode(response.bodyBytes)); + setState(() { + suggestionsItem = (data as List) + .map((feature) => {'name': feature['name']}) + .toList(); + if (suggestionsItem.isNotEmpty) { + showDateFields = false; + showArrow = false; + } + }); + print("status code : ${response.statusCode}"); + } + } + } + + Future searchSuggestionsByTag(String input) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + + if (accessToken.isNotEmpty) { + var url = Uri.parse("${globals.api}/tags?name=${input}"); + final response = await http.get(url, headers: { + "Content-Type": "application/json", + HttpHeaders.cookieHeader: "access_token=$accessToken" + }); + + if (response.statusCode == 200) { + final data = json.decode(utf8.decode(response.bodyBytes)); + setState(() { + suggestionsTags = (data as List) + .map((feature) => {'name': feature['name']}) + .toList(); + if (suggestionsTags.isNotEmpty) { + showInputGeo = false; + showInputSearch = false; + showArrow = false; + } + }); + } + } + } + + Future> toggleInterested(String eventId) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + final url = Uri.parse("${globals.api}/events/${eventId}/interest"); + if (accessToken.isNotEmpty) { + final response = await http.post( + url, + headers: { + "Content-Type": "application/json", + HttpHeaders.cookieHeader: "access_token=$accessToken" + }, + ); + + if (response.statusCode != 200) { + throw (AppLocalizations.of(context)?.toogle_interest ?? + "Error toogle interest: ${response.statusCode}"); + } + + var event = json.decode(response.body); + return event; + } + return {"interested": false, "interested_count": 0}; + } + + Future fetchPostsByLocation() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + + if (accessToken.isNotEmpty) { + var url = await getUrlForEvents(); + final response = await http.get(url, headers: { + "Content-Type": "application/json", + HttpHeaders.cookieHeader: "access_token=$accessToken" + }); + + print("status code : ${response.statusCode}"); + if (response.statusCode == 200) { + final List body = json.decode(utf8.decode(response.bodyBytes)); + print("results fetch : ${body}"); + print("fetch count : ${_fetchCount}"); + // Update state after getting the response + + setState(() { + int counter = filteredPosts.length; + // If we have results, map them to Events + filteredPosts = body + .map((e) => Events.fromJson(e as Map)) + .toList(); + if (counter == filteredPosts.length) { + _fetchCount--; + } + }); + } else { + throw Exception('Failed to load posts'); + } + } + } + + onTapFunctionDatePicker( + {required BuildContext context, String position = ""}) async { + DateTime dateEvent = DateTime.now(); + if (startDatepicker.text.isNotEmpty) { + dateEvent = DateTime.parse(formatDate(startDatepicker.text)); + } + + DateTime? pickedDate = await showDatePicker( + context: context, firstDate: dateEvent, lastDate: DateTime(2104)); + if (pickedDate == null) return; + if (position == "start") { + startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + } else if (position == "end") { + endDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + } + + fetchPostsByLocation(); + } + + Padding _buildDateField(String position) { + TextEditingController datePicker = startDatepicker; + String hintText = AppLocalizations.of(context)?.start_date ?? "Start date"; + if (position == "end") { + datePicker = endDatepicker; + hintText = AppLocalizations.of(context)?.end_date ?? "End date"; + } + return Padding( + padding: const EdgeInsets.all(8.0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: datePicker, + readOnly: true, + decoration: InputDecoration( + border: OutlineInputBorder(), + suffixIcon: datePicker.text.isEmpty + ? null + : IconButton( + icon: const Icon(Icons.clear), + onPressed: () async { + setState(() { + datePicker.text = ''; + }); + fetchPostsByLocation(); + }, + ), + hintText: hintText), + onTap: () => + onTapFunctionDatePicker(context: context, position: position)), + ); + } + + Widget _buildSearchField({ + required TextEditingController controller, + required String labelText, + required Function(String) onChanged, + required Function() onClear, + required List> suggestions, + required Function(Map) onSuggestionTap, + }) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + TextField( + controller: controller, + decoration: InputDecoration( + labelText: labelText, + border: OutlineInputBorder(), + suffixIcon: controller.text.isEmpty + ? null + : IconButton( + icon: const Icon(Icons.clear), + onPressed: () => onClear(), + ), + ), + onChanged: onChanged, + ), + if (suggestions.isNotEmpty) + Container( + height: 200, + decoration: BoxDecoration( + border: Border.all(color: Colors.blue), + borderRadius: BorderRadius.circular(8), + ), + child: ListView.builder( + shrinkWrap: true, + itemCount: suggestions.length, + itemBuilder: (context, index) { + final suggestion = suggestions[index]; + return ListTile( + title: Text( + suggestion['name'] ?? suggestion['place_name'] ?? ''), + onTap: () => onSuggestionTap(suggestion), + ); + }, + ), + ), + ], + ), + ); + } + + Future popCamera() async { + await availableCameras().then((value) => Navigator.push(context, + MaterialPageRoute(builder: (_) => Camera(camera: value.first)))); + } + + @override + Widget build(BuildContext context) { + final loc = AppLocalizations.of(context); + final localeProvider = Provider.of(context); + return Scaffold( + appBar: AppBar( + title: Text(loc?.menu_list ?? "Item list menu"), + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + ), + drawer: MyDrawer(), + body: Column( + children: [ + _bannerAd == null + ? SizedBox.shrink() + : SizedBox( + height: _bannerAd!.size.height.toDouble(), + width: _bannerAd!.size.width.toDouble(), + child: AdWidget(ad: _bannerAd!), + ), + if (showInputSearch) + _buildSearchField( + controller: inputItem, + labelText: loc?.search_item ?? "Search by item", + onChanged: (value) { + _fetchCount = 0; + if (value.isNotEmpty) { + setState(() { + itemName = value; + searchSuggestionsByItem(value); + }); + } else { + setState(() { + inputItem.clear(); + itemName = ''; + suggestionsItem.clear(); + showDateFields = true; + showArrow = true; + }); + fetchPostsByLocation(); + } + }, + onClear: () { + _fetchCount = 0; + setState(() { + inputItem.clear(); + itemName = ''; + suggestionsItem.clear(); + showDateFields = true; + showArrow = true; + }); + fetchPostsByLocation(); + }, + suggestions: suggestionsItem, + onSuggestionTap: (suggestion) async { + _fetchCount = 0; + setState(() { + itemName = suggestion['name']; + inputItem.text = itemName; + suggestionsItem.clear(); + showDateFields = true; + showArrow = true; + }); + await fetchPostsByLocation(); + }, + ), + if ((showDateFields) && (showInputTag)) + _buildSearchField( + controller: inputTags, + labelText: loc?.search_tag ?? "Search by tags", + onChanged: (value) { + _fetchCount = 0; + if (value.isNotEmpty) { + setState(() { + itemTags = value; + searchSuggestionsByTag(value); + }); + } else { + setState(() { + inputTags.clear(); + showArrow = true; + showInputSearch = true; + showInputGeo = true; + itemTags = ''; + }); + fetchPostsByLocation(); + } + }, + onClear: () { + _fetchCount = 0; + setState(() { + inputTags.clear(); + }); + fetchPostsByLocation(); + }, + suggestions: suggestionsTags, + onSuggestionTap: (suggestion) async { + _fetchCount = 0; + + setState(() { + itemTags = suggestion['name']; + inputTags.text = itemTags; + suggestionsTags.clear(); + showArrow = true; + showInputSearch = true; + showInputGeo = true; + }); + await fetchPostsByLocation(); + }, + ), + if ((showDateFields) && (showArrow)) + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible(child: _buildDateField("start")), + Flexible(child: _buildDateField("end")) + ]), + if ((showDateFields) && (showInputGeo)) + _buildSearchField( + controller: inputGeo, + labelText: + loc?.search_geographical ?? 'Search by geographical zone', + onChanged: (value) async { + _fetchCount = 0; + + if (value.isNotEmpty) { + setState(() { + geographicalZone = value; + searchSuggestionsGeo(value); + }); + } else { + final prefs = await SharedPreferences.getInstance(); + prefs.remove("city_lat"); + prefs.remove("city_long"); + setState(() { + inputGeo.clear(); + geographicalZone = ''; + suggestionsGeo.clear(); + showArrow = true; + showInputSearch = true; + showInputTag = true; + }); + fetchPostsByLocation(); + } + }, + onClear: () async { + _fetchCount = 0; + final prefs = await SharedPreferences.getInstance(); + prefs.remove("city_lat"); + prefs.remove("city_long"); + setState(() { + inputGeo.clear(); + geographicalZone = ''; + suggestionsGeo.clear(); + showArrow = true; + showInputSearch = true; + showInputTag = true; + }); + fetchPostsByLocation(); + }, + suggestions: suggestionsGeo, + onSuggestionTap: (suggestion) async { + _fetchCount = 0; + final latitude = suggestion['geometry']['coordinates'][1]; + final longitude = suggestion['geometry']['coordinates'][0]; + setState(() { + geographicalZone = suggestion['place_name']; + inputGeo.text = geographicalZone; + suggestionsGeo.clear(); + showArrow = true; + showInputSearch = true; + showInputTag = true; + }); + final prefs = await SharedPreferences.getInstance(); + prefs.setDouble("city_lat", latitude); + prefs.setDouble("city_long", longitude); + await fetchPostsByLocation(); + }, + ), + if (showArrow) + IconButton( + onPressed: () { + setState(() { + showDateFields = !showDateFields; // Toggle visibility + }); + }, + icon: Icon( + showDateFields + ? Icons.keyboard_arrow_up + : Icons.keyboard_arrow_down, + color: Colors.blue, + ), + tooltip: showDateFields + ? loc?.show_date_field ?? 'Show Date Fields' + : loc?.hide_date_field ?? 'Hide Date Fields', + ), + Expanded( + child: FutureBuilder>( + future: postsFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return Center(child: CircularProgressIndicator()); + } else if (snapshot.hasData) { + final posts = snapshot.data!; + final displayedPosts = + filteredPosts.isEmpty ? posts : filteredPosts; + return buildPosts(displayedPosts); + } else { + return Center( + child: Text(AppLocalizations.of(context)?.no_data ?? + "No data available"), + ); + } + }, + ), + ), + ], + ), + floatingActionButton: FloatingActionButton( + onPressed: popCamera, + backgroundColor: Colors.blue, + tooltip: loc?.search ?? 'Recherche', + child: const Icon(Icons.photo_camera, color: Colors.white), + ), + ); + } + + // Function to display fetched data on screen + Widget buildPosts(List posts) { + final displayedPosts = filteredPosts; + // If filteredPosts is empty, show a message saying no data is available + if (displayedPosts.isEmpty) { + return Center( + child: Text( + AppLocalizations.of(context)?.no_events ?? + 'No events available for this location.', + style: TextStyle(fontSize: 18, color: Colors.grey)), + ); + } + + return ListView.separated( + controller: _scrollController, + itemCount: displayedPosts.isNotEmpty + ? displayedPosts.length + + (_isLoading ? 1 : 0) // Add 1 only if loading + : 0, + itemBuilder: (context, index) { + if (index >= displayedPosts.length) { + return _isLoading + ? Center(child: CircularProgressIndicator()) + : SizedBox.shrink(); + } + final post = displayedPosts[index]; + final startDate = DateTime.parse(post.startDate!); + //final date = DateFormat.yMd().format(startDate); + //final time = DateFormat.Hm().format(startDate); + final locale = + Provider.of(context).locale?.toString() ?? + 'en_US'; + final dateLongue = + DateFormat('EEEE d MMMM y', locale).format(startDate); + final countInterestedString = + AppLocalizations.of(context)?.count_interested ?? + "Interested people number"; + final countInterested = + "${countInterestedString} : ${post.interestedCount}"; + return ListTile( + title: Text('${post.name!}'), + subtitle: Text('${post.place!}\n${dateLongue}\n${countInterested}'), + trailing: IconButton( + onPressed: () async { + try { + final result = await toggleInterested(post.id!); + setState(() { + post.interested = result["interested"]; + post.interestedCount = result["interested_count"]; + }); + + if (result["interested"] == true) { + NotificationService.scheduleEventNotification( + eventId: post.id!, + title: "Rappel évènement", + body: + "Ton évènement '${post.name}' commence dans 1 heure !", + eventDate: DateTime.parse(post.startDate!), + ); + } else { + NotificationService.cancel(post.id!); + } + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + AppLocalizations.of(context)?.error_update ?? + "Error when updating")), + ); + } + }, + icon: Icon( + post.interested ?? false + ? Icons.favorite + : Icons.favorite_border, + color: + post.interested ?? false ? Colors.red : Colors.grey)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (_) => ItemMenu(title: post.id!)), + ); + }, + ); + }, + separatorBuilder: (context, index) { + return Divider(); + }); + } +} diff --git a/covas_mobile_new/lib/pages/LoginDemo.dart b/covas_mobile_new/lib/pages/LoginDemo.dart new file mode 100644 index 0000000..d6dd224 --- /dev/null +++ b/covas_mobile_new/lib/pages/LoginDemo.dart @@ -0,0 +1,169 @@ +import 'package:flutter/material.dart'; +import 'package:google_mobile_ads/google_mobile_ads.dart'; +import 'package:permission_handler/permission_handler.dart'; +import '../classes/auth_service.dart'; +import '../pages/ListItemMenu.dart'; +import '../pages/AddProfile.dart'; +import '../pages/ForgotPassword.dart'; +import '../classes/alert.dart'; +import '../classes/ad_helper.dart'; + +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // + +class LoginDemo extends StatefulWidget { + @override + _LoginDemoState createState() => _LoginDemoState(); +} + +class _LoginDemoState extends State with ShowAlertDialog { + BannerAd? _bannerAd; + TextEditingController inputPseudo = TextEditingController(); + TextEditingController inputPassword = TextEditingController(); + final AuthService _authService = AuthService(); + bool _rememberMe = false; + + Future _login(BuildContext context) async { + final pseudo = inputPseudo.text; + final password = inputPassword.text; + + if (pseudo.isEmpty || password.isEmpty) { + showAlertDialog(context, AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.empty_input ?? "Empty input"); + return; + } + + bool success = + await _authService.login(pseudo, password, rememberMe: _rememberMe); + + if (success) { + Navigator.push( + context, MaterialPageRoute(builder: (_) => ListItemMenu())); + } else { + showAlertDialog(context, AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.failed_auth ?? "Authentication failed"); + } + } + + @override + void initState() { + super.initState(); + AdHelper.createBannerAd(() => setState(() {})).then((ad) { + setState(() { + _bannerAd = ad; + }); + }); + + _checkLocationPermission(); + _checkLoginStatus(); + } + + Future _checkLoginStatus() async { + bool loggedIn = await _authService.isLoggedIn(); + if (loggedIn) { + Navigator.push( + context, MaterialPageRoute(builder: (_) => ListItemMenu())); + } + } + + Future _checkLocationPermission() async { + PermissionStatus status = await Permission.location.status; + if (!status.isGranted) { + await Permission.location.request(); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + title: Text(AppLocalizations.of(context)?.login_page ?? "Login Page"), + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + ), + body: SingleChildScrollView( + child: Column( + children: [ + _bannerAd == null + ? SizedBox.shrink() + : SizedBox( + height: _bannerAd!.size.height.toDouble(), + width: _bannerAd!.size.width.toDouble(), + child: AdWidget(ad: _bannerAd!), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 15), + child: TextField( + controller: inputPseudo, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.pseudo ?? 'Pseudo', + hintText: + AppLocalizations.of(context)?.enter_existing_pseudo ?? + 'Enter a existing pseudo', + ), + ), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 15, vertical: 15), + child: TextField( + controller: inputPassword, + obscureText: true, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: + AppLocalizations.of(context)?.password ?? "Password", + hintText: AppLocalizations.of(context)?.enter_password ?? + "Enter the password", + ), + ), + ), + CheckboxListTile( + title: Text( + AppLocalizations.of(context)?.remembr_me ?? "Remember me"), + value: _rememberMe, + onChanged: (newValue) { + setState(() { + _rememberMe = newValue ?? false; + }); + }, + ), + TextButton( + onPressed: () { + Navigator.push(context, + MaterialPageRoute(builder: (_) => PasswordForgot())); + }, + child: Text( + AppLocalizations.of(context)?.forgot_password ?? + 'Forgot Password', + style: TextStyle(color: Colors.blue, fontSize: 15)), + ), + Container( + height: 50, + width: 250, + decoration: BoxDecoration( + color: Colors.blue, borderRadius: BorderRadius.circular(20)), + child: TextButton( + onPressed: () => _login(context), + child: Text(AppLocalizations.of(context)?.sign_in ?? 'Sign in', + style: TextStyle(color: Colors.white, fontSize: 25)), + ), + ), + SizedBox(height: 130), + InkWell( + child: Text(AppLocalizations.of(context)?.new_user ?? + 'New User? Create Account'), + onTap: () { + Navigator.push( + context, MaterialPageRoute(builder: (_) => AddProfile())); + }, + ), + ], + ), + ), + ); + } +} diff --git a/covas_mobile_new/lib/pages/MapboxPages.dart b/covas_mobile_new/lib/pages/MapboxPages.dart new file mode 100644 index 0000000..549bc96 --- /dev/null +++ b/covas_mobile_new/lib/pages/MapboxPages.dart @@ -0,0 +1,452 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; // For environment variables +import 'package:flutter/services.dart'; // For loading assets +import 'package:http/http.dart' as http; +import 'package:mapbox_gl/mapbox_gl.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:geolocator/geolocator.dart'; // For getting the user's location + +import '../classes/alert.dart'; // Assuming this contains your error dialog code. +import '../variable/globals.dart' as globals; +import '../classes/MyDrawer.dart'; +import '../classes/auth_service.dart'; + +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // + +void main() async { + await dotenv.load(fileName: ".env"); // Load .env file + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Directions Example', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: const MapboxPages(title: 'Event Location', place: "Flutter"), + ); + } +} + +class MapboxPages extends StatefulWidget { + const MapboxPages({Key? key, required this.title, required this.place}) + : super(key: key); + + final String title; + final String place; + + @override + State createState() => _MapboxPagesState(); +} + +class _MapboxPagesState extends State with ShowAlertDialog { + final AuthService _authService = AuthService(); + + late MapboxMapController mapController; + late String mapboxAccessToken; + List routeCoordinates = []; + String selectedMode = 'driving'; + double longitude = 0.0; + double latitude = 0.0; + bool isLoading = true; + late LatLng userPosition; + bool isUserPositionInitialized = false; + Line? currentRouteLine; + + @override + void initState() { + super.initState(); + _authService.checkTokenStatus(context); + + _getUserLocation(); + } + + void _initToken() { + mapboxAccessToken = dotenv.env['MAPBOX_ACCESS_TOKEN'] ?? ''; + if (mapboxAccessToken.isEmpty) { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.map_token ?? + "Map Access Token is not available."); + } + } + + Future _getEventInfo() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + + if (accessToken.isNotEmpty) { + var urlGet = Uri.parse("${globals.api}/events/${widget.title}"); + + var responseGet = await http.get(urlGet, + headers: {HttpHeaders.cookieHeader: 'access_token=${accessToken}'}); + if (responseGet.statusCode == 200) { + var events = jsonDecode(utf8.decode(responseGet.bodyBytes)); + latitude = events["latitude"]; + longitude = events["longitude"]; + + setState(() { + isLoading = false; + }); + } else { + _handleErrorResponse(responseGet.statusCode); + } + } else { + showAlertDialog(context, AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.invalid_cache ?? "Invalid cache."); + } + } + + void _handleErrorResponse(int statusCode) { + final messages = { + 400: AppLocalizations.of(context)?.request_error ?? + "Poorly constructed query", + 406: AppLocalizations.of(context)?.incorrect_password ?? + "Incorrect password", + 404: AppLocalizations.of(context)?.unknown_user ?? "Unknown user", + 403: AppLocalizations.of(context)?.disabled_user ?? "Disabled user", + 410: AppLocalizations.of(context)?.invalid_token ?? "Invalid token", + 500: AppLocalizations.of(context)?.internal_error_server ?? + "Internal error server" + }; + + final errorMessage = messages[statusCode] ?? + AppLocalizations.of(context)?.unknown_error_auth ?? + "Unknown error auth"; + showAlertDialog( + context, AppLocalizations.of(context)?.error ?? "Error", errorMessage); + } + + Future _getUserLocation() async { + try { + bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); + if (!serviceEnabled) { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.geo_disabled ?? + "Location services are disabled."); + return; + } + + LocationPermission permission = await Geolocator.checkPermission(); + if (permission == LocationPermission.denied) { + permission = await Geolocator.requestPermission(); + if (permission == LocationPermission.denied) { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.permission_denied ?? + "Location permissions are denied."); + return; + } + } + + if (permission == LocationPermission.deniedForever) { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.enable_permission ?? + "Location permissions are permanently denied. Enable them in settings."); + return; + } + const LocationSettings locationSettings = LocationSettings( + accuracy: LocationAccuracy.medium, timeLimit: Duration(seconds: 5)); + Position? position; + try { + position = await Geolocator.getCurrentPosition( + locationSettings: locationSettings); + } on LocationServiceDisabledException { + // Handle location services disabled + position = await Geolocator.getLastKnownPosition(); + if (position == null) { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.no_last_position ?? + "No last known position available.."); + } + } catch (e) { + // Handle other errors + position = await Geolocator.getLastKnownPosition(); + if (position == null) { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.no_last_position ?? + "No last known position available"); + } + } + if (position != null) { + setState(() { + userPosition = LatLng(position!.latitude, position!.longitude); + isUserPositionInitialized = true; + }); + } + _initToken(); + _getEventInfo(); + } catch (e) { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.failed_location ?? + "Failed to get user location"); + } + } + + Future _fetchRoute( + LatLng origin, LatLng destination, String mode) async { + final url = Uri.parse( + 'https://api.mapbox.com/directions/v5/mapbox/$mode/${origin.longitude},${origin.latitude};${destination.longitude},${destination.latitude}?geometries=geojson&access_token=$mapboxAccessToken', + ); + + final response = await http.get(url); + if (response.statusCode == 200) { + final data = jsonDecode(response.body); + final geometry = data['routes'][0]['geometry']['coordinates']; + setState(() { + routeCoordinates = geometry.map((coord) { + return LatLng(coord[1], coord[0]); + }).toList(); + }); + } else { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.failed_fetch ?? + "Failed to fetch the route"); + } + } + + // Called when the map is created + void _onStyleLoaded() async { + // Log the map controller and coordinates + + // Check if the mapController is really initialized + if (mapController != null) { + try { + // Ensure the coordinates are valid + if (latitude != 0.0 && longitude != 0.0) { + // Load marker image as Uint8List + final userMarkerImage = await _loadMarkerImage('images/marker.png'); + + // Register the image with Mapbox + await mapController.addImage('event-marker', userMarkerImage); + + final symbolOptions = SymbolOptions( + geometry: LatLng(latitude, longitude), + iconImage: "event-marker", // Use the registered custom marker + iconSize: 0.4, // Optional: Adjust size + ); + + // Debugging symbol options + + // Add symbol to map + mapController!.addSymbol(symbolOptions); + } else { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.invalid_coordinates_symbol ?? + "Error: Invalid coordinates, cannot add symbol."); + } + } catch (e) { + // Handle any exception that occurs when adding the symbol + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.error_symbol ?? + "Error when adding symbol."); + } + } else { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.error_symbol ?? + "Error when adding symbol."); + } + } + + Future _drawRouteAndMarkers() async { + // Remove previous route line if it exists + if (currentRouteLine != null) { + await mapController.removeLine(currentRouteLine!); + currentRouteLine = null; + } + if (!isUserPositionInitialized) { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.position_not_init ?? + "User position is not yet initialized. Try again."); + return; + } + + if (mapController != null && + userPosition != null && + latitude != 0.0 && + longitude != 0.0) { + final destination = LatLng(latitude, longitude); + + // Register the custom images + // Add event marker + + final eventMarkerImage = await _loadMarkerImage('images/marker-red.png'); + + // Register the image with Mapbox + await mapController.addImage('user-marker', eventMarkerImage); + await mapController.addSymbol(SymbolOptions( + geometry: userPosition, + iconImage: 'user-marker', // Custom icon for event + iconSize: 0.2, + )); + + // Fetch and draw route + await _fetchRoute(userPosition, destination, selectedMode); + + if (routeCoordinates.isNotEmpty) { + currentRouteLine = await mapController.addLine( + LineOptions( + geometry: routeCoordinates, + lineColor: '#3b9ddd', + lineWidth: 5.0, + lineOpacity: 0.8, + ), + ); + + _zoomToFitRoute(routeCoordinates); + } + } else { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.invalid_coordinates ?? + "Invalid coordinates or user position."); + } + } + + void _zoomToFitRoute(List coordinates) { + // Calculate the bounding box + double minLat = coordinates.first.latitude; + double maxLat = coordinates.first.latitude; + double minLng = coordinates.first.longitude; + double maxLng = coordinates.first.longitude; + + for (LatLng coord in coordinates) { + if (coord.latitude < minLat) minLat = coord.latitude; + if (coord.latitude > maxLat) maxLat = coord.latitude; + if (coord.longitude < minLng) minLng = coord.longitude; + if (coord.longitude > maxLng) maxLng = coord.longitude; + } + + // Define the bounds + LatLng southwest = LatLng(minLat, minLng); + LatLng northeast = LatLng(maxLat, maxLng); + + mapController.moveCamera( + CameraUpdate.newLatLngBounds( + LatLngBounds(southwest: southwest, northeast: northeast), + left: 50, // Padding on the left + top: 50, // Padding on the top + right: 50, // Padding on the right + bottom: 50, // Padding on the bottom + ), + ); + } + + // Load image from assets + Future _loadMarkerImage(String assetPath) async { + final ByteData data = await rootBundle.load(assetPath); + return data.buffer.asUint8List(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.place), + actions: [ + DropdownButton( + value: selectedMode, + items: [ + DropdownMenuItem( + value: 'walking', + child: Row( + children: [ + Icon(Icons.directions_walk, color: Colors.blue), + SizedBox(width: 8), + Text(AppLocalizations.of(context)?.walking ?? 'Walking'), + ], + ), + ), + DropdownMenuItem( + value: 'cycling', + child: Row( + children: [ + Icon(Icons.directions_bike, color: Colors.green), + SizedBox(width: 8), + Text(AppLocalizations.of(context)?.cycling ?? 'Cycling'), + ], + ), + ), + DropdownMenuItem( + value: 'driving', + child: Row( + children: [ + Icon(Icons.directions_car, color: Colors.red), + SizedBox(width: 8), + Text(AppLocalizations.of(context)?.driving ?? 'Driving'), + ], + ), + ), + ], + onChanged: (mode) { + setState(() { + selectedMode = mode!; + }); + }, + ) + ], + ), + drawer: MyDrawer(), + body: Stack( + children: [ + isLoading + ? Center(child: CircularProgressIndicator()) + : MapboxMap( + accessToken: mapboxAccessToken, + onMapCreated: (controller) { + mapController = controller; + }, + onStyleLoadedCallback: _onStyleLoaded, + initialCameraPosition: CameraPosition( + target: LatLng(latitude, longitude), + zoom: 14.0, + ), + ), + Positioned( + bottom: 20, + right: 20, + child: FloatingActionButton( + onPressed: _drawRouteAndMarkers, + child: Icon(Icons.directions), + tooltip: AppLocalizations.of(context)?.get_direction ?? + 'Get Directions and Markers', + ), + ), + ], + ), + ); + } +} diff --git a/covas_mobile_new/lib/pages/UpdateEventImage.dart b/covas_mobile_new/lib/pages/UpdateEventImage.dart new file mode 100644 index 0000000..0a08e25 --- /dev/null +++ b/covas_mobile_new/lib/pages/UpdateEventImage.dart @@ -0,0 +1,815 @@ +import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:http/http.dart' as http; +import 'package:uuid/uuid.dart'; +import 'package:intl/intl.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:textfield_tags/textfield_tags.dart'; +import '../classes/MyDrawer.dart'; +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; + +import 'ItemMenu.dart'; +import '../classes/alert.dart'; +import '../classes/eventAdded.dart'; + +import '../variable/globals.dart' as globals; + +import '../classes/ad_helper.dart'; +import 'package:google_mobile_ads/google_mobile_ads.dart'; +import '../classes/auth_service.dart'; + +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import '../locale_provider.dart'; // + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await MobileAds.instance.initialize(); + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + Map events = {}; + String imagePath = ""; + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: UpdateeventImage(events: events, imagePath: imagePath), + ); + } +} + +class UpdateeventImage extends StatefulWidget { + const UpdateeventImage( + {Key? key, required this.events, required this.imagePath}) + : super(key: key); + final Map events; + final String imagePath; + + @override + _UpdateeventImageState createState() => _UpdateeventImageState(); +} + +class _UpdateeventImageState extends State + with ShowAlertDialog, ShowEventDialog { + BannerAd? _bannerAd; + final AuthService _authService = AuthService(); + + TextEditingController inputName = TextEditingController(); + + TextEditingController inputDate = TextEditingController(); + TextEditingController inputDesc = TextEditingController(); + + TextEditingController inputGeo = TextEditingController(); + + TextEditingController startDatepicker = TextEditingController(); + TextEditingController startTimepicker = TextEditingController(); + TextEditingController endDatepicker = TextEditingController(); + TextEditingController endTimepicker = TextEditingController(); + final _stringTagController = StringTagController(); + + List> suggestions = []; + String geographicalZone = ""; + + List initialTags = []; + + final _stringOrgaController = StringTagController(); + List initialOrga = []; + + onTapFunctionDatePicker( + {required BuildContext context, required String position}) async { + String date = "start_date"; + if (position == "end") { + date = "end_date"; + } + DateTime dateEvent; + if (widget.events[date].toString().isEmpty) { + dateEvent = DateTime.now(); + } else { + dateEvent = DateTime.parse(widget.events[date]); + } + DateTime? pickedDate = await showDatePicker( + context: context, + firstDate: dateEvent, + initialDate: dateEvent, + lastDate: DateTime(2104)); + if (pickedDate == null) return; + if (position == "start") { + startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + } + if (position == "end") { + endDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + } + } + + onTapFunctionTimePicker( + {required BuildContext context, required String position}) async { + String date = "start_date"; + if (position == "end") { + date = "end_date"; + } + TimeOfDay timeEvent; + if (widget.events[date].toString().isEmpty) { + timeEvent = TimeOfDay.now(); + } else { + timeEvent = TimeOfDay.fromDateTime(DateTime.parse(widget.events[date])); + } + TimeOfDay? pickedDate = + await showTimePicker(context: context, initialTime: timeEvent); + if (pickedDate == null) return; + if (position == "start") { + startTimepicker.text = pickedDate.format(context); + } + if (position == "end") { + endTimepicker.text = pickedDate.format(context); + } + } + + convertNulltoEmptyString(var check) { + if (check == null) { + return ""; + } + return check; + } + + convertNulltoArray(List check) { + if (check == null) { + return []; + } + return check; + } + + String formatDate(String date) { + var splitedDate = date.split("-"); + var day = splitedDate[0]; + var month = splitedDate[1]; + var year = splitedDate[2]; + + return "${year}-${month}-${day}"; + } + + Future _updateEvent(BuildContext context) async { + // Gather inputs + var name = inputName.text; + var place = inputGeo.text; + var description = inputDesc.text; + List tags = List.from(_stringTagController.getTags as List); + List organizers = + List.from(_stringOrgaController.getTags as List); + + var startDateFormat = formatDate(startDatepicker.text); + DateTime startDateCompare = DateTime.parse(startDateFormat); + DateTime dateNow = DateTime.now(); + var endDateFormat = formatDate(endDatepicker.text); + var startDate = + "${startDateFormat}T${startTimepicker.text.replaceAll('-', ':')}"; + var endDate = "${endDateFormat}T${endTimepicker.text.replaceAll('-', ':')}"; + + if (!startDateCompare.isAfter(dateNow)) { + showAlertDialog(context, AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.no_future_event ?? "No future event"); + return; + } + + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + + if (accessToken.isEmpty) { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.missing_token ?? + "Missing access token"); + return; + } + + try { + await dotenv.load(); + final ApiTokenGoogle = dotenv.env['PLACE_API_KEY'] ?? ''; + // Searchbox API for geocoding the place (No session token) + final searchboxUrl = Uri.parse( + 'https://maps.googleapis.com/maps/api/place/textsearch/json?query=${place}&key=${ApiTokenGoogle}'); + + // Perform the request + final searchboxResponse = await http.get(searchboxUrl); + + if (searchboxResponse.statusCode != 200) { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.geocoding_error ?? + "Error when geocoding"); + return; + } + + final searchboxData = json.decode(searchboxResponse.body); + if (searchboxData['results'].isEmpty) { + showAlertDialog(context, AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.no_found_place ?? "No found place"); + return; + } + + // Extract place details from the searchbox response + final firstFeature = searchboxData['results'][0]; + place = firstFeature["formatted_address"]; + final coordinates = firstFeature['geometry']['location']; + final longitude = coordinates["lng"]; + final latitude = coordinates["lat"]; + + // Check if a similar event exists + final eventsUrl = Uri.parse( + "${globals.api}/events/search?item=$name&date_event=$startDate"); + final eventsResponse = await http.get(eventsUrl, headers: { + HttpHeaders.cookieHeader: 'access_token=$accessToken', + }); + + if (eventsResponse.statusCode == 200) { + final events = json.decode(utf8.decode(eventsResponse.bodyBytes)); + if (events.isNotEmpty) { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => ItemMenu(title: events[0]["id"]), + ), + ); + return; + } + } + + // Upload image to imgbb + final imgbbUrl = Uri.parse( + 'https://api.imgbb.com/1/upload?expiration=15552000&key=${dotenv.env["IMGBB_API_KEY"]}'); + File image = File(widget.imagePath); + Uint8List imageBytes = await image.readAsBytes(); + String base64Image = base64.encode(imageBytes); + + final imgbbRequest = http.MultipartRequest('POST', imgbbUrl) + ..fields['image'] = base64Image; + final imgbbResponse = + await http.Response.fromStream(await imgbbRequest.send()); + + if (imgbbResponse.statusCode != 200) { + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.upload_error ?? + "Error when image uploading"); + return; + } + + final imgbbData = json.decode(imgbbResponse.body); + final imgUrl = imgbbData['data']['url']; + + // Create or update the event + final eventUrl = Uri.parse("${globals.api}/events"); + final eventResponse = await http.put( + eventUrl, + headers: { + HttpHeaders.cookieHeader: 'access_token=$accessToken', + HttpHeaders.acceptHeader: 'application/json, text/plain, */*', + HttpHeaders.contentTypeHeader: 'application/json', + }, + body: jsonEncode({ + 'name': name, + 'place': place, + 'start_date': startDate, + 'end_date': endDate, + 'organizers': organizers, + 'latitude': latitude, + 'longitude': longitude, + 'description': description, + 'imgUrl': imgUrl, + 'tags': tags, + }), + ); + + if (eventResponse.statusCode == 200 || eventResponse.statusCode == 201) { + String event_message = + AppLocalizations.of(context)?.event_added ?? "Event added"; + showEventDialog(context, "$event_message : $name"); + } else { + handleHttpError(eventResponse.statusCode, context); + } + } catch (e) { + showAlertDialog(context, AppLocalizations.of(context)?.error ?? "Error", + AppLocalizations.of(context)?.app_error ?? "Error application"); + } + } + +// Utility function to handle HTTP errors + void handleHttpError(int statusCode, BuildContext context) { + final messages = { + 400: AppLocalizations.of(context)?.request_error ?? + "Poorly constructed query", + 406: AppLocalizations.of(context)?.incorrect_password ?? + "Incorrect password", + 404: AppLocalizations.of(context)?.unknown_user ?? "Unknown user", + 403: AppLocalizations.of(context)?.disabled_user ?? "Disabled user", + 410: AppLocalizations.of(context)?.invalid_token ?? "Invalid token", + 500: AppLocalizations.of(context)?.internal_error_server ?? + "Internal error server" + }; + showAlertDialog( + context, + AppLocalizations.of(context)?.error ?? "Error", + messages[statusCode] ?? + AppLocalizations.of(context)?.unknown_error ?? + "Unknown error"); + } + + void start() async { + print("events : ${widget.events}"); + inputName.text = convertNulltoEmptyString(widget.events["name"]); + inputGeo.text = convertNulltoEmptyString(widget.events["place"]); + inputDesc.text = convertNulltoEmptyString(widget.events["description"]); + if (widget.events["start_date"].toString().isNotEmpty) { + DateTime pickedStartDate = + DateTime.parse(convertNulltoEmptyString(widget.events["start_date"])); + startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedStartDate); + startTimepicker.text = DateFormat("HH-mm").format(pickedStartDate); + } + if (widget.events["end_date"].toString().isNotEmpty) { + DateTime pickedEndDate = + DateTime.parse(convertNulltoEmptyString(widget.events["end_date"])); + endDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedEndDate); + endTimepicker.text = DateFormat("HH-mm").format(pickedEndDate); + } + initialTags = List.from(widget.events['tags'] as List); + initialOrga = List.from(widget.events['organizers'] as List); + } + + @override + void initState() { + super.initState(); + _authService.checkTokenStatus(context); + + AdHelper.createBannerAd(() => setState(() {})).then((ad) { + setState(() { + _bannerAd = ad; + }); + }); + start(); + } + + final _formKey = GlobalKey(); + String? _validateField(String? value) { + return value!.isEmpty + ? AppLocalizations.of(context)?.required_input ?? 'Required input' + : null; + } + + Future searchSuggestions(String input) async { + await dotenv.load(fileName: ".env"); // Load .env file + + final ApiTokenGoogle = dotenv.env['PLACE_API_KEY'] ?? ''; + + // Define the Searchbox API URL + final searchboxUrl = Uri.parse( + 'https://maps.googleapis.com/maps/api/place/textsearch/json?query=${input}&key=${ApiTokenGoogle}'); + + // Perform the request + final response = await http.get(searchboxUrl); + + if (response.statusCode == 200) { + final data = json.decode(response.body); + + setState(() { + // Map the results to extract name and full_address + suggestions = (data['results'] as List) + .map((feature) => { + 'name': feature['name'], + 'formatted_address': feature[ + 'formatted_address'] // Adjusted to match the data structure + }) + .toList(); + }); + } else { + throw Exception('Failed to load suggestions'); + } + } + + Padding _buildGeographicalZoneSearchField() { + return Padding( + padding: + const EdgeInsets.only(left: 15.0, right: 15.0, top: 15, bottom: 0), + child: Column( + children: [ + TextField( + controller: inputGeo, + decoration: InputDecoration( + labelText: AppLocalizations.of(context)?.location ?? 'Location', + border: OutlineInputBorder(), + suffixIcon: IconButton( + icon: const Icon(Icons.clear), + onPressed: () { + setState(() { + inputGeo.clear(); // Clear the text field + geographicalZone = ''; // Reset the geographical zone state + suggestions.clear(); // Optionally clear suggestions + }); + }, + ), + ), + onChanged: (value) { + setState(() { + geographicalZone = value; + searchSuggestions(value); + }); + }, + ), + if (suggestions.isNotEmpty) + Container( + height: 200, + decoration: BoxDecoration( + border: Border.all(color: Colors.blue), + borderRadius: BorderRadius.circular(8), + ), + child: ListView.builder( + shrinkWrap: true, + itemCount: suggestions.length, + itemBuilder: (context, index) { + return ListTile( + title: Text(suggestions[index]['name']), + subtitle: Text(suggestions[index]['formatted_address']), + onTap: () async { + print("suggestion tapped : ${suggestions[index]}"); + + setState(() { + geographicalZone = + suggestions[index]['formatted_address']; + inputGeo.text = geographicalZone; + suggestions.clear(); + }); + }, + ); + }, + ), + ), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + title: Text(AppLocalizations.of(context)?.add_event ?? + "Add or Update a event"), + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + ), + drawer: MyDrawer(), + body: Form( + key: _formKey, + child: SingleChildScrollView( + child: Column( + children: [ + _bannerAd == null + ? SizedBox.shrink() + : SizedBox( + height: _bannerAd!.size.height.toDouble(), + width: _bannerAd!.size.width.toDouble(), + child: AdWidget(ad: _bannerAd!)), + Padding( + padding: const EdgeInsets.only(top: 60.0), + child: Center( + child: Container( + width: 200, + height: 150, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(100.0)), + child: Image.file(File(widget.imagePath))), + ), + ), + Padding( + //padding: const EdgeInsets.only(left:15.0,right: 15.0,top:0,bottom: 0), + padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: inputName, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.name ?? "Name", + hintText: + AppLocalizations.of(context)?.edit_event_name ?? + "Edit event name"), + ), + ), + _buildGeographicalZoneSearchField(), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: startDatepicker, + readOnly: true, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.start_date ?? + "Start date", + hintText: AppLocalizations.of(context)?.select_date ?? + "Click to select a date"), + onTap: () => onTapFunctionDatePicker( + context: context, position: "start")), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: startTimepicker, + readOnly: true, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.start_time ?? + "Start time", + hintText: AppLocalizations.of(context)?.select_time ?? + "Click to select a time"), + onTap: () => onTapFunctionTimePicker( + context: context, position: "start")), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: endDatepicker, + readOnly: true, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.end_date ?? + "End date", + hintText: AppLocalizations.of(context)?.select_date ?? + "Click to select a date"), + onTap: () => onTapFunctionDatePicker( + context: context, position: "end")), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: endTimepicker, + readOnly: true, + validator: (value) => _validateField(value), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.end_time ?? + "End time", + hintText: AppLocalizations.of(context)?.select_time ?? + "Click to select a time"), + onTap: () => onTapFunctionTimePicker( + context: context, position: "end")), + ), + TextFieldTags( + textfieldTagsController: _stringTagController, + initialTags: initialTags, + textSeparators: const [' ', ','], + validator: (String tag) { + if (_stringTagController.getTags!.contains(tag)) { + return AppLocalizations.of(context)?.already_tag ?? + 'You have already entered this tag'; + } + return null; + }, + inputFieldBuilder: (context, inputFieldValues) { + return Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + child: TextField( + controller: inputFieldValues.textEditingController, + focusNode: inputFieldValues.focusNode, + onChanged: inputFieldValues.onTagChanged, + onSubmitted: inputFieldValues.onTagSubmitted, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: + AppLocalizations.of(context)?.tag ?? 'Tags', + hintText: inputFieldValues.tags.isNotEmpty + ? '' + : AppLocalizations.of(context)?.enter_tag ?? + "Enter tag...", + errorText: inputFieldValues.error, + prefixIcon: inputFieldValues.tags.isNotEmpty + ? SingleChildScrollView( + controller: + inputFieldValues.tagScrollController, + scrollDirection: Axis.vertical, + child: Padding( + padding: const EdgeInsets.only( + top: 8, + bottom: 8, + left: 8, + ), + child: Wrap( + runSpacing: 4.0, + spacing: 4.0, + children: inputFieldValues.tags + .map((String tag) { + return Container( + decoration: const BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(20.0), + ), + color: Colors.blue, + ), + margin: + const EdgeInsets.symmetric( + horizontal: 5.0), + padding: + const EdgeInsets.symmetric( + horizontal: 10.0, + vertical: 5.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + InkWell( + child: Text( + '$tag', + style: const TextStyle( + color: Colors.white), + ), + onTap: () { + //print("$tag selected"); + }, + ), + const SizedBox(width: 4.0), + InkWell( + child: const Icon( + Icons.cancel, + size: 14.0, + color: Color.fromARGB( + 255, 233, 233, 233), + ), + onTap: () { + inputFieldValues + .onTagRemoved(tag); + }, + ) + ], + ), + ); + }).toList()), + ), + ) + : null, + ), + ), + ); + }), + TextFieldTags( + textfieldTagsController: _stringOrgaController, + initialTags: initialOrga, + textSeparators: const [','], + validator: (String tag) { + if (_stringOrgaController.getTags!.contains(tag)) { + return AppLocalizations.of(context) + ?.already_organiser ?? + 'You have already entered this organizer'; + } + return null; + }, + inputFieldBuilder: (context, inputFieldValues) { + return Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + child: TextField( + controller: inputFieldValues.textEditingController, + focusNode: inputFieldValues.focusNode, + onChanged: inputFieldValues.onTagChanged, + onSubmitted: inputFieldValues.onTagSubmitted, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: + AppLocalizations.of(context)?.organizer ?? + 'Organizers', + hintText: inputFieldValues.tags.isNotEmpty + ? '' + : AppLocalizations.of(context) + ?.enter_organizer ?? + "Enter un organisateur...", + errorText: inputFieldValues.error, + prefixIcon: inputFieldValues.tags.isNotEmpty + ? SingleChildScrollView( + controller: + inputFieldValues.tagScrollController, + scrollDirection: Axis.vertical, + child: Padding( + padding: const EdgeInsets.only( + top: 8, + bottom: 8, + left: 8, + ), + child: Wrap( + runSpacing: 4.0, + spacing: 4.0, + children: inputFieldValues.tags + .map((String tag) { + return Container( + decoration: const BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(20.0), + ), + color: Colors.blue, + ), + margin: + const EdgeInsets.symmetric( + horizontal: 5.0), + padding: + const EdgeInsets.symmetric( + horizontal: 10.0, + vertical: 5.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + InkWell( + child: Text( + '$tag', + style: const TextStyle( + color: Colors.white), + ), + onTap: () { + //print("$tag selected"); + }, + ), + const SizedBox(width: 4.0), + InkWell( + child: const Icon( + Icons.cancel, + size: 14.0, + color: Color.fromARGB( + 255, 233, 233, 233), + ), + onTap: () { + inputFieldValues + .onTagRemoved(tag); + }, + ) + ], + ), + ); + }).toList()), + ), + ) + : null, + ), + ), + ); + }), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextField( + controller: inputDesc, + keyboardType: TextInputType.multiline, + maxLines: 10, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context)?.description ?? + 'Description', + hintText: + AppLocalizations.of(context)?.describe_event ?? + 'Describe the event'), + ), + ), + SizedBox( + height: 30, + ), + Container( + height: 50, + width: 250, + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.circular(20)), + child: TextButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + _updateEvent(context); + } + }, + child: Text( + AppLocalizations.of(context)?.add_event ?? 'Add', + style: TextStyle(color: Colors.white, fontSize: 25), + ), + ), + ) + ], + ), + ), + )); + } +} diff --git a/covas_mobile_new/lib/variable/globals.dart b/covas_mobile_new/lib/variable/globals.dart new file mode 100644 index 0000000..f90fa4d --- /dev/null +++ b/covas_mobile_new/lib/variable/globals.dart @@ -0,0 +1 @@ +String api = "https://backend.valczeryba.ovh"; diff --git a/covas_mobile_new/linux/.gitignore b/covas_mobile_new/linux/.gitignore new file mode 100644 index 0000000..d3896c9 --- /dev/null +++ b/covas_mobile_new/linux/.gitignore @@ -0,0 +1 @@ +flutter/ephemeral diff --git a/covas_mobile_new/linux/CMakeLists.txt b/covas_mobile_new/linux/CMakeLists.txt new file mode 100644 index 0000000..01cd2c2 --- /dev/null +++ b/covas_mobile_new/linux/CMakeLists.txt @@ -0,0 +1,128 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.13) +project(runner LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "covas_mobile_new") +# The unique GTK application identifier for this application. See: +# https://wiki.gnome.org/HowDoI/ChooseApplicationID +set(APPLICATION_ID "com.example.covas_mobile_new") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(SET CMP0063 NEW) + +# Load bundled libraries from the lib/ directory relative to the binary. +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Root filesystem for cross-building. +if(FLUTTER_TARGET_PLATFORM_SYSROOT) + set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endif() + +# Define build configuration options. +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") +endif() + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_14) + target_compile_options(${TARGET} PRIVATE -Wall -Werror) + target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) + +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) + +# Only the install-generated bundle's copy of the executable will launch +# correctly, since the resources must in the right relative locations. To avoid +# people trying to run the unbundled copy, put it in a subdirectory instead of +# the default top-level location. +set_target_properties(${BINARY_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" +) + + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# By default, "installing" just makes a relocatable bundle in the build +# directory. +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) + install(FILES "${bundled_library}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endforeach(bundled_library) + +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() diff --git a/covas_mobile_new/linux/flutter/CMakeLists.txt b/covas_mobile_new/linux/flutter/CMakeLists.txt new file mode 100644 index 0000000..d5bd016 --- /dev/null +++ b/covas_mobile_new/linux/flutter/CMakeLists.txt @@ -0,0 +1,88 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) + +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "fl_basic_message_channel.h" + "fl_binary_codec.h" + "fl_binary_messenger.h" + "fl_dart_project.h" + "fl_engine.h" + "fl_json_message_codec.h" + "fl_json_method_codec.h" + "fl_message_codec.h" + "fl_method_call.h" + "fl_method_channel.h" + "fl_method_codec.h" + "fl_method_response.h" + "fl_plugin_registrar.h" + "fl_plugin_registry.h" + "fl_standard_message_codec.h" + "fl_standard_method_codec.h" + "fl_string_codec.h" + "fl_value.h" + "fl_view.h" + "flutter_linux.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE + PkgConfig::GTK + PkgConfig::GLIB + PkgConfig::GIO +) +add_dependencies(flutter flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/_phony_ + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" + ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} +) diff --git a/covas_mobile_new/linux/flutter/generated_plugin_registrant.cc b/covas_mobile_new/linux/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000..7299b5c --- /dev/null +++ b/covas_mobile_new/linux/flutter/generated_plugin_registrant.cc @@ -0,0 +1,19 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + +#include +#include + +void fl_register_plugins(FlPluginRegistry* registry) { + 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) 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/covas_mobile_new/linux/flutter/generated_plugin_registrant.h b/covas_mobile_new/linux/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000..e0f0a47 --- /dev/null +++ b/covas_mobile_new/linux/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void fl_register_plugins(FlPluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/covas_mobile_new/linux/flutter/generated_plugins.cmake b/covas_mobile_new/linux/flutter/generated_plugins.cmake new file mode 100644 index 0000000..786ff5c --- /dev/null +++ b/covas_mobile_new/linux/flutter/generated_plugins.cmake @@ -0,0 +1,25 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + file_selector_linux + url_launcher_linux +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/covas_mobile_new/linux/runner/CMakeLists.txt b/covas_mobile_new/linux/runner/CMakeLists.txt new file mode 100644 index 0000000..e97dabc --- /dev/null +++ b/covas_mobile_new/linux/runner/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.13) +project(runner LANGUAGES CXX) + +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add preprocessor definitions for the application ID. +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + +# Add dependency libraries. Add any application-specific dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) + +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") diff --git a/covas_mobile_new/linux/runner/main.cc b/covas_mobile_new/linux/runner/main.cc new file mode 100644 index 0000000..e7c5c54 --- /dev/null +++ b/covas_mobile_new/linux/runner/main.cc @@ -0,0 +1,6 @@ +#include "my_application.h" + +int main(int argc, char** argv) { + g_autoptr(MyApplication) app = my_application_new(); + return g_application_run(G_APPLICATION(app), argc, argv); +} diff --git a/covas_mobile_new/linux/runner/my_application.cc b/covas_mobile_new/linux/runner/my_application.cc new file mode 100644 index 0000000..c3078e1 --- /dev/null +++ b/covas_mobile_new/linux/runner/my_application.cc @@ -0,0 +1,144 @@ +#include "my_application.h" + +#include +#ifdef GDK_WINDOWING_X11 +#include +#endif + +#include "flutter/generated_plugin_registrant.h" + +struct _MyApplication { + GtkApplication parent_instance; + char** dart_entrypoint_arguments; +}; + +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) + +// Called when first Flutter frame received. +static void first_frame_cb(MyApplication* self, FlView *view) +{ + gtk_widget_show(gtk_widget_get_toplevel(GTK_WIDGET(view))); +} + +// Implements GApplication::activate. +static void my_application_activate(GApplication* application) { + MyApplication* self = MY_APPLICATION(application); + GtkWindow* window = + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + + // Use a header bar when running in GNOME as this is the common style used + // by applications and is the setup most users will be using (e.g. Ubuntu + // desktop). + // If running on X and not using GNOME then just use a traditional title bar + // in case the window manager does more exotic layout, e.g. tiling. + // If running on Wayland assume the header bar will work (may need changing + // if future cases occur). + gboolean use_header_bar = TRUE; +#ifdef GDK_WINDOWING_X11 + GdkScreen* screen = gtk_window_get_screen(window); + if (GDK_IS_X11_SCREEN(screen)) { + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { + use_header_bar = FALSE; + } + } +#endif + if (use_header_bar) { + GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); + gtk_widget_show(GTK_WIDGET(header_bar)); + gtk_header_bar_set_title(header_bar, "covas_mobile_new"); + gtk_header_bar_set_show_close_button(header_bar, TRUE); + gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); + } else { + gtk_window_set_title(window, "covas_mobile_new"); + } + + gtk_window_set_default_size(window, 1280, 720); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); + + FlView* view = fl_view_new(project); + GdkRGBA background_color; + // Background defaults to black, override it here if necessary, e.g. #00000000 for transparent. + gdk_rgba_parse(&background_color, "#000000"); + fl_view_set_background_color(view, &background_color); + gtk_widget_show(GTK_WIDGET(view)); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + + // Show the window when Flutter renders. + // Requires the view to be realized so we can start rendering. + g_signal_connect_swapped(view, "first-frame", G_CALLBACK(first_frame_cb), self); + gtk_widget_realize(GTK_WIDGET(view)); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus(GTK_WIDGET(view)); +} + +// Implements GApplication::local_command_line. +static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { + MyApplication* self = MY_APPLICATION(application); + // Strip out the first argument as it is the binary name. + self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); + + g_autoptr(GError) error = nullptr; + if (!g_application_register(application, nullptr, &error)) { + g_warning("Failed to register: %s", error->message); + *exit_status = 1; + return TRUE; + } + + g_application_activate(application); + *exit_status = 0; + + return TRUE; +} + +// Implements GApplication::startup. +static void my_application_startup(GApplication* application) { + //MyApplication* self = MY_APPLICATION(object); + + // Perform any actions required at application startup. + + G_APPLICATION_CLASS(my_application_parent_class)->startup(application); +} + +// Implements GApplication::shutdown. +static void my_application_shutdown(GApplication* application) { + //MyApplication* self = MY_APPLICATION(object); + + // Perform any actions required at application shutdown. + + G_APPLICATION_CLASS(my_application_parent_class)->shutdown(application); +} + +// Implements GObject::dispose. +static void my_application_dispose(GObject* object) { + MyApplication* self = MY_APPLICATION(object); + g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); + G_OBJECT_CLASS(my_application_parent_class)->dispose(object); +} + +static void my_application_class_init(MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = my_application_activate; + G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; + G_APPLICATION_CLASS(klass)->startup = my_application_startup; + G_APPLICATION_CLASS(klass)->shutdown = my_application_shutdown; + G_OBJECT_CLASS(klass)->dispose = my_application_dispose; +} + +static void my_application_init(MyApplication* self) {} + +MyApplication* my_application_new() { + // Set the program name to the application ID, which helps various systems + // like GTK and desktop environments map this running application to its + // corresponding .desktop file. This ensures better integration by allowing + // the application to be recognized beyond its binary name. + g_set_prgname(APPLICATION_ID); + + return MY_APPLICATION(g_object_new(my_application_get_type(), + "application-id", APPLICATION_ID, + "flags", G_APPLICATION_NON_UNIQUE, + nullptr)); +} diff --git a/covas_mobile_new/linux/runner/my_application.h b/covas_mobile_new/linux/runner/my_application.h new file mode 100644 index 0000000..72271d5 --- /dev/null +++ b/covas_mobile_new/linux/runner/my_application.h @@ -0,0 +1,18 @@ +#ifndef FLUTTER_MY_APPLICATION_H_ +#define FLUTTER_MY_APPLICATION_H_ + +#include + +G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, + GtkApplication) + +/** + * my_application_new: + * + * Creates a new Flutter-based application. + * + * Returns: a new #MyApplication. + */ +MyApplication* my_application_new(); + +#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/covas_mobile_new/macos/.gitignore b/covas_mobile_new/macos/.gitignore new file mode 100644 index 0000000..746adbb --- /dev/null +++ b/covas_mobile_new/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/covas_mobile_new/macos/Flutter/Flutter-Debug.xcconfig b/covas_mobile_new/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 0000000..c2efd0b --- /dev/null +++ b/covas_mobile_new/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/covas_mobile_new/macos/Flutter/Flutter-Release.xcconfig b/covas_mobile_new/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 0000000..c2efd0b --- /dev/null +++ b/covas_mobile_new/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/covas_mobile_new/macos/Flutter/GeneratedPluginRegistrant.swift b/covas_mobile_new/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 0000000..c21fe97 --- /dev/null +++ b/covas_mobile_new/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,24 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + +import file_selector_macos +import flutter_local_notifications +import geolocator_apple +import path_provider_foundation +import shared_preferences_foundation +import url_launcher_macos +import webview_flutter_wkwebview + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) + FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) + GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) + SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) + WebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "WebViewFlutterPlugin")) +} diff --git a/covas_mobile_new/macos/Runner.xcodeproj/project.pbxproj b/covas_mobile_new/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..ecfec27 --- /dev/null +++ b/covas_mobile_new/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,705 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC10EC2044A3C60003C045; + remoteInfo = Runner; + }; + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* covas_mobile_new.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "covas_mobile_new.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 331C80D2294CF70F00263BE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C80D6294CF71000263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C80D7294CF71000263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 331C80D6294CF71000263BE5 /* RunnerTests */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* covas_mobile_new.app */, + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C80D4294CF70F00263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C80D1294CF70F00263BE5 /* Sources */, + 331C80D2294CF70F00263BE5 /* Frameworks */, + 331C80D3294CF70F00263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C80DA294CF71000263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* covas_mobile_new.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C80D4294CF70F00263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 33CC10EC2044A3C60003C045; + }; + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 331C80D4294CF70F00263BE5 /* RunnerTests */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C80D3294CF70F00263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C80D1294CF70F00263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC10EC2044A3C60003C045 /* Runner */; + targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; + }; + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 331C80DB294CF71000263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/covas_mobile_new.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/covas_mobile_new"; + }; + name = Debug; + }; + 331C80DC294CF71000263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/covas_mobile_new.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/covas_mobile_new"; + }; + name = Release; + }; + 331C80DD294CF71000263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/covas_mobile_new.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/covas_mobile_new"; + }; + name = Profile; + }; + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C80DB294CF71000263BE5 /* Debug */, + 331C80DC294CF71000263BE5 /* Release */, + 331C80DD294CF71000263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/covas_mobile_new/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/covas_mobile_new/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/covas_mobile_new/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/covas_mobile_new/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/covas_mobile_new/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..885bc64 --- /dev/null +++ b/covas_mobile_new/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/covas_mobile_new/macos/Runner.xcworkspace/contents.xcworkspacedata b/covas_mobile_new/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/covas_mobile_new/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/covas_mobile_new/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/covas_mobile_new/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/covas_mobile_new/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/covas_mobile_new/macos/Runner/AppDelegate.swift b/covas_mobile_new/macos/Runner/AppDelegate.swift new file mode 100644 index 0000000..b3c1761 --- /dev/null +++ b/covas_mobile_new/macos/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import Cocoa +import FlutterMacOS + +@main +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } +} diff --git a/covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a2ec33f --- /dev/null +++ b/covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 0000000000000000000000000000000000000000..82b6f9d9a33e198f5747104729e1fcef999772a5 GIT binary patch literal 102994 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ⅅ8MglG&ER{i5lN315cO?EdHNLrg? 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 z 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 Pe7HEdAEg|=c=LY&YVNkY literal 0 HcmV?d00001 diff --git a/covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 0000000000000000000000000000000000000000..13b35eba55c6dabc3aac36f33d859266c18fa0d0 GIT binary patch literal 5680 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 literal 0 HcmV?d00001 diff --git a/covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 0000000000000000000000000000000000000000..0a3f5fa40fb3d1e0710331a48de5d256da3f275d GIT binary patch literal 520 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 literal 0 HcmV?d00001 diff --git a/covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/covas_mobile_new/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 0000000000000000000000000000000000000000..2f1632cfddf3d9dade342351e627a0a75609fb46 GIT binary patch literal 2218 zcmV;b2vzrqP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91K%fHv1ONa40RR91KmY&$07g+lumAuE6iGxuRCodHTWf3-RTMruyW6Fu zQYeUM04eX6D5c0FCjKKPrco1(K`<0SL=crI{PC3-^hZU0kQie$gh-5!7z6SH6Q0J% zqot*`H1q{R5fHFYS}dje@;kG=v$L0(yY0?wY2%*c?A&{2?!D*x?m71{of2gv!$5|C z3>qG_BW}7K_yUcT3A5C6QD<+{aq?x;MAUyAiJn#Jv8_zZtQ{P zTRzbL3U9!qVuZzS$xKU10KiW~Bgdcv1-!uAhQxf3a7q+dU6lj?yoO4Lq4TUN4}h{N z*fIM=SS8|C2$(T>w$`t@3Tka!(r!7W`x z-isCVgQD^mG-MJ;XtJuK3V{Vy72GQ83KRWsHU?e*wrhKk=ApIYeDqLi;JI1e zuvv}5^Dc=k7F7?nm3nIw$NVmU-+R>> zyqOR$-2SDpJ}Pt;^RkJytDVXNTsu|mI1`~G7yw`EJR?VkGfNdqK9^^8P`JdtTV&tX4CNcV4 z&N06nZa??Fw1AgQOUSE2AmPE@WO(Fvo`%m`cDgiv(fAeRA%3AGXUbsGw{7Q`cY;1BI#ac3iN$$Hw z0LT0;xc%=q)me?Y*$xI@GRAw?+}>=9D+KTk??-HJ4=A>`V&vKFS75@MKdSF1JTq{S zc1!^8?YA|t+uKigaq!sT;Z!&0F2=k7F0PIU;F$leJLaw2UI6FL^w}OG&!;+b%ya1c z1n+6-inU<0VM-Y_s5iTElq)ThyF?StVcebpGI znw#+zLx2@ah{$_2jn+@}(zJZ{+}_N9BM;z)0yr|gF-4=Iyu@hI*Lk=-A8f#bAzc9f z`Kd6K--x@t04swJVC3JK1cHY-Hq+=|PN-VO;?^_C#;coU6TDP7Bt`;{JTG;!+jj(` zw5cLQ-(Cz-Tlb`A^w7|R56Ce;Wmr0)$KWOUZ6ai0PhzPeHwdl0H(etP zUV`va_i0s-4#DkNM8lUlqI7>YQLf)(lz9Q3Uw`)nc(z3{m5ZE77Ul$V%m)E}3&8L0 z-XaU|eB~Is08eORPk;=<>!1w)Kf}FOVS2l&9~A+@R#koFJ$Czd%Y(ENTV&A~U(IPI z;UY+gf+&6ioZ=roly<0Yst8ck>(M=S?B-ys3mLdM&)ex!hbt+ol|T6CTS+Sc0jv(& z7ijdvFwBq;0a{%3GGwkDKTeG`b+lyj0jjS1OMkYnepCdoosNY`*zmBIo*981BU%%U z@~$z0V`OVtIbEx5pa|Tct|Lg#ZQf5OYMUMRD>Wdxm5SAqV2}3!ceE-M2 z@O~lQ0OiKQp}o9I;?uxCgYVV?FH|?Riri*U$Zi_`V2eiA>l zdSm6;SEm6#T+SpcE8Ro_f2AwxzI z44hfe^WE3!h@W3RDyA_H440cpmYkv*)6m1XazTqw%=E5Xv7^@^^T7Q2wxr+Z2kVYr + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/covas_mobile_new/macos/Runner/Configs/AppInfo.xcconfig b/covas_mobile_new/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000..ef8d611 --- /dev/null +++ b/covas_mobile_new/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = covas_mobile_new + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2025 com.example. All rights reserved. diff --git a/covas_mobile_new/macos/Runner/Configs/Debug.xcconfig b/covas_mobile_new/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000..36b0fd9 --- /dev/null +++ b/covas_mobile_new/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/covas_mobile_new/macos/Runner/Configs/Release.xcconfig b/covas_mobile_new/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000..dff4f49 --- /dev/null +++ b/covas_mobile_new/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/covas_mobile_new/macos/Runner/Configs/Warnings.xcconfig b/covas_mobile_new/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000..42bcbf4 --- /dev/null +++ b/covas_mobile_new/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/covas_mobile_new/macos/Runner/DebugProfile.entitlements b/covas_mobile_new/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000..dddb8a3 --- /dev/null +++ b/covas_mobile_new/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/covas_mobile_new/macos/Runner/Info.plist b/covas_mobile_new/macos/Runner/Info.plist new file mode 100644 index 0000000..4789daa --- /dev/null +++ b/covas_mobile_new/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/covas_mobile_new/macos/Runner/MainFlutterWindow.swift b/covas_mobile_new/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000..3cc05eb --- /dev/null +++ b/covas_mobile_new/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/covas_mobile_new/macos/Runner/Release.entitlements b/covas_mobile_new/macos/Runner/Release.entitlements new file mode 100644 index 0000000..852fa1a --- /dev/null +++ b/covas_mobile_new/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/covas_mobile_new/macos/RunnerTests/RunnerTests.swift b/covas_mobile_new/macos/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..61f3bd1 --- /dev/null +++ b/covas_mobile_new/macos/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Cocoa +import FlutterMacOS +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/covas_mobile_new/pubspec.lock b/covas_mobile_new/pubspec.lock new file mode 100644 index 0000000..efb6d40 --- /dev/null +++ b/covas_mobile_new/pubspec.lock @@ -0,0 +1,1111 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + args: + dependency: transitive + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.dev" + source: hosted + version: "2.7.0" + asn1lib: + dependency: transitive + description: + name: asn1lib + sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024" + url: "https://pub.dev" + source: hosted + version: "1.6.5" + async: + dependency: transitive + description: + name: async + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + url: "https://pub.dev" + source: hosted + version: "2.13.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + camera: + dependency: "direct main" + description: + name: camera + sha256: d6ec2cbdbe2fa8f5e0d07d8c06368fe4effa985a4a5ddade9cc58a8cd849557d + url: "https://pub.dev" + source: hosted + version: "0.11.2" + camera_android_camerax: + dependency: transitive + description: + name: camera_android_camerax + sha256: "2d438248554f44766bf9ea34c117a5bb0074e241342ef7c22c768fb431335234" + url: "https://pub.dev" + source: hosted + version: "0.6.21" + 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: "2f757024a48696ff4814a789b0bd90f5660c0fb25f393ab4564fb483327930e2" + url: "https://pub.dev" + source: hosted + version: "2.10.0" + camera_web: + dependency: "direct main" + description: + name: camera_web + sha256: "595f28c89d1fb62d77c73c633193755b781c6d2e0ebcd8dc25b763b514e6ba8f" + url: "https://pub.dev" + source: hosted + version: "0.3.5" + characters: + dependency: transitive + description: + name: characters + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + clock: + dependency: transitive + description: + name: clock + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + url: "https://pub.dev" + source: hosted + version: "1.1.2" + collection: + dependency: transitive + description: + name: collection + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.dev" + source: hosted + version: "1.19.1" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" + url: "https://pub.dev" + source: hosted + version: "0.3.4+2" + crypto: + dependency: transitive + description: + name: crypto + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + url: "https://pub.dev" + source: hosted + version: "3.0.6" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + url: "https://pub.dev" + source: hosted + version: "1.0.8" + date_format_field: + dependency: "direct main" + description: + name: date_format_field + sha256: d07a428bd253454ff3123f2e57511cf6ec101d1135af3b79cebb40e1bee8bab8 + url: "https://pub.dev" + source: hosted + version: "0.1.0" + dbus: + dependency: transitive + description: + name: dbus + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" + url: "https://pub.dev" + source: hosted + version: "0.7.11" + devtools_shared: + dependency: transitive + description: + name: devtools_shared + sha256: "659e2d65aa5ef5c3551163811c5c6fa1b973b3df80d8cac6f618035edcdc1096" + url: "https://pub.dev" + source: hosted + version: "11.2.1" + dio: + dependency: transitive + description: + name: dio + sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9 + url: "https://pub.dev" + source: hosted + version: "5.9.0" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + dtd: + dependency: transitive + description: + name: dtd + sha256: "14a0360d898ded87c3d99591fc386b8a6ea5d432927bee709b22130cd25b993a" + url: "https://pub.dev" + source: hosted + version: "2.5.1" + encrypt: + dependency: transitive + description: + name: encrypt + sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" + url: "https://pub.dev" + source: hosted + version: "5.0.3" + encrypt_shared_preferences: + dependency: "direct main" + description: + name: encrypt_shared_preferences + sha256: "9be57e1f224d6f4353bdfa79de16b364ec7dddf38840c3288c547f262e50bbad" + url: "https://pub.dev" + source: hosted + version: "0.8.9" + extension_discovery: + dependency: transitive + description: + name: extension_discovery + sha256: de1fce715ab013cdfb00befc3bdf0914bea5e409c3a567b7f8f144bc061611a7 + url: "https://pub.dev" + source: hosted + version: "2.1.0" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + ffi: + dependency: transitive + description: + name: ffi + sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" + 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_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b" + url: "https://pub.dev" + source: hosted + version: "0.9.3+4" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + url: "https://pub.dev" + source: hosted + version: "1.1.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_dotenv: + dependency: "direct main" + description: + name: flutter_dotenv + sha256: b7c7be5cd9f6ef7a78429cabd2774d3c4af50e79cb2b7593e3d5d763ef95c61b + url: "https://pub.dev" + source: hosted + version: "5.2.1" + flutter_gemini: + dependency: "direct main" + description: + name: flutter_gemini + sha256: "993765fafb595e5d32153f393b9c5e71f853caa5bef123d292c21f672d2b9675" + url: "https://pub.dev" + source: hosted + version: "2.0.5" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + flutter_local_notifications: + dependency: "direct main" + description: + name: flutter_local_notifications + sha256: "674173fd3c9eda9d4c8528da2ce0ea69f161577495a9cc835a2a4ecd7eadeb35" + url: "https://pub.dev" + source: hosted + version: "17.2.4" + flutter_local_notifications_linux: + dependency: transitive + description: + name: flutter_local_notifications_linux + sha256: c49bd06165cad9beeb79090b18cd1eb0296f4bf4b23b84426e37dd7c027fc3af + url: "https://pub.dev" + source: hosted + version: "4.0.1" + flutter_local_notifications_platform_interface: + dependency: transitive + description: + name: flutter_local_notifications_platform_interface + sha256: "85f8d07fe708c1bdcf45037f2c0109753b26ae077e9d9e899d55971711a4ea66" + url: "https://pub.dev" + source: hosted + version: "7.2.0" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: b0694b7fb1689b0e6cc193b3f1fcac6423c4f93c74fb20b806c6b6f196db0c31 + url: "https://pub.dev" + source: hosted + version: "2.0.30" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + freezed_annotation: + dependency: transitive + description: + name: freezed_annotation + sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 + url: "https://pub.dev" + source: hosted + version: "2.4.4" + geolocator: + dependency: "direct main" + description: + name: geolocator + sha256: f62bcd90459e63210bbf9c35deb6a51c521f992a78de19a1fe5c11704f9530e2 + url: "https://pub.dev" + source: hosted + version: "13.0.4" + geolocator_android: + dependency: transitive + description: + name: geolocator_android + sha256: fcb1760a50d7500deca37c9a666785c047139b5f9ee15aa5469fae7dbbe3170d + url: "https://pub.dev" + source: hosted + version: "4.6.2" + geolocator_apple: + dependency: transitive + description: + name: geolocator_apple + sha256: dbdd8789d5aaf14cf69f74d4925ad1336b4433a6efdf2fce91e8955dc921bf22 + url: "https://pub.dev" + source: hosted + version: "2.3.13" + geolocator_platform_interface: + dependency: transitive + description: + name: geolocator_platform_interface + sha256: "30cb64f0b9adcc0fb36f628b4ebf4f731a2961a0ebd849f4b56200205056fe67" + url: "https://pub.dev" + source: hosted + version: "4.2.6" + geolocator_web: + dependency: transitive + description: + name: geolocator_web + sha256: b1ae9bdfd90f861fde8fd4f209c37b953d65e92823cb73c7dee1fa021b06f172 + url: "https://pub.dev" + source: hosted + version: "4.1.3" + geolocator_windows: + dependency: transitive + description: + name: geolocator_windows + sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6" + url: "https://pub.dev" + source: hosted + version: "0.2.5" + google_mobile_ads: + dependency: "direct main" + description: + name: google_mobile_ads + sha256: "0d4a3744b5e8ed1b8be6a1b452d309f811688855a497c6113fc4400f922db603" + url: "https://pub.dev" + source: hosted + version: "5.3.1" + http: + dependency: "direct main" + description: + name: http + sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007 + url: "https://pub.dev" + source: hosted + version: "1.5.0" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" + image_picker: + dependency: "direct main" + 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: "9f143b0dba3e459553209e20cc425c9801af48e6dfa4f01a0fcf927be3f41665" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + 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: + name: intl + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + url: "https://pub.dev" + source: hosted + version: "0.20.2" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" + json_rpc_2: + dependency: transitive + description: + name: json_rpc_2 + sha256: "246b321532f0e8e2ba474b4d757eaa558ae4fdd0688fdbc1e1ca9705f9b8ca0e" + url: "https://pub.dev" + source: hosted + version: "3.0.3" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" + url: "https://pub.dev" + source: hosted + version: "11.0.1" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + url: "https://pub.dev" + source: hosted + version: "3.0.10" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + lints: + dependency: transitive + description: + name: lints + sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + url: "https://pub.dev" + source: hosted + version: "0.12.17" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + meta: + dependency: transitive + description: + name: meta + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + url: "https://pub.dev" + source: hosted + version: "1.16.0" + mime: + dependency: transitive + description: + name: mime + sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" + url: "https://pub.dev" + source: hosted + version: "1.0.6" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + path: + dependency: "direct main" + description: + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + path_provider: + dependency: "direct main" + description: + name: path_provider + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db" + url: "https://pub.dev" + source: hosted + version: "2.2.18" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849" + url: "https://pub.dev" + source: hosted + version: "11.4.0" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc + url: "https://pub.dev" + source: hosted + version: "12.1.0" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023 + url: "https://pub.dev" + source: hosted + version: "9.4.7" + permission_handler_html: + dependency: transitive + description: + name: permission_handler_html + sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" + url: "https://pub.dev" + source: hosted + version: "0.1.3+5" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878 + url: "https://pub.dev" + source: hosted + version: "4.3.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" + url: "https://pub.dev" + source: hosted + version: "0.2.1" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1" + url: "https://pub.dev" + source: hosted + version: "7.0.1" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" + url: "https://pub.dev" + source: hosted + version: "3.9.1" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" + provider: + dependency: "direct main" + description: + name: provider + sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272" + url: "https://pub.dev" + source: hosted + version: "6.1.5+1" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" + url: "https://pub.dev" + source: hosted + version: "2.5.3" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: a2608114b1ffdcbc9c120eb71a0e207c71da56202852d4aab8a5e30a82269e74 + url: "https://pub.dev" + source: hosted + version: "2.4.12" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" + url: "https://pub.dev" + source: hosted + version: "2.5.4" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + url: "https://pub.dev" + source: hosted + version: "2.4.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shelf: + dependency: transitive + description: + name: shelf + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + url: "https://pub.dev" + source: hosted + version: "1.4.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + source_span: + dependency: transitive + description: + name: source_span + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + url: "https://pub.dev" + source: hosted + version: "1.10.1" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + sse: + dependency: transitive + description: + name: sse + sha256: fcc97470240bb37377f298e2bd816f09fd7216c07928641c0560719f50603643 + url: "https://pub.dev" + source: hosted + version: "4.1.8" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + url: "https://pub.dev" + source: hosted + version: "1.12.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 + url: "https://pub.dev" + source: hosted + version: "2.1.1" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.dev" + source: hosted + version: "1.2.2" + test_api: + dependency: transitive + description: + name: test_api + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + url: "https://pub.dev" + source: hosted + version: "0.7.6" + textfield_tags: + dependency: "direct main" + description: + name: textfield_tags + sha256: d1f2204114157a1296bb97c20d7f8c8c7fd036212812afb2e19de7bb34acc55b + url: "https://pub.dev" + source: hosted + version: "3.0.1" + timezone: + dependency: "direct main" + description: + name: timezone + sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d" + url: "https://pub.dev" + source: hosted + version: "0.9.4" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + unified_analytics: + dependency: transitive + description: + name: unified_analytics + sha256: "8d1429a4b27320a9c4fc854287d18c8fde1549bf622165c5837202a9f370b53d" + url: "https://pub.dev" + source: hosted + version: "8.0.5" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + url: "https://pub.dev" + source: hosted + version: "6.3.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "69ee86740f2847b9a4ba6cffa74ed12ce500bbe2b07f3dc1e643439da60637b7" + url: "https://pub.dev" + source: hosted + version: "6.3.18" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7 + url: "https://pub.dev" + source: hosted + version: "6.3.4" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f + url: "https://pub.dev" + source: hosted + version: "3.2.3" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" + url: "https://pub.dev" + source: hosted + version: "3.1.4" + uuid: + dependency: transitive + description: + name: uuid + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + url: "https://pub.dev" + source: hosted + version: "4.5.1" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + url: "https://pub.dev" + source: hosted + version: "2.2.0" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" + url: "https://pub.dev" + source: hosted + version: "15.0.2" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 + url: "https://pub.dev" + source: hosted + version: "3.0.3" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + webview_flutter: + dependency: transitive + description: + name: webview_flutter + sha256: c3e4fe614b1c814950ad07186007eff2f2e5dd2935eba7b9a9a1af8e5885f1ba + url: "https://pub.dev" + source: hosted + version: "4.13.0" + webview_flutter_android: + dependency: transitive + description: + name: webview_flutter_android + sha256: "9a25f6b4313978ba1c2cda03a242eea17848174912cfb4d2d8ee84a556f248e3" + url: "https://pub.dev" + source: hosted + version: "4.10.1" + webview_flutter_platform_interface: + dependency: transitive + description: + name: webview_flutter_platform_interface + sha256: "63d26ee3aca7256a83ccb576a50272edd7cfc80573a4305caa98985feb493ee0" + url: "https://pub.dev" + source: hosted + version: "2.14.0" + webview_flutter_wkwebview: + dependency: transitive + description: + name: webview_flutter_wkwebview + sha256: fb46db8216131a3e55bcf44040ca808423539bc6732e7ed34fb6d8044e3d512f + url: "https://pub.dev" + source: hosted + version: "3.23.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" + url: "https://pub.dev" + source: hosted + version: "6.6.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" + yaml_edit: + dependency: transitive + description: + name: yaml_edit + sha256: fb38626579fb345ad00e674e2af3a5c9b0cc4b9bfb8fd7f7ff322c7c9e62aef5 + url: "https://pub.dev" + source: hosted + version: "2.2.2" +sdks: + dart: ">=3.8.1 <4.0.0" + flutter: ">=3.32.8" diff --git a/covas_mobile_new/pubspec.yaml b/covas_mobile_new/pubspec.yaml new file mode 100644 index 0000000..6c86a73 --- /dev/null +++ b/covas_mobile_new/pubspec.yaml @@ -0,0 +1,117 @@ +name: covas_mobile +description: A new Flutter project. + +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.17.6 <3.0.0" + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + + + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + flutter_local_notifications: ^17.2.0 + timezone: ^0.9.4 + cupertino_icons: ^1.0.2 + http: ^1.2.1 + shared_preferences: ^2.2.3 + intl: ^0.20.2 + camera: ^0.11.0+1 + camera_web: ^0.3.3 + path_provider: ^2.1.3 + path: ^1.9.0 + flutter_gemini: ^2.0.4 + flutter_dotenv: ^5.1.0 + image_picker: ^1.1.2 + date_format_field: ^0.1.0 + textfield_tags: ^3.0.1 + geolocator: ^13.0.1 + permission_handler: ^11.3.1 + url_launcher: ^6.3.1 + google_mobile_ads: ^5.3.1 + encrypt_shared_preferences: ^0.8.8 + provider: ^6.1.2 # ou la dernière version + +dev_dependencies: + flutter_test: + sdk: flutter + + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^4.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + generate: true + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - images/flutter.png + - .env + - images/search.png + - images/marker.png + - images/marker-red.png + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/covas_mobile_new/test/widget_test.dart b/covas_mobile_new/test/widget_test.dart new file mode 100644 index 0000000..bcf0608 --- /dev/null +++ b/covas_mobile_new/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:covas_mobile_new/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/covas_mobile_new/web/favicon.png b/covas_mobile_new/web/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..8aaa46ac1ae21512746f852a42ba87e4165dfdd1 GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P(fs7NJL45ua8x7ey(0(N`6wRUPW#JP&EUCO@$SZnVVXYs8ErclUHn2 zVXFjIVFhG^g!Ppaz)DK8ZIvQ?0~DO|i&7O#^-S~(l1AfjnEK zjFOT9D}DX)@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7USFmqf|i<65o z3raHc^AtelCMM;Vme?vOfh>Xph&xL%(-1c06+^uR^q@XSM&D4+Kp$>4P^%3{)XKjo zGZknv$b36P8?Z_gF{nK@`XI}Z90TzwSQO}0J1!f2c(B=V`5aP@1P1a|PZ!4!3&Gl8 zTYqUsf!gYFyJnXpu0!n&N*SYAX-%d(5gVjrHJWqXQshj@!Zm{!01WsQrH~9=kTxW#6SvuapgMqt>$=j#%eyGrQzr zP{L-3gsMA^$I1&gsBAEL+vxi1*Igl=8#8`5?A-T5=z-sk46WA1IUT)AIZHx1rdUrf zVJrJn<74DDw`j)Ki#gt}mIT-Q`XRa2-jQXQoI%w`nb|XblvzK${ZzlV)m-XcwC(od z71_OEC5Bt9GEXosOXaPTYOia#R4ID2TiU~`zVMl08TV_C%DnU4^+HE>9(CE4D6?Fz oujB08i7adh9xk7*FX66dWH6F5TM;?E2b5PlUHx3vIVCg!0Dx9vYXATM literal 0 HcmV?d00001 diff --git a/covas_mobile_new/web/icons/Icon-192.png b/covas_mobile_new/web/icons/Icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..b749bfef07473333cf1dd31e9eed89862a5d52aa GIT binary patch literal 5292 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 literal 0 HcmV?d00001 diff --git a/covas_mobile_new/web/icons/Icon-512.png b/covas_mobile_new/web/icons/Icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..88cfd48dff1169879ba46840804b412fe02fefd6 GIT binary patch literal 8252 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 literal 0 HcmV?d00001 diff --git a/covas_mobile_new/web/icons/Icon-maskable-192.png b/covas_mobile_new/web/icons/Icon-maskable-192.png new file mode 100644 index 0000000000000000000000000000000000000000..eb9b4d76e525556d5d89141648c724331630325d GIT binary patch literal 5594 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 X>c!)3PgKfL&lX^$Z>Cpu&6)6jvi^Z! literal 0 HcmV?d00001 diff --git a/covas_mobile_new/web/icons/Icon-maskable-512.png b/covas_mobile_new/web/icons/Icon-maskable-512.png new file mode 100644 index 0000000000000000000000000000000000000000..d69c56691fbdb0b7efa65097c7cc1edac12a6d3e GIT binary patch literal 20998 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 MPgg&ebxsLQ025IeI{*Lx literal 0 HcmV?d00001 diff --git a/covas_mobile_new/web/index.html b/covas_mobile_new/web/index.html new file mode 100644 index 0000000..5a3c0f3 --- /dev/null +++ b/covas_mobile_new/web/index.html @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + covas_mobile_new + + + + + + diff --git a/covas_mobile_new/web/manifest.json b/covas_mobile_new/web/manifest.json new file mode 100644 index 0000000..2c93bd6 --- /dev/null +++ b/covas_mobile_new/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "covas_mobile_new", + "short_name": "covas_mobile_new", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/covas_mobile_new/windows/.gitignore b/covas_mobile_new/windows/.gitignore new file mode 100644 index 0000000..d492d0d --- /dev/null +++ b/covas_mobile_new/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/covas_mobile_new/windows/CMakeLists.txt b/covas_mobile_new/windows/CMakeLists.txt new file mode 100644 index 0000000..ddf4ff7 --- /dev/null +++ b/covas_mobile_new/windows/CMakeLists.txt @@ -0,0 +1,108 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.14) +project(covas_mobile_new LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "covas_mobile_new") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(VERSION 3.14...3.25) + +# Define build configuration option. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() +# Define settings for the Profile build mode. +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") + + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/covas_mobile_new/windows/flutter/CMakeLists.txt b/covas_mobile_new/windows/flutter/CMakeLists.txt new file mode 100644 index 0000000..903f489 --- /dev/null +++ b/covas_mobile_new/windows/flutter/CMakeLists.txt @@ -0,0 +1,109 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.14) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# Set fallback configurations for older versions of the flutter tool. +if (NOT DEFINED FLUTTER_TARGET_PLATFORM) + set(FLUTTER_TARGET_PLATFORM "windows-x64") +endif() + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + ${FLUTTER_TARGET_PLATFORM} $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/covas_mobile_new/windows/flutter/generated_plugin_registrant.cc b/covas_mobile_new/windows/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000..b2cbd25 --- /dev/null +++ b/covas_mobile_new/windows/flutter/generated_plugin_registrant.cc @@ -0,0 +1,23 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + +#include +#include +#include +#include + +void RegisterPlugins(flutter::PluginRegistry* registry) { + FileSelectorWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FileSelectorWindows")); + GeolocatorWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("GeolocatorWindows")); + PermissionHandlerWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); + UrlLauncherWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("UrlLauncherWindows")); +} diff --git a/covas_mobile_new/windows/flutter/generated_plugin_registrant.h b/covas_mobile_new/windows/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000..dc139d8 --- /dev/null +++ b/covas_mobile_new/windows/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/covas_mobile_new/windows/flutter/generated_plugins.cmake b/covas_mobile_new/windows/flutter/generated_plugins.cmake new file mode 100644 index 0000000..92c9a0d --- /dev/null +++ b/covas_mobile_new/windows/flutter/generated_plugins.cmake @@ -0,0 +1,27 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + file_selector_windows + geolocator_windows + permission_handler_windows + url_launcher_windows +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/covas_mobile_new/windows/runner/CMakeLists.txt b/covas_mobile_new/windows/runner/CMakeLists.txt new file mode 100644 index 0000000..394917c --- /dev/null +++ b/covas_mobile_new/windows/runner/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.14) +project(runner LANGUAGES CXX) + +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add preprocessor definitions for the build version. +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") + +# Disable Windows macros that collide with C++ standard library functions. +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") + +# Add dependency libraries and include directories. Add any application-specific +# dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/covas_mobile_new/windows/runner/Runner.rc b/covas_mobile_new/windows/runner/Runner.rc new file mode 100644 index 0000000..88c9d3d --- /dev/null +++ b/covas_mobile_new/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) +#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD +#else +#define VERSION_AS_NUMBER 1,0,0,0 +#endif + +#if defined(FLUTTER_VERSION) +#define VERSION_AS_STRING FLUTTER_VERSION +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "com.example" "\0" + VALUE "FileDescription", "covas_mobile_new" "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "covas_mobile_new" "\0" + VALUE "LegalCopyright", "Copyright (C) 2025 com.example. All rights reserved." "\0" + VALUE "OriginalFilename", "covas_mobile_new.exe" "\0" + VALUE "ProductName", "covas_mobile_new" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/covas_mobile_new/windows/runner/flutter_window.cpp b/covas_mobile_new/windows/runner/flutter_window.cpp new file mode 100644 index 0000000..955ee30 --- /dev/null +++ b/covas_mobile_new/windows/runner/flutter_window.cpp @@ -0,0 +1,71 @@ +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + + flutter_controller_->engine()->SetNextFrameCallback([&]() { + this->Show(); + }); + + // Flutter can complete the first frame before the "show window" callback is + // registered. The following call ensures a frame is pending to ensure the + // window is shown. It is a no-op if the first frame hasn't completed yet. + flutter_controller_->ForceRedraw(); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opportunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/covas_mobile_new/windows/runner/flutter_window.h b/covas_mobile_new/windows/runner/flutter_window.h new file mode 100644 index 0000000..6da0652 --- /dev/null +++ b/covas_mobile_new/windows/runner/flutter_window.h @@ -0,0 +1,33 @@ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/covas_mobile_new/windows/runner/main.cpp b/covas_mobile_new/windows/runner/main.cpp new file mode 100644 index 0000000..615f2cc --- /dev/null +++ b/covas_mobile_new/windows/runner/main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "flutter_window.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.Create(L"covas_mobile_new", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/covas_mobile_new/windows/runner/resource.h b/covas_mobile_new/windows/runner/resource.h new file mode 100644 index 0000000..66a65d1 --- /dev/null +++ b/covas_mobile_new/windows/runner/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/covas_mobile_new/windows/runner/resources/app_icon.ico b/covas_mobile_new/windows/runner/resources/app_icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c04e20caf6370ebb9253ad831cc31de4a9c965f6 GIT binary patch literal 33772 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 literal 0 HcmV?d00001 diff --git a/covas_mobile_new/windows/runner/runner.exe.manifest b/covas_mobile_new/windows/runner/runner.exe.manifest new file mode 100644 index 0000000..153653e --- /dev/null +++ b/covas_mobile_new/windows/runner/runner.exe.manifest @@ -0,0 +1,14 @@ + + + + + PerMonitorV2 + + + + + + + + + diff --git a/covas_mobile_new/windows/runner/utils.cpp b/covas_mobile_new/windows/runner/utils.cpp new file mode 100644 index 0000000..3a0b465 --- /dev/null +++ b/covas_mobile_new/windows/runner/utils.cpp @@ -0,0 +1,65 @@ +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + unsigned int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr) + -1; // remove the trailing null character + int input_length = (int)wcslen(utf16_string); + std::string utf8_string; + if (target_length == 0 || target_length > utf8_string.max_size()) { + return utf8_string; + } + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + input_length, utf8_string.data(), target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} diff --git a/covas_mobile_new/windows/runner/utils.h b/covas_mobile_new/windows/runner/utils.h new file mode 100644 index 0000000..3879d54 --- /dev/null +++ b/covas_mobile_new/windows/runner/utils.h @@ -0,0 +1,19 @@ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ diff --git a/covas_mobile_new/windows/runner/win32_window.cpp b/covas_mobile_new/windows/runner/win32_window.cpp new file mode 100644 index 0000000..60608d0 --- /dev/null +++ b/covas_mobile_new/windows/runner/win32_window.cpp @@ -0,0 +1,288 @@ +#include "win32_window.h" + +#include +#include + +#include "resource.h" + +namespace { + +/// Window attribute that enables dark mode window decorations. +/// +/// Redefined in case the developer's machine has a Windows SDK older than +/// version 10.0.22000.0. +/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +/// Registry key for app theme preference. +/// +/// A value of 0 indicates apps should use dark mode. A non-zero or missing +/// value indicates apps should use light mode. +constexpr const wchar_t kGetPreferredBrightnessRegKey[] = + L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; +constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + } + FreeLibrary(user32_module); +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registrar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::Create(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + UpdateTheme(window); + + return OnCreate(); +} + +bool Win32Window::Show() { + return ShowWindow(window_handle_, SW_SHOWNORMAL); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + + case WM_DWMCOLORIZATIONCOLORCHANGED: + UpdateTheme(hwnd); + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} + +void Win32Window::UpdateTheme(HWND const window) { + DWORD light_mode; + DWORD light_mode_size = sizeof(light_mode); + LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, + kGetPreferredBrightnessRegValue, + RRF_RT_REG_DWORD, nullptr, &light_mode, + &light_mode_size); + + if (result == ERROR_SUCCESS) { + BOOL enable_dark_mode = light_mode == 0; + DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, + &enable_dark_mode, sizeof(enable_dark_mode)); + } +} diff --git a/covas_mobile_new/windows/runner/win32_window.h b/covas_mobile_new/windows/runner/win32_window.h new file mode 100644 index 0000000..e901dde --- /dev/null +++ b/covas_mobile_new/windows/runner/win32_window.h @@ -0,0 +1,102 @@ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates a win32 window with |title| that is positioned and sized using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size this function will scale the inputted width and height as + // as appropriate for the default monitor. The window is invisible until + // |Show| is called. Returns true if the window was created successfully. + bool Create(const std::wstring& title, const Point& origin, const Size& size); + + // Show the current window. Returns true if the window was successfully shown. + bool Show(); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + // Update the window frame's theme to match the system theme. + static void UpdateTheme(HWND const window); + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_ From 2f74f5ed78f62bce510269e701d39e791b3dd821 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sun, 31 Aug 2025 18:22:40 +0200 Subject: [PATCH 02/16] fix applocalizations --- covas_mobile_new/.env | 7 + covas_mobile_new/debug | 1 + covas_mobile_new/l10n.yaml | 5 + covas_mobile_new/lib/classes/MyDrawer.dart | 2 +- .../lib/classes/notification_service.dart | 4 +- .../{l10n => gen_l10n}/app_localizations.dart | 2 +- .../app_localizations_de.dart | 0 .../app_localizations_en.dart | 0 .../app_localizations_fr.dart | 0 covas_mobile_new/lib/main.dart | 2 +- covas_mobile_new/lib/pages/AddProfile.dart | 2 +- covas_mobile_new/lib/pages/Camera.dart | 2 +- covas_mobile_new/lib/pages/CameraEdit.dart | 2 +- .../lib/pages/DisplayPictureScreen.dart | 2 +- covas_mobile_new/lib/pages/EditEvent.dart | 2 +- covas_mobile_new/lib/pages/EditProfile.dart | 2 +- covas_mobile_new/lib/pages/EditSettings.dart | 2 +- .../lib/pages/ForgotPassword.dart | 2 +- covas_mobile_new/lib/pages/ItemMenu.dart | 2 +- .../lib/pages/ListItemByOrganizers.dart | 2 +- .../lib/pages/ListItemByTags.dart | 2 +- covas_mobile_new/lib/pages/ListItemMenu.dart | 2 +- covas_mobile_new/lib/pages/LoginDemo.dart | 2 +- covas_mobile_new/lib/pages/MapboxPages.dart | 2 +- .../lib/pages/UpdateEventImage.dart | 2 +- .../Flutter/GeneratedPluginRegistrant.swift | 2 + covas_mobile_new/pubspec.lock | 192 ++++++++++++++---- covas_mobile_new/pubspec.yaml | 23 ++- .../windows/flutter/generated_plugins.cmake | 1 + 29 files changed, 203 insertions(+), 68 deletions(-) create mode 100644 covas_mobile_new/.env create mode 100644 covas_mobile_new/debug create mode 100644 covas_mobile_new/l10n.yaml rename covas_mobile_new/lib/{l10n => gen_l10n}/app_localizations.dart (99%) rename covas_mobile_new/lib/{l10n => gen_l10n}/app_localizations_de.dart (100%) rename covas_mobile_new/lib/{l10n => gen_l10n}/app_localizations_en.dart (100%) rename covas_mobile_new/lib/{l10n => gen_l10n}/app_localizations_fr.dart (100%) diff --git a/covas_mobile_new/.env b/covas_mobile_new/.env new file mode 100644 index 0000000..1999b68 --- /dev/null +++ b/covas_mobile_new/.env @@ -0,0 +1,7 @@ +GEMINI_API_KEY=AIzaSyA_duijigpl47KaNYMZmtiUjor1C2REKMo +GOOGLEMAP_API_KEY=AIzaSyA_duijigpl47KaNYMZmtiUjor1C2REKMo +IMGBB_API_KEY=87a91f7e54516808dda2c4feffbd5287 +MAPBOX_ACCESS_TOKEN=pk.eyJ1IjoidmFsY3plODAiLCJhIjoiY20ydGtsbWQ1MDN0OTJpcjVuZWhpY2RiZSJ9.ZKQHadu6CDlXUZV3RTxpPA +PLACE_API_KEY=AIzaSyAt1LQIV_hwJQF56sXjb4oxEZEC0wI3PKg +AD_UNIT_ID=ca-app-pub-4855855675386260/2474310045 +KEY_ENCRYPT=FXNF4VSYvaLdldlq \ No newline at end of file diff --git a/covas_mobile_new/debug b/covas_mobile_new/debug new file mode 100644 index 0000000..e3d568d --- /dev/null +++ b/covas_mobile_new/debug @@ -0,0 +1 @@ +Running Gradle task 'assembleRelease'... 567ms diff --git a/covas_mobile_new/l10n.yaml b/covas_mobile_new/l10n.yaml new file mode 100644 index 0000000..614c53b --- /dev/null +++ b/covas_mobile_new/l10n.yaml @@ -0,0 +1,5 @@ +arb-dir: lib/l10n +template-arb-file: app_en.arb +output-localization-file: app_localizations.dart +output-class: AppLocalizations +output-dir: lib/gen_l10n diff --git a/covas_mobile_new/lib/classes/MyDrawer.dart b/covas_mobile_new/lib/classes/MyDrawer.dart index 8fcf62c..e1b95ce 100644 --- a/covas_mobile_new/lib/classes/MyDrawer.dart +++ b/covas_mobile_new/lib/classes/MyDrawer.dart @@ -15,7 +15,7 @@ import 'package:encrypt_shared_preferences/provider.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; class MyDrawer extends StatelessWidget with ShowAlertDialog { Future logout(BuildContext context) async { diff --git a/covas_mobile_new/lib/classes/notification_service.dart b/covas_mobile_new/lib/classes/notification_service.dart index 4ff081e..4784e0e 100644 --- a/covas_mobile_new/lib/classes/notification_service.dart +++ b/covas_mobile_new/lib/classes/notification_service.dart @@ -3,7 +3,7 @@ import 'package:timezone/timezone.dart' as tz; import 'package:timezone/data/latest_all.dart' as tz; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; class NotificationService { @@ -78,8 +78,6 @@ class NotificationService { ), androidScheduleMode: AndroidScheduleMode .inexactAllowWhileIdle, // évite l'erreur Exact Alarm - uiLocalNotificationDateInterpretation: - UILocalNotificationDateInterpretation.absoluteTime, matchDateTimeComponents: DateTimeComponents.dateAndTime, ); } diff --git a/covas_mobile_new/lib/l10n/app_localizations.dart b/covas_mobile_new/lib/gen_l10n/app_localizations.dart similarity index 99% rename from covas_mobile_new/lib/l10n/app_localizations.dart rename to covas_mobile_new/lib/gen_l10n/app_localizations.dart index 502fa07..3335313 100644 --- a/covas_mobile_new/lib/l10n/app_localizations.dart +++ b/covas_mobile_new/lib/gen_l10n/app_localizations.dart @@ -19,7 +19,7 @@ import 'app_localizations_fr.dart'; /// `supportedLocales` list. For example: /// /// ```dart -/// import 'l10n/app_localizations.dart'; +/// import 'gen_l10n/app_localizations.dart'; /// /// return MaterialApp( /// localizationsDelegates: AppLocalizations.localizationsDelegates, diff --git a/covas_mobile_new/lib/l10n/app_localizations_de.dart b/covas_mobile_new/lib/gen_l10n/app_localizations_de.dart similarity index 100% rename from covas_mobile_new/lib/l10n/app_localizations_de.dart rename to covas_mobile_new/lib/gen_l10n/app_localizations_de.dart diff --git a/covas_mobile_new/lib/l10n/app_localizations_en.dart b/covas_mobile_new/lib/gen_l10n/app_localizations_en.dart similarity index 100% rename from covas_mobile_new/lib/l10n/app_localizations_en.dart rename to covas_mobile_new/lib/gen_l10n/app_localizations_en.dart diff --git a/covas_mobile_new/lib/l10n/app_localizations_fr.dart b/covas_mobile_new/lib/gen_l10n/app_localizations_fr.dart similarity index 100% rename from covas_mobile_new/lib/l10n/app_localizations_fr.dart rename to covas_mobile_new/lib/gen_l10n/app_localizations_fr.dart diff --git a/covas_mobile_new/lib/main.dart b/covas_mobile_new/lib/main.dart index cba36b6..af9c6ed 100644 --- a/covas_mobile_new/lib/main.dart +++ b/covas_mobile_new/lib/main.dart @@ -4,7 +4,7 @@ import 'package:provider/provider.dart'; import 'pages/LoginDemo.dart'; import 'locale_provider.dart'; // <-- à adapter selon ton arborescence -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'classes/notification_service.dart'; void main() async { diff --git a/covas_mobile_new/lib/pages/AddProfile.dart b/covas_mobile_new/lib/pages/AddProfile.dart index 5888f57..a49af47 100644 --- a/covas_mobile_new/lib/pages/AddProfile.dart +++ b/covas_mobile_new/lib/pages/AddProfile.dart @@ -14,7 +14,7 @@ import '../variable/globals.dart' as globals; import '../classes/ad_helper.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // Créé plus loin diff --git a/covas_mobile_new/lib/pages/Camera.dart b/covas_mobile_new/lib/pages/Camera.dart index 0189dc0..a29fa76 100644 --- a/covas_mobile_new/lib/pages/Camera.dart +++ b/covas_mobile_new/lib/pages/Camera.dart @@ -8,7 +8,7 @@ import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; import '../classes/auth_service.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // Créé plus loin diff --git a/covas_mobile_new/lib/pages/CameraEdit.dart b/covas_mobile_new/lib/pages/CameraEdit.dart index 408e8fc..f4c276f 100644 --- a/covas_mobile_new/lib/pages/CameraEdit.dart +++ b/covas_mobile_new/lib/pages/CameraEdit.dart @@ -9,7 +9,7 @@ import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; import '../classes/auth_service.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // Créé diff --git a/covas_mobile_new/lib/pages/DisplayPictureScreen.dart b/covas_mobile_new/lib/pages/DisplayPictureScreen.dart index aea3380..107521d 100644 --- a/covas_mobile_new/lib/pages/DisplayPictureScreen.dart +++ b/covas_mobile_new/lib/pages/DisplayPictureScreen.dart @@ -18,7 +18,7 @@ import '../classes/ad_helper.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; import '../classes/auth_service.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // Créé diff --git a/covas_mobile_new/lib/pages/EditEvent.dart b/covas_mobile_new/lib/pages/EditEvent.dart index d0519c3..37ef215 100644 --- a/covas_mobile_new/lib/pages/EditEvent.dart +++ b/covas_mobile_new/lib/pages/EditEvent.dart @@ -23,7 +23,7 @@ import '../classes/ad_helper.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; import '../classes/auth_service.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // Créé diff --git a/covas_mobile_new/lib/pages/EditProfile.dart b/covas_mobile_new/lib/pages/EditProfile.dart index ff62847..f2e42e8 100644 --- a/covas_mobile_new/lib/pages/EditProfile.dart +++ b/covas_mobile_new/lib/pages/EditProfile.dart @@ -19,7 +19,7 @@ import '../classes/ad_helper.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; import '../classes/auth_service.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // Créé diff --git a/covas_mobile_new/lib/pages/EditSettings.dart b/covas_mobile_new/lib/pages/EditSettings.dart index c6e36f9..e169b8a 100644 --- a/covas_mobile_new/lib/pages/EditSettings.dart +++ b/covas_mobile_new/lib/pages/EditSettings.dart @@ -15,7 +15,7 @@ import 'package:google_mobile_ads/google_mobile_ads.dart'; import '../classes/auth_service.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // Créé diff --git a/covas_mobile_new/lib/pages/ForgotPassword.dart b/covas_mobile_new/lib/pages/ForgotPassword.dart index fb216c1..1d876f5 100644 --- a/covas_mobile_new/lib/pages/ForgotPassword.dart +++ b/covas_mobile_new/lib/pages/ForgotPassword.dart @@ -12,7 +12,7 @@ import '../classes/alert.dart'; import '../variable/globals.dart' as globals; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // diff --git a/covas_mobile_new/lib/pages/ItemMenu.dart b/covas_mobile_new/lib/pages/ItemMenu.dart index def7c59..0f1d492 100644 --- a/covas_mobile_new/lib/pages/ItemMenu.dart +++ b/covas_mobile_new/lib/pages/ItemMenu.dart @@ -26,7 +26,7 @@ import 'package:google_mobile_ads/google_mobile_ads.dart'; import '../classes/auth_service.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // diff --git a/covas_mobile_new/lib/pages/ListItemByOrganizers.dart b/covas_mobile_new/lib/pages/ListItemByOrganizers.dart index 65bc4f7..228a8fb 100644 --- a/covas_mobile_new/lib/pages/ListItemByOrganizers.dart +++ b/covas_mobile_new/lib/pages/ListItemByOrganizers.dart @@ -15,7 +15,7 @@ import '../classes/auth_service.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // import '../classes/notification_service.dart'; diff --git a/covas_mobile_new/lib/pages/ListItemByTags.dart b/covas_mobile_new/lib/pages/ListItemByTags.dart index 1dbd8df..cf5d805 100644 --- a/covas_mobile_new/lib/pages/ListItemByTags.dart +++ b/covas_mobile_new/lib/pages/ListItemByTags.dart @@ -16,7 +16,7 @@ import '../classes/auth_service.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // import '../classes/notification_service.dart'; diff --git a/covas_mobile_new/lib/pages/ListItemMenu.dart b/covas_mobile_new/lib/pages/ListItemMenu.dart index 7ce2daf..ee26b23 100644 --- a/covas_mobile_new/lib/pages/ListItemMenu.dart +++ b/covas_mobile_new/lib/pages/ListItemMenu.dart @@ -20,7 +20,7 @@ import '../classes/ad_helper.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; import '../classes/auth_service.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // Créé plus loin import '../classes/notification_service.dart'; diff --git a/covas_mobile_new/lib/pages/LoginDemo.dart b/covas_mobile_new/lib/pages/LoginDemo.dart index d6dd224..1152928 100644 --- a/covas_mobile_new/lib/pages/LoginDemo.dart +++ b/covas_mobile_new/lib/pages/LoginDemo.dart @@ -9,7 +9,7 @@ import '../classes/alert.dart'; import '../classes/ad_helper.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // diff --git a/covas_mobile_new/lib/pages/MapboxPages.dart b/covas_mobile_new/lib/pages/MapboxPages.dart index 549bc96..a345fcc 100644 --- a/covas_mobile_new/lib/pages/MapboxPages.dart +++ b/covas_mobile_new/lib/pages/MapboxPages.dart @@ -14,7 +14,7 @@ import '../classes/MyDrawer.dart'; import '../classes/auth_service.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // diff --git a/covas_mobile_new/lib/pages/UpdateEventImage.dart b/covas_mobile_new/lib/pages/UpdateEventImage.dart index 0a08e25..e2e3e43 100644 --- a/covas_mobile_new/lib/pages/UpdateEventImage.dart +++ b/covas_mobile_new/lib/pages/UpdateEventImage.dart @@ -21,7 +21,7 @@ import 'package:google_mobile_ads/google_mobile_ads.dart'; import '../classes/auth_service.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import '../locale_provider.dart'; // diff --git a/covas_mobile_new/macos/Flutter/GeneratedPluginRegistrant.swift b/covas_mobile_new/macos/Flutter/GeneratedPluginRegistrant.swift index c21fe97..f6178c4 100644 --- a/covas_mobile_new/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/covas_mobile_new/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,6 +8,7 @@ import Foundation import file_selector_macos import flutter_local_notifications import geolocator_apple +import package_info_plus import path_provider_foundation import shared_preferences_foundation import url_launcher_macos @@ -17,6 +18,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) + FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) diff --git a/covas_mobile_new/pubspec.lock b/covas_mobile_new/pubspec.lock index efb6d40..bebcfb5 100644 --- a/covas_mobile_new/pubspec.lock +++ b/covas_mobile_new/pubspec.lock @@ -25,6 +25,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.13.0" + benchmark: + dependency: transitive + description: + name: benchmark + sha256: cb3eeea01e3f054df76ee9775ca680f3afa5f19f39b2bb426ba78ba27654493b + url: "https://pub.dev" + source: hosted + version: "0.3.0" boolean_selector: dependency: transitive description: @@ -129,6 +137,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" + dart_sort_queue: + dependency: transitive + description: + name: dart_sort_queue + sha256: f3353ba8b4850e072d3368757f62edb79af34a9703c3e3df9c59342721f5f5b1 + url: "https://pub.dev" + source: hosted + version: "0.0.2+3" date_format_field: dependency: "direct main" description: @@ -189,10 +205,10 @@ packages: dependency: "direct main" description: name: encrypt_shared_preferences - sha256: "9be57e1f224d6f4353bdfa79de16b364ec7dddf38840c3288c547f262e50bbad" + sha256: f864d44f8e2cc87685ae6fd649a63e1e97dbdbe411fa134786122e2925d9ec7c url: "https://pub.dev" source: hosted - version: "0.8.9" + version: "0.9.10" extension_discovery: dependency: transitive description: @@ -274,50 +290,58 @@ packages: dependency: "direct main" description: name: flutter_dotenv - sha256: b7c7be5cd9f6ef7a78429cabd2774d3c4af50e79cb2b7593e3d5d763ef95c61b + sha256: d4130c4a43e0b13fefc593bc3961f2cb46e30cb79e253d4a526b1b5d24ae1ce4 url: "https://pub.dev" source: hosted - version: "5.2.1" + version: "6.0.0" flutter_gemini: dependency: "direct main" description: name: flutter_gemini - sha256: "993765fafb595e5d32153f393b9c5e71f853caa5bef123d292c21f672d2b9675" + sha256: b7264b1d19acc4b1a5628a0e26c0976aa1fb948f0d3243bc3510ff51e09476b7 url: "https://pub.dev" source: hosted - version: "2.0.5" + version: "3.0.0" flutter_lints: dependency: "direct dev" description: name: flutter_lints - sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "6.0.0" flutter_local_notifications: dependency: "direct main" description: name: flutter_local_notifications - sha256: "674173fd3c9eda9d4c8528da2ce0ea69f161577495a9cc835a2a4ecd7eadeb35" + sha256: a9966c850de5e445331b854fa42df96a8020066d67f125a5964cbc6556643f68 url: "https://pub.dev" source: hosted - version: "17.2.4" + version: "19.4.1" flutter_local_notifications_linux: dependency: transitive description: name: flutter_local_notifications_linux - sha256: c49bd06165cad9beeb79090b18cd1eb0296f4bf4b23b84426e37dd7c027fc3af + sha256: e3c277b2daab8e36ac5a6820536668d07e83851aeeb79c446e525a70710770a5 url: "https://pub.dev" source: hosted - version: "4.0.1" + version: "6.0.0" flutter_local_notifications_platform_interface: dependency: transitive description: name: flutter_local_notifications_platform_interface - sha256: "85f8d07fe708c1bdcf45037f2c0109753b26ae077e9d9e899d55971711a4ea66" + sha256: "277d25d960c15674ce78ca97f57d0bae2ee401c844b6ac80fcd972a9c99d09fe" url: "https://pub.dev" source: hosted - version: "7.2.0" + version: "9.1.0" + flutter_local_notifications_windows: + dependency: transitive + description: + name: flutter_local_notifications_windows + sha256: ed46d7ae4ec9d19e4c8fa2badac5fe27ba87a3fe387343ce726f927af074ec98 + url: "https://pub.dev" + source: hosted + version: "1.0.2" flutter_localizations: dependency: "direct main" description: flutter @@ -341,30 +365,30 @@ packages: description: flutter source: sdk version: "0.0.0" - freezed_annotation: + geoclue: dependency: transitive description: - name: freezed_annotation - sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 + name: geoclue + sha256: c2a998c77474fc57aa00c6baa2928e58f4b267649057a1c76738656e9dbd2a7f url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "0.1.1" geolocator: dependency: "direct main" description: name: geolocator - sha256: f62bcd90459e63210bbf9c35deb6a51c521f992a78de19a1fe5c11704f9530e2 + sha256: "79939537046c9025be47ec645f35c8090ecadb6fe98eba146a0d25e8c1357516" url: "https://pub.dev" source: hosted - version: "13.0.4" + version: "14.0.2" geolocator_android: dependency: transitive description: name: geolocator_android - sha256: fcb1760a50d7500deca37c9a666785c047139b5f9ee15aa5469fae7dbbe3170d + sha256: "179c3cb66dfa674fc9ccbf2be872a02658724d1c067634e2c427cf6df7df901a" url: "https://pub.dev" source: hosted - version: "4.6.2" + version: "5.0.2" geolocator_apple: dependency: transitive description: @@ -373,6 +397,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.13" + geolocator_linux: + dependency: transitive + description: + name: geolocator_linux + sha256: c4e966f0a7a87e70049eac7a2617f9e16fd4c585a26e4330bdfc3a71e6a721f3 + url: "https://pub.dev" + source: hosted + version: "0.2.3" geolocator_platform_interface: dependency: transitive description: @@ -397,14 +429,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.5" + geotypes: + dependency: transitive + description: + name: geotypes + sha256: "5bedf57de92283133dd221e363812ef50eaaba414f0823b1974ef7d84b86991f" + url: "https://pub.dev" + source: hosted + version: "0.0.2" google_mobile_ads: dependency: "direct main" description: name: google_mobile_ads - sha256: "0d4a3744b5e8ed1b8be6a1b452d309f811688855a497c6113fc4400f922db603" + sha256: a4f59019f2c32769fb6c60ed8aa321e9c21a36297e2c4f23452b3e779a3e7a26 url: "https://pub.dev" source: hosted - version: "5.3.1" + version: "6.0.0" + gsettings: + dependency: transitive + description: + name: gsettings + sha256: "1b0ce661f5436d2db1e51f3c4295a49849f03d304003a7ba177d01e3a858249c" + url: "https://pub.dev" + source: hosted + version: "0.2.8" http: dependency: "direct main" description: @@ -497,10 +545,10 @@ packages: dependency: transitive description: name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" url: "https://pub.dev" source: hosted - version: "0.6.7" + version: "0.7.2" json_annotation: dependency: transitive description: @@ -545,10 +593,10 @@ packages: dependency: transitive description: name: lints - sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" + sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0 url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "6.0.0" logging: dependency: transitive description: @@ -557,6 +605,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" + mapbox_maps_flutter: + dependency: "direct main" + description: + name: mapbox_maps_flutter + sha256: "9afe65d06230c6fe368859329ec76f0f9b31558c210a6711c1e0644b2109c525" + url: "https://pub.dev" + source: hosted + version: "2.10.0" matcher: dependency: transitive description: @@ -585,10 +641,10 @@ packages: dependency: transitive description: name: mime - sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "2.0.0" nested: dependency: transitive description: @@ -597,6 +653,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + package_info_plus: + dependency: transitive + description: + name: package_info_plus + sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968" + url: "https://pub.dev" + source: hosted + version: "8.3.1" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" + url: "https://pub.dev" + source: hosted + version: "3.2.1" path: dependency: "direct main" description: @@ -657,18 +729,18 @@ packages: dependency: "direct main" description: name: permission_handler - sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849" + sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1 url: "https://pub.dev" source: hosted - version: "11.4.0" + version: "12.0.1" permission_handler_android: dependency: transitive description: name: permission_handler_android - sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc + sha256: "1e3bc410ca1bf84662104b100eb126e066cb55791b7451307f9708d4007350e6" url: "https://pub.dev" source: hosted - version: "12.1.0" + version: "13.0.1" permission_handler_apple: dependency: transitive description: @@ -749,6 +821,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.5+1" + rbush: + dependency: transitive + description: + name: rbush + sha256: "48b683421b4afb43a642f82c6aa31911e54f3069143d31c7d33cbe329df13403" + url: "https://pub.dev" + source: hosted + version: "1.1.1" shared_preferences: dependency: "direct main" description: @@ -874,6 +954,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" + sweepline_intersections: + dependency: transitive + description: + name: sweepline_intersections + sha256: a665c707200a4f07140a4029b41a7c4883beb3f04322cd8e08ebf650f69e1176 + url: "https://pub.dev" + source: hosted + version: "0.0.4" term_glyph: dependency: transitive description: @@ -902,10 +990,34 @@ packages: dependency: "direct main" description: name: timezone - sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d" + sha256: dd14a3b83cfd7cb19e7888f1cbc20f258b8d71b54c06f79ac585f14093a287d1 url: "https://pub.dev" source: hosted - version: "0.9.4" + version: "0.10.1" + turf: + dependency: transitive + description: + name: turf + sha256: "75347c45a5c1de805db7cb182286f05a3770e01546626c4dc292709d15cbe436" + url: "https://pub.dev" + source: hosted + version: "0.0.10" + turf_equality: + dependency: transitive + description: + name: turf_equality + sha256: f0f44ffe389547941358e0d3d4a747db2bd56115b32ff1cede5e5bdf3126a3e2 + url: "https://pub.dev" + source: hosted + version: "0.1.0" + turf_pip: + dependency: transitive + description: + name: turf_pip + sha256: ba4fd414baffd5d7b30880658ad6db82461c49ec023f8ffd0c23d398ad8b14be + url: "https://pub.dev" + source: hosted + version: "0.0.2" typed_data: dependency: transitive description: @@ -1074,6 +1186,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.23.0" + win32: + dependency: transitive + description: + name: win32 + sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03" + url: "https://pub.dev" + source: hosted + version: "5.14.0" xdg_directories: dependency: transitive description: diff --git a/covas_mobile_new/pubspec.yaml b/covas_mobile_new/pubspec.yaml index 6c86a73..11f865a 100644 --- a/covas_mobile_new/pubspec.yaml +++ b/covas_mobile_new/pubspec.yaml @@ -18,7 +18,8 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.17.6 <3.0.0" + #sdk: ">=2.17.6 <3.0.0" + sdk: ">=3.0.0 <4.0.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -36,8 +37,8 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - flutter_local_notifications: ^17.2.0 - timezone: ^0.9.4 + flutter_local_notifications: ^19.4.1 + timezone: ^0.10.1 cupertino_icons: ^1.0.2 http: ^1.2.1 shared_preferences: ^2.2.3 @@ -46,17 +47,18 @@ dependencies: camera_web: ^0.3.3 path_provider: ^2.1.3 path: ^1.9.0 - flutter_gemini: ^2.0.4 - flutter_dotenv: ^5.1.0 + flutter_gemini: ^3.0.0 + flutter_dotenv: ^6.0.0 image_picker: ^1.1.2 date_format_field: ^0.1.0 textfield_tags: ^3.0.1 - geolocator: ^13.0.1 - permission_handler: ^11.3.1 + geolocator: ^14.0.2 + permission_handler: ^12.0.1 url_launcher: ^6.3.1 - google_mobile_ads: ^5.3.1 - encrypt_shared_preferences: ^0.8.8 + google_mobile_ads: ^6.0.0 + encrypt_shared_preferences: ^0.9.10 provider: ^6.1.2 # ou la dernière version + mapbox_maps_flutter: ^2.10.0 dev_dependencies: flutter_test: @@ -67,7 +69,7 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: ^4.0.0 + flutter_lints: ^6.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec @@ -75,7 +77,6 @@ dev_dependencies: # The following section is specific to Flutter packages. flutter: generate: true - # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. diff --git a/covas_mobile_new/windows/flutter/generated_plugins.cmake b/covas_mobile_new/windows/flutter/generated_plugins.cmake index 92c9a0d..954663e 100644 --- a/covas_mobile_new/windows/flutter/generated_plugins.cmake +++ b/covas_mobile_new/windows/flutter/generated_plugins.cmake @@ -10,6 +10,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + flutter_local_notifications_windows ) set(PLUGIN_BUNDLED_LIBRARIES) From 61694838391877d720e429e387734d478353e848 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sun, 31 Aug 2025 18:24:49 +0200 Subject: [PATCH 03/16] fix new version applocalization --- covas_mobile_new/.env | 7 - covas_mobile_new/.gitignore | 10 +- covas_mobile_new/debug | 1 - {covas_mobile => covas_mobile_old}/.gitignore | 0 {covas_mobile => covas_mobile_old}/.metadata | 0 {covas_mobile => covas_mobile_old}/README.md | 0 .../analysis_options.yaml | 0 .../android/.gitignore | 0 covas_mobile_old/android/app/build.gradle | 50 + .../android/app/build.gradle.old | 0 .../android/app/src/debug/AndroidManifest.xml | 0 .../android/app/src/main/AndroidManifest.xml | 0 .../com/example/covas_mobile/MainActivity.kt | 0 .../res/drawable-v21/launch_background.xml | 0 .../main/res/drawable/launch_background.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../app/src/main/res/values-night/styles.xml | 0 .../app/src/main/res/values/styles.xml | 0 .../app/src/profile/AndroidManifest.xml | 0 .../android/build.gradle | 0 .../android/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.properties | 0 .../android/settings.gradl.old | 0 covas_mobile_old/android/settings.gradle | 11 + .../images/flutter.png | Bin .../images/marker-red.png | Bin .../images/marker.png | Bin .../images/search.png | Bin .../ios/.gitignore | 0 .../ios/Flutter/AppFrameworkInfo.plist | 0 .../ios/Flutter/Debug.xcconfig | 0 .../ios/Flutter/Release.xcconfig | 0 .../ios/Runner.xcodeproj/project.pbxproj | 0 .../contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../xcshareddata/WorkspaceSettings.xcsettings | 0 .../xcshareddata/xcschemes/Runner.xcscheme | 0 .../contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../xcshareddata/WorkspaceSettings.xcsettings | 0 .../ios/Runner/AppDelegate.swift | 0 .../AppIcon.appiconset/Contents.json | 0 .../Icon-App-1024x1024@1x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin .../Icon-App-83.5x83.5@2x.png | Bin .../LaunchImage.imageset/Contents.json | 0 .../LaunchImage.imageset/LaunchImage.png | Bin .../LaunchImage.imageset/LaunchImage@2x.png | Bin .../LaunchImage.imageset/LaunchImage@3x.png | Bin .../LaunchImage.imageset/README.md | 0 .../Runner/Base.lproj/LaunchScreen.storyboard | 0 .../ios/Runner/Base.lproj/Main.storyboard | 0 .../ios/Runner/Info.plist | 0 .../ios/Runner/Runner-Bridging-Header.h | 0 {covas_mobile => covas_mobile_old}/l10n.yaml | 0 .../lib/classes/MyDrawer.dart | 0 .../lib/classes/ad_helper.dart | 0 .../lib/classes/addEventImage.dart | 0 .../lib/classes/alert.dart | 0 .../lib/classes/auth_service.dart | 0 .../lib/classes/eventAdded.dart | 0 .../lib/classes/events.dart | 0 .../lib/classes/getEventImage.dart | 0 .../lib/classes/notification_service.dart | 2 +- .../lib/l10n/app_de.arb | 0 .../lib/l10n/app_en.arb | 0 .../lib/l10n/app_fr.arb | 0 .../lib/l10n/app_localizations.dart | 977 ++++++++++++++++++ .../lib/l10n/app_localizations_de.dart | 434 ++++++++ .../lib/l10n/app_localizations_en.dart | 434 ++++++++ .../lib/l10n/app_localizations_fr.dart | 437 ++++++++ .../lib/locale_provider.dart | 0 .../lib/main.dart | 0 .../lib/pages/AddProfile.dart | 0 .../lib/pages/Camera.dart | 0 .../lib/pages/CameraEdit.dart | 0 .../lib/pages/DisplayPictureScreen.dart | 0 .../lib/pages/EditEvent.dart | 0 .../lib/pages/EditProfile.dart | 0 .../lib/pages/EditSettings.dart | 0 .../lib/pages/ForgotPassword.dart | 0 .../lib/pages/ItemMenu.dart | 0 .../lib/pages/ListItemByOrganizers.dart | 0 .../lib/pages/ListItemByTags.dart | 0 .../lib/pages/ListItemMenu.dart | 0 .../lib/pages/LoginDemo.dart | 0 .../lib/pages/MapboxPages.dart | 0 .../lib/pages/UpdateEventImage.dart | 0 .../lib/variable/globals.dart | 0 .../linux/.gitignore | 0 .../linux/CMakeLists.txt | 0 .../linux/flutter/CMakeLists.txt | 0 .../flutter/generated_plugin_registrant.cc | 0 .../flutter/generated_plugin_registrant.h | 0 .../linux/flutter/generated_plugins.cmake | 0 .../linux/main.cc | 0 .../linux/my_application.cc | 0 .../linux/my_application.h | 0 .../macos/.gitignore | 0 .../macos/Flutter/Flutter-Debug.xcconfig | 0 .../macos/Flutter/Flutter-Release.xcconfig | 0 .../Flutter/GeneratedPluginRegistrant.swift | 0 .../macos/Runner.xcodeproj/project.pbxproj | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../xcshareddata/xcschemes/Runner.xcscheme | 0 .../contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../macos/Runner/AppDelegate.swift | 0 .../AppIcon.appiconset/Contents.json | 0 .../AppIcon.appiconset/app_icon_1024.png | Bin .../AppIcon.appiconset/app_icon_128.png | Bin .../AppIcon.appiconset/app_icon_16.png | Bin .../AppIcon.appiconset/app_icon_256.png | Bin .../AppIcon.appiconset/app_icon_32.png | Bin .../AppIcon.appiconset/app_icon_512.png | Bin .../AppIcon.appiconset/app_icon_64.png | Bin .../macos/Runner/Base.lproj/MainMenu.xib | 0 .../macos/Runner/Configs/AppInfo.xcconfig | 0 .../macos/Runner/Configs/Debug.xcconfig | 0 .../macos/Runner/Configs/Release.xcconfig | 0 .../macos/Runner/Configs/Warnings.xcconfig | 0 .../macos/Runner/DebugProfile.entitlements | 0 .../macos/Runner/Info.plist | 0 .../macos/Runner/MainFlutterWindow.swift | 0 .../macos/Runner/Release.entitlements | 0 .../pubspec.lock | 64 +- .../pubspec.yaml | 2 +- .../test/widget_test.dart | 0 .../web/favicon.png | Bin .../web/icons/Icon-192.png | Bin .../web/icons/Icon-512.png | Bin .../web/icons/Icon-maskable-192.png | Bin .../web/icons/Icon-maskable-512.png | Bin .../web/index.html | 0 .../web/manifest.json | 0 .../windows/.gitignore | 0 .../windows/CMakeLists.txt | 0 .../windows/flutter/CMakeLists.txt | 0 .../flutter/generated_plugin_registrant.cc | 0 .../flutter/generated_plugin_registrant.h | 0 .../windows/flutter/generated_plugins.cmake | 0 .../windows/runner/CMakeLists.txt | 0 .../windows/runner/Runner.rc | 0 .../windows/runner/flutter_window.cpp | 0 .../windows/runner/flutter_window.h | 0 .../windows/runner/main.cpp | 0 .../windows/runner/resource.h | 0 .../windows/runner/resources/app_icon.ico | Bin .../windows/runner/runner.exe.manifest | 0 .../windows/runner/utils.cpp | 0 .../windows/runner/utils.h | 0 .../windows/runner/win32_window.cpp | 0 .../windows/runner/win32_window.h | 0 169 files changed, 2384 insertions(+), 45 deletions(-) delete mode 100644 covas_mobile_new/.env delete mode 100644 covas_mobile_new/debug rename {covas_mobile => covas_mobile_old}/.gitignore (100%) rename {covas_mobile => covas_mobile_old}/.metadata (100%) rename {covas_mobile => covas_mobile_old}/README.md (100%) rename {covas_mobile => covas_mobile_old}/analysis_options.yaml (100%) rename {covas_mobile => covas_mobile_old}/android/.gitignore (100%) create mode 100644 covas_mobile_old/android/app/build.gradle rename covas_mobile/android/app/build.gradle => covas_mobile_old/android/app/build.gradle.old (100%) rename {covas_mobile => covas_mobile_old}/android/app/src/debug/AndroidManifest.xml (100%) rename {covas_mobile => covas_mobile_old}/android/app/src/main/AndroidManifest.xml (100%) rename {covas_mobile => covas_mobile_old}/android/app/src/main/kotlin/com/example/covas_mobile/MainActivity.kt (100%) rename {covas_mobile => covas_mobile_old}/android/app/src/main/res/drawable-v21/launch_background.xml (100%) rename {covas_mobile => covas_mobile_old}/android/app/src/main/res/drawable/launch_background.xml (100%) rename {covas_mobile => covas_mobile_old}/android/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename {covas_mobile => covas_mobile_old}/android/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename {covas_mobile => covas_mobile_old}/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename {covas_mobile => covas_mobile_old}/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename {covas_mobile => covas_mobile_old}/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename {covas_mobile => covas_mobile_old}/android/app/src/main/res/values-night/styles.xml (100%) rename {covas_mobile => covas_mobile_old}/android/app/src/main/res/values/styles.xml (100%) rename {covas_mobile => covas_mobile_old}/android/app/src/profile/AndroidManifest.xml (100%) rename {covas_mobile => covas_mobile_old}/android/build.gradle (100%) rename {covas_mobile => covas_mobile_old}/android/gradle.properties (100%) rename {covas_mobile => covas_mobile_old}/android/gradle/wrapper/gradle-wrapper.properties (100%) rename covas_mobile/android/settings.gradle => covas_mobile_old/android/settings.gradl.old (100%) create mode 100644 covas_mobile_old/android/settings.gradle rename {covas_mobile => covas_mobile_old}/images/flutter.png (100%) rename {covas_mobile => covas_mobile_old}/images/marker-red.png (100%) rename {covas_mobile => covas_mobile_old}/images/marker.png (100%) rename {covas_mobile => covas_mobile_old}/images/search.png (100%) rename {covas_mobile => covas_mobile_old}/ios/.gitignore (100%) rename {covas_mobile => covas_mobile_old}/ios/Flutter/AppFrameworkInfo.plist (100%) rename {covas_mobile => covas_mobile_old}/ios/Flutter/Debug.xcconfig (100%) rename {covas_mobile => covas_mobile_old}/ios/Flutter/Release.xcconfig (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner.xcodeproj/project.pbxproj (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner.xcworkspace/contents.xcworkspacedata (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/AppDelegate.swift (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Base.lproj/LaunchScreen.storyboard (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Base.lproj/Main.storyboard (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Info.plist (100%) rename {covas_mobile => covas_mobile_old}/ios/Runner/Runner-Bridging-Header.h (100%) rename {covas_mobile => covas_mobile_old}/l10n.yaml (100%) rename {covas_mobile => covas_mobile_old}/lib/classes/MyDrawer.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/classes/ad_helper.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/classes/addEventImage.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/classes/alert.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/classes/auth_service.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/classes/eventAdded.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/classes/events.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/classes/getEventImage.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/classes/notification_service.dart (97%) rename {covas_mobile => covas_mobile_old}/lib/l10n/app_de.arb (100%) rename {covas_mobile => covas_mobile_old}/lib/l10n/app_en.arb (100%) rename {covas_mobile => covas_mobile_old}/lib/l10n/app_fr.arb (100%) create mode 100644 covas_mobile_old/lib/l10n/app_localizations.dart create mode 100644 covas_mobile_old/lib/l10n/app_localizations_de.dart create mode 100644 covas_mobile_old/lib/l10n/app_localizations_en.dart create mode 100644 covas_mobile_old/lib/l10n/app_localizations_fr.dart rename {covas_mobile => covas_mobile_old}/lib/locale_provider.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/main.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/AddProfile.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/Camera.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/CameraEdit.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/DisplayPictureScreen.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/EditEvent.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/EditProfile.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/EditSettings.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/ForgotPassword.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/ItemMenu.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/ListItemByOrganizers.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/ListItemByTags.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/ListItemMenu.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/LoginDemo.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/MapboxPages.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/pages/UpdateEventImage.dart (100%) rename {covas_mobile => covas_mobile_old}/lib/variable/globals.dart (100%) rename {covas_mobile => covas_mobile_old}/linux/.gitignore (100%) rename {covas_mobile => covas_mobile_old}/linux/CMakeLists.txt (100%) rename {covas_mobile => covas_mobile_old}/linux/flutter/CMakeLists.txt (100%) rename {covas_mobile => covas_mobile_old}/linux/flutter/generated_plugin_registrant.cc (100%) rename {covas_mobile => covas_mobile_old}/linux/flutter/generated_plugin_registrant.h (100%) rename {covas_mobile => covas_mobile_old}/linux/flutter/generated_plugins.cmake (100%) rename {covas_mobile => covas_mobile_old}/linux/main.cc (100%) rename {covas_mobile => covas_mobile_old}/linux/my_application.cc (100%) rename {covas_mobile => covas_mobile_old}/linux/my_application.h (100%) rename {covas_mobile => covas_mobile_old}/macos/.gitignore (100%) rename {covas_mobile => covas_mobile_old}/macos/Flutter/Flutter-Debug.xcconfig (100%) rename {covas_mobile => covas_mobile_old}/macos/Flutter/Flutter-Release.xcconfig (100%) rename {covas_mobile => covas_mobile_old}/macos/Flutter/GeneratedPluginRegistrant.swift (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner.xcodeproj/project.pbxproj (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner.xcworkspace/contents.xcworkspacedata (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/AppDelegate.swift (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Base.lproj/MainMenu.xib (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Configs/AppInfo.xcconfig (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Configs/Debug.xcconfig (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Configs/Release.xcconfig (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Configs/Warnings.xcconfig (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/DebugProfile.entitlements (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Info.plist (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/MainFlutterWindow.swift (100%) rename {covas_mobile => covas_mobile_old}/macos/Runner/Release.entitlements (100%) rename {covas_mobile => covas_mobile_old}/pubspec.lock (95%) rename {covas_mobile => covas_mobile_old}/pubspec.yaml (99%) rename {covas_mobile => covas_mobile_old}/test/widget_test.dart (100%) rename {covas_mobile => covas_mobile_old}/web/favicon.png (100%) rename {covas_mobile => covas_mobile_old}/web/icons/Icon-192.png (100%) rename {covas_mobile => covas_mobile_old}/web/icons/Icon-512.png (100%) rename {covas_mobile => covas_mobile_old}/web/icons/Icon-maskable-192.png (100%) rename {covas_mobile => covas_mobile_old}/web/icons/Icon-maskable-512.png (100%) rename {covas_mobile => covas_mobile_old}/web/index.html (100%) rename {covas_mobile => covas_mobile_old}/web/manifest.json (100%) rename {covas_mobile => covas_mobile_old}/windows/.gitignore (100%) rename {covas_mobile => covas_mobile_old}/windows/CMakeLists.txt (100%) rename {covas_mobile => covas_mobile_old}/windows/flutter/CMakeLists.txt (100%) rename {covas_mobile => covas_mobile_old}/windows/flutter/generated_plugin_registrant.cc (100%) rename {covas_mobile => covas_mobile_old}/windows/flutter/generated_plugin_registrant.h (100%) rename {covas_mobile => covas_mobile_old}/windows/flutter/generated_plugins.cmake (100%) rename {covas_mobile => covas_mobile_old}/windows/runner/CMakeLists.txt (100%) rename {covas_mobile => covas_mobile_old}/windows/runner/Runner.rc (100%) rename {covas_mobile => covas_mobile_old}/windows/runner/flutter_window.cpp (100%) rename {covas_mobile => covas_mobile_old}/windows/runner/flutter_window.h (100%) rename {covas_mobile => covas_mobile_old}/windows/runner/main.cpp (100%) rename {covas_mobile => covas_mobile_old}/windows/runner/resource.h (100%) rename {covas_mobile => covas_mobile_old}/windows/runner/resources/app_icon.ico (100%) rename {covas_mobile => covas_mobile_old}/windows/runner/runner.exe.manifest (100%) rename {covas_mobile => covas_mobile_old}/windows/runner/utils.cpp (100%) rename {covas_mobile => covas_mobile_old}/windows/runner/utils.h (100%) rename {covas_mobile => covas_mobile_old}/windows/runner/win32_window.cpp (100%) rename {covas_mobile => covas_mobile_old}/windows/runner/win32_window.h (100%) diff --git a/covas_mobile_new/.env b/covas_mobile_new/.env deleted file mode 100644 index 1999b68..0000000 --- a/covas_mobile_new/.env +++ /dev/null @@ -1,7 +0,0 @@ -GEMINI_API_KEY=AIzaSyA_duijigpl47KaNYMZmtiUjor1C2REKMo -GOOGLEMAP_API_KEY=AIzaSyA_duijigpl47KaNYMZmtiUjor1C2REKMo -IMGBB_API_KEY=87a91f7e54516808dda2c4feffbd5287 -MAPBOX_ACCESS_TOKEN=pk.eyJ1IjoidmFsY3plODAiLCJhIjoiY20ydGtsbWQ1MDN0OTJpcjVuZWhpY2RiZSJ9.ZKQHadu6CDlXUZV3RTxpPA -PLACE_API_KEY=AIzaSyAt1LQIV_hwJQF56sXjb4oxEZEC0wI3PKg -AD_UNIT_ID=ca-app-pub-4855855675386260/2474310045 -KEY_ENCRYPT=FXNF4VSYvaLdldlq \ No newline at end of file diff --git a/covas_mobile_new/.gitignore b/covas_mobile_new/.gitignore index 3820a95..e158b41 100644 --- a/covas_mobile_new/.gitignore +++ b/covas_mobile_new/.gitignore @@ -5,11 +5,9 @@ *.swp .DS_Store .atom/ -.build/ .buildlog/ .history .svn/ -.swiftpm/ migrate_working_dir/ # IntelliJ related @@ -27,11 +25,15 @@ migrate_working_dir/ **/doc/api/ **/ios/Flutter/.last_build_id .dart_tool/ +.flutter-plugins .flutter-plugins-dependencies +.packages .pub-cache/ .pub/ /build/ -/coverage/ + +# Web related +lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols @@ -43,3 +45,5 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + +.env \ No newline at end of file diff --git a/covas_mobile_new/debug b/covas_mobile_new/debug deleted file mode 100644 index e3d568d..0000000 --- a/covas_mobile_new/debug +++ /dev/null @@ -1 +0,0 @@ -Running Gradle task 'assembleRelease'... 567ms diff --git a/covas_mobile/.gitignore b/covas_mobile_old/.gitignore similarity index 100% rename from covas_mobile/.gitignore rename to covas_mobile_old/.gitignore diff --git a/covas_mobile/.metadata b/covas_mobile_old/.metadata similarity index 100% rename from covas_mobile/.metadata rename to covas_mobile_old/.metadata diff --git a/covas_mobile/README.md b/covas_mobile_old/README.md similarity index 100% rename from covas_mobile/README.md rename to covas_mobile_old/README.md diff --git a/covas_mobile/analysis_options.yaml b/covas_mobile_old/analysis_options.yaml similarity index 100% rename from covas_mobile/analysis_options.yaml rename to covas_mobile_old/analysis_options.yaml diff --git a/covas_mobile/android/.gitignore b/covas_mobile_old/android/.gitignore similarity index 100% rename from covas_mobile/android/.gitignore rename to covas_mobile_old/android/.gitignore diff --git a/covas_mobile_old/android/app/build.gradle b/covas_mobile_old/android/app/build.gradle new file mode 100644 index 0000000..4846dfc --- /dev/null +++ b/covas_mobile_old/android/app/build.gradle @@ -0,0 +1,50 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' + +android { + compileSdkVersion 34 + + defaultConfig { + applicationId "com.example.covas_mobile" + minSdkVersion 21 + targetSdkVersion 34 + versionCode 1 + versionName "1.0" + } + + buildTypes { + release { + signingConfig signingConfigs.debug + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} diff --git a/covas_mobile/android/app/build.gradle b/covas_mobile_old/android/app/build.gradle.old similarity index 100% rename from covas_mobile/android/app/build.gradle rename to covas_mobile_old/android/app/build.gradle.old diff --git a/covas_mobile/android/app/src/debug/AndroidManifest.xml b/covas_mobile_old/android/app/src/debug/AndroidManifest.xml similarity index 100% rename from covas_mobile/android/app/src/debug/AndroidManifest.xml rename to covas_mobile_old/android/app/src/debug/AndroidManifest.xml diff --git a/covas_mobile/android/app/src/main/AndroidManifest.xml b/covas_mobile_old/android/app/src/main/AndroidManifest.xml similarity index 100% rename from covas_mobile/android/app/src/main/AndroidManifest.xml rename to covas_mobile_old/android/app/src/main/AndroidManifest.xml diff --git a/covas_mobile/android/app/src/main/kotlin/com/example/covas_mobile/MainActivity.kt b/covas_mobile_old/android/app/src/main/kotlin/com/example/covas_mobile/MainActivity.kt similarity index 100% rename from covas_mobile/android/app/src/main/kotlin/com/example/covas_mobile/MainActivity.kt rename to covas_mobile_old/android/app/src/main/kotlin/com/example/covas_mobile/MainActivity.kt diff --git a/covas_mobile/android/app/src/main/res/drawable-v21/launch_background.xml b/covas_mobile_old/android/app/src/main/res/drawable-v21/launch_background.xml similarity index 100% rename from covas_mobile/android/app/src/main/res/drawable-v21/launch_background.xml rename to covas_mobile_old/android/app/src/main/res/drawable-v21/launch_background.xml diff --git a/covas_mobile/android/app/src/main/res/drawable/launch_background.xml b/covas_mobile_old/android/app/src/main/res/drawable/launch_background.xml similarity index 100% rename from covas_mobile/android/app/src/main/res/drawable/launch_background.xml rename to covas_mobile_old/android/app/src/main/res/drawable/launch_background.xml diff --git a/covas_mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/covas_mobile_old/android/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from covas_mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to covas_mobile_old/android/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/covas_mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/covas_mobile_old/android/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from covas_mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to covas_mobile_old/android/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/covas_mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/covas_mobile_old/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from covas_mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to covas_mobile_old/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/covas_mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/covas_mobile_old/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from covas_mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to covas_mobile_old/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/covas_mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/covas_mobile_old/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from covas_mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to covas_mobile_old/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/covas_mobile/android/app/src/main/res/values-night/styles.xml b/covas_mobile_old/android/app/src/main/res/values-night/styles.xml similarity index 100% rename from covas_mobile/android/app/src/main/res/values-night/styles.xml rename to covas_mobile_old/android/app/src/main/res/values-night/styles.xml diff --git a/covas_mobile/android/app/src/main/res/values/styles.xml b/covas_mobile_old/android/app/src/main/res/values/styles.xml similarity index 100% rename from covas_mobile/android/app/src/main/res/values/styles.xml rename to covas_mobile_old/android/app/src/main/res/values/styles.xml diff --git a/covas_mobile/android/app/src/profile/AndroidManifest.xml b/covas_mobile_old/android/app/src/profile/AndroidManifest.xml similarity index 100% rename from covas_mobile/android/app/src/profile/AndroidManifest.xml rename to covas_mobile_old/android/app/src/profile/AndroidManifest.xml diff --git a/covas_mobile/android/build.gradle b/covas_mobile_old/android/build.gradle similarity index 100% rename from covas_mobile/android/build.gradle rename to covas_mobile_old/android/build.gradle diff --git a/covas_mobile/android/gradle.properties b/covas_mobile_old/android/gradle.properties similarity index 100% rename from covas_mobile/android/gradle.properties rename to covas_mobile_old/android/gradle.properties diff --git a/covas_mobile/android/gradle/wrapper/gradle-wrapper.properties b/covas_mobile_old/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from covas_mobile/android/gradle/wrapper/gradle-wrapper.properties rename to covas_mobile_old/android/gradle/wrapper/gradle-wrapper.properties diff --git a/covas_mobile/android/settings.gradle b/covas_mobile_old/android/settings.gradl.old similarity index 100% rename from covas_mobile/android/settings.gradle rename to covas_mobile_old/android/settings.gradl.old diff --git a/covas_mobile_old/android/settings.gradle b/covas_mobile_old/android/settings.gradle new file mode 100644 index 0000000..0c6dae7 --- /dev/null +++ b/covas_mobile_old/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + diff --git a/covas_mobile/images/flutter.png b/covas_mobile_old/images/flutter.png similarity index 100% rename from covas_mobile/images/flutter.png rename to covas_mobile_old/images/flutter.png diff --git a/covas_mobile/images/marker-red.png b/covas_mobile_old/images/marker-red.png similarity index 100% rename from covas_mobile/images/marker-red.png rename to covas_mobile_old/images/marker-red.png diff --git a/covas_mobile/images/marker.png b/covas_mobile_old/images/marker.png similarity index 100% rename from covas_mobile/images/marker.png rename to covas_mobile_old/images/marker.png diff --git a/covas_mobile/images/search.png b/covas_mobile_old/images/search.png similarity index 100% rename from covas_mobile/images/search.png rename to covas_mobile_old/images/search.png diff --git a/covas_mobile/ios/.gitignore b/covas_mobile_old/ios/.gitignore similarity index 100% rename from covas_mobile/ios/.gitignore rename to covas_mobile_old/ios/.gitignore diff --git a/covas_mobile/ios/Flutter/AppFrameworkInfo.plist b/covas_mobile_old/ios/Flutter/AppFrameworkInfo.plist similarity index 100% rename from covas_mobile/ios/Flutter/AppFrameworkInfo.plist rename to covas_mobile_old/ios/Flutter/AppFrameworkInfo.plist diff --git a/covas_mobile/ios/Flutter/Debug.xcconfig b/covas_mobile_old/ios/Flutter/Debug.xcconfig similarity index 100% rename from covas_mobile/ios/Flutter/Debug.xcconfig rename to covas_mobile_old/ios/Flutter/Debug.xcconfig diff --git a/covas_mobile/ios/Flutter/Release.xcconfig b/covas_mobile_old/ios/Flutter/Release.xcconfig similarity index 100% rename from covas_mobile/ios/Flutter/Release.xcconfig rename to covas_mobile_old/ios/Flutter/Release.xcconfig diff --git a/covas_mobile/ios/Runner.xcodeproj/project.pbxproj b/covas_mobile_old/ios/Runner.xcodeproj/project.pbxproj similarity index 100% rename from covas_mobile/ios/Runner.xcodeproj/project.pbxproj rename to covas_mobile_old/ios/Runner.xcodeproj/project.pbxproj diff --git a/covas_mobile/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/covas_mobile_old/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from covas_mobile/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to covas_mobile_old/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/covas_mobile/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/covas_mobile_old/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from covas_mobile/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to covas_mobile_old/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/covas_mobile/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/covas_mobile_old/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings similarity index 100% rename from covas_mobile/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings rename to covas_mobile_old/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/covas_mobile/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/covas_mobile_old/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from covas_mobile/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to covas_mobile_old/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/covas_mobile/ios/Runner.xcworkspace/contents.xcworkspacedata b/covas_mobile_old/ios/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from covas_mobile/ios/Runner.xcworkspace/contents.xcworkspacedata rename to covas_mobile_old/ios/Runner.xcworkspace/contents.xcworkspacedata diff --git a/covas_mobile/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/covas_mobile_old/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from covas_mobile/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to covas_mobile_old/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/covas_mobile/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/covas_mobile_old/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings similarity index 100% rename from covas_mobile/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings rename to covas_mobile_old/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/covas_mobile/ios/Runner/AppDelegate.swift b/covas_mobile_old/ios/Runner/AppDelegate.swift similarity index 100% rename from covas_mobile/ios/Runner/AppDelegate.swift rename to covas_mobile_old/ios/Runner/AppDelegate.swift diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/covas_mobile_old/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json rename to covas_mobile_old/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json diff --git a/covas_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/covas_mobile_old/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/covas_mobile_old/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png rename to covas_mobile_old/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png diff --git a/covas_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/covas_mobile_old/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md similarity index 100% rename from covas_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md rename to covas_mobile_old/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md diff --git a/covas_mobile/ios/Runner/Base.lproj/LaunchScreen.storyboard b/covas_mobile_old/ios/Runner/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from covas_mobile/ios/Runner/Base.lproj/LaunchScreen.storyboard rename to covas_mobile_old/ios/Runner/Base.lproj/LaunchScreen.storyboard diff --git a/covas_mobile/ios/Runner/Base.lproj/Main.storyboard b/covas_mobile_old/ios/Runner/Base.lproj/Main.storyboard similarity index 100% rename from covas_mobile/ios/Runner/Base.lproj/Main.storyboard rename to covas_mobile_old/ios/Runner/Base.lproj/Main.storyboard diff --git a/covas_mobile/ios/Runner/Info.plist b/covas_mobile_old/ios/Runner/Info.plist similarity index 100% rename from covas_mobile/ios/Runner/Info.plist rename to covas_mobile_old/ios/Runner/Info.plist diff --git a/covas_mobile/ios/Runner/Runner-Bridging-Header.h b/covas_mobile_old/ios/Runner/Runner-Bridging-Header.h similarity index 100% rename from covas_mobile/ios/Runner/Runner-Bridging-Header.h rename to covas_mobile_old/ios/Runner/Runner-Bridging-Header.h diff --git a/covas_mobile/l10n.yaml b/covas_mobile_old/l10n.yaml similarity index 100% rename from covas_mobile/l10n.yaml rename to covas_mobile_old/l10n.yaml diff --git a/covas_mobile/lib/classes/MyDrawer.dart b/covas_mobile_old/lib/classes/MyDrawer.dart similarity index 100% rename from covas_mobile/lib/classes/MyDrawer.dart rename to covas_mobile_old/lib/classes/MyDrawer.dart diff --git a/covas_mobile/lib/classes/ad_helper.dart b/covas_mobile_old/lib/classes/ad_helper.dart similarity index 100% rename from covas_mobile/lib/classes/ad_helper.dart rename to covas_mobile_old/lib/classes/ad_helper.dart diff --git a/covas_mobile/lib/classes/addEventImage.dart b/covas_mobile_old/lib/classes/addEventImage.dart similarity index 100% rename from covas_mobile/lib/classes/addEventImage.dart rename to covas_mobile_old/lib/classes/addEventImage.dart diff --git a/covas_mobile/lib/classes/alert.dart b/covas_mobile_old/lib/classes/alert.dart similarity index 100% rename from covas_mobile/lib/classes/alert.dart rename to covas_mobile_old/lib/classes/alert.dart diff --git a/covas_mobile/lib/classes/auth_service.dart b/covas_mobile_old/lib/classes/auth_service.dart similarity index 100% rename from covas_mobile/lib/classes/auth_service.dart rename to covas_mobile_old/lib/classes/auth_service.dart diff --git a/covas_mobile/lib/classes/eventAdded.dart b/covas_mobile_old/lib/classes/eventAdded.dart similarity index 100% rename from covas_mobile/lib/classes/eventAdded.dart rename to covas_mobile_old/lib/classes/eventAdded.dart diff --git a/covas_mobile/lib/classes/events.dart b/covas_mobile_old/lib/classes/events.dart similarity index 100% rename from covas_mobile/lib/classes/events.dart rename to covas_mobile_old/lib/classes/events.dart diff --git a/covas_mobile/lib/classes/getEventImage.dart b/covas_mobile_old/lib/classes/getEventImage.dart similarity index 100% rename from covas_mobile/lib/classes/getEventImage.dart rename to covas_mobile_old/lib/classes/getEventImage.dart diff --git a/covas_mobile/lib/classes/notification_service.dart b/covas_mobile_old/lib/classes/notification_service.dart similarity index 97% rename from covas_mobile/lib/classes/notification_service.dart rename to covas_mobile_old/lib/classes/notification_service.dart index 3c4bb0c..4ff081e 100644 --- a/covas_mobile/lib/classes/notification_service.dart +++ b/covas_mobile_old/lib/classes/notification_service.dart @@ -70,7 +70,7 @@ class NotificationService { android: AndroidNotificationDetails( 'events_channel', 'Events', - channelDescription: 'Favorite event notifications', + channelDescription: 'Favorite event notifications ', importance: Importance.high, priority: Priority.high, ), diff --git a/covas_mobile/lib/l10n/app_de.arb b/covas_mobile_old/lib/l10n/app_de.arb similarity index 100% rename from covas_mobile/lib/l10n/app_de.arb rename to covas_mobile_old/lib/l10n/app_de.arb diff --git a/covas_mobile/lib/l10n/app_en.arb b/covas_mobile_old/lib/l10n/app_en.arb similarity index 100% rename from covas_mobile/lib/l10n/app_en.arb rename to covas_mobile_old/lib/l10n/app_en.arb diff --git a/covas_mobile/lib/l10n/app_fr.arb b/covas_mobile_old/lib/l10n/app_fr.arb similarity index 100% rename from covas_mobile/lib/l10n/app_fr.arb rename to covas_mobile_old/lib/l10n/app_fr.arb diff --git a/covas_mobile_old/lib/l10n/app_localizations.dart b/covas_mobile_old/lib/l10n/app_localizations.dart new file mode 100644 index 0000000..502fa07 --- /dev/null +++ b/covas_mobile_old/lib/l10n/app_localizations.dart @@ -0,0 +1,977 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:intl/intl.dart' as intl; + +import 'app_localizations_de.dart'; +import 'app_localizations_en.dart'; +import 'app_localizations_fr.dart'; + +// ignore_for_file: type=lint + +/// Callers can lookup localized strings with an instance of AppLocalizations +/// returned by `AppLocalizations.of(context)`. +/// +/// Applications need to include `AppLocalizations.delegate()` in their app's +/// `localizationDelegates` list, and the locales they support in the app's +/// `supportedLocales` list. For example: +/// +/// ```dart +/// import 'l10n/app_localizations.dart'; +/// +/// return MaterialApp( +/// localizationsDelegates: AppLocalizations.localizationsDelegates, +/// supportedLocales: AppLocalizations.supportedLocales, +/// home: MyApplicationHome(), +/// ); +/// ``` +/// +/// ## Update pubspec.yaml +/// +/// Please make sure to update your pubspec.yaml to include the following +/// packages: +/// +/// ```yaml +/// dependencies: +/// # Internationalization support. +/// flutter_localizations: +/// sdk: flutter +/// intl: any # Use the pinned version from flutter_localizations +/// +/// # Rest of dependencies +/// ``` +/// +/// ## iOS Applications +/// +/// iOS applications define key application metadata, including supported +/// locales, in an Info.plist file that is built into the application bundle. +/// To configure the locales supported by your app, you’ll need to edit this +/// file. +/// +/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file. +/// Then, in the Project Navigator, open the Info.plist file under the Runner +/// project’s Runner folder. +/// +/// Next, select the Information Property List item, select Add Item from the +/// Editor menu, then select Localizations from the pop-up menu. +/// +/// Select and expand the newly-created Localizations item then, for each +/// locale your application supports, add a new item and select the locale +/// you wish to add from the pop-up menu in the Value field. This list should +/// be consistent with the languages listed in the AppLocalizations.supportedLocales +/// property. +abstract class AppLocalizations { + AppLocalizations(String locale) + : localeName = intl.Intl.canonicalizedLocale(locale.toString()); + + final String localeName; + + static AppLocalizations? of(BuildContext context) { + return Localizations.of(context, AppLocalizations); + } + + static const LocalizationsDelegate delegate = + _AppLocalizationsDelegate(); + + /// A list of this localizations delegate along with the default localizations + /// delegates. + /// + /// Returns a list of localizations delegates containing this delegate along with + /// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, + /// and GlobalWidgetsLocalizations.delegate. + /// + /// Additional delegates can be added by appending to this list in + /// MaterialApp. This list does not have to be used at all if a custom list + /// of delegates is preferred or required. + static const List> localizationsDelegates = + >[ + delegate, + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ]; + + /// A list of this localizations delegate's supported locales. + static const List supportedLocales = [ + Locale('de'), + Locale('en'), + Locale('fr') + ]; + + /// No description provided for @menu_list. + /// + /// In en, this message translates to: + /// **'Event list menu'** + String get menu_list; + + /// No description provided for @language. + /// + /// In en, this message translates to: + /// **'Language'** + String get language; + + /// No description provided for @home. + /// + /// In en, this message translates to: + /// **'Home'** + String get home; + + /// No description provided for @settings. + /// + /// In en, this message translates to: + /// **'Settings'** + String get settings; + + /// No description provided for @update_profile. + /// + /// In en, this message translates to: + /// **'Update profile'** + String get update_profile; + + /// No description provided for @about. + /// + /// In en, this message translates to: + /// **'About'** + String get about; + + /// No description provided for @log_out. + /// + /// In en, this message translates to: + /// **'Log out'** + String get log_out; + + /// No description provided for @french. + /// + /// In en, this message translates to: + /// **'French'** + String get french; + + /// No description provided for @english. + /// + /// In en, this message translates to: + /// **'English'** + String get english; + + /// No description provided for @german. + /// + /// In en, this message translates to: + /// **'German'** + String get german; + + /// No description provided for @select_language. + /// + /// In en, this message translates to: + /// **'Select language'** + String get select_language; + + /// No description provided for @search_item. + /// + /// In en, this message translates to: + /// **'Search by item'** + String get search_item; + + /// No description provided for @search_tag. + /// + /// In en, this message translates to: + /// **'Search by tags'** + String get search_tag; + + /// No description provided for @search_geographical. + /// + /// In en, this message translates to: + /// **'Search by geographical zone'** + String get search_geographical; + + /// No description provided for @show_date_field. + /// + /// In en, this message translates to: + /// **'Show Date Fields'** + String get show_date_field; + + /// No description provided for @hide_date_field. + /// + /// In en, this message translates to: + /// **'Hide Date Fields'** + String get hide_date_field; + + /// No description provided for @no_data. + /// + /// In en, this message translates to: + /// **'No data available'** + String get no_data; + + /// No description provided for @search. + /// + /// In en, this message translates to: + /// **'Search'** + String get search; + + /// No description provided for @no_events. + /// + /// In en, this message translates to: + /// **'No events available for this location.'** + String get no_events; + + /// No description provided for @start_date. + /// + /// In en, this message translates to: + /// **'Start date'** + String get start_date; + + /// No description provided for @end_date. + /// + /// In en, this message translates to: + /// **'End date'** + String get end_date; + + /// No description provided for @failed_suggestions. + /// + /// In en, this message translates to: + /// **'Failed to load suggestions'** + String get failed_suggestions; + + /// No description provided for @error. + /// + /// In en, this message translates to: + /// **'Error'** + String get error; + + /// No description provided for @password_different. + /// + /// In en, this message translates to: + /// **'Must write a different password'** + String get password_different; + + /// No description provided for @create. + /// + /// In en, this message translates to: + /// **'Creation'** + String get create; + + /// No description provided for @user_create. + /// + /// In en, this message translates to: + /// **'Your user created'** + String get user_create; + + /// No description provided for @user_update. + /// + /// In en, this message translates to: + /// **'Your user updated'** + String get user_update; + + /// No description provided for @request_error. + /// + /// In en, this message translates to: + /// **'Poorly constructed query'** + String get request_error; + + /// No description provided for @incorrect_password. + /// + /// In en, this message translates to: + /// **'Incorrect password'** + String get incorrect_password; + + /// No description provided for @unknown_user. + /// + /// In en, this message translates to: + /// **'Unknown user'** + String get unknown_user; + + /// No description provided for @disabled_user. + /// + /// In en, this message translates to: + /// **'User disabled'** + String get disabled_user; + + /// No description provided for @invalid_token. + /// + /// In en, this message translates to: + /// **'Invalid token'** + String get invalid_token; + + /// No description provided for @internal_error_server. + /// + /// In en, this message translates to: + /// **'Internal error server'** + String get internal_error_server; + + /// No description provided for @unknown_error_auth. + /// + /// In en, this message translates to: + /// **'Unknown error authentification'** + String get unknown_error_auth; + + /// No description provided for @required_input. + /// + /// In en, this message translates to: + /// **'Required input'** + String get required_input; + + /// No description provided for @create_profile. + /// + /// In en, this message translates to: + /// **'Create profile'** + String get create_profile; + + /// No description provided for @edit_pseudo. + /// + /// In en, this message translates to: + /// **'Edit pseudo'** + String get edit_pseudo; + + /// No description provided for @password. + /// + /// In en, this message translates to: + /// **'Password'** + String get password; + + /// No description provided for @enter_password. + /// + /// In en, this message translates to: + /// **'Enter the passord'** + String get enter_password; + + /// No description provided for @password_confirmed. + /// + /// In en, this message translates to: + /// **'Password confirmed'** + String get password_confirmed; + + /// No description provided for @last_name. + /// + /// In en, this message translates to: + /// **'Last name'** + String get last_name; + + /// No description provided for @first_name. + /// + /// In en, this message translates to: + /// **'First name'** + String get first_name; + + /// No description provided for @email. + /// + /// In en, this message translates to: + /// **'Mail'** + String get email; + + /// No description provided for @edit_last_name. + /// + /// In en, this message translates to: + /// **'Edit name'** + String get edit_last_name; + + /// No description provided for @edit_first_name. + /// + /// In en, this message translates to: + /// **'Edit first name'** + String get edit_first_name; + + /// No description provided for @edit_email. + /// + /// In en, this message translates to: + /// **'Edit email address'** + String get edit_email; + + /// No description provided for @birth_date. + /// + /// In en, this message translates to: + /// **'Birth date'** + String get birth_date; + + /// No description provided for @edit_birth. + /// + /// In en, this message translates to: + /// **'Edit birth date'** + String get edit_birth; + + /// No description provided for @create_profile_button. + /// + /// In en, this message translates to: + /// **'Create profile'** + String get create_profile_button; + + /// No description provided for @take_picture. + /// + /// In en, this message translates to: + /// **'Take a picture'** + String get take_picture; + + /// No description provided for @error_ia. + /// + /// In en, this message translates to: + /// **'Google AI failed to analyze picture. Retry with another one'** + String get error_ia; + + /// No description provided for @no_data_geo. + /// + /// In en, this message translates to: + /// **'No geographical data'** + String get no_data_geo; + + /// No description provided for @response_status_update. + /// + /// In en, this message translates to: + /// **'response status code update'** + String get response_status_update; + + /// No description provided for @error_token. + /// + /// In en, this message translates to: + /// **'Token error'** + String get error_token; + + /// No description provided for @error_format. + /// + /// In en, this message translates to: + /// **'Data format error given by AI'** + String get error_format; + + /// No description provided for @display_picture. + /// + /// In en, this message translates to: + /// **'Display the Picture'** + String get display_picture; + + /// No description provided for @analyze_image. + /// + /// In en, this message translates to: + /// **'Image Analyze in progress'** + String get analyze_image; + + /// No description provided for @loading_progress. + /// + /// In en, this message translates to: + /// **'Loading progress'** + String get loading_progress; + + /// No description provided for @error_event. + /// + /// In en, this message translates to: + /// **'Event error'** + String get error_event; + + /// No description provided for @no_future_event. + /// + /// In en, this message translates to: + /// **'No future event'** + String get no_future_event; + + /// No description provided for @error_user. + /// + /// In en, this message translates to: + /// **'Error user'** + String get error_user; + + /// No description provided for @empty_input. + /// + /// In en, this message translates to: + /// **'Empty input'** + String get empty_input; + + /// No description provided for @info_event. + /// + /// In en, this message translates to: + /// **'Event info'** + String get info_event; + + /// No description provided for @event_already. + /// + /// In en, this message translates to: + /// **'Event already exists'** + String get event_already; + + /// No description provided for @picture_error. + /// + /// In en, this message translates to: + /// **'Picture error'** + String get picture_error; + + /// No description provided for @no_picture_published. + /// + /// In en, this message translates to: + /// **'No picture published'** + String get no_picture_published; + + /// No description provided for @event_update. + /// + /// In en, this message translates to: + /// **'Event updated'** + String get event_update; + + /// No description provided for @location. + /// + /// In en, this message translates to: + /// **'Location'** + String get location; + + /// No description provided for @add_event. + /// + /// In en, this message translates to: + /// **'Add or Update a event'** + String get add_event; + + /// No description provided for @edit_image. + /// + /// In en, this message translates to: + /// **'Edit pictures'** + String get edit_image; + + /// No description provided for @name. + /// + /// In en, this message translates to: + /// **'Name'** + String get name; + + /// No description provided for @edit_event_name. + /// + /// In en, this message translates to: + /// **'Edit event name'** + String get edit_event_name; + + /// No description provided for @start_time. + /// + /// In en, this message translates to: + /// **'Start time'** + String get start_time; + + /// No description provided for @end_time. + /// + /// In en, this message translates to: + /// **'End time'** + String get end_time; + + /// No description provided for @select_date. + /// + /// In en, this message translates to: + /// **'Click to select a date'** + String get select_date; + + /// No description provided for @select_time. + /// + /// In en, this message translates to: + /// **'Click to select a time'** + String get select_time; + + /// No description provided for @tag. + /// + /// In en, this message translates to: + /// **'Tags'** + String get tag; + + /// No description provided for @already_tag. + /// + /// In en, this message translates to: + /// **'You have already this tags'** + String get already_tag; + + /// No description provided for @enter_tag. + /// + /// In en, this message translates to: + /// **'Enter a tag'** + String get enter_tag; + + /// No description provided for @organizer. + /// + /// In en, this message translates to: + /// **'Organizer'** + String get organizer; + + /// No description provided for @already_organiser. + /// + /// In en, this message translates to: + /// **'You have already a organizer'** + String get already_organiser; + + /// No description provided for @enter_organizer. + /// + /// In en, this message translates to: + /// **'Enter a organizer'** + String get enter_organizer; + + /// No description provided for @description. + /// + /// In en, this message translates to: + /// **'Description'** + String get description; + + /// No description provided for @describe_event. + /// + /// In en, this message translates to: + /// **'Describe event'** + String get describe_event; + + /// No description provided for @add. + /// + /// In en, this message translates to: + /// **'Add'** + String get add; + + /// No description provided for @different_password_error. + /// + /// In en, this message translates to: + /// **'Different password'** + String get different_password_error; + + /// No description provided for @update. + /// + /// In en, this message translates to: + /// **'Update'** + String get update; + + /// No description provided for @updated. + /// + /// In en, this message translates to: + /// **'Updated'** + String get updated; + + /// No description provided for @settings_updated. + /// + /// In en, this message translates to: + /// **'Settings updated'** + String get settings_updated; + + /// No description provided for @define_kilometer. + /// + /// In en, this message translates to: + /// **'Define Kilometer'** + String get define_kilometer; + + /// No description provided for @email_sent. + /// + /// In en, this message translates to: + /// **'Email has been sent'** + String get email_sent; + + /// No description provided for @forgot_password. + /// + /// In en, this message translates to: + /// **'Forgot password'** + String get forgot_password; + + /// No description provided for @enter_email. + /// + /// In en, this message translates to: + /// **'Enter the email'** + String get enter_email; + + /// No description provided for @send_email. + /// + /// In en, this message translates to: + /// **'Send email'** + String get send_email; + + /// No description provided for @invalid_cache. + /// + /// In en, this message translates to: + /// **'Invalid cache'** + String get invalid_cache; + + /// No description provided for @item_date. + /// + /// In en, this message translates to: + /// **'Date : '** + String get item_date; + + /// No description provided for @item_maps. + /// + /// In en, this message translates to: + /// **'Maps : '** + String get item_maps; + + /// No description provided for @item_organizer. + /// + /// In en, this message translates to: + /// **'Organizer : '** + String get item_organizer; + + /// No description provided for @item_description. + /// + /// In en, this message translates to: + /// **'Description : '** + String get item_description; + + /// No description provided for @item_tags. + /// + /// In en, this message translates to: + /// **'Tags : '** + String get item_tags; + + /// No description provided for @failed_auth. + /// + /// In en, this message translates to: + /// **'Authentification failed'** + String get failed_auth; + + /// No description provided for @login_page. + /// + /// In en, this message translates to: + /// **'Login page'** + String get login_page; + + /// No description provided for @pseudo. + /// + /// In en, this message translates to: + /// **'Pseudo'** + String get pseudo; + + /// No description provided for @enter_existing_pseudo. + /// + /// In en, this message translates to: + /// **'Enter a existing pseudo'** + String get enter_existing_pseudo; + + /// No description provided for @remembr_me. + /// + /// In en, this message translates to: + /// **'Remember me'** + String get remembr_me; + + /// No description provided for @new_user. + /// + /// In en, this message translates to: + /// **'New User? Create Account'** + String get new_user; + + /// No description provided for @sign_in. + /// + /// In en, this message translates to: + /// **'Sign in'** + String get sign_in; + + /// No description provided for @map_token. + /// + /// In en, this message translates to: + /// **'Mapbox Access Token is not available'** + String get map_token; + + /// No description provided for @geo_disabled. + /// + /// In en, this message translates to: + /// **'Location services are disabled.'** + String get geo_disabled; + + /// No description provided for @permission_denied. + /// + /// In en, this message translates to: + /// **'Location permissions are denied.'** + String get permission_denied; + + /// No description provided for @enable_permission. + /// + /// In en, this message translates to: + /// **'Location permissions are permanently denied. Enable them in settings.'** + String get enable_permission; + + /// No description provided for @no_last_position. + /// + /// In en, this message translates to: + /// **'No last known position available.'** + String get no_last_position; + + /// No description provided for @failed_location. + /// + /// In en, this message translates to: + /// **'Failed to get user location'** + String get failed_location; + + /// No description provided for @failed_fetch. + /// + /// In en, this message translates to: + /// **'Failed to fetch the route'** + String get failed_fetch; + + /// No description provided for @invalid_coordinates_symbol. + /// + /// In en, this message translates to: + /// **'Invalid coordinates, cannot add symbol.'** + String get invalid_coordinates_symbol; + + /// No description provided for @error_symbol. + /// + /// In en, this message translates to: + /// **'Error when adding symbol.'** + String get error_symbol; + + /// No description provided for @position_not_init. + /// + /// In en, this message translates to: + /// **'User position is not yet initialized. Try again.'** + String get position_not_init; + + /// No description provided for @invalid_coordinates. + /// + /// In en, this message translates to: + /// **'Invalid coordinates.'** + String get invalid_coordinates; + + /// No description provided for @walking. + /// + /// In en, this message translates to: + /// **'Walking'** + String get walking; + + /// No description provided for @cycling. + /// + /// In en, this message translates to: + /// **'Cycling'** + String get cycling; + + /// No description provided for @driving. + /// + /// In en, this message translates to: + /// **'Driving'** + String get driving; + + /// No description provided for @get_direction. + /// + /// In en, this message translates to: + /// **'Get Directions and Markers'** + String get get_direction; + + /// No description provided for @missing_token. + /// + /// In en, this message translates to: + /// **'Missing access token'** + String get missing_token; + + /// No description provided for @geocoding_error. + /// + /// In en, this message translates to: + /// **'Error when geocoding'** + String get geocoding_error; + + /// No description provided for @no_found_place. + /// + /// In en, this message translates to: + /// **'No found place'** + String get no_found_place; + + /// No description provided for @upload_error. + /// + /// In en, this message translates to: + /// **'Error when image uploading'** + String get upload_error; + + /// No description provided for @event_added. + /// + /// In en, this message translates to: + /// **'Event added'** + String get event_added; + + /// No description provided for @unknown_error. + /// + /// In en, this message translates to: + /// **'Unknown error'** + String get unknown_error; + + /// No description provided for @app_error. + /// + /// In en, this message translates to: + /// **'Application error'** + String get app_error; + + /// No description provided for @at. + /// + /// In en, this message translates to: + /// **'at'** + String get at; + + /// No description provided for @to_date. + /// + /// In en, this message translates to: + /// **'to'** + String get to_date; + + /// No description provided for @item_link. + /// + /// In en, this message translates to: + /// **'Link : '** + String get item_link; + + /// No description provided for @item_ticket. + /// + /// In en, this message translates to: + /// **'Ticket : '** + String get item_ticket; + + /// No description provided for @link. + /// + /// In en, this message translates to: + /// **'Link'** + String get link; + + /// No description provided for @edit_link. + /// + /// In en, this message translates to: + /// **'Edit link name'** + String get edit_link; + + /// No description provided for @ticket. + /// + /// In en, this message translates to: + /// **'Ticket'** + String get ticket; + + /// No description provided for @edit_ticket. + /// + /// In en, this message translates to: + /// **'Edit ticket link'** + String get edit_ticket; + + /// No description provided for @toogle_interest. + /// + /// In en, this message translates to: + /// **'Error toggle interest'** + String get toogle_interest; + + /// No description provided for @error_update. + /// + /// In en, this message translates to: + /// **'Error when updating'** + String get error_update; + + /// No description provided for @count_interested. + /// + /// In en, this message translates to: + /// **'Interested people number'** + String get count_interested; +} + +class _AppLocalizationsDelegate + extends LocalizationsDelegate { + const _AppLocalizationsDelegate(); + + @override + Future load(Locale locale) { + return SynchronousFuture(lookupAppLocalizations(locale)); + } + + @override + bool isSupported(Locale locale) => + ['de', 'en', 'fr'].contains(locale.languageCode); + + @override + bool shouldReload(_AppLocalizationsDelegate old) => false; +} + +AppLocalizations lookupAppLocalizations(Locale locale) { + // Lookup logic when only language code is specified. + switch (locale.languageCode) { + case 'de': + return AppLocalizationsDe(); + case 'en': + return AppLocalizationsEn(); + case 'fr': + return AppLocalizationsFr(); + } + + throw FlutterError( + 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.'); +} diff --git a/covas_mobile_old/lib/l10n/app_localizations_de.dart b/covas_mobile_old/lib/l10n/app_localizations_de.dart new file mode 100644 index 0000000..46d179a --- /dev/null +++ b/covas_mobile_old/lib/l10n/app_localizations_de.dart @@ -0,0 +1,434 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for German (`de`). +class AppLocalizationsDe extends AppLocalizations { + AppLocalizationsDe([String locale = 'de']) : super(locale); + + @override + String get menu_list => 'Veranstaltungsmenü'; + + @override + String get language => 'Sprache'; + + @override + String get home => 'Startseite'; + + @override + String get settings => 'Einstellungen'; + + @override + String get update_profile => 'Profil aktualisieren'; + + @override + String get about => 'Über'; + + @override + String get log_out => 'Abmelden'; + + @override + String get french => 'Französisch'; + + @override + String get english => 'Englisch'; + + @override + String get german => 'Deutsch'; + + @override + String get select_language => 'Sprache auswählen'; + + @override + String get search_item => 'Nach Element suchen'; + + @override + String get search_tag => 'Nach Schlagwörtern suchen'; + + @override + String get search_geographical => 'Nach geografischer Zone suchen'; + + @override + String get show_date_field => 'Datumsfelder anzeigen'; + + @override + String get hide_date_field => 'Datumsfelder ausblenden'; + + @override + String get no_data => 'Keine Daten verfügbar'; + + @override + String get search => 'Suchen'; + + @override + String get no_events => 'Keine Veranstaltungen für diesen Ort verfügbar.'; + + @override + String get start_date => 'Anfangsdatum'; + + @override + String get end_date => 'Enddatum'; + + @override + String get failed_suggestions => 'Vorschläge konnten nicht geladen werden'; + + @override + String get error => 'Fehler'; + + @override + String get password_different => 'Ein anderes Passwort eingeben'; + + @override + String get create => 'Erstellung'; + + @override + String get user_create => 'Benutzer wurde erstellt'; + + @override + String get user_update => 'Benutzer wurde aktualisiert'; + + @override + String get request_error => 'Fehlerhafte Anfrage'; + + @override + String get incorrect_password => 'Falsches Passwort'; + + @override + String get unknown_user => 'Unbekannter Benutzer'; + + @override + String get disabled_user => 'Benutzer deaktiviert'; + + @override + String get invalid_token => 'Ungültiger Token'; + + @override + String get internal_error_server => 'Interner Serverfehler'; + + @override + String get unknown_error_auth => 'Unbekannter Authentifizierungsfehler'; + + @override + String get required_input => 'Pflichtfeld'; + + @override + String get create_profile => 'Profil erstellen'; + + @override + String get edit_pseudo => 'Benutzernamen bearbeiten'; + + @override + String get password => 'Passwort'; + + @override + String get enter_password => 'Passwort eingeben'; + + @override + String get password_confirmed => 'Passwort bestätigt'; + + @override + String get last_name => 'Nachname'; + + @override + String get first_name => 'Vorname'; + + @override + String get email => 'E-Mail'; + + @override + String get edit_last_name => 'Nachnamen bearbeiten'; + + @override + String get edit_first_name => 'Vornamen bearbeiten'; + + @override + String get edit_email => 'E-Mail-Adresse bearbeiten'; + + @override + String get birth_date => 'Geburtsdatum'; + + @override + String get edit_birth => 'Geburtsdatum bearbeiten'; + + @override + String get create_profile_button => 'Profil erstellen'; + + @override + String get take_picture => 'Foto aufnehmen'; + + @override + String get error_ia => + 'Google KI konnte das Bild nicht analysieren. Bitte ein anderes versuchen.'; + + @override + String get no_data_geo => 'Keine geografischen Daten'; + + @override + String get response_status_update => 'Statuscode-Antwort aktualisieren'; + + @override + String get error_token => 'Token-Fehler'; + + @override + String get error_format => 'Vom KI geliefertes Datenformat ist fehlerhaft'; + + @override + String get display_picture => 'Bild anzeigen'; + + @override + String get analyze_image => 'Bildanalyse läuft'; + + @override + String get loading_progress => 'Ladefortschritt'; + + @override + String get error_event => 'Veranstaltungsfehler'; + + @override + String get no_future_event => 'Keine zukünftigen Veranstaltungen'; + + @override + String get error_user => 'Benutzerfehler'; + + @override + String get empty_input => 'Eingabefeld leer'; + + @override + String get info_event => 'Veranstaltungsinfo'; + + @override + String get event_already => 'Veranstaltung existiert bereits'; + + @override + String get picture_error => 'Bildfehler'; + + @override + String get no_picture_published => 'Kein Bild veröffentlicht'; + + @override + String get event_update => 'Veranstaltung aktualisiert'; + + @override + String get location => 'Ort'; + + @override + String get add_event => 'Veranstaltung hinzufügen oder aktualisieren'; + + @override + String get edit_image => 'Bilder bearbeiten'; + + @override + String get name => 'Name'; + + @override + String get edit_event_name => 'Veranstaltungsname bearbeiten'; + + @override + String get start_time => 'Startzeit'; + + @override + String get end_time => 'Endzeit'; + + @override + String get select_date => 'Zum Auswählen eines Datums klicken'; + + @override + String get select_time => 'Zum Auswählen einer Uhrzeit klicken'; + + @override + String get tag => 'Schlagwörter'; + + @override + String get already_tag => 'Dieses Schlagwort ist bereits vorhanden'; + + @override + String get enter_tag => 'Ein Schlagwort eingeben'; + + @override + String get organizer => 'Veranstalter'; + + @override + String get already_organiser => 'Veranstalter bereits vorhanden'; + + @override + String get enter_organizer => 'Veranstalter eingeben'; + + @override + String get description => 'Beschreibung'; + + @override + String get describe_event => 'Veranstaltung beschreiben'; + + @override + String get add => 'Hinzufügen'; + + @override + String get different_password_error => 'Passwörter stimmen nicht überein'; + + @override + String get update => 'Aktualisieren'; + + @override + String get updated => 'Aktualisiert'; + + @override + String get settings_updated => 'Einstellungen aktualisiert'; + + @override + String get define_kilometer => 'Kilometer definieren'; + + @override + String get email_sent => 'E-Mail wurde gesendet'; + + @override + String get forgot_password => 'Passwort vergessen'; + + @override + String get enter_email => 'E-Mail eingeben'; + + @override + String get send_email => 'E-Mail senden'; + + @override + String get invalid_cache => 'Ungültiger Cache'; + + @override + String get item_date => 'Datum : '; + + @override + String get item_maps => 'Karte : '; + + @override + String get item_organizer => 'Veranstalter : '; + + @override + String get item_description => 'Beschreibung : '; + + @override + String get item_tags => 'Schlagwörter : '; + + @override + String get failed_auth => 'Authentifizierung fehlgeschlagen'; + + @override + String get login_page => 'Anmeldeseite'; + + @override + String get pseudo => 'Benutzername'; + + @override + String get enter_existing_pseudo => 'Vorhandenen Benutzernamen eingeben'; + + @override + String get remembr_me => 'Angemeldet bleiben'; + + @override + String get new_user => 'Neuer Benutzer? Konto erstellen'; + + @override + String get sign_in => 'Anmelden'; + + @override + String get map_token => 'Mapbox-Zugangstoken ist nicht verfügbar'; + + @override + String get geo_disabled => 'Standortdienste sind deaktiviert.'; + + @override + String get permission_denied => 'Standortberechtigungen wurden verweigert.'; + + @override + String get enable_permission => + 'Standortberechtigungen dauerhaft verweigert. Bitte in den Einstellungen aktivieren.'; + + @override + String get no_last_position => 'Keine letzte bekannte Position verfügbar.'; + + @override + String get failed_location => 'Standort konnte nicht ermittelt werden'; + + @override + String get failed_fetch => 'Route konnte nicht abgerufen werden'; + + @override + String get invalid_coordinates_symbol => + 'Ungültige Koordinaten, Symbol kann nicht hinzugefügt werden.'; + + @override + String get error_symbol => 'Fehler beim Hinzufügen des Symbols.'; + + @override + String get position_not_init => + 'Benutzerposition noch nicht initialisiert. Erneut versuchen.'; + + @override + String get invalid_coordinates => 'Ungültige Koordinaten.'; + + @override + String get walking => 'Zu Fuß'; + + @override + String get cycling => 'Mit dem Fahrrad'; + + @override + String get driving => 'Mit dem Auto'; + + @override + String get get_direction => 'Wegbeschreibung und Markierungen anzeigen'; + + @override + String get missing_token => 'Zugangstoken fehlt'; + + @override + String get geocoding_error => 'Fehler bei der Geokodierung'; + + @override + String get no_found_place => 'Kein Ort gefunden'; + + @override + String get upload_error => 'Fehler beim Hochladen des Bildes'; + + @override + String get event_added => 'Veranstaltung hinzugefügt'; + + @override + String get unknown_error => 'Unbekannter Fehler'; + + @override + String get app_error => 'Anwendungsfehler'; + + @override + String get at => 'um'; + + @override + String get to_date => 'bis'; + + @override + String get item_link => 'Link : '; + + @override + String get item_ticket => 'Abendkarte : '; + + @override + String get link => 'Link'; + + @override + String get edit_link => 'Linkereignis bearbeiten'; + + @override + String get ticket => 'Abendkarte'; + + @override + String get edit_ticket => 'Ticketlink bearbeiten'; + + @override + String get toogle_interest => 'Fehler beim Umschalten des Interesses'; + + @override + String get error_update => 'Fehler beim Update'; + + @override + String get count_interested => 'Anzahl der Interessenten'; +} diff --git a/covas_mobile_old/lib/l10n/app_localizations_en.dart b/covas_mobile_old/lib/l10n/app_localizations_en.dart new file mode 100644 index 0000000..59d7a22 --- /dev/null +++ b/covas_mobile_old/lib/l10n/app_localizations_en.dart @@ -0,0 +1,434 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for English (`en`). +class AppLocalizationsEn extends AppLocalizations { + AppLocalizationsEn([String locale = 'en']) : super(locale); + + @override + String get menu_list => 'Event list menu'; + + @override + String get language => 'Language'; + + @override + String get home => 'Home'; + + @override + String get settings => 'Settings'; + + @override + String get update_profile => 'Update profile'; + + @override + String get about => 'About'; + + @override + String get log_out => 'Log out'; + + @override + String get french => 'French'; + + @override + String get english => 'English'; + + @override + String get german => 'German'; + + @override + String get select_language => 'Select language'; + + @override + String get search_item => 'Search by item'; + + @override + String get search_tag => 'Search by tags'; + + @override + String get search_geographical => 'Search by geographical zone'; + + @override + String get show_date_field => 'Show Date Fields'; + + @override + String get hide_date_field => 'Hide Date Fields'; + + @override + String get no_data => 'No data available'; + + @override + String get search => 'Search'; + + @override + String get no_events => 'No events available for this location.'; + + @override + String get start_date => 'Start date'; + + @override + String get end_date => 'End date'; + + @override + String get failed_suggestions => 'Failed to load suggestions'; + + @override + String get error => 'Error'; + + @override + String get password_different => 'Must write a different password'; + + @override + String get create => 'Creation'; + + @override + String get user_create => 'Your user created'; + + @override + String get user_update => 'Your user updated'; + + @override + String get request_error => 'Poorly constructed query'; + + @override + String get incorrect_password => 'Incorrect password'; + + @override + String get unknown_user => 'Unknown user'; + + @override + String get disabled_user => 'User disabled'; + + @override + String get invalid_token => 'Invalid token'; + + @override + String get internal_error_server => 'Internal error server'; + + @override + String get unknown_error_auth => 'Unknown error authentification'; + + @override + String get required_input => 'Required input'; + + @override + String get create_profile => 'Create profile'; + + @override + String get edit_pseudo => 'Edit pseudo'; + + @override + String get password => 'Password'; + + @override + String get enter_password => 'Enter the passord'; + + @override + String get password_confirmed => 'Password confirmed'; + + @override + String get last_name => 'Last name'; + + @override + String get first_name => 'First name'; + + @override + String get email => 'Mail'; + + @override + String get edit_last_name => 'Edit name'; + + @override + String get edit_first_name => 'Edit first name'; + + @override + String get edit_email => 'Edit email address'; + + @override + String get birth_date => 'Birth date'; + + @override + String get edit_birth => 'Edit birth date'; + + @override + String get create_profile_button => 'Create profile'; + + @override + String get take_picture => 'Take a picture'; + + @override + String get error_ia => + 'Google AI failed to analyze picture. Retry with another one'; + + @override + String get no_data_geo => 'No geographical data'; + + @override + String get response_status_update => 'response status code update'; + + @override + String get error_token => 'Token error'; + + @override + String get error_format => 'Data format error given by AI'; + + @override + String get display_picture => 'Display the Picture'; + + @override + String get analyze_image => 'Image Analyze in progress'; + + @override + String get loading_progress => 'Loading progress'; + + @override + String get error_event => 'Event error'; + + @override + String get no_future_event => 'No future event'; + + @override + String get error_user => 'Error user'; + + @override + String get empty_input => 'Empty input'; + + @override + String get info_event => 'Event info'; + + @override + String get event_already => 'Event already exists'; + + @override + String get picture_error => 'Picture error'; + + @override + String get no_picture_published => 'No picture published'; + + @override + String get event_update => 'Event updated'; + + @override + String get location => 'Location'; + + @override + String get add_event => 'Add or Update a event'; + + @override + String get edit_image => 'Edit pictures'; + + @override + String get name => 'Name'; + + @override + String get edit_event_name => 'Edit event name'; + + @override + String get start_time => 'Start time'; + + @override + String get end_time => 'End time'; + + @override + String get select_date => 'Click to select a date'; + + @override + String get select_time => 'Click to select a time'; + + @override + String get tag => 'Tags'; + + @override + String get already_tag => 'You have already this tags'; + + @override + String get enter_tag => 'Enter a tag'; + + @override + String get organizer => 'Organizer'; + + @override + String get already_organiser => 'You have already a organizer'; + + @override + String get enter_organizer => 'Enter a organizer'; + + @override + String get description => 'Description'; + + @override + String get describe_event => 'Describe event'; + + @override + String get add => 'Add'; + + @override + String get different_password_error => 'Different password'; + + @override + String get update => 'Update'; + + @override + String get updated => 'Updated'; + + @override + String get settings_updated => 'Settings updated'; + + @override + String get define_kilometer => 'Define Kilometer'; + + @override + String get email_sent => 'Email has been sent'; + + @override + String get forgot_password => 'Forgot password'; + + @override + String get enter_email => 'Enter the email'; + + @override + String get send_email => 'Send email'; + + @override + String get invalid_cache => 'Invalid cache'; + + @override + String get item_date => 'Date : '; + + @override + String get item_maps => 'Maps : '; + + @override + String get item_organizer => 'Organizer : '; + + @override + String get item_description => 'Description : '; + + @override + String get item_tags => 'Tags : '; + + @override + String get failed_auth => 'Authentification failed'; + + @override + String get login_page => 'Login page'; + + @override + String get pseudo => 'Pseudo'; + + @override + String get enter_existing_pseudo => 'Enter a existing pseudo'; + + @override + String get remembr_me => 'Remember me'; + + @override + String get new_user => 'New User? Create Account'; + + @override + String get sign_in => 'Sign in'; + + @override + String get map_token => 'Mapbox Access Token is not available'; + + @override + String get geo_disabled => 'Location services are disabled.'; + + @override + String get permission_denied => 'Location permissions are denied.'; + + @override + String get enable_permission => + 'Location permissions are permanently denied. Enable them in settings.'; + + @override + String get no_last_position => 'No last known position available.'; + + @override + String get failed_location => 'Failed to get user location'; + + @override + String get failed_fetch => 'Failed to fetch the route'; + + @override + String get invalid_coordinates_symbol => + 'Invalid coordinates, cannot add symbol.'; + + @override + String get error_symbol => 'Error when adding symbol.'; + + @override + String get position_not_init => + 'User position is not yet initialized. Try again.'; + + @override + String get invalid_coordinates => 'Invalid coordinates.'; + + @override + String get walking => 'Walking'; + + @override + String get cycling => 'Cycling'; + + @override + String get driving => 'Driving'; + + @override + String get get_direction => 'Get Directions and Markers'; + + @override + String get missing_token => 'Missing access token'; + + @override + String get geocoding_error => 'Error when geocoding'; + + @override + String get no_found_place => 'No found place'; + + @override + String get upload_error => 'Error when image uploading'; + + @override + String get event_added => 'Event added'; + + @override + String get unknown_error => 'Unknown error'; + + @override + String get app_error => 'Application error'; + + @override + String get at => 'at'; + + @override + String get to_date => 'to'; + + @override + String get item_link => 'Link : '; + + @override + String get item_ticket => 'Ticket : '; + + @override + String get link => 'Link'; + + @override + String get edit_link => 'Edit link name'; + + @override + String get ticket => 'Ticket'; + + @override + String get edit_ticket => 'Edit ticket link'; + + @override + String get toogle_interest => 'Error toggle interest'; + + @override + String get error_update => 'Error when updating'; + + @override + String get count_interested => 'Interested people number'; +} diff --git a/covas_mobile_old/lib/l10n/app_localizations_fr.dart b/covas_mobile_old/lib/l10n/app_localizations_fr.dart new file mode 100644 index 0000000..8f1750b --- /dev/null +++ b/covas_mobile_old/lib/l10n/app_localizations_fr.dart @@ -0,0 +1,437 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for French (`fr`). +class AppLocalizationsFr extends AppLocalizations { + AppLocalizationsFr([String locale = 'fr']) : super(locale); + + @override + String get menu_list => 'Liste d\'évènement'; + + @override + String get language => 'Langue'; + + @override + String get home => 'Accueil'; + + @override + String get settings => 'Paramètres'; + + @override + String get update_profile => 'Modifier le profil'; + + @override + String get about => 'À propos'; + + @override + String get log_out => 'Se déconnecter'; + + @override + String get french => 'Français'; + + @override + String get english => 'Anglais'; + + @override + String get german => 'Allemand'; + + @override + String get select_language => 'Selectionne la langue'; + + @override + String get search_item => 'Recherche par item'; + + @override + String get search_tag => 'Recherche par tags'; + + @override + String get search_geographical => 'Recherche par zone géographique'; + + @override + String get show_date_field => 'Afficher champ date'; + + @override + String get hide_date_field => 'Cacher Date Fields'; + + @override + String get no_data => 'Aucune donnée disponible'; + + @override + String get search => 'Recherche'; + + @override + String get no_events => 'Pas d\'évènements dans cette localisation'; + + @override + String get start_date => 'Date de début'; + + @override + String get end_date => 'Date de fin'; + + @override + String get failed_suggestions => 'Echec de chargement des suggestions'; + + @override + String get error => 'Erreur'; + + @override + String get password_different => 'Tu dois écrire un mot de passe different'; + + @override + String get create => 'Création'; + + @override + String get user_create => 'Votre utilisateur a été créé'; + + @override + String get user_update => 'Votre utilisateur a été modifié'; + + @override + String get request_error => 'Requête mal construite'; + + @override + String get incorrect_password => 'Mot de passe incorrect'; + + @override + String get unknown_user => 'Utilisateur inconnu'; + + @override + String get disabled_user => 'Utilisateur désactivé'; + + @override + String get invalid_token => 'Token invalide'; + + @override + String get internal_error_server => 'Erreur interne de serveur'; + + @override + String get unknown_error_auth => 'Problème d\'authentification inconnu'; + + @override + String get required_input => 'Champ requis'; + + @override + String get create_profile => 'Creation profil'; + + @override + String get edit_pseudo => 'Modifier le pseudo'; + + @override + String get password => 'Mot de passe'; + + @override + String get enter_password => 'Entrez le password'; + + @override + String get password_confirmed => 'Confirmez le mot de passe'; + + @override + String get last_name => 'Nom'; + + @override + String get first_name => 'Prénom'; + + @override + String get email => 'Email'; + + @override + String get edit_last_name => 'Modifier le nom'; + + @override + String get edit_first_name => 'Modifier le prénom'; + + @override + String get edit_email => 'Modifier l\'email'; + + @override + String get birth_date => 'Date de naissance'; + + @override + String get edit_birth => 'Modifier la date de naissance'; + + @override + String get create_profile_button => 'Créer le profil'; + + @override + String get take_picture => 'Take a picture'; + + @override + String get error_ia => + 'L\'IA de Google n\'a pas su analyser l\'image. Recommencer avec une autre'; + + @override + String get no_data_geo => 'Aucune donnée géographique'; + + @override + String get response_status_update => + 'Code du statut de réponse de la modification'; + + @override + String get error_token => 'Erreur de token'; + + @override + String get error_format => 'Erreur de format de donnée fourni par l\'IA'; + + @override + String get display_picture => 'Display the Picture'; + + @override + String get analyze_image => 'Analyse de l\'image en cours'; + + @override + String get loading_progress => 'Chargement en cours'; + + @override + String get error_event => 'Erreur de l\'évènement'; + + @override + String get no_future_event => 'Évènement non futur'; + + @override + String get error_user => 'Erreur de l\'utilisateur'; + + @override + String get empty_input => 'Champ vide'; + + @override + String get info_event => 'Event info'; + + @override + String get event_already => 'Event already exists'; + + @override + String get picture_error => 'Erreur image'; + + @override + String get no_picture_published => 'Image non publiée'; + + @override + String get event_update => 'Évènement modifié'; + + @override + String get location => 'Lieu'; + + @override + String get add_event => 'Ajouter ou modifier un évènement'; + + @override + String get edit_image => 'Changer la photo'; + + @override + String get name => 'Nom'; + + @override + String get edit_event_name => 'Changer le nom de l\'évènement'; + + @override + String get start_time => 'Heure de début'; + + @override + String get end_time => 'Heure de fin'; + + @override + String get select_date => 'Cliquer pour selectionner une date'; + + @override + String get select_time => 'Cliquer pour selectionner une heure'; + + @override + String get tag => 'Tags'; + + @override + String get already_tag => 'Tu as déjà entré ce tag'; + + @override + String get enter_tag => 'Entrer un tag'; + + @override + String get organizer => 'Organisateur'; + + @override + String get already_organiser => 'Tu as déjà rentré cet organisateur'; + + @override + String get enter_organizer => 'Entrer un organisateur'; + + @override + String get description => 'Description'; + + @override + String get describe_event => 'Décrire l\'évènement'; + + @override + String get add => 'Ajouter'; + + @override + String get different_password_error => 'Mot de passe différent'; + + @override + String get update => 'Mettre à jour'; + + @override + String get updated => 'Mis à jour'; + + @override + String get settings_updated => 'Paramètre mis à jour'; + + @override + String get define_kilometer => 'Definir un kilomètre'; + + @override + String get email_sent => 'Email a été envoyé'; + + @override + String get forgot_password => 'Mot de passe oublié'; + + @override + String get enter_email => 'Entrez l\'email'; + + @override + String get send_email => 'Send email'; + + @override + String get invalid_cache => 'Cache invalide'; + + @override + String get item_date => 'Date : '; + + @override + String get item_maps => 'Carte : '; + + @override + String get item_organizer => 'Organisateurs : '; + + @override + String get item_description => 'Description : '; + + @override + String get item_tags => 'Tags : '; + + @override + String get failed_auth => 'Échec de l\'authenticaton'; + + @override + String get login_page => 'Page d\'authentification'; + + @override + String get pseudo => 'Pseudo'; + + @override + String get enter_existing_pseudo => 'Entrez un pseudo existant'; + + @override + String get remembr_me => 'Se souvenir de moi'; + + @override + String get new_user => 'Nouvel utilisateur ? Créer un compte'; + + @override + String get sign_in => 'Se connecter'; + + @override + String get map_token => 'Token d\'accès de Mapbox n\'est pas disponible'; + + @override + String get geo_disabled => 'Les services de localisation sont désactivés.'; + + @override + String get permission_denied => + 'Les permissions de localisation sont refusées.'; + + @override + String get enable_permission => + 'Les permissions de localisation sont toujours désactivés. Il faut les désactiver'; + + @override + String get no_last_position => 'Aucune position n\'est pas disponible.'; + + @override + String get failed_location => + 'Échec de récupération des données geographique'; + + @override + String get failed_fetch => 'Échec de récupération des routes'; + + @override + String get invalid_coordinates_symbol => + 'Coordonnées invalides. On ne peut pas ajouter le symbole'; + + @override + String get error_symbol => 'Erreur lors de l\'ajout du symbole'; + + @override + String get position_not_init => + 'Coordonnées non initialisées. Essaye encore.'; + + @override + String get invalid_coordinates => 'Coordonnées invalides'; + + @override + String get walking => 'Marche'; + + @override + String get cycling => 'Vélo'; + + @override + String get driving => 'Voiture'; + + @override + String get get_direction => 'Get Directions and Markers'; + + @override + String get missing_token => 'Token d\'accès manquant'; + + @override + String get geocoding_error => 'Erreur lors du geocodage'; + + @override + String get no_found_place => 'Lieu introuvable'; + + @override + String get upload_error => 'Erreur lors de l\'upload d\'image'; + + @override + String get event_added => 'Évènement ajouté'; + + @override + String get unknown_error => 'Erreur inconnue'; + + @override + String get app_error => 'Erreur d\'application'; + + @override + String get at => 'à'; + + @override + String get to_date => 'jusqu\'à'; + + @override + String get item_link => 'Lien : '; + + @override + String get item_ticket => 'Billet : '; + + @override + String get link => 'Lien'; + + @override + String get edit_link => 'Editer le lien'; + + @override + String get ticket => 'Billet'; + + @override + String get edit_ticket => 'Editer le lien du billet'; + + @override + String get toogle_interest => 'Erreur de bouton de changement'; + + @override + String get error_update => 'Erreur lors de la mise à jour'; + + @override + String get count_interested => 'Nombre de personne interessé'; +} diff --git a/covas_mobile/lib/locale_provider.dart b/covas_mobile_old/lib/locale_provider.dart similarity index 100% rename from covas_mobile/lib/locale_provider.dart rename to covas_mobile_old/lib/locale_provider.dart diff --git a/covas_mobile/lib/main.dart b/covas_mobile_old/lib/main.dart similarity index 100% rename from covas_mobile/lib/main.dart rename to covas_mobile_old/lib/main.dart diff --git a/covas_mobile/lib/pages/AddProfile.dart b/covas_mobile_old/lib/pages/AddProfile.dart similarity index 100% rename from covas_mobile/lib/pages/AddProfile.dart rename to covas_mobile_old/lib/pages/AddProfile.dart diff --git a/covas_mobile/lib/pages/Camera.dart b/covas_mobile_old/lib/pages/Camera.dart similarity index 100% rename from covas_mobile/lib/pages/Camera.dart rename to covas_mobile_old/lib/pages/Camera.dart diff --git a/covas_mobile/lib/pages/CameraEdit.dart b/covas_mobile_old/lib/pages/CameraEdit.dart similarity index 100% rename from covas_mobile/lib/pages/CameraEdit.dart rename to covas_mobile_old/lib/pages/CameraEdit.dart diff --git a/covas_mobile/lib/pages/DisplayPictureScreen.dart b/covas_mobile_old/lib/pages/DisplayPictureScreen.dart similarity index 100% rename from covas_mobile/lib/pages/DisplayPictureScreen.dart rename to covas_mobile_old/lib/pages/DisplayPictureScreen.dart diff --git a/covas_mobile/lib/pages/EditEvent.dart b/covas_mobile_old/lib/pages/EditEvent.dart similarity index 100% rename from covas_mobile/lib/pages/EditEvent.dart rename to covas_mobile_old/lib/pages/EditEvent.dart diff --git a/covas_mobile/lib/pages/EditProfile.dart b/covas_mobile_old/lib/pages/EditProfile.dart similarity index 100% rename from covas_mobile/lib/pages/EditProfile.dart rename to covas_mobile_old/lib/pages/EditProfile.dart diff --git a/covas_mobile/lib/pages/EditSettings.dart b/covas_mobile_old/lib/pages/EditSettings.dart similarity index 100% rename from covas_mobile/lib/pages/EditSettings.dart rename to covas_mobile_old/lib/pages/EditSettings.dart diff --git a/covas_mobile/lib/pages/ForgotPassword.dart b/covas_mobile_old/lib/pages/ForgotPassword.dart similarity index 100% rename from covas_mobile/lib/pages/ForgotPassword.dart rename to covas_mobile_old/lib/pages/ForgotPassword.dart diff --git a/covas_mobile/lib/pages/ItemMenu.dart b/covas_mobile_old/lib/pages/ItemMenu.dart similarity index 100% rename from covas_mobile/lib/pages/ItemMenu.dart rename to covas_mobile_old/lib/pages/ItemMenu.dart diff --git a/covas_mobile/lib/pages/ListItemByOrganizers.dart b/covas_mobile_old/lib/pages/ListItemByOrganizers.dart similarity index 100% rename from covas_mobile/lib/pages/ListItemByOrganizers.dart rename to covas_mobile_old/lib/pages/ListItemByOrganizers.dart diff --git a/covas_mobile/lib/pages/ListItemByTags.dart b/covas_mobile_old/lib/pages/ListItemByTags.dart similarity index 100% rename from covas_mobile/lib/pages/ListItemByTags.dart rename to covas_mobile_old/lib/pages/ListItemByTags.dart diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile_old/lib/pages/ListItemMenu.dart similarity index 100% rename from covas_mobile/lib/pages/ListItemMenu.dart rename to covas_mobile_old/lib/pages/ListItemMenu.dart diff --git a/covas_mobile/lib/pages/LoginDemo.dart b/covas_mobile_old/lib/pages/LoginDemo.dart similarity index 100% rename from covas_mobile/lib/pages/LoginDemo.dart rename to covas_mobile_old/lib/pages/LoginDemo.dart diff --git a/covas_mobile/lib/pages/MapboxPages.dart b/covas_mobile_old/lib/pages/MapboxPages.dart similarity index 100% rename from covas_mobile/lib/pages/MapboxPages.dart rename to covas_mobile_old/lib/pages/MapboxPages.dart diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile_old/lib/pages/UpdateEventImage.dart similarity index 100% rename from covas_mobile/lib/pages/UpdateEventImage.dart rename to covas_mobile_old/lib/pages/UpdateEventImage.dart diff --git a/covas_mobile/lib/variable/globals.dart b/covas_mobile_old/lib/variable/globals.dart similarity index 100% rename from covas_mobile/lib/variable/globals.dart rename to covas_mobile_old/lib/variable/globals.dart diff --git a/covas_mobile/linux/.gitignore b/covas_mobile_old/linux/.gitignore similarity index 100% rename from covas_mobile/linux/.gitignore rename to covas_mobile_old/linux/.gitignore diff --git a/covas_mobile/linux/CMakeLists.txt b/covas_mobile_old/linux/CMakeLists.txt similarity index 100% rename from covas_mobile/linux/CMakeLists.txt rename to covas_mobile_old/linux/CMakeLists.txt diff --git a/covas_mobile/linux/flutter/CMakeLists.txt b/covas_mobile_old/linux/flutter/CMakeLists.txt similarity index 100% rename from covas_mobile/linux/flutter/CMakeLists.txt rename to covas_mobile_old/linux/flutter/CMakeLists.txt diff --git a/covas_mobile/linux/flutter/generated_plugin_registrant.cc b/covas_mobile_old/linux/flutter/generated_plugin_registrant.cc similarity index 100% rename from covas_mobile/linux/flutter/generated_plugin_registrant.cc rename to covas_mobile_old/linux/flutter/generated_plugin_registrant.cc diff --git a/covas_mobile/linux/flutter/generated_plugin_registrant.h b/covas_mobile_old/linux/flutter/generated_plugin_registrant.h similarity index 100% rename from covas_mobile/linux/flutter/generated_plugin_registrant.h rename to covas_mobile_old/linux/flutter/generated_plugin_registrant.h diff --git a/covas_mobile/linux/flutter/generated_plugins.cmake b/covas_mobile_old/linux/flutter/generated_plugins.cmake similarity index 100% rename from covas_mobile/linux/flutter/generated_plugins.cmake rename to covas_mobile_old/linux/flutter/generated_plugins.cmake diff --git a/covas_mobile/linux/main.cc b/covas_mobile_old/linux/main.cc similarity index 100% rename from covas_mobile/linux/main.cc rename to covas_mobile_old/linux/main.cc diff --git a/covas_mobile/linux/my_application.cc b/covas_mobile_old/linux/my_application.cc similarity index 100% rename from covas_mobile/linux/my_application.cc rename to covas_mobile_old/linux/my_application.cc diff --git a/covas_mobile/linux/my_application.h b/covas_mobile_old/linux/my_application.h similarity index 100% rename from covas_mobile/linux/my_application.h rename to covas_mobile_old/linux/my_application.h diff --git a/covas_mobile/macos/.gitignore b/covas_mobile_old/macos/.gitignore similarity index 100% rename from covas_mobile/macos/.gitignore rename to covas_mobile_old/macos/.gitignore diff --git a/covas_mobile/macos/Flutter/Flutter-Debug.xcconfig b/covas_mobile_old/macos/Flutter/Flutter-Debug.xcconfig similarity index 100% rename from covas_mobile/macos/Flutter/Flutter-Debug.xcconfig rename to covas_mobile_old/macos/Flutter/Flutter-Debug.xcconfig diff --git a/covas_mobile/macos/Flutter/Flutter-Release.xcconfig b/covas_mobile_old/macos/Flutter/Flutter-Release.xcconfig similarity index 100% rename from covas_mobile/macos/Flutter/Flutter-Release.xcconfig rename to covas_mobile_old/macos/Flutter/Flutter-Release.xcconfig diff --git a/covas_mobile/macos/Flutter/GeneratedPluginRegistrant.swift b/covas_mobile_old/macos/Flutter/GeneratedPluginRegistrant.swift similarity index 100% rename from covas_mobile/macos/Flutter/GeneratedPluginRegistrant.swift rename to covas_mobile_old/macos/Flutter/GeneratedPluginRegistrant.swift diff --git a/covas_mobile/macos/Runner.xcodeproj/project.pbxproj b/covas_mobile_old/macos/Runner.xcodeproj/project.pbxproj similarity index 100% rename from covas_mobile/macos/Runner.xcodeproj/project.pbxproj rename to covas_mobile_old/macos/Runner.xcodeproj/project.pbxproj diff --git a/covas_mobile/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/covas_mobile_old/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from covas_mobile/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to covas_mobile_old/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/covas_mobile/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/covas_mobile_old/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from covas_mobile/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to covas_mobile_old/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/covas_mobile/macos/Runner.xcworkspace/contents.xcworkspacedata b/covas_mobile_old/macos/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from covas_mobile/macos/Runner.xcworkspace/contents.xcworkspacedata rename to covas_mobile_old/macos/Runner.xcworkspace/contents.xcworkspacedata diff --git a/covas_mobile/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/covas_mobile_old/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from covas_mobile/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to covas_mobile_old/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/covas_mobile/macos/Runner/AppDelegate.swift b/covas_mobile_old/macos/Runner/AppDelegate.swift similarity index 100% rename from covas_mobile/macos/Runner/AppDelegate.swift rename to covas_mobile_old/macos/Runner/AppDelegate.swift diff --git a/covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png similarity index 100% rename from covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png rename to covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png diff --git a/covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png similarity index 100% rename from covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png rename to covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png diff --git a/covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png similarity index 100% rename from covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png rename to covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png diff --git a/covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png similarity index 100% rename from covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png rename to covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png diff --git a/covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png similarity index 100% rename from covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png rename to covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png diff --git a/covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png similarity index 100% rename from covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png rename to covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png diff --git a/covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png similarity index 100% rename from covas_mobile/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png rename to covas_mobile_old/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png diff --git a/covas_mobile/macos/Runner/Base.lproj/MainMenu.xib b/covas_mobile_old/macos/Runner/Base.lproj/MainMenu.xib similarity index 100% rename from covas_mobile/macos/Runner/Base.lproj/MainMenu.xib rename to covas_mobile_old/macos/Runner/Base.lproj/MainMenu.xib diff --git a/covas_mobile/macos/Runner/Configs/AppInfo.xcconfig b/covas_mobile_old/macos/Runner/Configs/AppInfo.xcconfig similarity index 100% rename from covas_mobile/macos/Runner/Configs/AppInfo.xcconfig rename to covas_mobile_old/macos/Runner/Configs/AppInfo.xcconfig diff --git a/covas_mobile/macos/Runner/Configs/Debug.xcconfig b/covas_mobile_old/macos/Runner/Configs/Debug.xcconfig similarity index 100% rename from covas_mobile/macos/Runner/Configs/Debug.xcconfig rename to covas_mobile_old/macos/Runner/Configs/Debug.xcconfig diff --git a/covas_mobile/macos/Runner/Configs/Release.xcconfig b/covas_mobile_old/macos/Runner/Configs/Release.xcconfig similarity index 100% rename from covas_mobile/macos/Runner/Configs/Release.xcconfig rename to covas_mobile_old/macos/Runner/Configs/Release.xcconfig diff --git a/covas_mobile/macos/Runner/Configs/Warnings.xcconfig b/covas_mobile_old/macos/Runner/Configs/Warnings.xcconfig similarity index 100% rename from covas_mobile/macos/Runner/Configs/Warnings.xcconfig rename to covas_mobile_old/macos/Runner/Configs/Warnings.xcconfig diff --git a/covas_mobile/macos/Runner/DebugProfile.entitlements b/covas_mobile_old/macos/Runner/DebugProfile.entitlements similarity index 100% rename from covas_mobile/macos/Runner/DebugProfile.entitlements rename to covas_mobile_old/macos/Runner/DebugProfile.entitlements diff --git a/covas_mobile/macos/Runner/Info.plist b/covas_mobile_old/macos/Runner/Info.plist similarity index 100% rename from covas_mobile/macos/Runner/Info.plist rename to covas_mobile_old/macos/Runner/Info.plist diff --git a/covas_mobile/macos/Runner/MainFlutterWindow.swift b/covas_mobile_old/macos/Runner/MainFlutterWindow.swift similarity index 100% rename from covas_mobile/macos/Runner/MainFlutterWindow.swift rename to covas_mobile_old/macos/Runner/MainFlutterWindow.swift diff --git a/covas_mobile/macos/Runner/Release.entitlements b/covas_mobile_old/macos/Runner/Release.entitlements similarity index 100% rename from covas_mobile/macos/Runner/Release.entitlements rename to covas_mobile_old/macos/Runner/Release.entitlements diff --git a/covas_mobile/pubspec.lock b/covas_mobile_old/pubspec.lock similarity index 95% rename from covas_mobile/pubspec.lock rename to covas_mobile_old/pubspec.lock index 000d6d5..a64ca26 100644 --- a/covas_mobile/pubspec.lock +++ b/covas_mobile_old/pubspec.lock @@ -85,26 +85,26 @@ packages: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" clock: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.1" convert: dependency: transitive description: @@ -189,10 +189,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.3" ffi: dependency: transitive description: @@ -481,10 +481,10 @@ packages: dependency: "direct main" description: name: intl - sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" url: "https://pub.dev" source: hosted - version: "0.19.0" + version: "0.20.2" js: dependency: transitive description: @@ -505,26 +505,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "11.0.1" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" lints: dependency: transitive description: @@ -569,10 +569,10 @@ packages: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.17" material_color_utilities: dependency: transitive description: @@ -585,10 +585,10 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.16.0" mime: dependency: transitive description: @@ -609,10 +609,10 @@ packages: dependency: "direct main" description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" path_provider: dependency: "direct main" description: @@ -809,7 +809,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: @@ -830,18 +830,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" stream_transform: dependency: transitive description: @@ -870,10 +870,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.6" textfield_tags: dependency: "direct main" description: @@ -974,10 +974,10 @@ packages: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" vm_service: dependency: transitive description: @@ -1043,5 +1043,5 @@ packages: source: hosted version: "6.5.0" sdks: - dart: ">=3.5.0 <4.0.0" + dart: ">=3.8.0-0 <4.0.0" flutter: ">=3.24.0" diff --git a/covas_mobile/pubspec.yaml b/covas_mobile_old/pubspec.yaml similarity index 99% rename from covas_mobile/pubspec.yaml rename to covas_mobile_old/pubspec.yaml index 65ffd79..a803f44 100644 --- a/covas_mobile/pubspec.yaml +++ b/covas_mobile_old/pubspec.yaml @@ -41,7 +41,7 @@ dependencies: cupertino_icons: ^1.0.2 http: ^1.2.1 shared_preferences: ^2.2.3 - intl: ^0.19.0 + intl: ^0.20.2 camera: ^0.11.0+1 camera_web: ^0.3.3 path_provider: ^2.1.3 diff --git a/covas_mobile/test/widget_test.dart b/covas_mobile_old/test/widget_test.dart similarity index 100% rename from covas_mobile/test/widget_test.dart rename to covas_mobile_old/test/widget_test.dart diff --git a/covas_mobile/web/favicon.png b/covas_mobile_old/web/favicon.png similarity index 100% rename from covas_mobile/web/favicon.png rename to covas_mobile_old/web/favicon.png diff --git a/covas_mobile/web/icons/Icon-192.png b/covas_mobile_old/web/icons/Icon-192.png similarity index 100% rename from covas_mobile/web/icons/Icon-192.png rename to covas_mobile_old/web/icons/Icon-192.png diff --git a/covas_mobile/web/icons/Icon-512.png b/covas_mobile_old/web/icons/Icon-512.png similarity index 100% rename from covas_mobile/web/icons/Icon-512.png rename to covas_mobile_old/web/icons/Icon-512.png diff --git a/covas_mobile/web/icons/Icon-maskable-192.png b/covas_mobile_old/web/icons/Icon-maskable-192.png similarity index 100% rename from covas_mobile/web/icons/Icon-maskable-192.png rename to covas_mobile_old/web/icons/Icon-maskable-192.png diff --git a/covas_mobile/web/icons/Icon-maskable-512.png b/covas_mobile_old/web/icons/Icon-maskable-512.png similarity index 100% rename from covas_mobile/web/icons/Icon-maskable-512.png rename to covas_mobile_old/web/icons/Icon-maskable-512.png diff --git a/covas_mobile/web/index.html b/covas_mobile_old/web/index.html similarity index 100% rename from covas_mobile/web/index.html rename to covas_mobile_old/web/index.html diff --git a/covas_mobile/web/manifest.json b/covas_mobile_old/web/manifest.json similarity index 100% rename from covas_mobile/web/manifest.json rename to covas_mobile_old/web/manifest.json diff --git a/covas_mobile/windows/.gitignore b/covas_mobile_old/windows/.gitignore similarity index 100% rename from covas_mobile/windows/.gitignore rename to covas_mobile_old/windows/.gitignore diff --git a/covas_mobile/windows/CMakeLists.txt b/covas_mobile_old/windows/CMakeLists.txt similarity index 100% rename from covas_mobile/windows/CMakeLists.txt rename to covas_mobile_old/windows/CMakeLists.txt diff --git a/covas_mobile/windows/flutter/CMakeLists.txt b/covas_mobile_old/windows/flutter/CMakeLists.txt similarity index 100% rename from covas_mobile/windows/flutter/CMakeLists.txt rename to covas_mobile_old/windows/flutter/CMakeLists.txt diff --git a/covas_mobile/windows/flutter/generated_plugin_registrant.cc b/covas_mobile_old/windows/flutter/generated_plugin_registrant.cc similarity index 100% rename from covas_mobile/windows/flutter/generated_plugin_registrant.cc rename to covas_mobile_old/windows/flutter/generated_plugin_registrant.cc diff --git a/covas_mobile/windows/flutter/generated_plugin_registrant.h b/covas_mobile_old/windows/flutter/generated_plugin_registrant.h similarity index 100% rename from covas_mobile/windows/flutter/generated_plugin_registrant.h rename to covas_mobile_old/windows/flutter/generated_plugin_registrant.h diff --git a/covas_mobile/windows/flutter/generated_plugins.cmake b/covas_mobile_old/windows/flutter/generated_plugins.cmake similarity index 100% rename from covas_mobile/windows/flutter/generated_plugins.cmake rename to covas_mobile_old/windows/flutter/generated_plugins.cmake diff --git a/covas_mobile/windows/runner/CMakeLists.txt b/covas_mobile_old/windows/runner/CMakeLists.txt similarity index 100% rename from covas_mobile/windows/runner/CMakeLists.txt rename to covas_mobile_old/windows/runner/CMakeLists.txt diff --git a/covas_mobile/windows/runner/Runner.rc b/covas_mobile_old/windows/runner/Runner.rc similarity index 100% rename from covas_mobile/windows/runner/Runner.rc rename to covas_mobile_old/windows/runner/Runner.rc diff --git a/covas_mobile/windows/runner/flutter_window.cpp b/covas_mobile_old/windows/runner/flutter_window.cpp similarity index 100% rename from covas_mobile/windows/runner/flutter_window.cpp rename to covas_mobile_old/windows/runner/flutter_window.cpp diff --git a/covas_mobile/windows/runner/flutter_window.h b/covas_mobile_old/windows/runner/flutter_window.h similarity index 100% rename from covas_mobile/windows/runner/flutter_window.h rename to covas_mobile_old/windows/runner/flutter_window.h diff --git a/covas_mobile/windows/runner/main.cpp b/covas_mobile_old/windows/runner/main.cpp similarity index 100% rename from covas_mobile/windows/runner/main.cpp rename to covas_mobile_old/windows/runner/main.cpp diff --git a/covas_mobile/windows/runner/resource.h b/covas_mobile_old/windows/runner/resource.h similarity index 100% rename from covas_mobile/windows/runner/resource.h rename to covas_mobile_old/windows/runner/resource.h diff --git a/covas_mobile/windows/runner/resources/app_icon.ico b/covas_mobile_old/windows/runner/resources/app_icon.ico similarity index 100% rename from covas_mobile/windows/runner/resources/app_icon.ico rename to covas_mobile_old/windows/runner/resources/app_icon.ico diff --git a/covas_mobile/windows/runner/runner.exe.manifest b/covas_mobile_old/windows/runner/runner.exe.manifest similarity index 100% rename from covas_mobile/windows/runner/runner.exe.manifest rename to covas_mobile_old/windows/runner/runner.exe.manifest diff --git a/covas_mobile/windows/runner/utils.cpp b/covas_mobile_old/windows/runner/utils.cpp similarity index 100% rename from covas_mobile/windows/runner/utils.cpp rename to covas_mobile_old/windows/runner/utils.cpp diff --git a/covas_mobile/windows/runner/utils.h b/covas_mobile_old/windows/runner/utils.h similarity index 100% rename from covas_mobile/windows/runner/utils.h rename to covas_mobile_old/windows/runner/utils.h diff --git a/covas_mobile/windows/runner/win32_window.cpp b/covas_mobile_old/windows/runner/win32_window.cpp similarity index 100% rename from covas_mobile/windows/runner/win32_window.cpp rename to covas_mobile_old/windows/runner/win32_window.cpp diff --git a/covas_mobile/windows/runner/win32_window.h b/covas_mobile_old/windows/runner/win32_window.h similarity index 100% rename from covas_mobile/windows/runner/win32_window.h rename to covas_mobile_old/windows/runner/win32_window.h From 6d504139b042ab4331c20209c0ff3e36e2619b55 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sun, 31 Aug 2025 21:08:58 +0200 Subject: [PATCH 04/16] fix gemini prompt --- .../lib/pages/DisplayPictureScreen.dart | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/covas_mobile_new/lib/pages/DisplayPictureScreen.dart b/covas_mobile_new/lib/pages/DisplayPictureScreen.dart index 107521d..9893b6f 100644 --- a/covas_mobile_new/lib/pages/DisplayPictureScreen.dart +++ b/covas_mobile_new/lib/pages/DisplayPictureScreen.dart @@ -221,15 +221,13 @@ class DisplayPictureScreenState extends State final file = File(widget.imagePath); - gemini - .textAndImage( - text: - "Peux-tu donner le nom, la date (si l'année n'est pas précisé, mettez l'année actuelle ou future) et le lieu de l'évènement sous format JSON (sans le caratère json au début de la chaine de caractère) avec les valeurs suivantes : name, place, description, tags (tableau sans espace), organizers (tableau), start_date et end_date (si le end_date est vide, alors donnez une valeur de six de plus par rapport à start_date) sous le format en YYYY-MM-DD HH:mm:ssZ", - images: [file.readAsBytesSync()], - modelName: "models/gemini-1.5-pro-latest") - .then((value) => searchEvents( - value?.content?.parts?.last.text ?? '', widget.imagePath)) - .catchError((e) => displayError); + gemini.prompt(parts: [ + Part.text( + "Peux-tu donner le nom, la date (si l'année n'est pas précisé, mettez l'année actuelle ou future) et le lieu de l'évènement sous format JSON (sans le caratère json au début de la chaine de caractère) avec les valeurs suivantes : name, place, description, tags (tableau sans espace), organizers (tableau), start_date et end_date (si le end_date est vide, alors donnez une valeur de six de plus par rapport à start_date) sous le format en YYYY-MM-DD HH:mm:ssZ"), + Part.bytes(file.readAsBytesSync()) + ], model: "models/gemini-1.5-pro-latest").then((value) { + searchEvents(value?.output ?? '', widget.imagePath); + }).catchError((e) => displayError); } @override From 3310bd572e0aa2f7e71f553470a53f26b2fb638c Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Mon, 1 Sep 2025 22:14:08 +0200 Subject: [PATCH 05/16] fix mapbox pages --- covas_mobile_new/images/flutter.png | Bin 0 -> 46481 bytes covas_mobile_new/images/marker-red.png | Bin 0 -> 37200 bytes covas_mobile_new/images/marker.png | Bin 0 -> 11120 bytes covas_mobile_new/images/search.png | Bin 0 -> 18266 bytes covas_mobile_new/lib/pages/MapboxPages.dart | 430 +++++--------------- 5 files changed, 104 insertions(+), 326 deletions(-) create mode 100644 covas_mobile_new/images/flutter.png create mode 100644 covas_mobile_new/images/marker-red.png create mode 100644 covas_mobile_new/images/marker.png create mode 100644 covas_mobile_new/images/search.png diff --git a/covas_mobile_new/images/flutter.png b/covas_mobile_new/images/flutter.png new file mode 100644 index 0000000000000000000000000000000000000000..e02f15336c0f624751dcd02a84770bb2d42de27f GIT binary patch literal 46481 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 k-+HI>?>na9T~s#&fik=5C{Gj6y4AL0z?V*mgE literal 0 HcmV?d00001 diff --git a/covas_mobile_new/images/search.png b/covas_mobile_new/images/search.png new file mode 100644 index 0000000000000000000000000000000000000000..9454673d0b6e090e4b9d0cdd598a591c1e9334a0 GIT binary patch literal 18266 zcmZ{Mc_7pO|M*HML@80ucZPDbqH@!XgnAb$wJAwSM#5Z8yrmI}vP$T9mr6{@Q8qJ2 zT8?#Tgw0K^9nLY^@A(?NKdJBU^^e-?@w^__^Krg#`yFkTO0AKC!C*`6YFE zxL6iJsa}`6Shpjt(<<`O+E-7n(v~X(e_efGf3^SiW6J_pHtmY|&~Zg9YVp;DQm?kM zT5^@Uho0yf>gwqk4JTkPF?o!X5B#yN1Z986cNcPdIUQB;iU=eTQ#Tq|wxCl?ev76A zd-fURo}Nmg7s*-7J|)CEE~=%w-2Y*o9lIPWdgx(<6zs8?=m*Ow`eYe3(SwvDISM$o zYqzew+l{AGh@OE5bgFf(fO2Iy=U2E|{i!{H!6(*!+Pq_ibu?DEac%|{X+gvn_nbax zNb2&sBbQds?tsV$ZCd)zkTk4Q-6`Qr9k=H7+)hLLmnu0e?NWqI)!{hUvg-n@*NCT~ z*J3%*L(oA6iJdsJ5+)XcPE0r`w>~;Sw0p0|c*`vtkHB7MuUyl7Jj^|hBbsiIE8qES zfirA!D0g|~o&_II&Hesj0&F|u85ZTb_{f6m8yhjA=UYh6L9v9EC)=l`(Elb;r*di5K-0FZmyj#qAq1gdY*$af%!9X_YZ_GbSzsi>;G$gS0oWuQ zI}0~JI_bn(Ee@LlAm}pmU00r*+l&5$lFBStvUPN{=rlH5ueq1D0-3F|m;_^KX6Tuz zKxw>z+biEwrzYE@qobW1lixik_+EB`+p7sjZs4rJVQ*pLE0@S;+1}Ije^uEGPrQX8 zRUQx%6GNQe+=17!<34oB=3RU6U^J39(tG}D=b2J|MC1@)0vm31MOv7XR?7jLgFNll zq%khZE_`Q)q1`w7WGObQQcQStN{q`?zfPu^eC_?(8$g_f`z9Cf=)l73Q!)4rh8Y^1 z{kVUI;$vg!@m;9NAJ!7egi56S$w!s(S_~bI0}f@^vL*gh>rj_#3{5vXZcDGZL;bb^gkW-mzr9FTQ zE&9O3YH$|d@V0}9<)V?NZ}Vq%h)2H6@cZE2Io2rMKlXhOPa*uG(iNcrj-9khYXBJ% zY|nq6R*YyrD<6Lw3kYsXwRU6akYOLuj-v$OP0G7852u;C5igAWAGHQ+{b>Dh_|@>O ziE}ukt^fqG*pCw0qpqfwQQvz5Ib{6){0xDqGJp~qc$_~0j+(|eihBgFzfqhYMGdVd zX)M09diSSkx165s6%{*|f`Lda(&6e;3qI!leMU)qTRi36Kvb6e#}y=8+SsL?uZG_Q z$5y&(A^&=Lmv=4JbqV4V&q5Ez527zV`3QE#uo08bUW|4LY*9#-AmaF6r^L6FyLSe*#mGA)Prj}^4?m|zjMqZyyo>^q_WpxUC()!L z*CBZHz`$i|=+a6)#ByYgOV~|5uTviT*PEjQ=Wo!CFRSJZxa534Avq58#W~W~b+C>g zu)nOm)lPQVZbHa+|4H-KPD@Qim#Jt^= zKC@Jg_BY{6CC%NOHKb$L7N0CLth2hKyRw0?YiE}Bw6a5WV_+g5-H3X!zqUpsZx*q+5YuySU)v9V8g+}Oe**&6wVq+@$*FSmT) zRhF6c^Q!bcb3?khviq~9?2wp%!B$<)D%{N(MY*J|BsvPMj$edYf)_+9En&Hna8u*Au$PrD<*}L}?YG`fCsz6nk}(*| zu~*-OF=>kmlzh%vHazVPhAR`3LnmTROukeNQgW*k#K+Q8x>$<3uxn%g9F%A_V?B^( zYBseU>1h3arV`!w`fTUMX@nZ%o|e#ul*wPXjcodfEC7IO5I0Tg)B2hmUs3Yw4i3f8 z11!oa212<>qu%80z602qp2NZ^^y+icMvdL$<0-}WPDOjY2~MiyFg80$`vKUrmx=?o z^R;Z*;7bY^+wXvq2;U&K9CZ0d= z)@*UYfVfPMDajI^yVkVLxwgc$!@$Gi(Sm9*3t}PCdnL@jBu!AeP(!yx>ndgVaaKnH zqtfATxFm6J==L^L@tIHMttMdQ?)fU59L~6a8?lqcVBB(=Q~u@1Cn7L_h0i_+o4mHL zOoxa69QM326M8SlwbI0*FN9Mn!mhgx{;+%m)8OIXyXBw06?&|57doyg%oaeUFc9#d zj>)K4`epjr4zIl4`uK-u9`Jd}a7hc|4#xSZeXFY#Ei6(O7t*uo17RVi(v#O!*z6}m ztNo&k{qyyqm&xSg$egWy#e5!1rIy1s8?V20yP6{o7!4g$pz*^HcmqeI&gT`?HA@b6IjRDFh>tS{bwBT)J)SQ+rM z#A}@jYHC#SA;$an>^-Ko$7{eav@gjdkwN81$)S}4A}K#o=-yj0btRuQo80bfAFG{q z;)T8END(@a-=@fZDfd@Jw^|ZDT}A0iJ_<91AX=t#E0XP0owY4u=J*nyR#ThRzLJIVO+VZP(Vi~juC{ZFAFzDxB7GCoZ8#sV_kJwba_1!WV>@&eBi!Sup!-;D+ge& zl?Llc8)dA^D2j4~n~W{;=S-39rh{5$nO@?N%;7cLeOAI8Bub3XBRw;F$~R6fl4SlJ zHeq*6hjS1&0=LouS4@!|(WT>-yv<$}WOhRaP#cptSfzLA~5E<0&Gci>m6gO z(zAz?g;}PPspZpQ%NAMR81jF@55Cpd5Gvg%ucyUVtHYnb#oAdobTn|W)ze+VCuoVw zLdin(dSaT*o+}gDO>L%Ko?fi{g&H611%by^|9LmIP@-hyi$J}ntyz(En%Cm`Xk9p- zzt`G_62%K+6)~+wK3Je2-5yJ!eCzBM4nOLmsoyBxmwCs1di-0-iBAv3m2J0T5;4yX zz$%A)r;MZ{pZei7B*LC|3DsmvEk|;1PCgYllT&t%p!buGcNoYsZx*NX3@4DwCg~fF zzGgpwD_cksU%+fHjJy%-Z^i7n-o<>NxcgJH>16%0;P}cr^09mMb3gJA1`iD*{E3y1 z<=t*00(zcJZ%y^%SLCj|mN(jAkrt|x!q5G)g3HKC)e*_kC3F%_mdf?&FlFSW{#U5vWM z?Cqun8w%g{JTo#_KO#pvE4nb8b^#M(tz^=)ogjZa7jJUlq~!>~gRq{n4;P>{>?NrC zK3%x0j9=k_bC;Oj&iJ^0%GMOqLZQ6!U|I24s1&mGZdC7SK_IP}lGf+tr#gamVN~D2 zV&GVbFlBUmx%fbL8^=aARW$^A?O|V~#$uO^!k(6cF%2p3Qr(v^Jo=3ZZD1czGbxNU zdak)jDbdy4D*9eMcI9M4yETaByc2ZZ;JpaWH|qH0ZJ+oOTY=GdMg_k@ljjQCmUrWrf92$f*EcY!~&2)R7kKr+ecLY{t) zU57OqgXzm`G_CoObG+pAGoLIEB2FMx+gq3+#EVP!u&P9h81cxdU8wid8T<~czIoP` zjL;Sb%b*awkvFZL`a;)p^ju^;pq(jC@zPWhC4=o<@cmIYZ6cW;&?&zESKK+XwYq`AjUp%KD&lHs9 zPL;MDxj9dn=vg&prSP+4#*XoHgB*KFcWdJ{Jri5@ayH?qFJ5eNJfS2orZUsK>mqOSqFhfRzHORy zI)HQWyw5#5V-%~yL$C0%t@Y@Ak&A~@^G}r?bK)|!t;)hFde88E;lS;CB@^`i0V1Vq(a36V z+q&8-WJOZ!%YcsaEK3KJWN(HNt;Fu+5^xAOGHBdN5B8AQg`ziXKXVN6wBJ1&_14W+ zz!;K`eQDHQz)7_WujxE+SfQ7@P9JGUoM+oz4~r(1rD2|s`l%?(@!~7#O9=O~5)}zI zikq`B%t&w(ya$K4j8}l!`C8G{pDWWA%O1kyk#}(?98(s9?VGW;?mgD)T!Jn;KGKsg zNDHS7`3i|=+n5xg4rzVvM7~jbU`=*|x3}eGH=_5} zrBgR{CGetbxQMK*OFTxOGvM=E)FiqlS_j9(G!UzM*7ZmOfw{+6t*}qf|F!GEzDq>4 zu>R%E(z?au8RwJYBjQP2s12-0DYa`~(*;Q$+|DuTIoo@k&a6-037b&BrtIb%A_$o- zZ2Wu8JA6#U_zoNb(=ecf0hLK&LpWp; znwpr{j}h9R!?6XnR0(ZsB-J7iW=1-xD#k1qp?6k9eB`1P$Pc_M{spP$V59G zdg{@p3IYPhssW$}cS2eL_Aa#i+0N+vBICNfSXpgh^XP;pxAWGwW?~5W#zq<1^S#yE zc)4D{otm02L8@!+sk^{=%)egZs7YSYMXb`Wdby}JJ?9@vCYx_sUExL1JG<0>G+c^q z`6isIdnp)W8h%?<7~z+3{6-fRUwL`oC5trTtmM8yiknGDT*fvHmk32DF#Pc8+Z zHKZze@<rEWf7p9dDodVumU(r&4PN&6^FVFujGc@}L|mZWF{^;!1mjPuZ-C95|6f#KnZmIAApzyAUCSVb zD~u6jfc?;kiihrFu&YPJ(Xzi@iGF1dD5mc?(bYNf=Kxp8hGm8M7D<;P*PbqI3v8OZ z0ZTooSlbSoth&WlRiV=fu-)O9SL(<5FePo+6A+x<_-Mufn2gC*6Lb(CU%>&)sfz*R z4!t_4Xl&ZDVR8?;Nu#5Y%g9a4w@awvw7sX&-b zJ^k1WkcMd{eoe?L!VKpq_+^&XQo<=|`J$kMn}ipnr(bEd4!Cp4pVJQ4-=-$T77Y#f z(dr5oGAQF!X_|<0GpJ&_{WVu8xXwuv$rN(`coAUiSmU9A=8UkRQfH6*kwfvulK)*h zp6d5F9EXbSZNhqr_FoY5w0D<&{lPU?9h~;x*sMsXnHNZSJs53d(ir+Ynu^-Ow}W=e zLo^W*{n?+G0ZpZtQ9`~OD@VWHqElF(Pam!fJ`7o2spCK60Y-@+ng z7)gusu*xbvTOj&Om^tvZCJkLnF5E@LJ(Sycgu{N@Z*Z%)Il$||{b&FY@S|zebKJjg z4Ko5r+)>)8s)~WP6aKXHn5g=b(;YYXI!GPUWPZaK2>}i6scfza@VZq-4te*g%?Cw% zu8kd=de-}XsTBwfb?$SqAim+8!kW{;sbt-!JDe?fhyX2~Z9O$cOGu8(2vs&m ze$p3k!L1Z>D5)%tADs-|yJ&nis)&evjWU;6qEW3CmSiR$hAh z1qKr^uw_jG-Q@M&HYtEzpA>9+mT>R5=hwfl6ovX)d>;uCEfRL_+lw`~W`<;G3C;_X zPEB{zmDd~ayj!>ZRtKdes5kKJ$tIkM=yoOMucFKVxo3A0h&xdfx?* zdJVyWL;EdTAed&Yg<#8)^MzvdcnnKq_Y3!&{z@SEOk)9j-;g?E6+Rs4C23{T*3 zTEjsaJf`k)(cHtTou(hRZ;pG2^#Hq^=j`p}dTurU{AoZ290`dcZpjc+-Bq#CBz7p? z^`reoE1DFH+`1*IaUJZg`v4ZaYXm`OCo$c`?*V~jrK1df;Z`@OMu#PeOX@lxu)!hEqI3+oTiF|&(42Xr3j zPy|T3FyHFhpHy1Q=Z%c}|BIjKgy^tLlVeHy*75pvMwL1 zK#?SnQjCHgId#pu!QyF--1-$FEoW`?{ zRe*izr3XI|v)JhHAu!W?FFlx;RD+gs1}icOd=3+y?J70Qv=k ztM5IspslE6&oX84ZTU1*j|2eT^T;0#oo`6JGnSzimF!&qZG3--c3(dnya~ z1!4x)1`~QBSQ6YW5rQ>=cD$RGF+RawEgp$V?IKv=K}^Q&($QgMNR@KKcJBPqsqZMz z-5}b-Pi`Oe1d)St(0t2h=K~i?Za%cQD!9=!K_tMMj?zwiv_jw7Ab2f=B0i(dJ^QRb z*OlX1h{!l-zsTmmhEbBAjys%30p6hJtr zX)MJ!!m(pyPcF8J`{jbusSEAxM>>z622;K?YF4D-x(FnK8$hiOq*#x1M$~k45l%vj z=}}Rn`h5P~7DsR-i*rQUk$Zggr}Tkoh}rFc6o}Ojs6%Cd>iO@c|IMMIA~rZk%0XJY zOl93P{!JtI+y#3`NWNjzUjlie*)L$jfv&nyNthO_1WLXC3!ZnUo8Hv}$>s}=WBwMN zo|j+V7#8eVJeiDo3fuT?h2!+7XYOm>-DAn{^#CEXHLOE!K&n6jNgvFW)|Htvk%EHt z8S6~ZvEQ>00R?sRuB|?efmXA?a0nQF)*@*r9-l(fBz;F;Z=OPtO}~)^ZtuRAlLUtJ z@8J%<;o)C4&JHjE1E!cDPH74R>Fhjn#|hQrod%9vK(AN@={>OJ*IRh!SVsWldg89$ zkryy_^Ks3q2@CHxRU-m!ft>^~LWb5s6Uzb)K4<_KA_G`|fP?4fOFs7^MvTDJIfpkD ziiyC1ohb)VMWuGU%7{2P7~ulj6+$KFW=DT4Mt)==0&rmV@{NbzLFliDf5?`J2M5&w zCWg#>hhTFNsz)*vmEuMbK}uJ!_d$@=fQW@*-h{`rF1gp!P>?K7hKf3#V$K9qGlvK= z$o>~L8C69^RcQixG#?pawHtxEOCO^1;wbcyOAfy3fQd6yGgQ#^5Dz!T55;@!61mUr z_xGW+WugQ0$=VZ(W`PFD)`b8Fvlu9{cgQRpS(4sm<;C0brgxV50y@NZHvuQt%2N)k z%-l(E|_Tut^7E!(BE9<)G8oL$DykyzdWoE8X^Y{yFm*( z_T8O#_Ko@MkZPcM8hT5?osssybpJTQ=rr%Fse(OpQ9hoq^7iLqHDoH1z&7HvFSSl& zfhe>~X6Zhk5H9vUk}w2WW_qNF^AKZ&tJvrO%u8wij75)gYFf?&crwmxM!pxp1s4EG zGPV1RF$Ef78<+NNnu>sprmdJ6upa8fzj@#D!6NQqun{28-k~j8g^hRl&N8xv8Sloc z&ix#;a;LCsk9#x0URDaAGAa$Li9Zl=BSJ z=rVF5bQ^lJ7NSUB9}TV*$;3mNd~69)3f3NlXMfKhA8o zq_ozJ-sk%q{$EI>q z!4azgHNf->HK=vHQ#%7YS5qzyX-M;SAB+Q{$bIE@rqa4y$qZLxC&z+Yr%h*^aM$S*lxfx`4A^`bEC?H z>D^SJ8V)#a^p~@?3$T>}prMW)(1EIzRgb^T7xP+$1zI2=6zATwB&g7WmtA~MWV#TV z_96Sq?oWj)JCvlaO_x2ywy`3%bmc zXD0SY*6XW5ri~>qUu=ME=nCS&%ycXPNnj0a~ zkA*NFF_voA!fL`geIf(Gn%VK+vYgtrx922>-wE(>6qxz86#KJ8mmZVoYI>dTJXkkg zHK4(pj*)_SShl~0qk0Ylqw1URcy@y~Xbo`EINEJ7WY4ke52Ecz;{tTnGun;M>E$0BO{qz43c}j04j!GsA z#SW}Yhot)QuSvvP-8JvKfK579;%spP!d?K&kd}~z%K(siee<$5b%3YVNjU-I6MbH) z5-|6`v!X0%D(W72&XGhe_$}#T*Cb)%Tq+C4DopIvKLMSycKW^;Rd`uraXoM)6#kHi z9}->!l3L-mpeV9gUK~E|5rl0^&RzMUrVPGwr9WRAT!Rbd>-?{=lp9i$HNabVajO>w z?h|x9sp7b;K=(>)?D*^|^8`aKad0JKyyftFkF*9NSVhyvIiOPi_42fJf=QsiCA&J<-BMgb8p$nVBB| zxt~KaF@g`li&3!yy&%)I5(04qKGI8e5|A86^uyI_00kW_(n@Ou8{pWX)-7gleRLpc zrIRMillji!xS@C(ZYJhg{wliJb^e$k<T#+OgvoB1N=+Q7AVXkq!6-I-@cnL z#>GHykA$&;)`6?bs#!6qOV~y?S23%bh%9{pDTjd;H{I!mbXhHI-~<*r<7qB}KZ>G~ zYt<5+r@XyTBF_s$Wq(mIQ+qn80+f3ET&B|Hj-*Y{eWuCl{On032oXJqrXsbq{z)Fy z(U3#&_P=71qdicNC`Wc^Q1?)0vL&Q#j7Fj~Cf|Bcg?pUo5bXR|X^n-+b6n!!z6rBr ze*UC72y-F*2@T$AU5B}u;~5$t)CTR`$0OhRit&S)fk1y{5vZB?tsE-K%3~#FDTj1 zljyYvmwrW<7zhZl)EWH^damyU92?0L;VPUe2t4MG{(6-xh?n%rkEU7=EGyQ8B1q*@ z73_l`mQ9Vp-iBa5?-2O~=nyUqsc4$Y&oBO%_GJBH5c1p$(zoG-kAS@ApzypXkLDpOf59=TFM& z%*`OK8LZ+Uko)Q_77IY9y5Ed?CSKUc^Wu=@cY*-u^ALX()lP3No_4&XH$%BcloH4v zy<69FfABiiea;-gnROBW4yp&6-{q@c@905^!mS%ZKnA?#6WG`}pckCk z@80ckr3(BLde3lOCpN!uEBaz6%1_ucKHSoCaeTcvaNM^&>>NnG0q_lB&zGbQsxyO( zdGu~NHe3ZtI50gCapfs0rKg`>OG^b+WQo+I-sd_a{8RW8^4mjizBrn1@G5P)!7mxy zvW9b&&x4}RhqBw^je$+S9PD!o!6jQ2#J64P0%kqnfIvvzGR2|;u4PNgd5|LWgP_bF zm^2Q=3ny+^Gutmfu)&Za4)Qy(bHbO}9sMP_xT&EFjX`^HJKwZXiAXJMDTUKT$ekhM zM9GAo^(>MSy@823LVaXeS9L(!tJdyZ9U-tJP#~kb1BjB`ysPP%SoD|clhK_(!=)^c zmjrU*GrDTSJ#}g(4Z4-D@96aeX#q9uKgtO5hN1(CJApUXtThfKu&FEONd8`fi(^f? za4b#_AYKftmGrAaQgefHK!Nrc+S=C?xspv_DfZ~n7wXx2xCHC{*$rw?^6SR@e4ncF zy;xTbo|pfl%KE{5m{k~7&R#BFcxeN`jSVuj0_5@En~$*ur2f)_$=gWw)=I&J`j-$d zlR2 zLE1$5P;~Zwt}7NRCt6}&QOx_#K(Y0yD%b&I1F@T?{_o<(G_cSv#xn(bL4R_~GSQG< zTym4PsWywz2XaSr?Kp1%Vk$~PFqkt~u*{{C+9m(X?Ik$-VN06R zC<$0_?u^iM?MpTiUN)VE?eytq|X{}0{SDVSK2^N=dM zgqslwAUDjL_sJZpOqqOE=?(Vei-AhnP6<>WA+|Vg;(2+|fy#kn?TN0=n|V&T>Kf$6 zjLQ0djFr)Kcby*@3QN132Y%cgVusz?RU1yxp4FVs}CNEx_OdGqd%(g0V~&|Ge%3 zyP)wB)8g|10bk5XL!lCR0WLMlYxb(^RdJkGR#(Ntdeo6ilCl4~PA|RSCLA!X2H}L7 z!*0cK(KCj!zH)I)TZ_Bt`9~Sw3$pPb1asgH0%WwS;v+Z8;5Q1{Q-iQv#g!>11HLK}la?tu@gqWL|76g~AB^Fs-A~^2DMTDw?xl zL1BixfVaI6Wt10DcrDA!&7F=Le%cKikt5)LmsN={?&G84%yPLMDg6B>91b28H zS3ucIIVe3^+dOWSj4iSd?hQ1JJFfYfgXjTfo@<-c^~O%}3wZ6xoSvHgD~nZoic zJ49QXOXETN@{Av=6aHy5ogUtzm6%+7_mo5RHVd7fbmea$}svm-|T()z->Y(}z zjCaWQq_7q74cA}%P`VmxT%s6lX|)+-(yk2-2K)OBOn!Q5-bKdl5R|Hq5C#}mEA_N4 zz2iUf&;W&NSYINjiwG_a@Jmb2TBQOQ1Y6LWs!;i%-gICjmbo-TO`d9bU8>3Ju8`1NBG~Z zTw1GWCUGJBohEOB8KxsyWNPU!)x1v18rWnRrI%*jYB}GP56oOL+fs#?W{1hgW~Ywx{v%z-qn zDjKBoLIAo4O6Tfps@!Rf2ZKE_t0*}u8S3!*TPDs{!H4qiSa>jqH)g)&G@m^p*Bd{@ ztkK$PXW`UQC!fjHPQ6nKLQ1`#HZ3E7dY8HC8=3K16r{bQH6|BI7X6LdGnvAlsOe%c zlP5vR^ubntP+=JxyH{l`XERO*vm%LpKD7~bk_fl~8Hd{mmvu<)x(X@{4dWgf$4`Lb zogejBd;b0oIwNQ)rcn(8?Rn?CsEcQw`N&o@0}Yp{5Vo}e4+>C-X!Ym)4axv7i^}QZ zBEOgxx3{-L`ETxE`nRtClNs$!hb`K}}=0L*5*RA~YA=chZNq4$3ai2p;$ zSmD&_9%L;E%7KYTTFOA71kvJ8IS%Mmh5Jj+0%7{!l~t)Yfk?>Tk6>4uTSvWC!49-< z*e)~fLnLVl-cy#!$pQInUmMvO@c7sA08lY!j(%+XiIfO!m*Hb3v7rYOSCrnM|DBzc z%UYnpn_wuXrcZ^-`hpVneD)KAg(g<6pU>6(+lo%_Vp^kVmd3Rp)@U?)pr%cJo2tD) zop%;4lQLXN2L+4x^cl6;!F@`_w>#G}?v*MHzTtQm-0e3OO8)oeX6Jfv5ji?pGN&U% zKcEU#MhlCecyg@bmui%&YmKW!Jf}sR`ZHcBMCOVhQfSz2hF|mX}RJBtQQf zEZFDTVLs;f^uFO=)KHZbDV@+dwWRmV1p#aG->fG%RZ&UfBhElSQ34{AZzRB33=n| zKJ2|9j(zfV&2%+;UmUDZQdLZK^tTA$g6N@0kV<*5PKs$@K6xC}nahXZsZ3*9yWqgn z#qMDrH+?)XKiE;}?$&8=^tE5`Gd6i2C}|%-I0WwLU(5^3k({>iU0ybR-{XG8{3|H9 z5maCa;n>ofT`_bI78*o>KKg8x3?pLq9a)qIPSIC9S27l!jD1Xuh6~iG(&$7|$)j}^ z5j?JE_H;4U=is8eh#yLa7ZA3j1d#)iv09b|b(w$pi&LcuH4M@TrAywNj@<+HudqG_ z3mZ#;UTGdygApneqld0#2?WP*s1zdm^pDm@^1_F^rGxdF1rN+61hAS`(O$p4@~O8{dta3?KnWp6V7THR5Av!?bYs)GRI_tcr4 z!7}_!&3M4%GP1}-V>IJ^Ma9O+YbuL|+udPCpk4ysoetzUQ>;nt~ZCXvivJ=h=m95roi4;phW$)?_7 z`zD(lIav@r@@D_?vhb#N2c4FF+H}2(=I+|!ww|*UH(+wuthbeb9m+n5xEOBLyJ|r# zem!IwRDa>lwH#o?k=_wMbnL>BtxM}EpS@X%P-hA9CC|bWOi3O4zG{JrlYQ_1x^i}t z3eM5>&u>jp1UbqEocL9f!$;d@2$kkqYAzfe(E*HF-{s)8$j`#S^Jmc+Xw#zOATj-P z^nBZX-iRxFxX1m7E~^OiDGl~IT>R&hl`^nbJohl7<6w!{$NL0Lq1HU{$V&kau`^jR zTak(uf$o;OI#vKqei1f&9z?rAprf6Pit zx-nT=NrDfUa(qF=ARu8+XO+dp(A-eb8m|c zm-T)+9-b4hCSkJg#*OyaBq)U|2ps;jDeqC@WmoX$(ENHE&}$YtG(;Tv{)s}NWIY}0 z?7q)+;EkMD3D3HQvI{@j@pvpWBG_(nXD!fEFf|2b zlbP7r*9D9jP`h$)cP%LLc_80hL`3>7-^R`IaL3KR?~+`_owS-`JkU)q4(L{$9B|Ywta6p-?XN1bYdO)xWR8M#~Bg%JPK+4x=CjS~;MFT+30x>Dc=u zW1gD95)%?6eB^Y9>*Ha`)~aImJ&$9Cq2yU+R}$#0qmLIj%x+=HPumr0+Cxk1hEX#U zFS~>R2NUY~BYZ$UTAuU~!fP%NV_-EfWQbeNxg>~C4GOyRcYMRrc#zHgp#p*J9 zJHbVn!RTMZ?||5lNij0})@VS<1PTEIJNggShFbMHedo2JiZ01^CFTAPbOS2cXRy zMenMLA>h0(K>0$iT`kdPw0Fadmwlf5q1UCltZhaPP)kZ{(o{h746nZ5#Iq|I~7=0(p-#(${CLA!Vk7~wi# z1e56hgAsZwK|inF<)7zpU+`;)`Q+?dyoj4uvFG=2nd?B*Fts$3_`GRj^>69)^4X||1rNlWEKe@Iv$IpV^S{be+lwgw0dP3djjbt9IGyy ztNBY2(eT9tF!yW)w+59C&oyE}?C_@jyaD+2qKuE^#ha5&A`E|M*_5|wUv=5)Fjvrq z(h+{bs~lh<;JsT((AWil-^S?>6`K(|0SM25$0cmVZWy3Ohux>qnTUzj04pk}GzWO6 zc{?4KW%ntWXoC8{i4;DF;(+HE`)_b+BTnJ#qjg!y|NRIlR-qlsn-><{MXUb@5XPpu ztpE5PlWzqg`47^D+JDU?LK{ez*)F&fHa+%p?NsI~0HOghNd1g$lM*)nDS_GLfT`p> zA+aM6Q5M-fujuIJ>>eTMOyM_&rh!_R-|J0J%q}Wv*}92+G8yZ8@8pm1gkQR*Krugf zTE>AQh_@4bc}LT4DV-lO5v@U3lQFC`shKRi=}$KHr~PBlY&<{zyhL;aWH<4m_U>&} zz8Wpeh-zSr?a> ze`@-)__pLU+E{G=JEN#sp(37*k9a){*N4z3x~f(Ua5{w(D$%DniS841#h7XqiD^a^;Mi~)MH|4z34NtJB+Cib>@ z|Mgox#~*+VGJ?0qBnu1RSdah$4?`vnW|N@?B#{P+svyZbyvSsn~ zbZ~_bh!IS`ZUSi%_#ct)jUa~tDUuvW4|Hwgl6Ri09u?tes zN%IPBsI&VRsQjWTCT%ROdxUF^dU%>M{(gR;P5In89(#FImkns89wu7;eih7ZMmfVl zRSb=9tl$paSR=lzW%!A8KJ2Pg@Dh-DfsXX%%clLUqZ780g*Ly$r)@z4JA@}`LanNp zGZ*_>vsrUqBRzYD_6cbiNxjdtY0NJKLQ=ZbI17#Vw5Qw ziv`&T+TB#&7}*b11*hbzaSv^jXjs9=z>{j1U!HdNtO zoU5%&o+xDql*!D*p`>di1sJN zo1;bdNUT?Ekz>ah918?f`k_cYd;{LZq2s0eg8u*rSuU@_Y(WpVH)NJ!+*E8>*G&#| zoZ+!(sbm(gkyg9&xpfO9Bq1`(5zOY|zpH+JI3eN}8y(t8tXJS~p0J2B*)JUaR3eZS z1RmOkc~{4O-&mM`Yy4a={g2qnJBVyh{!- zmjQH|WrvD<#;?~soBg~4B=kgP6wtcH7ITP6>Y}x^K@@Di!Tk`nX5k!xs z$j$&jw>Hf-yUp$-;Ag4y&u==saQa`=VGezuYGj^E1F@1?M#2B-v55B3)ctE*d+sw3 z8G-+oB?b(X|NjRq{`3k&N6DxCVdq0v9>#Ozmu&0yWRda$t@A%CbU;JD==l~_mB9dJ z^&9}wndrFUC%SsCRR0f`D$wNywZ8v{%m01bVs z?}RYN)s5+kZA(6GP!frv97wY22#eqB*_JImBr;vWtrFT7$W7AOgKa;p_+4D2@_?fH znD)ck%KgRij~iDhDwWN$cYZ}p?HzvSjhB12S=0nk=EyU{>EE5UXsObe6a@FTV zVSv;NeR9B9a?j-P$?91qXHRu1=)(G&V~yh#Mf?qlt%;X|8g|rOy?jK_IX9mcM__&W YHR=JUF!u!bW)945x8ttd9qv*855h*y*#H0l literal 0 HcmV?d00001 diff --git a/covas_mobile_new/lib/pages/MapboxPages.dart b/covas_mobile_new/lib/pages/MapboxPages.dart index a345fcc..75a8c1e 100644 --- a/covas_mobile_new/lib/pages/MapboxPages.dart +++ b/covas_mobile_new/lib/pages/MapboxPages.dart @@ -1,14 +1,15 @@ import 'dart:convert'; import 'dart:io'; +import 'dart:typed_data'; import 'package:flutter/material.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; // For environment variables -import 'package:flutter/services.dart'; // For loading assets +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:flutter/services.dart'; import 'package:http/http.dart' as http; -import 'package:mapbox_gl/mapbox_gl.dart'; +import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart' as mapbox; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:geolocator/geolocator.dart'; // For getting the user's location +import 'package:geolocator/geolocator.dart' as geo; -import '../classes/alert.dart'; // Assuming this contains your error dialog code. +import '../classes/alert.dart'; import '../variable/globals.dart' as globals; import '../classes/MyDrawer.dart'; import '../classes/auth_service.dart'; @@ -16,10 +17,15 @@ import '../classes/auth_service.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:covas_mobile/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; -import '../locale_provider.dart'; // +import '../locale_provider.dart'; void main() async { - await dotenv.load(fileName: ".env"); // Load .env file + WidgetsFlutterBinding.ensureInitialized(); + await dotenv.load(fileName: ".env"); + + // Set the access token globally + mapbox.MapboxOptions.setAccessToken(dotenv.env['MAPBOX_ACCESS_TOKEN'] ?? ''); + runApp(const MyApp()); } @@ -30,9 +36,7 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Directions Example', - theme: ThemeData( - primarySwatch: Colors.blue, - ), + theme: ThemeData(primarySwatch: Colors.blue), home: const MapboxPages(title: 'Event Location', place: "Flutter"), ); } @@ -52,36 +56,26 @@ class MapboxPages extends StatefulWidget { class _MapboxPagesState extends State with ShowAlertDialog { final AuthService _authService = AuthService(); - late MapboxMapController mapController; - late String mapboxAccessToken; - List routeCoordinates = []; - String selectedMode = 'driving'; + mapbox.MapboxMap? mapboxMap; + mapbox.PointAnnotationManager? pointAnnotationManager; + mapbox.PolylineAnnotationManager? polylineAnnotationManager; + double longitude = 0.0; double latitude = 0.0; bool isLoading = true; - late LatLng userPosition; + mapbox.Point? userPosition; bool isUserPositionInitialized = false; - Line? currentRouteLine; + + String selectedMode = 'driving'; + List> routeCoordinates = []; @override void initState() { super.initState(); _authService.checkTokenStatus(context); - _getUserLocation(); } - void _initToken() { - mapboxAccessToken = dotenv.env['MAPBOX_ACCESS_TOKEN'] ?? ''; - if (mapboxAccessToken.isEmpty) { - showAlertDialog( - context, - AppLocalizations.of(context)?.error ?? "Error", - AppLocalizations.of(context)?.map_token ?? - "Map Access Token is not available."); - } - } - Future _getEventInfo() async { SharedPreferences prefs = await SharedPreferences.getInstance(); var accessToken = prefs.getString("access_token") ?? ""; @@ -96,119 +90,51 @@ class _MapboxPagesState extends State with ShowAlertDialog { latitude = events["latitude"]; longitude = events["longitude"]; - setState(() { - isLoading = false; - }); + setState(() => isLoading = false); } else { _handleErrorResponse(responseGet.statusCode); } } else { - showAlertDialog(context, AppLocalizations.of(context)?.error ?? "Error", - AppLocalizations.of(context)?.invalid_cache ?? "Invalid cache."); + showAlertDialog(context, "Error", "Invalid cache."); } } void _handleErrorResponse(int statusCode) { - final messages = { - 400: AppLocalizations.of(context)?.request_error ?? - "Poorly constructed query", - 406: AppLocalizations.of(context)?.incorrect_password ?? - "Incorrect password", - 404: AppLocalizations.of(context)?.unknown_user ?? "Unknown user", - 403: AppLocalizations.of(context)?.disabled_user ?? "Disabled user", - 410: AppLocalizations.of(context)?.invalid_token ?? "Invalid token", - 500: AppLocalizations.of(context)?.internal_error_server ?? - "Internal error server" - }; - - final errorMessage = messages[statusCode] ?? - AppLocalizations.of(context)?.unknown_error_auth ?? - "Unknown error auth"; - showAlertDialog( - context, AppLocalizations.of(context)?.error ?? "Error", errorMessage); + final errorMessage = "Error $statusCode fetching event"; + showAlertDialog(context, "Error", errorMessage); } Future _getUserLocation() async { try { - bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); - if (!serviceEnabled) { - showAlertDialog( - context, - AppLocalizations.of(context)?.error ?? "Error", - AppLocalizations.of(context)?.geo_disabled ?? - "Location services are disabled."); - return; + bool serviceEnabled = await geo.Geolocator.isLocationServiceEnabled(); + if (!serviceEnabled) return; + + geo.LocationPermission permission = + await geo.Geolocator.checkPermission(); + if (permission == geo.LocationPermission.denied) { + permission = await geo.Geolocator.requestPermission(); } - LocationPermission permission = await Geolocator.checkPermission(); - if (permission == LocationPermission.denied) { - permission = await Geolocator.requestPermission(); - if (permission == LocationPermission.denied) { - showAlertDialog( - context, - AppLocalizations.of(context)?.error ?? "Error", - AppLocalizations.of(context)?.permission_denied ?? - "Location permissions are denied."); - return; - } - } + if (permission == geo.LocationPermission.deniedForever) return; + + geo.Position position = await geo.Geolocator.getCurrentPosition(); + setState(() { + userPosition = mapbox.Point( + coordinates: + mapbox.Position(position.latitude, position.longitude)); + isUserPositionInitialized = true; + }); - if (permission == LocationPermission.deniedForever) { - showAlertDialog( - context, - AppLocalizations.of(context)?.error ?? "Error", - AppLocalizations.of(context)?.enable_permission ?? - "Location permissions are permanently denied. Enable them in settings."); - return; - } - const LocationSettings locationSettings = LocationSettings( - accuracy: LocationAccuracy.medium, timeLimit: Duration(seconds: 5)); - Position? position; - try { - position = await Geolocator.getCurrentPosition( - locationSettings: locationSettings); - } on LocationServiceDisabledException { - // Handle location services disabled - position = await Geolocator.getLastKnownPosition(); - if (position == null) { - showAlertDialog( - context, - AppLocalizations.of(context)?.error ?? "Error", - AppLocalizations.of(context)?.no_last_position ?? - "No last known position available.."); - } - } catch (e) { - // Handle other errors - position = await Geolocator.getLastKnownPosition(); - if (position == null) { - showAlertDialog( - context, - AppLocalizations.of(context)?.error ?? "Error", - AppLocalizations.of(context)?.no_last_position ?? - "No last known position available"); - } - } - if (position != null) { - setState(() { - userPosition = LatLng(position!.latitude, position!.longitude); - isUserPositionInitialized = true; - }); - } - _initToken(); _getEventInfo(); } catch (e) { - showAlertDialog( - context, - AppLocalizations.of(context)?.error ?? "Error", - AppLocalizations.of(context)?.failed_location ?? - "Failed to get user location"); + showAlertDialog(context, "Error", "Failed to get location"); } } Future _fetchRoute( - LatLng origin, LatLng destination, String mode) async { + mapbox.Point origin, mapbox.Point destination, String mode) async { final url = Uri.parse( - 'https://api.mapbox.com/directions/v5/mapbox/$mode/${origin.longitude},${origin.latitude};${destination.longitude},${destination.latitude}?geometries=geojson&access_token=$mapboxAccessToken', + 'https://api.mapbox.com/directions/v5/mapbox/$mode/${origin.coordinates.lng},${origin.coordinates.lat};${destination.coordinates.lng},${destination.coordinates.lat}?geometries=geojson&access_token=${dotenv.env['MAPBOX_ACCESS_TOKEN']}', ); final response = await http.get(url); @@ -216,156 +142,63 @@ class _MapboxPagesState extends State with ShowAlertDialog { final data = jsonDecode(response.body); final geometry = data['routes'][0]['geometry']['coordinates']; setState(() { - routeCoordinates = geometry.map((coord) { - return LatLng(coord[1], coord[0]); - }).toList(); + routeCoordinates = (geometry as List) + .map>((coord) => [coord[0], coord[1]]) + .toList(); }); - } else { - showAlertDialog( - context, - AppLocalizations.of(context)?.error ?? "Error", - AppLocalizations.of(context)?.failed_fetch ?? - "Failed to fetch the route"); - } - } - - // Called when the map is created - void _onStyleLoaded() async { - // Log the map controller and coordinates - - // Check if the mapController is really initialized - if (mapController != null) { - try { - // Ensure the coordinates are valid - if (latitude != 0.0 && longitude != 0.0) { - // Load marker image as Uint8List - final userMarkerImage = await _loadMarkerImage('images/marker.png'); - - // Register the image with Mapbox - await mapController.addImage('event-marker', userMarkerImage); - - final symbolOptions = SymbolOptions( - geometry: LatLng(latitude, longitude), - iconImage: "event-marker", // Use the registered custom marker - iconSize: 0.4, // Optional: Adjust size - ); - - // Debugging symbol options - - // Add symbol to map - mapController!.addSymbol(symbolOptions); - } else { - showAlertDialog( - context, - AppLocalizations.of(context)?.error ?? "Error", - AppLocalizations.of(context)?.invalid_coordinates_symbol ?? - "Error: Invalid coordinates, cannot add symbol."); - } - } catch (e) { - // Handle any exception that occurs when adding the symbol - showAlertDialog( - context, - AppLocalizations.of(context)?.error ?? "Error", - AppLocalizations.of(context)?.error_symbol ?? - "Error when adding symbol."); - } - } else { - showAlertDialog( - context, - AppLocalizations.of(context)?.error ?? "Error", - AppLocalizations.of(context)?.error_symbol ?? - "Error when adding symbol."); } } Future _drawRouteAndMarkers() async { - // Remove previous route line if it exists - if (currentRouteLine != null) { - await mapController.removeLine(currentRouteLine!); - currentRouteLine = null; - } - if (!isUserPositionInitialized) { - showAlertDialog( - context, - AppLocalizations.of(context)?.error ?? "Error", - AppLocalizations.of(context)?.position_not_init ?? - "User position is not yet initialized. Try again."); - return; - } + if (mapboxMap == null || !isUserPositionInitialized) return; - if (mapController != null && - userPosition != null && - latitude != 0.0 && - longitude != 0.0) { - final destination = LatLng(latitude, longitude); + // Managers + pointAnnotationManager ??= + await mapboxMap!.annotations.createPointAnnotationManager(); + polylineAnnotationManager ??= + await mapboxMap!.annotations.createPolylineAnnotationManager(); - // Register the custom images - // Add event marker + // Clear old annotations + await pointAnnotationManager!.deleteAll(); + await polylineAnnotationManager!.deleteAll(); - final eventMarkerImage = await _loadMarkerImage('images/marker-red.png'); + final destination = + mapbox.Point(coordinates: mapbox.Position(longitude, latitude)); - // Register the image with Mapbox - await mapController.addImage('user-marker', eventMarkerImage); - await mapController.addSymbol(SymbolOptions( - geometry: userPosition, - iconImage: 'user-marker', // Custom icon for event - iconSize: 0.2, + // Add user marker + final userIcon = await _loadMarkerImage('images/marker.png'); + await pointAnnotationManager!.create(mapbox.PointAnnotationOptions( + geometry: mapbox.Point( + coordinates: mapbox.Position( + userPosition!.coordinates.lng, userPosition!.coordinates.lat)), + image: userIcon, + iconSize: 0.4, + )); + + // Add event marker + final eventIcon = await _loadMarkerImage('images/marker-red.png'); + await pointAnnotationManager!.create(mapbox.PointAnnotationOptions( + geometry: mapbox.Point( + coordinates: mapbox.Position( + destination.coordinates.lng, destination.coordinates.lat)), + image: eventIcon, + iconSize: 0.4, + )); + + // Fetch and draw route + await _fetchRoute(userPosition!, destination, selectedMode); + if (routeCoordinates.isNotEmpty) { + await polylineAnnotationManager!.create(mapbox.PolylineAnnotationOptions( + geometry: mapbox.LineString( + coordinates: + routeCoordinates.map((c) => mapbox.Position(c[0], c[1])).toList(), + ), + lineColor: Colors.blue.value, + lineWidth: 4.0, )); - - // Fetch and draw route - await _fetchRoute(userPosition, destination, selectedMode); - - if (routeCoordinates.isNotEmpty) { - currentRouteLine = await mapController.addLine( - LineOptions( - geometry: routeCoordinates, - lineColor: '#3b9ddd', - lineWidth: 5.0, - lineOpacity: 0.8, - ), - ); - - _zoomToFitRoute(routeCoordinates); - } - } else { - showAlertDialog( - context, - AppLocalizations.of(context)?.error ?? "Error", - AppLocalizations.of(context)?.invalid_coordinates ?? - "Invalid coordinates or user position."); } } - void _zoomToFitRoute(List coordinates) { - // Calculate the bounding box - double minLat = coordinates.first.latitude; - double maxLat = coordinates.first.latitude; - double minLng = coordinates.first.longitude; - double maxLng = coordinates.first.longitude; - - for (LatLng coord in coordinates) { - if (coord.latitude < minLat) minLat = coord.latitude; - if (coord.latitude > maxLat) maxLat = coord.latitude; - if (coord.longitude < minLng) minLng = coord.longitude; - if (coord.longitude > maxLng) maxLng = coord.longitude; - } - - // Define the bounds - LatLng southwest = LatLng(minLat, minLng); - LatLng northeast = LatLng(maxLat, maxLng); - - mapController.moveCamera( - CameraUpdate.newLatLngBounds( - LatLngBounds(southwest: southwest, northeast: northeast), - left: 50, // Padding on the left - top: 50, // Padding on the top - right: 50, // Padding on the right - bottom: 50, // Padding on the bottom - ), - ); - } - - // Load image from assets Future _loadMarkerImage(String assetPath) async { final ByteData data = await rootBundle.load(assetPath); return data.buffer.asUint8List(); @@ -374,78 +207,23 @@ class _MapboxPagesState extends State with ShowAlertDialog { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text(widget.place), - actions: [ - DropdownButton( - value: selectedMode, - items: [ - DropdownMenuItem( - value: 'walking', - child: Row( - children: [ - Icon(Icons.directions_walk, color: Colors.blue), - SizedBox(width: 8), - Text(AppLocalizations.of(context)?.walking ?? 'Walking'), - ], - ), - ), - DropdownMenuItem( - value: 'cycling', - child: Row( - children: [ - Icon(Icons.directions_bike, color: Colors.green), - SizedBox(width: 8), - Text(AppLocalizations.of(context)?.cycling ?? 'Cycling'), - ], - ), - ), - DropdownMenuItem( - value: 'driving', - child: Row( - children: [ - Icon(Icons.directions_car, color: Colors.red), - SizedBox(width: 8), - Text(AppLocalizations.of(context)?.driving ?? 'Driving'), - ], - ), - ), - ], - onChanged: (mode) { - setState(() { - selectedMode = mode!; - }); - }, - ) - ], - ), + appBar: AppBar(title: Text(widget.place)), drawer: MyDrawer(), - body: Stack( - children: [ - isLoading - ? Center(child: CircularProgressIndicator()) - : MapboxMap( - accessToken: mapboxAccessToken, - onMapCreated: (controller) { - mapController = controller; - }, - onStyleLoadedCallback: _onStyleLoaded, - initialCameraPosition: CameraPosition( - target: LatLng(latitude, longitude), - zoom: 14.0, - ), - ), - Positioned( - bottom: 20, - right: 20, - child: FloatingActionButton( - onPressed: _drawRouteAndMarkers, - child: Icon(Icons.directions), - tooltip: AppLocalizations.of(context)?.get_direction ?? - 'Get Directions and Markers', + body: isLoading + ? const Center(child: CircularProgressIndicator()) + : mapbox.MapWidget( + onMapCreated: (controller) { + mapboxMap = controller; + }, + cameraOptions: mapbox.CameraOptions( + center: mapbox.Point( + coordinates: mapbox.Position(longitude, latitude)), + zoom: 14.0, + ), ), - ), - ], + floatingActionButton: FloatingActionButton( + onPressed: _drawRouteAndMarkers, + child: const Icon(Icons.directions), ), ); } From 63ea3091e837d53b5f47e6a2e0aa4af491900a53 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Mon, 1 Sep 2025 23:07:40 +0200 Subject: [PATCH 06/16] fix flutter_notifications_lcoal --- covas_mobile_new/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/covas_mobile_new/pubspec.yaml b/covas_mobile_new/pubspec.yaml index 11f865a..e644a36 100644 --- a/covas_mobile_new/pubspec.yaml +++ b/covas_mobile_new/pubspec.yaml @@ -37,7 +37,6 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - flutter_local_notifications: ^19.4.1 timezone: ^0.10.1 cupertino_icons: ^1.0.2 http: ^1.2.1 @@ -59,6 +58,7 @@ dependencies: encrypt_shared_preferences: ^0.9.10 provider: ^6.1.2 # ou la dernière version mapbox_maps_flutter: ^2.10.0 + flutter_local_notifications: ^19.4.1 dev_dependencies: flutter_test: From 210da71d50d526995bfef5276dcd0e426dedce68 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Tue, 2 Sep 2025 10:15:03 +0200 Subject: [PATCH 07/16] fix notification local --- covas_mobile_new/android/app/build.gradle.kts | 5 +++++ covas_mobile_new/android/app/src/main/AndroidManifest.xml | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/covas_mobile_new/android/app/build.gradle.kts b/covas_mobile_new/android/app/build.gradle.kts index 5bd1701..110fc0e 100644 --- a/covas_mobile_new/android/app/build.gradle.kts +++ b/covas_mobile_new/android/app/build.gradle.kts @@ -13,6 +13,7 @@ android { compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 + isCoreLibraryDesugaringEnabled = true } kotlinOptions { @@ -39,6 +40,10 @@ android { } } +dependencies { + coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4") +} + flutter { source = "../.." } diff --git a/covas_mobile_new/android/app/src/main/AndroidManifest.xml b/covas_mobile_new/android/app/src/main/AndroidManifest.xml index 42ed197..7d164c5 100644 --- a/covas_mobile_new/android/app/src/main/AndroidManifest.xml +++ b/covas_mobile_new/android/app/src/main/AndroidManifest.xml @@ -3,6 +3,10 @@ android:label="covas_mobile_new" android:name="${applicationName}" android:icon="@mipmap/ic_launcher"> + + - From 9a9287bd208cf74d14d079c5b5f0de8ab60a98ca Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Tue, 2 Sep 2025 13:58:39 +0200 Subject: [PATCH 08/16] fix permissions --- covas_mobile_new/android/app/src/main/AndroidManifest.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/covas_mobile_new/android/app/src/main/AndroidManifest.xml b/covas_mobile_new/android/app/src/main/AndroidManifest.xml index 7d164c5..e132fdf 100644 --- a/covas_mobile_new/android/app/src/main/AndroidManifest.xml +++ b/covas_mobile_new/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,8 @@ - + + + @@ -15,6 +18,7 @@ android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" + android:enableOnBackInvokedCallback="true" android:windowSoftInputMode="adjustResize">