chore: replace FieldPB with GridField

This commit is contained in:
appflowy 2022-09-03 17:16:48 +08:00
parent f57ba8b9a8
commit 54d6f3709e
39 changed files with 338 additions and 278 deletions

View File

@ -25,7 +25,8 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
final MoveRowFFIService _rowService; final MoveRowFFIService _rowService;
LinkedHashMap<String, GroupController> groupControllers = LinkedHashMap(); LinkedHashMap<String, GroupController> groupControllers = LinkedHashMap();
GridFieldCache get fieldCache => _gridDataController.fieldCache; GridFieldController get fieldController =>
_gridDataController.fieldController;
String get gridId => _gridDataController.gridId; String get gridId => _gridDataController.gridId;
BoardBloc({required ViewPB view}) BoardBloc({required ViewPB view})

View File

@ -12,7 +12,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
import 'board_listener.dart'; import 'board_listener.dart';
typedef OnFieldsChanged = void Function(UnmodifiableListView<FieldPB>); typedef OnFieldsChanged = void Function(UnmodifiableListView<GridFieldContext>);
typedef OnGridChanged = void Function(GridPB); typedef OnGridChanged = void Function(GridPB);
typedef DidLoadGroups = void Function(List<GroupPB>); typedef DidLoadGroups = void Function(List<GroupPB>);
typedef OnUpdatedGroup = void Function(List<GroupPB>); typedef OnUpdatedGroup = void Function(List<GroupPB>);
@ -29,7 +29,7 @@ typedef OnError = void Function(FlowyError);
class BoardDataController { class BoardDataController {
final String gridId; final String gridId;
final GridFFIService _gridFFIService; final GridFFIService _gridFFIService;
final GridFieldCache fieldCache; final GridFieldController fieldController;
final BoardListener _listener; final BoardListener _listener;
// key: the block id // key: the block id
@ -56,7 +56,7 @@ class BoardDataController {
// ignore: prefer_collection_literals // ignore: prefer_collection_literals
_blocks = LinkedHashMap(), _blocks = LinkedHashMap(),
_gridFFIService = GridFFIService(gridId: view.id), _gridFFIService = GridFFIService(gridId: view.id),
fieldCache = GridFieldCache(gridId: view.id); fieldController = GridFieldController(gridId: view.id);
void addListener({ void addListener({
required OnGridChanged onGridChanged, required OnGridChanged onGridChanged,
@ -75,7 +75,7 @@ class BoardDataController {
_onRowsChanged = onRowsChanged; _onRowsChanged = onRowsChanged;
_onError = onError; _onError = onError;
fieldCache.addListener(onFields: (fields) { fieldController.addListener(onFields: (fields) {
_onFieldsChanged?.call(UnmodifiableListView(fields)); _onFieldsChanged?.call(UnmodifiableListView(fields));
}); });
@ -113,16 +113,15 @@ class BoardDataController {
() => result.fold( () => result.fold(
(grid) async { (grid) async {
_onGridChanged?.call(grid); _onGridChanged?.call(grid);
return await fieldController.loadFields(fieldIds: grid.fields).then(
return await _loadFields(grid).then((result) { (result) => result.fold(
return result.fold( (l) {
(l) { _loadGroups(grid.blocks);
_loadGroups(grid.blocks); return left(l);
return left(l); },
}, (err) => right(err),
(err) => right(err), ),
); );
});
}, },
(err) => right(err), (err) => right(err),
), ),
@ -136,33 +135,19 @@ class BoardDataController {
Future<void> dispose() async { Future<void> dispose() async {
await _gridFFIService.closeGrid(); await _gridFFIService.closeGrid();
await fieldCache.dispose(); await fieldController.dispose();
for (final blockCache in _blocks.values) { for (final blockCache in _blocks.values) {
blockCache.dispose(); blockCache.dispose();
} }
} }
Future<Either<Unit, FlowyError>> _loadFields(GridPB grid) async {
final result = await _gridFFIService.getFields(fieldIds: grid.fields);
return Future(
() => result.fold(
(fields) {
fieldCache.fields = fields.items;
_onFieldsChanged?.call(UnmodifiableListView(fieldCache.fields));
return left(unit);
},
(err) => right(err),
),
);
}
Future<void> _loadGroups(List<BlockPB> blocks) async { Future<void> _loadGroups(List<BlockPB> blocks) async {
for (final block in blocks) { for (final block in blocks) {
final cache = GridBlockCache( final cache = GridBlockCache(
gridId: gridId, gridId: gridId,
block: block, block: block,
fieldCache: fieldCache, fieldController: fieldController,
); );
cache.addListener(onRowsChanged: (reason) { cache.addListener(onRowsChanged: (reason) {

View File

@ -1,6 +1,6 @@
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart'; import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.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';
@ -20,8 +20,6 @@ class BoardDateCellBloc extends Bloc<BoardDateCellEvent, BoardDateCellState> {
emit(state.copyWith( emit(state.copyWith(
data: cellData, dateStr: _dateStrFromCellData(cellData))); data: cellData, dateStr: _dateStrFromCellData(cellData)));
}, },
didReceiveFieldUpdate: (FieldPB value) =>
emit(state.copyWith(field: value)),
); );
}, },
); );
@ -53,8 +51,6 @@ class BoardDateCellEvent with _$BoardDateCellEvent {
const factory BoardDateCellEvent.initial() = _InitialCell; const factory BoardDateCellEvent.initial() = _InitialCell;
const factory BoardDateCellEvent.didReceiveCellUpdate(DateCellDataPB? data) = const factory BoardDateCellEvent.didReceiveCellUpdate(DateCellDataPB? data) =
_DidReceiveCellUpdate; _DidReceiveCellUpdate;
const factory BoardDateCellEvent.didReceiveFieldUpdate(FieldPB field) =
_DidReceiveFieldUpdate;
} }
@freezed @freezed
@ -62,14 +58,14 @@ class BoardDateCellState with _$BoardDateCellState {
const factory BoardDateCellState({ const factory BoardDateCellState({
required DateCellDataPB? data, required DateCellDataPB? data,
required String dateStr, required String dateStr,
required FieldPB field, required GridFieldContext fieldContext,
}) = _BoardDateCellState; }) = _BoardDateCellState;
factory BoardDateCellState.initial(GridDateCellController context) { factory BoardDateCellState.initial(GridDateCellController context) {
final cellData = context.getCellData(); final cellData = context.getCellData();
return BoardDateCellState( return BoardDateCellState(
field: context.field, fieldContext: context.fieldContext,
data: cellData, data: cellData,
dateStr: _dateStrFromCellData(cellData), dateStr: _dateStrFromCellData(cellData),
); );

View File

@ -59,7 +59,7 @@ class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
return RowInfo( return RowInfo(
gridId: _rowService.gridId, gridId: _rowService.gridId,
fields: UnmodifiableListView( fields: UnmodifiableListView(
state.cells.map((cell) => cell.identifier.field).toList(), state.cells.map((cell) => cell.identifier.fieldContext).toList(),
), ),
rowPB: state.rowPB, rowPB: state.rowPB,
); );
@ -120,9 +120,9 @@ class BoardCellEquatable extends Equatable {
@override @override
List<Object?> get props => [ List<Object?> get props => [
identifier.field.id, identifier.fieldContext.id,
identifier.field.fieldType, identifier.fieldContext.fieldType,
identifier.field.visibility, identifier.fieldContext.visibility,
identifier.field.width, identifier.fieldContext.width,
]; ];
} }

View File

@ -10,15 +10,15 @@ typedef OnCardChanged = void Function(GridCellMap, RowsChangedReason);
class CardDataController extends BoardCellBuilderDelegate { class CardDataController extends BoardCellBuilderDelegate {
final RowPB rowPB; final RowPB rowPB;
final GridFieldCache _fieldCache; final GridFieldController _fieldController;
final GridRowCache _rowCache; final GridRowCache _rowCache;
final List<VoidCallback> _onCardChangedListeners = []; final List<VoidCallback> _onCardChangedListeners = [];
CardDataController({ CardDataController({
required this.rowPB, required this.rowPB,
required GridFieldCache fieldCache, required GridFieldController fieldController,
required GridRowCache rowCache, required GridRowCache rowCache,
}) : _fieldCache = fieldCache, }) : _fieldController = fieldController,
_rowCache = rowCache; _rowCache = rowCache;
GridCellMap loadData() { GridCellMap loadData() {
@ -41,7 +41,7 @@ class CardDataController extends BoardCellBuilderDelegate {
@override @override
GridCellFieldNotifier buildFieldNotifier() { GridCellFieldNotifier buildFieldNotifier() {
return GridCellFieldNotifier( return GridCellFieldNotifier(
notifier: GridCellFieldNotifierImpl(_fieldCache)); notifier: GridCellFieldNotifierImpl(_fieldController));
} }
@override @override

View File

@ -222,10 +222,10 @@ class _BoardContentState extends State<BoardContent> {
/// Return placeholder widget if the rowCache is null. /// Return placeholder widget if the rowCache is null.
if (rowCache == null) return SizedBox(key: ObjectKey(columnItem)); if (rowCache == null) return SizedBox(key: ObjectKey(columnItem));
final fieldCache = context.read<BoardBloc>().fieldCache; final fieldController = context.read<BoardBloc>().fieldController;
final gridId = context.read<BoardBloc>().gridId; final gridId = context.read<BoardBloc>().gridId;
final cardController = CardDataController( final cardController = CardDataController(
fieldCache: fieldCache, fieldController: fieldController,
rowCache: rowCache, rowCache: rowCache,
rowPB: rowPB, rowPB: rowPB,
); );
@ -252,7 +252,7 @@ class _BoardContentState extends State<BoardContent> {
dataController: cardController, dataController: cardController,
openCard: (context) => _openCard( openCard: (context) => _openCard(
gridId, gridId,
fieldCache, fieldController,
rowPB, rowPB,
rowCache, rowCache,
context, context,
@ -271,17 +271,17 @@ class _BoardContentState extends State<BoardContent> {
); );
} }
void _openCard(String gridId, GridFieldCache fieldCache, RowPB rowPB, void _openCard(String gridId, GridFieldController fieldController,
GridRowCache rowCache, BuildContext context) { RowPB rowPB, GridRowCache rowCache, BuildContext context) {
final rowInfo = RowInfo( final rowInfo = RowInfo(
gridId: gridId, gridId: gridId,
fields: UnmodifiableListView(fieldCache.fields), fields: UnmodifiableListView(fieldController.fieldContexts),
rowPB: rowPB, rowPB: rowPB,
); );
final dataController = GridRowDataController( final dataController = GridRowDataController(
rowInfo: rowInfo, rowInfo: rowInfo,
fieldCache: fieldCache, fieldController: fieldController,
rowCache: rowCache, rowCache: rowCache,
); );
@ -302,7 +302,7 @@ class _ToolbarBlocAdaptor extends StatelessWidget {
final bloc = context.read<BoardBloc>(); final bloc = context.read<BoardBloc>();
final toolbarContext = BoardToolbarContext( final toolbarContext = BoardToolbarContext(
viewId: bloc.gridId, viewId: bloc.gridId,
fieldCache: bloc.fieldCache, fieldController: bloc.fieldController,
); );
return BoardToolbar(toolbarContext: toolbarContext); return BoardToolbar(toolbarContext: toolbarContext);

View File

@ -19,16 +19,16 @@ import 'board_toolbar.dart';
class BoardSettingContext { class BoardSettingContext {
final String viewId; final String viewId;
final GridFieldCache fieldCache; final GridFieldController fieldController;
BoardSettingContext({ BoardSettingContext({
required this.viewId, required this.viewId,
required this.fieldCache, required this.fieldController,
}); });
factory BoardSettingContext.from(BoardToolbarContext toolbarContext) => factory BoardSettingContext.from(BoardToolbarContext toolbarContext) =>
BoardSettingContext( BoardSettingContext(
viewId: toolbarContext.viewId, viewId: toolbarContext.viewId,
fieldCache: toolbarContext.fieldCache, fieldController: toolbarContext.fieldController,
); );
} }
@ -93,13 +93,13 @@ class BoardSettingList extends StatelessWidget {
case BoardSettingAction.properties: case BoardSettingAction.properties:
GridPropertyList( GridPropertyList(
gridId: settingContext.viewId, gridId: settingContext.viewId,
fieldCache: settingContext.fieldCache) fieldController: settingContext.fieldController)
.show(context); .show(context);
break; break;
case BoardSettingAction.groups: case BoardSettingAction.groups:
GridGroupList( GridGroupList(
viewId: settingContext.viewId, viewId: settingContext.viewId,
fieldCache: settingContext.fieldCache) fieldController: settingContext.fieldController)
.show(context); .show(context);
break; break;
} }

View File

@ -9,11 +9,11 @@ import 'board_setting.dart';
class BoardToolbarContext { class BoardToolbarContext {
final String viewId; final String viewId;
final GridFieldCache fieldCache; final GridFieldController fieldController;
BoardToolbarContext({ BoardToolbarContext({
required this.viewId, required this.viewId,
required this.fieldCache, required this.fieldController,
}); });
} }

View File

@ -19,12 +19,12 @@ class GridBlockCache {
GridBlockCache({ GridBlockCache({
required this.gridId, required this.gridId,
required this.block, required this.block,
required GridFieldCache fieldCache, required GridFieldController fieldController,
}) { }) {
_rowCache = GridRowCache( _rowCache = GridRowCache(
gridId: gridId, gridId: gridId,
block: block, block: block,
notifier: GridRowFieldNotifierImpl(fieldCache), notifier: GridRowFieldNotifierImpl(fieldController),
); );
_listener = GridBlockListener(blockId: block.id); _listener = GridBlockListener(blockId: block.id);

View File

@ -148,10 +148,10 @@ class IGridCellController<T, D> extends Equatable {
_cellDataLoader = cellDataLoader, _cellDataLoader = cellDataLoader,
_cellDataPersistence = cellDataPersistence, _cellDataPersistence = cellDataPersistence,
_fieldNotifier = fieldNotifier, _fieldNotifier = fieldNotifier,
_fieldService = _fieldService = FieldService(
FieldService(gridId: cellId.gridId, fieldId: cellId.field.id), gridId: cellId.gridId, fieldId: cellId.fieldContext.id),
_cacheKey = _cacheKey = GridCellCacheKey(
GridCellCacheKey(rowId: cellId.rowId, fieldId: cellId.field.id); rowId: cellId.rowId, fieldId: cellId.fieldContext.id);
IGridCellController<T, D> clone() { IGridCellController<T, D> clone() {
return IGridCellController( return IGridCellController(
@ -166,11 +166,11 @@ class IGridCellController<T, D> extends Equatable {
String get rowId => cellId.rowId; String get rowId => cellId.rowId;
String get fieldId => cellId.field.id; String get fieldId => cellId.fieldContext.id;
FieldPB get field => cellId.field; GridFieldContext get fieldContext => cellId.fieldContext;
FieldType get fieldType => cellId.field.fieldType; FieldType get fieldType => cellId.fieldContext.fieldType;
VoidCallback? startListening( VoidCallback? startListening(
{required void Function(T?) onCellChanged, {required void Function(T?) onCellChanged,
@ -182,7 +182,8 @@ class IGridCellController<T, D> extends Equatable {
isListening = true; isListening = true;
_cellDataNotifier = ValueNotifier(_cellsCache.get(_cacheKey)); _cellDataNotifier = ValueNotifier(_cellsCache.get(_cacheKey));
_cellListener = CellListener(rowId: cellId.rowId, fieldId: cellId.field.id); _cellListener =
CellListener(rowId: cellId.rowId, fieldId: cellId.fieldContext.id);
/// 1.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.
/// For example: /// For example:
@ -308,14 +309,14 @@ class IGridCellController<T, D> extends Equatable {
@override @override
List<Object> get props => List<Object> get props =>
[_cellsCache.get(_cacheKey) ?? "", cellId.rowId + cellId.field.id]; [_cellsCache.get(_cacheKey) ?? "", cellId.rowId + cellId.fieldContext.id];
} }
class GridCellFieldNotifierImpl extends IGridCellFieldNotifier { class GridCellFieldNotifierImpl extends IGridCellFieldNotifier {
final GridFieldCache _cache; final GridFieldController _cache;
FieldChangesetCallback? _onChangesetFn; OnChangeset? _onChangesetFn;
GridCellFieldNotifierImpl(GridFieldCache cache) : _cache = cache; GridCellFieldNotifierImpl(GridFieldController cache) : _cache = cache;
@override @override
void onCellDispose() { void onCellDispose() {

View File

@ -60,17 +60,17 @@ class GridCellIdentifier with _$GridCellIdentifier {
const factory GridCellIdentifier({ const factory GridCellIdentifier({
required String gridId, required String gridId,
required String rowId, required String rowId,
required FieldPB field, required GridFieldContext fieldContext,
}) = _GridCellIdentifier; }) = _GridCellIdentifier;
// ignore: unused_element // ignore: unused_element
const GridCellIdentifier._(); const GridCellIdentifier._();
String get fieldId => field.id; String get fieldId => fieldContext.id;
FieldType get fieldType => field.fieldType; FieldType get fieldType => fieldContext.fieldType;
ValueKey key() { ValueKey key() {
return ValueKey("$rowId$fieldId${field.fieldType}"); return ValueKey("$rowId$fieldId${fieldContext.fieldType}");
} }
} }

View File

@ -176,7 +176,7 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
final result = await FieldService.updateFieldTypeOption( final result = await FieldService.updateFieldTypeOption(
gridId: cellController.gridId, gridId: cellController.gridId,
fieldId: cellController.field.id, fieldId: cellController.fieldContext.id,
typeOptionData: newDateTypeOption.writeToBuffer(), typeOptionData: newDateTypeOption.writeToBuffer(),
); );

View File

@ -1,5 +1,5 @@
import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.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';
@ -20,8 +20,6 @@ class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
emit(state.copyWith( emit(state.copyWith(
data: cellData, dateStr: _dateStrFromCellData(cellData))); data: cellData, dateStr: _dateStrFromCellData(cellData)));
}, },
didReceiveFieldUpdate: (FieldPB value) =>
emit(state.copyWith(field: value)),
); );
}, },
); );
@ -53,8 +51,6 @@ class DateCellEvent with _$DateCellEvent {
const factory DateCellEvent.initial() = _InitialCell; const factory DateCellEvent.initial() = _InitialCell;
const factory DateCellEvent.didReceiveCellUpdate(DateCellDataPB? data) = const factory DateCellEvent.didReceiveCellUpdate(DateCellDataPB? data) =
_DidReceiveCellUpdate; _DidReceiveCellUpdate;
const factory DateCellEvent.didReceiveFieldUpdate(FieldPB field) =
_DidReceiveFieldUpdate;
} }
@freezed @freezed
@ -62,14 +58,14 @@ class DateCellState with _$DateCellState {
const factory DateCellState({ const factory DateCellState({
required DateCellDataPB? data, required DateCellDataPB? data,
required String dateStr, required String dateStr,
required FieldPB field, required GridFieldContext fieldContext,
}) = _DateCellState; }) = _DateCellState;
factory DateCellState.initial(GridDateCellController context) { factory DateCellState.initial(GridDateCellController context) {
final cellData = context.getCellData(); final cellData = context.getCellData();
return DateCellState( return DateCellState(
field: context.field, fieldContext: context.fieldContext,
data: cellData, data: cellData,
dateStr: _dateStrFromCellData(cellData), dateStr: _dateStrFromCellData(cellData),
); );

View File

@ -11,7 +11,7 @@ class SelectOptionService {
SelectOptionService({required this.cellId}); SelectOptionService({required this.cellId});
String get gridId => cellId.gridId; String get gridId => cellId.gridId;
String get fieldId => cellId.field.id; String get fieldId => cellId.fieldContext.id;
String get rowId => cellId.rowId; String get rowId => cellId.rowId;
Future<Either<Unit, FlowyError>> create({required String name}) { Future<Either<Unit, FlowyError>> create({required String name}) {

View File

@ -1,36 +1,47 @@
import 'dart:collection'; import 'dart:collection';
import 'package:app_flowy/plugins/grid/application/field/grid_listener.dart'; import 'package:app_flowy/plugins/grid/application/field/grid_listener.dart';
import 'package:app_flowy/plugins/grid/application/grid_service.dart';
import 'package:app_flowy/plugins/grid/application/setting/setting_listener.dart';
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import '../row/row_cache.dart'; import '../row/row_cache.dart';
class FieldsNotifier extends ChangeNotifier { class _GridFieldNotifier extends ChangeNotifier {
List<FieldPB> _fields = []; List<GridFieldContext> _fieldContexts = [];
set fields(List<FieldPB> fields) { set fieldContexts(List<GridFieldContext> fieldContexts) {
_fields = fields; _fieldContexts = fieldContexts;
notifyListeners(); notifyListeners();
} }
List<FieldPB> get fields => _fields; void notify() {
notifyListeners();
}
List<GridFieldContext> get fieldContexts => _fieldContexts;
} }
typedef FieldChangesetCallback = void Function(FieldChangesetPB); typedef OnChangeset = void Function(FieldChangesetPB);
typedef FieldsCallback = void Function(List<FieldPB>); typedef OnReceiveFields = void Function(List<GridFieldContext>);
class GridFieldCache { class GridFieldController {
final String gridId; final String gridId;
final GridFieldsListener _fieldListener; final GridFieldsListener _fieldListener;
FieldsNotifier? _fieldNotifier = FieldsNotifier(); final SettingListener _settingListener;
final Map<FieldsCallback, VoidCallback> _fieldsCallbackMap = {}; final Map<OnReceiveFields, VoidCallback> _fieldCallbackMap = {};
final Map<FieldChangesetCallback, FieldChangesetCallback> final Map<OnChangeset, OnChangeset> _changesetCallbackMap = {};
_changesetCallbackMap = {};
GridFieldCache({required this.gridId}) _GridFieldNotifier? _fieldNotifier = _GridFieldNotifier();
: _fieldListener = GridFieldsListener(gridId: gridId) { final GridFFIService _gridFFIService;
GridFieldController({required this.gridId})
: _fieldListener = GridFieldsListener(gridId: gridId),
_gridFFIService = GridFFIService(gridId: gridId),
_settingListener = SettingListener(gridId: gridId) {
//Listen on field's changes
_fieldListener.start(onFieldsChanged: (result) { _fieldListener.start(onFieldsChanged: (result) {
result.fold( result.fold(
(changeset) { (changeset) {
@ -44,6 +55,28 @@ class GridFieldCache {
(err) => Log.error(err), (err) => Log.error(err),
); );
}); });
//Listen on setting changes
_settingListener.start(onSettingUpdated: (result) {
result.fold(
(setting) {
final List<String> groupFieldIds = setting.groupConfigurations.items
.map((item) => item.groupFieldId)
.toList();
bool isChanged = false;
if (_fieldNotifier != null) {
for (var field in _fieldNotifier!.fieldContexts) {
if (groupFieldIds.contains(field.id)) {
field._isGroupField = true;
isChanged = true;
}
}
if (isChanged) _fieldNotifier?.notify();
}
},
(r) => Log.error(r),
);
});
} }
Future<void> dispose() async { Future<void> dispose() async {
@ -52,49 +85,62 @@ class GridFieldCache {
_fieldNotifier = null; _fieldNotifier = null;
} }
List<FieldPB> get fields => [..._fieldNotifier?.fields ?? []]; List<GridFieldContext> get fieldContexts =>
[..._fieldNotifier?.fieldContexts ?? []];
set fields(List<FieldPB> fields) { Future<Either<Unit, FlowyError>> loadFields(
_fieldNotifier?.fields = [...fields]; {required List<FieldIdPB> fieldIds}) async {
final result = await _gridFFIService.getFields(fieldIds: fieldIds);
return Future(
() => result.fold(
(newFields) {
_fieldNotifier?.fieldContexts = newFields.items
.map((field) => GridFieldContext(field: field))
.toList();
return left(unit);
},
(err) => right(err),
),
);
} }
void addListener({ void addListener({
FieldsCallback? onFields, OnReceiveFields? onFields,
FieldChangesetCallback? onChangeset, OnChangeset? onChangeset,
bool Function()? listenWhen, bool Function()? listenWhen,
}) { }) {
if (onChangeset != null) { if (onChangeset != null) {
fn(c) { callback(c) {
if (listenWhen != null && listenWhen() == false) { if (listenWhen != null && listenWhen() == false) {
return; return;
} }
onChangeset(c); onChangeset(c);
} }
_changesetCallbackMap[onChangeset] = fn; _changesetCallbackMap[onChangeset] = callback;
} }
if (onFields != null) { if (onFields != null) {
fn() { callback() {
if (listenWhen != null && listenWhen() == false) { if (listenWhen != null && listenWhen() == false) {
return; return;
} }
onFields(fields); onFields(fieldContexts);
} }
_fieldsCallbackMap[onFields] = fn; _fieldCallbackMap[onFields] = callback;
_fieldNotifier?.addListener(fn); _fieldNotifier?.addListener(callback);
} }
} }
void removeListener({ void removeListener({
FieldsCallback? onFieldsListener, OnReceiveFields? onFieldsListener,
FieldChangesetCallback? onChangesetListener, OnChangeset? onChangesetListener,
}) { }) {
if (onFieldsListener != null) { if (onFieldsListener != null) {
final fn = _fieldsCallbackMap.remove(onFieldsListener); final callback = _fieldCallbackMap.remove(onFieldsListener);
if (fn != null) { if (callback != null) {
_fieldNotifier?.removeListener(fn); _fieldNotifier?.removeListener(callback);
} }
} }
@ -107,56 +153,58 @@ class GridFieldCache {
if (deletedFields.isEmpty) { if (deletedFields.isEmpty) {
return; return;
} }
final List<FieldPB> newFields = fields; final List<GridFieldContext> newFields = fieldContexts;
final Map<String, FieldIdPB> deletedFieldMap = { final Map<String, FieldIdPB> deletedFieldMap = {
for (var fieldOrder in deletedFields) fieldOrder.fieldId: fieldOrder for (var fieldOrder in deletedFields) fieldOrder.fieldId: fieldOrder
}; };
newFields.retainWhere((field) => (deletedFieldMap[field.id] == null)); newFields.retainWhere((field) => (deletedFieldMap[field.id] == null));
_fieldNotifier?.fields = newFields; _fieldNotifier?.fieldContexts = newFields;
} }
void _insertFields(List<IndexFieldPB> insertedFields) { void _insertFields(List<IndexFieldPB> insertedFields) {
if (insertedFields.isEmpty) { if (insertedFields.isEmpty) {
return; return;
} }
final List<FieldPB> newFields = fields; final List<GridFieldContext> newFields = fieldContexts;
for (final indexField in insertedFields) { for (final indexField in insertedFields) {
final gridField = GridFieldContext(field: indexField.field_1);
if (newFields.length > indexField.index) { if (newFields.length > indexField.index) {
newFields.insert(indexField.index, indexField.field_1); newFields.insert(indexField.index, gridField);
} else { } else {
newFields.add(indexField.field_1); newFields.add(gridField);
} }
} }
_fieldNotifier?.fields = newFields; _fieldNotifier?.fieldContexts = newFields;
} }
void _updateFields(List<FieldPB> updatedFields) { void _updateFields(List<FieldPB> updatedFields) {
if (updatedFields.isEmpty) { if (updatedFields.isEmpty) {
return; return;
} }
final List<FieldPB> newFields = fields; final List<GridFieldContext> newFields = fieldContexts;
for (final updatedField in updatedFields) { for (final updatedField in updatedFields) {
final index = final index =
newFields.indexWhere((field) => field.id == updatedField.id); newFields.indexWhere((field) => field.id == updatedField.id);
if (index != -1) { if (index != -1) {
newFields.removeAt(index); newFields.removeAt(index);
newFields.insert(index, updatedField); final gridField = GridFieldContext(field: updatedField);
newFields.insert(index, gridField);
} }
} }
_fieldNotifier?.fields = newFields; _fieldNotifier?.fieldContexts = newFields;
} }
} }
class GridRowFieldNotifierImpl extends IGridRowFieldNotifier { class GridRowFieldNotifierImpl extends IGridRowFieldNotifier {
final GridFieldCache _cache; final GridFieldController _cache;
FieldChangesetCallback? _onChangesetFn; OnChangeset? _onChangesetFn;
FieldsCallback? _onFieldFn; OnReceiveFields? _onFieldFn;
GridRowFieldNotifierImpl(GridFieldCache cache) : _cache = cache; GridRowFieldNotifierImpl(GridFieldController cache) : _cache = cache;
@override @override
UnmodifiableListView<FieldPB> get fields => UnmodifiableListView<GridFieldContext> get fields =>
UnmodifiableListView(_cache.fields); UnmodifiableListView(_cache.fieldContexts);
@override @override
void onRowFieldsChanged(VoidCallback callback) { void onRowFieldsChanged(VoidCallback callback) {
@ -188,3 +236,26 @@ class GridRowFieldNotifierImpl extends IGridRowFieldNotifier {
} }
} }
} }
class GridFieldContext {
final FieldPB _field;
bool _isGroupField = false;
String get id => _field.id;
FieldType get fieldType => _field.fieldType;
bool get visibility => _field.visibility;
double get width => _field.width.toDouble();
bool get isPrimary => _field.isPrimary;
String get name => _field.name;
FieldPB get field => _field;
bool get isGroupField => _isGroupField;
GridFieldContext({required FieldPB field}) : _field = field;
}

View File

@ -5,6 +5,8 @@ import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'field_cache.dart';
part 'field_service.freezed.dart'; part 'field_service.freezed.dart';
/// FieldService consists of lots of event functions. We define the events in the backend(Rust), /// FieldService consists of lots of event functions. We define the events in the backend(Rust),

View File

@ -1,3 +1,4 @@
import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pb.dart';

View File

@ -1,3 +1,4 @@
import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
import 'package:flowy_infra/notifier.dart'; import 'package:flowy_infra/notifier.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
@ -17,12 +18,12 @@ class TypeOptionDataController {
TypeOptionDataController({ TypeOptionDataController({
required this.gridId, required this.gridId,
required this.loader, required this.loader,
FieldPB? field, GridFieldContext? fieldContext,
}) { }) {
if (field != null) { if (fieldContext != null) {
_data = FieldTypeOptionDataPB.create() _data = FieldTypeOptionDataPB.create()
..gridId = gridId ..gridId = gridId
..field_2 = field; ..field_2 = fieldContext.field;
} }
} }

View File

@ -7,6 +7,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.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 'block/block_cache.dart'; import 'block/block_cache.dart';
import 'field/field_cache.dart';
import 'grid_data_controller.dart'; import 'grid_data_controller.dart';
import 'row/row_cache.dart'; import 'row/row_cache.dart';
import 'dart:collection'; import 'dart:collection';
@ -101,7 +102,7 @@ class GridEvent with _$GridEvent {
RowsChangedReason listState, RowsChangedReason listState,
) = _DidReceiveRowUpdate; ) = _DidReceiveRowUpdate;
const factory GridEvent.didReceiveFieldUpdate( const factory GridEvent.didReceiveFieldUpdate(
UnmodifiableListView<FieldPB> fields, UnmodifiableListView<GridFieldContext> fields,
) = _DidReceiveFieldUpdate; ) = _DidReceiveFieldUpdate;
const factory GridEvent.didReceiveGridUpdate( const factory GridEvent.didReceiveGridUpdate(
@ -138,9 +139,9 @@ class GridLoadingState with _$GridLoadingState {
} }
class GridFieldEquatable extends Equatable { class GridFieldEquatable extends Equatable {
final UnmodifiableListView<FieldPB> _fields; final UnmodifiableListView<GridFieldContext> _fields;
const GridFieldEquatable( const GridFieldEquatable(
UnmodifiableListView<FieldPB> fields, UnmodifiableListView<GridFieldContext> fields,
) : _fields = fields; ) : _fields = fields;
@override @override
@ -157,5 +158,6 @@ class GridFieldEquatable extends Equatable {
]; ];
} }
UnmodifiableListView<FieldPB> get value => UnmodifiableListView(_fields); UnmodifiableListView<GridFieldContext> get value =>
UnmodifiableListView(_fields);
} }

View File

@ -4,7 +4,6 @@ import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
import 'dart:async'; import 'dart:async';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
@ -13,7 +12,7 @@ import 'field/field_cache.dart';
import 'prelude.dart'; import 'prelude.dart';
import 'row/row_cache.dart'; import 'row/row_cache.dart';
typedef OnFieldsChanged = void Function(UnmodifiableListView<FieldPB>); typedef OnFieldsChanged = void Function(UnmodifiableListView<GridFieldContext>);
typedef OnGridChanged = void Function(GridPB); typedef OnGridChanged = void Function(GridPB);
typedef OnRowsChanged = void Function( typedef OnRowsChanged = void Function(
@ -25,7 +24,7 @@ typedef ListenOnRowChangedCondition = bool Function();
class GridDataController { class GridDataController {
final String gridId; final String gridId;
final GridFFIService _gridFFIService; final GridFFIService _gridFFIService;
final GridFieldCache fieldCache; final GridFieldController fieldController;
// key: the block id // key: the block id
final LinkedHashMap<String, GridBlockCache> _blocks; final LinkedHashMap<String, GridBlockCache> _blocks;
@ -49,7 +48,7 @@ class GridDataController {
// ignore: prefer_collection_literals // ignore: prefer_collection_literals
_blocks = LinkedHashMap(), _blocks = LinkedHashMap(),
_gridFFIService = GridFFIService(gridId: view.id), _gridFFIService = GridFFIService(gridId: view.id),
fieldCache = GridFieldCache(gridId: view.id); fieldController = GridFieldController(gridId: view.id);
void addListener({ void addListener({
required OnGridChanged onGridChanged, required OnGridChanged onGridChanged,
@ -60,7 +59,7 @@ class GridDataController {
_onRowChanged = onRowsChanged; _onRowChanged = onRowsChanged;
_onFieldsChanged = onFieldsChanged; _onFieldsChanged = onFieldsChanged;
fieldCache.addListener(onFields: (fields) { fieldController.addListener(onFields: (fields) {
_onFieldsChanged?.call(UnmodifiableListView(fields)); _onFieldsChanged?.call(UnmodifiableListView(fields));
}); });
} }
@ -72,7 +71,7 @@ class GridDataController {
(grid) async { (grid) async {
_initialBlocks(grid.blocks); _initialBlocks(grid.blocks);
_onGridChanged?.call(grid); _onGridChanged?.call(grid);
return await _loadFields(grid); return await fieldController.loadFields(fieldIds: grid.fields);
}, },
(err) => right(err), (err) => right(err),
), ),
@ -85,7 +84,7 @@ class GridDataController {
Future<void> dispose() async { Future<void> dispose() async {
await _gridFFIService.closeGrid(); await _gridFFIService.closeGrid();
await fieldCache.dispose(); await fieldController.dispose();
for (final blockCache in _blocks.values) { for (final blockCache in _blocks.values) {
blockCache.dispose(); blockCache.dispose();
@ -102,7 +101,7 @@ class GridDataController {
final cache = GridBlockCache( final cache = GridBlockCache(
gridId: gridId, gridId: gridId,
block: block, block: block,
fieldCache: fieldCache, fieldController: fieldController,
); );
cache.addListener( cache.addListener(
@ -114,18 +113,4 @@ class GridDataController {
_blocks[block.id] = cache; _blocks[block.id] = cache;
} }
} }
Future<Either<Unit, FlowyError>> _loadFields(GridPB grid) async {
final result = await _gridFFIService.getFields(fieldIds: grid.fields);
return Future(
() => result.fold(
(fields) {
fieldCache.fields = fields.items;
_onFieldsChanged?.call(UnmodifiableListView(fieldCache.fields));
return left(unit);
},
(err) => right(err),
),
);
}
} }

View File

@ -4,19 +4,18 @@ import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.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/field_cache.dart'; import 'field/field_cache.dart';
part 'grid_header_bloc.freezed.dart'; part 'grid_header_bloc.freezed.dart';
class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> { class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
final GridFieldCache fieldCache; final GridFieldController fieldController;
final String gridId; final String gridId;
GridHeaderBloc({ GridHeaderBloc({
required this.gridId, required this.gridId,
required this.fieldCache, required this.fieldController,
}) : super(GridHeaderState.initial(fieldCache.fields)) { }) : super(GridHeaderState.initial(fieldController.fieldContexts)) {
on<GridHeaderEvent>( on<GridHeaderEvent>(
(event, emit) async { (event, emit) async {
await event.map( await event.map(
@ -36,7 +35,7 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
Future<void> _moveField( Future<void> _moveField(
_MoveField value, Emitter<GridHeaderState> emit) async { _MoveField value, Emitter<GridHeaderState> emit) async {
final fields = List<FieldPB>.from(state.fields); final fields = List<GridFieldContext>.from(state.fields);
fields.insert(value.toIndex, fields.removeAt(value.fromIndex)); fields.insert(value.toIndex, fields.removeAt(value.fromIndex));
emit(state.copyWith(fields: fields)); emit(state.copyWith(fields: fields));
@ -49,7 +48,7 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
} }
Future<void> _startListening() async { Future<void> _startListening() async {
fieldCache.addListener( fieldController.addListener(
onFields: (fields) => add(GridHeaderEvent.didReceiveFieldUpdate(fields)), onFields: (fields) => add(GridHeaderEvent.didReceiveFieldUpdate(fields)),
listenWhen: () => !isClosed, listenWhen: () => !isClosed,
); );
@ -64,18 +63,18 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
@freezed @freezed
class GridHeaderEvent with _$GridHeaderEvent { class GridHeaderEvent with _$GridHeaderEvent {
const factory GridHeaderEvent.initial() = _InitialHeader; const factory GridHeaderEvent.initial() = _InitialHeader;
const factory GridHeaderEvent.didReceiveFieldUpdate(List<FieldPB> fields) = const factory GridHeaderEvent.didReceiveFieldUpdate(
_DidReceiveFieldUpdate; List<GridFieldContext> fields) = _DidReceiveFieldUpdate;
const factory GridHeaderEvent.moveField( const factory GridHeaderEvent.moveField(
FieldPB field, int fromIndex, int toIndex) = _MoveField; FieldPB field, int fromIndex, int toIndex) = _MoveField;
} }
@freezed @freezed
class GridHeaderState with _$GridHeaderState { class GridHeaderState with _$GridHeaderState {
const factory GridHeaderState({required List<FieldPB> fields}) = const factory GridHeaderState({required List<GridFieldContext> fields}) =
_GridHeaderState; _GridHeaderState;
factory GridHeaderState.initial(List<FieldPB> fields) { factory GridHeaderState.initial(List<GridFieldContext> fields) {
// final List<FieldPB> newFields = List.from(fields); // final List<FieldPB> newFields = List.from(fields);
// newFields.retainWhere((field) => field.visibility); // newFields.retainWhere((field) => field.visibility);
return GridHeaderState(fields: fields); return GridHeaderState(fields: fields);

View File

@ -1,7 +1,7 @@
import 'dart:collection'; import 'dart:collection';
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart'; import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.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';
@ -35,7 +35,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
}, },
didReceiveCells: (_DidReceiveCells value) async { didReceiveCells: (_DidReceiveCells value) async {
final cells = value.gridCellMap.values final cells = value.gridCellMap.values
.map((e) => GridCellEquatable(e.field)) .map((e) => GridCellEquatable(e.fieldContext))
.toList(); .toList();
emit(state.copyWith( emit(state.copyWith(
gridCellMap: value.gridCellMap, gridCellMap: value.gridCellMap,
@ -87,21 +87,23 @@ class RowState with _$RowState {
rowInfo: rowInfo, rowInfo: rowInfo,
gridCellMap: cellDataMap, gridCellMap: cellDataMap,
cells: UnmodifiableListView( cells: UnmodifiableListView(
cellDataMap.values.map((e) => GridCellEquatable(e.field)).toList(), cellDataMap.values
.map((e) => GridCellEquatable(e.fieldContext))
.toList(),
), ),
); );
} }
class GridCellEquatable extends Equatable { class GridCellEquatable extends Equatable {
final FieldPB _field; final GridFieldContext _fieldContext;
const GridCellEquatable(FieldPB field) : _field = field; const GridCellEquatable(GridFieldContext field) : _fieldContext = field;
@override @override
List<Object?> get props => [ List<Object?> get props => [
_field.id, _fieldContext.id,
_field.fieldType, _fieldContext.fieldType,
_field.visibility, _fieldContext.visibility,
_field.width, _fieldContext.width,
]; ];
} }

View File

@ -1,5 +1,6 @@
import 'dart:collection'; import 'dart:collection';
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart'; import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
@ -12,7 +13,7 @@ part 'row_cache.freezed.dart';
typedef RowUpdateCallback = void Function(); typedef RowUpdateCallback = void Function();
abstract class IGridRowFieldNotifier { abstract class IGridRowFieldNotifier {
UnmodifiableListView<FieldPB> get fields; UnmodifiableListView<GridFieldContext> get fields;
void onRowFieldsChanged(VoidCallback callback); void onRowFieldsChanged(VoidCallback callback);
void onRowFieldChanged(void Function(FieldPB) callback); void onRowFieldChanged(void Function(FieldPB) callback);
void onRowDispose(); void onRowDispose();
@ -217,7 +218,7 @@ class GridRowCache {
cellDataMap[field.id] = GridCellIdentifier( cellDataMap[field.id] = GridCellIdentifier(
rowId: rowId, rowId: rowId,
gridId: gridId, gridId: gridId,
field: field, fieldContext: field,
); );
} }
} }
@ -284,7 +285,7 @@ class _RowChangesetNotifier extends ChangeNotifier {
class RowInfo with _$RowInfo { class RowInfo with _$RowInfo {
const factory RowInfo({ const factory RowInfo({
required String gridId, required String gridId,
required UnmodifiableListView<FieldPB> fields, required UnmodifiableListView<GridFieldContext> fields,
required RowPB rowPB, required RowPB rowPB,
}) = _RowInfo; }) = _RowInfo;
} }

View File

@ -10,14 +10,14 @@ typedef OnRowChanged = void Function(GridCellMap, RowsChangedReason);
class GridRowDataController extends GridCellBuilderDelegate { class GridRowDataController extends GridCellBuilderDelegate {
final RowInfo rowInfo; final RowInfo rowInfo;
final List<VoidCallback> _onRowChangedListeners = []; final List<VoidCallback> _onRowChangedListeners = [];
final GridFieldCache _fieldCache; final GridFieldController _fieldController;
final GridRowCache _rowCache; final GridRowCache _rowCache;
GridRowDataController({ GridRowDataController({
required this.rowInfo, required this.rowInfo,
required GridFieldCache fieldCache, required GridFieldController fieldController,
required GridRowCache rowCache, required GridRowCache rowCache,
}) : _fieldCache = fieldCache, }) : _fieldController = fieldController,
_rowCache = rowCache; _rowCache = rowCache;
GridCellMap loadData() { GridCellMap loadData() {
@ -41,7 +41,7 @@ class GridRowDataController extends GridCellBuilderDelegate {
@override @override
GridCellFieldNotifier buildFieldNotifier() { GridCellFieldNotifier buildFieldNotifier() {
return GridCellFieldNotifier( return GridCellFieldNotifier(
notifier: GridCellFieldNotifierImpl(_fieldCache)); notifier: GridCellFieldNotifierImpl(_fieldController));
} }
@override @override

View File

@ -1,6 +1,5 @@
import 'package:app_flowy/plugins/grid/application/field/field_service.dart'; import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.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';
@ -11,14 +10,15 @@ import 'setting_controller.dart';
part 'group_bloc.freezed.dart'; part 'group_bloc.freezed.dart';
class GridGroupBloc extends Bloc<GridGroupEvent, GridGroupState> { class GridGroupBloc extends Bloc<GridGroupEvent, GridGroupState> {
final GridFieldCache _fieldCache; final GridFieldController _fieldController;
final SettingController _settingController; final SettingController _settingController;
Function(List<FieldPB>)? _onFieldsFn; Function(List<GridFieldContext>)? _onFieldsFn;
GridGroupBloc({required String viewId, required GridFieldCache fieldCache}) GridGroupBloc(
: _fieldCache = fieldCache, {required String viewId, required GridFieldController fieldController})
: _fieldController = fieldController,
_settingController = SettingController(viewId: viewId), _settingController = SettingController(viewId: viewId),
super(GridGroupState.initial(viewId, fieldCache.fields)) { super(GridGroupState.initial(viewId, fieldController.fieldContexts)) {
on<GridGroupEvent>( on<GridGroupEvent>(
(event, emit) async { (event, emit) async {
await event.map( await event.map(
@ -36,7 +36,7 @@ class GridGroupBloc extends Bloc<GridGroupEvent, GridGroupState> {
); );
}, },
didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) {
emit(state.copyWith(fields: value.fields)); emit(state.copyWith(fieldContexts: value.fields));
}, },
moveField: (_MoveField value) { moveField: (_MoveField value) {
// //
@ -49,7 +49,7 @@ class GridGroupBloc extends Bloc<GridGroupEvent, GridGroupState> {
@override @override
Future<void> close() async { Future<void> close() async {
if (_onFieldsFn != null) { if (_onFieldsFn != null) {
_fieldCache.removeListener(onFieldsListener: _onFieldsFn!); _fieldController.removeListener(onFieldsListener: _onFieldsFn!);
_onFieldsFn = null; _onFieldsFn = null;
} }
return super.close(); return super.close();
@ -57,7 +57,7 @@ class GridGroupBloc extends Bloc<GridGroupEvent, GridGroupState> {
void _startListening() { void _startListening() {
_onFieldsFn = (fields) => add(GridGroupEvent.didReceiveFieldUpdate(fields)); _onFieldsFn = (fields) => add(GridGroupEvent.didReceiveFieldUpdate(fields));
_fieldCache.addListener( _fieldController.addListener(
onFields: _onFieldsFn, onFields: _onFieldsFn,
listenWhen: () => !isClosed, listenWhen: () => !isClosed,
); );
@ -74,8 +74,8 @@ class GridGroupEvent with _$GridGroupEvent {
const factory GridGroupEvent.initial() = _Initial; const factory GridGroupEvent.initial() = _Initial;
const factory GridGroupEvent.setFieldVisibility( const factory GridGroupEvent.setFieldVisibility(
String fieldId, bool visibility) = _SetFieldVisibility; String fieldId, bool visibility) = _SetFieldVisibility;
const factory GridGroupEvent.didReceiveFieldUpdate(List<FieldPB> fields) = const factory GridGroupEvent.didReceiveFieldUpdate(
_DidReceiveFieldUpdate; List<GridFieldContext> fields) = _DidReceiveFieldUpdate;
const factory GridGroupEvent.moveField(int fromIndex, int toIndex) = const factory GridGroupEvent.moveField(int fromIndex, int toIndex) =
_MoveField; _MoveField;
} }
@ -84,12 +84,13 @@ class GridGroupEvent with _$GridGroupEvent {
class GridGroupState with _$GridGroupState { class GridGroupState with _$GridGroupState {
const factory GridGroupState({ const factory GridGroupState({
required String gridId, required String gridId,
required List<FieldPB> fields, required List<GridFieldContext> fieldContexts,
}) = _GridGroupState; }) = _GridGroupState;
factory GridGroupState.initial(String gridId, List<FieldPB> fields) => factory GridGroupState.initial(
String gridId, List<GridFieldContext> fieldContexts) =>
GridGroupState( GridGroupState(
gridId: gridId, gridId: gridId,
fields: fields, fieldContexts: fieldContexts,
); );
} }

View File

@ -1,6 +1,5 @@
import 'package:app_flowy/plugins/grid/application/field/field_service.dart'; import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.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';
@ -10,12 +9,14 @@ import '../field/field_cache.dart';
part 'property_bloc.freezed.dart'; part 'property_bloc.freezed.dart';
class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> { class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> {
final GridFieldCache _fieldCache; final GridFieldController _fieldController;
Function(List<FieldPB>)? _onFieldsFn; Function(List<GridFieldContext>)? _onFieldsFn;
GridPropertyBloc({required String gridId, required GridFieldCache fieldCache}) GridPropertyBloc(
: _fieldCache = fieldCache, {required String gridId, required GridFieldController fieldController})
super(GridPropertyState.initial(gridId, fieldCache.fields)) { : _fieldController = fieldController,
super(
GridPropertyState.initial(gridId, fieldController.fieldContexts)) {
on<GridPropertyEvent>( on<GridPropertyEvent>(
(event, emit) async { (event, emit) async {
await event.map( await event.map(
@ -33,7 +34,7 @@ class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> {
); );
}, },
didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) {
emit(state.copyWith(fields: value.fields)); emit(state.copyWith(fieldContexts: value.fields));
}, },
moveField: (_MoveField value) { moveField: (_MoveField value) {
// //
@ -46,7 +47,7 @@ class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> {
@override @override
Future<void> close() async { Future<void> close() async {
if (_onFieldsFn != null) { if (_onFieldsFn != null) {
_fieldCache.removeListener(onFieldsListener: _onFieldsFn!); _fieldController.removeListener(onFieldsListener: _onFieldsFn!);
_onFieldsFn = null; _onFieldsFn = null;
} }
return super.close(); return super.close();
@ -55,7 +56,7 @@ class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> {
void _startListening() { void _startListening() {
_onFieldsFn = _onFieldsFn =
(fields) => add(GridPropertyEvent.didReceiveFieldUpdate(fields)); (fields) => add(GridPropertyEvent.didReceiveFieldUpdate(fields));
_fieldCache.addListener( _fieldController.addListener(
onFields: _onFieldsFn, onFields: _onFieldsFn,
listenWhen: () => !isClosed, listenWhen: () => !isClosed,
); );
@ -67,8 +68,8 @@ class GridPropertyEvent with _$GridPropertyEvent {
const factory GridPropertyEvent.initial() = _Initial; const factory GridPropertyEvent.initial() = _Initial;
const factory GridPropertyEvent.setFieldVisibility( const factory GridPropertyEvent.setFieldVisibility(
String fieldId, bool visibility) = _SetFieldVisibility; String fieldId, bool visibility) = _SetFieldVisibility;
const factory GridPropertyEvent.didReceiveFieldUpdate(List<FieldPB> fields) = const factory GridPropertyEvent.didReceiveFieldUpdate(
_DidReceiveFieldUpdate; List<GridFieldContext> fields) = _DidReceiveFieldUpdate;
const factory GridPropertyEvent.moveField(int fromIndex, int toIndex) = const factory GridPropertyEvent.moveField(int fromIndex, int toIndex) =
_MoveField; _MoveField;
} }
@ -77,12 +78,15 @@ class GridPropertyEvent with _$GridPropertyEvent {
class GridPropertyState with _$GridPropertyState { class GridPropertyState with _$GridPropertyState {
const factory GridPropertyState({ const factory GridPropertyState({
required String gridId, required String gridId,
required List<FieldPB> fields, required List<GridFieldContext> fieldContexts,
}) = _GridPropertyState; }) = _GridPropertyState;
factory GridPropertyState.initial(String gridId, List<FieldPB> fields) => factory GridPropertyState.initial(
String gridId,
List<GridFieldContext> fieldContexts,
) =>
GridPropertyState( GridPropertyState(
gridId: gridId, gridId: gridId,
fields: fields, fieldContexts: fieldContexts,
); );
} }

View File

@ -41,6 +41,7 @@ class SettingController {
required OnError onError, required OnError onError,
}) { }) {
assert(_onSettingUpdated == null, 'Should call once'); assert(_onSettingUpdated == null, 'Should call once');
assert(_onError == null, 'Should call once');
_onSettingUpdated = onSettingUpdated; _onSettingUpdated = onSettingUpdated;
_onError = onError; _onError = onError;
} }

View File

@ -157,10 +157,11 @@ class _FlowyGridState extends State<FlowyGrid> {
} }
Widget _gridHeader(BuildContext context, String gridId) { Widget _gridHeader(BuildContext context, String gridId) {
final fieldCache = context.read<GridBloc>().dataController.fieldCache; final fieldController =
context.read<GridBloc>().dataController.fieldController;
return GridHeaderSliverAdaptor( return GridHeaderSliverAdaptor(
gridId: gridId, gridId: gridId,
fieldCache: fieldCache, fieldController: fieldController,
anchorScrollController: headerScrollController, anchorScrollController: headerScrollController,
); );
} }
@ -173,10 +174,11 @@ class _GridToolbarAdaptor extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocSelector<GridBloc, GridState, GridToolbarContext>( return BlocSelector<GridBloc, GridState, GridToolbarContext>(
selector: (state) { selector: (state) {
final fieldCache = context.read<GridBloc>().dataController.fieldCache; final fieldController =
context.read<GridBloc>().dataController.fieldController;
return GridToolbarContext( return GridToolbarContext(
gridId: state.gridId, gridId: state.gridId,
fieldCache: fieldCache, fieldController: fieldController,
); );
}, },
builder: (context, toolbarContext) { builder: (context, toolbarContext) {
@ -247,10 +249,11 @@ class _GridRowsState extends State<_GridRows> {
/// Return placeholder widget if the rowCache is null. /// Return placeholder widget if the rowCache is null.
if (rowCache == null) return const SizedBox(); if (rowCache == null) return const SizedBox();
final fieldCache = context.read<GridBloc>().dataController.fieldCache; final fieldController =
context.read<GridBloc>().dataController.fieldController;
final dataController = GridRowDataController( final dataController = GridRowDataController(
rowInfo: rowInfo, rowInfo: rowInfo,
fieldCache: fieldCache, fieldController: fieldController,
rowCache: rowCache, rowCache: rowCache,
); );
@ -264,7 +267,7 @@ class _GridRowsState extends State<_GridRows> {
_openRowDetailPage( _openRowDetailPage(
context, context,
rowInfo, rowInfo,
fieldCache, fieldController,
rowCache, rowCache,
cellBuilder, cellBuilder,
); );
@ -277,13 +280,13 @@ class _GridRowsState extends State<_GridRows> {
void _openRowDetailPage( void _openRowDetailPage(
BuildContext context, BuildContext context,
RowInfo rowInfo, RowInfo rowInfo,
GridFieldCache fieldCache, GridFieldController fieldController,
GridRowCache rowCache, GridRowCache rowCache,
GridCellBuilder cellBuilder, GridCellBuilder cellBuilder,
) { ) {
final dataController = GridRowDataController( final dataController = GridRowDataController(
rowInfo: rowInfo, rowInfo: rowInfo,
fieldCache: fieldCache, fieldController: fieldController,
rowCache: rowCache, rowCache: rowCache,
); );

View File

@ -1,8 +1,8 @@
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
import 'sizes.dart'; import 'sizes.dart';
class GridLayout { class GridLayout {
static double headerWidth(List<FieldPB> fields) { static double headerWidth(List<GridFieldContext> fields) {
if (fields.isEmpty) return 0; if (fields.isEmpty) return 0;
final fieldsWidth = fields final fieldsWidth = fields

View File

@ -1,3 +1,4 @@
import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
import 'package:app_flowy/plugins/grid/application/field/field_cell_bloc.dart'; import 'package:app_flowy/plugins/grid/application/field/field_cell_bloc.dart';
import 'package:app_flowy/plugins/grid/application/field/field_service.dart'; import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart'; import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';

View File

@ -18,11 +18,11 @@ import 'field_cell.dart';
class GridHeaderSliverAdaptor extends StatefulWidget { class GridHeaderSliverAdaptor extends StatefulWidget {
final String gridId; final String gridId;
final GridFieldCache fieldCache; final GridFieldController fieldController;
final ScrollController anchorScrollController; final ScrollController anchorScrollController;
const GridHeaderSliverAdaptor({ const GridHeaderSliverAdaptor({
required this.gridId, required this.gridId,
required this.fieldCache, required this.fieldController,
required this.anchorScrollController, required this.anchorScrollController,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -38,7 +38,7 @@ class _GridHeaderSliverAdaptorState extends State<GridHeaderSliverAdaptor> {
return BlocProvider( return BlocProvider(
create: (context) { create: (context) {
final bloc = getIt<GridHeaderBloc>( final bloc = getIt<GridHeaderBloc>(
param1: widget.gridId, param2: widget.fieldCache); param1: widget.gridId, param2: widget.fieldController);
bloc.add(const GridHeaderEvent.initial()); bloc.add(const GridHeaderEvent.initial());
return bloc; return bloc;
}, },
@ -84,7 +84,7 @@ class _GridHeaderState extends State<_GridHeader> {
final cells = state.fields final cells = state.fields
.where((field) => field.visibility) .where((field) => field.visibility)
.map((field) => .map((field) =>
GridFieldCellContext(gridId: widget.gridId, field: field)) GridFieldCellContext(gridId: widget.gridId, field: field.field))
.map((ctx) => GridFieldCell(ctx, key: ValueKey(ctx.field.id))) .map((ctx) => GridFieldCell(ctx, key: ValueKey(ctx.field.id)))
.toList(); .toList();

View File

@ -1,5 +1,6 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart'; import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_data_controller.dart'; import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_data_controller.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pb.dart';
@ -129,17 +130,18 @@ TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder({
TypeOptionContext<T> makeTypeOptionContext<T extends GeneratedMessage>({ TypeOptionContext<T> makeTypeOptionContext<T extends GeneratedMessage>({
required String gridId, required String gridId,
required FieldPB field, required GridFieldContext fieldContext,
}) { }) {
final loader = FieldTypeOptionLoader(gridId: gridId, field: field); final loader =
FieldTypeOptionLoader(gridId: gridId, field: fieldContext.field);
final dataController = TypeOptionDataController( final dataController = TypeOptionDataController(
gridId: gridId, gridId: gridId,
loader: loader, loader: loader,
field: field, fieldContext: fieldContext,
); );
return makeTypeOptionContextWithDataController( return makeTypeOptionContextWithDataController(
gridId: gridId, gridId: gridId,
fieldType: field.fieldType, fieldType: fieldContext.fieldType,
dataController: dataController, dataController: dataController,
); );
} }

View File

@ -189,13 +189,13 @@ class RowContent extends StatelessWidget {
final GridCellWidget child = builder.build(cellId); final GridCellWidget child = builder.build(cellId);
return CellContainer( return CellContainer(
width: cellId.field.width.toDouble(), width: cellId.fieldContext.width.toDouble(),
rowStateNotifier: rowStateNotifier:
Provider.of<RegionStateNotifier>(context, listen: false), Provider.of<RegionStateNotifier>(context, listen: false),
accessoryBuilder: (buildContext) { accessoryBuilder: (buildContext) {
final builder = child.accessoryBuilder; final builder = child.accessoryBuilder;
List<GridCellAccessory> accessories = []; List<GridCellAccessory> accessories = [];
if (cellId.field.isPrimary) { if (cellId.fieldContext.isPrimary) {
accessories.add(PrimaryCellAccessory( accessories.add(PrimaryCellAccessory(
onTapCallback: onExpand, onTapCallback: onExpand,
isCellEditing: buildContext.isCellEditing, isCellEditing: buildContext.isCellEditing,

View File

@ -215,7 +215,7 @@ class _RowDetailCell extends StatelessWidget {
SizedBox( SizedBox(
width: 150, width: 150,
child: FieldCellButton( child: FieldCellButton(
field: cellId.field, field: cellId.fieldContext.fieldContext,
onTap: () => _showFieldEditor(context), onTap: () => _showFieldEditor(context),
), ),
), ),
@ -230,10 +230,10 @@ class _RowDetailCell extends StatelessWidget {
void _showFieldEditor(BuildContext context) { void _showFieldEditor(BuildContext context) {
FieldEditor( FieldEditor(
gridId: cellId.gridId, gridId: cellId.gridId,
fieldName: cellId.field.name, fieldName: cellId.fieldContext.name,
typeOptionLoader: FieldTypeOptionLoader( typeOptionLoader: FieldTypeOptionLoader(
gridId: cellId.gridId, gridId: cellId.gridId,
field: cellId.field, field: cellId.fieldContext.fieldContext,
), ),
).show(context); ).show(context);
} }

View File

@ -6,7 +6,6 @@ import 'package:flowy_infra/theme.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_infra_ui/widget/spacing.dart'; import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:app_flowy/plugins/grid/application/setting/group_bloc.dart'; import 'package:app_flowy/plugins/grid/application/setting/group_bloc.dart';
@ -14,10 +13,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
class GridGroupList extends StatelessWidget { class GridGroupList extends StatelessWidget {
final String viewId; final String viewId;
final GridFieldCache fieldCache; final GridFieldController fieldController;
const GridGroupList({ const GridGroupList({
required this.viewId, required this.viewId,
required this.fieldCache, required this.fieldController,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -26,13 +25,13 @@ class GridGroupList extends StatelessWidget {
return BlocProvider( return BlocProvider(
create: (context) => GridGroupBloc( create: (context) => GridGroupBloc(
viewId: viewId, viewId: viewId,
fieldCache: fieldCache, fieldController: fieldController,
)..add(const GridGroupEvent.initial()), )..add(const GridGroupEvent.initial()),
child: BlocBuilder<GridGroupBloc, GridGroupState>( child: BlocBuilder<GridGroupBloc, GridGroupState>(
builder: (context, state) { builder: (context, state) {
final cells = state.fields.map((field) { final cells = state.fieldContexts.map((field) {
return _GridGroupCell( return _GridGroupCell(
field: field, fieldContext: field,
key: ValueKey(field.id), key: ValueKey(field.id),
); );
}).toList(); }).toList();
@ -56,8 +55,9 @@ class GridGroupList extends StatelessWidget {
} }
class _GridGroupCell extends StatelessWidget { class _GridGroupCell extends StatelessWidget {
final FieldPB field; final GridFieldContext fieldContext;
const _GridGroupCell({required this.field, Key? key}) : super(key: key); const _GridGroupCell({required this.fieldContext, Key? key})
: super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -73,9 +73,10 @@ class _GridGroupCell extends StatelessWidget {
// ), // ),
return FlowyButton( return FlowyButton(
text: FlowyText.medium(field.name, fontSize: 12), text: FlowyText.medium(fieldContext.name, fontSize: 12),
hoverColor: theme.hover, hoverColor: theme.hover,
leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), leftIcon:
svgWidget(fieldContext.fieldType.iconName(), color: theme.iconColor),
onTap: () {}, onTap: () {},
); );
} }

View File

@ -9,7 +9,6 @@ import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.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/field_entities.pb.dart';
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 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
@ -20,10 +19,10 @@ import '../header/field_editor.dart';
class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate { class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate {
final String gridId; final String gridId;
final GridFieldCache fieldCache; final GridFieldController fieldController;
const GridPropertyList({ const GridPropertyList({
required this.gridId, required this.gridId,
required this.fieldCache, required this.fieldController,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -45,13 +44,13 @@ class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => create: (context) =>
getIt<GridPropertyBloc>(param1: gridId, param2: fieldCache) getIt<GridPropertyBloc>(param1: gridId, param2: fieldController)
..add(const GridPropertyEvent.initial()), ..add(const GridPropertyEvent.initial()),
child: BlocBuilder<GridPropertyBloc, GridPropertyState>( child: BlocBuilder<GridPropertyBloc, GridPropertyState>(
builder: (context, state) { builder: (context, state) {
final cells = state.fields.map((field) { final cells = state.fieldContexts.map((field) {
return _GridPropertyCell( return _GridPropertyCell(
gridId: gridId, field: field, key: ValueKey(field.id)); gridId: gridId, fieldContext: field, key: ValueKey(field.id));
}).toList(); }).toList();
return ListView.separated( return ListView.separated(
@ -78,16 +77,17 @@ class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate {
} }
class _GridPropertyCell extends StatelessWidget { class _GridPropertyCell extends StatelessWidget {
final FieldPB field; final GridFieldContext fieldContext;
final String gridId; final String gridId;
const _GridPropertyCell({required this.gridId, required this.field, Key? key}) const _GridPropertyCell(
{required this.gridId, required this.fieldContext, Key? key})
: super(key: key); : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = context.watch<AppTheme>(); final theme = context.watch<AppTheme>();
final checkmark = field.visibility final checkmark = fieldContext.visibility
? svgWidget('home/show', color: theme.iconColor) ? svgWidget('home/show', color: theme.iconColor)
: svgWidget('home/hide', color: theme.iconColor); : svgWidget('home/hide', color: theme.iconColor);
@ -105,7 +105,7 @@ class _GridPropertyCell extends StatelessWidget {
onPressed: () { onPressed: () {
context.read<GridPropertyBloc>().add( context.read<GridPropertyBloc>().add(
GridPropertyEvent.setFieldVisibility( GridPropertyEvent.setFieldVisibility(
field.id, !field.visibility)); fieldContext.id, !fieldContext.visibility));
}, },
icon: checkmark.padding(all: 6), icon: checkmark.padding(all: 6),
) )
@ -115,14 +115,18 @@ class _GridPropertyCell extends StatelessWidget {
FlowyButton _editFieldButton(AppTheme theme, BuildContext context) { FlowyButton _editFieldButton(AppTheme theme, BuildContext context) {
return FlowyButton( return FlowyButton(
text: FlowyText.medium(field.name, fontSize: 12), text: FlowyText.medium(fieldContext.name, fontSize: 12),
hoverColor: theme.hover, hoverColor: theme.hover,
leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), leftIcon:
svgWidget(fieldContext.fieldType.iconName(), color: theme.iconColor),
onTap: () { onTap: () {
FieldEditor( FieldEditor(
gridId: gridId, gridId: gridId,
fieldName: field.name, fieldName: fieldContext.name,
typeOptionLoader: FieldTypeOptionLoader(gridId: gridId, field: field), typeOptionLoader: FieldTypeOptionLoader(
gridId: gridId,
field: fieldContext.field,
),
).show(context, anchorDirection: AnchorDirection.bottomRight); ).show(context, anchorDirection: AnchorDirection.bottomRight);
}, },
); );

View File

@ -17,11 +17,11 @@ import 'grid_property.dart';
class GridSettingContext { class GridSettingContext {
final String gridId; final String gridId;
final GridFieldCache fieldCache; final GridFieldController fieldController;
GridSettingContext({ GridSettingContext({
required this.gridId, required this.gridId,
required this.fieldCache, required this.fieldController,
}); });
} }
@ -44,7 +44,7 @@ class GridSettingList extends StatelessWidget {
case GridSettingAction.properties: case GridSettingAction.properties:
GridPropertyList( GridPropertyList(
gridId: settingContext.gridId, gridId: settingContext.gridId,
fieldCache: settingContext.fieldCache) fieldController: settingContext.fieldController)
.show(context); .show(context);
break; break;
} }

View File

@ -11,10 +11,10 @@ import 'grid_setting.dart';
class GridToolbarContext { class GridToolbarContext {
final String gridId; final String gridId;
final GridFieldCache fieldCache; final GridFieldController fieldController;
GridToolbarContext({ GridToolbarContext({
required this.gridId, required this.gridId,
required this.fieldCache, required this.fieldController,
}); });
} }
@ -26,7 +26,7 @@ class GridToolbar extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final settingContext = GridSettingContext( final settingContext = GridSettingContext(
gridId: toolbarContext.gridId, gridId: toolbarContext.gridId,
fieldCache: toolbarContext.fieldCache, fieldController: toolbarContext.fieldController,
); );
return SizedBox( return SizedBox(
height: 40, height: 40,

View File

@ -154,10 +154,10 @@ void _resolveGridDeps(GetIt getIt) {
(view, _) => GridBloc(view: view), (view, _) => GridBloc(view: view),
); );
getIt.registerFactoryParam<GridHeaderBloc, String, GridFieldCache>( getIt.registerFactoryParam<GridHeaderBloc, String, GridFieldController>(
(gridId, fieldCache) => GridHeaderBloc( (gridId, fieldController) => GridHeaderBloc(
gridId: gridId, gridId: gridId,
fieldCache: fieldCache, fieldController: fieldController,
), ),
); );
@ -200,7 +200,7 @@ void _resolveGridDeps(GetIt getIt) {
), ),
); );
getIt.registerFactoryParam<GridPropertyBloc, String, GridFieldCache>( getIt.registerFactoryParam<GridPropertyBloc, String, GridFieldController>(
(gridId, cache) => GridPropertyBloc(gridId: gridId, fieldCache: cache), (gridId, cache) => GridPropertyBloc(gridId: gridId, fieldController: cache),
); );
} }