Skip to content

Commit 8b40244

Browse files
authored
Merge pull request #525 from AppFlowy-IO/fix/grid_date_time
fix: edit date time issue
2 parents a384404 + 481fd9d commit 8b40244

File tree

14 files changed

+206
-183
lines changed

14 files changed

+206
-183
lines changed

frontend/app_flowy/assets/translations/en.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@
198198
"colorPannelTitle": "Colors",
199199
"pannelTitle": "Select an option or create one",
200200
"searchOption": "Search for an option"
201+
},
202+
"date": {
203+
"timeHintTextInTwelveHour": "12:00 AM",
204+
"timeHintTextInTwentyFourHour": "12:00"
201205
}
202206
}
203207
}

frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/context_builder.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ part of 'cell_service.dart';
22

33
typedef GridCellContext = _GridCellContext<String, String>;
44
typedef GridSelectOptionCellContext = _GridCellContext<SelectOptionCellData, String>;
5-
typedef GridDateCellContext = _GridCellContext<DateCellData, DateCalData>;
5+
typedef GridDateCellContext = _GridCellContext<DateCellData, CalendarData>;
66
typedef GridURLCellContext = _GridCellContext<URLCellData, String>;
77

88
class GridCellContextBuilder {
@@ -31,6 +31,7 @@ class GridCellContextBuilder {
3131
final cellDataLoader = GridCellDataLoader(
3232
gridCell: _gridCell,
3333
parser: DateCellDataParser(),
34+
config: const GridCellDataConfig(reloadOnFieldChanged: true),
3435
);
3536

3637
return GridDateCellContext(
@@ -218,6 +219,7 @@ class _GridCellContext<T, D> extends Equatable {
218219
}
219220

220221
void dispose() {
222+
_cellListener.stop();
221223
_loadDataOperation?.cancel();
222224
_saveDataOperation?.cancel();
223225

frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/data_persistence.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,18 @@ class CellDataPersistence implements _GridCellDataPersistence<String> {
3131
}
3232

3333
@freezed
34-
class DateCalData with _$DateCalData {
35-
const factory DateCalData({required DateTime date, String? time}) = _DateCellPersistenceData;
34+
class CalendarData with _$CalendarData {
35+
const factory CalendarData({required DateTime date, String? time}) = _CalendarData;
3636
}
3737

38-
class DateCellDataPersistence implements _GridCellDataPersistence<DateCalData> {
38+
class DateCellDataPersistence implements _GridCellDataPersistence<CalendarData> {
3939
final GridCell gridCell;
4040
DateCellDataPersistence({
4141
required this.gridCell,
4242
});
4343

4444
@override
45-
Future<Option<FlowyError>> save(DateCalData data) {
45+
Future<Option<FlowyError>> save(CalendarData data) {
4646
var payload = DateChangesetPayload.create()..cellIdentifier = _cellIdentifier(gridCell);
4747

4848
final date = (data.date.millisecondsSinceEpoch ~/ 1000).toString();

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

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
3838
emit(state.copyWith(focusedDay: focusedDay));
3939
},
4040
didReceiveCellUpdate: (DateCellData? cellData) {
41-
final dateData = dateDataFromCellData(cellData);
42-
final time = dateData.foldRight("", (dateData, previous) => dateData.time);
43-
emit(state.copyWith(dateData: dateData, time: time));
41+
final calData = calDataFromCellData(cellData);
42+
final time = calData.foldRight("", (dateData, previous) => dateData.time);
43+
emit(state.copyWith(calData: calData, time: time));
4444
},
4545
setIncludeTime: (includeTime) async {
4646
await _updateTypeOption(emit, includeTime: includeTime);
@@ -52,16 +52,21 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
5252
await _updateTypeOption(emit, timeFormat: timeFormat);
5353
},
5454
setTime: (time) async {
55-
await _updateDateData(emit, time: time);
55+
if (state.calData.isSome()) {
56+
await _updateDateData(emit, time: time);
57+
}
58+
},
59+
didUpdateCalData: (Option<CalendarData> data, Option<String> timeFormatError) {
60+
emit(state.copyWith(calData: data, timeFormatError: timeFormatError));
5661
},
5762
);
5863
},
5964
);
6065
}
6166

6267
Future<void> _updateDateData(Emitter<DateCalState> emit, {DateTime? date, String? time}) {
63-
final DateCalData newDateData = state.dateData.fold(
64-
() => DateCalData(date: date ?? DateTime.now(), time: time),
68+
final CalendarData newDateData = state.calData.fold(
69+
() => CalendarData(date: date ?? DateTime.now(), time: time),
6570
(dateData) {
6671
var newDateData = dateData;
6772
if (date != null && !isSameDay(newDateData.date, date)) {
@@ -78,24 +83,22 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
7883
return _saveDateData(emit, newDateData);
7984
}
8085

81-
Future<void> _saveDateData(Emitter<DateCalState> emit, DateCalData newDateData) async {
82-
if (state.dateData == Some(newDateData)) {
86+
Future<void> _saveDateData(Emitter<DateCalState> emit, CalendarData newCalData) async {
87+
if (state.calData == Some(newCalData)) {
8388
return;
8489
}
8590

86-
cellContext.saveCellData(newDateData, resultCallback: (result) {
91+
updateCalData(Option<CalendarData> calData, Option<String> timeFormatError) {
92+
if (!isClosed) add(DateCalEvent.didUpdateCalData(calData, timeFormatError));
93+
}
94+
95+
cellContext.saveCellData(newCalData, resultCallback: (result) {
8796
result.fold(
88-
() => emit(state.copyWith(
89-
dateData: Some(newDateData),
90-
timeFormatError: none(),
91-
)),
97+
() => updateCalData(Some(newCalData), none()),
9298
(err) {
9399
switch (ErrorCode.valueOf(err.code)!) {
94100
case ErrorCode.InvalidDateTimeFormat:
95-
emit(state.copyWith(
96-
dateData: Some(newDateData),
97-
timeFormatError: Some(timeFormatPrompt(err)),
98-
));
101+
updateCalData(none(), Some(timeFormatPrompt(err)));
99102
break;
100103
default:
101104
Log.error(err);
@@ -168,7 +171,7 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
168171
);
169172

170173
result.fold(
171-
(l) => emit(state.copyWith(dateTypeOption: newDateTypeOption)),
174+
(l) => emit(state.copyWith(dateTypeOption: newDateTypeOption, timeHintText: _timeHintText(newDateTypeOption))),
172175
(err) => Log.error(err),
173176
);
174177
}
@@ -185,6 +188,8 @@ class DateCalEvent with _$DateCalEvent {
185188
const factory DateCalEvent.setIncludeTime(bool includeTime) = _IncludeTime;
186189
const factory DateCalEvent.setTime(String time) = _Time;
187190
const factory DateCalEvent.didReceiveCellUpdate(DateCellData? data) = _DidReceiveCellUpdate;
191+
const factory DateCalEvent.didUpdateCalData(Option<CalendarData> data, Option<String> timeFormatError) =
192+
_DidUpdateCalData;
188193
}
189194

190195
@freezed
@@ -194,36 +199,48 @@ class DateCalState with _$DateCalState {
194199
required CalendarFormat format,
195200
required DateTime focusedDay,
196201
required Option<String> timeFormatError,
197-
required Option<DateCalData> dateData,
202+
required Option<CalendarData> calData,
198203
required String? time,
204+
required String timeHintText,
199205
}) = _DateCalState;
200206

201207
factory DateCalState.initial(
202208
DateTypeOption dateTypeOption,
203209
DateCellData? cellData,
204210
) {
205-
Option<DateCalData> dateData = dateDataFromCellData(cellData);
206-
final time = dateData.foldRight("", (dateData, previous) => dateData.time);
211+
Option<CalendarData> calData = calDataFromCellData(cellData);
212+
final time = calData.foldRight("", (dateData, previous) => dateData.time);
207213
return DateCalState(
208214
dateTypeOption: dateTypeOption,
209215
format: CalendarFormat.month,
210216
focusedDay: DateTime.now(),
211217
time: time,
212-
dateData: dateData,
218+
calData: calData,
213219
timeFormatError: none(),
220+
timeHintText: _timeHintText(dateTypeOption),
214221
);
215222
}
216223
}
217224

218-
Option<DateCalData> dateDataFromCellData(DateCellData? cellData) {
225+
String _timeHintText(DateTypeOption typeOption) {
226+
switch (typeOption.timeFormat) {
227+
case TimeFormat.TwelveHour:
228+
return LocaleKeys.grid_date_timeHintTextInTwelveHour.tr();
229+
case TimeFormat.TwentyFourHour:
230+
return LocaleKeys.grid_date_timeHintTextInTwentyFourHour.tr();
231+
}
232+
return "";
233+
}
234+
235+
Option<CalendarData> calDataFromCellData(DateCellData? cellData) {
219236
String? time = timeFromCellData(cellData);
220-
Option<DateCalData> dateData = none();
237+
Option<CalendarData> calData = none();
221238
if (cellData != null) {
222239
final timestamp = cellData.timestamp * 1000;
223240
final date = DateTime.fromMillisecondsSinceEpoch(timestamp.toInt());
224-
dateData = Some(DateCalData(date: date, time: time));
241+
calData = Some(CalendarData(date: date, time: time));
225242
}
226-
return dateData;
243+
return calData;
227244
}
228245

229246
$fixnum.Int64 timestampFromDateTime(DateTime dateTime) {

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
44
import 'package:freezed_annotation/freezed_annotation.dart';
55
import 'dart:async';
66
import 'cell_service/cell_service.dart';
7-
import 'package:dartz/dartz.dart';
87
part 'date_cell_bloc.freezed.dart';
98

109
class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
@@ -17,11 +16,7 @@ class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
1716
event.when(
1817
initial: () => _startListening(),
1918
didReceiveCellUpdate: (DateCellData? cellData) {
20-
if (cellData != null) {
21-
emit(state.copyWith(data: Some(cellData)));
22-
} else {
23-
emit(state.copyWith(data: none()));
24-
}
19+
emit(state.copyWith(data: cellData, dateStr: _dateStrFromCellData(cellData)));
2520
},
2621
didReceiveFieldUpdate: (Field value) => emit(state.copyWith(field: value)),
2722
);
@@ -60,21 +55,26 @@ class DateCellEvent with _$DateCellEvent {
6055
@freezed
6156
class DateCellState with _$DateCellState {
6257
const factory DateCellState({
63-
required Option<DateCellData> data,
58+
required DateCellData? data,
59+
required String dateStr,
6460
required Field field,
6561
}) = _DateCellState;
6662

6763
factory DateCellState.initial(GridDateCellContext context) {
6864
final cellData = context.getCellData();
69-
Option<DateCellData> data = none();
70-
71-
if (cellData != null) {
72-
data = Some(cellData);
73-
}
7465

7566
return DateCellState(
7667
field: context.field,
77-
data: data,
68+
data: cellData,
69+
dateStr: _dateStrFromCellData(cellData),
7870
);
7971
}
8072
}
73+
74+
String _dateStrFromCellData(DateCellData? cellData) {
75+
String dateStr = "";
76+
if (cellData != null) {
77+
dateStr = cellData.date + " " + cellData.time;
78+
}
79+
return dateStr;
80+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class _DateCellState extends State<DateCell> {
6464
cursor: SystemMouseCursors.click,
6565
child: Align(
6666
alignment: alignment,
67-
child: FlowyText.medium(state.data.foldRight("", (data, _) => data.date), fontSize: 12),
67+
child: FlowyText.medium(state.dateStr, fontSize: 12),
6868
),
6969
),
7070
),

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,18 +160,21 @@ class _CellCalendarWidget extends StatelessWidget {
160160
),
161161
),
162162
selectedDayPredicate: (day) {
163-
return state.dateData.fold(
163+
return state.calData.fold(
164164
() => false,
165165
(dateData) => isSameDay(dateData.date, day),
166166
);
167167
},
168168
onDaySelected: (selectedDay, focusedDay) {
169+
_CalDateTimeSetting.hide(context);
169170
context.read<DateCalBloc>().add(DateCalEvent.selectDay(selectedDay));
170171
},
171172
onFormatChanged: (format) {
173+
_CalDateTimeSetting.hide(context);
172174
context.read<DateCalBloc>().add(DateCalEvent.setCalFormat(format));
173175
},
174176
onPageChanged: (focusedDay) {
177+
_CalDateTimeSetting.hide(context);
175178
context.read<DateCalBloc>().add(DateCalEvent.setFocusedDay(focusedDay));
176179
},
177180
);
@@ -234,6 +237,7 @@ class _TimeTextFieldState extends State<_TimeTextField> {
234237
if (widget.bloc.state.dateTypeOption.includeTime) {
235238
_focusNode.addListener(() {
236239
if (mounted) {
240+
_CalDateTimeSetting.hide(context);
237241
widget.bloc.add(DateCalEvent.setTime(_controller.text));
238242
}
239243
});
@@ -257,6 +261,7 @@ class _TimeTextFieldState extends State<_TimeTextField> {
257261
child: RoundedInputField(
258262
height: 40,
259263
focusNode: _focusNode,
264+
hintText: state.timeHintText,
260265
controller: _controller,
261266
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
262267
normalBorderColor: theme.shader4,
@@ -326,6 +331,7 @@ class _CalDateTimeSetting extends StatefulWidget {
326331
}
327332

328333
void show(BuildContext context) {
334+
hide(context);
329335
FlowyOverlay.of(context).insertWithAnchor(
330336
widget: OverlayContainer(
331337
child: this,
@@ -337,6 +343,10 @@ class _CalDateTimeSetting extends StatefulWidget {
337343
anchorOffset: const Offset(20, 0),
338344
);
339345
}
346+
347+
static void hide(BuildContext context) {
348+
FlowyOverlay.of(context).remove(identifier());
349+
}
340350
}
341351

342352
class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {

frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl_type_option!(CheckboxTypeOption, FieldType::Checkbox);
4242
const YES: &str = "Yes";
4343
const NO: &str = "No";
4444

45-
impl CellDataOperation<String, String> for CheckboxTypeOption {
45+
impl CellDataOperation<String> for CheckboxTypeOption {
4646
fn decode_cell_data<T>(
4747
&self,
4848
encoded_data: T,

0 commit comments

Comments
 (0)