mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: hide the grid blocks from Dart
This commit is contained in:
parent
07ebb0cb95
commit
0cf0b29721
@ -1,7 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:app_flowy/plugins/grid/application/block/block_cache.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/row/row_service.dart';
|
||||
@ -229,8 +228,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
}
|
||||
|
||||
GridRowCache? getRowCache(String blockId) {
|
||||
final GridBlockCache? blockCache = _gridDataController.blocks[blockId];
|
||||
return blockCache?.rowCache;
|
||||
return _gridDataController.rowCache;
|
||||
}
|
||||
|
||||
void _startListening() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:app_flowy/plugins/grid/application/block/block_cache.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/view/grid_view_cache.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/grid_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
|
||||
@ -31,11 +31,7 @@ class BoardDataController {
|
||||
final GridFFIService _gridFFIService;
|
||||
final GridFieldController fieldController;
|
||||
final BoardListener _listener;
|
||||
|
||||
// key: the block id
|
||||
final LinkedHashMap<String, GridBlockCache> _blocks;
|
||||
UnmodifiableMapView<String, GridBlockCache> get blocks =>
|
||||
UnmodifiableMapView(_blocks);
|
||||
late GridViewCache _viewCache;
|
||||
|
||||
OnFieldsChanged? _onFieldsChanged;
|
||||
OnGridChanged? _onGridChanged;
|
||||
@ -43,21 +39,23 @@ class BoardDataController {
|
||||
OnRowsChanged? _onRowsChanged;
|
||||
OnError? _onError;
|
||||
|
||||
List<RowInfo> get rowInfos {
|
||||
final List<RowInfo> rows = [];
|
||||
for (var block in _blocks.values) {
|
||||
rows.addAll(block.rows);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
List<RowInfo> get rowInfos => _viewCache.rowInfos;
|
||||
GridRowCache get rowCache => _viewCache.rowCache;
|
||||
|
||||
BoardDataController({required ViewPB view})
|
||||
: gridId = view.id,
|
||||
_listener = BoardListener(view.id),
|
||||
// ignore: prefer_collection_literals
|
||||
_blocks = LinkedHashMap(),
|
||||
_gridFFIService = GridFFIService(gridId: view.id),
|
||||
fieldController = GridFieldController(gridId: view.id);
|
||||
fieldController = GridFieldController(gridId: view.id) {
|
||||
//
|
||||
_viewCache = GridViewCache(
|
||||
gridId: view.id,
|
||||
fieldController: fieldController,
|
||||
);
|
||||
_viewCache.addListener(onRowsChanged: (reason) {
|
||||
_onRowsChanged?.call(rowInfos, reason);
|
||||
});
|
||||
}
|
||||
|
||||
void addListener({
|
||||
required OnGridChanged onGridChanged,
|
||||
@ -110,23 +108,21 @@ class BoardDataController {
|
||||
|
||||
Future<Either<Unit, FlowyError>> openGrid() async {
|
||||
final result = await _gridFFIService.openGrid();
|
||||
return Future(
|
||||
() => result.fold(
|
||||
(grid) async {
|
||||
_onGridChanged?.call(grid);
|
||||
final result = await fieldController.loadFields(
|
||||
fieldIds: grid.fields,
|
||||
);
|
||||
return result.fold(
|
||||
(l) {
|
||||
_loadGroups(grid.blocks);
|
||||
return left(l);
|
||||
},
|
||||
(err) => right(err),
|
||||
);
|
||||
},
|
||||
(err) => right(err),
|
||||
),
|
||||
|
||||
return result.fold(
|
||||
(grid) async {
|
||||
_onGridChanged?.call(grid);
|
||||
final result = await fieldController.loadFields(fieldIds: grid.fields);
|
||||
return result.fold(
|
||||
(l) {
|
||||
_loadGroups();
|
||||
_viewCache.rowCache.initializeRows(grid.rows);
|
||||
return left(l);
|
||||
},
|
||||
(err) => right(err),
|
||||
);
|
||||
},
|
||||
(err) => right(err),
|
||||
);
|
||||
}
|
||||
|
||||
@ -138,26 +134,9 @@ class BoardDataController {
|
||||
Future<void> dispose() async {
|
||||
await _gridFFIService.closeGrid();
|
||||
await fieldController.dispose();
|
||||
|
||||
for (final blockCache in _blocks.values) {
|
||||
blockCache.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadGroups(List<BlockPB> blocks) async {
|
||||
for (final block in blocks) {
|
||||
final cache = GridBlockCache(
|
||||
gridId: gridId,
|
||||
block: block,
|
||||
fieldController: fieldController,
|
||||
);
|
||||
|
||||
cache.addListener(onRowsChanged: (reason) {
|
||||
_onRowsChanged?.call(rowInfos, reason);
|
||||
});
|
||||
_blocks[block.id] = cache;
|
||||
}
|
||||
|
||||
Future<void> _loadGroups() async {
|
||||
final result = await _gridFFIService.loadGroups();
|
||||
return Future(
|
||||
() => result.fold(
|
||||
|
@ -3,7 +3,7 @@ import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_servic
|
||||
import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/row/row_service.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
@ -3,7 +3,7 @@ import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_servic
|
||||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_field_notifier.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
typedef OnCardChanged = void Function(GridCellMap, RowsChangedReason);
|
||||
|
@ -16,8 +16,8 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
|
||||
import 'package:flowy_infra_ui/widget/error_page.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/field_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../grid/application/row/row_cache.dart';
|
||||
|
@ -1,53 +0,0 @@
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:app_flowy/core/grid_notification.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
|
||||
typedef GridBlockUpdateNotifierValue = Either<GridBlockChangesetPB, FlowyError>;
|
||||
|
||||
class GridBlockListener {
|
||||
final String blockId;
|
||||
PublishNotifier<GridBlockUpdateNotifierValue>? _rowsUpdateNotifier =
|
||||
PublishNotifier();
|
||||
GridNotificationListener? _listener;
|
||||
|
||||
GridBlockListener({required this.blockId});
|
||||
|
||||
void start(void Function(GridBlockUpdateNotifierValue) onBlockChanged) {
|
||||
if (_listener != null) {
|
||||
_listener?.stop();
|
||||
}
|
||||
|
||||
_listener = GridNotificationListener(
|
||||
objectId: blockId,
|
||||
handler: _handler,
|
||||
);
|
||||
|
||||
_rowsUpdateNotifier?.addPublishListener(onBlockChanged);
|
||||
}
|
||||
|
||||
void _handler(GridDartNotification ty, Either<Uint8List, FlowyError> result) {
|
||||
switch (ty) {
|
||||
case GridDartNotification.DidUpdateGridRows:
|
||||
result.fold(
|
||||
(payload) => _rowsUpdateNotifier?.value =
|
||||
left(GridBlockChangesetPB.fromBuffer(payload)),
|
||||
(error) => _rowsUpdateNotifier?.value = right(error),
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> stop() async {
|
||||
await _listener?.stop();
|
||||
_rowsUpdateNotifier?.dispose();
|
||||
_rowsUpdateNotifier = null;
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'block/block_cache.dart';
|
||||
import 'field/field_controller.dart';
|
||||
import 'grid_data_controller.dart';
|
||||
import 'row/row_cache.dart';
|
||||
@ -69,8 +68,7 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
||||
}
|
||||
|
||||
GridRowCache? getRowCache(String blockId, String rowId) {
|
||||
final GridBlockCache? blockCache = gridController.blocks[blockId];
|
||||
return blockCache?.rowCache;
|
||||
return gridController.rowCache;
|
||||
}
|
||||
|
||||
void _startListening() {
|
||||
|
@ -1,14 +1,10 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/filter_info.dart';
|
||||
import 'package:flowy_sdk/log.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-grid/block_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
|
||||
import 'dart:async';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'block/block_cache.dart';
|
||||
import 'view/grid_view_cache.dart';
|
||||
import 'field/field_controller.dart';
|
||||
import 'prelude.dart';
|
||||
import 'row/row_cache.dart';
|
||||
@ -27,29 +23,25 @@ class GridController {
|
||||
final String gridId;
|
||||
final GridFFIService _gridFFIService;
|
||||
final GridFieldController fieldController;
|
||||
late GridViewCache _viewCache;
|
||||
|
||||
OnRowsChanged? _onRowChanged;
|
||||
OnGridChanged? _onGridChanged;
|
||||
|
||||
// Getters
|
||||
// key: the block id
|
||||
final LinkedHashMap<String, GridBlockCache> _blocks;
|
||||
UnmodifiableMapView<String, GridBlockCache> get blocks =>
|
||||
UnmodifiableMapView(_blocks);
|
||||
|
||||
List<RowInfo> get rowInfos {
|
||||
final List<RowInfo> rows = [];
|
||||
for (var block in _blocks.values) {
|
||||
rows.addAll(block.rows);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
List<RowInfo> get rowInfos => _viewCache.rowInfos;
|
||||
GridRowCache get rowCache => _viewCache.rowCache;
|
||||
|
||||
GridController({required ViewPB view})
|
||||
: gridId = view.id,
|
||||
// ignore: prefer_collection_literals
|
||||
_blocks = LinkedHashMap(),
|
||||
_gridFFIService = GridFFIService(gridId: view.id),
|
||||
fieldController = GridFieldController(gridId: view.id);
|
||||
fieldController = GridFieldController(gridId: view.id) {
|
||||
_viewCache = GridViewCache(
|
||||
gridId: gridId,
|
||||
fieldController: fieldController,
|
||||
);
|
||||
_viewCache.addListener(onRowsChanged: (reason) {
|
||||
_onRowChanged?.call(rowInfos, reason);
|
||||
});
|
||||
}
|
||||
|
||||
void addListener({
|
||||
OnGridChanged? onGridChanged,
|
||||
@ -71,9 +63,8 @@ class GridController {
|
||||
return _gridFFIService.openGrid().then((result) {
|
||||
return result.fold(
|
||||
(grid) async {
|
||||
_initialBlocks(grid.blocks);
|
||||
_onGridChanged?.call(grid);
|
||||
|
||||
_viewCache.rowCache.initializeRows(grid.rows);
|
||||
final result = await fieldController.loadFields(
|
||||
fieldIds: grid.fields,
|
||||
);
|
||||
@ -91,30 +82,5 @@ class GridController {
|
||||
Future<void> dispose() async {
|
||||
await _gridFFIService.closeGrid();
|
||||
await fieldController.dispose();
|
||||
|
||||
for (final blockCache in _blocks.values) {
|
||||
blockCache.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
void _initialBlocks(List<BlockPB> blocks) {
|
||||
for (final block in blocks) {
|
||||
if (_blocks[block.id] != null) {
|
||||
Log.warn("Initial duplicate block's cache: ${block.id}");
|
||||
return;
|
||||
}
|
||||
|
||||
final cache = GridBlockCache(
|
||||
gridId: gridId,
|
||||
block: block,
|
||||
fieldController: fieldController,
|
||||
);
|
||||
|
||||
cache.addListener(onRowsChanged: (reason) {
|
||||
_onRowChanged?.call(rowInfos, reason);
|
||||
});
|
||||
|
||||
_blocks[block.id] = cache;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.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-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/group.pb.dart';
|
||||
|
@ -3,9 +3,7 @@ import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_servic
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.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/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
@ -28,7 +26,7 @@ abstract class IGridRowFieldNotifier {
|
||||
|
||||
class GridRowCache {
|
||||
final String gridId;
|
||||
final BlockPB block;
|
||||
final List<RowPB> rows;
|
||||
|
||||
/// _rows containers the current block's rows
|
||||
/// Use List to reverse the order of the GridRow.
|
||||
@ -47,7 +45,7 @@ class GridRowCache {
|
||||
|
||||
GridRowCache({
|
||||
required this.gridId,
|
||||
required this.block,
|
||||
required this.rows,
|
||||
required IGridRowFieldNotifier notifier,
|
||||
}) : _cellCache = GridCellCache(gridId: gridId),
|
||||
_rowChangeReasonNotifier = _RowChangesetNotifier(),
|
||||
@ -57,8 +55,10 @@ class GridRowCache {
|
||||
.receive(const RowsChangedReason.fieldDidChange()));
|
||||
notifier.onRowFieldChanged(
|
||||
(field) => _cellCache.removeCellWithFieldId(field.id));
|
||||
}
|
||||
|
||||
for (final row in block.rows) {
|
||||
void initializeRows(List<RowPB> rows) {
|
||||
for (final row in rows) {
|
||||
final rowInfo = buildGridRow(row);
|
||||
_rowList.add(rowInfo);
|
||||
}
|
||||
@ -70,14 +70,6 @@ class GridRowCache {
|
||||
await _cellCache.dispose();
|
||||
}
|
||||
|
||||
void applyChangesets(GridBlockChangesetPB changeset) {
|
||||
_deleteRows(changeset.deletedRows);
|
||||
_insertRows(changeset.insertedRows);
|
||||
_updateRows(changeset.updatedRows);
|
||||
_hideRows(changeset.invisibleRows);
|
||||
_showRows(changeset.visibleRows);
|
||||
}
|
||||
|
||||
void applyRowsChanged(GridViewRowsChangesetPB changeset) {
|
||||
_deleteRows(changeset.deletedRows);
|
||||
_insertRows(changeset.insertedRows);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
|
||||
import 'row_cache.dart';
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
import 'package:app_flowy/core/grid_notification.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
|
||||
typedef UpdateRowNotifiedValue = Either<RowPB, FlowyError>;
|
||||
typedef UpdateFieldNotifiedValue = Either<List<FieldPB>, FlowyError>;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/group_changeset.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
|
@ -1,29 +1,26 @@
|
||||
import 'dart:async';
|
||||
import 'package:app_flowy/plugins/grid/application/view/grid_view_listener.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
||||
|
||||
import '../field/field_controller.dart';
|
||||
import '../row/row_cache.dart';
|
||||
|
||||
/// Read https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/frontend/grid for more information
|
||||
class GridBlockCache {
|
||||
class GridViewCache {
|
||||
final String gridId;
|
||||
final BlockPB block;
|
||||
late GridRowCache _rowCache;
|
||||
final GridViewListener _gridViewListener;
|
||||
|
||||
List<RowInfo> get rows => _rowCache.visibleRows;
|
||||
List<RowInfo> get rowInfos => _rowCache.visibleRows;
|
||||
GridRowCache get rowCache => _rowCache;
|
||||
|
||||
GridBlockCache({
|
||||
GridViewCache({
|
||||
required this.gridId,
|
||||
required this.block,
|
||||
required GridFieldController fieldController,
|
||||
}) : _gridViewListener = GridViewListener(viewId: gridId) {
|
||||
_rowCache = GridRowCache(
|
||||
gridId: gridId,
|
||||
block: block,
|
||||
rows: [],
|
||||
notifier: GridRowFieldNotifierImpl(fieldController),
|
||||
);
|
||||
|
@ -1,8 +1,5 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:app_flowy/plugins/board/application/board_data_controller.dart';
|
||||
import 'package:app_flowy/plugins/board/board.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/block/block_cache.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_editor_bloc.dart';
|
||||
@ -74,10 +71,6 @@ class BoardTestContext {
|
||||
return _boardDataController.rowInfos;
|
||||
}
|
||||
|
||||
UnmodifiableMapView<String, GridBlockCache> get blocks {
|
||||
return _boardDataController.blocks;
|
||||
}
|
||||
|
||||
List<FieldInfo> get fieldContexts => fieldController.fieldInfos;
|
||||
|
||||
GridFieldController get fieldController {
|
||||
@ -113,15 +106,13 @@ class BoardTestContext {
|
||||
String fieldId,
|
||||
) async {
|
||||
final RowInfo rowInfo = rowInfos.last;
|
||||
final blockCache = blocks[rowInfo.rowPB.blockId];
|
||||
final rowCache = blockCache?.rowCache;
|
||||
|
||||
final rowCache = _boardDataController.rowCache;
|
||||
final fieldController = _boardDataController.fieldController;
|
||||
|
||||
final rowDataController = GridRowDataController(
|
||||
rowInfo: rowInfo,
|
||||
fieldController: fieldController,
|
||||
rowCache: rowCache!,
|
||||
rowCache: rowCache,
|
||||
);
|
||||
|
||||
final rowBloc = RowBloc(
|
||||
|
@ -1,5 +1,3 @@
|
||||
import 'dart:collection';
|
||||
import 'package:app_flowy/plugins/grid/application/block/block_cache.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_editor_bloc.dart';
|
||||
@ -26,10 +24,6 @@ class GridTestContext {
|
||||
return gridController.rowInfos;
|
||||
}
|
||||
|
||||
UnmodifiableMapView<String, GridBlockCache> get blocks {
|
||||
return gridController.blocks;
|
||||
}
|
||||
|
||||
List<FieldInfo> get fieldContexts => fieldController.fieldInfos;
|
||||
|
||||
GridFieldController get fieldController {
|
||||
@ -71,14 +65,13 @@ class GridTestContext {
|
||||
int rowIndex,
|
||||
) async {
|
||||
final RowInfo rowInfo = rowInfos[rowIndex];
|
||||
final blockCache = blocks[rowInfo.rowPB.blockId];
|
||||
final rowCache = blockCache?.rowCache;
|
||||
final rowCache = gridController.rowCache;
|
||||
final fieldController = gridController.fieldController;
|
||||
|
||||
final rowDataController = GridRowDataController(
|
||||
rowInfo: rowInfo,
|
||||
fieldController: fieldController,
|
||||
rowCache: rowCache!,
|
||||
rowCache: rowCache,
|
||||
);
|
||||
|
||||
final rowBloc = RowBloc(
|
||||
|
@ -6,7 +6,6 @@ const OBSERVABLE_CATEGORY: &str = "Grid";
|
||||
pub enum GridDartNotification {
|
||||
Unknown = 0,
|
||||
DidCreateBlock = 11,
|
||||
DidUpdateGridRows = 19,
|
||||
DidUpdateGridViewRows = 20,
|
||||
DidUpdateGridViewRowsVisibility = 21,
|
||||
DidUpdateGridFields = 22,
|
||||
|
@ -1,245 +0,0 @@
|
||||
use crate::entities::parser::NotEmptyStr;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::ErrorCode;
|
||||
use grid_rev_model::RowRevision;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// [BlockPB] contains list of row ids. The rows here does not contain any data, just the id
|
||||
/// of the row. Check out [RowPB] for more details.
|
||||
///
|
||||
///
|
||||
/// A grid can have many rows. Rows are therefore grouped into Blocks in order to make
|
||||
/// things more efficient.
|
||||
/// |
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct BlockPB {
|
||||
#[pb(index = 1)]
|
||||
pub id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub rows: Vec<RowPB>,
|
||||
}
|
||||
|
||||
impl BlockPB {
|
||||
pub fn new(block_id: &str, rows: Vec<RowPB>) -> Self {
|
||||
Self {
|
||||
id: block_id.to_owned(),
|
||||
rows,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// [RowPB] Describes a row. Has the id of the parent Block. Has the metadata of the row.
|
||||
#[derive(Debug, Default, Clone, ProtoBuf, Eq, PartialEq)]
|
||||
pub struct RowPB {
|
||||
#[pb(index = 1)]
|
||||
pub block_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub id: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub height: i32,
|
||||
}
|
||||
|
||||
impl RowPB {
|
||||
pub fn row_id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
|
||||
pub fn block_id(&self) -> &str {
|
||||
&self.block_id
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&RowRevision> for RowPB {
|
||||
fn from(rev: &RowRevision) -> Self {
|
||||
Self {
|
||||
block_id: rev.block_id.clone(),
|
||||
id: rev.id.clone(),
|
||||
height: rev.height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&mut RowRevision> for RowPB {
|
||||
fn from(rev: &mut RowRevision) -> Self {
|
||||
Self {
|
||||
block_id: rev.block_id.clone(),
|
||||
id: rev.id.clone(),
|
||||
height: rev.height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&Arc<RowRevision>> for RowPB {
|
||||
fn from(rev: &Arc<RowRevision>) -> Self {
|
||||
Self {
|
||||
block_id: rev.block_id.clone(),
|
||||
id: rev.id.clone(),
|
||||
height: rev.height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct OptionalRowPB {
|
||||
#[pb(index = 1, one_of)]
|
||||
pub row: Option<RowPB>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct RepeatedRowPB {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<RowPB>,
|
||||
}
|
||||
|
||||
impl std::convert::From<Vec<RowPB>> for RepeatedRowPB {
|
||||
fn from(items: Vec<RowPB>) -> Self {
|
||||
Self { items }
|
||||
}
|
||||
}
|
||||
|
||||
/// [RepeatedBlockPB] contains list of [BlockPB]
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct RepeatedBlockPB {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<BlockPB>,
|
||||
}
|
||||
|
||||
impl std::convert::From<Vec<BlockPB>> for RepeatedBlockPB {
|
||||
fn from(items: Vec<BlockPB>) -> Self {
|
||||
Self { items }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct InsertedRowPB {
|
||||
#[pb(index = 1)]
|
||||
pub row: RowPB,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub index: Option<i32>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub is_new: bool,
|
||||
}
|
||||
|
||||
impl InsertedRowPB {
|
||||
pub fn new(row: RowPB) -> Self {
|
||||
Self {
|
||||
row,
|
||||
index: None,
|
||||
is_new: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_index(row: RowPB, index: i32) -> Self {
|
||||
Self {
|
||||
row,
|
||||
index: Some(index),
|
||||
is_new: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<RowPB> for InsertedRowPB {
|
||||
fn from(row: RowPB) -> Self {
|
||||
Self {
|
||||
row,
|
||||
index: None,
|
||||
is_new: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&RowRevision> for InsertedRowPB {
|
||||
fn from(row: &RowRevision) -> Self {
|
||||
let row_order = RowPB::from(row);
|
||||
Self::from(row_order)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct UpdatedRowPB {
|
||||
#[pb(index = 1)]
|
||||
pub row: RowPB,
|
||||
|
||||
// represents as the cells that were updated in this row.
|
||||
#[pb(index = 2)]
|
||||
pub field_ids: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, ProtoBuf)]
|
||||
pub struct GridBlockChangesetPB {
|
||||
#[pb(index = 1)]
|
||||
pub view_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub inserted_rows: Vec<InsertedRowPB>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub deleted_rows: Vec<String>,
|
||||
|
||||
#[pb(index = 4)]
|
||||
pub updated_rows: Vec<UpdatedRowPB>,
|
||||
|
||||
#[pb(index = 5)]
|
||||
pub visible_rows: Vec<InsertedRowPB>,
|
||||
|
||||
#[pb(index = 6)]
|
||||
pub invisible_rows: Vec<String>,
|
||||
}
|
||||
impl GridBlockChangesetPB {
|
||||
pub fn insert(view_id: String, inserted_rows: Vec<InsertedRowPB>) -> Self {
|
||||
Self {
|
||||
view_id,
|
||||
inserted_rows,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delete(block_id: &str, deleted_rows: Vec<String>) -> Self {
|
||||
Self {
|
||||
view_id: block_id.to_owned(),
|
||||
deleted_rows,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(block_id: &str, updated_rows: Vec<UpdatedRowPB>) -> Self {
|
||||
Self {
|
||||
view_id: block_id.to_owned(),
|
||||
updated_rows,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// [QueryBlocksPayloadPB] is used to query the data of the block that belongs to the grid whose
|
||||
/// id is grid_id.
|
||||
#[derive(ProtoBuf, Default)]
|
||||
pub struct QueryBlocksPayloadPB {
|
||||
#[pb(index = 1)]
|
||||
pub grid_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub block_ids: Vec<String>,
|
||||
}
|
||||
|
||||
pub struct QueryGridBlocksParams {
|
||||
pub grid_id: String,
|
||||
pub block_ids: Vec<String>,
|
||||
}
|
||||
|
||||
impl TryInto<QueryGridBlocksParams> for QueryBlocksPayloadPB {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<QueryGridBlocksParams, Self::Error> {
|
||||
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
|
||||
Ok(QueryGridBlocksParams {
|
||||
grid_id: grid_id.0,
|
||||
block_ids: self.block_ids,
|
||||
})
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
use crate::entities::parser::NotEmptyStr;
|
||||
use crate::entities::{BlockPB, FieldIdPB};
|
||||
use crate::entities::{FieldIdPB, RowPB};
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::ErrorCode;
|
||||
|
||||
@ -13,7 +13,7 @@ pub struct GridPB {
|
||||
pub fields: Vec<FieldIdPB>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub blocks: Vec<BlockPB>,
|
||||
pub rows: Vec<RowPB>,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default)]
|
||||
|
@ -1,4 +1,3 @@
|
||||
pub mod block_entities;
|
||||
mod cell_entities;
|
||||
mod field_entities;
|
||||
pub mod filter_entities;
|
||||
@ -9,7 +8,6 @@ mod row_entities;
|
||||
pub mod setting_entities;
|
||||
mod view_entities;
|
||||
|
||||
pub use block_entities::*;
|
||||
pub use cell_entities::*;
|
||||
pub use field_entities::*;
|
||||
pub use filter_entities::*;
|
||||
|
@ -2,6 +2,136 @@ use crate::entities::parser::NotEmptyStr;
|
||||
use crate::entities::GridLayout;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::ErrorCode;
|
||||
use grid_rev_model::RowRevision;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// [RowPB] Describes a row. Has the id of the parent Block. Has the metadata of the row.
|
||||
#[derive(Debug, Default, Clone, ProtoBuf, Eq, PartialEq)]
|
||||
pub struct RowPB {
|
||||
#[pb(index = 1)]
|
||||
pub block_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub id: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub height: i32,
|
||||
}
|
||||
|
||||
impl RowPB {
|
||||
pub fn row_id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
|
||||
pub fn block_id(&self) -> &str {
|
||||
&self.block_id
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&RowRevision> for RowPB {
|
||||
fn from(rev: &RowRevision) -> Self {
|
||||
Self {
|
||||
block_id: rev.block_id.clone(),
|
||||
id: rev.id.clone(),
|
||||
height: rev.height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&mut RowRevision> for RowPB {
|
||||
fn from(rev: &mut RowRevision) -> Self {
|
||||
Self {
|
||||
block_id: rev.block_id.clone(),
|
||||
id: rev.id.clone(),
|
||||
height: rev.height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&Arc<RowRevision>> for RowPB {
|
||||
fn from(rev: &Arc<RowRevision>) -> Self {
|
||||
Self {
|
||||
block_id: rev.block_id.clone(),
|
||||
id: rev.id.clone(),
|
||||
height: rev.height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct OptionalRowPB {
|
||||
#[pb(index = 1, one_of)]
|
||||
pub row: Option<RowPB>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct RepeatedRowPB {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<RowPB>,
|
||||
}
|
||||
|
||||
impl std::convert::From<Vec<RowPB>> for RepeatedRowPB {
|
||||
fn from(items: Vec<RowPB>) -> Self {
|
||||
Self { items }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct InsertedRowPB {
|
||||
#[pb(index = 1)]
|
||||
pub row: RowPB,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub index: Option<i32>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub is_new: bool,
|
||||
}
|
||||
|
||||
impl InsertedRowPB {
|
||||
pub fn new(row: RowPB) -> Self {
|
||||
Self {
|
||||
row,
|
||||
index: None,
|
||||
is_new: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_index(row: RowPB, index: i32) -> Self {
|
||||
Self {
|
||||
row,
|
||||
index: Some(index),
|
||||
is_new: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<RowPB> for InsertedRowPB {
|
||||
fn from(row: RowPB) -> Self {
|
||||
Self {
|
||||
row,
|
||||
index: None,
|
||||
is_new: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&RowRevision> for InsertedRowPB {
|
||||
fn from(row: &RowRevision) -> Self {
|
||||
let row_order = RowPB::from(row);
|
||||
Self::from(row_order)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct UpdatedRowPB {
|
||||
#[pb(index = 1)]
|
||||
pub row: RowPB,
|
||||
|
||||
// represents as the cells that were updated in this row.
|
||||
#[pb(index = 2)]
|
||||
pub field_ids: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, ProtoBuf)]
|
||||
pub struct RowIdPB {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::entities::{GridLayout, InsertedRowPB, UpdatedRowPB};
|
||||
use crate::entities::{InsertedRowPB, UpdatedRowPB};
|
||||
use flowy_derive::ProtoBuf;
|
||||
|
||||
#[derive(Debug, Default, Clone, ProtoBuf)]
|
||||
@ -29,7 +29,7 @@ pub struct GridViewRowsChangesetPB {
|
||||
}
|
||||
|
||||
impl GridViewRowsChangesetPB {
|
||||
pub fn insert(view_id: String, inserted_rows: Vec<InsertedRowPB>) -> Self {
|
||||
pub fn from_insert(view_id: String, inserted_rows: Vec<InsertedRowPB>) -> Self {
|
||||
Self {
|
||||
view_id,
|
||||
inserted_rows,
|
||||
@ -37,19 +37,28 @@ impl GridViewRowsChangesetPB {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delete(block_id: &str, deleted_rows: Vec<String>) -> Self {
|
||||
pub fn from_delete(view_id: String, deleted_rows: Vec<String>) -> Self {
|
||||
Self {
|
||||
view_id: block_id.to_owned(),
|
||||
view_id,
|
||||
deleted_rows,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(block_id: &str, updated_rows: Vec<UpdatedRowPB>) -> Self {
|
||||
pub fn from_update(view_id: String, updated_rows: Vec<UpdatedRowPB>) -> Self {
|
||||
Self {
|
||||
view_id: block_id.to_owned(),
|
||||
view_id,
|
||||
updated_rows,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_move(view_id: String, deleted_rows: Vec<String>, inserted_rows: Vec<InsertedRowPB>) -> Self {
|
||||
Self {
|
||||
view_id,
|
||||
inserted_rows,
|
||||
deleted_rows,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use crate::services::field::{
|
||||
SelectOptionCellChangesetParams, SelectOptionCellDataPB, SelectOptionChangeset, SelectOptionChangesetPB,
|
||||
SelectOptionPB,
|
||||
};
|
||||
use crate::services::row::{make_block_pbs, make_row_from_row_rev};
|
||||
use crate::services::row::make_row_from_row_rev;
|
||||
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
||||
use grid_rev_model::FieldRevision;
|
||||
use lib_dispatch::prelude::{data_result, AFPluginData, AFPluginState, DataResult};
|
||||
@ -74,17 +74,6 @@ pub(crate) async fn get_all_filters_handler(
|
||||
data_result(filters)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||
pub(crate) async fn get_grid_blocks_handler(
|
||||
data: AFPluginData<QueryBlocksPayloadPB>,
|
||||
manager: AFPluginState<Arc<GridManager>>,
|
||||
) -> DataResult<RepeatedBlockPB, FlowyError> {
|
||||
let params: QueryGridBlocksParams = data.into_inner().try_into()?;
|
||||
let editor = manager.get_grid_editor(¶ms.grid_id).await?;
|
||||
let blocks = editor.get_blocks(Some(params.block_ids)).await?;
|
||||
data_result(make_block_pbs(blocks))
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "trace", skip(data, manager), err)]
|
||||
pub(crate) async fn get_fields_handler(
|
||||
data: AFPluginData<GetFieldPayloadPB>,
|
||||
|
@ -9,7 +9,7 @@ pub fn init(grid_manager: Arc<GridManager>) -> AFPlugin {
|
||||
let mut plugin = AFPlugin::new().name(env!("CARGO_PKG_NAME")).state(grid_manager);
|
||||
plugin = plugin
|
||||
.event(GridEvent::GetGrid, get_grid_handler)
|
||||
.event(GridEvent::GetGridBlocks, get_grid_blocks_handler)
|
||||
// .event(GridEvent::GetGridBlocks, get_grid_blocks_handler)
|
||||
.event(GridEvent::GetGridSetting, get_grid_setting_handler)
|
||||
.event(GridEvent::UpdateGridSetting, update_grid_setting_handler)
|
||||
.event(GridEvent::GetAllFilters, get_all_filters_handler)
|
||||
@ -59,13 +59,6 @@ pub enum GridEvent {
|
||||
#[event(input = "GridIdPB", output = "GridPB")]
|
||||
GetGrid = 0,
|
||||
|
||||
/// [GetGridBlocks] event is used to get the grid's block.
|
||||
///
|
||||
/// The event handler accepts a [QueryBlocksPayloadPB] and returns a [RepeatedBlockPB]
|
||||
/// if there are no errors.
|
||||
#[event(input = "QueryBlocksPayloadPB", output = "RepeatedBlockPB")]
|
||||
GetGridBlocks = 1,
|
||||
|
||||
/// [GetGridSetting] event is used to get the grid's settings.
|
||||
///
|
||||
/// The event handler accepts [GridIdPB] and return [GridSettingPB]
|
||||
|
@ -113,6 +113,10 @@ impl GridBlockRevisionEditor {
|
||||
self.pad.read().await.index_of_row(row_id)
|
||||
}
|
||||
|
||||
pub async fn number_of_rows(&self) -> i32 {
|
||||
self.pad.read().await.rows.len() as i32
|
||||
}
|
||||
|
||||
pub async fn get_row_rev(&self, row_id: &str) -> FlowyResult<Option<(usize, Arc<RowRevision>)>> {
|
||||
let row_rev = self.pad.read().await.get_row_rev(row_id);
|
||||
Ok(row_rev)
|
||||
|
@ -1,12 +1,12 @@
|
||||
use crate::dart_notification::{send_dart_notification, GridDartNotification};
|
||||
use crate::entities::{CellChangesetPB, GridBlockChangesetPB, InsertedRowPB, RowPB, UpdatedRowPB};
|
||||
use crate::entities::{CellChangesetPB, InsertedRowPB, UpdatedRowPB};
|
||||
use crate::manager::GridUser;
|
||||
use crate::services::block_editor::{GridBlockRevisionEditor, GridBlockRevisionMergeable};
|
||||
use crate::services::persistence::block_index::BlockIndexCache;
|
||||
use crate::services::persistence::rev_sqlite::{
|
||||
SQLiteGridBlockRevisionPersistence, SQLiteGridRevisionSnapshotPersistence,
|
||||
};
|
||||
use crate::services::row::{block_from_row_orders, make_row_from_row_rev, GridBlock};
|
||||
use crate::services::row::{make_row_from_row_rev, GridBlockRow, GridBlockRowRevision};
|
||||
use dashmap::DashMap;
|
||||
use flowy_database::ConnectionPool;
|
||||
use flowy_error::FlowyResult;
|
||||
@ -14,20 +14,28 @@ use flowy_revision::{RevisionManager, RevisionPersistence, RevisionPersistenceCo
|
||||
use grid_rev_model::{GridBlockMetaRevision, GridBlockMetaRevisionChangeset, RowChangeset, RowRevision};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Weak};
|
||||
use tokio::sync::{broadcast, RwLock};
|
||||
|
||||
pub trait GridBlockDelegate: Send + Sync + 'static {
|
||||
fn notify_did_insert_row(&self, row: InsertedRowPB);
|
||||
fn notify_did_update_row(&self, row: UpdatedRowPB);
|
||||
fn notify_did_delete_row(&self, row_id: String);
|
||||
}
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::broadcast;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum GridBlockEvent {
|
||||
DidInsertRow { row: InsertedRowPB },
|
||||
UpdateRow { row: UpdatedRowPB },
|
||||
DeleteRow { row_id: String },
|
||||
InsertRow {
|
||||
block_id: String,
|
||||
row: InsertedRowPB,
|
||||
},
|
||||
UpdateRow {
|
||||
block_id: String,
|
||||
row: UpdatedRowPB,
|
||||
},
|
||||
DeleteRow {
|
||||
block_id: String,
|
||||
row_id: String,
|
||||
},
|
||||
Move {
|
||||
block_id: String,
|
||||
deleted_row_id: String,
|
||||
inserted_row: InsertedRowPB,
|
||||
},
|
||||
}
|
||||
|
||||
type BlockId = String;
|
||||
@ -35,7 +43,7 @@ pub(crate) struct GridBlockManager {
|
||||
user: Arc<dyn GridUser>,
|
||||
persistence: Arc<BlockIndexCache>,
|
||||
block_editors: DashMap<BlockId, Arc<GridBlockRevisionEditor>>,
|
||||
notifier: broadcast::Sender<GridBlockEvent>,
|
||||
event_notifier: broadcast::Sender<GridBlockEvent>,
|
||||
}
|
||||
|
||||
impl GridBlockManager {
|
||||
@ -43,7 +51,7 @@ impl GridBlockManager {
|
||||
user: &Arc<dyn GridUser>,
|
||||
block_meta_revs: Vec<Arc<GridBlockMetaRevision>>,
|
||||
persistence: Arc<BlockIndexCache>,
|
||||
block_event_tx: broadcast::Sender<GridBlockEvent>,
|
||||
event_notifier: broadcast::Sender<GridBlockEvent>,
|
||||
) -> FlowyResult<Self> {
|
||||
let block_editors = make_block_editors(user, block_meta_revs).await?;
|
||||
let user = user.clone();
|
||||
@ -51,7 +59,7 @@ impl GridBlockManager {
|
||||
user,
|
||||
block_editors,
|
||||
persistence,
|
||||
notifier: block_event_tx,
|
||||
event_notifier,
|
||||
};
|
||||
Ok(manager)
|
||||
}
|
||||
@ -87,12 +95,12 @@ impl GridBlockManager {
|
||||
let _ = self.persistence.insert(&row_rev.block_id, &row_rev.id)?;
|
||||
let editor = self.get_block_editor(&row_rev.block_id).await?;
|
||||
|
||||
let mut index_row_order = InsertedRowPB::from(&row_rev);
|
||||
let (row_count, row_index) = editor.create_row(row_rev, start_row_id).await?;
|
||||
index_row_order.index = row_index;
|
||||
let changeset = GridBlockChangesetPB::insert(block_id.clone(), vec![index_row_order]);
|
||||
let _ = self.notify_did_update_block(&block_id, changeset).await?;
|
||||
Ok(row_count)
|
||||
let mut row = InsertedRowPB::from(&row_rev);
|
||||
let (number_of_rows, index) = editor.create_row(row_rev, start_row_id).await?;
|
||||
row.index = index;
|
||||
|
||||
let _ = self.event_notifier.send(GridBlockEvent::InsertRow { block_id, row });
|
||||
Ok(number_of_rows)
|
||||
}
|
||||
|
||||
pub(crate) async fn insert_row(
|
||||
@ -101,28 +109,20 @@ impl GridBlockManager {
|
||||
) -> FlowyResult<Vec<GridBlockMetaRevisionChangeset>> {
|
||||
let mut changesets = vec![];
|
||||
for (block_id, row_revs) in rows_by_block_id {
|
||||
let mut inserted_row_orders = vec![];
|
||||
let editor = self.get_block_editor(&block_id).await?;
|
||||
let mut row_count = 0;
|
||||
for row in row_revs {
|
||||
let _ = self.persistence.insert(&row.block_id, &row.id)?;
|
||||
let mut row_order = InsertedRowPB::from(&row);
|
||||
let (count, index) = editor.create_row(row, None).await?;
|
||||
row_count = count;
|
||||
row_order.index = index;
|
||||
inserted_row_orders.push(row_order);
|
||||
for row_rev in row_revs {
|
||||
let _ = self.persistence.insert(&row_rev.block_id, &row_rev.id)?;
|
||||
let mut row = InsertedRowPB::from(&row_rev);
|
||||
row.index = editor.create_row(row_rev, None).await?.1;
|
||||
let _ = self.event_notifier.send(GridBlockEvent::InsertRow {
|
||||
block_id: block_id.clone(),
|
||||
row,
|
||||
});
|
||||
}
|
||||
changesets.push(GridBlockMetaRevisionChangeset::from_row_count(
|
||||
block_id.clone(),
|
||||
row_count,
|
||||
editor.number_of_rows().await,
|
||||
));
|
||||
|
||||
let _ = self
|
||||
.notify_did_update_block(
|
||||
&block_id,
|
||||
GridBlockChangesetPB::insert(block_id.clone(), inserted_row_orders),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(changesets)
|
||||
@ -135,14 +135,15 @@ impl GridBlockManager {
|
||||
None => tracing::error!("Update row failed, can't find the row with id: {}", changeset.row_id),
|
||||
Some((_, row_rev)) => {
|
||||
let changed_field_ids = changeset.cell_by_field_id.keys().cloned().collect::<Vec<String>>();
|
||||
let updated_row = UpdatedRowPB {
|
||||
let row = UpdatedRowPB {
|
||||
row: make_row_from_row_rev(row_rev),
|
||||
field_ids: changed_field_ids,
|
||||
};
|
||||
let block_order_changeset = GridBlockChangesetPB::update(&editor.block_id, vec![updated_row]);
|
||||
let _ = self
|
||||
.notify_did_update_block(&editor.block_id, block_order_changeset)
|
||||
.await?;
|
||||
|
||||
let _ = self.event_notifier.send(GridBlockEvent::UpdateRow {
|
||||
block_id: editor.block_id.clone(),
|
||||
row,
|
||||
});
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@ -157,28 +158,30 @@ impl GridBlockManager {
|
||||
None => Ok(None),
|
||||
Some((_, row_rev)) => {
|
||||
let _ = editor.delete_rows(vec![Cow::Borrowed(&row_id)]).await?;
|
||||
let _ = self
|
||||
.notify_did_update_block(
|
||||
&block_id,
|
||||
GridBlockChangesetPB::delete(&block_id, vec![row_rev.id.clone()]),
|
||||
)
|
||||
.await?;
|
||||
let _ = self.event_notifier.send(GridBlockEvent::DeleteRow {
|
||||
block_id: editor.block_id.clone(),
|
||||
row_id: row_rev.id.clone(),
|
||||
});
|
||||
|
||||
Ok(Some(row_rev))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn delete_rows(&self, row_orders: Vec<RowPB>) -> FlowyResult<Vec<GridBlockMetaRevisionChangeset>> {
|
||||
pub(crate) async fn delete_rows(
|
||||
&self,
|
||||
block_rows: Vec<GridBlockRow>,
|
||||
) -> FlowyResult<Vec<GridBlockMetaRevisionChangeset>> {
|
||||
let mut changesets = vec![];
|
||||
for grid_block in block_from_row_orders(row_orders) {
|
||||
let editor = self.get_block_editor(&grid_block.id).await?;
|
||||
let row_ids = grid_block
|
||||
.rows
|
||||
for block_row in block_rows {
|
||||
let editor = self.get_block_editor(&block_row.block_id).await?;
|
||||
let row_ids = block_row
|
||||
.row_ids
|
||||
.into_iter()
|
||||
.map(|row_info| Cow::Owned(row_info.row_id().to_owned()))
|
||||
.map(Cow::Owned)
|
||||
.collect::<Vec<Cow<String>>>();
|
||||
let row_count = editor.delete_rows(row_ids).await?;
|
||||
let changeset = GridBlockMetaRevisionChangeset::from_row_count(grid_block.id.clone(), row_count);
|
||||
let changeset = GridBlockMetaRevisionChangeset::from_row_count(block_row.block_id, row_count);
|
||||
changesets.push(changeset);
|
||||
}
|
||||
|
||||
@ -196,16 +199,11 @@ impl GridBlockManager {
|
||||
is_new: false,
|
||||
};
|
||||
|
||||
let notified_changeset = GridBlockChangesetPB {
|
||||
view_id: editor.block_id.clone(),
|
||||
inserted_rows: vec![insert_row],
|
||||
deleted_rows: vec![delete_row_id],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let _ = self
|
||||
.notify_did_update_block(&editor.block_id, notified_changeset)
|
||||
.await?;
|
||||
let _ = self.event_notifier.send(GridBlockEvent::Move {
|
||||
block_id: editor.block_id.clone(),
|
||||
deleted_row_id: delete_row_id,
|
||||
inserted_row: insert_row,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -235,7 +233,7 @@ impl GridBlockManager {
|
||||
editor.get_row_revs::<&str>(None).await
|
||||
}
|
||||
|
||||
pub(crate) async fn get_blocks(&self, block_ids: Option<Vec<String>>) -> FlowyResult<Vec<GridBlock>> {
|
||||
pub(crate) async fn get_blocks(&self, block_ids: Option<Vec<String>>) -> FlowyResult<Vec<GridBlockRowRevision>> {
|
||||
let mut blocks = vec![];
|
||||
match block_ids {
|
||||
None => {
|
||||
@ -243,27 +241,20 @@ impl GridBlockManager {
|
||||
let editor = iter.value();
|
||||
let block_id = editor.block_id.clone();
|
||||
let row_revs = editor.get_row_revs::<&str>(None).await?;
|
||||
blocks.push(GridBlock { block_id, row_revs });
|
||||
blocks.push(GridBlockRowRevision { block_id, row_revs });
|
||||
}
|
||||
}
|
||||
Some(block_ids) => {
|
||||
for block_id in block_ids {
|
||||
let editor = self.get_block_editor(&block_id).await?;
|
||||
let row_revs = editor.get_row_revs::<&str>(None).await?;
|
||||
blocks.push(GridBlock { block_id, row_revs });
|
||||
blocks.push(GridBlockRowRevision { block_id, row_revs });
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(blocks)
|
||||
}
|
||||
|
||||
async fn notify_did_update_block(&self, block_id: &str, changeset: GridBlockChangesetPB) -> FlowyResult<()> {
|
||||
send_dart_notification(block_id, GridDartNotification::DidUpdateGridRows)
|
||||
.payload(changeset)
|
||||
.send();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn notify_did_update_cell(&self, changeset: CellChangesetPB) -> FlowyResult<()> {
|
||||
let id = format!("{}:{}", changeset.row_id, changeset.field_id);
|
||||
send_dart_notification(&id, GridDartNotification::DidUpdateCell).send();
|
||||
|
@ -3,7 +3,7 @@ use crate::entities::{FieldType, InsertedRowPB, RowPB};
|
||||
use crate::services::cell::{CellFilterOperation, TypeCellData};
|
||||
use crate::services::field::*;
|
||||
use crate::services::filter::{FilterChangeset, FilterMap, FilterResult, FilterResultNotification, FilterType};
|
||||
use crate::services::row::GridBlock;
|
||||
use crate::services::row::GridBlockRowRevision;
|
||||
use crate::services::view_editor::{GridViewChanged, GridViewChangedNotifier};
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_task::{QualityOfService, Task, TaskContent, TaskDispatcher};
|
||||
@ -20,7 +20,7 @@ pub trait FilterDelegate: Send + Sync + 'static {
|
||||
fn get_filter_rev(&self, filter_type: FilterType) -> Fut<Option<Arc<FilterRevision>>>;
|
||||
fn get_field_rev(&self, field_id: &str) -> Fut<Option<Arc<FieldRevision>>>;
|
||||
fn get_field_revs(&self, field_ids: Option<Vec<String>>) -> Fut<Vec<Arc<FieldRevision>>>;
|
||||
fn get_blocks(&self) -> Fut<Vec<GridBlock>>;
|
||||
fn get_blocks(&self) -> Fut<Vec<GridBlockRowRevision>>;
|
||||
fn get_row_rev(&self, rows_id: &str) -> Fut<Option<(usize, Arc<RowRevision>)>>;
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ use crate::services::field::{
|
||||
use crate::services::filter::FilterType;
|
||||
use crate::services::grid_editor_trait_impl::GridViewEditorDelegateImpl;
|
||||
use crate::services::persistence::block_index::BlockIndexCache;
|
||||
use crate::services::row::{GridBlock, RowRevisionBuilder};
|
||||
use crate::services::row::{GridBlockRow, GridBlockRowRevision, RowRevisionBuilder};
|
||||
use crate::services::view_editor::{GridViewChanged, GridViewManager};
|
||||
use bytes::Bytes;
|
||||
use flowy_database::ConnectionPool;
|
||||
@ -511,7 +511,7 @@ impl GridRevisionEditor {
|
||||
Ok(block_meta_revs)
|
||||
}
|
||||
|
||||
pub async fn get_blocks(&self, block_ids: Option<Vec<String>>) -> FlowyResult<Vec<GridBlock>> {
|
||||
pub async fn get_blocks(&self, block_ids: Option<Vec<String>>) -> FlowyResult<Vec<GridBlockRowRevision>> {
|
||||
let block_ids = match block_ids {
|
||||
None => self
|
||||
.grid_pad
|
||||
@ -527,8 +527,8 @@ impl GridRevisionEditor {
|
||||
Ok(blocks)
|
||||
}
|
||||
|
||||
pub async fn delete_rows(&self, row_orders: Vec<RowPB>) -> FlowyResult<()> {
|
||||
let changesets = self.block_manager.delete_rows(row_orders).await?;
|
||||
pub async fn delete_rows(&self, block_rows: Vec<GridBlockRow>) -> FlowyResult<()> {
|
||||
let changesets = self.block_manager.delete_rows(block_rows).await?;
|
||||
for changeset in changesets {
|
||||
let _ = self.update_block(changeset).await?;
|
||||
}
|
||||
@ -538,21 +538,17 @@ impl GridRevisionEditor {
|
||||
pub async fn get_grid(&self) -> FlowyResult<GridPB> {
|
||||
let pad = self.grid_pad.read().await;
|
||||
let fields = pad.get_field_revs(None)?.iter().map(FieldIdPB::from).collect();
|
||||
|
||||
let mut blocks = vec![];
|
||||
let mut all_rows = vec![];
|
||||
for block_rev in pad.get_block_meta_revs() {
|
||||
let rows = self.get_row_pbs(&block_rev.block_id).await?;
|
||||
let block = BlockPB {
|
||||
id: block_rev.block_id.clone(),
|
||||
rows,
|
||||
};
|
||||
blocks.push(block);
|
||||
if let Ok(rows) = self.get_row_pbs(&block_rev.block_id).await {
|
||||
all_rows.extend(rows);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(GridPB {
|
||||
id: self.grid_id.clone(),
|
||||
fields,
|
||||
blocks,
|
||||
rows: all_rows,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::services::block_manager::GridBlockManager;
|
||||
use crate::services::row::GridBlock;
|
||||
use crate::services::row::GridBlockRowRevision;
|
||||
use crate::services::view_editor::GridViewEditorDelegate;
|
||||
use flowy_sync::client_grid::GridRevisionPad;
|
||||
use flowy_task::TaskDispatcher;
|
||||
@ -63,7 +63,7 @@ impl GridViewEditorDelegate for GridViewEditorDelegateImpl {
|
||||
})
|
||||
}
|
||||
|
||||
fn get_blocks(&self) -> Fut<Vec<GridBlock>> {
|
||||
fn get_blocks(&self) -> Fut<Vec<GridBlockRowRevision>> {
|
||||
let block_manager = self.block_manager.clone();
|
||||
to_fut(async move { block_manager.get_blocks(None).await.unwrap_or_default() })
|
||||
}
|
||||
|
@ -2,4 +2,4 @@ mod row_builder;
|
||||
mod row_loader;
|
||||
|
||||
pub use row_builder::*;
|
||||
pub(crate) use row_loader::*;
|
||||
pub use row_loader::*;
|
||||
|
@ -1,42 +1,22 @@
|
||||
use crate::entities::{BlockPB, RepeatedBlockPB, RowPB};
|
||||
|
||||
use crate::entities::RowPB;
|
||||
use grid_rev_model::RowRevision;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct GridBlock {
|
||||
pub struct GridBlockRowRevision {
|
||||
pub(crate) block_id: String,
|
||||
pub row_revs: Vec<Arc<RowRevision>>,
|
||||
}
|
||||
|
||||
pub(crate) fn block_from_row_orders(row_orders: Vec<RowPB>) -> Vec<BlockPB> {
|
||||
let mut map: HashMap<String, BlockPB> = HashMap::new();
|
||||
row_orders.into_iter().for_each(|row_info| {
|
||||
// Memory Optimization: escape clone block_id
|
||||
let block_id = row_info.block_id().to_owned();
|
||||
let cloned_block_id = block_id.clone();
|
||||
map.entry(block_id)
|
||||
.or_insert_with(|| BlockPB::new(&cloned_block_id, vec![]))
|
||||
.rows
|
||||
.push(row_info);
|
||||
});
|
||||
map.into_values().collect::<Vec<_>>()
|
||||
pub struct GridBlockRow {
|
||||
pub block_id: String,
|
||||
pub row_ids: Vec<String>,
|
||||
}
|
||||
//
|
||||
// #[inline(always)]
|
||||
// fn make_cell_by_field_id(
|
||||
// field_map: &HashMap<&String, &FieldRevision>,
|
||||
// field_id: String,
|
||||
// cell_rev: CellRevision,
|
||||
// ) -> Option<(String, Cell)> {
|
||||
// let field_rev = field_map.get(&field_id)?;
|
||||
// let data = decode_cell_data(cell_rev.data, field_rev).data;
|
||||
// let cell = Cell::new(&field_id, data);
|
||||
// Some((field_id, cell))
|
||||
// }
|
||||
|
||||
pub(crate) fn make_row_pb_from_row_rev(row_revs: &[Arc<RowRevision>]) -> Vec<RowPB> {
|
||||
row_revs.iter().map(RowPB::from).collect::<Vec<_>>()
|
||||
impl GridBlockRow {
|
||||
pub fn new(block_id: String, row_ids: Vec<String>) -> Self {
|
||||
Self { block_id, row_ids }
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn make_row_from_row_rev(row_rev: Arc<RowRevision>) -> RowPB {
|
||||
@ -52,14 +32,3 @@ pub(crate) fn make_rows_from_row_revs(row_revs: &[Arc<RowRevision>]) -> Vec<RowP
|
||||
|
||||
row_revs.iter().map(make_row).collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub(crate) fn make_block_pbs(blocks: Vec<GridBlock>) -> RepeatedBlockPB {
|
||||
blocks
|
||||
.into_iter()
|
||||
.map(|block| {
|
||||
let row_pbs = make_row_pb_from_row_rev(&block.row_revs);
|
||||
BlockPB::new(&block.block_id, row_pbs)
|
||||
})
|
||||
.collect::<Vec<BlockPB>>()
|
||||
.into()
|
||||
}
|
||||
|
@ -1,6 +1,3 @@
|
||||
use crate::services::block_manager::GridBlockManager;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct SortController {}
|
||||
impl SortController {
|
||||
pub fn new() -> Self {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::dart_notification::{send_dart_notification, GridDartNotification};
|
||||
use crate::entities::{GridBlockChangesetPB, GridRowsVisibilityChangesetPB};
|
||||
use crate::entities::GridRowsVisibilityChangesetPB;
|
||||
use crate::services::filter::FilterResultNotification;
|
||||
use async_stream::stream;
|
||||
use futures::stream::StreamExt;
|
||||
|
@ -1,11 +1,12 @@
|
||||
use crate::dart_notification::{send_dart_notification, GridDartNotification};
|
||||
use crate::entities::*;
|
||||
use crate::services::block_manager::GridBlockEvent;
|
||||
use crate::services::filter::{FilterChangeset, FilterController, FilterTaskHandler, FilterType, UpdatedFilterType};
|
||||
use crate::services::group::{
|
||||
default_group_configuration, find_group_field, make_group_controller, Group, GroupConfigurationReader,
|
||||
GroupController, MoveGroupRowContext,
|
||||
};
|
||||
use crate::services::row::GridBlock;
|
||||
use crate::services::row::GridBlockRowRevision;
|
||||
use crate::services::sort::SortController;
|
||||
use crate::services::view_editor::changed_notifier::GridViewChangedNotifier;
|
||||
use crate::services::view_editor::trait_impl::*;
|
||||
@ -23,6 +24,7 @@ use lib_infra::async_trait::async_trait;
|
||||
use lib_infra::future::Fut;
|
||||
use lib_infra::ref_map::RefCountValue;
|
||||
use nanoid::nanoid;
|
||||
use std::borrow::Cow;
|
||||
use std::future::Future;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{broadcast, RwLock};
|
||||
@ -46,7 +48,7 @@ pub trait GridViewEditorDelegate: Send + Sync + 'static {
|
||||
|
||||
/// Get all the blocks that the current Grid has.
|
||||
/// One grid has a list of blocks
|
||||
fn get_blocks(&self) -> Fut<Vec<GridBlock>>;
|
||||
fn get_blocks(&self) -> Fut<Vec<GridBlockRowRevision>>;
|
||||
|
||||
fn get_task_scheduler(&self) -> Arc<RwLock<TaskDispatcher>>;
|
||||
}
|
||||
@ -128,6 +130,35 @@ impl GridViewRevisionEditor {
|
||||
self.filter_controller.read().await.close().await;
|
||||
}
|
||||
|
||||
pub async fn handle_block_event(&self, event: Cow<'_, GridBlockEvent>) {
|
||||
let changeset = match event.into_owned() {
|
||||
GridBlockEvent::InsertRow { block_id: _, row } => {
|
||||
//
|
||||
GridViewRowsChangesetPB::from_insert(self.view_id.clone(), vec![row])
|
||||
}
|
||||
GridBlockEvent::UpdateRow { block_id: _, row } => {
|
||||
//
|
||||
GridViewRowsChangesetPB::from_update(self.view_id.clone(), vec![row])
|
||||
}
|
||||
GridBlockEvent::DeleteRow { block_id: _, row_id } => {
|
||||
//
|
||||
GridViewRowsChangesetPB::from_delete(self.view_id.clone(), vec![row_id])
|
||||
}
|
||||
GridBlockEvent::Move {
|
||||
block_id: _,
|
||||
deleted_row_id,
|
||||
inserted_row,
|
||||
} => {
|
||||
//
|
||||
GridViewRowsChangesetPB::from_move(self.view_id.clone(), vec![deleted_row_id], vec![inserted_row])
|
||||
}
|
||||
};
|
||||
|
||||
send_dart_notification(&self.view_id, GridDartNotification::DidUpdateGridViewRows)
|
||||
.payload(changeset)
|
||||
.send();
|
||||
}
|
||||
|
||||
pub async fn notify_rows_did_changed(&self) {
|
||||
//
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ use flowy_revision::{RevisionManager, RevisionPersistence, RevisionPersistenceCo
|
||||
use grid_rev_model::{FieldRevision, FilterRevision, RowChangeset, RowRevision};
|
||||
use lib_infra::future::Fut;
|
||||
use lib_infra::ref_map::RefCountHashMap;
|
||||
use std::borrow::Cow;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{broadcast, RwLock};
|
||||
|
||||
@ -24,8 +25,7 @@ pub struct GridViewManager {
|
||||
grid_id: String,
|
||||
user: Arc<dyn GridUser>,
|
||||
delegate: Arc<dyn GridViewEditorDelegate>,
|
||||
view_editors: RwLock<RefCountHashMap<Arc<GridViewRevisionEditor>>>,
|
||||
block_event_rx: broadcast::Receiver<GridBlockEvent>,
|
||||
view_editors: Arc<RwLock<RefCountHashMap<Arc<GridViewRevisionEditor>>>>,
|
||||
}
|
||||
|
||||
impl GridViewManager {
|
||||
@ -35,13 +35,13 @@ impl GridViewManager {
|
||||
delegate: Arc<dyn GridViewEditorDelegate>,
|
||||
block_event_rx: broadcast::Receiver<GridBlockEvent>,
|
||||
) -> FlowyResult<Self> {
|
||||
let view_editors = RwLock::new(RefCountHashMap::default());
|
||||
let view_editors = Arc::new(RwLock::new(RefCountHashMap::default()));
|
||||
listen_on_grid_block_event(block_event_rx, view_editors.clone());
|
||||
Ok(Self {
|
||||
grid_id,
|
||||
user,
|
||||
delegate,
|
||||
view_editors,
|
||||
block_event_rx,
|
||||
})
|
||||
}
|
||||
|
||||
@ -233,6 +233,27 @@ impl GridViewManager {
|
||||
}
|
||||
}
|
||||
|
||||
fn listen_on_grid_block_event(
|
||||
mut block_event_rx: broadcast::Receiver<GridBlockEvent>,
|
||||
view_editors: Arc<RwLock<RefCountHashMap<Arc<GridViewRevisionEditor>>>>,
|
||||
) {
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
while let Ok(event) = block_event_rx.recv().await {
|
||||
let read_guard = view_editors.read().await;
|
||||
let view_editors = read_guard.values();
|
||||
let event = if view_editors.len() == 1 {
|
||||
Cow::Owned(event)
|
||||
} else {
|
||||
Cow::Borrowed(&event)
|
||||
};
|
||||
for view_editor in view_editors.iter() {
|
||||
view_editor.handle_block_event(event.clone()).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
pub async fn make_grid_view_rev_manager(
|
||||
user: &Arc<dyn GridUser>,
|
||||
view_id: &str,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::entities::{GridLayout, GridLayoutPB, GridSettingPB};
|
||||
use crate::services::filter::{FilterDelegate, FilterType};
|
||||
use crate::services::group::{GroupConfigurationReader, GroupConfigurationWriter};
|
||||
use crate::services::row::GridBlock;
|
||||
use crate::services::row::GridBlockRowRevision;
|
||||
use crate::services::view_editor::GridViewEditorDelegate;
|
||||
use bytes::Bytes;
|
||||
use flowy_database::ConnectionPool;
|
||||
@ -154,7 +154,7 @@ impl FilterDelegate for GridViewFilterDelegateImpl {
|
||||
self.editor_delegate.get_field_revs(field_ids)
|
||||
}
|
||||
|
||||
fn get_blocks(&self) -> Fut<Vec<GridBlock>> {
|
||||
fn get_blocks(&self) -> Fut<Vec<GridBlockRowRevision>> {
|
||||
self.editor_delegate.get_blocks()
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::grid::block_test::script::RowScript::{AssertCell, CreateRow};
|
||||
use crate::grid::block_test::util::GridRowTestBuilder;
|
||||
use crate::grid::grid_editor::GridEditorTest;
|
||||
|
||||
use flowy_grid::entities::{CellPathParams, CreateRowParams, FieldType, GridLayout, RowPB};
|
||||
use flowy_grid::services::field::*;
|
||||
use flowy_grid::services::row::GridBlockRow;
|
||||
use grid_rev_model::{GridBlockMetaRevision, GridBlockMetaRevisionChangeset, RowChangeset, RowRevision};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
@ -82,28 +82,27 @@ impl GridRowTest {
|
||||
layout: GridLayout::Table,
|
||||
};
|
||||
let row_order = self.editor.create_row(params).await.unwrap();
|
||||
self.row_order_by_row_id
|
||||
.insert(row_order.row_id().to_owned(), row_order);
|
||||
self.row_by_row_id.insert(row_order.row_id().to_owned(), row_order);
|
||||
self.row_revs = self.get_row_revs().await;
|
||||
self.block_meta_revs = self.editor.get_block_meta_revs().await.unwrap();
|
||||
}
|
||||
RowScript::CreateRow { row_rev } => {
|
||||
let row_orders = self.editor.insert_rows(vec![row_rev]).await.unwrap();
|
||||
for row_order in row_orders {
|
||||
self.row_order_by_row_id
|
||||
.insert(row_order.row_id().to_owned(), row_order);
|
||||
self.row_by_row_id.insert(row_order.row_id().to_owned(), row_order);
|
||||
}
|
||||
self.row_revs = self.get_row_revs().await;
|
||||
self.block_meta_revs = self.editor.get_block_meta_revs().await.unwrap();
|
||||
}
|
||||
RowScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(),
|
||||
RowScript::DeleteRows { row_ids } => {
|
||||
let row_orders = row_ids
|
||||
let row_pbs = row_ids
|
||||
.into_iter()
|
||||
.map(|row_id| self.row_order_by_row_id.get(&row_id).unwrap().clone())
|
||||
.map(|row_id| self.row_by_row_id.get(&row_id).unwrap().clone())
|
||||
.collect::<Vec<RowPB>>();
|
||||
|
||||
self.editor.delete_rows(row_orders).await.unwrap();
|
||||
let block_rows = block_from_row_pbs(row_pbs);
|
||||
self.editor.delete_rows(block_rows).await.unwrap();
|
||||
self.row_revs = self.get_row_revs().await;
|
||||
self.block_meta_revs = self.editor.get_block_meta_revs().await.unwrap();
|
||||
}
|
||||
@ -270,6 +269,19 @@ impl GridRowTest {
|
||||
}
|
||||
}
|
||||
|
||||
fn block_from_row_pbs(row_orders: Vec<RowPB>) -> Vec<GridBlockRow> {
|
||||
let mut map: HashMap<String, GridBlockRow> = HashMap::new();
|
||||
row_orders.into_iter().for_each(|row_pb| {
|
||||
let block_id = row_pb.block_id().to_owned();
|
||||
let cloned_block_id = block_id.clone();
|
||||
map.entry(block_id)
|
||||
.or_insert_with(|| GridBlockRow::new(cloned_block_id, vec![]))
|
||||
.row_ids
|
||||
.push(row_pb.id);
|
||||
});
|
||||
map.into_values().collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
impl std::ops::Deref for GridRowTest {
|
||||
type Target = GridEditorTest;
|
||||
|
||||
|
@ -226,10 +226,8 @@ impl GridFilterTest {
|
||||
}
|
||||
}
|
||||
FilterScript::AssertNumberOfVisibleRows { expected } => {
|
||||
//
|
||||
let grid = self.editor.get_grid().await.unwrap();
|
||||
let rows = grid.blocks.into_iter().map(|block| block.rows).flatten().collect::<Vec<RowPB>>();
|
||||
assert_eq!(rows.len(), expected);
|
||||
assert_eq!(grid.rows.len(), expected);
|
||||
}
|
||||
FilterScript::Wait { millisecond } => {
|
||||
tokio::time::sleep(Duration::from_millis(millisecond)).await;
|
||||
|
@ -30,7 +30,7 @@ pub struct GridEditorTest {
|
||||
pub block_meta_revs: Vec<Arc<GridBlockMetaRevision>>,
|
||||
pub row_revs: Vec<Arc<RowRevision>>,
|
||||
pub field_count: usize,
|
||||
pub row_order_by_row_id: HashMap<String, RowPB>,
|
||||
pub row_by_row_id: HashMap<String, RowPB>,
|
||||
}
|
||||
|
||||
impl GridEditorTest {
|
||||
@ -77,7 +77,7 @@ impl GridEditorTest {
|
||||
block_meta_revs,
|
||||
row_revs,
|
||||
field_count: FieldType::COUNT,
|
||||
row_order_by_row_id: HashMap::default(),
|
||||
row_by_row_id: HashMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user