diff --git a/lib/core/config/dependencies.dart b/lib/core/config/dependencies.dart index b688d6c..a8bc333 100644 --- a/lib/core/config/dependencies.dart +++ b/lib/core/config/dependencies.dart @@ -60,7 +60,7 @@ List get apiClients { Provider( create: (context) => ProfileService(networkManager: context.read()), ), - Provider( + Provider( create: (context) => NotificationsService(networkManager: context.read()), ), ]; @@ -100,8 +100,10 @@ List get repositories { Provider( create: (context) => ProfileRepository(profileService: context.read()), ), - Provider( - create: (context) => NotificationsRepository(notificationsService: context.read()), + Provider( + create: + (context) => + NotificationsRepository(notificationsService: context.read()), ), ]; } @@ -155,7 +157,7 @@ List get viewModels { ChangeNotifierProvider( create: (context) => FinalCompletionOfDocumentsViewModel(), ), - ChangeNotifierProvider( + ChangeNotifierProvider( create: (context) => NotificationViewModel(repositoryViewModel: context.read()), diff --git a/lib/core/utils/app_toast.dart b/lib/core/utils/app_toast.dart index 8b843fa..d7512ab 100644 --- a/lib/core/utils/app_toast.dart +++ b/lib/core/utils/app_toast.dart @@ -21,4 +21,19 @@ class AppToast { autoCloseDuration: const Duration(seconds: 3), ); } + + static void notification( + BuildContext context, + String title, + String description, + ) { + toastification.show( + context: context, + type: ToastificationType.info, + style: ToastificationStyle.flatColored, + title: Text(title), + description: Text(description), + autoCloseDuration: const Duration(seconds: 6), + ); + } } diff --git a/lib/main.dart b/lib/main.dart index 0b21bc5..ea5eace 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -13,6 +13,8 @@ import 'package:tm_app/core/config/web_url_strategy.dart'; import 'package:tm_app/core/services/cache_init.dart'; import 'package:tm_app/core/services/firebase_service.dart'; import 'package:tm_app/core/theme/theme_provider.dart'; +import 'package:tm_app/core/utils/app_toast.dart'; +import 'package:toastification/toastification.dart'; import 'core/routes/app_routes.dart'; import 'core/theme/colors.dart'; @@ -61,6 +63,21 @@ class _MyAppState extends State { _handleMessage(initialMessage); } + if (kIsWeb) { + FirebaseMessaging.onMessage.listen((event) { + final overlayCtx = rootNavigatorKey.currentContext; + if (overlayCtx != null) { + if (overlayCtx.mounted) { + AppToast.notification( + overlayCtx, + event.notification?.title ?? 'New Notification', + event.notification?.body ?? 'New Notification', + ); + } + } + }); + } + FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage); } @@ -73,7 +90,9 @@ class _MyAppState extends State { @override void initState() { super.initState(); - setupInteractedMessage(); + WidgetsBinding.instance.addPostFrameCallback((_) { + setupInteractedMessage(); + }); } @override @@ -88,38 +107,40 @@ class _MyAppState extends State { // Listen to theme changes final themeProvider = context.watch(); - return MaterialApp.router( - title: 'OppLens', - debugShowCheckedModeBanner: false, - scrollBehavior: const MaterialScrollBehavior().copyWith( - dragDevices: { - PointerDeviceKind.mouse, - PointerDeviceKind.touch, - PointerDeviceKind.stylus, - PointerDeviceKind.unknown, - }, - ), - theme: ThemeData( - pageTransitionsTheme: PageTransitionsTheme( - builders: { - for (final platform in TargetPlatform.values) - platform: - kIsWeb - ? const FadeUpwardsPageTransitionsBuilder() - : const CupertinoPageTransitionsBuilder(), + return ToastificationWrapper( + child: MaterialApp.router( + title: 'OppLens', + debugShowCheckedModeBanner: false, + scrollBehavior: const MaterialScrollBehavior().copyWith( + dragDevices: { + PointerDeviceKind.mouse, + PointerDeviceKind.touch, + PointerDeviceKind.stylus, + PointerDeviceKind.unknown, }, ), - brightness: - themeProvider.isDarkMode ? Brightness.dark : Brightness.light, - primaryColor: AppColors.primaryColor, - scaffoldBackgroundColor: AppColors.backgroundColor, - colorScheme: ColorScheme.fromSeed( - seedColor: AppColors.primaryColor, + theme: ThemeData( + pageTransitionsTheme: PageTransitionsTheme( + builders: { + for (final platform in TargetPlatform.values) + platform: + kIsWeb + ? const FadeUpwardsPageTransitionsBuilder() + : const CupertinoPageTransitionsBuilder(), + }, + ), brightness: themeProvider.isDarkMode ? Brightness.dark : Brightness.light, + primaryColor: AppColors.primaryColor, + scaffoldBackgroundColor: AppColors.backgroundColor, + colorScheme: ColorScheme.fromSeed( + seedColor: AppColors.primaryColor, + brightness: + themeProvider.isDarkMode ? Brightness.dark : Brightness.light, + ), ), + routerConfig: appRouter, ), - routerConfig: appRouter, ); } } diff --git a/lib/views/tenders/pages/m_tenders_page.dart b/lib/views/tenders/pages/m_tenders_page.dart index 35d611c..44fbce5 100644 --- a/lib/views/tenders/pages/m_tenders_page.dart +++ b/lib/views/tenders/pages/m_tenders_page.dart @@ -43,32 +43,34 @@ class _MobileTendersPageState extends State { return Scaffold( backgroundColor: AppColors.backgroundColor, appBar: tenderMobileAppBar(title: TendersStrings.tendersTitle), - body: Consumer( - builder: (context, viewModel, child) { - if (viewModel.isLoading) { - return const Center( - child: CircularProgressIndicator(color: AppColors.jellyBean), - ); - } - if (viewModel.errorMessage != null) { - return Center(child: Text(viewModel.errorMessage!)); - } + body: SingleChildScrollView( + child: Consumer( + builder: (context, viewModel, child) { + if (viewModel.isLoading) { + return const Center( + child: CircularProgressIndicator(color: AppColors.jellyBean), + ); + } + if (viewModel.errorMessage != null) { + return Center(child: Text(viewModel.errorMessage!)); + } - if ((viewModel.tendersResponse?.data?.tenders == null || - viewModel.tendersResponse!.data!.tenders!.isEmpty) && - viewModel.isLoading == false) { - return const Center(child: Text(CommonStrings.noData)); - } + if ((viewModel.tendersResponse?.data?.tenders == null || + viewModel.tendersResponse!.data!.tenders!.isEmpty) && + viewModel.isLoading == false) { + return const Center(child: Text(CommonStrings.noData)); + } - return SafeArea( - child: Padding( - padding: EdgeInsets.symmetric(vertical: 18.0.h()), - child: MainTendersSlider( - tenders: viewModel.tendersResponse?.data?.tenders ?? [], + return SafeArea( + child: Padding( + padding: EdgeInsets.symmetric(vertical: 18.0.h()), + child: MainTendersSlider( + tenders: viewModel.tendersResponse?.data?.tenders ?? [], + ), ), - ), - ); - }, + ); + }, + ), ), ); } diff --git a/lib/views/tenders/widgets/main_tenders_slider.dart b/lib/views/tenders/widgets/main_tenders_slider.dart index 27e5380..b0c2b70 100644 --- a/lib/views/tenders/widgets/main_tenders_slider.dart +++ b/lib/views/tenders/widgets/main_tenders_slider.dart @@ -158,7 +158,7 @@ class _MainTendersSliderState extends State { Widget _nextPreviousArrows({required bool isLtr}) { return PositionedDirectional( - top: 607.0.h(), + top: 558.0.h(), bottom: 52.0.h(), start: 9.0.w(), end: 9.0.w(), diff --git a/lib/views/tenders/widgets/tender_card.dart b/lib/views/tenders/widgets/tender_card.dart index c0e90ed..1a67b2d 100644 --- a/lib/views/tenders/widgets/tender_card.dart +++ b/lib/views/tenders/widgets/tender_card.dart @@ -106,7 +106,7 @@ class TenderCard extends StatelessWidget { ], ), ), - SizedBox(height: isDesktop ? 20.0.h() : 72.0.h()), + SizedBox(height: isDesktop ? 20.0.h() : 52.0.h()), if (!isDesktop) TenderActionButtonsRow(tender: tender), ], );