Merge remote-tracking branch 'upstream/main' into tests

This commit is contained in:
misha
2025-10-08 14:33:47 +03:00
9 changed files with 113 additions and 29 deletions

View File

@@ -67,7 +67,7 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>yandexauth</string>
<string>yandexauth2</string>

View File

@@ -8,6 +8,7 @@
<array>
<string>applinks:eatvio.ru</string>
<string>applinks:www.eatvio.ru</string>
<string>applinks:5399b03636104c6d920b87c1ad329254.oauth.yandex.ru</string>
</array>
</dict>
</plist>

View File

@@ -1,3 +1,4 @@
import 'package:eatvio_app/core/internet_connection_cubit/internet_connection_cubit.dart';
import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/core/views/cubit/views_cubit.dart';
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/new_messages_cubit/new_messages_cubit.dart';
@@ -5,7 +6,6 @@ import 'package:eatvio_app/features/notifications/presentation/notifications_cub
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_cubit.dart';
import 'package:eatvio_app/features/chat/presentation/bloc/chats_cubit/chats_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart';
import 'package:eatvio_app/features/internet_connection_checker/internet_connection_checker_screen.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -16,18 +16,12 @@ class AppConfig {
/// Список глобальных BlocProvider'ов
static List<BlocProvider> get globalBlocProviders => [
BlocProvider<NewMessagesCubit>(create: (context) => sl<NewMessagesCubit>()),
BlocProvider<NotificationsCubit>(
create: (context) => sl<NotificationsCubit>()..getNotifications(),
),
BlocProvider<FeedCubit>(
create: (context) => sl<FeedCubit>()..loadFeedBlogPostList(),
),
BlocProvider<ProfileAvatarCubit>(
create: (context) => sl<ProfileAvatarCubit>()..getMyProfile(),
),
BlocProvider<ChatsCubit>(
create: (context) => sl<ChatsCubit>()..getChatRoomsWithLoading(),
),
BlocProvider<NotificationsCubit>(create: (context) => sl<NotificationsCubit>()..getNotifications()),
BlocProvider<FeedCubit>(create: (context) => sl<FeedCubit>()..loadFeedBlogPostList()),
BlocProvider<ProfileAvatarCubit>(create: (context) => sl<ProfileAvatarCubit>()..getMyProfile()),
BlocProvider<ChatsCubit>(create: (context) => sl<ChatsCubit>()..getChatRoomsWithLoading()),
BlocProvider<ViewsCubit>(create: (context) => sl<ViewsCubit>()),
BlocProvider<InternetConnectionCubit>(lazy: false, create: (context) => sl<InternetConnectionCubit>()),
];
/// Делегаты локализации
@@ -39,15 +33,5 @@ class AppConfig {
];
/// Поддерживаемые локали
static const List<Locale> supportedLocales = [
Locale.fromSubtags(languageCode: 'ru'),
];
/// Создание обертки для проверки интернет-соединения
static Widget createInternetConnectionWrapper(Widget child) {
return BlocProvider(
create: (context) => sl<ViewsCubit>(),
child: InternetConnectionCheckerScreen(child: child),
);
}
static const List<Locale> supportedLocales = [Locale.fromSubtags(languageCode: 'ru')];
}

View File

@@ -1,6 +1,6 @@
import 'package:eatvio_app/core/env_config.dart';
String baseUrl = EnvConfig.baseUrl;
String baseUrl = EnvConfig.devBaseUrl;
bool hidePlans = const bool.fromEnvironment('HIDE_PLANS', defaultValue: false);
const buildDate = String.fromEnvironment('BUILD_DATE', defaultValue: '');

View File

