Skip to content

Commit

Permalink
chore: reload row when fields were changed
Browse files Browse the repository at this point in the history
  • Loading branch information
appflowy committed Apr 30, 2022
1 parent 6b5126b commit 518d111
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -365,4 +365,11 @@ class GridCell with _$GridCell {
required Field field,
Cell? cell,
}) = _GridCell;

// ignore: unused_element
const GridCell._();

String cellId() {
return rowId + field.id + "${field.fieldType}";
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'dart:collection';
import 'package:app_flowy/workspace/application/grid/cell/cell_service.dart';
import 'package:equatable/equatable.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field;
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
Expand Down Expand Up @@ -28,7 +30,13 @@ class RowBloc extends Bloc<RowEvent, RowState> {
_rowService.createRow();
},
didReceiveCellDatas: (_DidReceiveCellDatas value) async {
emit(state.copyWith(cellDataMap: value.cellData));
final fields = value.gridCellMap.values.map((e) => CellSnapshot(e.field)).toList();
final snapshots = UnmodifiableListView(fields);
emit(state.copyWith(
gridCellMap: value.gridCellMap,
snapshots: snapshots,
changeReason: value.reason,
));
},
);
},
Expand All @@ -47,7 +55,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
Future<void> _startListening() async {
_rowListenFn = _rowCache.addRowListener(
rowId: state.rowData.rowId,
onUpdated: (cellDatas) => add(RowEvent.didReceiveCellDatas(cellDatas)),
onUpdated: (cellDatas, reason) => add(RowEvent.didReceiveCellDatas(cellDatas, reason)),
listenWhen: () => !isClosed,
);
}
Expand All @@ -57,18 +65,35 @@ class RowBloc extends Bloc<RowEvent, RowState> {
class RowEvent with _$RowEvent {
const factory RowEvent.initial() = _InitialRow;
const factory RowEvent.createRow() = _CreateRow;
const factory RowEvent.didReceiveCellDatas(GridCellMap cellData) = _DidReceiveCellDatas;
const factory RowEvent.didReceiveCellDatas(GridCellMap gridCellMap, GridRowChangeReason reason) =
_DidReceiveCellDatas;
}

@freezed
class RowState with _$RowState {
const factory RowState({
required GridRow rowData,
required GridCellMap cellDataMap,
required GridCellMap gridCellMap,
required UnmodifiableListView<CellSnapshot> snapshots,
GridRowChangeReason? changeReason,
}) = _RowState;

factory RowState.initial(GridRow rowData, GridCellMap cellDataMap) => RowState(
rowData: rowData,
cellDataMap: cellDataMap,
gridCellMap: cellDataMap,
snapshots: UnmodifiableListView(cellDataMap.values.map((e) => CellSnapshot(e.field)).toList()),
);
}

class CellSnapshot extends Equatable {
final Field _field;

const CellSnapshot(Field field) : _field = field;

@override
List<Object?> get props => [
_field.id,
_field.fieldType,
_field.visibility,
];
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
Future<void> _startListening() async {
_rowListenFn = _rowCache.addRowListener(
rowId: rowData.rowId,
onUpdated: (cellDatas) => add(RowDetailEvent.didReceiveCellDatas(cellDatas.values.toList())),
onUpdated: (cellDatas, reason) => add(RowDetailEvent.didReceiveCellDatas(cellDatas.values.toList())),
listenWhen: () => !isClosed,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class GridRowCache {

RowUpdateCallback addRowListener({
required String rowId,
void Function(GridCellMap)? onUpdated,
void Function(GridCellMap, GridRowChangeReason)? onUpdated,
bool Function()? listenWhen,
}) {
listenrHandler() async {
Expand All @@ -99,7 +99,7 @@ class GridRowCache {
final row = _rowsNotifier.rowDataWithId(rowId);
if (row != null) {
final GridCellMap cellDataMap = _makeGridCells(rowId, row);
onUpdated(cellDataMap);
onUpdated(cellDataMap, _rowsNotifier._changeReason);
}
}

Expand Down Expand Up @@ -339,7 +339,7 @@ class GridRow with _$GridRow {
const factory GridRow({
required String gridId,
required String rowId,
required List<Field> fields,
required UnmodifiableListView<Field> fields,
required double height,
Row? data,
}) = _GridRow;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import 'selection_cell/selection_cell.dart';
import 'text_cell.dart';

GridCellWidget buildGridCellWidget(GridCell gridCell, GridCellCache cellCache, {GridCellStyle? style}) {
final key = ValueKey(gridCell.rowId + gridCell.field.id);
final key = ValueKey(gridCell.cellId());

final cellContextBuilder = GridCellContextBuilder(gridCell: gridCell, cellCache: cellCache);

Expand Down Expand Up @@ -82,6 +82,25 @@ class GridCellRequestFocusNotifier extends ChangeNotifier {

abstract class GridCellStyle {}

class CellSingleFocusNode extends FocusNode {
VoidCallback? _listener;

void setSingleListener(VoidCallback listener) {
if (_listener != null) {
removeListener(_listener!);
}

_listener = listener;
super.addListener(listener);
}

void removeSingleListener() {
if (_listener != null) {
removeListener(_listener!);
}
}
}

class CellStateNotifier extends ChangeNotifier {
bool _isFocus = false;
bool _onEnter = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,16 @@ class NumberCell extends GridCellWidget {
class _NumberCellState extends State<NumberCell> {
late NumberCellBloc _cellBloc;
late TextEditingController _controller;
late FocusNode _focusNode;
late CellSingleFocusNode _focusNode;
Timer? _delayOperation;

@override
void initState() {
final cellContext = widget.cellContextBuilder.build();
_cellBloc = getIt<NumberCellBloc>(param1: cellContext)..add(const NumberCellEvent.initial());
_controller = TextEditingController(text: _cellBloc.state.content);
_focusNode = FocusNode();
_focusNode.addListener(() {
widget.onFocus.value = _focusNode.hasFocus;
focusChanged();
});
_focusNode = CellSingleFocusNode();
_listenFocusNode();
super.initState();
}

Expand Down Expand Up @@ -72,10 +69,19 @@ class _NumberCellState extends State<NumberCell> {
widget.requestFocus.removeAllListener();
_delayOperation?.cancel();
_cellBloc.close();
_focusNode.removeSingleListener();
_focusNode.dispose();
super.dispose();
}

@override
void didUpdateWidget(covariant NumberCell oldWidget) {
if (oldWidget != widget) {
_listenFocusNode();
}
super.didUpdateWidget(oldWidget);
}

Future<void> focusChanged() async {
if (mounted) {
_delayOperation?.cancel();
Expand All @@ -92,6 +98,14 @@ class _NumberCellState extends State<NumberCell> {
}
}

void _listenFocusNode() {
widget.onFocus.value = _focusNode.hasFocus;
_focusNode.setSingleListener(() {
widget.onFocus.value = _focusNode.hasFocus;
focusChanged();
});
}

void _listenCellRequestFocus(BuildContext context) {
widget.requestFocus.addListener(() {
if (_focusNode.hasFocus == false && _focusNode.canRequestFocus) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ class GridTextCell extends GridCellWidget {
class _GridTextCellState extends State<GridTextCell> {
late TextCellBloc _cellBloc;
late TextEditingController _controller;
late FocusNode _focusNode;

VoidCallback? _focusNodeListener;
late CellSingleFocusNode _focusNode;
Timer? _delayOperation;

@override
Expand All @@ -46,44 +44,37 @@ class _GridTextCellState extends State<GridTextCell> {
_cellBloc = getIt<TextCellBloc>(param1: cellContext);
_cellBloc.add(const TextCellEvent.initial());
_controller = TextEditingController(text: _cellBloc.state.content);
_focusNode = FocusNode();
_focusNode.addListener(() {
widget.onFocus.value = _focusNode.hasFocus;
focusChanged();
});
_focusNode = CellSingleFocusNode();

_listenFocusNode();
_listenRequestFocus(context);
super.initState();
}

@override
Widget build(BuildContext context) {
_listenCellRequestFocus(context);

return BlocProvider.value(
value: _cellBloc,
child: BlocConsumer<TextCellBloc, TextCellState>(
child: BlocListener<TextCellBloc, TextCellState>(
listener: (context, state) {
if (_controller.text != state.content) {
_controller.text = state.content;
}
},
buildWhen: (previous, current) => previous.content != current.content,
builder: (context, state) {
return TextField(
controller: _controller,
focusNode: _focusNode,
onChanged: (value) => focusChanged(),
onEditingComplete: () => _focusNode.unfocus(),
maxLines: null,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
decoration: InputDecoration(
contentPadding: EdgeInsets.zero,
border: InputBorder.none,
hintText: widget.cellStyle?.placeholder,
isDense: true,
),
);
},
child: TextField(
controller: _controller,
focusNode: _focusNode,
onChanged: (value) => focusChanged(),
onEditingComplete: () => _focusNode.unfocus(),
maxLines: null,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
decoration: InputDecoration(
contentPadding: EdgeInsets.zero,
border: InputBorder.none,
hintText: widget.cellStyle?.placeholder,
isDense: true,
),
),
),
);
}
Expand All @@ -93,17 +84,29 @@ class _GridTextCellState extends State<GridTextCell> {
widget.requestFocus.removeAllListener();
_delayOperation?.cancel();
_cellBloc.close();
_focusNode.removeSingleListener();
_focusNode.dispose();

super.dispose();
}

@override
void didUpdateWidget(covariant GridTextCell oldWidget) {
// TODO: implement didUpdateWidget
if (oldWidget != widget) {
_listenFocusNode();
}
super.didUpdateWidget(oldWidget);
}

void _listenCellRequestFocus(BuildContext context) {
void _listenFocusNode() {
widget.onFocus.value = _focusNode.hasFocus;
_focusNode.setSingleListener(() {
widget.onFocus.value = _focusNode.hasFocus;
focusChanged();
});
}

void _listenRequestFocus(BuildContext context) {
widget.requestFocus.addListener(() {
if (_focusNode.hasFocus == false && _focusNode.canRequestFocus) {
FocusScope.of(context).requestFocus(_focusNode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/p
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart';
Expand Down Expand Up @@ -153,14 +154,14 @@ class _RowCells extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<RowBloc, RowState>(
buildWhen: (previous, current) => previous.cellDataMap != current.cellDataMap,
buildWhen: (previous, current) => !listEquals(previous.snapshots, current.snapshots),
builder: (context, state) {
return IntrinsicHeight(
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: _makeCells(context, state.cellDataMap),
children: _makeCells(context, state.gridCellMap),
));
},
);
Expand Down

0 comments on commit 518d111

Please sign in to comment.