Browse Source

fix: sort the events in each day cell by time (#2412)

* fix: sort the events in each day cell by time

* fix: reorder issue in calendar day

---------

Co-authored-by: nathan <[email protected]>
Richard Shiue 2 years ago
parent
commit
d5b70c842b

+ 0 - 2
frontend/appflowy_flutter/lib/plugins/database_view/calendar/application/calendar_bloc.dart

@@ -77,7 +77,6 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
             emit(
               state.copyWith(
                 allEvents: allEvents,
-                updateEvent: eventData,
               ),
             );
           },
@@ -380,7 +379,6 @@ class CalendarState with _$CalendarState {
     CalendarEventData<CalendarDayEvent>? createdEvent,
     CalendarEventData<CalendarDayEvent>? newEvent,
     required List<String> deleteEventIds,
-    CalendarEventData<CalendarDayEvent>? updateEvent,
     required Option<CalendarLayoutSettingsPB> settings,
     required DatabaseLoadingState loadingState,
     required Option<FlowyError> noneOrError,

+ 99 - 103
frontend/appflowy_flutter/lib/plugins/database_view/calendar/presentation/calendar_day.dart

@@ -48,14 +48,13 @@ class CalendarDayCard extends StatelessWidget {
     return ChangeNotifierProvider(
       create: (_) => _CardEnterNotifier(),
       builder: (context, child) {
-        List<GestureDetector> cards = _buildCards(context);
-
         Widget? multipleCards;
-        if (cards.isNotEmpty) {
+        if (events.isNotEmpty) {
           multipleCards = Flexible(
             child: ListView.separated(
-              itemBuilder: (BuildContext context, int index) => cards[index],
-              itemCount: cards.length,
+              itemBuilder: (BuildContext context, int index) =>
+                  _buildCard(context, events[index]),
+              itemCount: events.length,
               padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 8.0),
               separatorBuilder: (BuildContext context, int index) =>
                   VSpace(GridSize.typeOptionSeparatorHeight),
@@ -97,114 +96,111 @@ class CalendarDayCard extends StatelessWidget {
     );
   }
 
-  List<GestureDetector> _buildCards(BuildContext context) {
-    final children = events.map((CalendarDayEvent event) {
-      final cellBuilder = CardCellBuilder<String>(_rowCache.cellCache);
-      final rowInfo = _rowCache.getRow(event.eventId);
+  GestureDetector _buildCard(BuildContext context, CalendarDayEvent event) {
+    final cellBuilder = CardCellBuilder<String>(_rowCache.cellCache);
+    final rowInfo = _rowCache.getRow(event.eventId);
+
+    final renderHook = RowCardRenderHook<String>();
+    renderHook.addTextFieldHook((cellData, primaryFieldId, _) {
+      if (cellData.isEmpty) {
+        return const SizedBox();
+      }
+      return Align(
+        alignment: Alignment.centerLeft,
+        child: FlowyText.medium(
+          cellData,
+          textAlign: TextAlign.left,
+          fontSize: 11,
+          maxLines: null, // Enable multiple lines
+        ),
+      );
+    });
 
-      final renderHook = RowCardRenderHook<String>();
-      renderHook.addTextFieldHook((cellData, primaryFieldId, _) {
-        if (cellData.isEmpty) {
-          return const SizedBox();
-        }
-        return Align(
-          alignment: Alignment.centerLeft,
-          child: FlowyText.medium(
-            cellData,
-            textAlign: TextAlign.left,
-            fontSize: 11,
-            maxLines: null, // Enable multiple lines
-          ),
-        );
-      });
-
-      renderHook.addDateFieldHook((cellData, cardData, _) {
-        return Align(
-          alignment: Alignment.centerLeft,
-          child: Padding(
-            padding: const EdgeInsets.symmetric(vertical: 2),
-            child: Row(
-              children: [
-                FlowyText.regular(
-                  cellData.date,
-                  fontSize: 10,
-                  color: Theme.of(context).hintColor,
-                ),
-                const Spacer(),
-                FlowyText.regular(
-                  cellData.time,
-                  fontSize: 10,
-                  color: Theme.of(context).hintColor,
-                )
-              ],
-            ),
+    renderHook.addDateFieldHook((cellData, cardData, _) {
+      return Align(
+        alignment: Alignment.centerLeft,
+        child: Padding(
+          padding: const EdgeInsets.symmetric(vertical: 2),
+          child: Row(
+            children: [
+              FlowyText.regular(
+                cellData.date,
+                fontSize: 10,
+                color: Theme.of(context).hintColor,
+              ),
+              const Spacer(),
+              FlowyText.regular(
+                cellData.time,
+                fontSize: 10,
+                color: Theme.of(context).hintColor,
+              )
+            ],
           ),
-        );
-      });
-
-      renderHook.addSelectOptionHook((selectedOptions, cardData, _) {
-        final children = selectedOptions.map(
-          (option) {
-            return SelectOptionTag.fromOption(
-              context: context,
-              option: option,
-            );
-          },
-        ).toList();
-
-        return IntrinsicHeight(
-          child: Padding(
-            padding: const EdgeInsets.symmetric(vertical: 2),
-            child: SizedBox.expand(
-              child: Wrap(spacing: 4, runSpacing: 4, children: children),
-            ),
+        ),
+      );
+    });
+
+    renderHook.addSelectOptionHook((selectedOptions, cardData, _) {
+      final children = selectedOptions.map(
+        (option) {
+          return SelectOptionTag.fromOption(
+            context: context,
+            option: option,
+          );
+        },
+      ).toList();
+
+      return IntrinsicHeight(
+        child: Padding(
+          padding: const EdgeInsets.symmetric(vertical: 2),
+          child: SizedBox.expand(
+            child: Wrap(spacing: 4, runSpacing: 4, children: children),
           ),
-        );
-      });
-
-      // renderHook.addDateFieldHook((cellData, cardData) {
-
-      final card = RowCard<String>(
-        // Add the key here to make sure the card is rebuilt when the cells
-        // in this row are updated.
-        key: ValueKey(event.eventId),
-        row: rowInfo!.rowPB,
-        viewId: viewId,
-        rowCache: _rowCache,
-        cardData: event.fieldId,
-        isEditing: false,
-        cellBuilder: cellBuilder,
-        openCard: (context) => _showRowDetailPage(event, context),
-        styleConfiguration: const RowCardStyleConfiguration(
-          showAccessory: false,
-          cellPadding: EdgeInsets.zero,
         ),
-        renderHook: renderHook,
-        onStartEditing: () {},
-        onEndEditing: () {},
       );
+    });
 
-      return GestureDetector(
-        onTap: () => _showRowDetailPage(event, context),
-        child: MouseRegion(
-          cursor: SystemMouseCursors.click,
-          child: Container(
-            padding: const EdgeInsets.symmetric(horizontal: 2),
-            decoration: BoxDecoration(
-              border: Border.fromBorderSide(
-                BorderSide(
-                  color: Theme.of(context).dividerColor,
-                  width: 1.5,
-                ),
+    // renderHook.addDateFieldHook((cellData, cardData) {
+
+    final card = RowCard<String>(
+      // Add the key here to make sure the card is rebuilt when the cells
+      // in this row are updated.
+      key: ValueKey(event.eventId),
+      row: rowInfo!.rowPB,
+      viewId: viewId,
+      rowCache: _rowCache,
+      cardData: event.fieldId,
+      isEditing: false,
+      cellBuilder: cellBuilder,
+      openCard: (context) => _showRowDetailPage(event, context),
+      styleConfiguration: const RowCardStyleConfiguration(
+        showAccessory: false,
+        cellPadding: EdgeInsets.zero,
+      ),
+      renderHook: renderHook,
+      onStartEditing: () {},
+      onEndEditing: () {},
+    );
+
+    return GestureDetector(
+      onTap: () => _showRowDetailPage(event, context),
+      child: MouseRegion(
+        cursor: SystemMouseCursors.click,
+        child: Container(
+          padding: const EdgeInsets.symmetric(horizontal: 2),
+          decoration: BoxDecoration(
+            border: Border.fromBorderSide(
+              BorderSide(
+                color: Theme.of(context).dividerColor,
+                width: 1.5,
               ),
-              borderRadius: Corners.s6Border,
             ),
-            child: card,
+            borderRadius: Corners.s6Border,
           ),
+          child: card,
         ),
-      );
-    }).toList();
-    return children;
+      ),
+    );
   }
 
   void _showRowDetailPage(CalendarDayEvent event, BuildContext context) {

+ 6 - 14
frontend/appflowy_flutter/lib/plugins/database_view/calendar/presentation/calendar_page.dart

@@ -72,19 +72,6 @@ class _CalendarPageState extends State<CalendarPage> {
                 );
               },
             ),
-            BlocListener<CalendarBloc, CalendarState>(
-              listenWhen: (p, c) => p.updateEvent != c.updateEvent,
-              listener: (context, state) {
-                if (state.updateEvent != null) {
-                  _eventController.removeWhere(
-                    (element) =>
-                        state.updateEvent!.event!.eventId ==
-                        element.event!.eventId,
-                  );
-                  _eventController.add(state.updateEvent!);
-                }
-              },
-            ),
             BlocListener<CalendarBloc, CalendarState>(
               listenWhen: (p, c) => p.createdEvent != c.createdEvent,
               listener: (context, state) {
@@ -196,7 +183,12 @@ class _CalendarPageState extends State<CalendarPage> {
     isInMonth,
   ) {
     final events = calenderEvents.map((value) => value.event!).toList();
-
+    // Sort the events by timestamp. Because the database view is not
+    // reserving the order of the events. Reserving the order of the rows/events
+    // is implemnted in the develop branch(WIP). Will be replaced with that.
+    events.sort(
+      (a, b) => a.event.timestamp.compareTo(b.event.timestamp),
+    );
     return CalendarDayCard(
       viewId: widget.view.id,
       isToday: isToday,

+ 5 - 0
frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/card_cell.dart

@@ -12,6 +12,9 @@ typedef CellRenderHook<C, CustomCardData> = Widget? Function(
 );
 typedef RenderHookByFieldType<C> = Map<FieldType, CellRenderHook<dynamic, C>>;
 
+/// The [RowCardRenderHook] is used to customize the rendering of the
+///  card cell. Each cell has itw own field type. So the [renderHook]
+///  is a map of [FieldType] to [CellRenderHook].
 class RowCardRenderHook<CustomCardData> {
   final RenderHookByFieldType<CustomCardData> renderHook = {};
   RowCardRenderHook();
@@ -25,12 +28,14 @@ class RowCardRenderHook<CustomCardData> {
     renderHook[FieldType.MultiSelect] = hookFn;
   }
 
+  /// Add a render hook for the [FieldType.RichText]
   void addTextFieldHook(
     CellRenderHook<String, CustomCardData?> hook,
   ) {
     renderHook[FieldType.RichText] = _typeSafeHook<String>(hook);
   }
 
+  /// Add a render hook for the [FieldType.Date]
   void addDateFieldHook(
     CellRenderHook<DateCellDataPB, CustomCardData?> hook,
   ) {