mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: format number cell
This commit is contained in:
parent
943b4507ac
commit
a707410548
@ -156,13 +156,6 @@ void _resolveGridDeps(GetIt getIt) {
|
||||
),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<GridHeaderBloc, String, List<Field>>(
|
||||
(gridId, fields) => GridHeaderBloc(
|
||||
data: GridHeaderData(gridId: gridId, fields: fields),
|
||||
service: FieldService(gridId: gridId),
|
||||
),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<FieldActionSheetBloc, GridFieldCellContext, void>(
|
||||
(data, _) => FieldActionSheetBloc(
|
||||
field: data.field,
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_listener.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';
|
||||
@ -11,12 +12,14 @@ part 'number_cell_bloc.freezed.dart';
|
||||
|
||||
class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
|
||||
final CellService _service;
|
||||
final CellListener _listener;
|
||||
final CellListener _cellListener;
|
||||
final FieldListener _fieldListener;
|
||||
|
||||
NumberCellBloc({
|
||||
required CellData cellData,
|
||||
}) : _service = CellService(),
|
||||
_listener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id),
|
||||
_cellListener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id),
|
||||
_fieldListener = FieldListener(fieldId: cellData.field.id),
|
||||
super(NumberCellState.initial(cellData)) {
|
||||
on<NumberCellEvent>(
|
||||
(event, emit) async {
|
||||
@ -27,36 +30,36 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
|
||||
didReceiveCellUpdate: (_DidReceiveCellUpdate value) {
|
||||
emit(state.copyWith(content: value.cell.content));
|
||||
},
|
||||
updateCell: (_UpdateCell value) {
|
||||
_updateCellValue(value, emit);
|
||||
updateCell: (_UpdateCell value) async {
|
||||
await _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,
|
||||
);
|
||||
}
|
||||
Future<void> _updateCellValue(_UpdateCell value, Emitter<NumberCellState> emit) async {
|
||||
final result = await _service.updateCell(
|
||||
gridId: state.cellData.gridId,
|
||||
fieldId: state.cellData.field.id,
|
||||
rowId: state.cellData.rowId,
|
||||
data: value.text,
|
||||
);
|
||||
result.fold(
|
||||
(field) => _getCellData(),
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _listener.stop();
|
||||
await _cellListener.stop();
|
||||
await _fieldListener.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _startListening() {
|
||||
_listener.updateCellNotifier.addPublishListener((result) {
|
||||
_cellListener.updateCellNotifier.addPublishListener((result) {
|
||||
result.fold(
|
||||
(notificationData) async {
|
||||
await _getCellData();
|
||||
@ -64,7 +67,15 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
_listener.start();
|
||||
_cellListener.start();
|
||||
|
||||
_fieldListener.updateFieldNotifier.addPublishListener((result) {
|
||||
result.fold(
|
||||
(field) => _getCellData(),
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
_fieldListener.start();
|
||||
}
|
||||
|
||||
Future<void> _getCellData() async {
|
||||
|
@ -26,7 +26,13 @@ class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
|
||||
didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) {
|
||||
emit(state.copyWith(field: value.field));
|
||||
},
|
||||
updateWidth: (_UpdateWidth value) {},
|
||||
updateWidth: (_UpdateWidth value) {
|
||||
final defaultWidth = state.field.width.toDouble();
|
||||
final width = defaultWidth + value.offset;
|
||||
if (width > defaultWidth && width < 300) {
|
||||
_fieldService.updateField(fieldId: state.field.id, width: width);
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -1,72 +0,0 @@
|
||||
import 'package:app_flowy/workspace/application/grid/data.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/field/grid_listenr.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';
|
||||
import 'dart:async';
|
||||
import 'field_service.dart';
|
||||
|
||||
part 'grid_header_bloc.freezed.dart';
|
||||
|
||||
class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
|
||||
final FieldService service;
|
||||
final GridFieldsListener _fieldListener;
|
||||
|
||||
GridHeaderBloc({
|
||||
required GridHeaderData data,
|
||||
required this.service,
|
||||
}) : _fieldListener = GridFieldsListener(gridId: data.gridId),
|
||||
super(GridHeaderState.initial(data.fields)) {
|
||||
on<GridHeaderEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
initial: (_InitialHeader value) async {
|
||||
_startListening();
|
||||
},
|
||||
createField: (_CreateField value) {},
|
||||
insertField: (_InsertField value) {},
|
||||
didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) {
|
||||
value.fields.retainWhere((field) => field.visibility);
|
||||
emit(state.copyWith(fields: value.fields));
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _startListening() async {
|
||||
_fieldListener.updateFieldsNotifier.addPublishListener((result) {
|
||||
result.fold(
|
||||
(fields) => add(GridHeaderEvent.didReceiveFieldUpdate(fields)),
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
|
||||
_fieldListener.start();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _fieldListener.stop();
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class GridHeaderEvent with _$GridHeaderEvent {
|
||||
const factory GridHeaderEvent.initial() = _InitialHeader;
|
||||
const factory GridHeaderEvent.createField() = _CreateField;
|
||||
const factory GridHeaderEvent.insertField({required bool onLeft}) = _InsertField;
|
||||
const factory GridHeaderEvent.didReceiveFieldUpdate(List<Field> fields) = _DidReceiveFieldUpdate;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class GridHeaderState with _$GridHeaderState {
|
||||
const factory GridHeaderState({required List<Field> fields}) = _GridHeaderState;
|
||||
|
||||
factory GridHeaderState.initial(List<Field> fields) {
|
||||
fields.retainWhere((field) => field.visibility);
|
||||
return GridHeaderState(fields: fields);
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ export 'data.dart';
|
||||
|
||||
// Field
|
||||
export 'field/field_service.dart';
|
||||
export 'field/grid_header_bloc.dart';
|
||||
export 'field/field_action_sheet_bloc.dart';
|
||||
export 'field/field_editor_bloc.dart';
|
||||
export 'field/field_switch_bloc.dart';
|
||||
|
@ -85,7 +85,7 @@ class _FlowyGridState extends State<FlowyGrid> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<GridBloc, GridState>(
|
||||
buildWhen: (previous, current) => previous.fields != current.fields,
|
||||
buildWhen: (previous, current) => previous.fields.length != current.fields.length,
|
||||
builder: (context, state) {
|
||||
if (state.fields.isEmpty) {
|
||||
return const Center(child: CircularProgressIndicator.adaptive());
|
||||
@ -99,10 +99,10 @@ class _FlowyGridState extends State<FlowyGrid> {
|
||||
physics: StyledScrollPhysics(),
|
||||
controller: _scrollController.verticalController,
|
||||
slivers: [
|
||||
_renderToolbar(state.gridId),
|
||||
_renderHeader(state.gridId),
|
||||
_renderRows(gridId: state.gridId, context: context),
|
||||
const GridFooter(),
|
||||
const _GridToolbarAdaptor(),
|
||||
GridHeader(gridId: state.gridId, fields: List.from(state.fields)),
|
||||
_GridRows(),
|
||||
const SliverToBoxAdapter(child: GridFooter()),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -125,33 +125,35 @@ class _FlowyGridState extends State<FlowyGrid> {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _renderHeader(String gridId) {
|
||||
return BlocSelector<GridBloc, GridState, List<Field>>(
|
||||
selector: (state) => state.fields,
|
||||
builder: (context, fields) {
|
||||
return GridHeader(gridId: gridId, fields: List.from(fields));
|
||||
},
|
||||
);
|
||||
}
|
||||
class _GridToolbarAdaptor extends StatelessWidget {
|
||||
const _GridToolbarAdaptor({Key? key}) : super(key: key);
|
||||
|
||||
Widget _renderToolbar(String gridId) {
|
||||
return BlocSelector<GridBloc, GridState, List<Field>>(
|
||||
selector: (state) => state.fields,
|
||||
builder: (context, fields) {
|
||||
final toolbarContext = GridToolbarContext(
|
||||
gridId: gridId,
|
||||
fields: fields,
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocSelector<GridBloc, GridState, GridToolbarContext>(
|
||||
selector: (state) {
|
||||
return GridToolbarContext(
|
||||
gridId: state.gridId,
|
||||
fields: state.fields,
|
||||
);
|
||||
|
||||
},
|
||||
builder: (context, toolbarContext) {
|
||||
return SliverToBoxAdapter(
|
||||
child: GridToolbar(toolbarContext: toolbarContext),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _renderRows({required String gridId, required BuildContext context}) {
|
||||
class _GridRows extends StatelessWidget {
|
||||
final _key = GlobalKey<SliverAnimatedListState>();
|
||||
_GridRows({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocConsumer<GridBloc, GridState>(
|
||||
listener: (context, state) {
|
||||
state.listState.map(
|
||||
|
@ -26,7 +26,7 @@ class _NumberCellState extends State<NumberCell> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_cellBloc = getIt<NumberCellBloc>(param1: widget.cellData);
|
||||
_cellBloc = getIt<NumberCellBloc>(param1: widget.cellData)..add(const NumberCellEvent.initial());
|
||||
_controller = TextEditingController(text: _cellBloc.state.content);
|
||||
_focusNode = CellFocusNode();
|
||||
super.initState();
|
||||
@ -48,7 +48,6 @@ class _NumberCellState extends State<NumberCell> {
|
||||
return TextField(
|
||||
controller: _controller,
|
||||
focusNode: _focusNode,
|
||||
onChanged: (value) => focusChanged(),
|
||||
onEditingComplete: () => _focusNode.unfocus(),
|
||||
maxLines: 1,
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
@ -76,7 +75,12 @@ class _NumberCellState extends State<NumberCell> {
|
||||
_delayOperation?.cancel();
|
||||
_delayOperation = Timer(const Duration(milliseconds: 300), () {
|
||||
if (_cellBloc.isClosed == false && _controller.text != _cellBloc.state.content) {
|
||||
_cellBloc.add(NumberCellEvent.updateCell(_controller.text));
|
||||
final number = num.tryParse(_controller.text);
|
||||
if (number != null) {
|
||||
_cellBloc.add(NumberCellEvent.updateCell(_controller.text));
|
||||
} else {
|
||||
_controller.text = "";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -12,17 +12,15 @@ class GridFooter extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliverToBoxAdapter(
|
||||
child: SizedBox(
|
||||
height: GridSize.footerHeight,
|
||||
child: Padding(
|
||||
padding: GridSize.headerContentInsets,
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(width: GridSize.leadingHeaderPadding),
|
||||
const SizedBox(width: 120, child: _AddRowButton()),
|
||||
],
|
||||
),
|
||||
return SizedBox(
|
||||
height: GridSize.footerHeight,
|
||||
child: Padding(
|
||||
padding: GridSize.headerContentInsets,
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(width: GridSize.leadingHeaderPadding),
|
||||
const SizedBox(width: 120, child: _AddRowButton()),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -41,7 +41,7 @@ class GridFieldCell extends StatelessWidget {
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onHorizontalDragCancel: () {},
|
||||
onHorizontalDragUpdate: (value) {
|
||||
Log.info(value.delta);
|
||||
context.read<FieldCellBloc>().add(FieldCellEvent.updateWidth(value.delta.dx));
|
||||
},
|
||||
child: FlowyHover(
|
||||
style: HoverStyle(
|
||||
|
@ -19,21 +19,10 @@ class GridHeader extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) {
|
||||
final bloc = getIt<GridHeaderBloc>(param1: gridId, param2: fields);
|
||||
bloc.add(const GridHeaderEvent.initial());
|
||||
return bloc;
|
||||
},
|
||||
child: BlocBuilder<GridHeaderBloc, GridHeaderState>(
|
||||
builder: (context, state) {
|
||||
return SliverPersistentHeader(
|
||||
delegate: _GridHeaderDelegate(gridId: gridId, fields: List.from(state.fields)),
|
||||
floating: true,
|
||||
pinned: true,
|
||||
);
|
||||
},
|
||||
),
|
||||
return SliverPersistentHeader(
|
||||
delegate: _GridHeaderDelegate(gridId: gridId, fields: List.from(fields)),
|
||||
floating: true,
|
||||
pinned: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -74,21 +74,21 @@ class _StyledSingleChildScrollViewState extends State<StyledSingleChildScrollVie
|
||||
}
|
||||
|
||||
class StyledCustomScrollView extends StatefulWidget {
|
||||
final double? contentSize;
|
||||
final Axis axis;
|
||||
final Color? trackColor;
|
||||
final Color? handleColor;
|
||||
final ScrollController? controller;
|
||||
final ScrollController? verticalController;
|
||||
final List<Widget> slivers;
|
||||
final double barSize;
|
||||
|
||||
const StyledCustomScrollView({
|
||||
Key? key,
|
||||
this.contentSize,
|
||||
this.axis = Axis.vertical,
|
||||
this.trackColor,
|
||||
this.handleColor,
|
||||
this.controller,
|
||||
this.verticalController,
|
||||
this.slivers = const <Widget>[],
|
||||
this.barSize = 12,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@ -96,17 +96,17 @@ class StyledCustomScrollView extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _StyledCustomScrollViewState extends State<StyledCustomScrollView> {
|
||||
late ScrollController scrollController;
|
||||
late ScrollController controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
scrollController = widget.controller ?? ScrollController();
|
||||
controller = widget.verticalController ?? ScrollController();
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@ -120,19 +120,23 @@ class _StyledCustomScrollViewState extends State<StyledCustomScrollView> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ScrollbarListStack(
|
||||
contentSize: widget.contentSize,
|
||||
axis: widget.axis,
|
||||
controller: scrollController,
|
||||
barSize: 12,
|
||||
trackColor: widget.trackColor,
|
||||
handleColor: widget.handleColor,
|
||||
var child = ScrollConfiguration(
|
||||
behavior: const ScrollBehavior().copyWith(scrollbars: false),
|
||||
child: CustomScrollView(
|
||||
scrollDirection: widget.axis,
|
||||
physics: StyledScrollPhysics(),
|
||||
controller: scrollController,
|
||||
controller: controller,
|
||||
slivers: widget.slivers,
|
||||
),
|
||||
);
|
||||
|
||||
return ScrollbarListStack(
|
||||
axis: widget.axis,
|
||||
controller: controller,
|
||||
barSize: widget.barSize,
|
||||
trackColor: widget.trackColor,
|
||||
handleColor: widget.handleColor,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user