mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-04-24 22:57:12 -04:00
fix: update row after field was changed
This commit is contained in:
parent
a3770a699c
commit
bf8a752b4d
9 changed files with 75 additions and 47 deletions
|
@ -172,7 +172,7 @@ void _resolveGridDeps(GetIt getIt) {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
getIt.registerFactoryParam<FieldEditorBloc, String, FieldContextLoader>(
|
getIt.registerFactoryParam<FieldEditorBloc, String, EditFieldContextLoader>(
|
||||||
(gridId, fieldLoader) => FieldEditorBloc(
|
(gridId, fieldLoader) => FieldEditorBloc(
|
||||||
service: FieldService(gridId: gridId),
|
service: FieldService(gridId: gridId),
|
||||||
fieldLoader: fieldLoader,
|
fieldLoader: fieldLoader,
|
||||||
|
|
|
@ -11,11 +11,11 @@ part 'field_editor_bloc.freezed.dart';
|
||||||
|
|
||||||
class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
|
class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
|
||||||
final FieldService service;
|
final FieldService service;
|
||||||
final FieldContextLoader _loader;
|
final EditFieldContextLoader _loader;
|
||||||
|
|
||||||
FieldEditorBloc({
|
FieldEditorBloc({
|
||||||
required this.service,
|
required this.service,
|
||||||
required FieldContextLoader fieldLoader,
|
required EditFieldContextLoader fieldLoader,
|
||||||
}) : _loader = fieldLoader,
|
}) : _loader = fieldLoader,
|
||||||
super(FieldEditorState.initial(service.gridId)) {
|
super(FieldEditorState.initial(service.gridId)) {
|
||||||
on<FieldEditorEvent>(
|
on<FieldEditorEvent>(
|
||||||
|
|
|
@ -112,11 +112,13 @@ class GridFieldCellContext extends Equatable {
|
||||||
List<Object> get props => [field.id];
|
List<Object> get props => [field.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class FieldContextLoader {
|
abstract class EditFieldContextLoader {
|
||||||
Future<Either<EditFieldContext, FlowyError>> load();
|
Future<Either<EditFieldContext, FlowyError>> load();
|
||||||
|
|
||||||
|
Future<Either<EditFieldContext, FlowyError>> switchToField(String fieldId, FieldType fieldType);
|
||||||
}
|
}
|
||||||
|
|
||||||
class NewFieldContextLoader extends FieldContextLoader {
|
class NewFieldContextLoader extends EditFieldContextLoader {
|
||||||
final String gridId;
|
final String gridId;
|
||||||
NewFieldContextLoader({
|
NewFieldContextLoader({
|
||||||
required this.gridId,
|
required this.gridId,
|
||||||
|
@ -130,9 +132,18 @@ class NewFieldContextLoader extends FieldContextLoader {
|
||||||
|
|
||||||
return GridEventGetEditFieldContext(payload).send();
|
return GridEventGetEditFieldContext(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<EditFieldContext, FlowyError>> switchToField(String fieldId, FieldType fieldType) {
|
||||||
|
final payload = GetEditFieldContextPayload.create()
|
||||||
|
..gridId = gridId
|
||||||
|
..fieldType = fieldType;
|
||||||
|
|
||||||
|
return GridEventGetEditFieldContext(payload).send();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FieldContextLoaderAdaptor extends FieldContextLoader {
|
class FieldContextLoaderAdaptor extends EditFieldContextLoader {
|
||||||
final String gridId;
|
final String gridId;
|
||||||
final Field field;
|
final Field field;
|
||||||
|
|
||||||
|
@ -150,4 +161,10 @@ class FieldContextLoaderAdaptor extends FieldContextLoader {
|
||||||
|
|
||||||
return GridEventGetEditFieldContext(payload).send();
|
return GridEventGetEditFieldContext(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<EditFieldContext, FlowyError>> switchToField(String fieldId, FieldType fieldType) async {
|
||||||
|
final fieldService = FieldService(gridId: gridId);
|
||||||
|
return fieldService.switchToField(fieldId, fieldType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
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:flowy_sdk/protobuf/flowy-grid-data-model/meta.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';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'field_service.dart';
|
|
||||||
|
|
||||||
part 'field_switch_bloc.freezed.dart';
|
part 'field_switch_bloc.freezed.dart';
|
||||||
|
|
||||||
|
@ -15,15 +12,10 @@ class FieldSwitcherBloc extends Bloc<FieldSwitchEvent, FieldSwitchState> {
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
await event.map(
|
await event.map(
|
||||||
toFieldType: (_ToFieldType value) async {
|
toFieldType: (_ToFieldType value) async {
|
||||||
final fieldService = FieldService(gridId: state.gridId);
|
emit(state.copyWith(
|
||||||
final result = await fieldService.switchToField(state.field.id, value.fieldType);
|
field: value.field,
|
||||||
result.fold(
|
typeOptionData: Uint8List.fromList(value.typeOptionData),
|
||||||
(newEditContext) {
|
));
|
||||||
final typeOptionData = Uint8List.fromList(newEditContext.typeOptionData);
|
|
||||||
emit(state.copyWith(field: newEditContext.gridField, typeOptionData: typeOptionData));
|
|
||||||
},
|
|
||||||
(err) => Log.error(err),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
didUpdateTypeOptionData: (_DidUpdateTypeOptionData value) {
|
didUpdateTypeOptionData: (_DidUpdateTypeOptionData value) {
|
||||||
emit(state.copyWith(typeOptionData: value.typeOptionData));
|
emit(state.copyWith(typeOptionData: value.typeOptionData));
|
||||||
|
@ -41,7 +33,7 @@ class FieldSwitcherBloc extends Bloc<FieldSwitchEvent, FieldSwitchState> {
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class FieldSwitchEvent with _$FieldSwitchEvent {
|
class FieldSwitchEvent with _$FieldSwitchEvent {
|
||||||
const factory FieldSwitchEvent.toFieldType(FieldType fieldType) = _ToFieldType;
|
const factory FieldSwitchEvent.toFieldType(Field field, List<int> typeOptionData) = _ToFieldType;
|
||||||
const factory FieldSwitchEvent.didUpdateTypeOptionData(Uint8List typeOptionData) = _DidUpdateTypeOptionData;
|
const factory FieldSwitchEvent.didUpdateTypeOptionData(Uint8List typeOptionData) = _DidUpdateTypeOptionData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,12 @@ part 'grid_header_bloc.freezed.dart';
|
||||||
|
|
||||||
class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
|
class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
|
||||||
final FieldService service;
|
final FieldService service;
|
||||||
final GridFieldsListener fieldListener;
|
final GridFieldsListener _fieldListener;
|
||||||
|
|
||||||
GridHeaderBloc({
|
GridHeaderBloc({
|
||||||
required GridHeaderData data,
|
required GridHeaderData data,
|
||||||
required this.service,
|
required this.service,
|
||||||
}) : fieldListener = GridFieldsListener(gridId: data.gridId),
|
}) : _fieldListener = GridFieldsListener(gridId: data.gridId),
|
||||||
super(GridHeaderState.initial(data.fields)) {
|
super(GridHeaderState.initial(data.fields)) {
|
||||||
on<GridHeaderEvent>(
|
on<GridHeaderEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
|
@ -36,19 +36,19 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _startListening() async {
|
Future<void> _startListening() async {
|
||||||
fieldListener.updateFieldsNotifier.addPublishListener((result) {
|
_fieldListener.updateFieldsNotifier.addPublishListener((result) {
|
||||||
result.fold(
|
result.fold(
|
||||||
(fields) => add(GridHeaderEvent.didReceiveFieldUpdate(fields)),
|
(fields) => add(GridHeaderEvent.didReceiveFieldUpdate(fields)),
|
||||||
(err) => Log.error(err),
|
(err) => Log.error(err),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
fieldListener.start();
|
_fieldListener.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
await fieldListener.stop();
|
await _fieldListener.stop();
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleRowUpdate(_DidUpdateRow value, Emitter<RowState> emit) {
|
void _handleRowUpdate(_DidUpdateRow value, Emitter<RowState> emit) {
|
||||||
final CellDataMap cellDataMap = _makeCellDatas(value.row);
|
final CellDataMap cellDataMap = _makeCellDatas(value.row, state.fields);
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
row: Future(() => Some(value.row)),
|
row: Future(() => Some(value.row)),
|
||||||
cellDataMap: Some(cellDataMap),
|
cellDataMap: Some(cellDataMap),
|
||||||
|
@ -63,7 +63,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
|
||||||
final optionRow = await state.row;
|
final optionRow = await state.row;
|
||||||
final CellDataMap cellDataMap = optionRow.fold(
|
final CellDataMap cellDataMap = optionRow.fold(
|
||||||
() => CellDataMap.identity(),
|
() => CellDataMap.identity(),
|
||||||
(row) => _makeCellDatas(row),
|
(row) => _makeCellDatas(row, value.fields),
|
||||||
);
|
);
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
|
@ -107,9 +107,9 @@ class RowBloc extends Bloc<RowEvent, RowState> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CellDataMap _makeCellDatas(Row row) {
|
CellDataMap _makeCellDatas(Row row, List<Field> fields) {
|
||||||
var map = CellDataMap.new();
|
var map = CellDataMap.new();
|
||||||
for (final field in state.fields) {
|
for (final field in fields) {
|
||||||
if (field.visibility) {
|
if (field.visibility) {
|
||||||
map[field.id] = CellData(
|
map[field.id] = CellData(
|
||||||
rowId: row.id,
|
rowId: row.id,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:app_flowy/workspace/application/grid/field/field_switch_bloc.dar
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'field_name_input.dart';
|
import 'field_name_input.dart';
|
||||||
|
@ -13,7 +14,7 @@ import 'field_switcher.dart';
|
||||||
class FieldEditor extends FlowyOverlayDelegate {
|
class FieldEditor extends FlowyOverlayDelegate {
|
||||||
final String gridId;
|
final String gridId;
|
||||||
final FieldEditorBloc _fieldEditorBloc;
|
final FieldEditorBloc _fieldEditorBloc;
|
||||||
final FieldContextLoader? fieldContextLoader;
|
final EditFieldContextLoader fieldContextLoader;
|
||||||
FieldEditor({
|
FieldEditor({
|
||||||
required this.gridId,
|
required this.gridId,
|
||||||
required this.fieldContextLoader,
|
required this.fieldContextLoader,
|
||||||
|
@ -29,7 +30,7 @@ class FieldEditor extends FlowyOverlayDelegate {
|
||||||
FlowyOverlay.of(context).remove(identifier());
|
FlowyOverlay.of(context).remove(identifier());
|
||||||
FlowyOverlay.of(context).insertWithAnchor(
|
FlowyOverlay.of(context).insertWithAnchor(
|
||||||
widget: OverlayContainer(
|
widget: OverlayContainer(
|
||||||
child: _FieldEditorWidget(_fieldEditorBloc),
|
child: _FieldEditorWidget(_fieldEditorBloc, fieldContextLoader),
|
||||||
constraints: BoxConstraints.loose(const Size(220, 400)),
|
constraints: BoxConstraints.loose(const Size(220, 400)),
|
||||||
),
|
),
|
||||||
identifier: identifier(),
|
identifier: identifier(),
|
||||||
|
@ -55,7 +56,8 @@ class FieldEditor extends FlowyOverlayDelegate {
|
||||||
|
|
||||||
class _FieldEditorWidget extends StatelessWidget {
|
class _FieldEditorWidget extends StatelessWidget {
|
||||||
final FieldEditorBloc editorBloc;
|
final FieldEditorBloc editorBloc;
|
||||||
const _FieldEditorWidget(this.editorBloc, {Key? key}) : super(key: key);
|
final EditFieldContextLoader fieldContextLoader;
|
||||||
|
const _FieldEditorWidget(this.editorBloc, this.fieldContextLoader, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -72,7 +74,7 @@ class _FieldEditorWidget extends StatelessWidget {
|
||||||
const VSpace(10),
|
const VSpace(10),
|
||||||
const _FieldNameTextField(),
|
const _FieldNameTextField(),
|
||||||
const VSpace(10),
|
const VSpace(10),
|
||||||
_FieldSwitcher(SwitchFieldContext(state.gridId, field, state.typeOptionData)),
|
_renderSwitchButton(context, field, state),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -80,16 +82,13 @@ class _FieldEditorWidget extends StatelessWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class _FieldSwitcher extends StatelessWidget {
|
Widget _renderSwitchButton(BuildContext context, Field field, FieldEditorState state) {
|
||||||
final SwitchFieldContext switchContext;
|
|
||||||
const _FieldSwitcher(this.switchContext, {Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return FieldSwitcher(
|
return FieldSwitcher(
|
||||||
switchContext: switchContext,
|
switchContext: SwitchFieldContext(state.gridId, field, state.typeOptionData),
|
||||||
|
onSwitchToField: (fieldId, fieldType) {
|
||||||
|
return fieldContextLoader.switchToField(fieldId, fieldType);
|
||||||
|
},
|
||||||
onUpdated: (field, typeOptionData) {
|
onUpdated: (field, typeOptionData) {
|
||||||
context.read<FieldEditorBloc>().add(FieldEditorEvent.switchField(field, typeOptionData));
|
context.read<FieldEditorBloc>().add(FieldEditorEvent.switchField(field, typeOptionData));
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,6 +7,8 @@ import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
|
import 'package:flowy_sdk/log.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.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:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pbserver.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pbserver.dart';
|
||||||
|
@ -17,20 +19,26 @@ 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/header/field_type_list.dart';
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart';
|
||||||
import 'field_type_extension.dart';
|
import 'field_type_extension.dart';
|
||||||
|
import 'package:dartz/dartz.dart' show Either;
|
||||||
import 'type_option/multi_select.dart';
|
import 'type_option/multi_select.dart';
|
||||||
import 'type_option/number.dart';
|
import 'type_option/number.dart';
|
||||||
import 'type_option/single_select.dart';
|
import 'type_option/single_select.dart';
|
||||||
|
|
||||||
typedef UpdateFieldCallback = void Function(Field, Uint8List);
|
typedef UpdateFieldCallback = void Function(Field, Uint8List);
|
||||||
|
typedef SwitchToFieldCallback = Future<Either<EditFieldContext, FlowyError>> Function(
|
||||||
|
String fieldId,
|
||||||
|
FieldType fieldType,
|
||||||
|
);
|
||||||
|
|
||||||
class FieldSwitcher extends StatefulWidget {
|
class FieldSwitcher extends StatefulWidget {
|
||||||
final SwitchFieldContext switchContext;
|
final SwitchFieldContext switchContext;
|
||||||
final UpdateFieldCallback onUpdated;
|
final UpdateFieldCallback onUpdated;
|
||||||
|
final SwitchToFieldCallback onSwitchToField;
|
||||||
|
|
||||||
const FieldSwitcher({
|
const FieldSwitcher({
|
||||||
required this.switchContext,
|
required this.switchContext,
|
||||||
required this.onUpdated,
|
required this.onUpdated,
|
||||||
|
required this.onSwitchToField,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@ -79,8 +87,20 @@ class _FieldSwitcherState extends State<FieldSwitcher> {
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||||
hoverColor: theme.hover,
|
hoverColor: theme.hover,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
final list = FieldTypeList(onSelectField: (fieldType) {
|
final list = FieldTypeList(onSelectField: (newFieldType) {
|
||||||
context.read<FieldSwitcherBloc>().add(FieldSwitchEvent.toFieldType(fieldType));
|
widget.onSwitchToField(field.id, newFieldType).then((result) {
|
||||||
|
result.fold(
|
||||||
|
(editFieldContext) {
|
||||||
|
context.read<FieldSwitcherBloc>().add(
|
||||||
|
FieldSwitchEvent.toFieldType(
|
||||||
|
editFieldContext.gridField,
|
||||||
|
editFieldContext.typeOptionData,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
(err) => Log.error(err),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
_showOverlay(context, list);
|
_showOverlay(context, list);
|
||||||
},
|
},
|
||||||
|
|
|
@ -19,12 +19,12 @@ class GridRowWidget extends StatefulWidget {
|
||||||
|
|
||||||
class _GridRowWidgetState extends State<GridRowWidget> {
|
class _GridRowWidgetState extends State<GridRowWidget> {
|
||||||
late RowBloc _rowBloc;
|
late RowBloc _rowBloc;
|
||||||
late RowRegionStateNotifier _rowStateNotifier;
|
late _RegionStateNotifier _rowStateNotifier;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_rowBloc = getIt<RowBloc>(param1: widget.data)..add(const RowEvent.initial());
|
_rowBloc = getIt<RowBloc>(param1: widget.data)..add(const RowEvent.initial());
|
||||||
_rowStateNotifier = RowRegionStateNotifier();
|
_rowStateNotifier = _RegionStateNotifier();
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ class _RowLeading extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Consumer<RowRegionStateNotifier>(
|
return Consumer<_RegionStateNotifier>(
|
||||||
builder: (context, state, _) {
|
builder: (context, state, _) {
|
||||||
return SizedBox(width: GridSize.leadingHeaderPadding, child: state.onEnter ? _activeWidget() : null);
|
return SizedBox(width: GridSize.leadingHeaderPadding, child: state.onEnter ? _activeWidget() : null);
|
||||||
},
|
},
|
||||||
|
@ -140,7 +140,7 @@ class _RowCells extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RowRegionStateNotifier extends ChangeNotifier {
|
class _RegionStateNotifier extends ChangeNotifier {
|
||||||
bool _onEnter = false;
|
bool _onEnter = false;
|
||||||
|
|
||||||
set onEnter(bool value) {
|
set onEnter(bool value) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue