From fe2f4a872ba6535d02f037d95888df17bc115e3e Mon Sep 17 00:00:00 2001 From: mohammad Date: Thu, 17 Jul 2025 12:38:58 +0300 Subject: [PATCH] Refactor memory event handling: replace MemoryBookableSpaceService with a new implementation and integrate caching logic in CalendarEventsBloc --- .../memory_bookable_space_service.dart | 63 +++++++++++++++++++ .../domain/LoadEventsParam.dart | 6 ++ .../bloc/calendar/events_bloc.dart | 28 +-------- .../model/memory_bookable_space_service.dart | 35 ----------- .../presentation/view/booking_page.dart | 17 ++--- 5 files changed, 79 insertions(+), 70 deletions(-) create mode 100644 lib/pages/access_management/booking_system/data/services/memory_bookable_space_service.dart delete mode 100644 lib/pages/access_management/booking_system/presentation/model/memory_bookable_space_service.dart diff --git a/lib/pages/access_management/booking_system/data/services/memory_bookable_space_service.dart b/lib/pages/access_management/booking_system/data/services/memory_bookable_space_service.dart new file mode 100644 index 00000000..7aec2398 --- /dev/null +++ b/lib/pages/access_management/booking_system/data/services/memory_bookable_space_service.dart @@ -0,0 +1,63 @@ +import 'package:syncrow_web/pages/access_management/booking_system/data/services/remote_calendar_service.dart'; +import 'package:syncrow_web/pages/access_management/booking_system/domain/LoadEventsParam.dart'; +import 'package:syncrow_web/pages/access_management/booking_system/domain/models/calendar_event_booking.dart'; +import 'package:syncrow_web/pages/access_management/booking_system/domain/services/calendar_system_service.dart'; + +class MemoryBookableSpaceService implements CalendarSystemService { + final Map _eventsCache = {}; + + @override + Future getCalendarEvents({ + required LoadEventsParam params, + }) async { + final key = params.generateKey(); + + return _eventsCache[key]!; + } + + void setEvents( + LoadEventsParam param, + CalendarEventsResponse events, + ) { + final key = param.generateKey(); + _eventsCache[key] = events; + } + + void addEvent(LoadEventsParam param, CalendarEventsResponse event) { + final key = param.generateKey(); + + _eventsCache[key] = event; + } + + void clear() { + _eventsCache.clear(); + } +} + +class MemoryCalendarServiceWithRemoteFallback implements CalendarSystemService { + final MemoryBookableSpaceService memoryService; + final RemoteCalendarService remoteService; + + MemoryCalendarServiceWithRemoteFallback({ + required this.memoryService, + required this.remoteService, + }); + + @override + Future getCalendarEvents({ + required LoadEventsParam params, + }) async { + final key = params.generateKey(); + final doesExistInMemory = memoryService._eventsCache.containsKey(key); + + if (doesExistInMemory) { + return memoryService.getCalendarEvents(params: params); + } else { + final remoteResult = + await remoteService.getCalendarEvents(params: params); + memoryService.setEvents(params, remoteResult); + + return remoteResult; + } + } +} diff --git a/lib/pages/access_management/booking_system/domain/LoadEventsParam.dart b/lib/pages/access_management/booking_system/domain/LoadEventsParam.dart index f5088b6e..542dd5dc 100644 --- a/lib/pages/access_management/booking_system/domain/LoadEventsParam.dart +++ b/lib/pages/access_management/booking_system/domain/LoadEventsParam.dart @@ -26,3 +26,9 @@ class LoadEventsParam extends Equatable { ); } } + +extension KeyGenerator on LoadEventsParam { + String generateKey() { + return '$id-${startDate.year}-${startDate.month.toString().padLeft(2, '0')}'; + } +} \ No newline at end of file diff --git a/lib/pages/access_management/booking_system/presentation/bloc/calendar/events_bloc.dart b/lib/pages/access_management/booking_system/presentation/bloc/calendar/events_bloc.dart index 3945e5f5..b42947bd 100644 --- a/lib/pages/access_management/booking_system/presentation/bloc/calendar/events_bloc.dart +++ b/lib/pages/access_management/booking_system/presentation/bloc/calendar/events_bloc.dart @@ -5,21 +5,16 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/access_management/booking_system/domain/LoadEventsParam.dart'; import 'package:syncrow_web/pages/access_management/booking_system/domain/models/calendar_event_booking.dart'; import 'package:syncrow_web/pages/access_management/booking_system/domain/services/calendar_system_service.dart'; -import 'package:syncrow_web/pages/access_management/booking_system/presentation/model/memory_bookable_space_service.dart'; +import 'package:syncrow_web/pages/access_management/booking_system/data/services/memory_bookable_space_service.dart'; part 'events_event.dart'; part 'events_state.dart'; class CalendarEventsBloc extends Bloc { final EventController eventController = EventController(); final CalendarSystemService calendarService; - final Map> _eventsCache = {}; - final MemoryBookableSpaceService memoryService; - - CalendarEventsBloc({ required this.calendarService, - required this.memoryService, }) : super(EventsInitial()) { on(_onLoadEvents); on(_onAddEvent); @@ -34,24 +29,12 @@ class CalendarEventsBloc extends Bloc { final month = param.endDate.month; final year = param.endDate.year; final spaceId = param.id; - final cachedEvents = memoryService.getEvents(spaceId, year, month); - if (cachedEvents != null) { - eventController.addAll(cachedEvents); - emit(EventsLoaded( - events: cachedEvents, - spaceId: spaceId, - month: month, - year: year, - )); - return; - } emit(EventsLoading()); try { final response = await calendarService.getCalendarEvents(params: param); final events = response.data.map(_toCalendarEventData).toList(); - memoryService.setEvents(spaceId, year, month, events); eventController.addAll(events); emit(EventsLoaded( events: events, @@ -69,15 +52,6 @@ class CalendarEventsBloc extends Bloc { if (state is EventsLoaded) { final loaded = state as EventsLoaded; - final cacheKey = - '${loaded.spaceId}-${loaded.year}-${loaded.month.toString().padLeft(2, '0')}'; - - if (_eventsCache.containsKey(cacheKey)) { - final cachedEvents = - List.from(_eventsCache[cacheKey]!); - cachedEvents.add(event.event); - _eventsCache[cacheKey] = cachedEvents; - } emit(EventsLoaded( events: [...eventController.events], diff --git a/lib/pages/access_management/booking_system/presentation/model/memory_bookable_space_service.dart b/lib/pages/access_management/booking_system/presentation/model/memory_bookable_space_service.dart deleted file mode 100644 index c9017d90..00000000 --- a/lib/pages/access_management/booking_system/presentation/model/memory_bookable_space_service.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:calendar_view/calendar_view.dart'; - -class MemoryBookableSpaceService { - final Map> _eventsCache = {}; - - List? getEvents(String spaceId, int year, int month) { - final key = _generateKey(spaceId, year, month); - return _eventsCache[key]; - } - - void setEvents( - String spaceId, - int year, - int month, - List events, - ) { - final key = _generateKey(spaceId, year, month); - _eventsCache[key] = events; - } - - void addEvent(String spaceId, int year, int month, CalendarEventData event) { - final key = _generateKey(spaceId, year, month); - final events = _eventsCache[key] ?? []; - events.add(event); - _eventsCache[key] = events; - } - - void clear() { - _eventsCache.clear(); - } - - String _generateKey(String spaceId, int year, int month) { - return '$spaceId-$year-${month.toString().padLeft(2, '0')}'; - } -} \ No newline at end of file diff --git a/lib/pages/access_management/booking_system/presentation/view/booking_page.dart b/lib/pages/access_management/booking_system/presentation/view/booking_page.dart index 1030462d..b1e1ebfe 100644 --- a/lib/pages/access_management/booking_system/presentation/view/booking_page.dart +++ b/lib/pages/access_management/booking_system/presentation/view/booking_page.dart @@ -8,7 +8,7 @@ import 'package:syncrow_web/pages/access_management/booking_system/presentation/ import 'package:syncrow_web/pages/access_management/booking_system/presentation/bloc/date_selection/date_selection_event.dart'; import 'package:syncrow_web/pages/access_management/booking_system/presentation/bloc/date_selection/date_selection_state.dart'; import 'package:syncrow_web/pages/access_management/booking_system/presentation/bloc/selected_bookable_space_bloc/selected_bookable_space_bloc.dart'; -import 'package:syncrow_web/pages/access_management/booking_system/presentation/model/memory_bookable_space_service.dart'; +import 'package:syncrow_web/pages/access_management/booking_system/data/services/memory_bookable_space_service.dart'; import 'package:syncrow_web/pages/access_management/booking_system/presentation/view/widgets/booking_sidebar.dart'; import 'package:syncrow_web/pages/access_management/booking_system/presentation/view/widgets/custom_calendar_page.dart'; import 'package:syncrow_web/pages/access_management/booking_system/presentation/view/widgets/icon_text_button.dart'; @@ -65,13 +65,14 @@ class _BookingPageState extends State { BlocProvider(create: (_) => SelectedBookableSpaceBloc()), BlocProvider(create: (_) => DateSelectionBloc()), BlocProvider( - create: (_) => CalendarEventsBloc( - memoryService: MemoryBookableSpaceService(), - calendarService: RemoteCalendarService( - HTTPService(), - ), - ), - ), + create: (_) => CalendarEventsBloc( + calendarService: MemoryCalendarServiceWithRemoteFallback( + remoteService: RemoteCalendarService( + HTTPService(), + ), + memoryService: MemoryBookableSpaceService(), + ), + )), ], child: Builder( builder: (context) =>