mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: config caladen ui
This commit is contained in:
parent
f617a04900
commit
d3841154a5
Before Width: | Height: | Size: 516 B After Width: | Height: | Size: 516 B |
@ -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(),
|
||||
);
|
||||
}
|
||||
|
@ -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) {}
|
||||
}
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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),
|
||||
),
|
||||
);
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user