chore: config number ui

This commit is contained in:
appflowy 2022-04-07 20:54:22 +08:00
parent e15d335fed
commit 11627269be
6 changed files with 106 additions and 13 deletions

View File

@ -194,7 +194,6 @@ void _resolveGridDeps(GetIt getIt) {
getIt.registerFactoryParam<NumberCellBloc, CellData, void>( getIt.registerFactoryParam<NumberCellBloc, CellData, void>(
(cellData, _) => NumberCellBloc( (cellData, _) => NumberCellBloc(
service: CellService(),
cellData: cellData, cellData: cellData,
), ),
); );

View File

@ -26,7 +26,7 @@ class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
_startListening(); _startListening();
}, },
select: (_Selected value) async { select: (_Selected value) async {
service.updateCell( _service.updateCell(
gridId: state.cellData.gridId, gridId: state.cellData.gridId,
fieldId: state.cellData.field.id, fieldId: state.cellData.field.id,
rowId: state.cellData.rowId, rowId: state.cellData.rowId,
@ -43,6 +43,7 @@ class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
@override @override
Future<void> close() async { Future<void> close() async {
await _listener.stop();
return super.close(); return super.close();
} }

View File

@ -1,4 +1,6 @@
import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart';
import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.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-data-model/grid.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
@ -8,37 +10,87 @@ import 'cell_service.dart';
part 'number_cell_bloc.freezed.dart'; part 'number_cell_bloc.freezed.dart';
class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> { class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
final CellService service; final CellService _service;
final CellListener _listener;
NumberCellBloc({ NumberCellBloc({
required this.service,
required CellData cellData, required CellData cellData,
}) : super(NumberCellState.initial()) { }) : _service = CellService(),
_listener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id),
super(NumberCellState.initial(cellData)) {
on<NumberCellEvent>( on<NumberCellEvent>(
(event, emit) async { (event, emit) async {
await event.map( await event.map(
initial: (_InitialCell value) async {}, initial: (_Initial value) async {
_startListening();
},
didReceiveCellUpdate: (_DidReceiveCellUpdate value) {
emit(state.copyWith(content: value.cell.content));
},
updateCell: (_UpdateCell value) {
_updateCellValue(value, emit);
},
); );
}, },
); );
} }
void _updateCellValue(_UpdateCell value, Emitter<NumberCellState> emit) {
final number = num.tryParse(value.text);
if (number == null) {
emit(state.copyWith(content: ""));
} else {
_service.updateCell(
gridId: state.cellData.gridId,
fieldId: state.cellData.field.id,
rowId: state.cellData.rowId,
data: value.text,
);
}
}
@override @override
Future<void> close() async { Future<void> close() async {
await _listener.stop();
return super.close(); return super.close();
} }
void _startListening() {
_listener.updateCellNotifier.addPublishListener((result) {
result.fold(
(notificationData) async {
final result = await _service.getCell(
gridId: state.cellData.gridId,
fieldId: state.cellData.field.id,
rowId: state.cellData.rowId,
);
result.fold(
(cell) => add(NumberCellEvent.didReceiveCellUpdate(cell)),
(err) => Log.error(err),
);
},
(err) => Log.error(err),
);
});
_listener.start();
}
} }
@freezed @freezed
class NumberCellEvent with _$NumberCellEvent { class NumberCellEvent with _$NumberCellEvent {
const factory NumberCellEvent.initial() = _InitialCell; const factory NumberCellEvent.initial() = _Initial;
const factory NumberCellEvent.updateCell(String text) = _UpdateCell;
const factory NumberCellEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate;
} }
@freezed @freezed
class NumberCellState with _$NumberCellState { class NumberCellState with _$NumberCellState {
const factory NumberCellState({ const factory NumberCellState({
Cell? cell, required CellData cellData,
required String content,
}) = _NumberCellState; }) = _NumberCellState;
factory NumberCellState.initial() => const NumberCellState(); factory NumberCellState.initial(CellData cellData) {
return NumberCellState(cellData: cellData, content: cellData.cell?.content ?? "");
}
} }

View File

@ -1,5 +1,8 @@
import 'dart:async';
import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart';
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
@ -17,20 +20,44 @@ class NumberCell extends StatefulWidget {
class _NumberCellState extends State<NumberCell> { class _NumberCellState extends State<NumberCell> {
late NumberCellBloc _cellBloc; late NumberCellBloc _cellBloc;
late TextEditingController _controller;
late CellFocusNode _focusNode;
Timer? _delayOperation;
@override @override
void initState() { void initState() {
_cellBloc = getIt<NumberCellBloc>(param1: widget.cellData); _cellBloc = getIt<NumberCellBloc>(param1: widget.cellData);
_controller = TextEditingController(text: _cellBloc.state.content);
_focusNode = CellFocusNode();
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_focusNode.addCallback(context, focusChanged);
return BlocProvider.value( return BlocProvider.value(
value: _cellBloc, value: _cellBloc,
child: BlocBuilder<NumberCellBloc, NumberCellState>( child: BlocConsumer<NumberCellBloc, NumberCellState>(
listener: (context, state) {
if (_controller.text != state.content) {
_controller.text = state.content;
}
},
builder: (context, state) { builder: (context, state) {
return Container(); return TextField(
controller: _controller,
focusNode: _focusNode,
onChanged: (value) => focusChanged(),
onEditingComplete: () => _focusNode.unfocus(),
maxLines: 1,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
decoration: const InputDecoration(
contentPadding: EdgeInsets.zero,
border: InputBorder.none,
isDense: true,
),
);
}, },
), ),
); );
@ -38,7 +65,20 @@ class _NumberCellState extends State<NumberCell> {
@override @override
Future<void> dispose() async { Future<void> dispose() async {
_delayOperation?.cancel();
_cellBloc.close(); _cellBloc.close();
_focusNode.dispose();
super.dispose(); super.dispose();
} }
Future<void> focusChanged() async {
if (mounted) {
_delayOperation?.cancel();
_delayOperation = Timer(const Duration(milliseconds: 300), () {
if (_cellBloc.isClosed == false && _controller.text != _cellBloc.state.content) {
_cellBloc.add(NumberCellEvent.updateCell(_controller.text));
}
});
}
}
} }

View File

@ -63,6 +63,7 @@ class _GridTextCellState extends State<GridTextCell> {
@override @override
Future<void> dispose() async { Future<void> dispose() async {
_delayOperation?.cancel();
_cellBloc.close(); _cellBloc.close();
_focusNode.dispose(); _focusNode.dispose();
super.dispose(); super.dispose();
@ -72,7 +73,7 @@ class _GridTextCellState extends State<GridTextCell> {
if (mounted) { if (mounted) {
_delayOperation?.cancel(); _delayOperation?.cancel();
_delayOperation = Timer(const Duration(milliseconds: 300), () { _delayOperation = Timer(const Duration(milliseconds: 300), () {
if (_cellBloc.isClosed == false) { if (_cellBloc.isClosed == false && _controller.text != _cellBloc.state.content) {
_cellBloc.add(TextCellEvent.updateText(_controller.text)); _cellBloc.add(TextCellEvent.updateText(_controller.text));
} }
}); });

View File

@ -19,7 +19,7 @@ class FieldTypeList extends StatelessWidget with FlowyOverlayDelegate {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final cells = FieldType.values.map((fieldType) { final cells = FieldType.values.where((ty) => ty != FieldType.DateTime).map((fieldType) {
return FieldTypeCell( return FieldTypeCell(
fieldType: fieldType, fieldType: fieldType,
onSelectField: (fieldType) { onSelectField: (fieldType) {