mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: using cow for row ids stuff
This commit is contained in:
parent
b92660058c
commit
a755d52371
@ -148,7 +148,7 @@ void _resolveDocDeps(GetIt getIt) {
|
||||
void _resolveGridDeps(GetIt getIt) {
|
||||
// Grid
|
||||
getIt.registerFactoryParam<GridBloc, View, void>(
|
||||
(view, _) => GridBloc(view: view, service: GridService()),
|
||||
(view, _) => GridBloc(view: view),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<RowBloc, RowData, void>(
|
||||
|
@ -9,27 +9,31 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'grid_block_service.dart';
|
||||
import 'field/grid_listenr.dart';
|
||||
import 'grid_listener.dart';
|
||||
import 'grid_service.dart';
|
||||
|
||||
part 'grid_bloc.freezed.dart';
|
||||
|
||||
class GridBloc extends Bloc<GridEvent, GridState> {
|
||||
final View view;
|
||||
final GridService service;
|
||||
final GridService _gridService;
|
||||
final GridListener _gridListener;
|
||||
final GridFieldsListener _fieldListener;
|
||||
GridBlockService? _blockService;
|
||||
|
||||
GridBloc({required this.view, required this.service})
|
||||
GridBloc({required this.view})
|
||||
: _fieldListener = GridFieldsListener(gridId: view.id),
|
||||
_gridService = GridService(),
|
||||
_gridListener = GridListener(gridId: view.id),
|
||||
super(GridState.initial()) {
|
||||
on<GridEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
initial: (InitialGrid value) async {
|
||||
await _initGrid(emit);
|
||||
_startListening();
|
||||
},
|
||||
createRow: (_CreateRow value) {
|
||||
service.createRow(gridId: view.id);
|
||||
_gridService.createRow(gridId: view.id);
|
||||
},
|
||||
delete: (_Delete value) {},
|
||||
rename: (_Rename value) {},
|
||||
@ -48,7 +52,7 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _fieldListener.stop();
|
||||
await _blockService?.stop();
|
||||
await _gridListener.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
@ -64,22 +68,17 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
||||
await _loadGrid(emit);
|
||||
}
|
||||
|
||||
Future<void> _initGridBlock(Grid grid) async {
|
||||
_blockService = GridBlockService(
|
||||
gridId: grid.id,
|
||||
blockOrders: grid.blockOrders,
|
||||
);
|
||||
|
||||
_blockService?.blocksUpdateNotifier?.addPublishListener((result) {
|
||||
result.fold(
|
||||
(blockMap) => add(GridEvent.didReceiveRowUpdate(_buildRows(blockMap))),
|
||||
(err) => Log.error('$err'),
|
||||
);
|
||||
void _startListening() {
|
||||
_gridListener.rowsUpdateNotifier.addPublishListener((result) {
|
||||
result.fold((blockOrders) {
|
||||
add(GridEvent.didReceiveRowUpdate(_buildRows(blockOrders)));
|
||||
}, (err) => Log.error(err));
|
||||
});
|
||||
_gridListener.start();
|
||||
}
|
||||
|
||||
Future<void> _loadGrid(Emitter<GridState> emit) async {
|
||||
final result = await service.loadGrid(gridId: view.id);
|
||||
final result = await _gridService.loadGrid(gridId: view.id);
|
||||
return Future(
|
||||
() => result.fold(
|
||||
(grid) async => await _loadFields(grid, emit),
|
||||
@ -89,14 +88,14 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
||||
}
|
||||
|
||||
Future<void> _loadFields(Grid grid, Emitter<GridState> emit) async {
|
||||
final result = await service.getFields(gridId: grid.id, fieldOrders: grid.fieldOrders);
|
||||
final result = await _gridService.getFields(gridId: grid.id, fieldOrders: grid.fieldOrders);
|
||||
return Future(
|
||||
() => result.fold(
|
||||
(fields) {
|
||||
_initGridBlock(grid);
|
||||
emit(state.copyWith(
|
||||
grid: Some(grid),
|
||||
fields: fields.items,
|
||||
rows: _buildRows(grid.blockOrders),
|
||||
loadingState: GridLoadingState.finish(left(unit)),
|
||||
));
|
||||
},
|
||||
@ -105,17 +104,17 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
||||
);
|
||||
}
|
||||
|
||||
List<GridBlockRow> _buildRows(GridBlockMap blockMap) {
|
||||
List<GridBlockRow> _buildRows(List<GridBlockOrder> blockOrders) {
|
||||
List<GridBlockRow> rows = [];
|
||||
blockMap.forEach((_, GridBlock gridBlock) {
|
||||
rows.addAll(gridBlock.rowOrders.map(
|
||||
for (final blockOrder in blockOrders) {
|
||||
rows.addAll(blockOrder.rowOrders.map(
|
||||
(rowOrder) => GridBlockRow(
|
||||
gridId: view.id,
|
||||
rowId: rowOrder.rowId,
|
||||
height: rowOrder.height.toDouble(),
|
||||
),
|
||||
));
|
||||
});
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.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:app_flowy/core/notification_helper.dart';
|
||||
|
||||
class GridListener {
|
||||
final String gridId;
|
||||
PublishNotifier<Either<List<GridBlockOrder>, FlowyError>> rowsUpdateNotifier = PublishNotifier(comparable: null);
|
||||
GridNotificationListener? _listener;
|
||||
|
||||
GridListener({required this.gridId});
|
||||
|
||||
void start() {
|
||||
_listener = GridNotificationListener(
|
||||
objectId: gridId,
|
||||
handler: _handler,
|
||||
);
|
||||
}
|
||||
|
||||
void _handler(GridNotification ty, Either<Uint8List, FlowyError> result) {
|
||||
switch (ty) {
|
||||
case GridNotification.DidUpdateBlock:
|
||||
result.fold(
|
||||
(payload) => rowsUpdateNotifier.value = left([GridBlockOrder.fromBuffer(payload)]),
|
||||
(error) => rowsUpdateNotifier.value = right(error),
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> stop() async {
|
||||
await _listener?.stop();
|
||||
rowsUpdateNotifier.dispose();
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
class GridService {
|
||||
Future<Either<loadGrid, FlowyError>> loadGrid({required String gridId}) async {
|
||||
Future<Either<Grid, FlowyError>> loadGrid({required String gridId}) async {
|
||||
await FolderEventSetLatestView(ViewId(value: gridId)).send();
|
||||
|
||||
final payload = GridId(value: gridId);
|
||||
|
@ -803,17 +803,22 @@ class RepeatedGridBlock extends $pb.GeneratedMessage {
|
||||
class GridBlockOrder extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockOrder', createEmptyInstance: create)
|
||||
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId')
|
||||
..pc<RowOrder>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', $pb.PbFieldType.PM, subBuilder: RowOrder.create)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
GridBlockOrder._() : super();
|
||||
factory GridBlockOrder({
|
||||
$core.String? blockId,
|
||||
$core.Iterable<RowOrder>? rowOrders,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (blockId != null) {
|
||||
_result.blockId = blockId;
|
||||
}
|
||||
if (rowOrders != null) {
|
||||
_result.rowOrders.addAll(rowOrders);
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory GridBlockOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
@ -845,6 +850,9 @@ class GridBlockOrder extends $pb.GeneratedMessage {
|
||||
$core.bool hasBlockId() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearBlockId() => clearField(1);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
$core.List<RowOrder> get rowOrders => $_getList(1);
|
||||
}
|
||||
|
||||
class GridBlock extends $pb.GeneratedMessage {
|
||||
|
@ -165,11 +165,12 @@ const GridBlockOrder$json = const {
|
||||
'1': 'GridBlockOrder',
|
||||
'2': const [
|
||||
const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'},
|
||||
const {'1': 'row_orders', '3': 2, '4': 3, '5': 11, '6': '.RowOrder', '10': 'rowOrders'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `GridBlockOrder`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List gridBlockOrderDescriptor = $convert.base64Decode('Cg5HcmlkQmxvY2tPcmRlchIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZA==');
|
||||
final $typed_data.Uint8List gridBlockOrderDescriptor = $convert.base64Decode('Cg5HcmlkQmxvY2tPcmRlchIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIoCgpyb3dfb3JkZXJzGAIgAygLMgkuUm93T3JkZXJSCXJvd09yZGVycw==');
|
||||
@$core.Deprecated('Use gridBlockDescriptor instead')
|
||||
const GridBlock$json = const {
|
||||
'1': 'GridBlock',
|
||||
|
@ -17,7 +17,7 @@ class GridMeta extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create)
|
||||
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
|
||||
..pc<FieldMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: FieldMeta.create)
|
||||
..pc<GridBlockMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetas', $pb.PbFieldType.PM, subBuilder: GridBlockMeta.create)
|
||||
..pc<GridBlockMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: GridBlockMeta.create)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@ -25,7 +25,7 @@ class GridMeta extends $pb.GeneratedMessage {
|
||||
factory GridMeta({
|
||||
$core.String? gridId,
|
||||
$core.Iterable<FieldMeta>? fields,
|
||||
$core.Iterable<GridBlockMeta>? blockMetas,
|
||||
$core.Iterable<GridBlockMeta>? blocks,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (gridId != null) {
|
||||
@ -34,8 +34,8 @@ class GridMeta extends $pb.GeneratedMessage {
|
||||
if (fields != null) {
|
||||
_result.fields.addAll(fields);
|
||||
}
|
||||
if (blockMetas != null) {
|
||||
_result.blockMetas.addAll(blockMetas);
|
||||
if (blocks != null) {
|
||||
_result.blocks.addAll(blocks);
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
@ -73,7 +73,7 @@ class GridMeta extends $pb.GeneratedMessage {
|
||||
$core.List<FieldMeta> get fields => $_getList(1);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
$core.List<GridBlockMeta> get blockMetas => $_getList(2);
|
||||
$core.List<GridBlockMeta> get blocks => $_getList(2);
|
||||
}
|
||||
|
||||
class GridBlockMeta extends $pb.GeneratedMessage {
|
||||
@ -154,21 +154,21 @@ class GridBlockMeta extends $pb.GeneratedMessage {
|
||||
class GridBlockMetaData extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMetaData', createEmptyInstance: create)
|
||||
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId')
|
||||
..pc<RowMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowMetas', $pb.PbFieldType.PM, subBuilder: RowMeta.create)
|
||||
..pc<RowMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
GridBlockMetaData._() : super();
|
||||
factory GridBlockMetaData({
|
||||
$core.String? blockId,
|
||||
$core.Iterable<RowMeta>? rowMetas,
|
||||
$core.Iterable<RowMeta>? rows,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (blockId != null) {
|
||||
_result.blockId = blockId;
|
||||
}
|
||||
if (rowMetas != null) {
|
||||
_result.rowMetas.addAll(rowMetas);
|
||||
if (rows != null) {
|
||||
_result.rows.addAll(rows);
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
@ -203,7 +203,7 @@ class GridBlockMetaData extends $pb.GeneratedMessage {
|
||||
void clearBlockId() => clearField(1);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
$core.List<RowMeta> get rowMetas => $_getList(1);
|
||||
$core.List<RowMeta> get rows => $_getList(1);
|
||||
}
|
||||
|
||||
class FieldMeta extends $pb.GeneratedMessage {
|
||||
|
@ -29,12 +29,12 @@ const GridMeta$json = const {
|
||||
'2': const [
|
||||
const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
|
||||
const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fields'},
|
||||
const {'1': 'block_metas', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blockMetas'},
|
||||
const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSLwoLYmxvY2tfbWV0YXMYAyADKAsyDi5HcmlkQmxvY2tNZXRhUgpibG9ja01ldGFz');
|
||||
final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSJgoGYmxvY2tzGAMgAygLMg4uR3JpZEJsb2NrTWV0YVIGYmxvY2tz');
|
||||
@$core.Deprecated('Use gridBlockMetaDescriptor instead')
|
||||
const GridBlockMeta$json = const {
|
||||
'1': 'GridBlockMeta',
|
||||
@ -52,12 +52,12 @@ const GridBlockMetaData$json = const {
|
||||
'1': 'GridBlockMetaData',
|
||||
'2': const [
|
||||
const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'},
|
||||
const {'1': 'row_metas', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rowMetas'},
|
||||
const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `GridBlockMetaData`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List gridBlockMetaDataDescriptor = $convert.base64Decode('ChFHcmlkQmxvY2tNZXRhRGF0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIlCglyb3dfbWV0YXMYAiADKAsyCC5Sb3dNZXRhUghyb3dNZXRhcw==');
|
||||
final $typed_data.Uint8List gridBlockMetaDataDescriptor = $convert.base64Decode('ChFHcmlkQmxvY2tNZXRhRGF0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIcCgRyb3dzGAIgAygLMgguUm93TWV0YVIEcm93cw==');
|
||||
@$core.Deprecated('Use fieldMetaDescriptor instead')
|
||||
const FieldMeta$json = const {
|
||||
'1': 'FieldMeta',
|
||||
|
@ -186,7 +186,7 @@ pub(crate) async fn delete_row_handler(
|
||||
) -> Result<(), FlowyError> {
|
||||
let params: RowIdentifier = data.into_inner().try_into()?;
|
||||
let editor = manager.get_grid_editor(¶ms.grid_id)?;
|
||||
let _ = editor.delete_row(¶ms.row_id)?;
|
||||
let _ = editor.delete_row(¶ms.row_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ pub(crate) async fn duplicate_row_handler(
|
||||
) -> Result<(), FlowyError> {
|
||||
let params: RowIdentifier = data.into_inner().try_into()?;
|
||||
let editor = manager.get_grid_editor(¶ms.grid_id)?;
|
||||
let _ = editor.duplicate_row(¶ms.row_id)?;
|
||||
let _ = editor.duplicate_row(¶ms.row_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ use flowy_sync::entities::revision::Revision;
|
||||
use flowy_sync::util::make_delta_from_revisions;
|
||||
use lib_infra::future::FutureResult;
|
||||
use lib_ot::core::PlainTextAttributes;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
@ -54,11 +55,11 @@ impl ClientGridBlockMetaEditor {
|
||||
Ok(row_count)
|
||||
}
|
||||
|
||||
pub async fn delete_rows(&self, ids: Vec<String>) -> FlowyResult<i32> {
|
||||
pub async fn delete_rows(&self, ids: Vec<Cow<'_, String>>) -> FlowyResult<i32> {
|
||||
let mut row_count = 0;
|
||||
let _ = self
|
||||
.modify(|pad| {
|
||||
let changeset = pad.delete_rows(&ids)?;
|
||||
let changeset = pad.delete_rows(ids)?;
|
||||
row_count = pad.number_of_rows();
|
||||
Ok(changeset)
|
||||
})
|
||||
@ -71,17 +72,24 @@ impl ClientGridBlockMetaEditor {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_row_metas(&self, row_ids: Option<Vec<String>>) -> FlowyResult<Vec<Arc<RowMeta>>> {
|
||||
let row_metas = self.pad.read().await.get_row_metas(&row_ids)?;
|
||||
pub async fn get_row_metas<T>(&self, row_ids: Option<Vec<Cow<'_, T>>>) -> FlowyResult<Vec<Arc<RowMeta>>>
|
||||
where
|
||||
T: AsRef<str> + ToOwned + ?Sized,
|
||||
{
|
||||
let row_metas = self.pad.read().await.get_row_metas(row_ids)?;
|
||||
Ok(row_metas)
|
||||
}
|
||||
|
||||
pub async fn get_cell_metas(&self, field_id: &str, row_ids: &Option<Vec<String>>) -> FlowyResult<Vec<CellMeta>> {
|
||||
pub async fn get_cell_metas(
|
||||
&self,
|
||||
field_id: &str,
|
||||
row_ids: Option<Vec<Cow<'_, String>>>,
|
||||
) -> FlowyResult<Vec<CellMeta>> {
|
||||
let cell_metas = self.pad.read().await.get_cell_metas(field_id, row_ids)?;
|
||||
Ok(cell_metas)
|
||||
}
|
||||
|
||||
pub async fn get_row_orders(&self, row_ids: &Option<Vec<String>>) -> FlowyResult<Vec<RowOrder>> {
|
||||
pub async fn get_row_orders(&self, row_ids: Option<Vec<Cow<'_, String>>>) -> FlowyResult<Vec<RowOrder>> {
|
||||
let row_orders = self
|
||||
.pad
|
||||
.read()
|
||||
|
@ -2,7 +2,8 @@ use crate::dart_notification::{send_dart_notification, GridNotification};
|
||||
use crate::manager::GridUser;
|
||||
use crate::services::block_meta_editor::ClientGridBlockMetaEditor;
|
||||
use crate::services::persistence::block_index::BlockIndexPersistence;
|
||||
use crate::services::row::{make_block_rows, make_rows_from_row_metas, GridBlockSnapshot};
|
||||
use crate::services::row::{group_row_orders, make_rows_from_row_metas, GridBlockSnapshot};
|
||||
use std::borrow::Cow;
|
||||
|
||||
use dashmap::DashMap;
|
||||
use flowy_error::FlowyResult;
|
||||
@ -18,6 +19,7 @@ use std::sync::Arc;
|
||||
pub(crate) struct GridBlockMetaEditorManager {
|
||||
grid_id: String,
|
||||
user: Arc<dyn GridUser>,
|
||||
// Key: block_id
|
||||
editor_map: DashMap<String, Arc<ClientGridBlockMetaEditor>>,
|
||||
persistence: Arc<BlockIndexPersistence>,
|
||||
}
|
||||
@ -92,19 +94,6 @@ impl GridBlockMetaEditorManager {
|
||||
Ok(changesets)
|
||||
}
|
||||
|
||||
pub(crate) async fn delete_rows(&self, row_orders: Vec<RowOrder>) -> FlowyResult<Vec<GridBlockMetaChangeset>> {
|
||||
let mut changesets = vec![];
|
||||
for block_row in make_block_rows(&row_orders) {
|
||||
let editor = self.get_editor(&block_row.block_id).await?;
|
||||
let row_count = editor.delete_rows(block_row.row_ids).await?;
|
||||
|
||||
let changeset = GridBlockMetaChangeset::from_row_count(&block_row.block_id, row_count);
|
||||
changesets.push(changeset);
|
||||
}
|
||||
|
||||
Ok(changesets)
|
||||
}
|
||||
|
||||
pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> {
|
||||
let editor = self.get_editor_from_row_id(&changeset.row_id).await?;
|
||||
let _ = editor.update_row(changeset.clone()).await?;
|
||||
@ -112,6 +101,23 @@ impl GridBlockMetaEditorManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn delete_rows(&self, row_orders: Vec<RowOrder>) -> FlowyResult<Vec<GridBlockMetaChangeset>> {
|
||||
let mut changesets = vec![];
|
||||
for block_order in group_row_orders(row_orders) {
|
||||
let editor = self.get_editor(&block_order.block_id).await?;
|
||||
let row_ids = block_order
|
||||
.row_orders
|
||||
.into_iter()
|
||||
.map(|row_order| Cow::Owned(row_order.row_id))
|
||||
.collect::<Vec<Cow<String>>>();
|
||||
let row_count = editor.delete_rows(row_ids).await?;
|
||||
let changeset = GridBlockMetaChangeset::from_row_count(&block_order.block_id, row_count);
|
||||
changesets.push(changeset);
|
||||
}
|
||||
|
||||
Ok(changesets)
|
||||
}
|
||||
|
||||
pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> {
|
||||
let row_id = changeset.row_id.clone();
|
||||
let editor = self.get_editor_from_row_id(&row_id).await?;
|
||||
@ -130,7 +136,7 @@ impl GridBlockMetaEditorManager {
|
||||
|
||||
pub async fn get_row_meta(&self, row_id: &str) -> FlowyResult<Option<Arc<RowMeta>>> {
|
||||
let editor = self.get_editor_from_row_id(row_id).await?;
|
||||
let row_ids = vec![row_id.to_owned()];
|
||||
let row_ids = vec![Cow::Borrowed(row_id)];
|
||||
let mut row_metas = editor.get_row_metas(Some(row_ids)).await?;
|
||||
if row_metas.is_empty() {
|
||||
Ok(None)
|
||||
@ -139,11 +145,16 @@ impl GridBlockMetaEditorManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_row_orders(&self, block_id: &str) -> FlowyResult<Vec<RowOrder>> {
|
||||
let editor = self.get_editor(block_id).await?;
|
||||
editor.get_row_orders(None).await
|
||||
}
|
||||
|
||||
pub(crate) async fn make_block_snapshots(&self, block_ids: Vec<String>) -> FlowyResult<Vec<GridBlockSnapshot>> {
|
||||
let mut snapshots = vec![];
|
||||
for block_id in block_ids {
|
||||
let editor = self.get_editor(&block_id).await?;
|
||||
let row_metas = editor.get_row_metas(None).await?;
|
||||
let row_metas = editor.get_row_metas::<&str>(None).await?;
|
||||
snapshots.push(GridBlockSnapshot { block_id, row_metas });
|
||||
}
|
||||
Ok(snapshots)
|
||||
@ -155,22 +166,22 @@ impl GridBlockMetaEditorManager {
|
||||
&self,
|
||||
block_ids: Vec<String>,
|
||||
field_id: &str,
|
||||
row_ids: Option<Vec<String>>,
|
||||
row_ids: Option<Vec<Cow<'_, String>>>,
|
||||
) -> FlowyResult<Vec<CellMeta>> {
|
||||
let mut block_cell_metas = vec![];
|
||||
for block_id in block_ids {
|
||||
let editor = self.get_editor(&block_id).await?;
|
||||
let cell_metas = editor.get_cell_metas(field_id, &row_ids).await?;
|
||||
let cell_metas = editor.get_cell_metas(field_id, row_ids.clone()).await?;
|
||||
block_cell_metas.extend(cell_metas);
|
||||
}
|
||||
Ok(block_cell_metas)
|
||||
}
|
||||
|
||||
async fn notify_block_did_update_row(&self, block_id: &str) -> FlowyResult<()> {
|
||||
let block_order: GridBlockOrder = block_id.into();
|
||||
send_dart_notification(&self.grid_id, GridNotification::DidUpdateBlock)
|
||||
.payload(block_order)
|
||||
.send();
|
||||
// let block_order: GridBlockOrder = block_id.into();
|
||||
// send_dart_notification(&self.grid_id, GridNotification::DidUpdateBlock)
|
||||
// .payload(block_order)
|
||||
// .send();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -196,30 +207,6 @@ impl GridBlockMetaEditorManager {
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
//
|
||||
// let field_meta_map = field_metas
|
||||
// .iter()
|
||||
// .map(|field_meta| (&field_meta.id, field_meta))
|
||||
// .collect::<HashMap<&String, &FieldMeta>>();
|
||||
//
|
||||
// let mut cells = vec![];
|
||||
// changeset
|
||||
// .cell_by_field_id
|
||||
// .into_iter()
|
||||
// .for_each(
|
||||
// |(field_id, cell_meta)| match make_cell_by_field_id(&field_meta_map, field_id, cell_meta) {
|
||||
// None => {}
|
||||
// Some((_, cell)) => cells.push(cell),
|
||||
// },
|
||||
// );
|
||||
//
|
||||
// if !cells.is_empty() {
|
||||
// send_dart_notification(&changeset.row_id, GridNotification::DidUpdateRow)
|
||||
// .payload(RepeatedCell::from(cells))
|
||||
// .send();
|
||||
// }
|
||||
// Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,17 +337,18 @@ impl ClientGridEditor {
|
||||
}
|
||||
|
||||
pub async fn grid_data(&self) -> FlowyResult<Grid> {
|
||||
let field_orders = self.pad.read().await.get_field_orders();
|
||||
let block_orders = self
|
||||
.pad
|
||||
.read()
|
||||
.await
|
||||
.get_block_metas()
|
||||
.into_iter()
|
||||
.map(|grid_block_meta| GridBlockOrder {
|
||||
block_id: grid_block_meta.block_id,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let pad_read_guard = self.pad.read().await;
|
||||
let field_orders = pad_read_guard.get_field_orders();
|
||||
let mut block_orders = vec![];
|
||||
for block_order in pad_read_guard.get_block_metas() {
|
||||
let row_orders = self.block_meta_manager.get_row_orders(&block_order.block_id).await?;
|
||||
let block_order = GridBlockOrder {
|
||||
block_id: block_order.block_id,
|
||||
row_orders,
|
||||
};
|
||||
block_orders.push(block_order);
|
||||
}
|
||||
|
||||
Ok(Grid {
|
||||
id: self.grid_id.clone(),
|
||||
field_orders,
|
||||
|
@ -1,41 +1,28 @@
|
||||
use crate::services::row::decode_cell_data;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_grid_data_model::entities::{
|
||||
Cell, CellMeta, FieldMeta, GridBlock, RepeatedGridBlock, Row, RowMeta, RowOrder,
|
||||
Cell, CellMeta, FieldMeta, GridBlock, GridBlockOrder, RepeatedGridBlock, Row, RowMeta, RowOrder,
|
||||
};
|
||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub(crate) struct BlockRows {
|
||||
pub(crate) block_id: String,
|
||||
pub(crate) row_ids: Vec<String>,
|
||||
}
|
||||
|
||||
impl BlockRows {
|
||||
pub fn new(block_id: &str) -> Self {
|
||||
BlockRows {
|
||||
block_id: block_id.to_owned(),
|
||||
row_ids: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GridBlockSnapshot {
|
||||
pub(crate) block_id: String,
|
||||
pub row_metas: Vec<Arc<RowMeta>>,
|
||||
}
|
||||
|
||||
pub(crate) fn make_block_rows(row_orders: &[RowOrder]) -> Vec<BlockRows> {
|
||||
let mut map: HashMap<&String, BlockRows> = HashMap::new();
|
||||
row_orders.iter().for_each(|row_order| {
|
||||
let block_id = &row_order.block_id;
|
||||
let row_id = row_order.row_id.clone();
|
||||
pub(crate) fn group_row_orders(row_orders: Vec<RowOrder>) -> Vec<GridBlockOrder> {
|
||||
let mut map: HashMap<String, GridBlockOrder> = HashMap::new();
|
||||
row_orders.into_iter().for_each(|row_order| {
|
||||
// Memory Optimization: escape clone block_id
|
||||
let block_id = row_order.block_id.clone();
|
||||
map.entry(block_id)
|
||||
.or_insert_with(|| BlockRows::new(block_id))
|
||||
.row_ids
|
||||
.push(row_id);
|
||||
.or_insert_with(|| GridBlockOrder::new(&row_order.block_id))
|
||||
.row_orders
|
||||
.push(row_order);
|
||||
});
|
||||
map.into_values().collect::<Vec<_>>()
|
||||
}
|
||||
|
@ -260,11 +260,17 @@ impl std::convert::From<Vec<GridBlock>> for RepeatedGridBlock {
|
||||
pub struct GridBlockOrder {
|
||||
#[pb(index = 1)]
|
||||
pub block_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub row_orders: Vec<RowOrder>,
|
||||
}
|
||||
|
||||
impl std::convert::From<&str> for GridBlockOrder {
|
||||
fn from(s: &str) -> Self {
|
||||
GridBlockOrder { block_id: s.to_owned() }
|
||||
impl GridBlockOrder {
|
||||
pub fn new(block_id: &str) -> Self {
|
||||
GridBlockOrder {
|
||||
block_id: block_id.to_owned(),
|
||||
row_orders: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2715,6 +2715,7 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedGridBlock {
|
||||
pub struct GridBlockOrder {
|
||||
// message fields
|
||||
pub block_id: ::std::string::String,
|
||||
pub row_orders: ::protobuf::RepeatedField<RowOrder>,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
@ -2756,10 +2757,40 @@ impl GridBlockOrder {
|
||||
pub fn take_block_id(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.block_id, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// repeated .RowOrder row_orders = 2;
|
||||
|
||||
|
||||
pub fn get_row_orders(&self) -> &[RowOrder] {
|
||||
&self.row_orders
|
||||
}
|
||||
pub fn clear_row_orders(&mut self) {
|
||||
self.row_orders.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_row_orders(&mut self, v: ::protobuf::RepeatedField<RowOrder>) {
|
||||
self.row_orders = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
pub fn mut_row_orders(&mut self) -> &mut ::protobuf::RepeatedField<RowOrder> {
|
||||
&mut self.row_orders
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_row_orders(&mut self) -> ::protobuf::RepeatedField<RowOrder> {
|
||||
::std::mem::replace(&mut self.row_orders, ::protobuf::RepeatedField::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for GridBlockOrder {
|
||||
fn is_initialized(&self) -> bool {
|
||||
for v in &self.row_orders {
|
||||
if !v.is_initialized() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
true
|
||||
}
|
||||
|
||||
@ -2770,6 +2801,9 @@ impl ::protobuf::Message for GridBlockOrder {
|
||||
1 => {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?;
|
||||
},
|
||||
2 => {
|
||||
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.row_orders)?;
|
||||
},
|
||||
_ => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||
},
|
||||
@ -2785,6 +2819,10 @@ impl ::protobuf::Message for GridBlockOrder {
|
||||
if !self.block_id.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(1, &self.block_id);
|
||||
}
|
||||
for value in &self.row_orders {
|
||||
let len = value.compute_size();
|
||||
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
|
||||
};
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
||||
self.cached_size.set(my_size);
|
||||
my_size
|
||||
@ -2794,6 +2832,11 @@ impl ::protobuf::Message for GridBlockOrder {
|
||||
if !self.block_id.is_empty() {
|
||||
os.write_string(1, &self.block_id)?;
|
||||
}
|
||||
for v in &self.row_orders {
|
||||
os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
|
||||
os.write_raw_varint32(v.get_cached_size())?;
|
||||
v.write_to_with_cached_sizes(os)?;
|
||||
};
|
||||
os.write_unknown_fields(self.get_unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
@ -2837,6 +2880,11 @@ impl ::protobuf::Message for GridBlockOrder {
|
||||
|m: &GridBlockOrder| { &m.block_id },
|
||||
|m: &mut GridBlockOrder| { &mut m.block_id },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<RowOrder>>(
|
||||
"row_orders",
|
||||
|m: &GridBlockOrder| { &m.row_orders },
|
||||
|m: &mut GridBlockOrder| { &mut m.row_orders },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<GridBlockOrder>(
|
||||
"GridBlockOrder",
|
||||
fields,
|
||||
@ -2854,6 +2902,7 @@ impl ::protobuf::Message for GridBlockOrder {
|
||||
impl ::protobuf::Clear for GridBlockOrder {
|
||||
fn clear(&mut self) {
|
||||
self.block_id.clear();
|
||||
self.row_orders.clear();
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
@ -5283,31 +5332,32 @@ static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05\
|
||||
.CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\
|
||||
\x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05\
|
||||
items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\
|
||||
\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\
|
||||
\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\
|
||||
\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\
|
||||
\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\
|
||||
\x07content\"\x8f\x01\n\x14CellNotificationData\x12\x17\n\x07grid_id\x18\
|
||||
\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07\
|
||||
fieldId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\x12\x1a\n\x07co\
|
||||
ntent\x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\x0eone_of_content\"+\n\
|
||||
\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05i\
|
||||
tems\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04\
|
||||
name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"\
|
||||
#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\
|
||||
\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\
|
||||
\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13on\
|
||||
e_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07grid_id\
|
||||
\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\
|
||||
\x06.FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\
|
||||
\x0etypeOptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\x0cst\
|
||||
artFieldIdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPayload\x12\
|
||||
\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\
|
||||
\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16Qu\
|
||||
eryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\
|
||||
\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblo\
|
||||
ckOrdersb\x06proto3\
|
||||
items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"U\n\x0eGridBlockOrder\
|
||||
\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_orders\
|
||||
\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\"E\n\tGridBlock\x12\x0e\n\
|
||||
\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b\
|
||||
2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\
|
||||
\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07content\
|
||||
\"\x8f\x01\n\x14CellNotificationData\x12\x17\n\x07grid_id\x18\x01\x20\
|
||||
\x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\
|
||||
\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\x12\x1a\n\x07content\
|
||||
\x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\x0eone_of_content\"+\n\x0cRepe\
|
||||
atedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\
|
||||
\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\
|
||||
\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\
|
||||
\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10\
|
||||
CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\
|
||||
\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of\
|
||||
_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07grid_id\x18\
|
||||
\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.\
|
||||
FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\x0etype\
|
||||
OptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\x0cstartField\
|
||||
IdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPayload\x12\x17\n\
|
||||
\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\
|
||||
\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16QueryGridB\
|
||||
locksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x122\n\
|
||||
\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblockOrder\
|
||||
sb\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
@ -28,7 +28,7 @@ pub struct GridMeta {
|
||||
// message fields
|
||||
pub grid_id: ::std::string::String,
|
||||
pub fields: ::protobuf::RepeatedField<FieldMeta>,
|
||||
pub block_metas: ::protobuf::RepeatedField<GridBlockMeta>,
|
||||
pub blocks: ::protobuf::RepeatedField<GridBlockMeta>,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
@ -96,29 +96,29 @@ impl GridMeta {
|
||||
::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new())
|
||||
}
|
||||
|
||||
// repeated .GridBlockMeta block_metas = 3;
|
||||
// repeated .GridBlockMeta blocks = 3;
|
||||
|
||||
|
||||
pub fn get_block_metas(&self) -> &[GridBlockMeta] {
|
||||
&self.block_metas
|
||||
pub fn get_blocks(&self) -> &[GridBlockMeta] {
|
||||
&self.blocks
|
||||
}
|
||||
pub fn clear_block_metas(&mut self) {
|
||||
self.block_metas.clear();
|
||||
pub fn clear_blocks(&mut self) {
|
||||
self.blocks.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_block_metas(&mut self, v: ::protobuf::RepeatedField<GridBlockMeta>) {
|
||||
self.block_metas = v;
|
||||
pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField<GridBlockMeta>) {
|
||||
self.blocks = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
pub fn mut_block_metas(&mut self) -> &mut ::protobuf::RepeatedField<GridBlockMeta> {
|
||||
&mut self.block_metas
|
||||
pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField<GridBlockMeta> {
|
||||
&mut self.blocks
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_block_metas(&mut self) -> ::protobuf::RepeatedField<GridBlockMeta> {
|
||||
::std::mem::replace(&mut self.block_metas, ::protobuf::RepeatedField::new())
|
||||
pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField<GridBlockMeta> {
|
||||
::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new())
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ impl ::protobuf::Message for GridMeta {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
for v in &self.block_metas {
|
||||
for v in &self.blocks {
|
||||
if !v.is_initialized() {
|
||||
return false;
|
||||
}
|
||||
@ -148,7 +148,7 @@ impl ::protobuf::Message for GridMeta {
|
||||
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.fields)?;
|
||||
},
|
||||
3 => {
|
||||
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.block_metas)?;
|
||||
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?;
|
||||
},
|
||||
_ => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||
@ -169,7 +169,7 @@ impl ::protobuf::Message for GridMeta {
|
||||
let len = value.compute_size();
|
||||
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
|
||||
};
|
||||
for value in &self.block_metas {
|
||||
for value in &self.blocks {
|
||||
let len = value.compute_size();
|
||||
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
|
||||
};
|
||||
@ -187,7 +187,7 @@ impl ::protobuf::Message for GridMeta {
|
||||
os.write_raw_varint32(v.get_cached_size())?;
|
||||
v.write_to_with_cached_sizes(os)?;
|
||||
};
|
||||
for v in &self.block_metas {
|
||||
for v in &self.blocks {
|
||||
os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
|
||||
os.write_raw_varint32(v.get_cached_size())?;
|
||||
v.write_to_with_cached_sizes(os)?;
|
||||
@ -241,9 +241,9 @@ impl ::protobuf::Message for GridMeta {
|
||||
|m: &mut GridMeta| { &mut m.fields },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<GridBlockMeta>>(
|
||||
"block_metas",
|
||||
|m: &GridMeta| { &m.block_metas },
|
||||
|m: &mut GridMeta| { &mut m.block_metas },
|
||||
"blocks",
|
||||
|m: &GridMeta| { &m.blocks },
|
||||
|m: &mut GridMeta| { &mut m.blocks },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<GridMeta>(
|
||||
"GridMeta",
|
||||
@ -263,7 +263,7 @@ impl ::protobuf::Clear for GridMeta {
|
||||
fn clear(&mut self) {
|
||||
self.grid_id.clear();
|
||||
self.fields.clear();
|
||||
self.block_metas.clear();
|
||||
self.blocks.clear();
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
@ -513,7 +513,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockMeta {
|
||||
pub struct GridBlockMetaData {
|
||||
// message fields
|
||||
pub block_id: ::std::string::String,
|
||||
pub row_metas: ::protobuf::RepeatedField<RowMeta>,
|
||||
pub rows: ::protobuf::RepeatedField<RowMeta>,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
@ -556,35 +556,35 @@ impl GridBlockMetaData {
|
||||
::std::mem::replace(&mut self.block_id, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// repeated .RowMeta row_metas = 2;
|
||||
// repeated .RowMeta rows = 2;
|
||||
|
||||
|
||||
pub fn get_row_metas(&self) -> &[RowMeta] {
|
||||
&self.row_metas
|
||||
pub fn get_rows(&self) -> &[RowMeta] {
|
||||
&self.rows
|
||||
}
|
||||
pub fn clear_row_metas(&mut self) {
|
||||
self.row_metas.clear();
|
||||
pub fn clear_rows(&mut self) {
|
||||
self.rows.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_row_metas(&mut self, v: ::protobuf::RepeatedField<RowMeta>) {
|
||||
self.row_metas = v;
|
||||
pub fn set_rows(&mut self, v: ::protobuf::RepeatedField<RowMeta>) {
|
||||
self.rows = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
pub fn mut_row_metas(&mut self) -> &mut ::protobuf::RepeatedField<RowMeta> {
|
||||
&mut self.row_metas
|
||||
pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField<RowMeta> {
|
||||
&mut self.rows
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_row_metas(&mut self) -> ::protobuf::RepeatedField<RowMeta> {
|
||||
::std::mem::replace(&mut self.row_metas, ::protobuf::RepeatedField::new())
|
||||
pub fn take_rows(&mut self) -> ::protobuf::RepeatedField<RowMeta> {
|
||||
::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for GridBlockMetaData {
|
||||
fn is_initialized(&self) -> bool {
|
||||
for v in &self.row_metas {
|
||||
for v in &self.rows {
|
||||
if !v.is_initialized() {
|
||||
return false;
|
||||
}
|
||||
@ -600,7 +600,7 @@ impl ::protobuf::Message for GridBlockMetaData {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?;
|
||||
},
|
||||
2 => {
|
||||
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.row_metas)?;
|
||||
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?;
|
||||
},
|
||||
_ => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||
@ -617,7 +617,7 @@ impl ::protobuf::Message for GridBlockMetaData {
|
||||
if !self.block_id.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(1, &self.block_id);
|
||||
}
|
||||
for value in &self.row_metas {
|
||||
for value in &self.rows {
|
||||
let len = value.compute_size();
|
||||
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
|
||||
};
|
||||
@ -630,7 +630,7 @@ impl ::protobuf::Message for GridBlockMetaData {
|
||||
if !self.block_id.is_empty() {
|
||||
os.write_string(1, &self.block_id)?;
|
||||
}
|
||||
for v in &self.row_metas {
|
||||
for v in &self.rows {
|
||||
os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
|
||||
os.write_raw_varint32(v.get_cached_size())?;
|
||||
v.write_to_with_cached_sizes(os)?;
|
||||
@ -679,9 +679,9 @@ impl ::protobuf::Message for GridBlockMetaData {
|
||||
|m: &mut GridBlockMetaData| { &mut m.block_id },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<RowMeta>>(
|
||||
"row_metas",
|
||||
|m: &GridBlockMetaData| { &m.row_metas },
|
||||
|m: &mut GridBlockMetaData| { &mut m.row_metas },
|
||||
"rows",
|
||||
|m: &GridBlockMetaData| { &m.rows },
|
||||
|m: &mut GridBlockMetaData| { &mut m.rows },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<GridBlockMetaData>(
|
||||
"GridBlockMetaData",
|
||||
@ -700,7 +700,7 @@ impl ::protobuf::Message for GridBlockMetaData {
|
||||
impl ::protobuf::Clear for GridBlockMetaData {
|
||||
fn clear(&mut self) {
|
||||
self.block_id.clear();
|
||||
self.row_metas.clear();
|
||||
self.rows.clear();
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
@ -3453,26 +3453,26 @@ impl ::protobuf::reflect::ProtobufValue for FieldType {
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\nmeta.proto\"x\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\
|
||||
\n\nmeta.proto\"o\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\
|
||||
\x06gridId\x12\"\n\x06fields\x18\x02\x20\x03(\x0b2\n.FieldMetaR\x06field\
|
||||
s\x12/\n\x0bblock_metas\x18\x03\x20\x03(\x0b2\x0e.GridBlockMetaR\nblockM\
|
||||
etas\"o\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07bl\
|
||||
ockId\x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\
|
||||
\x1b\n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"U\n\x11GridBlockMet\
|
||||
aData\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_m\
|
||||
etas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xbc\x02\n\tFieldMe\
|
||||
ta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\
|
||||
\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\
|
||||
\n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\
|
||||
\x06frozen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\
|
||||
\x20\x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05w\
|
||||
idth\x12>\n\x0ctype_options\x18\x08\x20\x03(\x0b2\x1b.FieldMeta.TypeOpti\
|
||||
onsEntryR\x0btypeOptions\x1a>\n\x10TypeOptionsEntry\x12\x10\n\x03key\x18\
|
||||
\x01\x20\x01(\tR\x03key\x12\x14\n\x05value\x18\x02\x20\x01(\tR\x05value:\
|
||||
\x028\x01\"\xa8\x03\n\x15FieldChangesetPayload\x12\x19\n\x08field_id\x18\
|
||||
\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06\
|
||||
gridId\x12\x14\n\x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04des\
|
||||
c\x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\
|
||||
s\x12&\n\x06blocks\x18\x03\x20\x03(\x0b2\x0e.GridBlockMetaR\x06blocks\"o\
|
||||
\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\
|
||||
\x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\
|
||||
\n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"L\n\x11GridBlockMetaDat\
|
||||
a\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\
|
||||
\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x04rows\"\xbc\x02\n\tFieldMeta\x12\
|
||||
\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01\
|
||||
(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield\
|
||||
_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\
|
||||
\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\
|
||||
\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\x12>\
|
||||
\n\x0ctype_options\x18\x08\x20\x03(\x0b2\x1b.FieldMeta.TypeOptionsEntryR\
|
||||
\x0btypeOptions\x1a>\n\x10TypeOptionsEntry\x12\x10\n\x03key\x18\x01\x20\
|
||||
\x01(\tR\x03key\x12\x14\n\x05value\x18\x02\x20\x01(\tR\x05value:\x028\
|
||||
\x01\"\xa8\x03\n\x15FieldChangesetPayload\x12\x19\n\x08field_id\x18\x01\
|
||||
\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06grid\
|
||||
Id\x12\x14\n\x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\
|
||||
\x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\
|
||||
\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\
|
||||
\x08H\x03R\x06frozen\x12\x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nv\
|
||||
isibility\x12\x16\n\x05width\x18\x08\x20\x01(\x05H\x05R\x05width\x12*\n\
|
||||
|
@ -57,6 +57,7 @@ message RepeatedGridBlock {
|
||||
}
|
||||
message GridBlockOrder {
|
||||
string block_id = 1;
|
||||
repeated RowOrder row_orders = 2;
|
||||
}
|
||||
message GridBlock {
|
||||
string id = 1;
|
||||
|
@ -3,7 +3,7 @@ syntax = "proto3";
|
||||
message GridMeta {
|
||||
string grid_id = 1;
|
||||
repeated FieldMeta fields = 2;
|
||||
repeated GridBlockMeta block_metas = 3;
|
||||
repeated GridBlockMeta blocks = 3;
|
||||
}
|
||||
message GridBlockMeta {
|
||||
string block_id = 1;
|
||||
@ -12,7 +12,7 @@ message GridBlockMeta {
|
||||
}
|
||||
message GridBlockMetaData {
|
||||
string block_id = 1;
|
||||
repeated RowMeta row_metas = 2;
|
||||
repeated RowMeta rows = 2;
|
||||
}
|
||||
message FieldMeta {
|
||||
string id = 1;
|
||||
|
@ -5,6 +5,7 @@ use flowy_grid_data_model::entities::{CellMeta, GridBlockMetaData, RowMeta, RowM
|
||||
use lib_infra::uuid;
|
||||
use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::borrow::Cow;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
@ -67,38 +68,48 @@ impl GridBlockMetaPad {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult<Option<GridBlockMetaChange>> {
|
||||
pub fn delete_rows(&mut self, row_ids: Vec<Cow<'_, String>>) -> CollaborateResult<Option<GridBlockMetaChange>> {
|
||||
self.modify(|rows| {
|
||||
rows.retain(|row| !row_ids.contains(&row.id));
|
||||
rows.retain(|row| !row_ids.contains(&Cow::Borrowed(&row.id)));
|
||||
Ok(Some(()))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_row_metas(&self, row_ids: &Option<Vec<String>>) -> CollaborateResult<Vec<Arc<RowMeta>>> {
|
||||
pub fn get_row_metas<T>(&self, row_ids: Option<Vec<Cow<'_, T>>>) -> CollaborateResult<Vec<Arc<RowMeta>>>
|
||||
where
|
||||
T: AsRef<str> + ToOwned + ?Sized,
|
||||
{
|
||||
match row_ids {
|
||||
None => Ok(self.row_metas.to_vec()),
|
||||
Some(row_ids) => {
|
||||
let row_map = self
|
||||
.row_metas
|
||||
.iter()
|
||||
.map(|row| (&row.id, row.clone()))
|
||||
.collect::<HashMap<&String, Arc<RowMeta>>>();
|
||||
.map(|row| (row.id.as_str(), row.clone()))
|
||||
.collect::<HashMap<&str, Arc<RowMeta>>>();
|
||||
|
||||
Ok(row_ids
|
||||
.iter()
|
||||
.flat_map(|row_id| match row_map.get(row_id) {
|
||||
None => {
|
||||
tracing::error!("Can't find the row with id: {}", row_id);
|
||||
None
|
||||
.flat_map(|row_id| {
|
||||
let row_id = row_id.as_ref().as_ref();
|
||||
match row_map.get(row_id) {
|
||||
None => {
|
||||
tracing::error!("Can't find the row with id: {}", row_id);
|
||||
None
|
||||
}
|
||||
Some(row) => Some(row.clone()),
|
||||
}
|
||||
Some(row) => Some(row.clone()),
|
||||
})
|
||||
.collect::<Vec<_>>())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_cell_metas(&self, field_id: &str, row_ids: &Option<Vec<String>>) -> CollaborateResult<Vec<CellMeta>> {
|
||||
pub fn get_cell_metas(
|
||||
&self,
|
||||
field_id: &str,
|
||||
row_ids: Option<Vec<Cow<'_, String>>>,
|
||||
) -> CollaborateResult<Vec<CellMeta>> {
|
||||
let rows = self.get_row_metas(row_ids)?;
|
||||
let cell_metas = rows
|
||||
.iter()
|
||||
@ -227,6 +238,7 @@ impl std::default::Default for GridBlockMetaPad {
|
||||
mod tests {
|
||||
use crate::client_grid::{GridBlockMetaDelta, GridBlockMetaPad};
|
||||
use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset};
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[test]
|
||||
fn block_meta_add_row() {
|
||||
@ -331,7 +343,7 @@ mod tests {
|
||||
};
|
||||
|
||||
let _ = pad.add_row_meta(row.clone(), None).unwrap().unwrap();
|
||||
let change = pad.delete_rows(&[row.id]).unwrap().unwrap();
|
||||
let change = pad.delete_rows(vec![Cow::Borrowed(&row.id)]).unwrap().unwrap();
|
||||
assert_eq!(
|
||||
change.delta.to_delta_str(),
|
||||
r#"[{"retain":29},{"delete":77},{"retain":2}]"#
|
||||
|
Loading…
Reference in New Issue
Block a user