Skip to content

Commit a2dfc8b

Browse files
committed
chore: set time
1 parent 81d7514 commit a2dfc8b

File tree

4 files changed

+125
-76
lines changed

4 files changed

+125
-76
lines changed

frontend/app_flowy/lib/workspace/application/grid/cell/date_cal_bloc.dart

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
22
import 'package:flowy_sdk/log.dart';
3+
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
34
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell;
45
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
56
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -16,13 +17,17 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
1617
final GridDefaultCellContext cellContext;
1718
void Function()? _onCellChangedFn;
1819

19-
DateCalBloc({required this.cellContext}) : super(DateCalState.initial(cellContext)) {
20+
DateCalBloc({
21+
required DateTypeOption dateTypeOption,
22+
required DateTime? selectedDay,
23+
required this.cellContext,
24+
}) : super(DateCalState.initial(dateTypeOption, selectedDay)) {
2025
on<DateCalEvent>(
2126
(event, emit) async {
2227
await event.map(
2328
initial: (_Initial value) async {
2429
_startListening();
25-
await _loadDateTypeOption(emit);
30+
// await _loadDateTypeOption(emit);
2631
},
2732
selectDay: (_SelectDay value) {
2833
if (!isSameDay(state.selectedDay, value.day)) {
@@ -46,6 +51,7 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
4651
setTimeFormat: (_TimeFormat value) async {
4752
await _updateTypeOption(emit, timeFormat: value.timeFormat);
4853
},
54+
setTime: (_Time value) {},
4955
);
5056
},
5157
);
@@ -71,12 +77,12 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
7177
);
7278
}
7379

80+
// ignore: unused_element
7481
Future<void> _loadDateTypeOption(Emitter<DateCalState> emit) async {
7582
final result = await cellContext.getTypeOptionData();
7683
result.fold(
7784
(data) {
7885
final typeOptionData = DateTypeOption.fromBuffer(data);
79-
8086
DateTime? selectedDay;
8187
final cellData = cellContext.getCellData()?.data;
8288

@@ -86,7 +92,7 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
8692
}
8793

8894
emit(state.copyWith(
89-
dateTypeOption: some(typeOptionData),
95+
dateTypeOption: typeOptionData,
9096
selectedDay: selectedDay,
9197
));
9298
},
@@ -105,35 +111,31 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
105111
TimeFormat? timeFormat,
106112
bool? includeTime,
107113
}) async {
108-
final newDateTypeOption = state.dateTypeOption.fold(() => null, (dateTypeOption) {
109-
dateTypeOption.freeze();
110-
return dateTypeOption.rebuild((typeOption) {
111-
if (dateFormat != null) {
112-
typeOption.dateFormat = dateFormat;
113-
}
114-
115-
if (timeFormat != null) {
116-
typeOption.timeFormat = timeFormat;
117-
}
118-
119-
if (includeTime != null) {
120-
typeOption.includeTime = includeTime;
121-
}
122-
});
114+
state.dateTypeOption.freeze();
115+
final newDateTypeOption = state.dateTypeOption.rebuild((typeOption) {
116+
if (dateFormat != null) {
117+
typeOption.dateFormat = dateFormat;
118+
}
119+
120+
if (timeFormat != null) {
121+
typeOption.timeFormat = timeFormat;
122+
}
123+
124+
if (includeTime != null) {
125+
typeOption.includeTime = includeTime;
126+
}
123127
});
124128

125-
if (newDateTypeOption != null) {
126-
final result = await FieldService.updateFieldTypeOption(
127-
gridId: cellContext.gridId,
128-
fieldId: cellContext.field.id,
129-
typeOptionData: newDateTypeOption.writeToBuffer(),
130-
);
129+
final result = await FieldService.updateFieldTypeOption(
130+
gridId: cellContext.gridId,
131+
fieldId: cellContext.field.id,
132+
typeOptionData: newDateTypeOption.writeToBuffer(),
133+
);
131134

132-
result.fold(
133-
(l) => emit(state.copyWith(dateTypeOption: Some(newDateTypeOption))),
134-
(err) => Log.error(err),
135-
);
136-
}
135+
result.fold(
136+
(l) => emit(state.copyWith(dateTypeOption: newDateTypeOption)),
137+
(err) => Log.error(err),
138+
);
137139
}
138140
}
139141

@@ -146,23 +148,31 @@ class DateCalEvent with _$DateCalEvent {
146148
const factory DateCalEvent.setTimeFormat(TimeFormat timeFormat) = _TimeFormat;
147149
const factory DateCalEvent.setDateFormat(DateFormat dateFormat) = _DateFormat;
148150
const factory DateCalEvent.setIncludeTime(bool includeTime) = _IncludeTime;
151+
const factory DateCalEvent.setTime(String time) = _Time;
149152
const factory DateCalEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate;
150153
}
151154

152155
@freezed
153156
class DateCalState with _$DateCalState {
154157
const factory DateCalState({
155-
required Option<DateTypeOption> dateTypeOption,
158+
required DateTypeOption dateTypeOption,
156159
required CalendarFormat format,
157160
required DateTime focusedDay,
158-
required Option<String> time,
161+
required String time,
162+
required Option<FlowyError> inputTimeError,
159163
DateTime? selectedDay,
160164
}) = _DateCalState;
161165

162-
factory DateCalState.initial(GridCellContext context) => DateCalState(
163-
dateTypeOption: none(),
166+
factory DateCalState.initial(
167+
DateTypeOption dateTypeOption,
168+
DateTime? selectedDay,
169+
) =>
170+
DateCalState(
171+
dateTypeOption: dateTypeOption,
164172
format: CalendarFormat.month,
165173
focusedDay: DateTime.now(),
166-
time: none(),
174+
selectedDay: selectedDay,
175+
time: "",
176+
inputTimeError: none(),
167177
);
168178
}

frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell/calendar.dart

Lines changed: 73 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ import 'package:flowy_infra/theme.dart';
88
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
99
import 'package:flowy_infra_ui/style_widget/button.dart';
1010
import 'package:flowy_infra_ui/style_widget/text.dart';
11+
import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
1112
import 'package:flowy_infra_ui/widget/spacing.dart';
13+
import 'package:flowy_sdk/log.dart';
1214
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
1315
import 'package:flutter/material.dart';
1416
import 'package:flutter_bloc/flutter_bloc.dart';
1517
import 'package:table_calendar/table_calendar.dart';
1618
import 'package:app_flowy/workspace/application/grid/prelude.dart';
17-
import 'package:dartz/dartz.dart' show Option;
19+
import 'package:fixnum/fixnum.dart' as $fixnum;
1820

1921
final kToday = DateTime.now();
2022
final kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day);
@@ -35,22 +37,38 @@ class CellCalendar with FlowyOverlayDelegate {
3537
}) async {
3638
CellCalendar.remove(context);
3739

38-
final calendar = _CellCalendarWidget(
39-
onSelected: onSelected,
40-
includeTime: false,
41-
cellContext: cellContext,
42-
);
40+
final result = await cellContext.getTypeOptionData();
41+
result.fold(
42+
(data) {
43+
final typeOptionData = DateTypeOption.fromBuffer(data);
44+
DateTime? selectedDay;
45+
final cellData = cellContext.getCellData()?.data;
46+
47+
if (cellData != null) {
48+
final timestamp = $fixnum.Int64.parseInt(cellData).toInt();
49+
selectedDay = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
50+
}
51+
52+
final calendar = _CellCalendarWidget(
53+
onSelected: onSelected,
54+
cellContext: cellContext,
55+
dateTypeOption: typeOptionData,
56+
selectedDay: selectedDay,
57+
);
4358

44-
FlowyOverlay.of(context).insertWithAnchor(
45-
widget: OverlayContainer(
46-
child: calendar,
47-
constraints: BoxConstraints.loose(const Size(320, 500)),
48-
),
49-
identifier: CellCalendar.identifier(),
50-
anchorContext: context,
51-
anchorDirection: AnchorDirection.leftWithCenterAligned,
52-
style: FlowyOverlayStyle(blur: false),
53-
delegate: this,
59+
FlowyOverlay.of(context).insertWithAnchor(
60+
widget: OverlayContainer(
61+
child: calendar,
62+
constraints: BoxConstraints.loose(const Size(320, 500)),
63+
),
64+
identifier: CellCalendar.identifier(),
65+
anchorContext: context,
66+
anchorDirection: AnchorDirection.leftWithCenterAligned,
67+
style: FlowyOverlayStyle(blur: false),
68+
delegate: this,
69+
);
70+
},
71+
(err) => Log.error(err),
5472
);
5573
}
5674

@@ -70,22 +88,28 @@ class CellCalendar with FlowyOverlayDelegate {
7088
}
7189

7290
class _CellCalendarWidget extends StatelessWidget {
73-
final bool includeTime;
7491
final GridDefaultCellContext cellContext;
92+
final DateTypeOption dateTypeOption;
93+
final DateTime? selectedDay;
7594
final void Function(DateTime) onSelected;
7695

7796
const _CellCalendarWidget({
7897
required this.onSelected,
79-
required this.includeTime,
8098
required this.cellContext,
99+
required this.dateTypeOption,
100+
this.selectedDay,
81101
Key? key,
82102
}) : super(key: key);
83103

84104
@override
85105
Widget build(BuildContext context) {
86106
final theme = context.watch<AppTheme>();
87107
return BlocProvider(
88-
create: (context) => DateCalBloc(cellContext: cellContext)..add(const DateCalEvent.initial()),
108+
create: (context) => DateCalBloc(
109+
dateTypeOption: dateTypeOption,
110+
selectedDay: selectedDay,
111+
cellContext: cellContext,
112+
)..add(const DateCalEvent.initial()),
89113
child: BlocConsumer<DateCalBloc, DateCalState>(
90114
listener: (context, state) {
91115
if (state.selectedDay != null) {
@@ -101,12 +125,11 @@ class _CellCalendarWidget extends StatelessWidget {
101125
const VSpace(10),
102126
]);
103127

104-
state.dateTypeOption.foldRight(null, (dateTypeOption, _) {
128+
if (state.dateTypeOption.includeTime) {
105129
children.addAll([
106130
const _TimeTextField(),
107-
const VSpace(10),
108131
]);
109-
});
132+
}
110133

111134
children.addAll([
112135
Divider(height: 1, color: theme.shader5),
@@ -189,7 +212,7 @@ class _IncludeTimeButton extends StatelessWidget {
189212
Widget build(BuildContext context) {
190213
final theme = context.watch<AppTheme>();
191214
return BlocSelector<DateCalBloc, DateCalState, bool>(
192-
selector: (state) => state.dateTypeOption.foldRight(false, (option, _) => option.includeTime),
215+
selector: (state) => state.dateTypeOption.includeTime,
193216
builder: (context, includeTime) {
194217
return SizedBox(
195218
height: 50,
@@ -219,7 +242,19 @@ class _TimeTextField extends StatelessWidget {
219242

220243
@override
221244
Widget build(BuildContext context) {
222-
return Container();
245+
final theme = context.watch<AppTheme>();
246+
return Padding(
247+
padding: kMargin,
248+
child: RoundedInputField(
249+
height: 40,
250+
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
251+
normalBorderColor: theme.shader4,
252+
errorBorderColor: theme.red,
253+
cursorColor: theme.main1,
254+
errorText: context.read<DateCalBloc>().state.inputTimeError.fold(() => "", (error) => error.toString()),
255+
onEditingComplete: (value) => context.read<DateCalBloc>().add(DateCalEvent.setTime(value)),
256+
),
257+
);
223258
}
224259
}
225260

@@ -230,29 +265,33 @@ class _DateTypeOptionButton extends StatelessWidget {
230265
Widget build(BuildContext context) {
231266
final theme = context.watch<AppTheme>();
232267
final title = LocaleKeys.grid_field_dateFormat.tr() + " &" + LocaleKeys.grid_field_timeFormat.tr();
233-
return BlocSelector<DateCalBloc, DateCalState, Option<DateTypeOption>>(
268+
return BlocSelector<DateCalBloc, DateCalState, DateTypeOption>(
234269
selector: (state) => state.dateTypeOption,
235270
builder: (context, dateTypeOption) {
236271
return FlowyButton(
237272
text: FlowyText.medium(title, fontSize: 12),
238273
hoverColor: theme.hover,
239274
margin: kMargin,
240-
onTap: () {
241-
dateTypeOption.fold(() => null, (dateTypeOption) {
242-
final setting = _CalDateTimeSetting(dateTypeOption: dateTypeOption);
243-
setting.show(context);
244-
});
245-
},
275+
onTap: () => _showTimeSetting(dateTypeOption, context),
246276
rightIcon: svgWidget("grid/more", color: theme.iconColor),
247277
);
248278
},
249279
);
250280
}
281+
282+
void _showTimeSetting(DateTypeOption dateTypeOption, BuildContext context) {
283+
final setting = _CalDateTimeSetting(
284+
dateTypeOption: dateTypeOption,
285+
onEvent: (event) => context.read<DateCalBloc>().add(event),
286+
);
287+
setting.show(context);
288+
}
251289
}
252290

253291
class _CalDateTimeSetting extends StatefulWidget {
254292
final DateTypeOption dateTypeOption;
255-
const _CalDateTimeSetting({required this.dateTypeOption, Key? key}) : super(key: key);
293+
final Function(DateCalEvent) onEvent;
294+
const _CalDateTimeSetting({required this.dateTypeOption, required this.onEvent, Key? key}) : super(key: key);
256295

257296
@override
258297
State<_CalDateTimeSetting> createState() => _CalDateTimeSettingState();
@@ -283,9 +322,7 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
283322
DateFormatButton(onTap: () {
284323
final list = DateFormatList(
285324
selectedFormat: widget.dateTypeOption.dateFormat,
286-
onSelected: (format) {
287-
context.read<DateCalBloc>().add(DateCalEvent.setDateFormat(format));
288-
},
325+
onSelected: (format) => widget.onEvent(DateCalEvent.setDateFormat(format)),
289326
);
290327
_showOverlay(context, list);
291328
}),
@@ -294,9 +331,7 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
294331
onTap: () {
295332
final list = TimeFormatList(
296333
selectedFormat: widget.dateTypeOption.timeFormat,
297-
onSelected: (format) {
298-
context.read<DateCalBloc>().add(DateCalEvent.setTimeFormat(format));
299-
},
334+
onSelected: (format) => widget.onEvent(DateCalEvent.setTimeFormat(format)),
300335
);
301336
_showOverlay(context, list);
302337
},

frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/common/text_field.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class _InputTextFieldState extends State<InputTextField> {
5353
widget.onChanged!(text);
5454
}
5555
},
56-
onEditingComplete: () {
56+
onEditingComplete: (_) {
5757
if (widget.onDone != null) {
5858
widget.onDone!(_controller.text);
5959
}

frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class RoundedInputField extends StatefulWidget {
1515
final String errorText;
1616
final TextStyle style;
1717
final ValueChanged<String>? onChanged;
18-
final VoidCallback? onEditingComplete;
18+
final Function(String)? onEditingComplete;
1919
final String? initialValue;
2020
final EdgeInsets margin;
2121
final EdgeInsets padding;
@@ -90,7 +90,11 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
9090
}
9191
setState(() {});
9292
},
93-
onEditingComplete: widget.onEditingComplete,
93+
onEditingComplete: () {
94+
if (widget.onEditingComplete != null) {
95+
widget.onEditingComplete!(inputText);
96+
}
97+
},
9498
cursorColor: widget.cursorColor,
9599
obscureText: obscuteText,
96100
style: widget.style,

0 commit comments

Comments
 (0)