mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: auto reload when field was changed
This commit is contained in:
parent
be49784f5a
commit
af5f42d296
@ -16,7 +16,6 @@ import 'package:app_flowy/user/presentation/router.dart';
|
||||
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell;
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
|
||||
@ -182,19 +181,19 @@ void _resolveGridDeps(GetIt getIt) {
|
||||
),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<NumberCellBloc, GridCellContext<Cell>, void>(
|
||||
getIt.registerFactoryParam<NumberCellBloc, GridDefaultCellContext, void>(
|
||||
(context, _) => NumberCellBloc(
|
||||
cellContext: context,
|
||||
),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<DateCellBloc, GridCellContext<Cell>, void>(
|
||||
getIt.registerFactoryParam<DateCellBloc, GridDefaultCellContext, void>(
|
||||
(context, _) => DateCellBloc(
|
||||
cellContext: context,
|
||||
),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<CheckboxCellBloc, GridCellContext<Cell>, void>(
|
||||
getIt.registerFactoryParam<CheckboxCellBloc, GridDefaultCellContext, void>(
|
||||
(cellData, _) => CheckboxCellBloc(
|
||||
service: CellService(),
|
||||
cellContext: cellData,
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:dartz/dartz.dart';
|
||||
@ -6,6 +7,7 @@ import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
@ -13,6 +15,9 @@ import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart';
|
||||
|
||||
part 'cell_service.freezed.dart';
|
||||
|
||||
typedef GridDefaultCellContext = GridCellContext<Cell>;
|
||||
typedef GridSelectOptionCellContext = GridCellContext<SelectOptionContext>;
|
||||
|
||||
class GridCellContext<T> {
|
||||
final GridCell gridCell;
|
||||
final GridCellCache cellCache;
|
||||
@ -22,6 +27,7 @@ class GridCellContext<T> {
|
||||
final CellListener _cellListener;
|
||||
final CellService _cellService = CellService();
|
||||
final ValueNotifier<dynamic> _cellDataNotifier = ValueNotifier(null);
|
||||
Timer? _delayOperation;
|
||||
|
||||
GridCellContext({
|
||||
required this.gridCell,
|
||||
@ -41,6 +47,12 @@ class GridCellContext<T> {
|
||||
objectId: "$hashCode",
|
||||
fieldId: gridCell.field.id,
|
||||
);
|
||||
|
||||
if (cellDataLoader.reloadOnFieldChanged) {
|
||||
cellCache.addListener(cacheKey, () {
|
||||
reloadCellData();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
String get gridId => gridCell.gridId;
|
||||
@ -73,16 +85,18 @@ class GridCellContext<T> {
|
||||
_cellService.updateCell(gridId: gridId, fieldId: field.id, rowId: rowId, data: data);
|
||||
}
|
||||
|
||||
void _loadData() {
|
||||
// It may trigger getCell multiple times. Use cancel operation to fix this.
|
||||
cellDataLoader.loadData().then((data) {
|
||||
_cellDataNotifier.value = data;
|
||||
setCellData(data);
|
||||
});
|
||||
void reloadCellData() {
|
||||
_loadData();
|
||||
}
|
||||
|
||||
void onFieldChanged(VoidCallback callback) {
|
||||
cellCache.addListener(cacheKey, callback);
|
||||
void _loadData() {
|
||||
_delayOperation?.cancel();
|
||||
_delayOperation = Timer(const Duration(milliseconds: 10), () {
|
||||
cellDataLoader.loadData().then((data) {
|
||||
_cellDataNotifier.value = data;
|
||||
setCellData(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void onCellChanged(void Function(T) callback) {
|
||||
@ -94,13 +108,15 @@ class GridCellContext<T> {
|
||||
});
|
||||
}
|
||||
|
||||
void removeListener() {
|
||||
cellCache.removeListener(cacheKey);
|
||||
void dispose() {
|
||||
_delayOperation?.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class GridCellDataLoader<T> {
|
||||
Future<T?> loadData();
|
||||
|
||||
bool get reloadOnFieldChanged => true;
|
||||
}
|
||||
|
||||
class DefaultCellDataLoader implements GridCellDataLoader<Cell> {
|
||||
@ -125,6 +141,9 @@ class DefaultCellDataLoader implements GridCellDataLoader<Cell> {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
bool get reloadOnFieldChanged => true;
|
||||
}
|
||||
|
||||
// key: rowId
|
||||
|
@ -7,13 +7,12 @@ import 'cell_service.dart';
|
||||
part 'checkbox_cell_bloc.freezed.dart';
|
||||
|
||||
class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
|
||||
final GridCellContext<Cell> _cellContext;
|
||||
final GridDefaultCellContext cellContext;
|
||||
|
||||
CheckboxCellBloc({
|
||||
required CellService service,
|
||||
required GridCellContext<Cell> cellContext,
|
||||
}) : _cellContext = cellContext,
|
||||
super(CheckboxCellState.initial(cellContext)) {
|
||||
required this.cellContext,
|
||||
}) : super(CheckboxCellState.initial(cellContext)) {
|
||||
on<CheckboxCellEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
@ -33,11 +32,12 @@ class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
cellContext.dispose();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _startListening() {
|
||||
_cellContext.onCellChanged((cell) {
|
||||
cellContext.onCellChanged((cell) {
|
||||
if (!isClosed) {
|
||||
add(CheckboxCellEvent.didReceiveCellUpdate(cell));
|
||||
}
|
||||
@ -45,7 +45,7 @@ class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
|
||||
}
|
||||
|
||||
void _updateCellData() {
|
||||
_cellContext.saveCellData(!state.isSelected ? "Yes" : "No");
|
||||
cellContext.saveCellData(!state.isSelected ? "Yes" : "No");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_listener.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell, Field;
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
@ -9,12 +7,9 @@ import 'cell_service.dart';
|
||||
part 'date_cell_bloc.freezed.dart';
|
||||
|
||||
class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
|
||||
final SingleFieldListener _fieldListener;
|
||||
final GridCellContext<Cell> cellContext;
|
||||
final GridDefaultCellContext cellContext;
|
||||
|
||||
DateCellBloc({required this.cellContext})
|
||||
: _fieldListener = SingleFieldListener(fieldId: cellContext.fieldId),
|
||||
super(DateCellState.initial(cellContext)) {
|
||||
DateCellBloc({required this.cellContext}) : super(DateCellState.initial(cellContext)) {
|
||||
on<DateCellEvent>(
|
||||
(event, emit) async {
|
||||
event.map(
|
||||
@ -39,7 +34,7 @@ class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _fieldListener.stop();
|
||||
cellContext.dispose();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
@ -49,14 +44,6 @@ class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
|
||||
add(DateCellEvent.didReceiveCellUpdate(cell));
|
||||
}
|
||||
});
|
||||
|
||||
_fieldListener.updateFieldNotifier?.addPublishListener((result) {
|
||||
result.fold(
|
||||
(field) => add(DateCellEvent.didReceiveFieldUpdate(field)),
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
}, listenWhen: () => !isClosed);
|
||||
_fieldListener.start();
|
||||
}
|
||||
|
||||
void _updateCellData(DateTime day) {
|
||||
|
@ -1,5 +1,3 @@
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_listener.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
@ -9,13 +7,11 @@ import 'cell_service.dart';
|
||||
part 'number_cell_bloc.freezed.dart';
|
||||
|
||||
class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
|
||||
final GridCellContext<Cell> cellContext;
|
||||
final SingleFieldListener _fieldListener;
|
||||
final GridDefaultCellContext cellContext;
|
||||
|
||||
NumberCellBloc({
|
||||
required this.cellContext,
|
||||
}) : _fieldListener = SingleFieldListener(fieldId: cellContext.fieldId),
|
||||
super(NumberCellState.initial(cellContext)) {
|
||||
}) : super(NumberCellState.initial(cellContext)) {
|
||||
on<NumberCellEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
@ -40,7 +36,7 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _fieldListener.stop();
|
||||
cellContext.dispose();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
@ -50,14 +46,6 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
|
||||
add(NumberCellEvent.didReceiveCellUpdate(cell));
|
||||
}
|
||||
});
|
||||
|
||||
_fieldListener.updateFieldNotifier?.addPublishListener((result) {
|
||||
result.fold(
|
||||
(field) => cellContext.reloadCellData(),
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
_fieldListener.start();
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +62,8 @@ class NumberCellState with _$NumberCellState {
|
||||
required String content,
|
||||
}) = _NumberCellState;
|
||||
|
||||
factory NumberCellState.initial(GridCellContext context) {
|
||||
return NumberCellState(content: context.getCellData().cell?.content ?? "");
|
||||
factory NumberCellState.initial(GridDefaultCellContext context) {
|
||||
final cell = context.getCellData();
|
||||
return NumberCellState(content: cell?.content ?? "");
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,9 @@ class SelectOptionCellDataLoader implements GridCellDataLoader<SelectOptionConte
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
bool get reloadOnFieldChanged => true;
|
||||
}
|
||||
|
||||
class SelectOptionService {
|
||||
|
@ -3,18 +3,15 @@ import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_listener.dart';
|
||||
|
||||
part 'selection_cell_bloc.freezed.dart';
|
||||
|
||||
class SelectionCellBloc extends Bloc<SelectionCellEvent, SelectionCellState> {
|
||||
final SingleFieldListener _fieldListener;
|
||||
final GridCellContext<SelectOptionContext> cellContext;
|
||||
|
||||
SelectionCellBloc({
|
||||
required this.cellContext,
|
||||
}) : _fieldListener = SingleFieldListener(fieldId: cellContext.fieldId),
|
||||
super(SelectionCellState.initial(cellContext)) {
|
||||
}) : super(SelectionCellState.initial(cellContext)) {
|
||||
on<SelectionCellEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
@ -34,8 +31,7 @@ class SelectionCellBloc extends Bloc<SelectionCellEvent, SelectionCellState> {
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _fieldListener.stop();
|
||||
cellContext.removeListener();
|
||||
cellContext.dispose();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
@ -48,8 +44,6 @@ class SelectionCellBloc extends Bloc<SelectionCellEvent, SelectionCellState> {
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
cellContext.onFieldChanged(() => cellContext.reloadCellData());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_listener.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
@ -14,7 +11,6 @@ part 'selection_editor_bloc.freezed.dart';
|
||||
class SelectOptionEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionEditorState> {
|
||||
final SelectOptionService _selectOptionService;
|
||||
final GridCellContext<SelectOptionContext> cellContext;
|
||||
Timer? _delayOperation;
|
||||
|
||||
SelectOptionEditorBloc({
|
||||
required this.cellContext,
|
||||
@ -51,8 +47,7 @@ class SelectOptionEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionE
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
_delayOperation?.cancel();
|
||||
cellContext.removeListener();
|
||||
cellContext.dispose();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
@ -86,27 +81,6 @@ class SelectOptionEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionE
|
||||
}
|
||||
}
|
||||
|
||||
// void _loadOptions() async {
|
||||
// _delayOperation?.cancel();
|
||||
// _delayOperation = Timer(
|
||||
// const Duration(milliseconds: 1),
|
||||
// () async {
|
||||
// final result = await _selectOptionService.getOpitonContext();
|
||||
// if (isClosed) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// result.fold(
|
||||
// (selectOptionContext) => add(SelectOptionEditorEvent.didReceiveOptions(
|
||||
// selectOptionContext.options,
|
||||
// selectOptionContext.selectOptions,
|
||||
// )),
|
||||
// (err) => Log.error(err),
|
||||
// );
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
|
||||
void _startListening() {
|
||||
cellContext.onCellChanged((selectOptionContext) {
|
||||
if (!isClosed) {
|
||||
@ -116,8 +90,6 @@ class SelectOptionEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionE
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
cellContext.onFieldChanged(() => cellContext.reloadCellData());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,22 +1,16 @@
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell;
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
import 'cell_listener.dart';
|
||||
import 'cell_service.dart';
|
||||
|
||||
part 'text_cell_bloc.freezed.dart';
|
||||
|
||||
class TextCellBloc extends Bloc<TextCellEvent, TextCellState> {
|
||||
final CellService _service;
|
||||
final CellListener _cellListener;
|
||||
|
||||
final GridCellContext cellContext;
|
||||
TextCellBloc({
|
||||
required GridCellContext cellContext,
|
||||
}) : _service = CellService(),
|
||||
_cellListener = CellListener(rowId: cellContext.rowId, fieldId: cellContext.fieldId),
|
||||
super(TextCellState.initial(cellContext.gridCell)) {
|
||||
required this.cellContext,
|
||||
}) : super(TextCellState.initial(cellContext.gridCell)) {
|
||||
on<TextCellEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
@ -24,7 +18,7 @@ class TextCellBloc extends Bloc<TextCellEvent, TextCellState> {
|
||||
_startListening();
|
||||
},
|
||||
updateText: (_UpdateText value) {
|
||||
updateCellContent(value.text);
|
||||
cellContext.saveCellData(value.text);
|
||||
emit(state.copyWith(content: value.text));
|
||||
},
|
||||
didReceiveCellData: (_DidReceiveCellData value) {
|
||||
@ -46,45 +40,16 @@ class TextCellBloc extends Bloc<TextCellEvent, TextCellState> {
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _cellListener.stop();
|
||||
cellContext.dispose();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void updateCellContent(String content) {
|
||||
final fieldId = state.cellData.field.id;
|
||||
final gridId = state.cellData.gridId;
|
||||
final rowId = state.cellData.rowId;
|
||||
_service.updateCell(
|
||||
data: content,
|
||||
fieldId: fieldId,
|
||||
gridId: gridId,
|
||||
rowId: rowId,
|
||||
);
|
||||
}
|
||||
|
||||
void _startListening() {
|
||||
_cellListener.updateCellNotifier?.addPublishListener((result) {
|
||||
result.fold(
|
||||
(notificationData) async => await _loadCellData(),
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
cellContext.onCellChanged((cell) {
|
||||
if (!isClosed) {
|
||||
add(TextCellEvent.didReceiveCellUpdate(cell));
|
||||
}
|
||||
});
|
||||
_cellListener.start();
|
||||
}
|
||||
|
||||
Future<void> _loadCellData() async {
|
||||
final result = await _service.getCell(
|
||||
gridId: state.cellData.gridId,
|
||||
fieldId: state.cellData.field.id,
|
||||
rowId: state.cellData.rowId,
|
||||
);
|
||||
if (isClosed) {
|
||||
return;
|
||||
}
|
||||
result.fold(
|
||||
(cell) => add(TextCellEvent.didReceiveCellUpdate(cell)),
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/cell/select_option_service.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell, FieldType;
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType;
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'checkbox_cell.dart';
|
||||
@ -39,7 +39,7 @@ GridCellContext makeCellContext(GridCell gridCell, GridCellCache cellCache) {
|
||||
case FieldType.DateTime:
|
||||
case FieldType.Number:
|
||||
case FieldType.RichText:
|
||||
return GridCellContext<Cell>(
|
||||
return GridDefaultCellContext(
|
||||
gridCell: gridCell,
|
||||
cellCache: cellCache,
|
||||
cellDataLoader: DefaultCellDataLoader(gridCell: gridCell),
|
||||
|
@ -1,7 +1,6 @@
|
||||
import 'dart:collection';
|
||||
import 'package:app_flowy/workspace/application/grid/cell/cell_service.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/cell/selection_editor_bloc.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/edit_option_pannel.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/widget.dart';
|
||||
|
Loading…
Reference in New Issue
Block a user