mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: optimize cell focus
This commit is contained in:
parent
d0b4abb0c8
commit
f972cdd3fb
@ -44,7 +44,16 @@ class BlankCell extends StatelessWidget {
|
||||
abstract class GridCellWidget extends HoverWidget {
|
||||
@override
|
||||
final ValueNotifier<bool> onFocus = ValueNotifier<bool>(false);
|
||||
|
||||
final GridCellRequestFocusNotifier requestFocus = GridCellRequestFocusNotifier();
|
||||
|
||||
GridCellWidget({Key? key}) : super(key: key);
|
||||
}
|
||||
|
||||
class GridCellRequestFocusNotifier extends ChangeNotifier {
|
||||
void notify() {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class GridCellStyle {}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
@ -31,17 +32,20 @@ class CellContainer extends StatelessWidget {
|
||||
final GridCellWidget child;
|
||||
final Widget? expander;
|
||||
final double width;
|
||||
final RegionStateNotifier rowStateNotifier;
|
||||
const CellContainer({
|
||||
Key? key,
|
||||
required this.child,
|
||||
required this.width,
|
||||
required this.rowStateNotifier,
|
||||
this.expander,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
return ChangeNotifierProxyProvider<RegionStateNotifier, CellStateNotifier>(
|
||||
create: (_) => CellStateNotifier(),
|
||||
update: (_, row, cell) => cell!..onEnter = row.onEnter,
|
||||
child: Selector<CellStateNotifier, bool>(
|
||||
selector: (context, notifier) => notifier.isFocus,
|
||||
builder: (context, isFocus, _) {
|
||||
@ -54,11 +58,15 @@ class CellContainer extends StatelessWidget {
|
||||
container = _CellEnterRegion(child: container, expander: expander!);
|
||||
}
|
||||
|
||||
return Container(
|
||||
constraints: BoxConstraints(maxWidth: width),
|
||||
decoration: _makeBoxDecoration(context, isFocus),
|
||||
padding: GridSize.cellContentInsets,
|
||||
child: container,
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onTap: () => child.requestFocus.notify(),
|
||||
child: Container(
|
||||
constraints: BoxConstraints(maxWidth: width),
|
||||
decoration: _makeBoxDecoration(context, isFocus),
|
||||
padding: GridSize.cellContentInsets,
|
||||
child: container,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
@ -24,6 +24,7 @@ class _CheckboxCellState extends State<CheckboxCell> {
|
||||
void initState() {
|
||||
final cellContext = widget.cellContextBuilder.build();
|
||||
_cellBloc = getIt<CheckboxCellBloc>(param1: cellContext)..add(const CheckboxCellEvent.initial());
|
||||
_listenCellRequestFocus();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@ -48,9 +49,21 @@ class _CheckboxCellState extends State<CheckboxCell> {
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant CheckboxCell oldWidget) {
|
||||
_listenCellRequestFocus();
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
_cellBloc.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _listenCellRequestFocus() {
|
||||
widget.requestFocus.addListener(() {
|
||||
_cellBloc.add(const CheckboxCellEvent.select());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ class _NumberCellState extends State<NumberCell> {
|
||||
late NumberCellBloc _cellBloc;
|
||||
late TextEditingController _controller;
|
||||
late FocusNode _focusNode;
|
||||
VoidCallback? _focusListener;
|
||||
Timer? _delayOperation;
|
||||
|
||||
@override
|
||||
@ -40,6 +41,7 @@ class _NumberCellState extends State<NumberCell> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_listenCellRequestFocus(context);
|
||||
return BlocProvider.value(
|
||||
value: _cellBloc,
|
||||
child: BlocConsumer<NumberCellBloc, NumberCellState>(
|
||||
@ -68,6 +70,9 @@ class _NumberCellState extends State<NumberCell> {
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
if (_focusListener != null) {
|
||||
widget.requestFocus.removeListener(_focusListener!);
|
||||
}
|
||||
_delayOperation?.cancel();
|
||||
_cellBloc.close();
|
||||
_focusNode.dispose();
|
||||
@ -89,4 +94,19 @@ class _NumberCellState extends State<NumberCell> {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _listenCellRequestFocus(BuildContext context) {
|
||||
if (_focusListener != null) {
|
||||
widget.requestFocus.removeListener(_focusListener!);
|
||||
}
|
||||
|
||||
focusListener() {
|
||||
if (_focusNode.hasFocus == false && _focusNode.canRequestFocus) {
|
||||
FocusScope.of(context).requestFocus(_focusNode);
|
||||
}
|
||||
}
|
||||
|
||||
_focusListener = focusListener;
|
||||
widget.requestFocus.addListener(focusListener);
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class _GridTextCellState extends State<GridTextCell> {
|
||||
late TextCellBloc _cellBloc;
|
||||
late TextEditingController _controller;
|
||||
late FocusNode _focusNode;
|
||||
|
||||
VoidCallback? _focusListener;
|
||||
Timer? _delayOperation;
|
||||
|
||||
@override
|
||||
@ -50,11 +50,14 @@ class _GridTextCellState extends State<GridTextCell> {
|
||||
widget.onFocus.value = _focusNode.hasFocus;
|
||||
focusChanged();
|
||||
});
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_listenCellRequestFocus(context);
|
||||
|
||||
return BlocProvider.value(
|
||||
value: _cellBloc,
|
||||
child: BlocConsumer<TextCellBloc, TextCellState>(
|
||||
@ -84,8 +87,26 @@ class _GridTextCellState extends State<GridTextCell> {
|
||||
);
|
||||
}
|
||||
|
||||
void _listenCellRequestFocus(BuildContext context) {
|
||||
if (_focusListener != null) {
|
||||
widget.requestFocus.removeListener(_focusListener!);
|
||||
}
|
||||
|
||||
focusListener() {
|
||||
if (_focusNode.hasFocus == false && _focusNode.canRequestFocus) {
|
||||
FocusScope.of(context).requestFocus(_focusNode);
|
||||
}
|
||||
}
|
||||
|
||||
_focusListener = focusListener;
|
||||
widget.requestFocus.addListener(focusListener);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
if (_focusListener != null) {
|
||||
widget.requestFocus.removeListener(_focusListener!);
|
||||
}
|
||||
_delayOperation?.cancel();
|
||||
_cellBloc.close();
|
||||
_focusNode.dispose();
|
||||
|
@ -88,7 +88,7 @@ class _RowLeading extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<_RegionStateNotifier>(
|
||||
return Consumer<RegionStateNotifier>(
|
||||
builder: (context, state, _) {
|
||||
return SizedBox(width: GridSize.leadingHeaderPadding, child: state.onEnter ? _activeWidget() : null);
|
||||
},
|
||||
@ -164,13 +164,13 @@ class _RowCells extends StatelessWidget {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: _makeCells(state.cellDataMap),
|
||||
children: _makeCells(context, state.cellDataMap),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _makeCells(GridCellMap gridCellMap) {
|
||||
List<Widget> _makeCells(BuildContext context, GridCellMap gridCellMap) {
|
||||
return gridCellMap.values.map(
|
||||
(gridCell) {
|
||||
Widget? expander;
|
||||
@ -181,6 +181,7 @@ class _RowCells extends StatelessWidget {
|
||||
return CellContainer(
|
||||
width: gridCell.field.width.toDouble(),
|
||||
child: buildGridCellWidget(gridCell, cellCache),
|
||||
rowStateNotifier: Provider.of<RegionStateNotifier>(context, listen: false),
|
||||
expander: expander,
|
||||
);
|
||||
},
|
||||
@ -188,7 +189,7 @@ class _RowCells extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _RegionStateNotifier extends ChangeNotifier {
|
||||
class RegionStateNotifier extends ChangeNotifier {
|
||||
bool _onEnter = false;
|
||||
|
||||
set onEnter(bool value) {
|
||||
@ -226,11 +227,11 @@ class _RowEnterRegion extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _RowEnterRegionState extends State<_RowEnterRegion> {
|
||||
late _RegionStateNotifier _rowStateNotifier;
|
||||
late RegionStateNotifier _rowStateNotifier;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_rowStateNotifier = _RegionStateNotifier();
|
||||
_rowStateNotifier = RegionStateNotifier();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user