refactor: rename GridCellContext to GridCellController

This commit is contained in:
appflowy 2022-07-14 20:40:01 +08:00
parent 3844d6aad1
commit 8ac75af875
25 changed files with 139 additions and 169 deletions

View File

@ -153,31 +153,31 @@ void _resolveGridDeps(GetIt getIt) {
), ),
); );
getIt.registerFactoryParam<TextCellBloc, GridCellContext, void>( getIt.registerFactoryParam<TextCellBloc, GridCellController, void>(
(context, _) => TextCellBloc( (context, _) => TextCellBloc(
cellContext: context, cellContext: context,
), ),
); );
getIt.registerFactoryParam<SelectOptionCellBloc, GridSelectOptionCellContext, void>( getIt.registerFactoryParam<SelectOptionCellBloc, GridSelectOptionCellController, void>(
(context, _) => SelectOptionCellBloc( (context, _) => SelectOptionCellBloc(
cellContext: context, cellContext: context,
), ),
); );
getIt.registerFactoryParam<NumberCellBloc, GridCellContext, void>( getIt.registerFactoryParam<NumberCellBloc, GridCellController, void>(
(context, _) => NumberCellBloc( (context, _) => NumberCellBloc(
cellContext: context, cellContext: context,
), ),
); );
getIt.registerFactoryParam<DateCellBloc, GridDateCellContext, void>( getIt.registerFactoryParam<DateCellBloc, GridDateCellController, void>(
(context, _) => DateCellBloc( (context, _) => DateCellBloc(
cellContext: context, cellContext: context,
), ),
); );
getIt.registerFactoryParam<CheckboxCellBloc, GridCellContext, void>( getIt.registerFactoryParam<CheckboxCellBloc, GridCellController, void>(
(cellData, _) => CheckboxCellBloc( (cellData, _) => CheckboxCellBloc(
service: CellService(), service: CellService(),
cellContext: cellData, cellContext: cellData,

View File

@ -2,19 +2,19 @@ part of 'cell_service.dart';
typedef GridCellMap = LinkedHashMap<String, GridCell>; typedef GridCellMap = LinkedHashMap<String, GridCell>;
class _GridCellCacheObject { class _GridCellCacheItem {
GridCellCacheKey key; GridCellId key;
dynamic object; dynamic object;
_GridCellCacheObject({ _GridCellCacheItem({
required this.key, required this.key,
required this.object, required this.object,
}); });
} }
class GridCellCacheKey { class GridCellId {
final String fieldId; final String fieldId;
final String rowId; final String rowId;
GridCellCacheKey({ GridCellId({
required this.fieldId, required this.fieldId,
required this.rowId, required this.rowId,
}); });
@ -33,7 +33,7 @@ class GridCellsCache {
_cellDataByFieldId.remove(fieldId); _cellDataByFieldId.remove(fieldId);
} }
void insert<T extends _GridCellCacheObject>(T item) { void insert<T extends _GridCellCacheItem>(T item) {
var map = _cellDataByFieldId[item.key.fieldId]; var map = _cellDataByFieldId[item.key.fieldId];
if (map == null) { if (map == null) {
_cellDataByFieldId[item.key.fieldId] = {}; _cellDataByFieldId[item.key.fieldId] = {};
@ -43,7 +43,7 @@ class GridCellsCache {
map![item.key.rowId] = item.object; map![item.key.rowId] = item.object;
} }
T? get<T>(GridCellCacheKey key) { T? get<T>(GridCellId key) {
final map = _cellDataByFieldId[key.fieldId]; final map = _cellDataByFieldId[key.fieldId];
if (map == null) { if (map == null) {
return null; return null;

View File

@ -5,6 +5,7 @@ import 'cell_service.dart';
abstract class GridFieldChangedNotifier { abstract class GridFieldChangedNotifier {
void onFieldChanged(void Function(Field) callback); void onFieldChanged(void Function(Field) callback);
void dispose();
} }
class GridCellFieldNotifier { class GridCellFieldNotifier {
@ -26,7 +27,7 @@ class GridCellFieldNotifier {
); );
} }
void addFieldListener(GridCellCacheKey cacheKey, VoidCallback onFieldChanged) { void addFieldListener(GridCellId cacheKey, VoidCallback onFieldChanged) {
var map = _fieldListenerByFieldId[cacheKey.fieldId]; var map = _fieldListenerByFieldId[cacheKey.fieldId];
if (map == null) { if (map == null) {
_fieldListenerByFieldId[cacheKey.fieldId] = {}; _fieldListenerByFieldId[cacheKey.fieldId] = {};
@ -42,7 +43,7 @@ class GridCellFieldNotifier {
} }
} }
void removeFieldListener(GridCellCacheKey cacheKey, VoidCallback fn) { void removeFieldListener(GridCellId cacheKey, VoidCallback fn) {
var callbacks = _fieldListenerByFieldId[cacheKey.fieldId]?[cacheKey.rowId]; var callbacks = _fieldListenerByFieldId[cacheKey.fieldId]?[cacheKey.rowId];
final index = callbacks?.indexWhere((callback) => callback == fn); final index = callbacks?.indexWhere((callback) => callback == fn);
if (index != null && index != -1) { if (index != null && index != -1) {

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'package:app_flowy/workspace/application/grid/grid_service.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart';
@ -16,6 +17,8 @@ import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart';
import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
import 'dart:convert' show utf8; import 'dart:convert' show utf8;
import 'cell_field_notifier.dart';
part 'cell_service.freezed.dart'; part 'cell_service.freezed.dart';
part 'cell_data_loader.dart'; part 'cell_data_loader.dart';
part 'context_builder.dart'; part 'context_builder.dart';

View File

@ -1,22 +1,22 @@
part of 'cell_service.dart'; part of 'cell_service.dart';
typedef GridCellContext = _GridCellContext<String, String>; typedef GridCellController = IGridCellController<String, String>;
typedef GridSelectOptionCellContext = _GridCellContext<SelectOptionCellData, String>; typedef GridSelectOptionCellController = IGridCellController<SelectOptionCellData, String>;
typedef GridDateCellContext = _GridCellContext<DateCellData, CalendarData>; typedef GridDateCellController = IGridCellController<DateCellData, CalendarData>;
typedef GridURLCellContext = _GridCellContext<URLCellData, String>; typedef GridURLCellController = IGridCellController<URLCellData, String>;
class GridCellContextBuilder { class GridCellControllerBuilder {
final GridCell _gridCell; final GridCell _gridCell;
final GridCellsCache _cellCache; final GridCellsCache _cellCache;
final GridFieldCache _fieldCache; final GridFieldCache _fieldCache;
GridCellContextBuilder( GridCellControllerBuilder(
{required GridCell gridCell, required GridCellsCache cellCache, required GridFieldCache fieldCache}) {required GridCell gridCell, required GridCellsCache cellCache, required GridFieldCache fieldCache})
: _cellCache = cellCache, : _cellCache = cellCache,
_fieldCache = fieldCache, _fieldCache = fieldCache,
_gridCell = gridCell; _gridCell = gridCell;
_GridCellContext build() { IGridCellController build() {
final cellFieldNotifier = GridCellFieldNotifier(notifier: _GridFieldChangedNotifierImpl(_fieldCache)); final cellFieldNotifier = GridCellFieldNotifier(notifier: _GridFieldChangedNotifierImpl(_fieldCache));
switch (_gridCell.field.fieldType) { switch (_gridCell.field.fieldType) {
@ -25,7 +25,7 @@ class GridCellContextBuilder {
gridCell: _gridCell, gridCell: _gridCell,
parser: StringCellDataParser(), parser: StringCellDataParser(),
); );
return GridCellContext( return GridCellController(
gridCell: _gridCell, gridCell: _gridCell,
cellCache: _cellCache, cellCache: _cellCache,
cellDataLoader: cellDataLoader, cellDataLoader: cellDataLoader,
@ -39,7 +39,7 @@ class GridCellContextBuilder {
config: const GridCellDataConfig(reloadOnFieldChanged: true), config: const GridCellDataConfig(reloadOnFieldChanged: true),
); );
return GridDateCellContext( return GridDateCellController(
gridCell: _gridCell, gridCell: _gridCell,
cellCache: _cellCache, cellCache: _cellCache,
cellDataLoader: cellDataLoader, cellDataLoader: cellDataLoader,
@ -52,7 +52,7 @@ class GridCellContextBuilder {
parser: StringCellDataParser(), parser: StringCellDataParser(),
config: const GridCellDataConfig(reloadOnFieldChanged: true), config: const GridCellDataConfig(reloadOnFieldChanged: true),
); );
return GridCellContext( return GridCellController(
gridCell: _gridCell, gridCell: _gridCell,
cellCache: _cellCache, cellCache: _cellCache,
cellDataLoader: cellDataLoader, cellDataLoader: cellDataLoader,
@ -64,7 +64,7 @@ class GridCellContextBuilder {
gridCell: _gridCell, gridCell: _gridCell,
parser: StringCellDataParser(), parser: StringCellDataParser(),
); );
return GridCellContext( return GridCellController(
gridCell: _gridCell, gridCell: _gridCell,
cellCache: _cellCache, cellCache: _cellCache,
cellDataLoader: cellDataLoader, cellDataLoader: cellDataLoader,
@ -79,7 +79,7 @@ class GridCellContextBuilder {
config: const GridCellDataConfig(reloadOnFieldChanged: true), config: const GridCellDataConfig(reloadOnFieldChanged: true),
); );
return GridSelectOptionCellContext( return GridSelectOptionCellController(
gridCell: _gridCell, gridCell: _gridCell,
cellCache: _cellCache, cellCache: _cellCache,
cellDataLoader: cellDataLoader, cellDataLoader: cellDataLoader,
@ -92,7 +92,7 @@ class GridCellContextBuilder {
gridCell: _gridCell, gridCell: _gridCell,
parser: URLCellDataParser(), parser: URLCellDataParser(),
); );
return GridURLCellContext( return GridURLCellController(
gridCell: _gridCell, gridCell: _gridCell,
cellCache: _cellCache, cellCache: _cellCache,
cellDataLoader: cellDataLoader, cellDataLoader: cellDataLoader,
@ -105,12 +105,12 @@ class GridCellContextBuilder {
} }
// T: the type of the CellData // T: the type of the CellData
// D: the type of the data that will be save to disk // D: the type of the data that will be saved to disk
// ignore: must_be_immutable // ignore: must_be_immutable
class _GridCellContext<T, D> extends Equatable { class IGridCellController<T, D> extends Equatable {
final GridCell gridCell; final GridCell gridCell;
final GridCellsCache _cellsCache; final GridCellsCache _cellsCache;
final GridCellCacheKey _cacheKey; final GridCellId _cacheKey;
final FieldService _fieldService; final FieldService _fieldService;
final GridCellFieldNotifier _cellFieldNotifier; final GridCellFieldNotifier _cellFieldNotifier;
// final GridCellFieldNotifier _fieldNotifier; // final GridCellFieldNotifier _fieldNotifier;
@ -118,14 +118,15 @@ class _GridCellContext<T, D> extends Equatable {
final IGridCellDataPersistence<D> _cellDataPersistence; final IGridCellDataPersistence<D> _cellDataPersistence;
late final CellListener _cellListener; late final CellListener _cellListener;
late final ValueNotifier<T?>? _cellDataNotifier; ValueNotifier<T?>? _cellDataNotifier;
bool isListening = false; bool isListening = false;
VoidCallback? _onFieldChangedFn; VoidCallback? _onFieldChangedFn;
Timer? _loadDataOperation; Timer? _loadDataOperation;
Timer? _saveDataOperation; Timer? _saveDataOperation;
bool isDispose = false;
_GridCellContext({ IGridCellController({
required this.gridCell, required this.gridCell,
required GridCellsCache cellCache, required GridCellsCache cellCache,
required GridCellFieldNotifier cellFieldNotifier, required GridCellFieldNotifier cellFieldNotifier,
@ -137,10 +138,10 @@ class _GridCellContext<T, D> extends Equatable {
_cellDataPersistence = cellDataPersistence, _cellDataPersistence = cellDataPersistence,
_cellFieldNotifier = cellFieldNotifier, _cellFieldNotifier = cellFieldNotifier,
_fieldService = FieldService(gridId: gridCell.gridId, fieldId: gridCell.field.id), _fieldService = FieldService(gridId: gridCell.gridId, fieldId: gridCell.field.id),
_cacheKey = GridCellCacheKey(rowId: gridCell.rowId, fieldId: gridCell.field.id); _cacheKey = GridCellId(rowId: gridCell.rowId, fieldId: gridCell.field.id);
_GridCellContext<T, D> clone() { IGridCellController<T, D> clone() {
return _GridCellContext( return IGridCellController(
gridCell: gridCell, gridCell: gridCell,
cellDataLoader: _cellDataLoader, cellDataLoader: _cellDataLoader,
cellCache: _cellsCache, cellCache: _cellsCache,
@ -160,7 +161,7 @@ class _GridCellContext<T, D> extends Equatable {
FieldType get fieldType => gridCell.field.fieldType; FieldType get fieldType => gridCell.field.fieldType;
VoidCallback? startListening({required void Function(T?) onCellChanged}) { VoidCallback? startListening({required void Function(T?) onCellChanged, VoidCallback? onCellFieldChanged}) {
if (isListening) { if (isListening) {
Log.error("Already started. It seems like you should call clone first"); Log.error("Already started. It seems like you should call clone first");
return null; return null;
@ -176,7 +177,7 @@ class _GridCellContext<T, D> extends Equatable {
_cellDataNotifier = ValueNotifier(_cellsCache.get(_cacheKey)); _cellDataNotifier = ValueNotifier(_cellsCache.get(_cacheKey));
_cellListener = CellListener(rowId: gridCell.rowId, fieldId: gridCell.field.id); _cellListener = CellListener(rowId: gridCell.rowId, fieldId: gridCell.field.id);
/// Listen on user edit event and load the new cell data if needed. /// 1.Listen on user edit event and load the new cell data if needed.
_cellListener.start(onCellChanged: (result) { _cellListener.start(onCellChanged: (result) {
result.fold( result.fold(
(_) => _loadData(), (_) => _loadData(),
@ -184,12 +185,19 @@ class _GridCellContext<T, D> extends Equatable {
); );
}); });
/// Listen on the field event and load the cell data if needed. /// 2.Listen on the field event and load the cell data if needed.
if (_cellDataLoader.config.reloadOnFieldChanged) { _onFieldChangedFn = () {
_onFieldChangedFn = () => _loadData(); if (onCellFieldChanged != null) {
_cellFieldNotifier.addFieldListener(_cacheKey, _onFieldChangedFn!); onCellFieldChanged();
} }
if (_cellDataLoader.config.reloadOnFieldChanged) {
_loadData();
}
};
_cellFieldNotifier.addFieldListener(_cacheKey, _onFieldChangedFn!);
/// Notify the listener, the cell data was changed. /// Notify the listener, the cell data was changed.
onCellChangedFn() => onCellChanged(_cellDataNotifier?.value); onCellChangedFn() => onCellChanged(_cellDataNotifier?.value);
_cellDataNotifier?.addListener(onCellChangedFn); _cellDataNotifier?.addListener(onCellChangedFn);
@ -234,15 +242,21 @@ class _GridCellContext<T, D> extends Equatable {
_loadDataOperation = Timer(const Duration(milliseconds: 10), () { _loadDataOperation = Timer(const Duration(milliseconds: 10), () {
_cellDataLoader.loadData().then((data) { _cellDataLoader.loadData().then((data) {
_cellDataNotifier?.value = data; _cellDataNotifier?.value = data;
_cellsCache.insert(_GridCellCacheObject(key: _cacheKey, object: data)); _cellsCache.insert(_GridCellCacheItem(key: _cacheKey, object: data));
}); });
}); });
} }
void dispose() { void dispose() {
if (isDispose) {
Log.error("$this should only dispose once");
return;
}
isDispose = true;
_cellListener.stop(); _cellListener.stop();
_loadDataOperation?.cancel(); _loadDataOperation?.cancel();
_saveDataOperation?.cancel(); _saveDataOperation?.cancel();
_cellDataNotifier = null;
if (_onFieldChangedFn != null) { if (_onFieldChangedFn != null) {
_cellFieldNotifier.removeFieldListener(_cacheKey, _onFieldChangedFn!); _cellFieldNotifier.removeFieldListener(_cacheKey, _onFieldChangedFn!);

View File

@ -6,7 +6,7 @@ import 'cell_service/cell_service.dart';
part 'checkbox_cell_bloc.freezed.dart'; part 'checkbox_cell_bloc.freezed.dart';
class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> { class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
final GridCellContext cellContext; final GridCellController cellContext;
void Function()? _onCellChangedFn; void Function()? _onCellChangedFn;
CheckboxCellBloc({ CheckboxCellBloc({
@ -67,7 +67,7 @@ class CheckboxCellState with _$CheckboxCellState {
required bool isSelected, required bool isSelected,
}) = _CheckboxCellState; }) = _CheckboxCellState;
factory CheckboxCellState.initial(GridCellContext context) { factory CheckboxCellState.initial(GridCellController context) {
return CheckboxCellState(isSelected: _isSelected(context.getCellData())); return CheckboxCellState(isSelected: _isSelected(context.getCellData()));
} }
} }

View File

@ -16,7 +16,7 @@ import 'package:fixnum/fixnum.dart' as $fixnum;
part 'date_cal_bloc.freezed.dart'; part 'date_cal_bloc.freezed.dart';
class DateCalBloc extends Bloc<DateCalEvent, DateCalState> { class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
final GridDateCellContext cellContext; final GridDateCellController cellContext;
void Function()? _onCellChangedFn; void Function()? _onCellChangedFn;
DateCalBloc({ DateCalBloc({

View File

@ -7,7 +7,7 @@ import 'cell_service/cell_service.dart';
part 'date_cell_bloc.freezed.dart'; part 'date_cell_bloc.freezed.dart';
class DateCellBloc extends Bloc<DateCellEvent, DateCellState> { class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
final GridDateCellContext cellContext; final GridDateCellController cellContext;
void Function()? _onCellChangedFn; void Function()? _onCellChangedFn;
DateCellBloc({required this.cellContext}) : super(DateCellState.initial(cellContext)) { DateCellBloc({required this.cellContext}) : super(DateCellState.initial(cellContext)) {
@ -60,7 +60,7 @@ class DateCellState with _$DateCellState {
required Field field, required Field field,
}) = _DateCellState; }) = _DateCellState;
factory DateCellState.initial(GridDateCellContext context) { factory DateCellState.initial(GridDateCellController context) {
final cellData = context.getCellData(); final cellData = context.getCellData();
return DateCellState( return DateCellState(

View File

@ -8,7 +8,7 @@ import 'cell_service/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 GridCellContext cellContext; final GridCellController cellContext;
void Function()? _onCellChangedFn; void Function()? _onCellChangedFn;
NumberCellBloc({ NumberCellBloc({
@ -72,7 +72,7 @@ class NumberCellState with _$NumberCellState {
required Either<String, FlowyError> content, required Either<String, FlowyError> content,
}) = _NumberCellState; }) = _NumberCellState;
factory NumberCellState.initial(GridCellContext context) { factory NumberCellState.initial(GridCellController context) {
final cellContent = context.getCellData() ?? ""; final cellContent = context.getCellData() ?? "";
return NumberCellState( return NumberCellState(
content: left(cellContent), content: left(cellContent),

View File

@ -7,7 +7,7 @@ import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_serv
part 'select_option_cell_bloc.freezed.dart'; part 'select_option_cell_bloc.freezed.dart';
class SelectOptionCellBloc extends Bloc<SelectOptionCellEvent, SelectOptionCellState> { class SelectOptionCellBloc extends Bloc<SelectOptionCellEvent, SelectOptionCellState> {
final GridSelectOptionCellContext cellContext; final GridSelectOptionCellController cellContext;
void Function()? _onCellChangedFn; void Function()? _onCellChangedFn;
SelectOptionCellBloc({ SelectOptionCellBloc({
@ -66,7 +66,7 @@ class SelectOptionCellState with _$SelectOptionCellState {
required List<SelectOption> selectedOptions, required List<SelectOption> selectedOptions,
}) = _SelectOptionCellState; }) = _SelectOptionCellState;
factory SelectOptionCellState.initial(GridSelectOptionCellContext context) { factory SelectOptionCellState.initial(GridSelectOptionCellController context) {
final data = context.getCellData(); final data = context.getCellData();
return SelectOptionCellState( return SelectOptionCellState(

View File

@ -1,5 +1,4 @@
import 'dart:async'; import 'dart:async';
import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
@ -13,16 +12,13 @@ part 'select_option_editor_bloc.freezed.dart';
class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionEditorState> { class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionEditorState> {
final SelectOptionService _selectOptionService; final SelectOptionService _selectOptionService;
final GridSelectOptionCellContext cellContext; final GridSelectOptionCellController cellController;
late final GridFieldsListener _fieldListener;
void Function()? _onCellChangedFn;
Timer? _delayOperation; Timer? _delayOperation;
SelectOptionCellEditorBloc({ SelectOptionCellEditorBloc({
required this.cellContext, required this.cellController,
}) : _selectOptionService = SelectOptionService(gridCell: cellContext.gridCell), }) : _selectOptionService = SelectOptionService(gridCell: cellController.gridCell),
_fieldListener = GridFieldsListener(gridId: cellContext.gridId), super(SelectOptionEditorState.initial(cellController)) {
super(SelectOptionEditorState.initial(cellContext)) {
on<SelectOptionEditorEvent>( on<SelectOptionEditorEvent>(
(event, emit) async { (event, emit) async {
await event.map( await event.map(
@ -64,13 +60,8 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
@override @override
Future<void> close() async { Future<void> close() async {
if (_onCellChangedFn != null) {
cellContext.removeListener(_onCellChangedFn!);
_onCellChangedFn = null;
}
_delayOperation?.cancel(); _delayOperation?.cancel();
await _fieldListener.stop(); cellController.dispose();
cellContext.dispose();
return super.close(); return super.close();
} }
@ -157,24 +148,16 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
} }
void _startListening() { void _startListening() {
_onCellChangedFn = cellContext.startListening( cellController.startListening(
onCellChanged: ((selectOptionContext) { onCellChanged: ((selectOptionContext) {
if (!isClosed) { if (!isClosed) {
_loadOptions(); _loadOptions();
} }
}), }),
); onCellFieldChanged: () {
_fieldListener.start(onFieldsChanged: (result) {
result.fold(
(changeset) {
if (changeset.updatedFields.isNotEmpty) {
_loadOptions(); _loadOptions();
}
}, },
(err) => Log.error(err),
); );
});
} }
} }
@ -200,7 +183,7 @@ class SelectOptionEditorState with _$SelectOptionEditorState {
required Option<String> filter, required Option<String> filter,
}) = _SelectOptionEditorState; }) = _SelectOptionEditorState;
factory SelectOptionEditorState.initial(GridSelectOptionCellContext context) { factory SelectOptionEditorState.initial(GridSelectOptionCellController context) {
final data = context.getCellData(loadIfNoCache: false); final data = context.getCellData(loadIfNoCache: false);
return SelectOptionEditorState( return SelectOptionEditorState(
options: data?.options ?? [], options: data?.options ?? [],

View File

@ -6,7 +6,7 @@ import 'cell_service/cell_service.dart';
part 'text_cell_bloc.freezed.dart'; part 'text_cell_bloc.freezed.dart';
class TextCellBloc extends Bloc<TextCellEvent, TextCellState> { class TextCellBloc extends Bloc<TextCellEvent, TextCellState> {
final GridCellContext cellContext; final GridCellController cellContext;
void Function()? _onCellChangedFn; void Function()? _onCellChangedFn;
TextCellBloc({ TextCellBloc({
required this.cellContext, required this.cellContext,
@ -63,7 +63,7 @@ class TextCellState with _$TextCellState {
required String content, required String content,
}) = _TextCellState; }) = _TextCellState;
factory TextCellState.initial(GridCellContext context) => TextCellState( factory TextCellState.initial(GridCellController context) => TextCellState(
content: context.getCellData() ?? "", content: context.getCellData() ?? "",
); );
} }

View File

@ -7,7 +7,7 @@ import 'cell_service/cell_service.dart';
part 'url_cell_bloc.freezed.dart'; part 'url_cell_bloc.freezed.dart';
class URLCellBloc extends Bloc<URLCellEvent, URLCellState> { class URLCellBloc extends Bloc<URLCellEvent, URLCellState> {
final GridURLCellContext cellContext; final GridURLCellController cellContext;
void Function()? _onCellChangedFn; void Function()? _onCellChangedFn;
URLCellBloc({ URLCellBloc({
required this.cellContext, required this.cellContext,
@ -67,7 +67,7 @@ class URLCellState with _$URLCellState {
required String url, required String url,
}) = _URLCellState; }) = _URLCellState;
factory URLCellState.initial(GridURLCellContext context) { factory URLCellState.initial(GridURLCellController context) {
final cellData = context.getCellData(); final cellData = context.getCellData();
return URLCellState( return URLCellState(
content: cellData?.content ?? "", content: cellData?.content ?? "",

View File

@ -7,7 +7,7 @@ import 'cell_service/cell_service.dart';
part 'url_cell_editor_bloc.freezed.dart'; part 'url_cell_editor_bloc.freezed.dart';
class URLCellEditorBloc extends Bloc<URLCellEditorEvent, URLCellEditorState> { class URLCellEditorBloc extends Bloc<URLCellEditorEvent, URLCellEditorState> {
final GridURLCellContext cellContext; final GridURLCellController cellContext;
void Function()? _onCellChangedFn; void Function()? _onCellChangedFn;
URLCellEditorBloc({ URLCellEditorBloc({
required this.cellContext, required this.cellContext,
@ -64,7 +64,7 @@ class URLCellEditorState with _$URLCellEditorState {
required String content, required String content,
}) = _URLCellEditorState; }) = _URLCellEditorState;
factory URLCellEditorState.initial(GridURLCellContext context) { factory URLCellEditorState.initial(GridURLCellController context) {
final cellData = context.getCellData(); final cellData = context.getCellData();
return URLCellEditorState( return URLCellEditorState(
content: cellData?.content ?? "", content: cellData?.content ?? "",

View File

@ -228,12 +228,14 @@ class _GridRowsState extends State<_GridRows> {
Animation<double> animation, Animation<double> animation,
) { ) {
final rowCache = context.read<GridBloc>().getRowCache(rowData.blockId, rowData.rowId); final rowCache = context.read<GridBloc>().getRowCache(rowData.blockId, rowData.rowId);
final fieldCache = context.read<GridBloc>().fieldCache;
if (rowCache != null) { if (rowCache != null) {
return SizeTransition( return SizeTransition(
sizeFactor: animation, sizeFactor: animation,
child: GridRowWidget( child: GridRowWidget(
rowData: rowData, rowData: rowData,
rowCache: rowCache, rowCache: rowCache,
fieldCache: fieldCache,
key: ValueKey(rowData.rowId), key: ValueKey(rowData.rowId),
), ),
); );

View File

@ -22,67 +22,34 @@ class GridCellBuilder {
}); });
GridCellWidget build(GridCell cell, {GridCellStyle? style}) { GridCellWidget build(GridCell cell, {GridCellStyle? style}) {
final key = ValueKey(gridCell.cellId()); final key = ValueKey(cell.cellId());
final cellContextBuilder = GridCellContextBuilder( final cellControllerBuilder = GridCellControllerBuilder(
gridCell: gridCell, gridCell: cell,
cellCache: cellCache, cellCache: cellCache,
fieldCache: fieldCache, fieldCache: fieldCache,
); );
switch (gridCell.field.fieldType) { switch (cell.field.fieldType) {
case FieldType.Checkbox: case FieldType.Checkbox:
return CheckboxCell(cellContextBuilder: cellContextBuilder, key: key); return CheckboxCell(cellControllerBuilder: cellControllerBuilder, key: key);
case FieldType.DateTime: case FieldType.DateTime:
return DateCell(cellContextBuilder: cellContextBuilder, key: key, style: style); return DateCell(cellControllerBuilder: cellControllerBuilder, key: key, style: style);
case FieldType.SingleSelect: case FieldType.SingleSelect:
return SingleSelectCell(cellContextBuilder: cellContextBuilder, style: style, key: key); return SingleSelectCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
case FieldType.MultiSelect: case FieldType.MultiSelect:
return MultiSelectCell(cellContextBuilder: cellContextBuilder, style: style, key: key); return MultiSelectCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
case FieldType.Number: case FieldType.Number:
return NumberCell(cellContextBuilder: cellContextBuilder, key: key); return NumberCell(cellContorllerBuilder: cellControllerBuilder, key: key);
case FieldType.RichText: case FieldType.RichText:
return GridTextCell(cellContextBuilder: cellContextBuilder, style: style, key: key); return GridTextCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
case FieldType.URL: case FieldType.URL:
return GridURLCell(cellContextBuilder: cellContextBuilder, style: style, key: key); return GridURLCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
} }
throw UnimplementedError; throw UnimplementedError;
} }
} }
GridCellWidget buildGridCellWidget(
GridCell gridCell, {
required GridCellsCache cellCache,
required GridFieldCache fieldCache,
GridCellStyle? style,
}) {
final key = ValueKey(gridCell.cellId());
final cellContextBuilder = GridCellContextBuilder(
gridCell: gridCell,
cellCache: cellCache,
fieldCache: fieldCache,
);
switch (gridCell.field.fieldType) {
case FieldType.Checkbox:
return CheckboxCell(cellContextBuilder: cellContextBuilder, key: key);
case FieldType.DateTime:
return DateCell(cellContextBuilder: cellContextBuilder, key: key, style: style);
case FieldType.SingleSelect:
return SingleSelectCell(cellContextBuilder: cellContextBuilder, style: style, key: key);
case FieldType.MultiSelect:
return MultiSelectCell(cellContextBuilder: cellContextBuilder, style: style, key: key);
case FieldType.Number:
return NumberCell(cellContextBuilder: cellContextBuilder, key: key);
case FieldType.RichText:
return GridTextCell(cellContextBuilder: cellContextBuilder, style: style, key: key);
case FieldType.URL:
return GridURLCell(cellContextBuilder: cellContextBuilder, style: style, key: key);
}
throw UnimplementedError;
}
class BlankCell extends StatelessWidget { class BlankCell extends StatelessWidget {
const BlankCell({Key? key}) : super(key: key); const BlankCell({Key? key}) : super(key: key);

View File

@ -7,9 +7,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'cell_builder.dart'; import 'cell_builder.dart';
class CheckboxCell extends GridCellWidget { class CheckboxCell extends GridCellWidget {
final GridCellContextBuilder cellContextBuilder; final GridCellControllerBuilder cellControllerBuilder;
CheckboxCell({ CheckboxCell({
required this.cellContextBuilder, required this.cellControllerBuilder,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -22,7 +22,7 @@ class _CheckboxCellState extends GridCellState<CheckboxCell> {
@override @override
void initState() { void initState() {
final cellContext = widget.cellContextBuilder.build(); final cellContext = widget.cellControllerBuilder.build();
_cellBloc = getIt<CheckboxCellBloc>(param1: cellContext)..add(const CheckboxCellEvent.initial()); _cellBloc = getIt<CheckboxCellBloc>(param1: cellContext)..add(const CheckboxCellEvent.initial());
super.initState(); super.initState();
} }

View File

@ -19,12 +19,12 @@ abstract class GridCellDelegate {
} }
class DateCell extends GridCellWidget { class DateCell extends GridCellWidget {
final GridCellContextBuilder cellContextBuilder; final GridCellControllerBuilder cellControllerBuilder;
late final DateCellStyle? cellStyle; late final DateCellStyle? cellStyle;
DateCell({ DateCell({
GridCellStyle? style, GridCellStyle? style,
required this.cellContextBuilder, required this.cellControllerBuilder,
Key? key, Key? key,
}) : super(key: key) { }) : super(key: key) {
if (style != null) { if (style != null) {
@ -43,7 +43,7 @@ class _DateCellState extends GridCellState<DateCell> {
@override @override
void initState() { void initState() {
final cellContext = widget.cellContextBuilder.build(); final cellContext = widget.cellControllerBuilder.build();
_cellBloc = getIt<DateCellBloc>(param1: cellContext)..add(const DateCellEvent.initial()); _cellBloc = getIt<DateCellBloc>(param1: cellContext)..add(const DateCellEvent.initial());
super.initState(); super.initState();
} }

View File

@ -31,7 +31,7 @@ class DateCellEditor with FlowyOverlayDelegate {
Future<void> show( Future<void> show(
BuildContext context, { BuildContext context, {
required GridDateCellContext cellContext, required GridDateCellController cellContext,
}) async { }) async {
DateCellEditor.remove(context); DateCellEditor.remove(context);
@ -75,7 +75,7 @@ class DateCellEditor with FlowyOverlayDelegate {
} }
class _CellCalendarWidget extends StatelessWidget { class _CellCalendarWidget extends StatelessWidget {
final GridDateCellContext cellContext; final GridDateCellController cellContext;
final DateTypeOption dateTypeOption; final DateTypeOption dateTypeOption;
const _CellCalendarWidget({ const _CellCalendarWidget({

View File

@ -7,10 +7,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'cell_builder.dart'; import 'cell_builder.dart';
class NumberCell extends GridCellWidget { class NumberCell extends GridCellWidget {
final GridCellContextBuilder cellContextBuilder; final GridCellControllerBuilder cellContorllerBuilder;
NumberCell({ NumberCell({
required this.cellContextBuilder, required this.cellContorllerBuilder,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -25,7 +25,7 @@ class _NumberCellState extends GridFocusNodeCellState<NumberCell> {
@override @override
void initState() { void initState() {
final cellContext = widget.cellContextBuilder.build(); final cellContext = widget.cellContorllerBuilder.build();
_cellBloc = getIt<NumberCellBloc>(param1: cellContext)..add(const NumberCellEvent.initial()); _cellBloc = getIt<NumberCellBloc>(param1: cellContext)..add(const NumberCellEvent.initial());
_controller = TextEditingController(text: contentFromState(_cellBloc.state)); _controller = TextEditingController(text: contentFromState(_cellBloc.state));
super.initState(); super.initState();

View File

@ -21,11 +21,11 @@ class SelectOptionCellStyle extends GridCellStyle {
} }
class SingleSelectCell extends GridCellWidget { class SingleSelectCell extends GridCellWidget {
final GridCellContextBuilder cellContextBuilder; final GridCellControllerBuilder cellContorllerBuilder;
late final SelectOptionCellStyle? cellStyle; late final SelectOptionCellStyle? cellStyle;
SingleSelectCell({ SingleSelectCell({
required this.cellContextBuilder, required this.cellContorllerBuilder,
GridCellStyle? style, GridCellStyle? style,
Key? key, Key? key,
}) : super(key: key) { }) : super(key: key) {
@ -45,7 +45,7 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
@override @override
void initState() { void initState() {
final cellContext = widget.cellContextBuilder.build() as GridSelectOptionCellContext; final cellContext = widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
_cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)..add(const SelectOptionCellEvent.initial()); _cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)..add(const SelectOptionCellEvent.initial());
super.initState(); super.initState();
} }
@ -60,7 +60,7 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
selectOptions: state.selectedOptions, selectOptions: state.selectedOptions,
cellStyle: widget.cellStyle, cellStyle: widget.cellStyle,
onFocus: (value) => widget.onCellEditing.value = value, onFocus: (value) => widget.onCellEditing.value = value,
cellContextBuilder: widget.cellContextBuilder); cellContorllerBuilder: widget.cellContorllerBuilder);
}, },
), ),
); );
@ -75,11 +75,11 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
//---------------------------------------------------------------- //----------------------------------------------------------------
class MultiSelectCell extends GridCellWidget { class MultiSelectCell extends GridCellWidget {
final GridCellContextBuilder cellContextBuilder; final GridCellControllerBuilder cellContorllerBuilder;
late final SelectOptionCellStyle? cellStyle; late final SelectOptionCellStyle? cellStyle;
MultiSelectCell({ MultiSelectCell({
required this.cellContextBuilder, required this.cellContorllerBuilder,
GridCellStyle? style, GridCellStyle? style,
Key? key, Key? key,
}) : super(key: key) { }) : super(key: key) {
@ -99,7 +99,7 @@ class _MultiSelectCellState extends State<MultiSelectCell> {
@override @override
void initState() { void initState() {
final cellContext = widget.cellContextBuilder.build() as GridSelectOptionCellContext; final cellContext = widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
_cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)..add(const SelectOptionCellEvent.initial()); _cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)..add(const SelectOptionCellEvent.initial());
super.initState(); super.initState();
} }
@ -114,7 +114,7 @@ class _MultiSelectCellState extends State<MultiSelectCell> {
selectOptions: state.selectedOptions, selectOptions: state.selectedOptions,
cellStyle: widget.cellStyle, cellStyle: widget.cellStyle,
onFocus: (value) => widget.onCellEditing.value = value, onFocus: (value) => widget.onCellEditing.value = value,
cellContextBuilder: widget.cellContextBuilder); cellContorllerBuilder: widget.cellContorllerBuilder);
}, },
), ),
); );
@ -131,12 +131,12 @@ class _SelectOptionCell extends StatelessWidget {
final List<SelectOption> selectOptions; final List<SelectOption> selectOptions;
final void Function(bool) onFocus; final void Function(bool) onFocus;
final SelectOptionCellStyle? cellStyle; final SelectOptionCellStyle? cellStyle;
final GridCellContextBuilder cellContextBuilder; final GridCellControllerBuilder cellContorllerBuilder;
const _SelectOptionCell({ const _SelectOptionCell({
required this.selectOptions, required this.selectOptions,
required this.onFocus, required this.onFocus,
required this.cellStyle, required this.cellStyle,
required this.cellContextBuilder, required this.cellContorllerBuilder,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -172,7 +172,7 @@ class _SelectOptionCell extends StatelessWidget {
InkWell( InkWell(
onTap: () { onTap: () {
onFocus(true); onFocus(true);
final cellContext = cellContextBuilder.build() as GridSelectOptionCellContext; final cellContext = cellContorllerBuilder.build() as GridSelectOptionCellController;
SelectOptionCellEditor.show(context, cellContext, () => onFocus(false)); SelectOptionCellEditor.show(context, cellContext, () => onFocus(false));
}, },
), ),

View File

@ -24,11 +24,11 @@ import 'text_field.dart';
const double _editorPannelWidth = 300; const double _editorPannelWidth = 300;
class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate { class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate {
final GridSelectOptionCellContext cellContext; final GridSelectOptionCellController cellController;
final VoidCallback onDismissed; final VoidCallback onDismissed;
const SelectOptionCellEditor({ const SelectOptionCellEditor({
required this.cellContext, required this.cellController,
required this.onDismissed, required this.onDismissed,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -37,7 +37,7 @@ class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => SelectOptionCellEditorBloc( create: (context) => SelectOptionCellEditorBloc(
cellContext: cellContext, cellController: cellController,
)..add(const SelectOptionEditorEvent.initial()), )..add(const SelectOptionEditorEvent.initial()),
child: BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>( child: BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>(
builder: (context, state) { builder: (context, state) {
@ -59,12 +59,12 @@ class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate {
static void show( static void show(
BuildContext context, BuildContext context,
GridSelectOptionCellContext cellContext, GridSelectOptionCellController cellContext,
VoidCallback onDismissed, VoidCallback onDismissed,
) { ) {
SelectOptionCellEditor.remove(context); SelectOptionCellEditor.remove(context);
final editor = SelectOptionCellEditor( final editor = SelectOptionCellEditor(
cellContext: cellContext, cellController: cellContext,
onDismissed: onDismissed, onDismissed: onDismissed,
); );

View File

@ -14,10 +14,10 @@ class GridTextCellStyle extends GridCellStyle {
} }
class GridTextCell extends GridCellWidget { class GridTextCell extends GridCellWidget {
final GridCellContextBuilder cellContextBuilder; final GridCellControllerBuilder cellContorllerBuilder;
late final GridTextCellStyle? cellStyle; late final GridTextCellStyle? cellStyle;
GridTextCell({ GridTextCell({
required this.cellContextBuilder, required this.cellContorllerBuilder,
GridCellStyle? style, GridCellStyle? style,
Key? key, Key? key,
}) : super(key: key) { }) : super(key: key) {
@ -39,7 +39,7 @@ class _GridTextCellState extends GridFocusNodeCellState<GridTextCell> {
@override @override
void initState() { void initState() {
final cellContext = widget.cellContextBuilder.build(); final cellContext = widget.cellContorllerBuilder.build();
_cellBloc = getIt<TextCellBloc>(param1: cellContext); _cellBloc = getIt<TextCellBloc>(param1: cellContext);
_cellBloc.add(const TextCellEvent.initial()); _cellBloc.add(const TextCellEvent.initial());
_controller = TextEditingController(text: _cellBloc.state.content); _controller = TextEditingController(text: _cellBloc.state.content);

View File

@ -7,7 +7,7 @@ import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
class URLCellEditor extends StatefulWidget with FlowyOverlayDelegate { class URLCellEditor extends StatefulWidget with FlowyOverlayDelegate {
final GridURLCellContext cellContext; final GridURLCellController cellContext;
final VoidCallback completed; final VoidCallback completed;
const URLCellEditor({required this.cellContext, required this.completed, Key? key}) : super(key: key); const URLCellEditor({required this.cellContext, required this.completed, Key? key}) : super(key: key);
@ -16,7 +16,7 @@ class URLCellEditor extends StatefulWidget with FlowyOverlayDelegate {
static void show( static void show(
BuildContext context, BuildContext context,
GridURLCellContext cellContext, GridURLCellController cellContext,
VoidCallback completed, VoidCallback completed,
) { ) {
FlowyOverlay.of(context).remove(identifier()); FlowyOverlay.of(context).remove(identifier());

View File

@ -31,10 +31,10 @@ enum GridURLCellAccessoryType {
} }
class GridURLCell extends GridCellWidget { class GridURLCell extends GridCellWidget {
final GridCellContextBuilder cellContextBuilder; final GridCellControllerBuilder cellContorllerBuilder;
late final GridURLCellStyle? cellStyle; late final GridURLCellStyle? cellStyle;
GridURLCell({ GridURLCell({
required this.cellContextBuilder, required this.cellContorllerBuilder,
GridCellStyle? style, GridCellStyle? style,
Key? key, Key? key,
}) : super(key: key) { }) : super(key: key) {
@ -51,11 +51,11 @@ class GridURLCell extends GridCellWidget {
GridCellAccessory accessoryFromType(GridURLCellAccessoryType ty, GridCellAccessoryBuildContext buildContext) { GridCellAccessory accessoryFromType(GridURLCellAccessoryType ty, GridCellAccessoryBuildContext buildContext) {
switch (ty) { switch (ty) {
case GridURLCellAccessoryType.edit: case GridURLCellAccessoryType.edit:
final cellContext = cellContextBuilder.build() as GridURLCellContext; final cellContext = cellContorllerBuilder.build() as GridURLCellController;
return _EditURLAccessory(cellContext: cellContext, anchorContext: buildContext.anchorContext); return _EditURLAccessory(cellContext: cellContext, anchorContext: buildContext.anchorContext);
case GridURLCellAccessoryType.copyURL: case GridURLCellAccessoryType.copyURL:
final cellContext = cellContextBuilder.build() as GridURLCellContext; final cellContext = cellContorllerBuilder.build() as GridURLCellController;
return _CopyURLAccessory(cellContext: cellContext); return _CopyURLAccessory(cellContext: cellContext);
} }
} }
@ -83,7 +83,7 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
@override @override
void initState() { void initState() {
final cellContext = widget.cellContextBuilder.build() as GridURLCellContext; final cellContext = widget.cellContorllerBuilder.build() as GridURLCellController;
_cellBloc = URLCellBloc(cellContext: cellContext); _cellBloc = URLCellBloc(cellContext: cellContext);
_cellBloc.add(const URLCellEvent.initial()); _cellBloc.add(const URLCellEvent.initial());
super.initState(); super.initState();
@ -132,7 +132,7 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
if (url.isNotEmpty && await canLaunchUrl(uri)) { if (url.isNotEmpty && await canLaunchUrl(uri)) {
await launchUrl(uri); await launchUrl(uri);
} else { } else {
final cellContext = widget.cellContextBuilder.build() as GridURLCellContext; final cellContext = widget.cellContorllerBuilder.build() as GridURLCellController;
widget.onCellEditing.value = true; widget.onCellEditing.value = true;
URLCellEditor.show(context, cellContext, () { URLCellEditor.show(context, cellContext, () {
widget.onCellEditing.value = false; widget.onCellEditing.value = false;
@ -155,7 +155,7 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
} }
class _EditURLAccessory extends StatelessWidget with GridCellAccessory { class _EditURLAccessory extends StatelessWidget with GridCellAccessory {
final GridURLCellContext cellContext; final GridURLCellController cellContext;
final BuildContext anchorContext; final BuildContext anchorContext;
const _EditURLAccessory({ const _EditURLAccessory({
required this.cellContext, required this.cellContext,
@ -176,7 +176,7 @@ class _EditURLAccessory extends StatelessWidget with GridCellAccessory {
} }
class _CopyURLAccessory extends StatelessWidget with GridCellAccessory { class _CopyURLAccessory extends StatelessWidget with GridCellAccessory {
final GridURLCellContext cellContext; final GridURLCellController cellContext;
const _CopyURLAccessory({required this.cellContext, Key? key}) : super(key: key); const _CopyURLAccessory({required this.cellContext, Key? key}) : super(key: key);
@override @override