浏览代码

chore: config caladen ui

appflowy 3 年之前
父节点
当前提交
d3841154a5

+ 0 - 0
frontend/app_flowy/assets/images/editor/clock_alarm.svg → frontend/app_flowy/assets/images/grid/clock.svg


+ 12 - 2
frontend/app_flowy/lib/workspace/application/grid/cell/date_cal_bloc.dart

@@ -28,7 +28,7 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
               emit(state.copyWith(selectedDay: value.day));
             }
           },
-          setFormat: (_CalendarFormat value) {
+          setCalFormat: (_CalendarFormat value) {
             emit(state.copyWith(format: value.format));
           },
           setFocusedDay: (_FocusedDay value) {
@@ -38,6 +38,11 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
           didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) {
             emit(state.copyWith(field: value.field));
           },
+          setIncludeTime: (_IncludeTime value) {
+            emit(state.copyWith(includeTime: value.includeTime));
+          },
+          setDateFormat: (_DateFormat value) {},
+          setTimeFormat: (_TimeFormat value) {},
         );
       },
     );
@@ -97,8 +102,11 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
 class DateCalEvent with _$DateCalEvent {
   const factory DateCalEvent.initial() = _Initial;
   const factory DateCalEvent.selectDay(DateTime day) = _SelectDay;
-  const factory DateCalEvent.setFormat(CalendarFormat format) = _CalendarFormat;
+  const factory DateCalEvent.setCalFormat(CalendarFormat format) = _CalendarFormat;
   const factory DateCalEvent.setFocusedDay(DateTime day) = _FocusedDay;
+  const factory DateCalEvent.setTimeFormat(TimeFormat value) = _TimeFormat;
+  const factory DateCalEvent.setDateFormat(DateFormat value) = _DateFormat;
+  const factory DateCalEvent.setIncludeTime(bool includeTime) = _IncludeTime;
   const factory DateCalEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate;
   const factory DateCalEvent.didReceiveFieldUpdate(Field field) = _DidReceiveFieldUpdate;
 }
@@ -111,6 +119,7 @@ class DateCalState with _$DateCalState {
     required CalendarFormat format,
     required DateTime focusedDay,
     required bool includeTime,
+    required Option<String> time,
     DateTime? selectedDay,
   }) = _DateCalState;
 
@@ -120,5 +129,6 @@ class DateCalState with _$DateCalState {
         format: CalendarFormat.month,
         focusedDay: DateTime.now(),
         includeTime: false,
+        time: none(),
       );
 }

+ 181 - 39
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell/calendar.dart

@@ -1,6 +1,15 @@
+import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:app_flowy/workspace/application/grid/cell/date_cal_bloc.dart';
+import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/flowy_infra_ui.dart';
+import 'package:flowy_infra_ui/style_widget/button.dart';
+import 'package:flowy_infra_ui/style_widget/text.dart';
+import 'package:flowy_infra_ui/widget/spacing.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
+import 'package:flutter/material.dart';
 import 'package:flutter/widgets.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:table_calendar/table_calendar.dart';
@@ -9,6 +18,7 @@ import 'package:app_flowy/workspace/application/grid/prelude.dart';
 final kToday = DateTime.now();
 final kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day);
 final kLastDay = DateTime(kToday.year, kToday.month + 3, kToday.day);
