mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: merge remote-tracking branch 'main' into develop (#2530)
* feat: show unscheduled events in calendar toolbar (#2411)
* refactor: use same show row detail function
* fix: adjust popover offset
* feat: show unscheduled events in toolbar
* chore: apply suggestions from Xazin
* refactor: refactor list item into separate widget
---------
Co-authored-by: Nathan.fooo <86001920+appflowy@users.noreply.github.com>
* fix: default include time (#2444)
* fix: default include time
* chore: clarify logic and add comments
* chore: bump version 0.1.4 (#2455)
* chore: Update README.md
Update product screenshots
* fix: wrong day of week (#2468)
* feat: select which properties to show in calendar (#2482)
* feat: improve sidebar item dragged appearance (#2471)
* fix: show delete icon for document icon properly (#2475)
* feat: add hover effect on an event card (#2487)
* chore: delete unncessary openCard method in RowCardContainer
* chore: delete unnessary code and add comment
* chore: update editor v0.1.12 and format the readme (#2489)
* fix: number sort (#2507)
* bump version 0.1.5 (#2506)
* chore: bump version 0.1.5
* fix: could not trigger slash menu after inserting an emoji
* Revert "feat: add hover effect on an event card (#2487)"
This reverts commit f0a4b4b77d
.
* feat: add hover effect on an event card
* fix: #2469 duplicated cover
* chore: update changelog.md (#2510)
* chore: Update README.md
Add a screenshot of the calendar view
* fix: some regressions
---------
Co-authored-by: Nathan.fooo <86001920+appflowy@users.noreply.github.com>
Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
Co-authored-by: Annie <anqi.annie.wang@gmail.com>
Co-authored-by: Yijing Huang <hyj891204@gmail.com>
This commit is contained in:
@ -51,5 +51,6 @@ class CalendarSettingEvent with _$CalendarSettingEvent {
|
||||
}
|
||||
|
||||
enum CalendarSettingAction {
|
||||
properties,
|
||||
layout,
|
||||
}
|
||||
|
@ -1,24 +1,23 @@
|
||||
import 'package:appflowy/plugins/database_view/application/row/row_cache.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/row/row_data_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/card/card.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/card/card_cell_builder.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/card/cells/card_cell.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/card/cells/number_card_cell.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/card/cells/url_card_cell.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/cell_builder.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/row_detail.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../grid/presentation/layout/sizes.dart';
|
||||
import '../../widgets/row/cells/select_option_cell/extension.dart';
|
||||
import '../application/calendar_bloc.dart';
|
||||
import 'calendar_page.dart';
|
||||
|
||||
class CalendarDayCard extends StatelessWidget {
|
||||
final String viewId;
|
||||
@ -102,7 +101,7 @@ class CalendarDayCard extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
GestureDetector _buildCard(BuildContext context, CalendarDayEvent event) {
|
||||
Widget _buildCard(BuildContext context, CalendarDayEvent event) {
|
||||
final styles = <FieldType, CardCellStyle>{
|
||||
FieldType.Number: NumberCardCellStyle(10),
|
||||
FieldType.URL: URLCardCellStyle(10),
|
||||
@ -193,7 +192,12 @@ class CalendarDayCard extends StatelessWidget {
|
||||
cardData: event.dateFieldId,
|
||||
isEditing: false,
|
||||
cellBuilder: cellBuilder,
|
||||
openCard: (context) => _showRowDetailPage(event, context),
|
||||
openCard: (context) => showEventDetails(
|
||||
context: context,
|
||||
event: event,
|
||||
viewId: viewId,
|
||||
rowCache: _rowCache,
|
||||
),
|
||||
styleConfiguration: const RowCardStyleConfiguration(
|
||||
showAccessory: false,
|
||||
cellPadding: EdgeInsets.zero,
|
||||
@ -203,44 +207,24 @@ class CalendarDayCard extends StatelessWidget {
|
||||
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,
|
||||
),
|
||||
return FlowyHover(
|
||||
style: HoverStyle(
|
||||
hoverColor: Theme.of(context).colorScheme.tertiaryContainer,
|
||||
foregroundColorOnHover: Theme.of(context).colorScheme.onBackground,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showRowDetailPage(CalendarDayEvent event, BuildContext context) {
|
||||
final dataController = RowController(
|
||||
rowId: event.eventId,
|
||||
viewId: viewId,
|
||||
rowCache: _rowCache,
|
||||
);
|
||||
|
||||
FlowyOverlay.show(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return RowDetailPage(
|
||||
cellBuilder: GridCellBuilder(
|
||||
cellCache: _rowCache.cellCache,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 2),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.fromBorderSide(
|
||||
BorderSide(
|
||||
color: Theme.of(context).dividerColor,
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
dataController: dataController,
|
||||
);
|
||||
},
|
||||
borderRadius: Corners.s6Border,
|
||||
),
|
||||
child: card,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../application/row/row_cache.dart';
|
||||
import '../../application/row/row_data_controller.dart';
|
||||
import '../../widgets/row/cell_builder.dart';
|
||||
import '../../widgets/row/row_detail.dart';
|
||||
@ -76,7 +77,12 @@ class _CalendarPageState extends State<CalendarPage> {
|
||||
listenWhen: (p, c) => p.editEvent != c.editEvent,
|
||||
listener: (context, state) {
|
||||
if (state.editEvent != null) {
|
||||
_showEditEventPage(state.editEvent!.event!, context);
|
||||
showEventDetails(
|
||||
context: context,
|
||||
event: state.editEvent!.event!,
|
||||
viewId: widget.view.id,
|
||||
rowCache: _calendarBloc.rowCache,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
@ -165,8 +171,9 @@ class _CalendarPageState extends State<CalendarPage> {
|
||||
}
|
||||
|
||||
Widget _headerWeekDayBuilder(day) {
|
||||
// incoming day starts from Monday, the symbols start from Sunday
|
||||
final symbols = DateFormat.EEEE(context.locale.toLanguageTag()).dateSymbols;
|
||||
final weekDayString = symbols.WEEKDAYS[day];
|
||||
final weekDayString = symbols.WEEKDAYS[(day + 1) % 7];
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: CalendarSize.daysOfWeekInsets,
|
||||
@ -210,27 +217,32 @@ class _CalendarPageState extends State<CalendarPage> {
|
||||
}
|
||||
|
||||
WeekDays _weekdayFromInt(int dayOfWeek) {
|
||||
// MonthView places the first day of week on the second column for some reason.
|
||||
return WeekDays.values[(dayOfWeek + 1) % 7];
|
||||
}
|
||||
|
||||
void _showEditEventPage(CalendarDayEvent event, BuildContext context) {
|
||||
final dataController = RowController(
|
||||
rowId: event.eventId,
|
||||
viewId: widget.view.id,
|
||||
rowCache: _calendarBloc.rowCache,
|
||||
);
|
||||
|
||||
FlowyOverlay.show(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return RowDetailPage(
|
||||
cellBuilder: GridCellBuilder(
|
||||
cellCache: _calendarBloc.rowCache.cellCache,
|
||||
),
|
||||
dataController: dataController,
|
||||
);
|
||||
},
|
||||
);
|
||||
// dayOfWeek starts from Sunday, WeekDays starts from Monday
|
||||
return WeekDays.values[(dayOfWeek - 1) % 7];
|
||||
}
|
||||
}
|
||||
|
||||
void showEventDetails({
|
||||
required BuildContext context,
|
||||
required CalendarDayEvent event,
|
||||
required String viewId,
|
||||
required RowCache rowCache,
|
||||
}) {
|
||||
final dataController = RowController(
|
||||
rowId: event.eventId,
|
||||
viewId: viewId,
|
||||
rowCache: rowCache,
|
||||
);
|
||||
|
||||
FlowyOverlay.show(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return RowDetailPage(
|
||||
cellBuilder: GridCellBuilder(
|
||||
cellCache: rowCache.cellCache,
|
||||
),
|
||||
dataController: dataController,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -216,6 +216,7 @@ class LayoutDateField extends StatelessWidget {
|
||||
direction: PopoverDirection.leftWithTopAligned,
|
||||
constraints: BoxConstraints.loose(const Size(300, 400)),
|
||||
mutex: popoverMutex,
|
||||
offset: const Offset(-16, 0),
|
||||
popupBuilder: (context) {
|
||||
return BlocProvider(
|
||||
create: (context) => getIt<DatabasePropertyBloc>(
|
||||
@ -236,9 +237,9 @@ class LayoutDateField extends StatelessWidget {
|
||||
onUpdated(fieldInfo.id);
|
||||
popoverMutex.close();
|
||||
},
|
||||
leftIcon: svgWidget('grid/field/date'),
|
||||
leftIcon: const FlowySvg(name: 'grid/field/date'),
|
||||
rightIcon: fieldInfo.id == fieldId
|
||||
? svgWidget('grid/checkmark')
|
||||
? const FlowySvg(name: 'grid/checkmark')
|
||||
: null,
|
||||
),
|
||||
);
|
||||
@ -332,12 +333,13 @@ class FirstDayOfWeek extends StatelessWidget {
|
||||
direction: PopoverDirection.leftWithTopAligned,
|
||||
constraints: BoxConstraints.loose(const Size(300, 400)),
|
||||
mutex: popoverMutex,
|
||||
offset: const Offset(-16, 0),
|
||||
popupBuilder: (context) {
|
||||
final symbols =
|
||||
DateFormat.EEEE(context.locale.toLanguageTag()).dateSymbols;
|
||||
// starts from sunday
|
||||
final items = symbols.WEEKDAYS.asMap().entries.map((entry) {
|
||||
final index = (entry.key - 1) % 7;
|
||||
final index = entry.key;
|
||||
final string = entry.value;
|
||||
return SizedBox(
|
||||
height: GridSize.popoverItemHeight,
|
||||
@ -347,8 +349,9 @@ class FirstDayOfWeek extends StatelessWidget {
|
||||
onUpdated(index);
|
||||
popoverMutex.close();
|
||||
},
|
||||
rightIcon:
|
||||
firstDayOfWeek == index ? svgWidget('grid/checkmark') : null,
|
||||
rightIcon: firstDayOfWeek == index
|
||||
? const FlowySvg(name: 'grid/checkmark')
|
||||
: null,
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
|
@ -2,8 +2,10 @@ import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/calendar/application/calendar_setting_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/toolbar/grid_property.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
@ -38,6 +40,11 @@ class CalendarSetting extends StatelessWidget {
|
||||
final CalendarSettingAction? action =
|
||||
state.selectedAction.foldLeft(null, (previous, action) => action);
|
||||
switch (action) {
|
||||
case CalendarSettingAction.properties:
|
||||
return GridPropertyList(
|
||||
viewId: settingContext.viewId,
|
||||
fieldController: settingContext.fieldController,
|
||||
);
|
||||
case CalendarSettingAction.layout:
|
||||
return CalendarLayoutSetting(
|
||||
onUpdated: onUpdated,
|
||||
@ -78,9 +85,16 @@ class AllCalendarSettings extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _settingItem(BuildContext context, CalendarSettingAction action) {
|
||||
Widget? icon;
|
||||
if (action.iconName() != null) {
|
||||
icon = FlowySvg(
|
||||
name: action.iconName()!,
|
||||
);
|
||||
}
|
||||
return SizedBox(
|
||||
height: GridSize.popoverItemHeight,
|
||||
child: FlowyButton(
|
||||
leftIcon: icon,
|
||||
text: FlowyText.medium(action.title()),
|
||||
onTap: () {
|
||||
context
|
||||
@ -93,8 +107,19 @@ class AllCalendarSettings extends StatelessWidget {
|
||||
}
|
||||
|
||||
extension _SettingExtension on CalendarSettingAction {
|
||||
String? iconName() {
|
||||
switch (this) {
|
||||
case CalendarSettingAction.properties:
|
||||
return 'grid/setting/properties';
|
||||
case CalendarSettingAction.layout:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
String title() {
|
||||
switch (this) {
|
||||
case CalendarSettingAction.properties:
|
||||
return LocaleKeys.grid_settings_Properties.tr();
|
||||
case CalendarSettingAction.layout:
|
||||
return LocaleKeys.grid_settings_layout.tr();
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/calendar/presentation/calendar_page.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:calendar_view/calendar_view.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
@ -19,7 +21,8 @@ class CalendarToolbar extends StatelessWidget {
|
||||
height: 40,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
children: const [
|
||||
_UnscheduleEventsButton(),
|
||||
_SettingButton(),
|
||||
],
|
||||
),
|
||||
@ -28,25 +31,22 @@ class CalendarToolbar extends StatelessWidget {
|
||||
}
|
||||
|
||||
class _SettingButton extends StatefulWidget {
|
||||
const _SettingButton({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _SettingButtonState();
|
||||
}
|
||||
|
||||
class _SettingButtonState extends State<_SettingButton> {
|
||||
late PopoverController popoverController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
popoverController = PopoverController();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppFlowyPopover(
|
||||
controller: popoverController,
|
||||
direction: PopoverDirection.bottomWithRightAligned,
|
||||
triggerActions: PopoverTriggerFlags.none,
|
||||
constraints: BoxConstraints.loose(const Size(300, 400)),
|
||||
margin: EdgeInsets.zero,
|
||||
child: FlowyTextButton(
|
||||
@ -54,7 +54,6 @@ class _SettingButtonState extends State<_SettingButton> {
|
||||
fillColor: Colors.transparent,
|
||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||
padding: GridSize.typeOptionContentInsets,
|
||||
onPressed: () => popoverController.show(),
|
||||
),
|
||||
popupBuilder: (BuildContext popoverContext) {
|
||||
final bloc = context.watch<CalendarBloc>();
|
||||
@ -81,3 +80,100 @@ class _SettingButtonState extends State<_SettingButton> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _UnscheduleEventsButton extends StatefulWidget {
|
||||
const _UnscheduleEventsButton({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<_UnscheduleEventsButton> createState() =>
|
||||
_UnscheduleEventsButtonState();
|
||||
}
|
||||
|
||||
class _UnscheduleEventsButtonState extends State<_UnscheduleEventsButton> {
|
||||
late final PopoverController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = PopoverController();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<CalendarBloc, CalendarState>(
|
||||
builder: (context, state) {
|
||||
final unscheduledEvents = state.allEvents
|
||||
.where((e) => e.date == DateTime.fromMillisecondsSinceEpoch(0))
|
||||
.toList();
|
||||
final viewId = context.read<CalendarBloc>().viewId;
|
||||
final rowCache = context.read<CalendarBloc>().rowCache;
|
||||
return AppFlowyPopover(
|
||||
direction: PopoverDirection.bottomWithCenterAligned,
|
||||
controller: _controller,
|
||||
offset: const Offset(0, 8),
|
||||
child: FlowyTextButton(
|
||||
"${LocaleKeys.calendar_settings_noDateTitle.tr()} (${unscheduledEvents.length})",
|
||||
fillColor: Colors.transparent,
|
||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||
padding: GridSize.typeOptionContentInsets,
|
||||
),
|
||||
popupBuilder: (context) {
|
||||
if (unscheduledEvents.isEmpty) {
|
||||
return SizedBox(
|
||||
height: GridSize.popoverItemHeight,
|
||||
child: Center(
|
||||
child: FlowyText.medium(
|
||||
LocaleKeys.calendar_settings_emptyNoDate.tr(),
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return ListView.separated(
|
||||
itemBuilder: (context, index) => _UnscheduledEventItem(
|
||||
event: unscheduledEvents[index],
|
||||
onPressed: () {
|
||||
showEventDetails(
|
||||
context: context,
|
||||
event: unscheduledEvents[index].event!,
|
||||
viewId: viewId,
|
||||
rowCache: rowCache,
|
||||
);
|
||||
_controller.close();
|
||||
},
|
||||
),
|
||||
itemCount: unscheduledEvents.length,
|
||||
separatorBuilder: (context, index) =>
|
||||
VSpace(GridSize.typeOptionSeparatorHeight),
|
||||
shrinkWrap: true,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _UnscheduledEventItem extends StatelessWidget {
|
||||
final CalendarEventData<CalendarDayEvent> event;
|
||||
final VoidCallback onPressed;
|
||||
const _UnscheduledEventItem({
|
||||
required this.event,
|
||||
required this.onPressed,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: GridSize.popoverItemHeight,
|
||||
child: FlowyTextButton(
|
||||
event.title,
|
||||
fillColor: Colors.transparent,
|
||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||
padding: GridSize.typeOptionContentInsets,
|
||||
onPressed: onPressed,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ class RowCardContainer extends StatelessWidget {
|
||||
}
|
||||
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () => openCard(context),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
|
@ -75,7 +75,7 @@ class DateCellCalendarBloc
|
||||
String? time,
|
||||
bool? includeTime,
|
||||
}) async {
|
||||
// make sure date and time are not updated together from the UI
|
||||
// make sure that not both date and time are updated at the same time
|
||||
assert(
|
||||
date == null && time == null ||
|
||||
date == null && time != null ||
|
||||
@ -83,7 +83,7 @@ class DateCellCalendarBloc
|
||||
);
|
||||
String? newTime = time ?? state.time;
|
||||
|
||||
DateTime? newDate = date;
|
||||
DateTime? newDate = _utcToLocalAddTime(date);
|
||||
if (time != null && time.isNotEmpty) {
|
||||
newDate = state.dateTime ?? DateTime.now();
|
||||
}
|
||||
@ -122,6 +122,24 @@ class DateCellCalendarBloc
|
||||
);
|
||||
}
|
||||
|
||||
DateTime? _utcToLocalAddTime(DateTime? date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
final now = DateTime.now();
|
||||
// the incoming date is Utc. this trick converts it into Local
|
||||
// and add the current time, though the time may be overwritten by
|
||||
// explicitly provided time string
|
||||
return DateTime(
|
||||
date.year,
|
||||
date.month,
|
||||
date.day,
|
||||
now.hour,
|
||||
now.minute,
|
||||
now.second,
|
||||
);
|
||||
}
|
||||
|
||||
String timeFormatPrompt(FlowyError error) {
|
||||
String msg = "${LocaleKeys.grid_field_invalidTimeFormat.tr()}.";
|
||||
switch (state.dateTypeOptionPB.timeFormat) {
|
||||
|
@ -115,8 +115,11 @@ class _CellCalendarWidgetState extends State<_CellCalendarWidget> {
|
||||
AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: state.includeTime
|
||||
? _TimeTextField(popoverMutex: popoverMutex)
|
||||
: const SizedBox(),
|
||||
? _TimeTextField(
|
||||
timeStr: state.time,
|
||||
popoverMutex: popoverMutex,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
const TypeOptionSeparator(spacing: 12.0),
|
||||
const _IncludeTimeButton(),
|
||||
@ -265,9 +268,11 @@ class _IncludeTimeButton extends StatelessWidget {
|
||||
}
|
||||
|
||||
class _TimeTextField extends StatefulWidget {
|
||||
final String? timeStr;
|
||||
final PopoverMutex popoverMutex;
|
||||
|
||||
const _TimeTextField({
|
||||
required this.timeStr,
|
||||
required this.popoverMutex,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
@ -278,10 +283,12 @@ class _TimeTextField extends StatefulWidget {
|
||||
|
||||
class _TimeTextFieldState extends State<_TimeTextField> {
|
||||
late final FocusNode _focusNode;
|
||||
late final TextEditingController _textController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_focusNode = FocusNode();
|
||||
_textController = TextEditingController()..text = widget.timeStr ?? "";
|
||||
|
||||
_focusNode.addListener(() {
|
||||
if (_focusNode.hasFocus) {
|
||||
@ -300,7 +307,8 @@ class _TimeTextFieldState extends State<_TimeTextField> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<DateCellCalendarBloc, DateCellCalendarState>(
|
||||
return BlocConsumer<DateCellCalendarBloc, DateCellCalendarState>(
|
||||
listener: (context, state) => _textController.text = state.time ?? "",
|
||||
builder: (context, state) {
|
||||
return Column(
|
||||
children: [
|
||||
@ -310,13 +318,14 @@ class _TimeTextFieldState extends State<_TimeTextField> {
|
||||
child: FlowyTextField(
|
||||
text: state.time ?? "",
|
||||
focusNode: _focusNode,
|
||||
controller: _textController,
|
||||
submitOnLeave: true,
|
||||
hintText: state.timeHintText,
|
||||
errorText: state.timeFormatError,
|
||||
onSubmitted: (timeString) {
|
||||
onSubmitted: (timeStr) {
|
||||
context
|
||||
.read<DateCellCalendarBloc>()
|
||||
.add(DateCellCalendarEvent.setTime(timeString));
|
||||
.add(DateCellCalendarEvent.setTime(timeStr));
|
||||
},
|
||||
),
|
||||
),
|
||||
|
Reference in New Issue
Block a user