import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/foundation.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; class GridService { final String gridId; GridService({ required this.gridId, }); Future> loadGrid() async { await FolderEventSetLatestView(ViewId(value: gridId)).send(); final payload = GridId(value: gridId); return GridEventGetGridData(payload).send(); } Future> createRow({Option? startRowId}) { CreateRowPayload payload = CreateRowPayload.create()..gridId = gridId; startRowId?.fold(() => null, (id) => payload.startRowId = id); return GridEventCreateRow(payload).send(); } Future> getFields({required List fieldOrders}) { final payload = QueryFieldPayload.create() ..gridId = gridId ..fieldOrders = RepeatedFieldOrder(items: fieldOrders); return GridEventGetFields(payload).send(); } Future> closeGrid() { final request = ViewId(value: gridId); return FolderEventCloseView(request).send(); } } class FieldsNotifier extends ChangeNotifier { List _fields = []; set fields(List fields) { _fields = fields; notifyListeners(); } List get fields => _fields; } class GridFieldCache { final String gridId; late final GridFieldsListener _fieldListener; final FieldsNotifier _fieldNotifier = FieldsNotifier(); GridFieldCache({required this.gridId}) { _fieldListener = GridFieldsListener(gridId: gridId); _fieldListener.updateFieldsNotifier?.addPublishListener((result) { result.fold( (changeset) { _deleteFields(changeset.deletedFields); _insertFields(changeset.insertedFields); _updateFields(changeset.updatedFields); }, (err) => Log.error(err), ); }); _fieldListener.start(); } Future dispose() async { await _fieldListener.stop(); _fieldNotifier.dispose(); } void applyChangeset(GridFieldChangeset changeset) {} UnmodifiableListView get unmodifiableFields => UnmodifiableListView(_fieldNotifier.fields); List get clonedFields => [..._fieldNotifier.fields]; set fields(List fields) { _fieldNotifier.fields = [...fields]; } void addListener({VoidCallback? listener, void Function(List)? onChanged, bool Function()? listenWhen}) { _fieldNotifier.addListener(() { if (listenWhen != null && listenWhen() == false) { return; } if (onChanged != null) { onChanged(clonedFields); } if (listener != null) { listener(); } }); } void _deleteFields(List deletedFields) { if (deletedFields.isEmpty) { return; } final List fields = _fieldNotifier.fields; final Map deletedFieldMap = { for (var fieldOrder in deletedFields) fieldOrder.fieldId: fieldOrder }; fields.retainWhere((field) => (deletedFieldMap[field.id] == null)); _fieldNotifier.fields = fields; } void _insertFields(List insertedFields) { if (insertedFields.isEmpty) { return; } final List fields = _fieldNotifier.fields; for (final indexField in insertedFields) { if (fields.length > indexField.index) { fields.insert(indexField.index, indexField.field_1); } else { fields.add(indexField.field_1); } } _fieldNotifier.fields = fields; } void _updateFields(List updatedFields) { if (updatedFields.isEmpty) { return; } final List fields = _fieldNotifier.fields; for (final updatedField in updatedFields) { final index = fields.indexWhere((field) => field.id == updatedField.id); if (index != -1) { fields.removeAt(index); fields.insert(index, updatedField); } } _fieldNotifier.fields = fields; } }