diff --git a/.gitea/workflows/test-flight-cd.yaml b/.gitea/workflows/test-flight-cd.yaml
index 9d810d8e..c9649f0e 100644
--- a/.gitea/workflows/test-flight-cd.yaml
+++ b/.gitea/workflows/test-flight-cd.yaml
@@ -11,6 +11,29 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
+ - name: Checkout env repository
+ uses: actions/checkout@v2
+ with:
+ repository: mso7nueh/eatvio_app_env
+ path: env_repo
+ token: ${{ vars.MSO7NUEH_TOKEN }}
+ ref: main
+
+ - name: Copy .env file
+ run: |
+ cp env_repo/.env .env
+
+ - name: Load environment variables from .env
+ run: |
+ set -a
+ source .env
+ set +a
+ # Export all variables to GITHUB_ENV
+ while IFS= read -r line; do
+ if [[ $line =~ ^[A-Za-z_][A-Za-z0-9_]*= ]]; then
+ echo "$line" >> $GITHUB_ENV
+ fi
+ done < .env
- name: Unlock login keychain
run: |
@@ -18,12 +41,25 @@ jobs:
env:
KEYCHAIN_PASSWORD: ${{ vars.IOS_RUNNER_CI_PASSWORD }}
+ - name: Setup API key
+ run: |
+ echo "${API_APPSTORE_KEY}" | tr -d '\n' | base64 --decode > ios/AuthKey.p8
+ chmod 600 ios/AuthKey.p8
+ ls -la ios/AuthKey.p8
+ echo "File size: $(wc -c < ios/AuthKey.p8) bytes"
+ echo "Contents of ios directory:"
+ ls -la ios/
+ env:
+ API_APPSTORE_KEY: ${{ vars.API_APPSTORE_KEY }}
+
- name: Flutter build
run: |
flutter clean
flutter pub get
flutter pub upgrade
flutter pub run build_runner build --delete-conflicting-outputs
+ # Configure Flutter for release mode
+ flutter build ios --config-only --release
cd ios
pod update
fastlane beta
@@ -31,6 +67,8 @@ jobs:
LANG: en_US.UTF-8
LC_ALL: en_US.UTF-8
MATCH_PASSWORD: ${{ vars.IOS_RUNNER_CI_PASSWORD }}
+ FASTLANE_PASSWORD: ${{ vars.FASTLANE_PASSWORD }}
MATCH_GIT_URL: http://gitea.office.local:3000/mso7nueh/fastlane
FASTLANE_USER: eatvio2023@icloud.com
- FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ vars.FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD }}
\ No newline at end of file
+ FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ vars.FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD }}
+ API_APPSTORE_KEY: ${{ vars.API_APPSTORE_KEY }}
diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml
index 75372b09..f1f63162 100644
--- a/.gitea/workflows/test.yml
+++ b/.gitea/workflows/test.yml
@@ -3,7 +3,7 @@ name: Eatvio App Android Test
on: [ pull_request ]
env:
- flutter_version: "3.32.5"
+ flutter_version: "3.35.1"
java_version: "21.x"
flutter_channel: "stable"
my_local_cache_dir: "/opt/hostedtoolcache/"
@@ -16,6 +16,30 @@ jobs:
steps:
- uses: actions/checkout@v3
+ - name: Checkout env repository
+ uses: actions/checkout@v3
+ with:
+ repository: mso7nueh/eatvio_app_env
+ path: env_repo
+ token: ${{ vars.MSO7NUEH_TOKEN }}
+ ref: main
+
+ - name: Copy .env file
+ run: |
+ cp env_repo/.env .env
+
+ - name: Load environment variables from .env
+ run: |
+ set -a
+ source .env
+ set +a
+ # Export all variables to GITHUB_ENV
+ while IFS= read -r line; do
+ if [[ $line =~ ^[A-Za-z_][A-Za-z0-9_]*= ]]; then
+ echo "$line" >> $GITHUB_ENV
+ fi
+ done < .env
+
- name: Create key.properties file
run: |
cat > android/key.properties <
diff --git a/android/gradle.properties b/android/gradle.properties
index 25971708..f018a618 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -1,3 +1,3 @@
-org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
+org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
index f587a472..e603bd33 100644
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-all.zip
diff --git a/android/settings.gradle b/android/settings.gradle
index 833c476b..e173b2c9 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -18,11 +18,11 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
- id "com.android.application" version "8.7.3" apply false
+ id "com.android.application" version "8.12.0" apply false
// START: FlutterFire Configuration
- id "com.google.gms.google-services" version "4.4.2" apply false
+ id "com.google.gms.google-services" version "4.4.3" apply false
// END: FlutterFire Configuration
- id "org.jetbrains.kotlin.android" version "2.0.21" apply false
+ id "org.jetbrains.kotlin.android" version "2.2.10" apply false
}
include ":app"
diff --git a/assets/icons/resend.svg b/assets/icons/resend.svg
new file mode 100644
index 00000000..245a03be
--- /dev/null
+++ b/assets/icons/resend.svg
@@ -0,0 +1,3 @@
+
diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist
index 8c6e5614..86343d86 100644
--- a/ios/Flutter/AppFrameworkInfo.plist
+++ b/ios/Flutter/AppFrameworkInfo.plist
@@ -21,6 +21,6 @@
CFBundleVersion
1.0
MinimumOSVersion
- 12.0
+ 16.0
diff --git a/ios/Gemfile b/ios/Gemfile
index 7a118b49..791ac593 100644
--- a/ios/Gemfile
+++ b/ios/Gemfile
@@ -1,3 +1,3 @@
source "https://rubygems.org"
-gem "fastlane"
+gem "fastlane", "~> 2.217"
diff --git a/ios/Podfile b/ios/Podfile
index 53a8d390..4fe34ec9 100644
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
-platform :ios, '14.0'
+platform :ios, '16.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
@@ -39,7 +39,7 @@ post_install do |installer|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
- config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '14.0'
+ config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.camera
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index d2269b71..7d740632 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -370,7 +370,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 16.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@@ -388,7 +388,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 52;
+ CURRENT_PROJECT_VERSION = 71;
DEVELOPMENT_TEAM = VL68C36HYS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@@ -406,7 +406,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
- MARKETING_VERSION = 1.0.50;
+ MARKETING_VERSION = 1.2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.eatvioapp.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.eatvioapp.app 1747050044";
@@ -466,7 +466,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 16.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -518,7 +518,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 16.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@@ -538,7 +538,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 52;
+ CURRENT_PROJECT_VERSION = 71;
DEVELOPMENT_TEAM = VL68C36HYS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@@ -556,7 +556,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
- MARKETING_VERSION = 1.0.50;
+ MARKETING_VERSION = 1.2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.eatvioapp.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.eatvioapp.app 1747050044";
@@ -576,7 +576,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 52;
+ CURRENT_PROJECT_VERSION = 71;
DEVELOPMENT_TEAM = VL68C36HYS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@@ -594,7 +594,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
- MARKETING_VERSION = 1.0.50;
+ MARKETING_VERSION = 1.2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.eatvioapp.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.eatvioapp.app 1747050044";
diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
index 9c12df59..1a6f2553 100644
--- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -41,7 +41,7 @@
CFBundleInfoDictionaryVersion
6.0
CFBundleName
- eatvio_app
+ Итвио
CFBundlePackageType
APPL
CFBundleShortVersionString
@@ -21,7 +21,7 @@
CFBundleSignature
????
CFBundleVersion
- 52
+ 71
ITSAppUsesNonExemptEncryption
LSRequiresIPhoneOS
diff --git a/ios/fastlane/Fastfile b/ios/fastlane/Fastfile
index 4073b355..3a74adf3 100644
--- a/ios/fastlane/Fastfile
+++ b/ios/fastlane/Fastfile
@@ -18,9 +18,69 @@ default_platform(:ios)
platform :ios do
desc "Push a new beta build to TestFlight"
lane :beta do
- match(type: "appstore")
+ UI.message "Current working directory: #{Dir.pwd}"
+ UI.message "Checking API key file..."
+
+ possible_paths = [
+ "../AuthKey.p8",
+ "./AuthKey.p8",
+ "../../AuthKey.p8",
+ File.expand_path("../AuthKey.p8"),
+ File.expand_path("./AuthKey.p8")
+ ]
+
+ auth_key_path = nil
+ possible_paths.each do |path|
+ if File.exist?(path)
+ UI.message "Found AuthKey.p8 at: #{path}"
+ auth_key_path = File.expand_path(path)
+ break
+ end
+ end
+
+ if auth_key_path.nil?
+ UI.user_error!("API key file not found. Tried paths: #{possible_paths.join(', ')}")
+ end
+
+ UI.message "Using auth_key_path: #{auth_key_path}"
+
+ # Configure Flutter for release mode
+ UI.message "Configuring Flutter for release mode..."
+ sh("cd .. && flutter build ios --config-only --release")
+
+ match(type: "appstore", readonly: true)
increment_build_number(xcodeproj: "Runner.xcodeproj")
- build_app(workspace: "Runner.xcworkspace", scheme: "Runner", export_method: "app-store", codesigning_identity: "Apple Distribution")
- upload_to_testflight
+
+ build_app(
+ workspace: "Runner.xcworkspace",
+ scheme: "Runner",
+ export_method: "app-store",
+ codesigning_identity: "Apple Distribution",
+ )
+
+
+
+ app_store_connect_api_key(
+ key_id: "325JS9JCZH",
+ issuer_id: "dfa27d1d-2bb8-4d4d-847e-0b32f9b880b3",
+ key_filepath: auth_key_path,
+ duration: 1200,
+ in_house: false
+ )
+
+ begin
+ upload_to_testflight(
+ skip_waiting_for_build_processing: true,
+ skip_submission: true,
+ distribute_external: false,
+ notify_external_testers: false,
+ changelog: "TestFlight build #{get_build_number(xcodeproj: 'Runner.xcodeproj')}",
+ verbose: true
+ )
+ rescue => ex
+ UI.error "Upload to TestFlight failed: #{ex.message}"
+ UI.error "Full error: #{ex.backtrace.join("\n")}"
+ raise ex
+ end
end
end
diff --git a/ios/fastlane/report.xml b/ios/fastlane/report.xml
index c86e2b65..0d039029 100644
--- a/ios/fastlane/report.xml
+++ b/ios/fastlane/report.xml
@@ -5,22 +5,24 @@
-
+
-
+
-
+
-
+
+
+
diff --git a/lib/core/app_router.dart b/lib/core/app_router.dart
index 5e9f2cf6..e1ae5612 100644
--- a/lib/core/app_router.dart
+++ b/lib/core/app_router.dart
@@ -1,5 +1,3 @@
-import 'dart:io';
-import 'package:device_info_plus/device_info_plus.dart';
import 'package:dio/dio.dart';
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/firebase_api.dart';
@@ -26,6 +24,7 @@ import 'package:eatvio_app/features/consultations/presentation/pages/consultatio
import 'package:eatvio_app/features/finances_and_consultations_archive/presentation/consultant_finances_screen.dart';
import 'package:eatvio_app/features/finances_and_consultations_archive/presentation/user_purchases_screen.dart';
import 'package:eatvio_app/features/menu/presentation/pages/blocked_users_screen.dart';
+import 'package:eatvio_app/features/menu/presentation/pages/notifications_settings_screen.dart';
import 'package:eatvio_app/features/order_info/presentation/info_by_order_screen.dart';
import 'package:eatvio_app/features/create_diet/presentation/create_diet_screen.dart';
import 'package:eatvio_app/features/create_diet/presentation/diet_preview_screen.dart';
@@ -114,21 +113,13 @@ class AppRouter {
name: 'authScreen',
builder: (context, state) => const AuthScreen(),
routes: [
- GoRoute(
- path: 'registration-screen',
- name: 'registrationScreen',
- builder: (context, state) => const RegistrationScreen(),
- ),
+ GoRoute(path: 'registration-screen', name: 'registrationScreen', builder: (context, state) => const RegistrationScreen()),
GoRoute(
path: 'forget-password-screen',
name: 'forgetPasswordScreen',
- builder: (context, state) => ForgetPasswordScreen(isAuth: state.extra as bool,),
- ),
- GoRoute(
- path: 'scan-qr-code-screen',
- name: 'scanQRCodeScreen',
- builder: (context, state) => const ScanQRCodeScreen(),
+ builder: (context, state) => ForgetPasswordScreen(isAuth: state.extra as bool),
),
+ GoRoute(path: 'scan-qr-code-screen', name: 'scanQRCodeScreen', builder: (context, state) => const ScanQRCodeScreen()),
],
),
ShellRoute(
@@ -166,19 +157,23 @@ class AppRouter {
GoRoute(
path: '/diary-screen',
name: 'diaryScreen',
- pageBuilder: (context, state) => const NoTransitionPage(
- child: DiaryScreen(),
- ),
+ pageBuilder: (context, state) => const NoTransitionPage(child: DiaryScreen()),
),
GoRoute(
- path: ConsultationsScreen.path,
- name: ConsultationsScreen.name,
- pageBuilder: (context, state) => const NoTransitionPage(child: ConsultationsScreen())),
- GoRoute(path: '/chat-select-screen', name: 'chatSelectScreen', pageBuilder: (context, state) => const NoTransitionPage(child: ChatsScreen())),
+ path: ConsultationsScreen.path,
+ name: ConsultationsScreen.name,
+ pageBuilder: (context, state) => const NoTransitionPage(child: ConsultationsScreen()),
+ ),
GoRoute(
- path: '/notifications-screen',
- name: 'notificationsScreen',
- pageBuilder: (context, state) => const NoTransitionPage(child: NotificationsScreen())),
+ path: '/chat-select-screen',
+ name: 'chatSelectScreen',
+ pageBuilder: (context, state) => const NoTransitionPage(child: ChatsScreen()),
+ ),
+ GoRoute(
+ path: '/notifications-screen',
+ name: 'notificationsScreen',
+ pageBuilder: (context, state) => const NoTransitionPage(child: NotificationsScreen()),
+ ),
GoRoute(
path: '/menu-screen',
name: 'menuScreen',
@@ -195,32 +190,16 @@ class AppRouter {
),
],
),
- GoRoute(
- name: 'blockedUsersScreen',
- path: '/blocked-users-screen',
- builder: (context, state) => const BlockedUsersScreen(),
- ),
+ GoRoute(name: 'blockedUsersScreen', path: '/blocked-users-screen', builder: (context, state) => const BlockedUsersScreen()),
GoRoute(
path: '/welcome-screen',
name: 'welcomeScreen',
builder: (context, state) => const WelcomeScreen(),
redirect: (context, state) async {
try {
- if (await TokenStorage.haveTokenInStorage()) {
- final firebaseApi = sl();
- final fbToken = await firebaseApi.getToken();
- final deviceInfo = DeviceInfoPlugin();
- await sl().post(
- '/api/profile/notification/token/register',
- data: {
- 'platform': Platform.isIOS ? 'ios' : 'android',
- 'hw_id': Platform.isIOS ? (await deviceInfo.iosInfo).identifierForVendor : (await deviceInfo.androidInfo).id,
- 'token': fbToken,
- },
- );
- }
final sharedPreferences = await SharedPreferences.getInstance();
final welcomeScreenWasShowed = sharedPreferences.getBool('welcomeScreenWasShowed') ?? false;
+ await sl().registerPushToken();
if (welcomeScreenWasShowed == false) {
return null;
} else if (await TokenStorage.haveTokenInStorage()) {
@@ -229,7 +208,7 @@ class AppRouter {
return '/auth-screen';
}
} catch (e) {
- rethrow;
+ return '/feed-screen';
}
},
),
@@ -254,26 +233,10 @@ class AppRouter {
}
},
),
- GoRoute(
- path: ConsultationsArchiveScreen.path,
- name: ConsultationsArchiveScreen.name,
- builder: (context, state) => const ConsultationsArchiveScreen(),
- ),
- GoRoute(
- path: ConsultantFinancesScreen.path,
- name: ConsultantFinancesScreen.name,
- builder: (context, state) => const ConsultantFinancesScreen(),
- ),
- GoRoute(
- path: UserPurchasesScreen.path,
- name: UserPurchasesScreen.name,
- builder: (context, state) => const UserPurchasesScreen(),
- ),
- GoRoute(
- path: '/user-finance-screen',
- name: 'userFinanceScreen',
- builder: (context, state) => const UserFinanceScreen(),
- ),
+ GoRoute(path: ConsultationsArchiveScreen.path, name: ConsultationsArchiveScreen.name, builder: (context, state) => const ConsultationsArchiveScreen()),
+ GoRoute(path: ConsultantFinancesScreen.path, name: ConsultantFinancesScreen.name, builder: (context, state) => const ConsultantFinancesScreen()),
+ GoRoute(path: UserPurchasesScreen.path, name: UserPurchasesScreen.name, builder: (context, state) => const UserPurchasesScreen()),
+ GoRoute(path: '/user-finance-screen', name: 'userFinanceScreen', builder: (context, state) => const UserFinanceScreen()),
GoRoute(
path: CardSettingsScreen.path,
name: CardSettingsScreen.name,
@@ -288,11 +251,7 @@ class AppRouter {
builder: (context, state) {
final slug = state.uri.queryParameters['slug'];
if (slug != null) {
- return AboutPlanScreen(
- slug: slug,
- navigateToComments: false,
- index: null,
- );
+ return AboutPlanScreen(slug: slug, navigateToComments: false, index: null);
}
final data = state.extra as Map;
@@ -306,29 +265,23 @@ class AppRouter {
builder: (context, state) {
final slug = state.uri.queryParameters['slug'];
if (slug != null) {
- return AboutRecipeScreen(
- recipeSlug: slug,
- navigateToComments: false,
- index: null,
- );
+ return AboutRecipeScreen(recipeSlug: slug, navigateToComments: false, index: null);
}
final data = state.extra as Map;
- return AboutRecipeScreen(
- recipeSlug: data['recipe'] as String,
- index: data['index'] as int?,
- navigateToComments: data['navigateToComments'] as bool,
- );
+ return AboutRecipeScreen(recipeSlug: data['recipe'] as String, index: data['index'] as int?, navigateToComments: data['navigateToComments'] as bool);
},
),
GoRoute(
path: RecipeCreateScreen.path,
name: RecipeCreateScreen.name,
- builder: (context, state) => RecipeCreateScreen(
- recipe: state.extra != null ? state.extra as Recipe : null,
- ),
+ builder: (context, state) => RecipeCreateScreen(recipe: state.extra != null ? state.extra as Recipe : null),
+ ),
+ GoRoute(
+ path: '/profile-screen',
+ name: 'profileScreen',
+ builder: (context, state) => ProfileScreen(author: state.extra as Author),
),
- GoRoute(path: '/profile-screen', name: 'profileScreen', builder: (context, state) => ProfileScreen(author: state.extra as Author)),
GoRoute(
path: '/subs-screen/:slug',
name: 'subsScreen',
@@ -340,11 +293,7 @@ class AppRouter {
builder: (context, state) {
final slug = state.uri.queryParameters['slug'];
if (slug != null) {
- return AboutDietScreen(
- slug: slug,
- index: null,
- navigateToComments: false,
- );
+ return AboutDietScreen(slug: slug, index: null, navigateToComments: false);
}
final data = state.extra as Map;
return AboutDietScreen(slug: data['slug'] as String, index: data['index'] as int?, navigateToComments: data['navigateToComments'] as bool);
@@ -356,19 +305,18 @@ class AppRouter {
builder: (context, state) => BlogPostCreateScreen(feedBlogPostModel: state.extra != null ? state.extra as FeedBlogPostModel : null),
),
GoRoute(
- path: '/blog-post-screen',
- name: 'blogPostScreen',
- builder: (context, state) {
- final id = state.uri.queryParameters['id'];
- final parsedId = int.tryParse(id ?? '');
- if (parsedId != null) {
- return BlogPostScreen(
- id: parsedId,
- );
- }
+ path: '/blog-post-screen',
+ name: 'blogPostScreen',
+ builder: (context, state) {
+ final id = state.uri.queryParameters['id'];
+ final parsedId = int.tryParse(id ?? '');
+ if (parsedId != null) {
+ return BlogPostScreen(id: parsedId);
+ }
- return BlogPostScreen(id: state.extra as int);
- }),
+ return BlogPostScreen(id: state.extra as int);
+ },
+ ),
GoRoute(
path: '/chat-screen',
name: 'chatScreen',
@@ -376,10 +324,7 @@ class AppRouter {
final data = state.extra as Map;
final uuid = data['uuid'] as String;
final sendInitialMessage = data['sendInitialMessage'] as bool?;
- return ChatScreen(
- uuid: uuid,
- sendInitialMessage: sendInitialMessage,
- );
+ return ChatScreen(uuid: uuid, sendInitialMessage: sendInitialMessage);
},
),
GoRoute(
@@ -412,7 +357,11 @@ class AppRouter {
name: 'physicalFormScreen',
builder: (context, state) => PhysicalFormScreen(settingsEntity: state.extra as SettingsEntity),
),
- GoRoute(path: 'pressure-screen', name: 'pressureScreen', builder: (context, state) => PressureScreen(settingsEntity: state.extra as SettingsEntity)),
+ GoRoute(
+ path: 'pressure-screen',
+ name: 'pressureScreen',
+ builder: (context, state) => PressureScreen(settingsEntity: state.extra as SettingsEntity),
+ ),
GoRoute(
path: 'change-password-screen',
name: 'changePasswordScreen',
@@ -429,9 +378,7 @@ class AppRouter {
GoRoute(
path: '/stepper-become-consultant-screen',
name: 'stepperBecomeConsultantScreen',
- builder: (context, state) => StepperBecomeConsultantScreen(
- slug: state.extra == null ? null : state.extra as String,
- ),
+ builder: (context, state) => StepperBecomeConsultantScreen(slug: state.extra == null ? null : state.extra as String),
),
GoRoute(path: '/calendar-screen', name: 'calendarScreen', builder: (context, state) => const CalendarScreen()),
GoRoute(path: '/support-screen', name: 'supportScreen', builder: (context, state) => const SupportScreen()),
@@ -459,7 +406,11 @@ class AppRouter {
GoRoute(path: CreatePlanScreen.path, name: CreatePlanScreen.name, builder: (context, state) => const CreatePlanScreen()),
GoRoute(path: MyDietsScreen.path, name: MyDietsScreen.name, builder: (context, state) => const MyDietsScreen()),
GoRoute(path: MyPlansScreen.path, name: MyPlansScreen.name, builder: (context, state) => const MyPlansScreen()),
- GoRoute(path: UserDetailsScreen.path, name: UserDetailsScreen.name, builder: (context, state) => UserDetailsScreen(slug: state.extra as String)),
+ GoRoute(
+ path: UserDetailsScreen.path,
+ name: UserDetailsScreen.name,
+ builder: (context, state) => UserDetailsScreen(slug: state.extra as String),
+ ),
GoRoute(path: DevToolsScreen.path, name: DevToolsScreen.name, builder: (context, state) => const DevToolsScreen()),
GoRoute(path: ConsultantRatingScreen.path, name: ConsultantRatingScreen.name, builder: (context, state) => const ConsultantRatingScreen()),
GoRoute(
@@ -469,10 +420,7 @@ class AppRouter {
final data = state.extra as Map;
final planId = data['planId'] as int;
final successfulPayment = data['successfulPayment'] as bool?;
- return InfoByOrderScreen(
- planId: planId,
- successfulPayment: successfulPayment,
- );
+ return InfoByOrderScreen(planId: planId, successfulPayment: successfulPayment);
},
),
GoRoute(
@@ -482,10 +430,7 @@ class AppRouter {
final data = state.extra as Map;
final planId = data['planId'] as int;
final url = data['url'] as String;
- return PaymentScreen(
- url: url,
- planId: planId,
- );
+ return PaymentScreen(url: url, planId: planId);
},
),
GoRoute(
@@ -495,10 +440,7 @@ class AppRouter {
final data = state.extra as Map;
final diaryId = data['diaryId'] as int;
final currentPlanDay = data['currentDiaryDay'] as int;
- return UserDiaryScreen(
- diaryId: diaryId,
- currentPlanDay: currentPlanDay,
- );
+ return UserDiaryScreen(diaryId: diaryId, currentPlanDay: currentPlanDay);
},
),
GoRoute(
@@ -506,16 +448,9 @@ class AppRouter {
name: 'verifyScreen',
builder: (context, state) => VerifyScreen(passKey: state.extra as String),
),
- GoRoute(
- path: '/verify-email-screen',
- name: 'verifyEmailScreen',
- builder: (context, state) => const VerifyEmailScreen(),
- ),
- GoRoute(
- path: MyRecipesScreen.path,
- name: MyRecipesScreen.name,
- builder: (context, state) => const MyRecipesScreen(),
- ),
+ GoRoute(path: '/verify-email-screen', name: 'verifyEmailScreen', builder: (context, state) => const VerifyEmailScreen()),
+ GoRoute(path: MyRecipesScreen.path, name: MyRecipesScreen.name, builder: (context, state) => const MyRecipesScreen()),
+ GoRoute(path: '/notifications-settings-screen', name: 'notificationsSettingsScreen', builder: (context, state) => const NotificationsSettingsScreen()),
GoRoute(
path: PersonalDietSuggestionScreen.path,
diff --git a/lib/core/comments/presentation/comments_actions_bottom_sheet.dart b/lib/core/comments/presentation/comments_actions_bottom_sheet.dart
index deeea5ff..3c1c3859 100644
--- a/lib/core/comments/presentation/comments_actions_bottom_sheet.dart
+++ b/lib/core/comments/presentation/comments_actions_bottom_sheet.dart
@@ -1,11 +1,10 @@
-import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
+import 'package:eatvio_app/core/widgets/bottom_sheet_action_widget.dart';
import 'package:eatvio_app/core/widgets/bottom_sheet_handler_bar.dart';
import 'package:eatvio_app/core/widgets/custom_divider.dart';
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
-import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
void showCommentsActionsBottomSheet(
@@ -23,7 +22,7 @@ void showCommentsActionsBottomSheet(
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (context) => Container(
- margin: EdgeInsets.only(left: 8, right: 8, bottom: MediaQuery.of(context).padding.bottom),
+ margin: EdgeInsets.only(left: 8, right: 8, bottom: MediaQuery.of(context).padding.bottom + 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: appTheme.whiteA700,
@@ -123,7 +122,7 @@ class _CommentsActionsBottomSheetState extends State
),
const BottomSheetHandlerBar(),
if (widget.isMyComment)
- _ActionWidget(
+ BottomSheetActionWidget(
text: s.edit,
iconPath: 'assets/icons/edit_paint.svg',
needToPop: false,
@@ -132,13 +131,13 @@ class _CommentsActionsBottomSheetState extends State
}),
)
else if (widget.reply != null)
- _ActionWidget(
+ BottomSheetActionWidget(
text: s.reply,
iconPath: 'assets/icons/reply.svg',
onTap: widget.reply!,
),
if (widget.reply != null) const CustomDivider(),
- _ActionWidget(
+ BottomSheetActionWidget(
text: s.copy,
iconPath: 'assets/icons/copy2.svg',
onTap: widget.copy,
@@ -146,21 +145,21 @@ class _CommentsActionsBottomSheetState extends State
if (widget.isMyComment) ...[
if (widget.reply != null) ...[
const CustomDivider(),
- _ActionWidget(
+ BottomSheetActionWidget(
text: s.reply,
iconPath: 'assets/icons/reply.svg',
onTap: widget.reply!,
),
],
const CustomDivider(),
- _ActionWidget(
+ BottomSheetActionWidget(
text: s.deleteComment,
iconPath: 'assets/icons/red_trash.svg',
onTap: widget.delete,
),
] else ...[
const CustomDivider(),
- _ActionWidget(
+ BottomSheetActionWidget(
text: s.complain,
iconPath: 'assets/icons/complain.svg',
onTap: widget.complain,
@@ -172,32 +171,3 @@ class _CommentsActionsBottomSheetState extends State
}
}
-class _ActionWidget extends StatelessWidget {
- const _ActionWidget({required this.text, required this.iconPath, required this.onTap, this.needToPop = true});
- final String text;
- final String iconPath;
- final void Function() onTap;
- final bool needToPop;
- @override
- Widget build(BuildContext context) {
- return GestureDetector(
- onTap: () {
- if (needToPop) Navigator.pop(context);
- onTap();
- },
- child: Padding(
- padding: const EdgeInsets.symmetric(vertical: 12),
- child: Row(
- children: [
- Text(
- text,
- style: TextStyles.textLMedium.copyWith(color: appTheme.black),
- ),
- const Spacer(),
- SvgPicture.asset(iconPath)
- ],
- ),
- ),
- );
- }
-}
diff --git a/lib/core/const.dart b/lib/core/const.dart
index 4f38a54e..98f7bc4a 100644
--- a/lib/core/const.dart
+++ b/lib/core/const.dart
@@ -1,5 +1,8 @@
-// String baseUrl = 'https://eatvio.ru';
-String baseUrl = 'https://dev2.eatvio.com';
+import 'package:eatvio_app/core/env_config.dart';
+
+String baseUrl = EnvConfig.baseUrl;
+bool hidePlans = const bool.fromEnvironment('HIDE_PLANS', defaultValue: false);
+const buildDate = String.fromEnvironment('BUILD_DATE', defaultValue: '');
const List durationValues = [7, 14, 21];
diff --git a/lib/core/credentials_storage.dart b/lib/core/credentials_storage.dart
deleted file mode 100644
index 6e9870e5..00000000
--- a/lib/core/credentials_storage.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
-
-abstract class CredentialsStorage {
- static Future haveCredentialsInStorage() async {
- try {
- if (await const FlutterSecureStorage().read(key: 'email') == null || await const FlutterSecureStorage().read(key: 'password') == null) {
- return false;
- } else {
- return true;
- }
- } catch (e) {
- return false;
- }
- }
-
- static Future