mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
refactor: add GridCellState and GridFocusNodeCellState
This commit is contained in:
parent
81efee557c
commit
4887885aae
@ -48,7 +48,9 @@ class BlankCell extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class GridCellWidget implements AccessoryWidget, CellContainerFocustable {
|
||||
abstract class GridCellWidget extends StatefulWidget implements AccessoryWidget, CellContainerFocustable {
|
||||
GridCellWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
final ValueNotifier<bool> isFocus = ValueNotifier<bool>(false);
|
||||
|
||||
@ -59,6 +61,72 @@ abstract class GridCellWidget implements AccessoryWidget, CellContainerFocustabl
|
||||
final GridCellRequestBeginFocus requestBeginFocus = GridCellRequestBeginFocus();
|
||||
}
|
||||
|
||||
abstract class GridCellState<T extends GridCellWidget> extends State<T> {
|
||||
@override
|
||||
void initState() {
|
||||
widget.requestBeginFocus.setListener(() => requestBeginFocus());
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant T oldWidget) {
|
||||
if (oldWidget != this) {
|
||||
widget.requestBeginFocus.setListener(() => requestBeginFocus());
|
||||
}
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
widget.requestBeginFocus.removeAllListener();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void requestBeginFocus();
|
||||
}
|
||||
|
||||
abstract class GridFocusNodeCellState<T extends GridCellWidget> extends GridCellState<T> {
|
||||
SingleListenrFocusNode focusNode = SingleListenrFocusNode();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_listenOnFocusNodeChanged();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant T oldWidget) {
|
||||
if (oldWidget != this) {
|
||||
_listenOnFocusNodeChanged();
|
||||
}
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
focusNode.removeAllListener();
|
||||
focusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void requestBeginFocus() {
|
||||
if (focusNode.hasFocus == false && focusNode.canRequestFocus) {
|
||||
FocusScope.of(context).requestFocus(focusNode);
|
||||
}
|
||||
}
|
||||
|
||||
void _listenOnFocusNodeChanged() {
|
||||
widget.isFocus.value = focusNode.hasFocus;
|
||||
focusNode.setListener(() {
|
||||
widget.isFocus.value = focusNode.hasFocus;
|
||||
focusChanged();
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> focusChanged() async {}
|
||||
}
|
||||
|
||||
class GridCellRequestBeginFocus extends ChangeNotifier {
|
||||
VoidCallback? _listener;
|
||||
|
||||
|
@ -6,7 +6,7 @@ import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'cell_builder.dart';
|
||||
|
||||
class CheckboxCell extends StatefulWidget with GridCellWidget {
|
||||
class CheckboxCell extends GridCellWidget {
|
||||
final GridCellContextBuilder cellContextBuilder;
|
||||
CheckboxCell({
|
||||
required this.cellContextBuilder,
|
||||
@ -14,17 +14,17 @@ class CheckboxCell extends StatefulWidget with GridCellWidget {
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<CheckboxCell> createState() => _CheckboxCellState();
|
||||
GridCellState<CheckboxCell> createState() => _CheckboxCellState();
|
||||
}
|
||||
|
||||
class _CheckboxCellState extends State<CheckboxCell> {
|
||||
class _CheckboxCellState extends GridCellState<CheckboxCell> {
|
||||
late CheckboxCellBloc _cellBloc;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
final cellContext = widget.cellContextBuilder.build();
|
||||
_cellBloc = getIt<CheckboxCellBloc>(param1: cellContext)..add(const CheckboxCellEvent.initial());
|
||||
_handleRequestFocus();
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@ -49,22 +49,14 @@ class _CheckboxCellState extends State<CheckboxCell> {
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant CheckboxCell oldWidget) {
|
||||
_handleRequestFocus();
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
widget.requestBeginFocus.removeAllListener();
|
||||
_cellBloc.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _handleRequestFocus() {
|
||||
widget.requestBeginFocus.setListener(() {
|
||||
_cellBloc.add(const CheckboxCellEvent.select());
|
||||
});
|
||||
@override
|
||||
void requestBeginFocus() {
|
||||
_cellBloc.add(const CheckboxCellEvent.select());
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ abstract class GridCellDelegate {
|
||||
GridCellDelegate get delegate;
|
||||
}
|
||||
|
||||
class DateCell extends StatefulWidget with GridCellWidget {
|
||||
class DateCell extends GridCellWidget {
|
||||
final GridCellContextBuilder cellContextBuilder;
|
||||
late final DateCellStyle? cellStyle;
|
||||
|
||||
|
@ -7,7 +7,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'cell_builder.dart';
|
||||
|
||||
class NumberCell extends StatefulWidget with GridCellWidget {
|
||||
class NumberCell extends GridCellWidget {
|
||||
final GridCellContextBuilder cellContextBuilder;
|
||||
|
||||
NumberCell({
|
||||
@ -16,13 +16,12 @@ class NumberCell extends StatefulWidget with GridCellWidget {
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<NumberCell> createState() => _NumberCellState();
|
||||
GridFocusNodeCellState<NumberCell> createState() => _NumberCellState();
|
||||
}
|
||||
|
||||
class _NumberCellState extends State<NumberCell> {
|
||||
class _NumberCellState extends GridFocusNodeCellState<NumberCell> {
|
||||
late NumberCellBloc _cellBloc;
|
||||
late TextEditingController _controller;
|
||||
late SingleListenrFocusNode _focusNode;
|
||||
Timer? _delayOperation;
|
||||
|
||||
@override
|
||||
@ -30,14 +29,11 @@ class _NumberCellState extends State<NumberCell> {
|
||||
final cellContext = widget.cellContextBuilder.build();
|
||||
_cellBloc = getIt<NumberCellBloc>(param1: cellContext)..add(const NumberCellEvent.initial());
|
||||
_controller = TextEditingController(text: contentFromState(_cellBloc.state));
|
||||
_focusNode = SingleListenrFocusNode();
|
||||
_listenOnFocusNodeChanged();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_handleCellRequestFocus(context);
|
||||
return BlocProvider.value(
|
||||
value: _cellBloc,
|
||||
child: MultiBlocListener(
|
||||
@ -49,8 +45,8 @@ class _NumberCellState extends State<NumberCell> {
|
||||
],
|
||||
child: TextField(
|
||||
controller: _controller,
|
||||
focusNode: _focusNode,
|
||||
onEditingComplete: () => _focusNode.unfocus(),
|
||||
focusNode: focusNode,
|
||||
onEditingComplete: () => focusNode.unfocus(),
|
||||
maxLines: null,
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
decoration: const InputDecoration(
|
||||
@ -65,20 +61,12 @@ class _NumberCellState extends State<NumberCell> {
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
widget.requestBeginFocus.removeAllListener();
|
||||
_delayOperation?.cancel();
|
||||
_cellBloc.close();
|
||||
_focusNode.removeAllListener();
|
||||
_focusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant NumberCell oldWidget) {
|
||||
_listenOnFocusNodeChanged();
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
Future<void> focusChanged() async {
|
||||
if (mounted) {
|
||||
_delayOperation?.cancel();
|
||||
@ -90,22 +78,6 @@ class _NumberCellState extends State<NumberCell> {
|
||||
}
|
||||
}
|
||||
|
||||
void _listenOnFocusNodeChanged() {
|
||||
widget.isFocus.value = _focusNode.hasFocus;
|
||||
_focusNode.setListener(() {
|
||||
widget.isFocus.value = _focusNode.hasFocus;
|
||||
focusChanged();
|
||||
});
|
||||
}
|
||||
|
||||
void _handleCellRequestFocus(BuildContext context) {
|
||||
widget.requestBeginFocus.setListener(() {
|
||||
if (_focusNode.hasFocus == false && _focusNode.canRequestFocus) {
|
||||
FocusScope.of(context).requestFocus(_focusNode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
String contentFromState(NumberCellState state) {
|
||||
return state.content.fold((l) => l, (r) => "");
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ class SelectOptionCellStyle extends GridCellStyle {
|
||||
});
|
||||
}
|
||||
|
||||
class SingleSelectCell extends StatefulWidget with GridCellWidget {
|
||||
class SingleSelectCell extends GridCellWidget {
|
||||
final GridCellContextBuilder cellContextBuilder;
|
||||
late final SelectOptionCellStyle? cellStyle;
|
||||
|
||||
@ -74,7 +74,7 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
class MultiSelectCell extends StatefulWidget with GridCellWidget {
|
||||
class MultiSelectCell extends GridCellWidget {
|
||||
final GridCellContextBuilder cellContextBuilder;
|
||||
late final SelectOptionCellStyle? cellStyle;
|
||||
|
||||
|
@ -13,7 +13,7 @@ class GridTextCellStyle extends GridCellStyle {
|
||||
});
|
||||
}
|
||||
|
||||
class GridTextCell extends StatefulWidget with GridCellWidget {
|
||||
class GridTextCell extends GridCellWidget {
|
||||
final GridCellContextBuilder cellContextBuilder;
|
||||
late final GridTextCellStyle? cellStyle;
|
||||
GridTextCell({
|
||||
@ -29,13 +29,12 @@ class GridTextCell extends StatefulWidget with GridCellWidget {
|
||||
}
|
||||
|
||||
@override
|
||||
State<GridTextCell> createState() => _GridTextCellState();
|
||||
GridFocusNodeCellState<GridTextCell> createState() => _GridTextCellState();
|
||||
}
|
||||
|
||||
class _GridTextCellState extends State<GridTextCell> {
|
||||
class _GridTextCellState extends GridFocusNodeCellState<GridTextCell> {
|
||||
late TextCellBloc _cellBloc;
|
||||
late TextEditingController _controller;
|
||||
late SingleListenrFocusNode _focusNode;
|
||||
Timer? _delayOperation;
|
||||
|
||||
@override
|
||||
@ -44,10 +43,6 @@ class _GridTextCellState extends State<GridTextCell> {
|
||||
_cellBloc = getIt<TextCellBloc>(param1: cellContext);
|
||||
_cellBloc.add(const TextCellEvent.initial());
|
||||
_controller = TextEditingController(text: _cellBloc.state.content);
|
||||
_focusNode = SingleListenrFocusNode();
|
||||
|
||||
_listenOnFocusNodeChanged();
|
||||
_listenRequestFocus(context);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@ -63,9 +58,9 @@ class _GridTextCellState extends State<GridTextCell> {
|
||||
},
|
||||
child: TextField(
|
||||
controller: _controller,
|
||||
focusNode: _focusNode,
|
||||
focusNode: focusNode,
|
||||
onChanged: (value) => focusChanged(),
|
||||
onEditingComplete: () => _focusNode.unfocus(),
|
||||
onEditingComplete: () => focusNode.unfocus(),
|
||||
maxLines: null,
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
decoration: InputDecoration(
|
||||
@ -81,39 +76,12 @@ class _GridTextCellState extends State<GridTextCell> {
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
widget.requestBeginFocus.removeAllListener();
|
||||
_delayOperation?.cancel();
|
||||
_cellBloc.close();
|
||||
_focusNode.removeAllListener();
|
||||
_focusNode.dispose();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant GridTextCell oldWidget) {
|
||||
if (oldWidget != widget) {
|
||||
_listenOnFocusNodeChanged();
|
||||
}
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
void _listenOnFocusNodeChanged() {
|
||||
widget.isFocus.value = _focusNode.hasFocus;
|
||||
_focusNode.setListener(() {
|
||||
widget.isFocus.value = _focusNode.hasFocus;
|
||||
focusChanged();
|
||||
});
|
||||
}
|
||||
|
||||
void _listenRequestFocus(BuildContext context) {
|
||||
widget.requestBeginFocus.setListener(() {
|
||||
if (_focusNode.hasFocus == false && _focusNode.canRequestFocus) {
|
||||
FocusScope.of(context).requestFocus(_focusNode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> focusChanged() async {
|
||||
if (mounted) {
|
||||
_delayOperation?.cancel();
|
||||
|
@ -30,7 +30,7 @@ enum GridURLCellAccessoryType {
|
||||
copyURL,
|
||||
}
|
||||
|
||||
class GridURLCell extends StatefulWidget with GridCellWidget {
|
||||
class GridURLCell extends GridCellWidget {
|
||||
final GridCellContextBuilder cellContextBuilder;
|
||||
late final GridURLCellStyle? cellStyle;
|
||||
GridURLCell({
|
||||
@ -46,7 +46,7 @@ class GridURLCell extends StatefulWidget with GridCellWidget {
|
||||
}
|
||||
|
||||
@override
|
||||
State<GridURLCell> createState() => _GridURLCellState();
|
||||
GridCellState<GridURLCell> createState() => _GridURLCellState();
|
||||
|
||||
GridCellAccessory accessoryFromType(GridURLCellAccessoryType ty, GridCellAccessoryBuildContext buildContext) {
|
||||
switch (ty) {
|
||||
@ -78,7 +78,7 @@ class GridURLCell extends StatefulWidget with GridCellWidget {
|
||||
};
|
||||
}
|
||||
|
||||
class _GridURLCellState extends State<GridURLCell> {
|
||||
class _GridURLCellState extends GridCellState<GridURLCell> {
|
||||
late URLCellBloc _cellBloc;
|
||||
|
||||
@override
|
||||
@ -86,7 +86,6 @@ class _GridURLCellState extends State<GridURLCell> {
|
||||
final cellContext = widget.cellContextBuilder.build() as GridURLCellContext;
|
||||
_cellBloc = URLCellBloc(cellContext: cellContext);
|
||||
_cellBloc.add(const URLCellEvent.initial());
|
||||
_handleRequestFocus();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@ -125,17 +124,10 @@ class _GridURLCellState extends State<GridURLCell> {
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
widget.requestBeginFocus.removeAllListener();
|
||||
_cellBloc.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant GridURLCell oldWidget) {
|
||||
_handleRequestFocus();
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
Future<void> _openUrlOrEdit(String url) async {
|
||||
final uri = Uri.parse(url);
|
||||
if (url.isNotEmpty && await canLaunchUrl(uri)) {
|
||||
@ -146,10 +138,9 @@ class _GridURLCellState extends State<GridURLCell> {
|
||||
}
|
||||
}
|
||||
|
||||
void _handleRequestFocus() {
|
||||
widget.requestBeginFocus.setListener(() {
|
||||
_openUrlOrEdit(_cellBloc.state.url);
|
||||
});
|
||||
@override
|
||||
void requestBeginFocus() {
|
||||
_openUrlOrEdit(_cellBloc.state.url);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user