+const kMargin = EdgeInsets.symmetric(horizontal: 6, vertical: 10);
 
 class CellCalendar with FlowyOverlayDelegate {
   final VoidCallback onDismissed;
@@ -47,7 +57,7 @@ class CellCalendar with FlowyOverlayDelegate {
     FlowyOverlay.of(context).insertWithAnchor(
       widget: OverlayContainer(
         child: calendar,
-        constraints: BoxConstraints.tight(const Size(320, 320)),
+        constraints: BoxConstraints.tight(const Size(320, 500)),
       ),
       identifier: CellCalendar.identifier(),
       anchorContext: context,
@@ -67,6 +77,9 @@ class CellCalendar with FlowyOverlayDelegate {
 
   @override
   void didRemove() => onDismissed();
+
+  @override
+  bool asBarrier() => true;
 }
 
 class _CellCalendarWidget extends StatelessWidget {
@@ -94,46 +107,175 @@ class _CellCalendarWidget extends StatelessWidget {
         },
         listenWhen: (p, c) => p.selectedDay != c.selectedDay,
         builder: (context, state) {
-          return TableCalendar(
-            firstDay: kFirstDay,
-            lastDay: kLastDay,
-            focusedDay: state.focusedDay,
-            rowHeight: 40,
-            calendarFormat: state.format,
-            headerStyle: const HeaderStyle(formatButtonVisible: false),
-            calendarStyle: CalendarStyle(
-              selectedDecoration: BoxDecoration(
-                color: theme.main1,
-                shape: BoxShape.circle,
-              ),
-              todayDecoration: BoxDecoration(
-                color: theme.shader4,
-                shape: BoxShape.circle,
-              ),
-              selectedTextStyle: TextStyle(
-                color: theme.surface,
-                fontSize: 14.0,
-              ),
-              todayTextStyle: TextStyle(
-                color: theme.surface,
-                fontSize: 14.0,
-              ),
-            ),
-            selectedDayPredicate: (day) {
-              return isSameDay(state.selectedDay, day);
-            },
-            onDaySelected: (selectedDay, focusedDay) {
-              context.read<DateCalBloc>().add(DateCalEvent.selectDay(selectedDay));
-            },
-            onFormatChanged: (format) {
-              context.read<DateCalBloc>().add(DateCalEvent.setFormat(format));
-            },
-            onPageChanged: (focusedDay) {
-              context.read<DateCalBloc>().add(DateCalEvent.setFocusedDay(focusedDay));
-            },
-          );
+          List<Widget> children = [];
+
+          children.addAll([
+            _buildCalendar(state, theme, context),
+            const VSpace(10),
+          ]);
+
+          if (state.includeTime) {
+            children.addAll([
+              const _TimeTextField(),
+              const VSpace(10),
+            ]);
+          }
+
+          children.addAll([
+            Divider(height: 1, color: theme.shader5),
+            const _IncludeTimeButton(),
+          ]);
+
+          state.typeOptinoData.fold(() => null, (dateTypeOption) {
+            children.add(_DateTypeOptionButton(dateTypeOption: dateTypeOption));
+          });
+
+          return Column(children: children);
         },
       ),
     );
   }
+
+  TableCalendar<dynamic> _buildCalendar(DateCalState state, AppTheme theme, BuildContext context) {
+    return TableCalendar(
+      firstDay: kFirstDay,
+      lastDay: kLastDay,
+      focusedDay: state.focusedDay,
+      rowHeight: 40,
+      calendarFormat: state.format,
+      headerStyle: HeaderStyle(
+        formatButtonVisible: false,
+        titleCentered: true,
+        leftChevronMargin: EdgeInsets.zero,
+        leftChevronPadding: EdgeInsets.zero,
+        leftChevronIcon: svgWidget("home/arrow_left"),
+        rightChevronPadding: EdgeInsets.zero,
+        rightChevronMargin: EdgeInsets.zero,
+        rightChevronIcon: svgWidget("home/arrow_right"),
+      ),
+      calendarStyle: CalendarStyle(
+        selectedDecoration: BoxDecoration(
+          color: theme.main1,
+          shape: BoxShape.circle,
+        ),
+        todayDecoration: BoxDecoration(
+          color: theme.shader4,
+          shape: BoxShape.circle,
+        ),
+        selectedTextStyle: TextStyle(
+          color: theme.surface,
+          fontSize: 14.0,
+        ),
+        todayTextStyle: TextStyle(
+          color: theme.surface,
+          fontSize: 14.0,
+        ),
+      ),
+      selectedDayPredicate: (day) {
+        return isSameDay(state.selectedDay, day);
+      },
+      onDaySelected: (selectedDay, focusedDay) {
+        context.read<DateCalBloc>().add(DateCalEvent.selectDay(selectedDay));
+      },
+      onFormatChanged: (format) {
+        context.read<DateCalBloc>().add(DateCalEvent.setCalFormat(format));
+      },
+      onPageChanged: (focusedDay) {
+        context.read<DateCalBloc>().add(DateCalEvent.setFocusedDay(focusedDay));
+      },
+    );
+  }
+}
+
+class _IncludeTimeButton extends StatelessWidget {
+  const _IncludeTimeButton({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    final theme = context.watch<AppTheme>();
+    return BlocSelector<DateCalBloc, DateCalState, bool>(
+      selector: (state) => state.includeTime,
+      builder: (context, includeTime) {
+        return SizedBox(
+          height: 50,
+          child: Padding(
+            padding: kMargin,
+            child: Row(
+              children: [
+                svgWidget("grid/clock", color: theme.iconColor),
+                const HSpace(4),
+                FlowyText.medium(LocaleKeys.grid_field_includeTime.tr(), fontSize: 14),
+                const Spacer(),
+                Switch(
+                  value: includeTime,
+                  onChanged: (newValue) => context.read<DateCalBloc>().add(DateCalEvent.setIncludeTime(newValue)),
+                ),
+              ],
+            ),
+          ),
+        );
+      },
+    );
+  }
+}
+
+class _TimeTextField extends StatelessWidget {
+  const _TimeTextField({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Container();
+  }
+}
+
+class _DateTypeOptionButton extends StatelessWidget {
+  final DateTypeOption dateTypeOption;
+  const _DateTypeOptionButton({required this.dateTypeOption, Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    final theme = context.watch<AppTheme>();
+    final title = LocaleKeys.grid_field_dateFormat.tr() + " &" + LocaleKeys.grid_field_timeFormat.tr();
+    return FlowyButton(
+      text: FlowyText.medium(title, fontSize: 12),
+      hoverColor: theme.hover,
+      margin: kMargin,
+      onTap: () {
+        final setting = _CalDateTimeSetting(dateTypeOption: dateTypeOption);
+        setting.show(context);
+      },
+      rightIcon: svgWidget("grid/more", color: theme.iconColor),
+    );
+  }
+}
+
+class _CalDateTimeSetting extends StatelessWidget {
+  final DateTypeOption dateTypeOption;
+  const _CalDateTimeSetting({required this.dateTypeOption, Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(children: [
+      DateFormatButton(onTap: () {
+        final list = DateFormatList(
+          selectedFormat: dateTypeOption.dateFormat,
+          onSelected: (format) {
+            context.read<DateTypeOptionBloc>().add(DateTypeOptionEvent.didSelectDateFormat(format));
+          },
+        );
+      }),
+      TimeFormatButton(
+        timeFormat: dateTypeOption.timeFormat,
+        onTap: () {
+          final list = TimeFormatList(
+              selectedFormat: dateTypeOption.timeFormat,
+              onSelected: (format) {
+                context.read<DateTypeOptionBloc>().add(DateTypeOptionEvent.didSelectTimeFormat(format));
+              });
+        },
+      ),
+    ]);
+  }
+
+  void show(BuildContext context) {}
 }

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart

@@ -150,7 +150,7 @@ class FieldCellButton extends StatelessWidget {
       onTap: onTap,
       leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor),
       text: FlowyText.medium(field.name, fontSize: 12),
-      padding: GridSize.cellContentInsets,
+      margin: GridSize.cellContentInsets,
     );
   }
 }

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart

@@ -80,7 +80,7 @@ class _FieldEditorPannelState extends State<FieldEditorPannel> {
       height: GridSize.typeOptionItemHeight,
       child: FlowyButton(
         text: FlowyText.medium(field.fieldType.title(), fontSize: 12),
-        padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
+        margin: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
         hoverColor: theme.hover,
         onTap: () {
           final list = FieldTypeList(onSelectField: (newFieldType) {

+ 47 - 23
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart

@@ -50,8 +50,8 @@ class DateTypeOptionWidget extends TypeOptionWidget {
         listener: (context, state) => dataDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()),
         builder: (context, state) {
           return Column(children: [
-            _dateFormatButton(context, state.typeOption.dateFormat),
-            _timeFormatButton(context, state.typeOption.timeFormat),
+            _renderDateFormatButton(context, state.typeOption.dateFormat),
+            _renderTimeFormatButton(context, state.typeOption.timeFormat),
             const _IncludeTimeButton(),
           ]);
         },
@@ -59,44 +59,68 @@ class DateTypeOptionWidget extends TypeOptionWidget {
     );
   }
 
-  Widget _dateFormatButton(BuildContext context, DateFormat dataFormat) {
+  Widget _renderDateFormatButton(BuildContext context, DateFormat dataFormat) {
+    return DateFormatButton(onTap: () {
+      final list = DateFormatList(
+        selectedFormat: dataFormat,
+        onSelected: (format) {
+          context.read<DateTypeOptionBloc>().add(DateTypeOptionEvent.didSelectDateFormat(format));
+        },
+      );
+      overlayDelegate.showOverlay(context, list);
+    });
+  }
+
+  Widget _renderTimeFormatButton(BuildContext context, TimeFormat timeFormat) {
+    return TimeFormatButton(
+      timeFormat: timeFormat,
+      onTap: () {
+        final list = TimeFormatList(
+            selectedFormat: timeFormat,
+            onSelected: (format) {
+              context.read<DateTypeOptionBloc>().add(DateTypeOptionEvent.didSelectTimeFormat(format));
+            });
+        overlayDelegate.showOverlay(context, list);
+      },
+    );
+  }
+}
+
+class DateFormatButton extends StatelessWidget {
+  final VoidCallback onTap;
+  const DateFormatButton({required this.onTap, Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
     return SizedBox(
       height: GridSize.typeOptionItemHeight,
       child: FlowyButton(
         text: FlowyText.medium(LocaleKeys.grid_field_dateFormat.tr(), fontSize: 12),
-        padding: GridSize.typeOptionContentInsets,
+        margin: GridSize.typeOptionContentInsets,
         hoverColor: theme.hover,
-        onTap: () {
-          final list = DateFormatList(
-            selectedFormat: dataFormat,
-            onSelected: (format) {
-              context.read<DateTypeOptionBloc>().add(DateTypeOptionEvent.didSelectDateFormat(format));
-            },
-          );
-          overlayDelegate.showOverlay(context, list);
-        },
+        onTap: onTap,
         rightIcon: svgWidget("grid/more", color: theme.iconColor),
       ),
     );
   }
+}
 
-  Widget _timeFormatButton(BuildContext context, TimeFormat timeFormat) {
+class TimeFormatButton extends StatelessWidget {
+  final TimeFormat timeFormat;
+  final VoidCallback onTap;
+  const TimeFormatButton({required this.timeFormat, required this.onTap, Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
     return SizedBox(
       height: GridSize.typeOptionItemHeight,
       child: FlowyButton(
         text: FlowyText.medium(LocaleKeys.grid_field_timeFormat.tr(), fontSize: 12),
-        padding: GridSize.typeOptionContentInsets,
+        margin: GridSize.typeOptionContentInsets,
         hoverColor: theme.hover,
-        onTap: () {
-          final list = TimeFormatList(
-              selectedFormat: timeFormat,
-              onSelected: (format) {
-                context.read<DateTypeOptionBloc>().add(DateTypeOptionEvent.didSelectTimeFormat(format));
-              });
-          overlayDelegate.showOverlay(context, list);
-        },
+        onTap: onTap,
         rightIcon: svgWidget("grid/more", color: theme.iconColor),
       ),
     );

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart

@@ -60,7 +60,7 @@ class NumberTypeOptionWidget extends TypeOptionWidget {
                   FlowyText.regular(state.typeOption.format.title(), fontSize: 12),
                 ],
               ),
-              padding: GridSize.typeOptionContentInsets,
+              margin: GridSize.typeOptionContentInsets,
               hoverColor: theme.hover,
               onTap: () {
                 final list = NumberFormatList(

+ 3 - 3
frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart

@@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
 class FlowyButton extends StatelessWidget {
   final Widget text;
   final VoidCallback? onTap;
-  final EdgeInsets padding;
+  final EdgeInsets margin;
   final Widget? leftIcon;
   final Widget? rightIcon;
   final Color hoverColor;
@@ -16,7 +16,7 @@ class FlowyButton extends StatelessWidget {
     Key? key,
     required this.text,
     this.onTap,
-    this.padding = const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
+    this.margin = const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
     this.leftIcon,
     this.rightIcon,
     this.hoverColor = Colors.transparent,
@@ -50,7 +50,7 @@ class FlowyButton extends StatelessWidget {
     }
 
     return Padding(
-      padding: padding,
+      padding: margin,
       child: Row(
         mainAxisAlignment: MainAxisAlignment.center,
         crossAxisAlignment: CrossAxisAlignment.center,