@@ -1,3 +1,4 @@
import 'package:eatvio_app/core/internet_connection_cubit/internet_connection_cubit.dart';
import 'package:eatvio_app/core/views/cubit/views_cubit.dart';
import 'package:eatvio_app/features/auth/presentation/bloc/auth_cubit/auth_cubit.dart';
import 'package:eatvio_app/features/auth/presentation/bloc/reset_password_cubit/reset_password_cubit.dart';
@@ -64,6 +65,7 @@ class CubitRegistrations {
sl.registerLazySingleton<NotificationsCubit>(() => NotificationsCubit(wsManager: sl(), notificationsRepository: sl()));
sl.registerLazySingleton<ProfileAvatarCubit>(() => ProfileAvatarCubit(profileRepository: sl()));
sl.registerLazySingleton<ChatsCubit>(() => ChatsCubit(chatRepository: sl(), wsManager: sl(), profileRepository: sl()));
sl.registerLazySingleton<InternetConnectionCubit>(() => InternetConnectionCubit());
}
/// Регистрация Cubit'ов как фабрик

View File

@@ -0,0 +1,73 @@
import 'dart:async';
import 'dart:developer';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:eatvio_app/core/env_config.dart';
import 'package:eatvio_app/core/internet_connection_cubit/internet_connection_state.dart';
import 'package:eatvio_app/core/utils/toasts.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:http/http.dart' as http;
class InternetConnectionCubit extends Cubit<InternetConnectionState> {
InternetConnectionCubit() : super(InternetConnectionState()) {
checkConnection();
_connectivitySubscription = _connectivity.onConnectivityChanged.listen(_updateAccessStatus);
_listener = AppLifecycleListener(
onResume: () async {
_connectivitySubscription.resume();
await checkConnection();
},
onHide: _connectivitySubscription.pause,
onPause: _connectivitySubscription.pause,
);
}
final Connectivity _connectivity = Connectivity();
late StreamSubscription<List<ConnectivityResult>> _connectivitySubscription;
late final AppLifecycleListener _listener;
Future<void> checkConnection() async {
late List<ConnectivityResult> result;
try {
result = await _connectivity.checkConnectivity();
} on PlatformException catch (e) {
log('Couldn\'t check connectivity status', error: e);
return;
}
return _updateAccessStatus(result);
}
Future<void> _updateAccessStatus(List<ConnectivityResult> result) async {
final hasInternet = await _checkInternetAccess(result);
if (!hasInternet) showInternetConnectionToast();
emit(state.copyWith(isInternetAvailable: hasInternet));
}
Future<bool> _checkInternetAccess(List<ConnectivityResult> result) async {
if (result.contains(ConnectivityResult.none)) {
return false;
}
final uris = [Uri.parse(EnvConfig.googleCheckUrl), Uri.parse(EnvConfig.yandexCheckUrl), Uri.parse(EnvConfig.devBaseUrl), Uri.parse(EnvConfig.baseUrl)];
for (final uri in uris) {
try {
final response = await http.get(uri).timeout(const Duration(seconds: 3));
return response.statusCode >= 100 && response.statusCode < 600;
} catch (e) {
continue;
}
}
return false;
}
@override
Future<void> close() {
_connectivitySubscription.cancel();
_listener.dispose();
return super.close();
}
}

View File

@@ -0,0 +1,13 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'internet_connection_state.freezed.dart';
@freezed
abstract class InternetConnectionState with _$InternetConnectionState {
factory InternetConnectionState({
@Default(true) bool isInternetAvailable,
}) = _InternetConnectionState;
}

View File

@@ -38,4 +38,16 @@ void showSuccessToast(String message) {
textColor: appTheme.whiteA700,
fontSize: 16.0,
);
}
}
void showInternetConnectionToast() {
Fluttertoast.showToast(
msg: 'Проверьте подключение к интернету',
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.TOP,
timeInSecForIosWeb: 3,
backgroundColor: appTheme.red,
textColor: Colors.white,
fontSize: 16.0,
);
}

View File

@@ -23,8 +23,7 @@ class MyApp extends StatelessWidget {
child: KeyboardDismisser(
child: MaterialApp.router(
theme: ThemeHelper().themeData(),
routerConfig: AppRouter.appRouter,
builder: (context, child) => AppConfig.createInternetConnectionWrapper(child!),
routerConfig: AppRouter.appRouter,
debugShowCheckedModeBanner: false,
localizationsDelegates: AppConfig.localizationDelegates,
supportedLocales: AppConfig.supportedLocales,