29 Commits

Author SHA1 Message Date
3a74b8017d Scooter order payment screen fix 2026-09-15 21:28:33 +03:00
153a763b6f Registration pipeline chenged - fill profile step added. Order payment fixed 2026-09-14 19:20:31 +03:00
7460408784 Finish screen - attention message added 2026-09-14 08:42:25 +03:00
5f57af2ad2 bug fixes 2026-09-04 13:41:57 +03:00
cf5b56e365 Tariff subsriptionId fix 2026-08-31 10:37:08 +03:00
b0c9f6dc17 fix qr 2026-08-31 09:57:40 +03:00
ece8e7ba79 bug fixes 2026-08-31 09:53:29 +03:00
02b3e5caa8 Tariff description fix, iOS payment card binding fix 2026-08-31 09:18:33 +03:00
a556dc5736 bug fixes 2026-08-29 00:00:09 +03:00
6513a004d9 fix profile 2026-08-18 15:09:53 +03:00
80a95ece5b fix to prod 2026-08-14 13:47:11 +03:00
f53fea576e add page company detail 2026-08-13 09:34:06 +03:00
182be1049b some fix
# Conflicts:
#	lib/presentation/navigation/app_router.dart
#	pubspec.yaml
2026-08-11 00:23:16 +03:00
c9b8d143d1 fixing the app launch bug 2026-07-27 11:06:04 +03:00
d5f70ee9c4 change package name 2026-07-19 20:27:26 +03:00
99d2875b56 Merge pull request 'map fix' (#8) from fix/ios-fix into main
Reviewed-on: #8
2026-07-16 11:16:14 +00:00
46cd22c287 fix merge conflict 2026-07-16 14:14:22 +03:00
0a6c40181a Merge pull request 'add test block' (#7) from fix/bug-fix into main
Reviewed-on: #7
2026-07-16 07:26:56 +00:00
fcb23e0d5f fix merge conflict 2026-07-16 10:15:10 +03:00
7a2c214ff5 map fix 2026-07-15 22:58:33 +03:00
11c00ad2cc add test block 2026-07-15 22:46:42 +03:00
419b54d5dd Merge pull request 'fix payment card change. fix adding a new payment card' (#6) from fix/bug-fix into main
Reviewed-on: #6
2026-07-13 12:47:55 +00:00
a6e8b9d070 fix payment card change. fix adding a new payment card 2026-07-13 15:46:34 +03:00
4a919a5bcc Merge pull request 'fix add new card in bottomsheet' (#5) from fix/bug-fix into main
Reviewed-on: #5
2026-07-13 08:50:59 +00:00
e91f373258 fix add new card in bottomsheet 2026-07-13 11:49:00 +03:00
902c6d27a4 Merge pull request 'fix/bug-fix' (#4) from fix/bug-fix into main
Reviewed-on: #4
2026-07-12 22:53:19 +00:00
98c5a7a1d1 fix 2026-07-13 01:38:13 +03:00
9eda119527 fix 2026-07-08 13:09:20 +03:00
939b5be7d8 Merge pull request 'fix/ios-launch' (#3) from fix/ios-launch into main
Reviewed-on: #3
2026-06-01 15:02:16 +00:00
372 changed files with 26925 additions and 22785 deletions

View File

@@ -15,7 +15,7 @@ plugins {
} }
android { android {
namespace = "com.sparkit.be_happy" namespace = "com.behappybel.behappy"
compileSdk = flutter.compileSdkVersion compileSdk = flutter.compileSdkVersion
ndkVersion = "27.0.12077973" ndkVersion = "27.0.12077973"
@@ -44,7 +44,7 @@ android {
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.sparkit.behappy" applicationId = "com.behappybel.behappy"
// You can update the following values to match your application needs. // You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config. // For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = 26 minSdk = 26

View File

@@ -8,6 +8,7 @@
<queries> <queries>
<intent> <intent>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" /> <data android:scheme="https" />
</intent> </intent>
<intent> <intent>
@@ -25,7 +26,7 @@
<meta-data <meta-data
android:name="com.yandex.runtime.API_KEY" android:name="com.yandex.runtime.API_KEY"
android:value="a0ef1404-2650-4f28-9891-c965ecc09174" /> android:value="45fe500d-b549-4444-9e4b-3b2acd78ee2c" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
@@ -49,6 +50,14 @@
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
<intent-filter android:label="card_binding_deep_link">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="com.behappy.app" android:host="card-result" />
</intent-filter>
</activity> </activity>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->

View File

@@ -1,4 +1,4 @@
package com.sparkit.be_happy package com.behappybel.behappy
import android.os.Bundle import android.os.Bundle
import com.yandex.mapkit.MapKitFactory import com.yandex.mapkit.MapKitFactory
@@ -6,7 +6,7 @@ import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity() { class MainActivity : FlutterActivity() {
override protected fun onCreate(savedInstanceState: Bundle?) { override protected fun onCreate(savedInstanceState: Bundle?) {
MapKitFactory.setApiKey("a0ef1404-2650-4f28-9891-c965ecc09174") MapKitFactory.setApiKey("45fe500d-b549-4444-9e4b-3b2acd78ee2c")
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 B

View File

@@ -1,12 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" /> <item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
<!-- You can insert your own image assets here --> </item>
<!-- <item> <item>
<bitmap <bitmap android:gravity="center" android:src="@drawable/splash"/>
android:gravity="center" </item>
android:src="@mipmap/launch_image" />
</item> -->
</layer-list> </layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 B

View File

@@ -1,12 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" /> <item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
<!-- You can insert your own image assets here --> </item>
<!-- <item> <item>
<bitmap <bitmap android:gravity="center" android:src="@drawable/splash"/>
android:gravity="center" </item>
android:src="@mipmap/launch_image" />
</item> -->
</layer-list> </layer-list>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@@ -5,6 +5,10 @@
<!-- Show a splash screen on the activity. Automatically removed when <!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame --> the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item> <item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style> </style>
<!-- Theme applied to the Android Window as soon as the process has started. <!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your This theme determines the color of the Android Window while your

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@@ -5,6 +5,10 @@
<!-- Show a splash screen on the activity. Automatically removed when <!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame --> the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item> <item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style> </style>
<!-- Theme applied to the Android Window as soon as the process has started. <!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your This theme determines the color of the Android Window while your

View File

@@ -2,3 +2,8 @@ org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
yandexMapkit.variant=full yandexMapkit.variant=full
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
kotlin.incremental=false
# This newDsl flag was added automatically by Flutter migrator
android.newDsl=false

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

BIN
assets/icons/failed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
assets/icons/fine.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
assets/icons/success.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
assets/payment_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
assets/rules_alpha.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
assets/rules_apple_pay.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
assets/rules_belcard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
assets/rules_mastercard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
assets/rules_visa.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
assets/tech_works.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

3
devtools_options.yaml Normal file
View File

@@ -0,0 +1,3 @@
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:

View File

@@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>MinimumOSVersion</key>
<string>13.0</string>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>en</string> <string>en</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>

View File

@@ -1,6 +1,6 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig" #include "Generated.xcconfig"
#include? "Secrets.xcconfig" #include? "Secrets.xcconfig"
YANDEX_MAPKIT_API_KEY=a0ef1404-2650-4f28-9891-c965ecc09174 YANDEX_MAPKIT_API_KEY=45fe500d-b549-4444-9e4b-3b2acd78ee2c
// Переопределение Pods/ML Kit: arm64 для симулятора на Apple Silicon (M1/M4) // Переопределение Pods/ML Kit: arm64 для симулятора на Apple Silicon (M1/M4)
EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386 EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386

View File

@@ -1,5 +1,5 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig" #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"
#include "Generated.xcconfig" #include "Generated.xcconfig"
#include? "Secrets.xcconfig" #include? "Secrets.xcconfig"
YANDEX_MAPKIT_API_KEY=a0ef1404-2650-4f28-9891-c965ecc09174 YANDEX_MAPKIT_API_KEY=45fe500d-b549-4444-9e4b-3b2acd78ee2c
EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386 EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386

View File

@@ -1,5 +1,5 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig" #include "Generated.xcconfig"
#include? "Secrets.xcconfig" #include? "Secrets.xcconfig"
YANDEX_MAPKIT_API_KEY=a0ef1404-2650-4f28-9891-c965ecc09174 YANDEX_MAPKIT_API_KEY=45fe500d-b549-4444-9e4b-3b2acd78ee2c
EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386 EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386

View File

@@ -1,8 +1,9 @@
# image_picker_ios и др. требуют минимум iOS 13 # image_picker_ios и др. требуют минимум iOS 13
platform :ios, '13.0' platform :ios, '15.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'
ENV['YANDEX_MAPKIT_VARIANT'] = 'full'
project 'Runner', { project 'Runner', {
'Debug' => :debug, 'Debug' => :debug,
@@ -43,6 +44,7 @@ post_install do |installer|
# ML Kit исключает arm64 для симулятора → сборка только x86_64. # ML Kit исключает arm64 для симулятора → сборка только x86_64.
# На M1 это ещё могло работать через Rosetta; на M4 симулятор только arm64. # На M1 это ещё могло работать через Rosetta; на M4 симулятор только arm64.
config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'i386' config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'i386'
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
end end
end end
end end

View File

@@ -2,6 +2,8 @@ PODS:
- device_info_plus (0.0.1): - device_info_plus (0.0.1):
- Flutter - Flutter
- Flutter (1.0.0) - Flutter (1.0.0)
- flutter_native_splash (2.4.3):
- Flutter
- flutter_secure_storage (6.0.0): - flutter_secure_storage (6.0.0):
- Flutter - Flutter
- geolocator_apple (1.2.0): - geolocator_apple (1.2.0):
@@ -12,9 +14,6 @@ PODS:
- mobile_scanner (7.0.0): - mobile_scanner (7.0.0):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- shared_preferences_foundation (0.0.1): - shared_preferences_foundation (0.0.1):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
@@ -22,17 +21,17 @@ PODS:
- Flutter - Flutter
- yandex_mapkit (0.0.1): - yandex_mapkit (0.0.1):
- Flutter - Flutter
- YandexMapsMobile (= 4.22.0-lite) - YandexMapsMobile (= 4.22.0-full)
- YandexMapsMobile (4.22.0-lite) - YandexMapsMobile (4.22.0-full)
DEPENDENCIES: DEPENDENCIES:
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- geolocator_apple (from `.symlinks/plugins/geolocator_apple/darwin`) - geolocator_apple (from `.symlinks/plugins/geolocator_apple/darwin`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- mobile_scanner (from `.symlinks/plugins/mobile_scanner/darwin`) - mobile_scanner (from `.symlinks/plugins/mobile_scanner/darwin`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- yandex_mapkit (from `.symlinks/plugins/yandex_mapkit/ios`) - yandex_mapkit (from `.symlinks/plugins/yandex_mapkit/ios`)
@@ -46,6 +45,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/device_info_plus/ios" :path: ".symlinks/plugins/device_info_plus/ios"
Flutter: Flutter:
:path: Flutter :path: Flutter
flutter_native_splash:
:path: ".symlinks/plugins/flutter_native_splash/ios"
flutter_secure_storage: flutter_secure_storage:
:path: ".symlinks/plugins/flutter_secure_storage/ios" :path: ".symlinks/plugins/flutter_secure_storage/ios"
geolocator_apple: geolocator_apple:
@@ -54,8 +55,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/image_picker_ios/ios" :path: ".symlinks/plugins/image_picker_ios/ios"
mobile_scanner: mobile_scanner:
:path: ".symlinks/plugins/mobile_scanner/darwin" :path: ".symlinks/plugins/mobile_scanner/darwin"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
shared_preferences_foundation: shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin" :path: ".symlinks/plugins/shared_preferences_foundation/darwin"
url_launcher_ios: url_launcher_ios:
@@ -66,16 +65,16 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13 flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e
image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326 image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326
mobile_scanner: 9157936403f5a0644ca3779a38ff8404c5434a93 mobile_scanner: 9157936403f5a0644ca3779a38ff8404c5434a93
path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
yandex_mapkit: bac34ca1bdf97e87252a8c6d09a95b1fe39ba103 yandex_mapkit: b0468cf6fdc2e5ef315e08c081cb48763db1edee
YandexMapsMobile: c73844c6096bbb240d1491adc511c2ef4a88d88d YandexMapsMobile: 27e6e45425bb61f0be2dbc2bf02d4e64926691a9
PODFILE CHECKSUM: 715b1068ab8815ca4115a24e305e836709652b69 PODFILE CHECKSUM: 4db91eb18e4c468b9b75ce0a1fbe33194b57f06a
COCOAPODS: 1.16.2 COCOAPODS: 1.16.2

View File

@@ -10,12 +10,12 @@
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
6D33173F8CCB65895D564988 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BB22D9E6003D7254B27B141 /* Pods_RunnerTests.framework */; }; 719658A7EA74BCF79744189C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 815E41E9A67B82F3B5893FB0 /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
947230899A63DCC5FC354559 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5825CAAC7BEAFA8756F6D22 /* Pods_RunnerTests.framework */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
FB3C1019114E649A3758FC7D /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 151F40E0A8A0B88D7F9715D8 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@@ -42,30 +42,30 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
0EB91AA8815BC4C23E9C769C /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; 12F1F4F8ABC8CE708CB9918F /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
151F40E0A8A0B88D7F9715D8 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; }; 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
4BB22D9E6003D7254B27B141 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4AADFAE03DF1A02E1E799949 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
4D0302F803C0949E93DDCE44 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; }; 53B78B2283B7ADCE0208F756 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
525F1415727A8E2A6F5CA828 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; }; 673086666704B99027FC010B /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
6EC6FEDB5882EB1ECF391D95 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB41CF90195004384FC /* Profile.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Profile.xcconfig; path = Flutter/Profile.xcconfig; sourceTree = "<group>"; }; 7AFC7F9B8515A109C72DDF1B /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
815E41E9A67B82F3B5893FB0 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9740EEB41CF90195004384FC /* Profile.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Profile.xcconfig; path = Flutter/Profile.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = "<group>"; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
BAF1C86965EF66AE2F0839BD /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; }; A5825CAAC7BEAFA8756F6D22 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BE9A8C77364E79EA4C6EE36B /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
D24CB1920C4748F67C854B22 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@@ -73,7 +73,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
6D33173F8CCB65895D564988 /* Pods_RunnerTests.framework in Frameworks */, 947230899A63DCC5FC354559 /* Pods_RunnerTests.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -81,7 +81,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
FB3C1019114E649A3758FC7D /* Pods_Runner.framework in Frameworks */, 719658A7EA74BCF79744189C /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -96,6 +96,15 @@
path = RunnerTests; path = RunnerTests;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
4E47A3B8F8440AE11EF826D6 /* Frameworks */ = {
isa = PBXGroup;
children = (
815E41E9A67B82F3B5893FB0 /* Pods_Runner.framework */,
A5825CAAC7BEAFA8756F6D22 /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = { 9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -115,8 +124,8 @@
97C146F01CF9000F007C117D /* Runner */, 97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */, 97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */, 331C8082294A63A400263BE5 /* RunnerTests */,
991E98147265C7C44D711731 /* Pods */, BBAC3160211F77BA6C1CDBEB /* Pods */,
E94B50B8FA90842D98EF918A /* Frameworks */, 4E47A3B8F8440AE11EF826D6 /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@@ -144,29 +153,19 @@
path = Runner; path = Runner;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
991E98147265C7C44D711731 /* Pods */ = { BBAC3160211F77BA6C1CDBEB /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4D0302F803C0949E93DDCE44 /* Pods-Runner.debug.xcconfig */, 4AADFAE03DF1A02E1E799949 /* Pods-Runner.debug.xcconfig */,
0EB91AA8815BC4C23E9C769C /* Pods-Runner.release.xcconfig */, 673086666704B99027FC010B /* Pods-Runner.release.xcconfig */,
525F1415727A8E2A6F5CA828 /* Pods-Runner.profile.xcconfig */, 53B78B2283B7ADCE0208F756 /* Pods-Runner.profile.xcconfig */,
BAF1C86965EF66AE2F0839BD /* Pods-RunnerTests.debug.xcconfig */, 7AFC7F9B8515A109C72DDF1B /* Pods-RunnerTests.debug.xcconfig */,
D24CB1920C4748F67C854B22 /* Pods-RunnerTests.release.xcconfig */, 12F1F4F8ABC8CE708CB9918F /* Pods-RunnerTests.release.xcconfig */,
BE9A8C77364E79EA4C6EE36B /* Pods-RunnerTests.profile.xcconfig */, 6EC6FEDB5882EB1ECF391D95 /* Pods-RunnerTests.profile.xcconfig */,
); );
name = Pods;
path = Pods; path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
E94B50B8FA90842D98EF918A /* Frameworks */ = {
isa = PBXGroup;
children = (
151F40E0A8A0B88D7F9715D8 /* Pods_Runner.framework */,
4BB22D9E6003D7254B27B141 /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@@ -174,7 +173,7 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = ( buildPhases = (
1D742F73AAFC432DF3836D7E /* [CP] Check Pods Manifest.lock */, 8320BCAEA155F95875F06656 /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */, 331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */, 331C807F294A63A400263BE5 /* Resources */,
83F4E53737A5B4793588BFEB /* Frameworks */, 83F4E53737A5B4793588BFEB /* Frameworks */,
@@ -193,15 +192,15 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
8734FCBECF65F25CB259DF82 /* [CP] Check Pods Manifest.lock */, C59C8F9337F753AC74343087 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */, 9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */, 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
25F6FF3856E913FFAF963081 /* [CP] Embed Pods Frameworks */, FB90C79E7B88832806AD3371 /* [CP] Embed Pods Frameworks */,
FF12327738E91E5AA87207B8 /* [CP] Copy Pods Resources */, 81264E30AB9A7C4C10AB44BA /* [CP] Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
@@ -273,7 +272,40 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
1D742F73AAFC432DF3836D7E /* [CP] Check Pods Manifest.lock */ = { 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";
};
81264E30AB9A7C4C10AB44BA /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
8320BCAEA155F95875F06656 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@@ -295,40 +327,22 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
25F6FF3856E913FFAF963081 /* [CP] Embed Pods Frameworks */ = { 9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1; alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputPaths = ( inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
); );
name = "Thin Binary"; name = "Run Script";
outputPaths = ( outputPaths = (
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
}; };
8734FCBECF65F25CB259DF82 /* [CP] Check Pods Manifest.lock */ = { C59C8F9337F753AC74343087 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@@ -350,36 +364,21 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
9740EEB61CF901F6004384FC /* Run Script */ = { FB90C79E7B88832806AD3371 /* [CP] Embed Pods Frameworks */ = {
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";
};
FF12327738E91E5AA87207B8 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputFileListPaths = ( inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
); );
name = "[CP] Copy Pods Resources"; name = "[CP] Embed Pods Frameworks";
outputFileListPaths = ( outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
@@ -479,7 +478,7 @@
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1";
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;
}; };
name = Profile; name = Profile;
@@ -490,15 +489,19 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = J463CU8H5F;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.sparkit.beHappy; PRODUCT_BUNDLE_IDENTIFIER = com.behappybel.behappy;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
@@ -507,14 +510,14 @@
}; };
331C8088294A63A400263BE5 /* Debug */ = { 331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = BAF1C86965EF66AE2F0839BD /* Pods-RunnerTests.debug.xcconfig */; baseConfigurationReference = 7AFC7F9B8515A109C72DDF1B /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.sparkit.beHappy.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = com.behappybel.behappy.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -525,14 +528,14 @@
}; };
331C8089294A63A400263BE5 /* Release */ = { 331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = D24CB1920C4748F67C854B22 /* Pods-RunnerTests.release.xcconfig */; baseConfigurationReference = 12F1F4F8ABC8CE708CB9918F /* Pods-RunnerTests.release.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.sparkit.beHappy.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = com.behappybel.behappy.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
@@ -541,14 +544,14 @@
}; };
331C808A294A63A400263BE5 /* Profile */ = { 331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = BE9A8C77364E79EA4C6EE36B /* Pods-RunnerTests.profile.xcconfig */; baseConfigurationReference = 6EC6FEDB5882EB1ECF391D95 /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.sparkit.beHappy.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = com.behappybel.behappy.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
@@ -608,7 +611,7 @@
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1";
}; };
name = Debug; name = Debug;
}; };
@@ -661,7 +664,7 @@
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule; SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1";
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;
}; };
name = Release; name = Release;
@@ -672,15 +675,19 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = J463CU8H5F;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.sparkit.beHappy; PRODUCT_BUNDLE_IDENTIFIER = com.behappybel.behappy;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@@ -694,15 +701,19 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = J463CU8H5F;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.sparkit.beHappy; PRODUCT_BUNDLE_IDENTIFIER = com.behappybel.behappy;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";

Binary file not shown.

Before

Width:  |  Height:  |  Size: 351 KiB

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 986 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "background.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 B

View File

@@ -1,23 +1,23 @@
{ {
"images" : [ "images" : [
{ {
"idiom" : "universal",
"filename" : "LaunchImage.png", "filename" : "LaunchImage.png",
"idiom" : "universal",
"scale" : "1x" "scale" : "1x"
}, },
{ {
"idiom" : "universal",
"filename" : "LaunchImage@2x.png", "filename" : "LaunchImage@2x.png",
"idiom" : "universal",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "universal",
"filename" : "LaunchImage@3x.png", "filename" : "LaunchImage@3x.png",
"idiom" : "universal",
"scale" : "3x" "scale" : "3x"
} }
], ],
"info" : { "info" : {
"version" : 1, "author" : "xcode",
"author" : "xcode" "version" : 1
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -16,13 +16,19 @@
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" image="LaunchBackground" translatesAutoresizingMaskIntoConstraints="NO" id="tWc-Dq-wcI"/>
</imageView> <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4"></imageView>
</subviews> </subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints> <constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/> <constraint firstItem="YRO-k0-Ey4" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="3T2-ad-Qdv"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/> <constraint firstItem="tWc-Dq-wcI" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="RPx-PI-7Xg"/>
<constraint firstItem="tWc-Dq-wcI" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="SdS-ul-q2q"/>
<constraint firstAttribute="trailing" secondItem="tWc-Dq-wcI" secondAttribute="trailing" id="Swv-Gf-Rwn"/>
<constraint firstAttribute="trailing" secondItem="YRO-k0-Ey4" secondAttribute="trailing" id="TQA-XW-tRk"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="duK-uY-Gun"/>
<constraint firstItem="tWc-Dq-wcI" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="kV7-tw-vXt"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="xPn-NY-SIU"/>
</constraints> </constraints>
</view> </view>
</viewController> </viewController>
@@ -32,6 +38,7 @@
</scene> </scene>
</scenes> </scenes>
<resources> <resources>
<image name="LaunchImage" width="168" height="185"/> <image name="LaunchImage" width="130" height="130"/>
<image name="LaunchBackground" width="1" height="1"/>
</resources> </resources>
</document> </document>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CADisableMinimumFrameDurationOnPhone</key> <key>CADisableMinimumFrameDurationOnPhone</key>
<true/> <true/>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
@@ -68,5 +68,28 @@
</array> </array>
<key>YandexMapKitApiKey</key> <key>YandexMapKitApiKey</key>
<string>$(YANDEX_MAPKIT_API_KEY)</string> <string>$(YANDEX_MAPKIT_API_KEY)</string>
</dict> <key>NSLocationWhenInUseUsageDescription</key>
<string>Данные о местоположении необходимы для поиска ближайших самокатов и отображения их на карте.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Данные о местоположении необходимы для отслеживания поездки на самокате в фоновом режиме.</string>
<key>NSCameraUsageDescription</key>
<string>Приложению нужен доступ к камере для сканирования QR-кодов самокатов</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Приложению нужен доступ к галерее для выбора фото профиля и подтверждения поездки</string>
<key>UIStatusBarHidden</key>
<false/>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>com.behappy.app</string>
<key>CFBundleURLSchemes</key>
<array>
<string>com.behappy.app</string>
</array>
</dict>
</array>
</dict>
</plist> </plist>

View File

@@ -1,5 +1,4 @@
import 'dart:convert'; import 'dart:convert';
import '../../domain/entities/client_notification.dart'; import '../../domain/entities/client_notification.dart';
class ClientNotificationDto { class ClientNotificationDto {
@@ -43,12 +42,19 @@ class ClientNotificationDto {
clientId: clientId, clientId: clientId,
type: _parseType(type), type: _parseType(type),
category: _parseCategory(category), category: _parseCategory(category),
createdAt: DateTime.parse(createdAt), createdAt: _parseUtcDate(createdAt),
canceledAt: canceledAt != null ? DateTime.parse(canceledAt!) : null, canceledAt: canceledAt != null ? _parseUtcDate(canceledAt!) : null,
readAt: readAt != null ? DateTime.parse(readAt!) : null, readAt: readAt != null ? _parseUtcDate(readAt!) : null,
); );
} }
DateTime _parseUtcDate(String dateString) {
if (dateString.endsWith('Z') || dateString.contains('+') || dateString.contains('-')) {
return DateTime.parse(dateString).toLocal();
}
return DateTime.parse('${dateString}Z').toLocal();
}
NotificationType _parseType(String type) { NotificationType _parseType(String type) {
switch (type.toLowerCase()) { switch (type.toLowerCase()) {
case 'info': case 'info':

View File

@@ -2,7 +2,7 @@ import '../../domain/entities/payment_card.dart';
class PaymentCardResponseDto { class PaymentCardResponseDto {
final int id; final int id;
final int clientId; final String bindingId;
final int expirationMonth; final int expirationMonth;
final int expirationYear; final int expirationYear;
final String cardHolder; final String cardHolder;
@@ -12,7 +12,7 @@ class PaymentCardResponseDto {
PaymentCardResponseDto({ PaymentCardResponseDto({
required this.id, required this.id,
required this.clientId, required this.bindingId,
required this.expirationMonth, required this.expirationMonth,
required this.expirationYear, required this.expirationYear,
required this.cardHolder, required this.cardHolder,
@@ -24,7 +24,7 @@ class PaymentCardResponseDto {
factory PaymentCardResponseDto.fromJson(Map<String, dynamic> json) { factory PaymentCardResponseDto.fromJson(Map<String, dynamic> json) {
return PaymentCardResponseDto( return PaymentCardResponseDto(
id: json['id'] as int, id: json['id'] as int,
clientId: json['clientId'] as int, bindingId: json['bindingId'] as String,
expirationMonth: json['expirationMonth'] as int, expirationMonth: json['expirationMonth'] as int,
expirationYear: json['expirationYear'] as int, expirationYear: json['expirationYear'] as int,
cardHolder: json['cardHolder'] as String, cardHolder: json['cardHolder'] as String,
@@ -37,13 +37,9 @@ class PaymentCardResponseDto {
PaymentCard toEntity(String? fullCardNumber) { PaymentCard toEntity(String? fullCardNumber) {
return PaymentCard( return PaymentCard(
id: id, id: id,
clientId: clientId, bindingId: bindingId,
expirationMonth: expirationMonth,
expirationYear: expirationYear,
cardHolder: cardHolder,
cardLastNumber: cardLastNumber, cardLastNumber: cardLastNumber,
isMain: isMain, isMain: isMain,
type: type,
); );
} }
} }

View File

@@ -21,6 +21,7 @@ import 'package:flutter_client_sse/constants/sse_request_type_enum.dart';
import 'package:flutter_client_sse/flutter_client_sse.dart'; import 'package:flutter_client_sse/flutter_client_sse.dart';
import '../../domain/entities/client_subscription.dart'; import '../../domain/entities/client_subscription.dart';
import '../../domain/entities/fine.dart';
import '../../domain/entities/point.dart'; import '../../domain/entities/point.dart';
import '../../domain/entities/user_profile.dart'; import '../../domain/entities/user_profile.dart';
import '../../domain/entities/payment_card.dart'; import '../../domain/entities/payment_card.dart';
@@ -35,8 +36,11 @@ import '../models/subscriptions_response.dart';
import '../models/user_check_response_dto.dart'; import '../models/user_check_response_dto.dart';
class ApiService { class ApiService {
static const String baseUrl = "https://sharing-api.sparkit.by/api/v1"; static const String baseUrl = "https://api.behappybel.by/api/v1";
static const String fileBaseUrl = "https://sharing-api.sparkit.by"; static const String fileBaseUrl = "https://api.behappybel.by/";
/*static const String baseUrl = "https://sharing-api.sparkit.by/api/v1";
static const String fileBaseUrl = "https://sharing-api.sparkit.by";*/
final SecurityService _securityService; final SecurityService _securityService;
final Dio _dio; final Dio _dio;
@@ -52,7 +56,11 @@ class ApiService {
try { try {
final response = await _dio.post( final response = await _dio.post(
"$baseUrl/auth/client/login", "$baseUrl/auth/client/login",
data: {"phone": phone, "model": model, "systemId": systemId}, data: {
"phone": phone,
"model": model,
"systemId": systemId
},
); );
if (response.statusCode == 200 || response.statusCode == 201) { if (response.statusCode == 200 || response.statusCode == 201) {
@@ -143,11 +151,12 @@ class ApiService {
} }
dynamic balanceRaw = profileData["balance"]; dynamic balanceRaw = profileData["balance"];
int? balance; double? balance;
if (balanceRaw is int) {
balance = balanceRaw; if (balanceRaw is num) {
balance = balanceRaw.toDouble();
} else if (balanceRaw is String) { } else if (balanceRaw is String) {
balance = int.tryParse(balanceRaw); balance = double.tryParse(balanceRaw);
} }
return UserProfile( return UserProfile(
@@ -166,6 +175,53 @@ class ApiService {
} }
} }
Future<void> deleteProfile() async {
try {
final response = await _dio.delete(
"$baseUrl/client/me",
options: await _getAuthOptions(),
);
if (response.statusCode == 200) {
final data = response.data;
final profileData = data["profile"];
if (profileData == null) return null;
String? parsedDate;
if (profileData["dob"] != null) {
try {
parsedDate = DateFormat(
'dd.MM.yyyy',
).format(DateTime.parse(profileData["dob"]));
} catch (_) {}
}
final int? avatarId = profileData["avatarId"];
String? avatarUrl;
if (avatarId != null && profileData["avatar"] != null) {
final String? avatarPath = profileData["avatar"]["path"];
if (avatarPath != null && avatarPath.isNotEmpty) {
avatarUrl = Uri.parse(fileBaseUrl).resolve(avatarPath).toString();
}
}
dynamic balanceRaw = profileData["balance"];
double? balance;
if (balanceRaw is num) {
balance = balanceRaw.toDouble();
} else if (balanceRaw is String) {
balance = double.tryParse(balanceRaw);
}
}
return null;
} catch (e) {
return null;
}
}
Future<List<PaymentCard>> getPaymentCards() async { Future<List<PaymentCard>> getPaymentCards() async {
final response = await _dio.get( final response = await _dio.get(
"$baseUrl/client/me", "$baseUrl/client/me",
@@ -177,13 +233,9 @@ class ApiService {
cardsJson.map((cardJson) async { cardsJson.map((cardJson) async {
return PaymentCard( return PaymentCard(
id: cardJson['id'], id: cardJson['id'],
clientId: cardJson['clientId'], bindingId: cardJson['bindingId'],
expirationMonth: cardJson['expirationMonth'],
expirationYear: cardJson['expirationYear'],
cardHolder: cardJson['cardHolder'],
cardLastNumber: cardJson['cardLastNumber'], cardLastNumber: cardJson['cardLastNumber'],
isMain: cardJson['isMain'], isMain: cardJson['isMain'],
type: cardJson['cardType'],
); );
}), }),
); );
@@ -238,11 +290,11 @@ class ApiService {
} }
dynamic balanceRaw = data["balance"]; dynamic balanceRaw = data["balance"];
int? balance; double? balance;
if (balanceRaw is int) { if (balanceRaw is double) {
balance = balanceRaw; balance = balanceRaw;
} else if (balanceRaw is String) { } else if (balanceRaw is String) {
balance = int.tryParse(balanceRaw); balance = double.tryParse(balanceRaw);
} }
return UserProfile( return UserProfile(
@@ -420,7 +472,7 @@ class ApiService {
int page = 1, int page = 1,
int pageSize = 500, int pageSize = 500,
}) async { }) async {
const path = "$baseUrl/zone/available"; const path = "$baseUrl/zone/available2";
final queryParams = { final queryParams = {
'readAll': 'true', 'readAll': 'true',
@@ -446,6 +498,35 @@ class ApiService {
} }
} }
Future<ZonesResponse?> getAllZones({
int page = 1,
int pageSize = 500,
}) async {
const path = "$baseUrl/zone/available2";
final queryParams = {
'readAll': 'true',
'page': page,
'pageSize': pageSize,
};
try {
final response = await _dio.get(
path,
queryParameters: queryParams,
options: await _getAuthOptions(),
);
if (response.statusCode == 200) {
return ZonesResponse.fromJson(response.data);
}
return null;
} catch (e) {
print("ERROR: getZones failed: $e");
return null;
}
}
Future<TariffsResponse?> getAvailableTariffs({required int scooterId}) async { Future<TariffsResponse?> getAvailableTariffs({required int scooterId}) async {
final url = "$baseUrl/scooterplan/$scooterId/available"; final url = "$baseUrl/scooterplan/$scooterId/available";
@@ -517,13 +598,13 @@ class ApiService {
} }
} }
Future<bool> activateSubscription({required int optionId}) async { Future<bool> activateSubscription({required int optionId, required int cardId}) async {
const url = "$baseUrl/scootersubscription/client"; const url = "$baseUrl/scootersubscription/client";
try { try {
final response = await _dio.post( final response = await _dio.post(
url, url,
data: {"optionId": optionId}, data: {"optionId": optionId, "cardId": cardId},
options: await _getAuthOptions(), options: await _getAuthOptions(),
); );
@@ -539,31 +620,25 @@ class ApiService {
} }
} }
Future<void> addPaymentCard({ Future<Map<String, dynamic>> addPaymentCard() async {
required String cardNumber,
required String cardHolder,
required int expirationMonth,
required int expirationYear,
required String cvv,
}) async {
const url = "$baseUrl/client/card"; const url = "$baseUrl/client/card";
final cleanCardNumber = cardNumber.replaceAll(' ', ''); /*final cleanCardNumber = cardNumber.replaceAll(' ', '');*/
try { try {
final response = await _dio.post( final response = await _dio.post(
url, url,
data: { /*data: {
"cardNumber": cleanCardNumber, "cardNumber": cleanCardNumber,
"cardHolder": cardHolder, "cardHolder": cardHolder,
"expirationMonth": expirationMonth, "expirationMonth": expirationMonth,
"expirationYear": expirationYear, "expirationYear": expirationYear,
"cvv": cvv, "cvv": cvv,
}, },*/
options: await _getAuthOptions(), options: await _getAuthOptions(),
); );
if (response.statusCode == 200 || response.statusCode == 201) { if (response.statusCode == 200 || response.statusCode == 201) {
return; return response.data;
} }
throw AuthException('Непредвиденный статус: ${response.statusCode}', 0); throw AuthException('Непредвиденный статус: ${response.statusCode}', 0);
@@ -714,17 +789,13 @@ class ApiService {
} }
} }
Future<ScooterOrder?> cancelRide(int orderId) async { Future<void> cancelRide(int orderId) async {
try { try {
final response = await _dio.put( final response = await _dio.put(
"$baseUrl/scooterorder/$orderId/cancel", "$baseUrl/scooterorder/$orderId/cancel",
options: await _getAuthOptions(), options: await _getAuthOptions(),
); );
if (response.statusCode == 200 || response.statusCode == 201) {
return ScooterOrder.fromJson(response.data);
}
return null;
} on DioException catch (e) { } on DioException catch (e) {
_handleDioError(e); _handleDioError(e);
return null; return null;
@@ -765,7 +836,7 @@ class ApiService {
} }
} }
Future<ScooterOrder?> finishRide({ Future<void> finishRide({
required int orderId, required int orderId,
required List<int> filesId, required List<int> filesId,
}) async { }) async {
@@ -776,10 +847,6 @@ class ApiService {
options: await _getAuthOptions(), options: await _getAuthOptions(),
); );
if (response.statusCode == 200 || response.statusCode == 201) {
return ScooterOrder.fromJson(response.data);
}
return null;
} on DioException catch (e) { } on DioException catch (e) {
if (e.response?.statusCode == 400) { if (e.response?.statusCode == 400) {
final data = e.response?.data; final data = e.response?.data;
@@ -947,6 +1014,64 @@ class ApiService {
} }
} }
/// GET /scooterorder/fines/client
Future<List<Fine>> getClientFines() async {
try {
final response = await _dio.get(
"$baseUrl/scooterorder/fines/client",
options: await _getAuthOptions(),
);
if (response.statusCode == 200 && response.data is Map) {
final List<dynamic> dataList = response.data['data'] ?? [];
return dataList.map((json) => Fine.fromJson(json)).toList();
}
return [];
} on DioException catch (e) {
_handleDioError(e);
return [];
}
}
/// GET /scooterorder/{id}/fine
Future<Fine?> getFineDetails(int orderId) async {
try {
final response = await _dio.get(
"$baseUrl/scooterorder/fines/client/$orderId",
options: await _getAuthOptions(),
);
if (response.statusCode == 200 && response.data != null) {
return Fine.fromJson(response.data);
}
return null;
} on DioException catch (e) {
_handleDioError(e);
return null;
}
}
/// PUT /scooterorder/fines/client/{id}
/// {id} — это id штрафа (Fine.id), а не id заказа (Fine.orderId)
Future<void> payFine({
required int orderId,
int? cardId,
required bool isBalance,
}) async {
try {
await _dio.put(
"$baseUrl/scooterorder/fines/client/$orderId",
data: {
"cardId": cardId ?? 0,
"isBalance": isBalance,
},
options: await _getAuthOptions(),
);
} on DioException catch (e) {
_handleDioError(e);
}
}
Future<Map<String, dynamic>> getNews() async { Future<Map<String, dynamic>> getNews() async {
try { try {
final response = await _dio.get( final response = await _dio.get(
@@ -1019,10 +1144,10 @@ class ApiService {
if (event.data != null && event.data!.isNotEmpty) { if (event.data != null && event.data!.isNotEmpty) {
try { try {
final Map<String, dynamic> jsonData = jsonDecode(event.data!); final Map<String, dynamic> jsonData = jsonDecode(event.data!);
print("✅ [SSE] Parsed JSON: $jsonData"); print("[SSE] Parsed JSON: $jsonData");
controller.add(jsonData); controller.add(jsonData);
} catch (e) { } catch (e) {
print("❌ [SSE] JSON Parse Error: $e | Raw: ${event.data}"); print("[SSE] JSON Parse Error: $e | Raw: ${event.data}");
} }
} }
}, },
@@ -1040,17 +1165,19 @@ class ApiService {
return controller.stream; return controller.stream;
} }
Future<List<Map<String, dynamic>>> getNotifications() async { Future<Map<String, dynamic>> getNotifications({
final url = Uri.parse('$baseUrl/notification/client'); int page = 1,
int pageSize = 10,
}) async {
final url = Uri.parse('$baseUrl/notification/client').replace(
queryParameters: {
'page': page.toString(),
'pageSize': pageSize.toString(),
},
);
final accessToken = await _securityService.getAccessToken(); final accessToken = await _securityService.getAccessToken();
if (accessToken == null) { if (accessToken == null) throw UnauthorizedException();
print("APISERVICE Error: Access token is null.");
throw UnauthorizedException();
}
print("GET NOTIFICATIONS REQUEST:");
print("URL: $url");
final response = await http.get( final response = await http.get(
url, url,
@@ -1060,34 +1187,17 @@ class ApiService {
}, },
); );
print("GET NOTIFICATIONS RESPONSE:");
print("STATUS: ${response.statusCode}");
print("BODY: ${response.body}");
if (response.statusCode == 200) { if (response.statusCode == 200) {
final data = jsonDecode(utf8.decode(response.bodyBytes)); final data = jsonDecode(utf8.decode(response.bodyBytes));
if (data is Map<String, dynamic>) {
// ✅ Проверяем, является ли ответ массивом или объектом с data[] return data;
if (data is List) {
return data.cast<Map<String, dynamic>>();
} else if (data is Map<String, dynamic>) {
final list = data['data'];
if (list is List) {
return list.cast<Map<String, dynamic>>();
} else {
throw Exception(
'Expected a List under "data" but got ${list.runtimeType}',
);
}
} else {
throw Exception('Expected a List or Map but got ${data.runtimeType}');
} }
throw Exception('Expected Map with data and pagination');
} else if (response.statusCode == 401) { } else if (response.statusCode == 401) {
throw UnauthorizedException(); throw UnauthorizedException();
} else if (response.statusCode == 403) { } else if (response.statusCode == 403) {
throw AuthBlockException(); throw AuthBlockException();
} }
throw Exception('Ошибка сервера: ${response.statusCode}'); throw Exception('Ошибка сервера: ${response.statusCode}');
} }
@@ -1176,5 +1286,6 @@ class ApiService {
} }
} }
// ✅ Добавь исключение (можно в отдельный файл)
class PromoCodeNotFoundException implements Exception {} class PromoCodeNotFoundException implements Exception {}

View File

@@ -1,7 +1,9 @@
import 'package:be_happy/domain/entities/client_notification.dart'; import 'package:be_happy/domain/entities/client_notification.dart';
import '../../data/network/api_service.dart'; import '../../data/network/api_service.dart';
import '../../domain/entities/pagination_meta.dart';
import '../../domain/repositories/notification_repository.dart'; import '../../domain/repositories/notification_repository.dart';
import '../../domain/usecase/get_notifications_usecase.dart';
import '../models/client_notification_dto.dart'; import '../models/client_notification_dto.dart';
class NotificationRepositoryImpl implements NotificationRepository { class NotificationRepositoryImpl implements NotificationRepository {
@@ -35,19 +37,27 @@ class NotificationRepositoryImpl implements NotificationRepository {
} }
@override @override
Future<List<ClientNotification>> getNotifications() async { Future<NotificationsResult> getNotifications({
int page = 1,
int pageSize = 10,
}) async {
try { try {
final List<Map<String, dynamic>> data = await _apiService.getNotifications(); final response = await _apiService.getNotifications(
final notifications = data.map((json) { page: page,
final dto = ClientNotificationDto.fromJson(json); pageSize: pageSize,
return dto.toEntity(); );
}).toList();
// dev.log('NotificationRepository: Загружено ${notifications.length} уведомлений'); final notifications = (response['data'] as List)
.map((json) => ClientNotificationDto.fromJson(json).toEntity())
.toList();
return notifications; final pagination = PaginationMeta.fromJson(response['pagination']);
return NotificationsResult(
notifications: notifications,
pagination: pagination,
);
} catch (e, stackTrace) { } catch (e, stackTrace) {
// dev.log('NotificationRepository: Ошибка: $e', stackTrace: stackTrace);
throw Exception('Не удалось загрузить уведомления: $e'); throw Exception('Не удалось загрузить уведомления: $e');
} }
} }

View File

@@ -32,25 +32,25 @@ class PaymentRepositoryImpl implements PaymentRepository {
} }
@override @override
Future<Result<void>> addPaymentCard({ Future<Result<Map<String, dynamic>>> addPaymentCard(
required String cardNumber, /*required String cardNumber,
required String cardHolder, required String cardHolder,
required String expiryMonth, required String expiryMonth,
required String expiryYear, required String expiryYear,
required String cvv, required String cvv,*/
}) async { ) async {
try { try {
await apiService.addPaymentCard( final result = await apiService.addPaymentCard(
cardNumber: cardNumber, /*cardNumber: cardNumber,
cardHolder: cardHolder, cardHolder: cardHolder,
expirationMonth: int.parse(expiryMonth), expirationMonth: int.parse(expiryMonth),
expirationYear: int.parse(expiryYear), expirationYear: int.parse(expiryYear),
cvv: cvv, cvv: cvv,*/
); );
// await securityService.saveCardFullNumber(cardId, cardNumber); // await securityService.saveCardFullNumber(cardId, cardNumber);
return Success(null); return Success(result);
} on AuthException catch (e) { } on AuthException catch (e) {
return Failure(AuthFailure(e.attemptsLeft)); return Failure(AuthFailure(e.attemptsLeft));
} on AuthBlockException catch (_) { } on AuthBlockException catch (_) {
@@ -98,9 +98,9 @@ class PaymentRepositoryImpl implements PaymentRepository {
} }
@override @override
Future<Result<bool>> activateSubscription(int optionId) async { Future<Result<bool>> activateSubscription(int optionId, int cardId) async {
try { try {
final success = await apiService.activateSubscription(optionId: optionId); final success = await apiService.activateSubscription(optionId: optionId, cardId: cardId);
return Success(success); return Success(success);
} on AuthException catch (e) { } on AuthException catch (e) {
return Failure(AuthFailure(e.attemptsLeft)); return Failure(AuthFailure(e.attemptsLeft));

View File

@@ -27,6 +27,11 @@ class UserProfileRepositoryImpl implements UserProfileRepository {
return await _apiService.getProfile() ?? _cachedProfile; return await _apiService.getProfile() ?? _cachedProfile;
} }
@override
Future<void> deleteProfile() async {
return await _apiService.deleteProfile();
}
@override @override
Future<UserProfile?> updateProfile(UserProfile profile) async { Future<UserProfile?> updateProfile(UserProfile profile) async {
//await Future.delayed(const Duration(milliseconds: 300)); //await Future.delayed(const Duration(milliseconds: 300));

View File

@@ -1,21 +1,22 @@
import 'dart:io'; import 'dart:io';
import 'package:be_happy/data/exceptions/auth_block_exception.dart';
import 'package:be_happy/data/exceptions/route_history_not_found_exception.dart';
import 'package:be_happy/data/exceptions/scooter_not_found_exception.dart';
import 'package:be_happy/data/exceptions/unauthorized_exception.dart';
import 'package:be_happy/data/exceptions/wrong_zone_exception.dart';
import 'package:be_happy/domain/entities/point.dart';
import 'package:be_happy/domain/repositories/scooter_repository.dart';
import '../../core/failures.dart'; import '../../core/failures.dart';
import '../../core/result.dart'; import '../../core/result.dart';
import '../../domain/entities/active_scooter_order.dart'; import '../../domain/entities/active_scooter_order.dart';
import '../../domain/entities/client_subscription.dart'; import '../../domain/entities/client_subscription.dart';
import '../../domain/entities/fine.dart';
import '../../domain/entities/point.dart';
import '../../domain/entities/scooter.dart'; import '../../domain/entities/scooter.dart';
import '../../domain/entities/tariff.dart'; import '../../domain/entities/tariff.dart';
import '../../domain/entities/subscription.dart'; import '../../domain/entities/subscription.dart';
import '../../domain/entities/scooter_order.dart'; import '../../domain/entities/scooter_order.dart';
import '../../domain/repositories/scooter_repository.dart';
import '../exceptions/auth_block_exception.dart';
import '../exceptions/auth_exception.dart'; import '../exceptions/auth_exception.dart';
import '../exceptions/route_history_not_found_exception.dart';
import '../exceptions/scooter_not_found_exception.dart';
import '../exceptions/unauthorized_exception.dart';
import '../exceptions/wrong_zone_exception.dart';
import '../network/api_service.dart'; import '../network/api_service.dart';
class ScooterRepositoryImpl extends ScooterRepository { class ScooterRepositoryImpl extends ScooterRepository {
@@ -192,15 +193,11 @@ class ScooterRepositoryImpl extends ScooterRepository {
} }
@override @override
Future<Result<ScooterOrder>> cancelRide(int orderId) async { Future<Result<void>> cancelRide(int orderId) async {
late final Result<ScooterOrder> result; late final Result<void> result;
try { try {
final order = await _apiService.cancelRide(orderId); await _apiService.cancelRide(orderId);
if (order != null) { result = Success(null);
result = Success(order);
} else {
result = Failure(UnknownFailure("Неизвестная ошибка"));
}
} on AuthException catch (e) { } on AuthException catch (e) {
result = Failure(AuthFailure(e.attemptsLeft)); result = Failure(AuthFailure(e.attemptsLeft));
} catch (e) { } catch (e) {
@@ -246,18 +243,11 @@ class ScooterRepositoryImpl extends ScooterRepository {
} }
@override @override
Future<Result<ScooterOrder>> finishRide(int orderId, List<int> files) async { Future<Result<void>> finishRide(int orderId, List<int> files) async {
late final Result<ScooterOrder> result; late final Result<ScooterOrder> result;
try { try {
final order = await _apiService.finishRide( await _apiService.finishRide(orderId: orderId, filesId: files);
orderId: orderId, result = Success(null);
filesId: files,
);
if (order != null) {
result = Success(order);
} else {
result = Failure(UnknownFailure("Неизвестная ошибка"));
}
} on AuthException catch (e) { } on AuthException catch (e) {
result = Failure(AuthFailure(e.attemptsLeft)); result = Failure(AuthFailure(e.attemptsLeft));
} on WrongZoneException catch (e) { } on WrongZoneException catch (e) {
@@ -274,7 +264,6 @@ class ScooterRepositoryImpl extends ScooterRepository {
try { try {
await _apiService.payRide(orderId); await _apiService.payRide(orderId);
result = Success(null); result = Success(null);
} on AuthException catch (e) { } on AuthException catch (e) {
result = Failure(AuthFailure(e.attemptsLeft)); result = Failure(AuthFailure(e.attemptsLeft));
} catch (e) { } catch (e) {
@@ -437,4 +426,70 @@ class ScooterRepositoryImpl extends ScooterRepository {
} }
return result; return result;
} }
@override
Future<Result<Fine>> getFineDetails(int orderId) async {
late final Result<Fine> result;
try {
final fine = await _apiService.getFineDetails(orderId);
if (fine != null) {
result = Success(fine);
} else {
result = Failure(UnknownFailure("Не удалось получить данные о штрафе"));
}
} on AuthException catch (e) {
result = Failure(AuthFailure(e.attemptsLeft));
} on UnauthorizedException catch (e) {
result = Failure(AuthFailure(0, message: e.toString()));
} on AuthBlockException catch (e) {
result = Failure(AuthBlockFailure(e.toString()));
} catch (e) {
result = Failure(UnknownFailure("Неизвестная ошибка"));
}
return result;
}
@override
Future<Result<List<Fine>>> getClientFines() async {
late final Result<List<Fine>> result;
try {
final fines = await _apiService.getClientFines();
result = Success(fines);
} on AuthException catch (e) {
result = Failure(AuthFailure(e.attemptsLeft));
} on UnauthorizedException catch (e) {
result = Failure(AuthFailure(0, message: e.toString()));
} on AuthBlockException catch (e) {
result = Failure(AuthBlockFailure(e.toString()));
} catch (e) {
result = Failure(UnknownFailure("Неизвестная ошибка"));
}
return result;
}
@override
Future<Result<void>> payFine({
required int orderId,
int? cardId,
required bool isBalance,
}) async {
late final Result<void> result;
try {
await _apiService.payFine(
orderId: orderId,
cardId: cardId,
isBalance: isBalance,
);
result = Success(null);
} on AuthException catch (e) {
result = Failure(AuthFailure(e.attemptsLeft));
} on UnauthorizedException catch (e) {
result = Failure(AuthFailure(0, message: e.toString()));
} on AuthBlockException catch (e) {
result = Failure(AuthBlockFailure(e.toString()));
} catch (e) {
result = Failure(UnknownFailure("Неизвестная ошибка"));
}
return result;
}
} }

View File

@@ -10,60 +10,60 @@ class ZoneRepositoryImpl extends ZoneRepository {
ZoneRepositoryImpl(this._apiService); ZoneRepositoryImpl(this._apiService);
@override @override
Future<List<Zone>> getZones(List<double> area, Future<List<Zone>> getZones(List<double> area, int page, int pageSize) async {
int page,
int pageSize,) async {
final List<Point> list = []; final List<Point> list = [];
final List<Point> list2 = []; final List<Point> list2 = [];
/*list.add(Point(55.182372,30.203347));
list.add(Point(55.173746,30.200257));
list.add(Point(55.172153,30.212531));
list.add(Point(55.179946,30.215964));
list2.add(Point(55.178304,30.227380));
list2.add(Point(55.178059,30.229654));
list2.add(Point(55.191339,30.234718));
list2.add(Point(55.194352,30.234890));
list2.add(Point(55.194377,30.231972));
list2.add(Point(55.192123,30.232744));
final zone = Zone(id: 123,
title: "Zone 01",
description: "description",
type: "Finish",
isActive: true,
shapeType: "polygon",
points: list,
speedLimit: "speedLimit");
final zone2 = Zone(id: 124,
title: "Zone 02",
description: "description",
type: "NotDrive",
isActive: true,
shapeType: "polygon",
points: list2,
speedLimit: "speedLimit");
*/
final responce = await _apiService.getZones( final responce = await _apiService.getZones(
area: area, area: area,
page: page, page: page,
pageSize: pageSize, pageSize: pageSize,
); );
final List<Zone>? zones = responce?.zones; if (responce == null) {
// zones?.add(zone); throw Exception(
// zones?.add(zone2); 'Failed to load zones for area: empty response from server',
);
print("Scooters: ${zones?.first.title}");
if (responce != null) {
return zones ?? List.empty();
} }
return List.empty(); final zones = responce.zones;
print("Zones: ${zones.length}");
return zones;
}
@override
Future<List<Zone>> getAllZones(int page, int pageSize) async {
final List<Point> list = [];
final List<Point> list2 = [];
final responce = await _apiService.getAllZones(
page: page,
pageSize: pageSize,
);
// apiService.getAllZones ловит свои ошибки (сеть/401/5xx) и в этом
// случае возвращает null. Раньше это тихо превращалось в "зон нет" —
// из-за чего сбой запроса выглядел как легитимный пустой ответ и
// (в связке с кешем на уровне MapBloc) навсегда "прятал" зоны на
// время сессии. Бросаем исключение, чтобы вызывающий код (usecase/bloc)
// мог отличить реальный сбой от честного "зон действительно нет"
// и, при необходимости, повторить запрос.
if (responce == null) {
throw Exception('Failed to load zones: empty response from server');
}
final zones = responce.zones;
print(zones.map((z) => '${z.type}:${z.id}'));
for (final z in zones) {
print("Zone ${z.type}:${z.id} geometry.length=${z.geometry.length}");
}
print("Zones: ${zones.length}");
return zones;
} }
} }

View File

@@ -10,6 +10,6 @@ class AppSettingsService {
} }
bool getMapSettingsFlag(String key) { bool getMapSettingsFlag(String key) {
return sharedPreferences.getBool(key) ?? false; return sharedPreferences.getBool(key) ?? true;
} }
} }

View File

@@ -17,6 +17,8 @@ import 'package:be_happy/domain/repositories/scooter_repository.dart';
import 'package:be_happy/domain/repositories/zone_repository.dart'; import 'package:be_happy/domain/repositories/zone_repository.dart';
import 'package:be_happy/domain/service/security_service.dart'; import 'package:be_happy/domain/service/security_service.dart';
import 'package:be_happy/domain/usecase/add_payment_card_usecase.dart'; // ← новый import 'package:be_happy/domain/usecase/add_payment_card_usecase.dart'; // ← новый
import 'package:be_happy/domain/usecase/delete_profile_usecase.dart';
import 'package:be_happy/domain/usecase/get_all_zones_usecase.dart';
import 'package:be_happy/domain/usecase/get_certificates_usecase.dart'; import 'package:be_happy/domain/usecase/get_certificates_usecase.dart';
import 'package:be_happy/domain/usecase/get_scooter_order_route_history_usecase.dart'; import 'package:be_happy/domain/usecase/get_scooter_order_route_history_usecase.dart';
import 'package:be_happy/domain/usecase/is_pin_set_usecase.dart'; import 'package:be_happy/domain/usecase/is_pin_set_usecase.dart';
@@ -54,6 +56,7 @@ import 'package:be_happy/domain/usecase/finish_ride_usecase.dart';
import 'package:be_happy/domain/usecase/pause_ride_usecase.dart'; import 'package:be_happy/domain/usecase/pause_ride_usecase.dart';
import 'package:be_happy/domain/usecase/resume_ride_usecase.dart'; import 'package:be_happy/domain/usecase/resume_ride_usecase.dart';
import 'package:be_happy/domain/usecase/verify_pin_usecase.dart'; import 'package:be_happy/domain/usecase/verify_pin_usecase.dart';
import 'package:be_happy/presentation/event/profile_event.dart';
import 'package:be_happy/presentation/viewmodel/active_ride_bloc.dart'; import 'package:be_happy/presentation/viewmodel/active_ride_bloc.dart';
import 'package:be_happy/presentation/viewmodel/add_card_bloc.dart'; // ← новый import 'package:be_happy/presentation/viewmodel/add_card_bloc.dart'; // ← новый
import 'package:be_happy/presentation/viewmodel/current_rides_bloc.dart'; import 'package:be_happy/presentation/viewmodel/current_rides_bloc.dart';
@@ -94,14 +97,18 @@ import '../domain/service/device_info_service.dart';
import '../domain/usecase/activate_subscription_usecase.dart'; import '../domain/usecase/activate_subscription_usecase.dart';
import '../domain/usecase/apply_promo_code_usecase.dart'; import '../domain/usecase/apply_promo_code_usecase.dart';
import '../domain/usecase/get_client_subscriptions_usecase.dart'; import '../domain/usecase/get_client_subscriptions_usecase.dart';
import '../domain/usecase/get_fine_details_usecase.dart';
import '../domain/usecase/get_fines_usecase.dart';
import '../domain/usecase/get_news_by_id_usecase.dart'; import '../domain/usecase/get_news_by_id_usecase.dart';
import '../domain/usecase/get_notifications_usecase.dart'; import '../domain/usecase/get_notifications_usecase.dart';
import '../domain/usecase/get_scooter_by_title_usecase.dart'; import '../domain/usecase/get_scooter_by_title_usecase.dart';
import '../domain/usecase/get_scooter_order_history_usecase.dart'; import '../domain/usecase/get_scooter_order_history_usecase.dart';
import '../domain/usecase/pay_fine_usecase.dart';
import '../domain/usecase/remove_payment_card_usecase.dart'; import '../domain/usecase/remove_payment_card_usecase.dart';
import '../domain/usecase/set_main_payment_card_usecase.dart'; import '../domain/usecase/set_main_payment_card_usecase.dart';
import '../presentation/viewmodel/auth_bloc.dart'; import '../presentation/viewmodel/auth_bloc.dart';
import '../presentation/viewmodel/edit_profile_bloc.dart'; import '../presentation/viewmodel/edit_profile_bloc.dart';
import '../presentation/viewmodel/fine_list_bloc.dart';
import '../presentation/viewmodel/map_bloc.dart'; import '../presentation/viewmodel/map_bloc.dart';
import '../presentation/viewmodel/news_bloc.dart'; import '../presentation/viewmodel/news_bloc.dart';
import '../presentation/viewmodel/notifications_bloc.dart'; import '../presentation/viewmodel/notifications_bloc.dart';
@@ -116,7 +123,13 @@ final getIt = GetIt.instance;
Future<void> setupDependencies() async { Future<void> setupDependencies() async {
final sharedPreferences = await SharedPreferences.getInstance(); final sharedPreferences = await SharedPreferences.getInstance();
final dio = Dio(); final dio = Dio();
dio.interceptors.add(LogInterceptor(/*requestHeader: false, responseHeader:false, */responseBody: true, requestBody: true)); dio.interceptors.add(
LogInterceptor(
/*requestHeader: false, responseHeader:false, */
responseBody: true,
requestBody: true,
),
);
dio.interceptors.add(AuthInterceptor()); dio.interceptors.add(AuthInterceptor());
// HTTP // HTTP
getIt.registerSingleton<http.Client>(http.Client()); getIt.registerSingleton<http.Client>(http.Client());
@@ -195,6 +208,8 @@ Future<void> setupDependencies() async {
getIt.registerSingleton<GetProfileUseCase>(GetProfileUseCase(getIt())); getIt.registerSingleton<GetProfileUseCase>(GetProfileUseCase(getIt()));
getIt.registerSingleton<DeleteProfileUsecase>(DeleteProfileUsecase(getIt(), getIt(), getIt()));
getIt.registerSingleton<UpdateProfileUseCase>(UpdateProfileUseCase(getIt())); getIt.registerSingleton<UpdateProfileUseCase>(UpdateProfileUseCase(getIt()));
getIt.registerSingleton<UploadProfilePhotoUsecase>( getIt.registerSingleton<UploadProfilePhotoUsecase>(
@@ -225,6 +240,9 @@ Future<void> setupDependencies() async {
getIt.registerSingleton<GetAvailableZonesUsecase>( getIt.registerSingleton<GetAvailableZonesUsecase>(
GetAvailableZonesUsecase(getIt()), GetAvailableZonesUsecase(getIt()),
); );
getIt.registerSingleton<GetAllZonesUsecase>(
GetAllZonesUsecase(getIt()),
);
getIt.registerSingleton<GetMapSettingsUsecase>( getIt.registerSingleton<GetMapSettingsUsecase>(
GetMapSettingsUsecase(getIt()), GetMapSettingsUsecase(getIt()),
); );
@@ -299,15 +317,18 @@ Future<void> setupDependencies() async {
() => NotificationsBloc(getIt<GetNotificationsUsecase>()), () => NotificationsBloc(getIt<GetNotificationsUsecase>()),
); );
// Blocs // Blocs
getIt.registerLazySingleton<SplashBloc>(() => SplashBloc(getIt())); getIt.registerLazySingleton<SplashBloc>(() => SplashBloc(getIt()));
getIt.registerFactory<PhoneAuthBloc>(() => PhoneAuthBloc(getIt())); getIt.registerFactory<PhoneAuthBloc>(() => PhoneAuthBloc(getIt()));
getIt.registerFactory<VerifyCodeBloc>(() => VerifyCodeBloc(getIt())); getIt.registerFactory<VerifyCodeBloc>(
() => VerifyCodeBloc(getIt(), getIt(), getIt()),
);
getIt.registerFactory<ProfileBloc>(() => ProfileBloc(getIt(), getIt(), getIt())); getIt.registerLazySingleton<ProfileBloc>(
() => ProfileBloc(getIt(), getIt(), getIt(), getIt(), getIt(), getIt()),
);
getIt.registerFactory<EditProfileBloc>( getIt.registerFactory<EditProfileBloc>(
() => EditProfileBloc(getIt(), getIt()), () => EditProfileBloc(getIt(), getIt()),
@@ -335,9 +356,8 @@ Future<void> setupDependencies() async {
getIt.registerFactory<AddCardBloc>(() => AddCardBloc(getIt())); getIt.registerFactory<AddCardBloc>(() => AddCardBloc(getIt()));
getIt.registerFactory<PaymentMethodSheetBloc>( getIt.registerFactory<PaymentMethodSheetBloc>(
() => PaymentMethodSheetBloc(getIt()), () => PaymentMethodSheetBloc(getIt(), getIt(), getIt(), getIt()),
); );
getIt.registerFactory<CurrentRidesBloc>(() => CurrentRidesBloc(getIt())); getIt.registerFactory<CurrentRidesBloc>(() => CurrentRidesBloc(getIt()));
@@ -352,7 +372,6 @@ Future<void> setupDependencies() async {
getIt.registerFactory<NewsBloc>(() => NewsBloc(getIt<NewsRepository>())); getIt.registerFactory<NewsBloc>(() => NewsBloc(getIt<NewsRepository>()));
getIt.registerFactory<SendPhotoBloc>(() => SendPhotoBloc(getIt(), getIt())); getIt.registerFactory<SendPhotoBloc>(() => SendPhotoBloc(getIt(), getIt()));
getIt.registerFactory<SubscriptionListBloc>( getIt.registerFactory<SubscriptionListBloc>(
@@ -384,22 +403,33 @@ Future<void> setupDependencies() async {
() => OrderHistoryBloc(getIt<GetScooterOrderHistoryUsecase>()), () => OrderHistoryBloc(getIt<GetScooterOrderHistoryUsecase>()),
); );
getIt.registerFactory<ScooterCodeBloc>( getIt.registerFactory<FineListBloc>(() => FineListBloc(getIt()));
() => ScooterCodeBloc(getScooterByTitleUsecase: getIt<GetScooterByTitleUsecase>()),
);
getIt.registerFactory<ScooterCodeBloc>(
() => ScooterCodeBloc(
getScooterByTitleUsecase: getIt<GetScooterByTitleUsecase>(),
getAddressUsecase: getIt<GetAddressByPointUsecase>(),
getPedestrianRoutesUsecase: getIt<GetPedestrianRoutesUsecase>()
),
);
// Repository // Repository
getIt.registerSingleton<PromoCodeRepository>( getIt.registerSingleton<PromoCodeRepository>(
PromoCodeRepositoryImpl(getIt<ApiService>()), PromoCodeRepositoryImpl(getIt<ApiService>()),
); );
// UseCase // UseCase
getIt.registerSingleton<ApplyPromoCodeUsecase>( getIt.registerSingleton<ApplyPromoCodeUsecase>(
ApplyPromoCodeUsecase(getIt<PromoCodeRepository>()), ApplyPromoCodeUsecase(getIt<PromoCodeRepository>()),
); );
// Bloc (factory, т.к. экран создаёт новый экземпляр) getIt.registerFactory<GetFinesUsecase>(() => GetFinesUsecase(getIt()));
getIt.registerFactory<GetFineDetailsUsecase>(() => GetFineDetailsUsecase(getIt()));
getIt.registerFactory<PayFineUsecase>(() => PayFineUsecase(getIt()));
// Bloc (factory, т.к. экран создаёт новый экземпляр)
getIt.registerFactory<PromoCodeBloc>( getIt.registerFactory<PromoCodeBloc>(
() => PromoCodeBloc(getIt<ApplyPromoCodeUsecase>()), () => PromoCodeBloc(getIt<ApplyPromoCodeUsecase>()),
); );

View File

@@ -32,7 +32,7 @@ class ClientNotification {
required this.createdAt, required this.createdAt,
this.canceledAt, this.canceledAt,
this.readAt, this.readAt,
}); }) ;
ClientNotification copyWith({ ClientNotification copyWith({
int? id, int? id,

View File

@@ -0,0 +1,62 @@
import 'package:equatable/equatable.dart';
class Fine extends Equatable {
final int id;
final int orderId; // ← добавлено
final String scooterNumber; // можно оставить для совместимости, но не использовать в UI
final DateTime createdAtDateTime; // ← новое поле
final String description;
final double amount;
final String amountPrint;
final List<String> photoUrls;
final bool isPaid;
const Fine({
required this.id,
required this.orderId,
required this.scooterNumber,
required this.createdAtDateTime,
required this.description,
required this.amount,
required this.amountPrint,
required this.photoUrls,
required this.isPaid,
});
factory Fine.fromJson(Map<String, dynamic> json, {String? scooterNumber}) {
final List<dynamic> filesJson = json['files'] ?? [];
final List<String> photos = filesJson
.map((file) => file['path'] as String? ?? file['filename'] as String? ?? '')
.where((path) => path.isNotEmpty)
.toList();
// Парсим createdAt как DateTime
final createdAtDateTime = DateTime.tryParse(json['createdAt'].toString()) ??
DateTime.now(); // fallback
return Fine(
id: json['id'] as int? ?? 0,
orderId: json['orderId'] as int? ?? 0,
scooterNumber: scooterNumber ?? '',
createdAtDateTime: createdAtDateTime,
description: json['description'] as String? ?? '',
amount: (json['value'] as num?)?.toDouble() ?? 0.0,
amountPrint: json['valuePrint'] as String? ?? '0,00 BYN',
photoUrls: photos,
isPaid: json['isPaid'] as bool? ?? false,
);
}
@override
List<Object?> get props => [
id,
orderId,
scooterNumber,
createdAtDateTime,
description,
amount,
amountPrint,
photoUrls,
isPaid,
];
}

View File

@@ -6,10 +6,10 @@ class MapSettings {
final bool restricted_driving_zones; final bool restricted_driving_zones;
MapSettings({ MapSettings({
required this.all_placemarks, this.all_placemarks = true,
required this.all_zones, this.all_zones = true,
required this.parking_zones, this.parking_zones = true,
required this.restricted_parking_zones, this.restricted_parking_zones = true,
required this.restricted_driving_zones, this.restricted_driving_zones = true,
}); });
} }

View File

@@ -0,0 +1,28 @@
class PaginationMeta {
final int total;
final int lastPage;
final int currentPage;
final int totalPerPage;
final int? prevPage;
final int? nextPage;
PaginationMeta({
required this.total,
required this.lastPage,
required this.currentPage,
required this.totalPerPage,
this.prevPage,
this.nextPage,
});
factory PaginationMeta.fromJson(Map<String, dynamic> json) {
return PaginationMeta(
total: json['total'] as int,
lastPage: json['lastPage'] as int,
currentPage: json['currentPage'] as int,
totalPerPage: json['totalPerPage'] as int,
prevPage: json['prevPage'] as int?,
nextPage: json['nextPage'] as int?,
);
}
}

View File

@@ -1,43 +1,27 @@
class PaymentCard { class PaymentCard {
final int id; final int id;
final int clientId; final String? bindingId;
final int expirationMonth;
final int expirationYear;
final String cardHolder;
final String cardLastNumber; final String cardLastNumber;
final bool isMain; final bool isMain;
final String type;
PaymentCard({ PaymentCard({
required this.id, required this.id,
required this.clientId, required this.bindingId,
required this.expirationMonth,
required this.expirationYear,
required this.cardHolder,
required this.cardLastNumber, required this.cardLastNumber,
required this.isMain, required this.isMain,
required this.type,
}); });
PaymentCard copyWith({ PaymentCard copyWith({
int? id, int? id,
int? clientId, String? bindingId,
int? expirationMonth,
int? expirationYear,
String? cardHolder,
String? cardLastNumber, String? cardLastNumber,
bool? isMain, bool? isMain,
String? type,
}) { }) {
return PaymentCard( return PaymentCard(
id: id ?? this.id, id: id ?? this.id,
clientId: clientId ?? this.clientId, bindingId: bindingId ?? this.bindingId,
expirationMonth: expirationMonth ?? this.expirationMonth,
expirationYear: expirationYear ?? this.expirationYear,
cardHolder: cardHolder ?? this.cardHolder,
cardLastNumber: cardLastNumber ?? this.cardLastNumber, cardLastNumber: cardLastNumber ?? this.cardLastNumber,
isMain: isMain ?? this.isMain, isMain: isMain ?? this.isMain,
type: type ?? this.type,
); );
} }
} }

View File

@@ -27,8 +27,12 @@ class ScooterOrder {
final DateTime? expiresAt; final DateTime? expiresAt;
final DateTime? cancelAt; final DateTime? cancelAt;
final String? cancelDescription; final String? cancelDescription;
final double mileage; //эту final double mileage;
final double avgSpeed; //эту и снизу еще 4 есть final double avgSpeed;
final String payTotalPricePrint;
final String unpayTotalPricePrint;
final String totalOrderPricePrint;
final bool hasFine;
ScooterOrder({ ScooterOrder({
required this.id, required this.id,
@@ -57,11 +61,17 @@ class ScooterOrder {
this.expiresAt, this.expiresAt,
this.cancelAt, this.cancelAt,
this.cancelDescription, this.cancelDescription,
required this.mileage, //эту required this.mileage,
required this.avgSpeed, //эту и снизу еще 2 есть required this.avgSpeed,
required this.payTotalPricePrint, // оплачено
required this.unpayTotalPricePrint, //неоплачено
required this.totalOrderPricePrint, //общая
required this.hasFine,
}); });
factory ScooterOrder.fromJson(Map<String, dynamic> json) { factory ScooterOrder.fromJson(Map<String, dynamic> json) {
final paymentInfo = json['paymentInfo'] as Map<String, dynamic>?;
return ScooterOrder( return ScooterOrder(
id: json['id'] ?? 0, id: json['id'] ?? 0,
scooterId: json['scooterId'] ?? 0, scooterId: json['scooterId'] ?? 0,
@@ -101,8 +111,12 @@ class ScooterOrder {
? DateTime.parse(json['cancelAt']) ? DateTime.parse(json['cancelAt'])
: null, : null,
cancelDescription: json['cancelDescription'], cancelDescription: json['cancelDescription'],
mileage: (json['mileage'] as num?)?.toDouble() ?? 0.0, //эту mileage: (json['mileage'] as num?)?.toDouble() ?? 0.0,
avgSpeed: (json['avgSpeed'] as num?)?.toDouble() ?? 0.0, //эту avgSpeed: (json['avgSpeed'] as num?)?.toDouble() ?? 0.0,
payTotalPricePrint: paymentInfo?['payTotalPricePrint'] ?? '',
unpayTotalPricePrint: paymentInfo?['unpayTotalPricePrint'] ?? '',
totalOrderPricePrint: paymentInfo?['totalOrderPricePrint'] ?? '',
hasFine: paymentInfo?['hasFine'] ?? false,
); );
} }

View File

@@ -10,6 +10,7 @@ class Tariff {
final double startPrice; // Старт цена final double startPrice; // Старт цена
final double cashback; // Процент кэшбэка final double cashback; // Процент кэшбэка
final double insurance; // Страховка final double insurance; // Страховка
final int subscriptionId;
Tariff({ Tariff({
required this.id, required this.id,
@@ -23,6 +24,7 @@ class Tariff {
required this.startPrice, required this.startPrice,
required this.cashback, required this.cashback,
required this.insurance, required this.insurance,
required this.subscriptionId,
}); });
factory Tariff.fromJson(Map<String, dynamic> json) { factory Tariff.fromJson(Map<String, dynamic> json) {
@@ -41,6 +43,7 @@ class Tariff {
startPrice: (planPrice['start'] as num?)?.toDouble() ?? 0.0, startPrice: (planPrice['start'] as num?)?.toDouble() ?? 0.0,
cashback: (planPrice['cashback'] as num?)?.toDouble() ?? 0.0, cashback: (planPrice['cashback'] as num?)?.toDouble() ?? 0.0,
insurance: (planPrice['insurance'] as num?)?.toDouble() ?? 0.0, insurance: (planPrice['insurance'] as num?)?.toDouble() ?? 0.0,
subscriptionId: json.containsKey('subscriptionId') ? json['subscriptionId'] : 0,
); );
} }

View File

@@ -3,7 +3,7 @@ class UserProfile {
String birthDate; String birthDate;
String phone; String phone;
String email; String email;
int? balance; double? balance;
int? avatarId; int? avatarId;
String? avatarUrl; String? avatarUrl;
@@ -21,7 +21,7 @@ class UserProfile {
String? name, String? name,
String? birthDate, String? birthDate,
String? email, String? email,
int? balance, double? balance,
int? avatarId, int? avatarId,
String? avatarUrl, String? avatarUrl,
}) { }) {

View File

@@ -1,3 +1,4 @@
import 'dart:convert'; import 'dart:convert';
import 'package:be_happy/domain/entities/point.dart'; import 'package:be_happy/domain/entities/point.dart';
@@ -9,7 +10,7 @@ class Zone {
final String type; final String type;
final bool isActive; final bool isActive;
final String shapeType; final String shapeType;
final List<Point> points; final List<List<List<Point>>> geometry;
final String speedLimit; final String speedLimit;
Zone({ Zone({
@@ -19,56 +20,89 @@ class Zone {
required this.type, required this.type,
required this.isActive, required this.isActive,
required this.shapeType, required this.shapeType,
required this.points, required this.geometry,
required this.speedLimit, required this.speedLimit,
}); });
List<Point> get points {
if (geometry.isNotEmpty && geometry[0].isNotEmpty) {
return geometry[0][0];
}
return [];
}
factory Zone.fromJson(Map<String, dynamic> json) { factory Zone.fromJson(Map<String, dynamic> json) {
final zoneCoordinates = json['coordinates'] as Map<String, dynamic>? ?? {}; final zoneCoordinates = json['coordinates'] as Map<String, dynamic>? ?? {};
final String coordsString = zoneCoordinates['coordinates'] ?? '[]'; final String coordsString = zoneCoordinates['coordinates'] ?? '[]';
final String shapeType = zoneCoordinates['type'] ?? 'Polygon'; final String shapeType = zoneCoordinates['type'] ?? 'Polygon';
List<Point> points = []; List<List<List<Point>>> parsedGeometry = [];
try { try {
final dynamic decoded = jsonDecode(coordsString); final dynamic decoded = jsonDecode(coordsString);
if (decoded is List && decoded.isNotEmpty) { if (decoded is List && decoded.isNotEmpty) {
List<dynamic> targetList = [];
if (shapeType == 'Polygon') { if (shapeType == 'Polygon') {
// У полигона структура [[[lat, lon], ...]] -> уходим на 1 уровень вглубь final polygonRings = _parseRings(decoded);
targetList = decoded[0] as List<dynamic>; if (polygonRings.isNotEmpty) parsedGeometry.add(polygonRings);
} else if (shapeType == 'MultiPolygon') {
for (var poly in decoded) {
if (poly is List) {
final polygonRings = _parseRings(poly);
if (polygonRings.isNotEmpty) parsedGeometry.add(polygonRings);
}
}
} else { } else {
// У LineString структура [[lat, lon], ...] -> используем как есть final singleRing = _parseCoordinateList(decoded);
targetList = decoded; if (singleRing.isNotEmpty) parsedGeometry.add([singleRing]);
} }
points = targetList.map((item) {
final List<dynamic> coords = item as List<dynamic>;
return Point(
(coords[1] as num).toDouble(),
(coords[0] as num).toDouble(),
);
}).toList();
} }
} catch (e) { } catch (e, stackTrace) {
print("PARSE ERROR for Zone ID ${json['id']}: $e"); // Replace with your project logger (e.g., debugPrint or Logger)
assert(() {
print("PARSE ERROR for Zone ID ${json['id']}: $e\n$stackTrace");
return true;
}());
} }
return Zone( return Zone(
id: json['id'] ?? 0, id: json['id'] as int? ?? 0,
title: json['title'] ?? 'Unknown', title: json['title'] as String? ?? 'Unknown',
description: json['description'] ?? '', description: json['description'] as String? ?? '',
type: json['type'] ?? '', type: json['type'] as String? ?? '',
isActive: json['isActive'] ?? false, isActive: json['isActive'] as bool? ?? false,
speedLimit: json['speedLimit'] ?? '', speedLimit: json['speedLimit'] as String? ?? '',
shapeType: shapeType, shapeType: shapeType,
points: points, geometry: parsedGeometry,
); );
} }
static List<List<Point>> _parseRings(List rawRings) {
List<List<Point>> polygonRings = [];
for (var ring in rawRings) {
if (ring is List) {
final ringPoints = _parseCoordinateList(ring);
if (ringPoints.isNotEmpty) polygonRings.add(ringPoints);
}
}
return polygonRings;
}
static List<Point> _parseCoordinateList(List rawCoords) {
List<Point> ringPoints = [];
for (var coord in rawCoords) {
if (coord is List && coord.length >= 2) {
ringPoints.add(Point(
(coord[1] as num).toDouble(),
(coord[0] as num).toDouble(),
));
}
}
return ringPoints;
}
@override @override
String toString() { String toString() {
return 'Zone{id: $id, title: $title, type: $type, points: $points}'; return 'Zone{id: $id, title: $title, type: $type, polygonsCount: ${geometry.length}}';
} }
} }

View File

@@ -1,5 +1,7 @@
import 'package:be_happy/domain/entities/client_notification.dart'; import 'package:be_happy/domain/entities/client_notification.dart';
import '../usecase/get_notifications_usecase.dart';
abstract class NotificationRepository { abstract class NotificationRepository {
/// Устанавливает постоянное SSE-соединение и возвращает поток уведомлений /// Устанавливает постоянное SSE-соединение и возвращает поток уведомлений
Stream<ClientNotification> getNotificationsStream(); Stream<ClientNotification> getNotificationsStream();
@@ -11,5 +13,7 @@ abstract class NotificationRepository {
void closeStream(); void closeStream();
/// получить список уведомлений /// получить список уведомлений
Future<List<ClientNotification>> getNotifications(); Future<NotificationsResult> getNotifications({
} int page = 1,
int pageSize = 10,
});}

View File

@@ -4,17 +4,17 @@ import '../entities/payment_card.dart';
abstract class PaymentRepository { abstract class PaymentRepository {
Future<Result<List<PaymentCard>>> getPaymentCards(); Future<Result<List<PaymentCard>>> getPaymentCards();
Future<Result<void>> addPaymentCard({ Future<Result<Map<String, dynamic>>> addPaymentCard(
required String cardNumber, /*required String cardNumber,
required String cardHolder, required String cardHolder,
required String expiryMonth, required String expiryMonth,
required String expiryYear, required String expiryYear,
required String cvv, required String cvv,*/
}); );
Future<Result<void>> setMainPaymentCard(int cardId); Future<Result<void>> setMainPaymentCard(int cardId);
Future<Result<void>> removePaymentCard(int cardId); Future<Result<void>> removePaymentCard(int cardId);
Future<Result<bool>> activateSubscription(int optionId); Future<Result<bool>> activateSubscription(int optionId, int cardId);
} }

View File

@@ -5,6 +5,7 @@ import '../entities/user_profile.dart';
abstract class UserProfileRepository { abstract class UserProfileRepository {
Future<UserProfile> getProfile(); Future<UserProfile> getProfile();
Future<void> deleteProfile();
Future<UserProfile?> updateProfile(UserProfile profile); Future<UserProfile?> updateProfile(UserProfile profile);
Future<int?> uploadProfilePhoto(File imageFile); Future<int?> uploadProfilePhoto(File imageFile);
Future<UserCheckFlags?> checkUser(); Future<UserCheckFlags?> checkUser();

View File

@@ -5,6 +5,7 @@ import 'package:be_happy/domain/entities/active_scooter_order.dart';
import '../../core/result.dart'; import '../../core/result.dart';
import '../entities/client_subscription.dart'; import '../entities/client_subscription.dart';
import '../entities/fine.dart';
import '../entities/point.dart'; import '../entities/point.dart';
import '../entities/scooter.dart'; import '../entities/scooter.dart';
import '../entities/subscription.dart'; import '../entities/subscription.dart';
@@ -27,10 +28,10 @@ abstract class ScooterRepository {
required bool isInsurance, required bool isInsurance,
}); });
Future<Result<ScooterOrder>> startRide(int orderId); Future<Result<ScooterOrder>> startRide(int orderId);
Future<Result<ScooterOrder>> cancelRide(int orderId); Future<Result<void>> cancelRide(int orderId);
Future<Result<ScooterOrder>> pauseRide(int orderId); Future<Result<ScooterOrder>> pauseRide(int orderId);
Future<Result<ScooterOrder>> resumeRide(int orderId); Future<Result<ScooterOrder>> resumeRide(int orderId);
Future<Result<ScooterOrder>> finishRide(int orderId, List<int> files); Future<Result<void>> finishRide(int orderId, List<int> files);
Future<Result<void>> payRide(int orderId); Future<Result<void>> payRide(int orderId);
Future<Result<List<ScooterOrder>>> getClientOrders(); Future<Result<List<ScooterOrder>>> getClientOrders();
Future<Result<List<int>>> uploadScooterPhotos(List<File> images); Future<Result<List<int>>> uploadScooterPhotos(List<File> images);
@@ -53,4 +54,14 @@ abstract class ScooterRepository {
Future<Result<List<Point>>> getScooterOrderRouteHistory(int id); Future<Result<List<Point>>> getScooterOrderRouteHistory(int id);
Future<Result<Fine>> getFineDetails(int orderId);
Future<Result<void>> payFine({
required int orderId,
int? cardId,
required bool isBalance,
});
Future<Result<List<Fine>>> getClientFines();
} }

View File

@@ -2,5 +2,6 @@ import '../entities/zone.dart';
abstract class ZoneRepository { abstract class ZoneRepository {
Future<List<Zone>> getZones(List<double> area, int page, int pageSize); Future<List<Zone>> getZones(List<double> area, int page, int pageSize);
Future<List<Zone>> getAllZones(int page, int pageSize);
} }

View File

@@ -6,7 +6,7 @@ class ActivateSubscriptionUsecase {
ActivateSubscriptionUsecase(this.repository); ActivateSubscriptionUsecase(this.repository);
Future<Result<bool>> call(int optionId) { Future<Result<bool>> call(int optionId, int cardId) {
return repository.activateSubscription(optionId); return repository.activateSubscription(optionId, cardId);
} }
} }

View File

@@ -6,19 +6,19 @@ class AddPaymentCardUsecase {
AddPaymentCardUsecase(this.repository); AddPaymentCardUsecase(this.repository);
Future<Result<void>> call({ Future<Result<Map<String, dynamic>>> call(
required String cardNumber, /*required String cardNumber,
required String cardHolder, required String cardHolder,
required String expiryMonth, required String expiryMonth,
required String expiryYear, required String expiryYear,
required String cvv, required String cvv,*/
}) { ) {
return repository.addPaymentCard( return repository.addPaymentCard(
cardNumber: cardNumber, /*cardNumber: cardNumber,
cardHolder: cardHolder, cardHolder: cardHolder,
expiryMonth: expiryMonth, expiryMonth: expiryMonth,
expiryYear: expiryYear, expiryYear: expiryYear,
cvv: cvv, cvv: cvv,*/
); );
} }
} }

View File

@@ -7,7 +7,7 @@ class CancelRideUsecase {
CancelRideUsecase(this.repository); CancelRideUsecase(this.repository);
Future<Result<ScooterOrder>> call(int orderId) { Future<Result<void>> call(int orderId) {
return repository.cancelRide(orderId); return repository.cancelRide(orderId);
} }
} }

Some files were not shown because too many files have changed in this diff Show More