chore: rename struct

This commit is contained in:
appflowy 2022-03-10 17:14:10 +08:00
parent e45be3b81e
commit 7ac6a1dc89
72 changed files with 1788 additions and 785 deletions

View File

@ -13,6 +13,7 @@ import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
import 'package:get_it/get_it.dart'; import 'package:get_it/get_it.dart';

View File

@ -1,4 +1,5 @@
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async'; import 'dart:async';

View File

@ -1,4 +1,5 @@
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async'; import 'dart:async';

View File

@ -1,4 +1,5 @@
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async'; import 'dart:async';

View File

@ -1,4 +1,5 @@
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async'; import 'dart:async';

View File

@ -1,4 +1,5 @@
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async'; import 'dart:async';

View File

@ -1,4 +1,4 @@
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async'; import 'dart:async';

View File

@ -1,5 +1,6 @@
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
class GridInfo { class GridInfo {
List<Row> rows; List<Row> rows;

View File

@ -3,6 +3,7 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
class GridService { class GridService {
Future<Either<Grid, FlowyError>> openGrid({required String gridId}) async { Future<Either<Grid, FlowyError>> openGrid({required String gridId}) async {

View File

@ -6,7 +6,7 @@ import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_scrollview.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_scrollview.dart';
import 'package:flowy_infra_ui/widget/error_page.dart'; import 'package:flowy_infra_ui/widget/error_page.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';

View File

@ -1,4 +1,4 @@
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'sizes.dart'; import 'sizes.dart';

View File

@ -1,4 +1,5 @@
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'checkbox_cell.dart'; import 'checkbox_cell.dart';
import 'date_cell.dart'; import 'date_cell.dart';

View File

@ -1,6 +1,5 @@
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra/theme.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';

View File

@ -1,6 +1,7 @@
import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';

View File

@ -1,6 +1,7 @@
import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';

View File

@ -1,6 +1,7 @@
import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';

View File

@ -1,6 +1,7 @@
import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SingleSelectCell extends StatefulWidget { class SingleSelectCell extends StatefulWidget {

View File

@ -1,6 +1,7 @@
import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';

View File

@ -5,7 +5,7 @@ import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';

View File

@ -2,7 +2,7 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.d
import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';

View File

@ -22,7 +22,6 @@ import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart';
import 'package:flowy_sdk/protobuf/dart-ffi/protobuf.dart'; import 'package:flowy_sdk/protobuf/dart-ffi/protobuf.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/protobuf.dart';
import 'package:flowy_sdk/protobuf/flowy-block/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-block/protobuf.dart';
import 'package:flowy_sdk/protobuf/flowy-collaboration/protobuf.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart';
// ignore: unused_import // ignore: unused_import

View File

@ -1,5 +1,5 @@
// Auto-generated, do not edit // Auto-generated, do not edit
export './folder_info.pb.dart'; export './folder_info.pb.dart';
export './ws_data.pb.dart'; export './ws_data.pb.dart';
export './text_block_info.pb.dart';
export './revision.pb.dart'; export './revision.pb.dart';
export './document_info.pb.dart';

View File

@ -0,0 +1,412 @@
///
// Generated code. Do not modify.
// source: text_block_info.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
import 'dart:core' as $core;
import 'package:fixnum/fixnum.dart' as $fixnum;
import 'package:protobuf/protobuf.dart' as $pb;
import 'revision.pb.dart' as $0;
class CreateTextBlockParams extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateTextBlockParams', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
..aOM<$0.RepeatedRevision>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revisions', subBuilder: $0.RepeatedRevision.create)
..hasRequiredFields = false
;
CreateTextBlockParams._() : super();
factory CreateTextBlockParams({
$core.String? id,
$0.RepeatedRevision? revisions,
}) {
final _result = create();
if (id != null) {
_result.id = id;
}
if (revisions != null) {
_result.revisions = revisions;
}
return _result;
}
factory CreateTextBlockParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory CreateTextBlockParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
CreateTextBlockParams clone() => CreateTextBlockParams()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
CreateTextBlockParams copyWith(void Function(CreateTextBlockParams) updates) => super.copyWith((message) => updates(message as CreateTextBlockParams)) as CreateTextBlockParams; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static CreateTextBlockParams create() => CreateTextBlockParams._();
CreateTextBlockParams createEmptyInstance() => create();
static $pb.PbList<CreateTextBlockParams> createRepeated() => $pb.PbList<CreateTextBlockParams>();
@$core.pragma('dart2js:noInline')
static CreateTextBlockParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CreateTextBlockParams>(create);
static CreateTextBlockParams? _defaultInstance;
@$pb.TagNumber(1)
$core.String get id => $_getSZ(0);
@$pb.TagNumber(1)
set id($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasId() => $_has(0);
@$pb.TagNumber(1)
void clearId() => clearField(1);
@$pb.TagNumber(2)
$0.RepeatedRevision get revisions => $_getN(1);
@$pb.TagNumber(2)
set revisions($0.RepeatedRevision v) { setField(2, v); }
@$pb.TagNumber(2)
$core.bool hasRevisions() => $_has(1);
@$pb.TagNumber(2)
void clearRevisions() => clearField(2);
@$pb.TagNumber(2)
$0.RepeatedRevision ensureRevisions() => $_ensure(1);
}
class TextBlockInfo extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TextBlockInfo', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId')
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'text')
..aInt64(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revId')
..aInt64(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'baseRevId')
..hasRequiredFields = false
;
TextBlockInfo._() : super();
factory TextBlockInfo({
$core.String? blockId,
$core.String? text,
$fixnum.Int64? revId,
$fixnum.Int64? baseRevId,
}) {
final _result = create();
if (blockId != null) {
_result.blockId = blockId;
}
if (text != null) {
_result.text = text;
}
if (revId != null) {
_result.revId = revId;
}
if (baseRevId != null) {
_result.baseRevId = baseRevId;
}
return _result;
}
factory TextBlockInfo.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory TextBlockInfo.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
TextBlockInfo clone() => TextBlockInfo()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
TextBlockInfo copyWith(void Function(TextBlockInfo) updates) => super.copyWith((message) => updates(message as TextBlockInfo)) as TextBlockInfo; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static TextBlockInfo create() => TextBlockInfo._();
TextBlockInfo createEmptyInstance() => create();
static $pb.PbList<TextBlockInfo> createRepeated() => $pb.PbList<TextBlockInfo>();
@$core.pragma('dart2js:noInline')
static TextBlockInfo getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TextBlockInfo>(create);
static TextBlockInfo? _defaultInstance;
@$pb.TagNumber(1)
$core.String get blockId => $_getSZ(0);
@$pb.TagNumber(1)
set blockId($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasBlockId() => $_has(0);
@$pb.TagNumber(1)
void clearBlockId() => clearField(1);
@$pb.TagNumber(2)
$core.String get text => $_getSZ(1);
@$pb.TagNumber(2)
set text($core.String v) { $_setString(1, v); }
@$pb.TagNumber(2)
$core.bool hasText() => $_has(1);
@$pb.TagNumber(2)
void clearText() => clearField(2);
@$pb.TagNumber(3)
$fixnum.Int64 get revId => $_getI64(2);
@$pb.TagNumber(3)
set revId($fixnum.Int64 v) { $_setInt64(2, v); }
@$pb.TagNumber(3)
$core.bool hasRevId() => $_has(2);
@$pb.TagNumber(3)
void clearRevId() => clearField(3);
@$pb.TagNumber(4)
$fixnum.Int64 get baseRevId => $_getI64(3);
@$pb.TagNumber(4)
set baseRevId($fixnum.Int64 v) { $_setInt64(3, v); }
@$pb.TagNumber(4)
$core.bool hasBaseRevId() => $_has(3);
@$pb.TagNumber(4)
void clearBaseRevId() => clearField(4);
}
class ResetTextBlockParams extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ResetTextBlockParams', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId')
..aOM<$0.RepeatedRevision>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revisions', subBuilder: $0.RepeatedRevision.create)
..hasRequiredFields = false
;
ResetTextBlockParams._() : super();
factory ResetTextBlockParams({
$core.String? blockId,
$0.RepeatedRevision? revisions,
}) {
final _result = create();
if (blockId != null) {
_result.blockId = blockId;
}
if (revisions != null) {
_result.revisions = revisions;
}
return _result;
}
factory ResetTextBlockParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory ResetTextBlockParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
ResetTextBlockParams clone() => ResetTextBlockParams()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
ResetTextBlockParams copyWith(void Function(ResetTextBlockParams) updates) => super.copyWith((message) => updates(message as ResetTextBlockParams)) as ResetTextBlockParams; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static ResetTextBlockParams create() => ResetTextBlockParams._();
ResetTextBlockParams createEmptyInstance() => create();
static $pb.PbList<ResetTextBlockParams> createRepeated() => $pb.PbList<ResetTextBlockParams>();
@$core.pragma('dart2js:noInline')
static ResetTextBlockParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ResetTextBlockParams>(create);
static ResetTextBlockParams? _defaultInstance;
@$pb.TagNumber(1)
$core.String get blockId => $_getSZ(0);
@$pb.TagNumber(1)
set blockId($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasBlockId() => $_has(0);
@$pb.TagNumber(1)
void clearBlockId() => clearField(1);
@$pb.TagNumber(2)
$0.RepeatedRevision get revisions => $_getN(1);
@$pb.TagNumber(2)
set revisions($0.RepeatedRevision v) { setField(2, v); }
@$pb.TagNumber(2)
$core.bool hasRevisions() => $_has(1);
@$pb.TagNumber(2)
void clearRevisions() => clearField(2);
@$pb.TagNumber(2)
$0.RepeatedRevision ensureRevisions() => $_ensure(1);
}
class TextBlockDelta extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TextBlockDelta', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId')
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deltaStr')
..hasRequiredFields = false
;
TextBlockDelta._() : super();
factory TextBlockDelta({
$core.String? blockId,
$core.String? deltaStr,
}) {
final _result = create();
if (blockId != null) {
_result.blockId = blockId;
}
if (deltaStr != null) {
_result.deltaStr = deltaStr;
}
return _result;
}
factory TextBlockDelta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory TextBlockDelta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
TextBlockDelta clone() => TextBlockDelta()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
TextBlockDelta copyWith(void Function(TextBlockDelta) updates) => super.copyWith((message) => updates(message as TextBlockDelta)) as TextBlockDelta; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static TextBlockDelta create() => TextBlockDelta._();
TextBlockDelta createEmptyInstance() => create();
static $pb.PbList<TextBlockDelta> createRepeated() => $pb.PbList<TextBlockDelta>();
@$core.pragma('dart2js:noInline')
static TextBlockDelta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TextBlockDelta>(create);
static TextBlockDelta? _defaultInstance;
@$pb.TagNumber(1)
$core.String get blockId => $_getSZ(0);
@$pb.TagNumber(1)
set blockId($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasBlockId() => $_has(0);
@$pb.TagNumber(1)
void clearBlockId() => clearField(1);
@$pb.TagNumber(2)
$core.String get deltaStr => $_getSZ(1);
@$pb.TagNumber(2)
set deltaStr($core.String v) { $_setString(1, v); }
@$pb.TagNumber(2)
$core.bool hasDeltaStr() => $_has(1);
@$pb.TagNumber(2)
void clearDeltaStr() => clearField(2);
}
class NewDocUser extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'NewDocUser', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'userId')
..aInt64(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revId')
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'docId')
..hasRequiredFields = false
;
NewDocUser._() : super();
factory NewDocUser({
$core.String? userId,
$fixnum.Int64? revId,
$core.String? docId,
}) {
final _result = create();
if (userId != null) {
_result.userId = userId;
}
if (revId != null) {
_result.revId = revId;
}
if (docId != null) {
_result.docId = docId;
}
return _result;
}
factory NewDocUser.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory NewDocUser.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
NewDocUser clone() => NewDocUser()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
NewDocUser copyWith(void Function(NewDocUser) updates) => super.copyWith((message) => updates(message as NewDocUser)) as NewDocUser; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static NewDocUser create() => NewDocUser._();
NewDocUser createEmptyInstance() => create();
static $pb.PbList<NewDocUser> createRepeated() => $pb.PbList<NewDocUser>();
@$core.pragma('dart2js:noInline')
static NewDocUser getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<NewDocUser>(create);
static NewDocUser? _defaultInstance;
@$pb.TagNumber(1)
$core.String get userId => $_getSZ(0);
@$pb.TagNumber(1)
set userId($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasUserId() => $_has(0);
@$pb.TagNumber(1)
void clearUserId() => clearField(1);
@$pb.TagNumber(2)
$fixnum.Int64 get revId => $_getI64(1);
@$pb.TagNumber(2)
set revId($fixnum.Int64 v) { $_setInt64(1, v); }
@$pb.TagNumber(2)
$core.bool hasRevId() => $_has(1);
@$pb.TagNumber(2)
void clearRevId() => clearField(2);
@$pb.TagNumber(3)
$core.String get docId => $_getSZ(2);
@$pb.TagNumber(3)
set docId($core.String v) { $_setString(2, v); }
@$pb.TagNumber(3)
$core.bool hasDocId() => $_has(2);
@$pb.TagNumber(3)
void clearDocId() => clearField(3);
}
class TextBlockId extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TextBlockId', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value')
..hasRequiredFields = false
;
TextBlockId._() : super();
factory TextBlockId({
$core.String? value,
}) {
final _result = create();
if (value != null) {
_result.value = value;
}
return _result;
}
factory TextBlockId.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory TextBlockId.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
TextBlockId clone() => TextBlockId()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
TextBlockId copyWith(void Function(TextBlockId) updates) => super.copyWith((message) => updates(message as TextBlockId)) as TextBlockId; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static TextBlockId create() => TextBlockId._();
TextBlockId createEmptyInstance() => create();
static $pb.PbList<TextBlockId> createRepeated() => $pb.PbList<TextBlockId>();
@$core.pragma('dart2js:noInline')
static TextBlockId getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TextBlockId>(create);
static TextBlockId? _defaultInstance;
@$pb.TagNumber(1)
$core.String get value => $_getSZ(0);
@$pb.TagNumber(1)
set value($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasValue() => $_has(0);
@$pb.TagNumber(1)
void clearValue() => clearField(1);
}

View File

@ -0,0 +1,7 @@
///
// Generated code. Do not modify.
// source: text_block_info.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields

View File

@ -0,0 +1,78 @@
///
// Generated code. Do not modify.
// source: text_block_info.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
import 'dart:core' as $core;
import 'dart:convert' as $convert;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use createTextBlockParamsDescriptor instead')
const CreateTextBlockParams$json = const {
'1': 'CreateTextBlockParams',
'2': const [
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
const {'1': 'revisions', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRevision', '10': 'revisions'},
],
};
/// Descriptor for `CreateTextBlockParams`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List createTextBlockParamsDescriptor = $convert.base64Decode('ChVDcmVhdGVUZXh0QmxvY2tQYXJhbXMSDgoCaWQYASABKAlSAmlkEi8KCXJldmlzaW9ucxgCIAEoCzIRLlJlcGVhdGVkUmV2aXNpb25SCXJldmlzaW9ucw==');
@$core.Deprecated('Use textBlockInfoDescriptor instead')
const TextBlockInfo$json = const {
'1': 'TextBlockInfo',
'2': const [
const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'},
const {'1': 'text', '3': 2, '4': 1, '5': 9, '10': 'text'},
const {'1': 'rev_id', '3': 3, '4': 1, '5': 3, '10': 'revId'},
const {'1': 'base_rev_id', '3': 4, '4': 1, '5': 3, '10': 'baseRevId'},
],
};
/// Descriptor for `TextBlockInfo`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List textBlockInfoDescriptor = $convert.base64Decode('Cg1UZXh0QmxvY2tJbmZvEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEhIKBHRleHQYAiABKAlSBHRleHQSFQoGcmV2X2lkGAMgASgDUgVyZXZJZBIeCgtiYXNlX3Jldl9pZBgEIAEoA1IJYmFzZVJldklk');
@$core.Deprecated('Use resetTextBlockParamsDescriptor instead')
const ResetTextBlockParams$json = const {
'1': 'ResetTextBlockParams',
'2': const [
const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'},
const {'1': 'revisions', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRevision', '10': 'revisions'},
],
};
/// Descriptor for `ResetTextBlockParams`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List resetTextBlockParamsDescriptor = $convert.base64Decode('ChRSZXNldFRleHRCbG9ja1BhcmFtcxIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIvCglyZXZpc2lvbnMYAiABKAsyES5SZXBlYXRlZFJldmlzaW9uUglyZXZpc2lvbnM=');
@$core.Deprecated('Use textBlockDeltaDescriptor instead')
const TextBlockDelta$json = const {
'1': 'TextBlockDelta',
'2': const [
const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'},
const {'1': 'delta_str', '3': 2, '4': 1, '5': 9, '10': 'deltaStr'},
],
};
/// Descriptor for `TextBlockDelta`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List textBlockDeltaDescriptor = $convert.base64Decode('Cg5UZXh0QmxvY2tEZWx0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIbCglkZWx0YV9zdHIYAiABKAlSCGRlbHRhU3Ry');
@$core.Deprecated('Use newDocUserDescriptor instead')
const NewDocUser$json = const {
'1': 'NewDocUser',
'2': const [
const {'1': 'user_id', '3': 1, '4': 1, '5': 9, '10': 'userId'},
const {'1': 'rev_id', '3': 2, '4': 1, '5': 3, '10': 'revId'},
const {'1': 'doc_id', '3': 3, '4': 1, '5': 9, '10': 'docId'},
],
};
/// Descriptor for `NewDocUser`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List newDocUserDescriptor = $convert.base64Decode('CgpOZXdEb2NVc2VyEhcKB3VzZXJfaWQYASABKAlSBnVzZXJJZBIVCgZyZXZfaWQYAiABKANSBXJldklkEhUKBmRvY19pZBgDIAEoCVIFZG9jSWQ=');
@$core.Deprecated('Use textBlockIdDescriptor instead')
const TextBlockId$json = const {
'1': 'TextBlockId',
'2': const [
const {'1': 'value', '3': 1, '4': 1, '5': 9, '10': 'value'},
],
};
/// Descriptor for `TextBlockId`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List textBlockIdDescriptor = $convert.base64Decode('CgtUZXh0QmxvY2tJZBIUCgV2YWx1ZRgBIAEoCVIFdmFsdWU=');

View File

@ -0,0 +1,9 @@
///
// Generated code. Do not modify.
// source: text_block_info.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
export 'text_block_info.pb.dart';

View File

@ -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) 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') ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
..pc<Field>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: Field.create) ..pc<Field>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: Field.create)
..pc<RowMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) ..pc<Block>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: Block.create)
..hasRequiredFields = false ..hasRequiredFields = false
; ;
@ -25,7 +25,7 @@ class GridMeta extends $pb.GeneratedMessage {
factory GridMeta({ factory GridMeta({
$core.String? gridId, $core.String? gridId,
$core.Iterable<Field>? fields, $core.Iterable<Field>? fields,
$core.Iterable<RowMeta>? rows, $core.Iterable<Block>? blocks,
}) { }) {
final _result = create(); final _result = create();
if (gridId != null) { if (gridId != null) {
@ -34,8 +34,8 @@ class GridMeta extends $pb.GeneratedMessage {
if (fields != null) { if (fields != null) {
_result.fields.addAll(fields); _result.fields.addAll(fields);
} }
if (rows != null) { if (blocks != null) {
_result.rows.addAll(rows); _result.blocks.addAll(blocks);
} }
return _result; return _result;
} }
@ -73,50 +73,55 @@ class GridMeta extends $pb.GeneratedMessage {
$core.List<Field> get fields => $_getList(1); $core.List<Field> get fields => $_getList(1);
@$pb.TagNumber(3) @$pb.TagNumber(3)
$core.List<RowMeta> get rows => $_getList(2); $core.List<Block> get blocks => $_getList(2);
} }
class GridBlock extends $pb.GeneratedMessage { class Block extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Block', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
..pc<RowMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startRowIndex', $pb.PbFieldType.O3)
..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowCount', $pb.PbFieldType.O3)
..hasRequiredFields = false ..hasRequiredFields = false
; ;
GridBlock._() : super(); Block._() : super();
factory GridBlock({ factory Block({
$core.String? id, $core.String? id,
$core.Iterable<RowMeta>? rows, $core.int? startRowIndex,
$core.int? rowCount,
}) { }) {
final _result = create(); final _result = create();
if (id != null) { if (id != null) {
_result.id = id; _result.id = id;
} }
if (rows != null) { if (startRowIndex != null) {
_result.rows.addAll(rows); _result.startRowIndex = startRowIndex;
}
if (rowCount != null) {
_result.rowCount = rowCount;
} }
return _result; return _result;
} }
factory GridBlock.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); factory Block.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory GridBlock.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); factory Block.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated( @$core.Deprecated(
'Using this can add significant overhead to your binary. ' 'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version') 'Will be removed in next major version')
GridBlock clone() => GridBlock()..mergeFromMessage(this); Block clone() => Block()..mergeFromMessage(this);
@$core.Deprecated( @$core.Deprecated(
'Using this can add significant overhead to your binary. ' 'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version') 'Will be removed in next major version')
GridBlock copyWith(void Function(GridBlock) updates) => super.copyWith((message) => updates(message as GridBlock)) as GridBlock; // ignore: deprecated_member_use Block copyWith(void Function(Block) updates) => super.copyWith((message) => updates(message as Block)) as Block; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i; $pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline') @$core.pragma('dart2js:noInline')
static GridBlock create() => GridBlock._(); static Block create() => Block._();
GridBlock createEmptyInstance() => create(); Block createEmptyInstance() => create();
static $pb.PbList<GridBlock> createRepeated() => $pb.PbList<GridBlock>(); static $pb.PbList<Block> createRepeated() => $pb.PbList<Block>();
@$core.pragma('dart2js:noInline') @$core.pragma('dart2js:noInline')
static GridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GridBlock>(create); static Block getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Block>(create);
static GridBlock? _defaultInstance; static Block? _defaultInstance;
@$pb.TagNumber(1) @$pb.TagNumber(1)
$core.String get id => $_getSZ(0); $core.String get id => $_getSZ(0);
@ -127,6 +132,76 @@ class GridBlock extends $pb.GeneratedMessage {
@$pb.TagNumber(1) @$pb.TagNumber(1)
void clearId() => clearField(1); void clearId() => clearField(1);
@$pb.TagNumber(2)
$core.int get startRowIndex => $_getIZ(1);
@$pb.TagNumber(2)
set startRowIndex($core.int v) { $_setSignedInt32(1, v); }
@$pb.TagNumber(2)
$core.bool hasStartRowIndex() => $_has(1);
@$pb.TagNumber(2)
void clearStartRowIndex() => clearField(2);
@$pb.TagNumber(3)
$core.int get rowCount => $_getIZ(2);
@$pb.TagNumber(3)
set rowCount($core.int v) { $_setSignedInt32(2, v); }
@$pb.TagNumber(3)
$core.bool hasRowCount() => $_has(2);
@$pb.TagNumber(3)
void clearRowCount() => clearField(3);
}
class BlockMeta extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlockMeta', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId')
..pc<RowMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create)
..hasRequiredFields = false
;
BlockMeta._() : super();
factory BlockMeta({
$core.String? blockId,
$core.Iterable<RowMeta>? rows,
}) {
final _result = create();
if (blockId != null) {
_result.blockId = blockId;
}
if (rows != null) {
_result.rows.addAll(rows);
}
return _result;
}
factory BlockMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory BlockMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
BlockMeta clone() => BlockMeta()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
BlockMeta copyWith(void Function(BlockMeta) updates) => super.copyWith((message) => updates(message as BlockMeta)) as BlockMeta; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static BlockMeta create() => BlockMeta._();
BlockMeta createEmptyInstance() => create();
static $pb.PbList<BlockMeta> createRepeated() => $pb.PbList<BlockMeta>();
@$core.pragma('dart2js:noInline')
static BlockMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BlockMeta>(create);
static BlockMeta? _defaultInstance;
@$pb.TagNumber(1)
$core.String get blockId => $_getSZ(0);
@$pb.TagNumber(1)
set blockId($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasBlockId() => $_has(0);
@$pb.TagNumber(1)
void clearBlockId() => clearField(1);
@$pb.TagNumber(2) @$pb.TagNumber(2)
$core.List<RowMeta> get rows => $_getList(1); $core.List<RowMeta> get rows => $_getList(1);
} }

View File

@ -29,23 +29,35 @@ const GridMeta$json = const {
'2': const [ '2': const [
const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.Field', '10': 'fields'}, const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.Field', '10': 'fields'},
const {'1': 'rows', '3': 3, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.Block', '10': 'blocks'},
], ],
}; };
/// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. /// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIcCgRyb3dzGAMgAygLMgguUm93TWV0YVIEcm93cw=='); final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIeCgZibG9ja3MYAyADKAsyBi5CbG9ja1IGYmxvY2tz');
@$core.Deprecated('Use gridBlockDescriptor instead') @$core.Deprecated('Use blockDescriptor instead')
const GridBlock$json = const { const Block$json = const {
'1': 'GridBlock', '1': 'Block',
'2': const [ '2': const [
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
const {'1': 'start_row_index', '3': 2, '4': 1, '5': 5, '10': 'startRowIndex'},
const {'1': 'row_count', '3': 3, '4': 1, '5': 5, '10': 'rowCount'},
],
};
/// Descriptor for `Block`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List blockDescriptor = $convert.base64Decode('CgVCbG9jaxIOCgJpZBgBIAEoCVICaWQSJgoPc3RhcnRfcm93X2luZGV4GAIgASgFUg1zdGFydFJvd0luZGV4EhsKCXJvd19jb3VudBgDIAEoBVIIcm93Q291bnQ=');
@$core.Deprecated('Use blockMetaDescriptor instead')
const BlockMeta$json = const {
'1': 'BlockMeta',
'2': const [
const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'},
const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'},
], ],
}; };
/// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. /// Descriptor for `BlockMeta`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSDgoCaWQYASABKAlSAmlkEhwKBHJvd3MYAiADKAsyCC5Sb3dNZXRhUgRyb3dz'); final $typed_data.Uint8List blockMetaDescriptor = $convert.base64Decode('CglCbG9ja01ldGESGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSHAoEcm93cxgCIAMoCzIILlJvd01ldGFSBHJvd3M=');
@$core.Deprecated('Use fieldDescriptor instead') @$core.Deprecated('Use fieldDescriptor instead')
const Field$json = const { const Field$json = const {
'1': 'Field', '1': 'Field',

View File

@ -3,12 +3,12 @@ use crate::web_socket::{make_block_ws_manager, EditorCommandSender};
use crate::{ use crate::{
errors::FlowyError, errors::FlowyError,
queue::{EditBlockQueue, EditorCommand}, queue::{EditBlockQueue, EditorCommand},
BlockUser, TextBlockUser,
}; };
use bytes::Bytes; use bytes::Bytes;
use flowy_collaboration::entities::ws_data::ServerRevisionWSData; use flowy_collaboration::entities::ws_data::ServerRevisionWSData;
use flowy_collaboration::{ use flowy_collaboration::{
entities::{document_info::BlockInfo, revision::Revision}, entities::{revision::Revision, text_block_info::TextBlockInfo},
errors::CollaborateResult, errors::CollaborateResult,
util::make_delta_from_revisions, util::make_delta_from_revisions,
}; };
@ -24,7 +24,7 @@ use lib_ws::WSConnectState;
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::{mpsc, oneshot}; use tokio::sync::{mpsc, oneshot};
pub struct ClientBlockEditor { pub struct ClientTextBlockEditor {
pub doc_id: String, pub doc_id: String,
#[allow(dead_code)] #[allow(dead_code)]
rev_manager: Arc<RevisionManager>, rev_manager: Arc<RevisionManager>,
@ -32,10 +32,10 @@ pub struct ClientBlockEditor {
edit_cmd_tx: EditorCommandSender, edit_cmd_tx: EditorCommandSender,
} }
impl ClientBlockEditor { impl ClientTextBlockEditor {
pub(crate) async fn new( pub(crate) async fn new(
doc_id: &str, doc_id: &str,
user: Arc<dyn BlockUser>, user: Arc<dyn TextBlockUser>,
mut rev_manager: RevisionManager, mut rev_manager: RevisionManager,
rev_web_socket: Arc<dyn RevisionWebSocket>, rev_web_socket: Arc<dyn RevisionWebSocket>,
cloud_service: Arc<dyn RevisionCloudService>, cloud_service: Arc<dyn RevisionCloudService>,
@ -174,7 +174,7 @@ impl ClientBlockEditor {
} }
} }
impl std::ops::Drop for ClientBlockEditor { impl std::ops::Drop for ClientTextBlockEditor {
fn drop(&mut self) { fn drop(&mut self) {
tracing::trace!("{} ClientBlockEditor was dropped", self.doc_id) tracing::trace!("{} ClientBlockEditor was dropped", self.doc_id)
} }
@ -182,7 +182,7 @@ impl std::ops::Drop for ClientBlockEditor {
// The edit queue will exit after the EditorCommandSender was dropped. // The edit queue will exit after the EditorCommandSender was dropped.
fn spawn_edit_queue( fn spawn_edit_queue(
user: Arc<dyn BlockUser>, user: Arc<dyn TextBlockUser>,
rev_manager: Arc<RevisionManager>, rev_manager: Arc<RevisionManager>,
delta: RichTextDelta, delta: RichTextDelta,
) -> EditorCommandSender { ) -> EditorCommandSender {
@ -193,7 +193,7 @@ fn spawn_edit_queue(
} }
#[cfg(feature = "flowy_unit_test")] #[cfg(feature = "flowy_unit_test")]
impl ClientBlockEditor { impl ClientTextBlockEditor {
pub async fn doc_json(&self) -> FlowyResult<String> { pub async fn doc_json(&self) -> FlowyResult<String> {
let (ret, rx) = oneshot::channel::<CollaborateResult<String>>(); let (ret, rx) = oneshot::channel::<CollaborateResult<String>>();
let msg = EditorCommand::ReadDeltaStr { ret }; let msg = EditorCommand::ReadDeltaStr { ret };
@ -217,14 +217,14 @@ impl ClientBlockEditor {
struct BlockInfoBuilder(); struct BlockInfoBuilder();
impl RevisionObjectBuilder for BlockInfoBuilder { impl RevisionObjectBuilder for BlockInfoBuilder {
type Output = BlockInfo; type Output = TextBlockInfo;
fn build_object(object_id: &str, revisions: Vec<Revision>) -> FlowyResult<Self::Output> { fn build_object(object_id: &str, revisions: Vec<Revision>) -> FlowyResult<Self::Output> {
let (base_rev_id, rev_id) = revisions.last().unwrap().pair_rev_id(); let (base_rev_id, rev_id) = revisions.last().unwrap().pair_rev_id();
let mut delta = make_delta_from_revisions(revisions)?; let mut delta = make_delta_from_revisions(revisions)?;
correct_delta(&mut delta); correct_delta(&mut delta);
Result::<BlockInfo, FlowyError>::Ok(BlockInfo { Result::<TextBlockInfo, FlowyError>::Ok(TextBlockInfo {
block_id: object_id.to_owned(), block_id: object_id.to_owned(),
text: delta.to_delta_str(), text: delta.to_delta_str(),
rev_id, rev_id,

View File

@ -1,28 +1,28 @@
use crate::entities::{ExportData, ExportParams, ExportPayload}; use crate::entities::{ExportData, ExportParams, ExportPayload};
use crate::BlockManager; use crate::TextBlockManager;
use flowy_collaboration::entities::document_info::{BlockDelta, BlockId}; use flowy_collaboration::entities::text_block_info::{TextBlockDelta, TextBlockId};
use flowy_error::FlowyError; use flowy_error::FlowyError;
use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult};
use std::convert::TryInto; use std::convert::TryInto;
use std::sync::Arc; use std::sync::Arc;
pub(crate) async fn get_block_data_handler( pub(crate) async fn get_block_data_handler(
data: Data<BlockId>, data: Data<TextBlockId>,
manager: AppData<Arc<BlockManager>>, manager: AppData<Arc<TextBlockManager>>,
) -> DataResult<BlockDelta, FlowyError> { ) -> DataResult<TextBlockDelta, FlowyError> {
let block_id: BlockId = data.into_inner(); let block_id: TextBlockId = data.into_inner();
let editor = manager.open_block(&block_id).await?; let editor = manager.open_block(&block_id).await?;
let delta_str = editor.delta_str().await?; let delta_str = editor.delta_str().await?;
data_result(BlockDelta { data_result(TextBlockDelta {
block_id: block_id.into(), block_id: block_id.into(),
delta_str, delta_str,
}) })
} }
pub(crate) async fn apply_delta_handler( pub(crate) async fn apply_delta_handler(
data: Data<BlockDelta>, data: Data<TextBlockDelta>,
manager: AppData<Arc<BlockManager>>, manager: AppData<Arc<TextBlockManager>>,
) -> DataResult<BlockDelta, FlowyError> { ) -> DataResult<TextBlockDelta, FlowyError> {
let block_delta = manager.receive_local_delta(data.into_inner()).await?; let block_delta = manager.receive_local_delta(data.into_inner()).await?;
data_result(block_delta) data_result(block_delta)
} }
@ -30,7 +30,7 @@ pub(crate) async fn apply_delta_handler(
#[tracing::instrument(skip(data, manager), err)] #[tracing::instrument(skip(data, manager), err)]
pub(crate) async fn export_handler( pub(crate) async fn export_handler(
data: Data<ExportPayload>, data: Data<ExportPayload>,
manager: AppData<Arc<BlockManager>>, manager: AppData<Arc<TextBlockManager>>,
) -> DataResult<ExportData, FlowyError> { ) -> DataResult<ExportData, FlowyError> {
let params: ExportParams = data.into_inner().try_into()?; let params: ExportParams = data.into_inner().try_into()?;
let editor = manager.open_block(&params.view_id).await?; let editor = manager.open_block(&params.view_id).await?;

View File

@ -1,11 +1,11 @@
use crate::event_handler::*; use crate::event_handler::*;
use crate::BlockManager; use crate::TextBlockManager;
use flowy_derive::{Flowy_Event, ProtoBuf_Enum}; use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
use lib_dispatch::prelude::Module; use lib_dispatch::prelude::Module;
use std::sync::Arc; use std::sync::Arc;
use strum_macros::Display; use strum_macros::Display;
pub fn create(block_manager: Arc<BlockManager>) -> Module { pub fn create(block_manager: Arc<TextBlockManager>) -> Module {
let mut module = Module::new().name(env!("CARGO_PKG_NAME")).data(block_manager); let mut module = Module::new().name(env!("CARGO_PKG_NAME")).data(block_manager);
module = module module = module

View File

@ -1,4 +1,4 @@
pub mod block_editor; pub mod editor;
mod entities; mod entities;
mod event_handler; mod event_handler;
pub mod event_map; pub mod event_map;
@ -15,13 +15,15 @@ pub mod errors {
pub const DOCUMENT_SYNC_INTERVAL_IN_MILLIS: u64 = 1000; pub const DOCUMENT_SYNC_INTERVAL_IN_MILLIS: u64 = 1000;
use crate::errors::FlowyError; use crate::errors::FlowyError;
use flowy_collaboration::entities::document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams}; use flowy_collaboration::entities::text_block_info::{
CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo,
};
use lib_infra::future::FutureResult; use lib_infra::future::FutureResult;
pub trait BlockCloudService: Send + Sync { pub trait BlockCloudService: Send + Sync {
fn create_block(&self, token: &str, params: CreateBlockParams) -> FutureResult<(), FlowyError>; fn create_block(&self, token: &str, params: CreateTextBlockParams) -> FutureResult<(), FlowyError>;
fn read_block(&self, token: &str, params: BlockId) -> FutureResult<Option<BlockInfo>, FlowyError>; fn read_block(&self, token: &str, params: TextBlockId) -> FutureResult<Option<TextBlockInfo>, FlowyError>;
fn update_block(&self, token: &str, params: ResetBlockParams) -> FutureResult<(), FlowyError>; fn update_block(&self, token: &str, params: ResetTextBlockParams) -> FutureResult<(), FlowyError>;
} }

View File

@ -1,9 +1,9 @@
use crate::{block_editor::ClientBlockEditor, errors::FlowyError, BlockCloudService}; use crate::{editor::ClientTextBlockEditor, errors::FlowyError, BlockCloudService};
use bytes::Bytes; use bytes::Bytes;
use dashmap::DashMap; use dashmap::DashMap;
use flowy_collaboration::entities::{ use flowy_collaboration::entities::{
document_info::{BlockDelta, BlockId},
revision::{md5, RepeatedRevision, Revision}, revision::{md5, RepeatedRevision, Revision},
text_block_info::{TextBlockDelta, TextBlockId},
ws_data::ServerRevisionWSData, ws_data::ServerRevisionWSData,
}; };
use flowy_database::ConnectionPool; use flowy_database::ConnectionPool;
@ -12,43 +12,42 @@ use flowy_sync::{RevisionCloudService, RevisionManager, RevisionPersistence, Rev
use lib_infra::future::FutureResult; use lib_infra::future::FutureResult;
use std::{convert::TryInto, sync::Arc}; use std::{convert::TryInto, sync::Arc};
pub trait BlockUser: Send + Sync { pub trait TextBlockUser: Send + Sync {
fn user_dir(&self) -> Result<String, FlowyError>; fn user_dir(&self) -> Result<String, FlowyError>;
fn user_id(&self) -> Result<String, FlowyError>; fn user_id(&self) -> Result<String, FlowyError>;
fn token(&self) -> Result<String, FlowyError>; fn token(&self) -> Result<String, FlowyError>;
fn db_pool(&self) -> Result<Arc<ConnectionPool>, FlowyError>; fn db_pool(&self) -> Result<Arc<ConnectionPool>, FlowyError>;
} }
pub struct BlockManager { pub struct TextBlockManager {
cloud_service: Arc<dyn BlockCloudService>, cloud_service: Arc<dyn BlockCloudService>,
rev_web_socket: Arc<dyn RevisionWebSocket>, rev_web_socket: Arc<dyn RevisionWebSocket>,
block_editors: Arc<BlockEditors>, editor_map: Arc<TextBlockEditorMap>,
block_user: Arc<dyn BlockUser>, user: Arc<dyn TextBlockUser>,
} }
impl BlockManager { impl TextBlockManager {
pub fn new( pub fn new(
cloud_service: Arc<dyn BlockCloudService>, cloud_service: Arc<dyn BlockCloudService>,
block_user: Arc<dyn BlockUser>, text_block_user: Arc<dyn TextBlockUser>,
rev_web_socket: Arc<dyn RevisionWebSocket>, rev_web_socket: Arc<dyn RevisionWebSocket>,
) -> Self { ) -> Self {
let block_editors = Arc::new(BlockEditors::new());
Self { Self {
cloud_service, cloud_service,
rev_web_socket, rev_web_socket,
block_editors, editor_map: Arc::new(TextBlockEditorMap::new()),
block_user, user: text_block_user,
} }
} }
pub fn init(&self) -> FlowyResult<()> { pub fn init(&self) -> FlowyResult<()> {
listen_ws_state_changed(self.rev_web_socket.clone(), self.block_editors.clone()); listen_ws_state_changed(self.rev_web_socket.clone(), self.editor_map.clone());
Ok(()) Ok(())
} }
#[tracing::instrument(level = "debug", skip(self, block_id), fields(block_id), err)] #[tracing::instrument(level = "debug", skip(self, block_id), fields(block_id), err)]
pub async fn open_block<T: AsRef<str>>(&self, block_id: T) -> Result<Arc<ClientBlockEditor>, FlowyError> { pub async fn open_block<T: AsRef<str>>(&self, block_id: T) -> Result<Arc<ClientTextBlockEditor>, FlowyError> {
let block_id = block_id.as_ref(); let block_id = block_id.as_ref();
tracing::Span::current().record("block_id", &block_id); tracing::Span::current().record("block_id", &block_id);
self.get_block_editor(block_id).await self.get_block_editor(block_id).await
@ -58,7 +57,7 @@ impl BlockManager {
pub fn close_block<T: AsRef<str>>(&self, block_id: T) -> Result<(), FlowyError> { pub fn close_block<T: AsRef<str>>(&self, block_id: T) -> Result<(), FlowyError> {
let block_id = block_id.as_ref(); let block_id = block_id.as_ref();
tracing::Span::current().record("block_id", &block_id); tracing::Span::current().record("block_id", &block_id);
self.block_editors.remove(block_id); self.editor_map.remove(block_id);
Ok(()) Ok(())
} }
@ -66,16 +65,16 @@ impl BlockManager {
pub fn delete_block<T: AsRef<str>>(&self, doc_id: T) -> Result<(), FlowyError> { pub fn delete_block<T: AsRef<str>>(&self, doc_id: T) -> Result<(), FlowyError> {
let doc_id = doc_id.as_ref(); let doc_id = doc_id.as_ref();
tracing::Span::current().record("doc_id", &doc_id); tracing::Span::current().record("doc_id", &doc_id);
self.block_editors.remove(doc_id); self.editor_map.remove(doc_id);
Ok(()) Ok(())
} }
#[tracing::instrument(level = "debug", skip(self, delta), fields(doc_id = %delta.block_id), err)] #[tracing::instrument(level = "debug", skip(self, delta), fields(doc_id = %delta.block_id), err)]
pub async fn receive_local_delta(&self, delta: BlockDelta) -> Result<BlockDelta, FlowyError> { pub async fn receive_local_delta(&self, delta: TextBlockDelta) -> Result<TextBlockDelta, FlowyError> {
let editor = self.get_block_editor(&delta.block_id).await?; let editor = self.get_block_editor(&delta.block_id).await?;
let _ = editor.compose_local_delta(Bytes::from(delta.delta_str)).await?; let _ = editor.compose_local_delta(Bytes::from(delta.delta_str)).await?;
let document_json = editor.delta_str().await?; let document_json = editor.delta_str().await?;
Ok(BlockDelta { Ok(TextBlockDelta {
block_id: delta.block_id.clone(), block_id: delta.block_id.clone(),
delta_str: document_json, delta_str: document_json,
}) })
@ -83,7 +82,7 @@ impl BlockManager {
pub async fn create_block<T: AsRef<str>>(&self, doc_id: T, revisions: RepeatedRevision) -> FlowyResult<()> { pub async fn create_block<T: AsRef<str>>(&self, doc_id: T, revisions: RepeatedRevision) -> FlowyResult<()> {
let doc_id = doc_id.as_ref().to_owned(); let doc_id = doc_id.as_ref().to_owned();
let db_pool = self.block_user.db_pool()?; let db_pool = self.user.db_pool()?;
// Maybe we could save the block to disk without creating the RevisionManager // Maybe we could save the block to disk without creating the RevisionManager
let rev_manager = self.make_block_rev_manager(&doc_id, db_pool)?; let rev_manager = self.make_block_rev_manager(&doc_id, db_pool)?;
let _ = rev_manager.reset_object(revisions).await?; let _ = rev_manager.reset_object(revisions).await?;
@ -93,9 +92,9 @@ impl BlockManager {
pub async fn receive_ws_data(&self, data: Bytes) { pub async fn receive_ws_data(&self, data: Bytes) {
let result: Result<ServerRevisionWSData, protobuf::ProtobufError> = data.try_into(); let result: Result<ServerRevisionWSData, protobuf::ProtobufError> = data.try_into();
match result { match result {
Ok(data) => match self.block_editors.get(&data.object_id) { Ok(data) => match self.editor_map.get(&data.object_id) {
None => tracing::error!("Can't find any source handler for {:?}-{:?}", data.object_id, data.ty), None => tracing::error!("Can't find any source handler for {:?}-{:?}", data.object_id, data.ty),
Some(block_editor) => match block_editor.receive_ws_data(data).await { Some(editor) => match editor.receive_ws_data(data).await {
Ok(_) => {} Ok(_) => {}
Err(e) => tracing::error!("{}", e), Err(e) => tracing::error!("{}", e),
}, },
@ -107,11 +106,11 @@ impl BlockManager {
} }
} }
impl BlockManager { impl TextBlockManager {
async fn get_block_editor(&self, block_id: &str) -> FlowyResult<Arc<ClientBlockEditor>> { async fn get_block_editor(&self, block_id: &str) -> FlowyResult<Arc<ClientTextBlockEditor>> {
match self.block_editors.get(block_id) { match self.editor_map.get(block_id) {
None => { None => {
let db_pool = self.block_user.db_pool()?; let db_pool = self.user.db_pool()?;
self.make_block_editor(block_id, db_pool).await self.make_block_editor(block_id, db_pool).await
} }
Some(editor) => Ok(editor), Some(editor) => Ok(editor),
@ -122,36 +121,36 @@ impl BlockManager {
&self, &self,
block_id: &str, block_id: &str,
pool: Arc<ConnectionPool>, pool: Arc<ConnectionPool>,
) -> Result<Arc<ClientBlockEditor>, FlowyError> { ) -> Result<Arc<ClientTextBlockEditor>, FlowyError> {
let user = self.block_user.clone(); let user = self.user.clone();
let token = self.block_user.token()?; let token = self.user.token()?;
let rev_manager = self.make_block_rev_manager(block_id, pool.clone())?; let rev_manager = self.make_block_rev_manager(block_id, pool.clone())?;
let cloud_service = Arc::new(BlockRevisionCloudService { let cloud_service = Arc::new(TextBlockRevisionCloudService {
token, token,
server: self.cloud_service.clone(), server: self.cloud_service.clone(),
}); });
let doc_editor = let doc_editor =
ClientBlockEditor::new(block_id, user, rev_manager, self.rev_web_socket.clone(), cloud_service).await?; ClientTextBlockEditor::new(block_id, user, rev_manager, self.rev_web_socket.clone(), cloud_service).await?;
self.block_editors.insert(block_id, &doc_editor); self.editor_map.insert(block_id, &doc_editor);
Ok(doc_editor) Ok(doc_editor)
} }
fn make_block_rev_manager(&self, doc_id: &str, pool: Arc<ConnectionPool>) -> Result<RevisionManager, FlowyError> { fn make_block_rev_manager(&self, doc_id: &str, pool: Arc<ConnectionPool>) -> Result<RevisionManager, FlowyError> {
let user_id = self.block_user.user_id()?; let user_id = self.user.user_id()?;
let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, doc_id, pool)); let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, doc_id, pool));
Ok(RevisionManager::new(&user_id, doc_id, rev_persistence)) Ok(RevisionManager::new(&user_id, doc_id, rev_persistence))
} }
} }
struct BlockRevisionCloudService { struct TextBlockRevisionCloudService {
token: String, token: String,
server: Arc<dyn BlockCloudService>, server: Arc<dyn BlockCloudService>,
} }
impl RevisionCloudService for BlockRevisionCloudService { impl RevisionCloudService for TextBlockRevisionCloudService {
#[tracing::instrument(level = "trace", skip(self))] #[tracing::instrument(level = "trace", skip(self))]
fn fetch_object(&self, user_id: &str, object_id: &str) -> FutureResult<Vec<Revision>, FlowyError> { fn fetch_object(&self, user_id: &str, object_id: &str) -> FutureResult<Vec<Revision>, FlowyError> {
let params: BlockId = object_id.to_string().into(); let params: TextBlockId = object_id.to_string().into();
let server = self.server.clone(); let server = self.server.clone();
let token = self.token.clone(); let token = self.token.clone();
let user_id = user_id.to_string(); let user_id = user_id.to_string();
@ -177,32 +176,24 @@ impl RevisionCloudService for BlockRevisionCloudService {
} }
} }
pub struct BlockEditors { pub struct TextBlockEditorMap {
inner: DashMap<String, Arc<ClientBlockEditor>>, inner: DashMap<String, Arc<ClientTextBlockEditor>>,
} }
impl BlockEditors { impl TextBlockEditorMap {
fn new() -> Self { fn new() -> Self {
Self { inner: DashMap::new() } Self { inner: DashMap::new() }
} }
pub(crate) fn insert(&self, block_id: &str, doc: &Arc<ClientBlockEditor>) { pub(crate) fn insert(&self, block_id: &str, doc: &Arc<ClientTextBlockEditor>) {
if self.inner.contains_key(block_id) { if self.inner.contains_key(block_id) {
log::warn!("Doc:{} already exists in cache", block_id); log::warn!("Doc:{} already exists in cache", block_id);
} }
self.inner.insert(block_id.to_string(), doc.clone()); self.inner.insert(block_id.to_string(), doc.clone());
} }
pub(crate) fn contains(&self, block_id: &str) -> bool { pub(crate) fn get(&self, block_id: &str) -> Option<Arc<ClientTextBlockEditor>> {
self.inner.get(block_id).is_some() Some(self.inner.get(block_id)?.clone())
}
pub(crate) fn get(&self, block_id: &str) -> Option<Arc<ClientBlockEditor>> {
if !self.contains(block_id) {
return None;
}
let opened_doc = self.inner.get(block_id).unwrap();
Some(opened_doc.clone())
} }
pub(crate) fn remove(&self, block_id: &str) { pub(crate) fn remove(&self, block_id: &str) {
@ -214,7 +205,7 @@ impl BlockEditors {
} }
#[tracing::instrument(level = "trace", skip(web_socket, handlers))] #[tracing::instrument(level = "trace", skip(web_socket, handlers))]
fn listen_ws_state_changed(web_socket: Arc<dyn RevisionWebSocket>, handlers: Arc<BlockEditors>) { fn listen_ws_state_changed(web_socket: Arc<dyn RevisionWebSocket>, handlers: Arc<TextBlockEditorMap>) {
tokio::spawn(async move { tokio::spawn(async move {
let mut notify = web_socket.subscribe_state_changed().await; let mut notify = web_socket.subscribe_state_changed().await;
while let Ok(state) = notify.recv().await { while let Ok(state) = notify.recv().await {

View File

@ -1,5 +1,5 @@
use crate::web_socket::EditorCommandReceiver; use crate::web_socket::EditorCommandReceiver;
use crate::BlockUser; use crate::TextBlockUser;
use async_stream::stream; use async_stream::stream;
use flowy_collaboration::util::make_delta_from_revisions; use flowy_collaboration::util::make_delta_from_revisions;
use flowy_collaboration::{ use flowy_collaboration::{
@ -21,14 +21,14 @@ use tokio::sync::{oneshot, RwLock};
// serial. // serial.
pub(crate) struct EditBlockQueue { pub(crate) struct EditBlockQueue {
document: Arc<RwLock<ClientDocument>>, document: Arc<RwLock<ClientDocument>>,
user: Arc<dyn BlockUser>, user: Arc<dyn TextBlockUser>,
rev_manager: Arc<RevisionManager>, rev_manager: Arc<RevisionManager>,
receiver: Option<EditorCommandReceiver>, receiver: Option<EditorCommandReceiver>,
} }
impl EditBlockQueue { impl EditBlockQueue {
pub(crate) fn new( pub(crate) fn new(
user: Arc<dyn BlockUser>, user: Arc<dyn TextBlockUser>,
rev_manager: Arc<RevisionManager>, rev_manager: Arc<RevisionManager>,
delta: RichTextDelta, delta: RichTextDelta,
receiver: EditorCommandReceiver, receiver: EditorCommandReceiver,

View File

@ -31,11 +31,11 @@ pub(crate) async fn make_block_ws_manager(
rev_web_socket: Arc<dyn RevisionWebSocket>, rev_web_socket: Arc<dyn RevisionWebSocket>,
) -> Arc<RevisionWebSocketManager> { ) -> Arc<RevisionWebSocketManager> {
let ws_data_provider = Arc::new(WSDataProvider::new(&doc_id, Arc::new(rev_manager.clone()))); let ws_data_provider = Arc::new(WSDataProvider::new(&doc_id, Arc::new(rev_manager.clone())));
let resolver = Arc::new(BlockConflictResolver { edit_cmd_tx }); let resolver = Arc::new(TextBlockConflictResolver { edit_cmd_tx });
let conflict_controller = let conflict_controller =
RichTextConflictController::new(&user_id, resolver, Arc::new(ws_data_provider.clone()), rev_manager); RichTextConflictController::new(&user_id, resolver, Arc::new(ws_data_provider.clone()), rev_manager);
let ws_data_stream = Arc::new(BlockRevisionWSDataStream::new(conflict_controller)); let ws_data_stream = Arc::new(TextBlockRevisionWSDataStream::new(conflict_controller));
let ws_data_sink = Arc::new(BlockWSDataSink(ws_data_provider)); let ws_data_sink = Arc::new(TextBlockWSDataSink(ws_data_provider));
let ping_duration = Duration::from_millis(DOCUMENT_SYNC_INTERVAL_IN_MILLIS); let ping_duration = Duration::from_millis(DOCUMENT_SYNC_INTERVAL_IN_MILLIS);
let ws_manager = Arc::new(RevisionWebSocketManager::new( let ws_manager = Arc::new(RevisionWebSocketManager::new(
"Block", "Block",
@ -62,11 +62,11 @@ fn listen_document_ws_state(_user_id: &str, _doc_id: &str, mut subscriber: broad
}); });
} }
pub(crate) struct BlockRevisionWSDataStream { pub(crate) struct TextBlockRevisionWSDataStream {
conflict_controller: Arc<RichTextConflictController>, conflict_controller: Arc<RichTextConflictController>,
} }
impl BlockRevisionWSDataStream { impl TextBlockRevisionWSDataStream {
pub fn new(conflict_controller: RichTextConflictController) -> Self { pub fn new(conflict_controller: RichTextConflictController) -> Self {
Self { Self {
conflict_controller: Arc::new(conflict_controller), conflict_controller: Arc::new(conflict_controller),
@ -74,7 +74,7 @@ impl BlockRevisionWSDataStream {
} }
} }
impl RevisionWSDataStream for BlockRevisionWSDataStream { impl RevisionWSDataStream for TextBlockRevisionWSDataStream {
fn receive_push_revision(&self, bytes: Bytes) -> BoxResultFuture<(), FlowyError> { fn receive_push_revision(&self, bytes: Bytes) -> BoxResultFuture<(), FlowyError> {
let resolver = self.conflict_controller.clone(); let resolver = self.conflict_controller.clone();
Box::pin(async move { resolver.receive_bytes(bytes).await }) Box::pin(async move { resolver.receive_bytes(bytes).await })
@ -96,19 +96,19 @@ impl RevisionWSDataStream for BlockRevisionWSDataStream {
} }
} }
pub(crate) struct BlockWSDataSink(pub(crate) Arc<WSDataProvider>); pub(crate) struct TextBlockWSDataSink(pub(crate) Arc<WSDataProvider>);
impl RevisionWebSocketSink for BlockWSDataSink { impl RevisionWebSocketSink for TextBlockWSDataSink {
fn next(&self) -> FutureResult<Option<ClientRevisionWSData>, FlowyError> { fn next(&self) -> FutureResult<Option<ClientRevisionWSData>, FlowyError> {
let sink_provider = self.0.clone(); let sink_provider = self.0.clone();
FutureResult::new(async move { sink_provider.next().await }) FutureResult::new(async move { sink_provider.next().await })
} }
} }
struct BlockConflictResolver { struct TextBlockConflictResolver {
edit_cmd_tx: EditorCommandSender, edit_cmd_tx: EditorCommandSender,
} }
impl ConflictResolver<RichTextAttributes> for BlockConflictResolver { impl ConflictResolver<RichTextAttributes> for TextBlockConflictResolver {
fn compose_delta(&self, delta: RichTextDelta) -> BoxResultFuture<DeltaMD5, FlowyError> { fn compose_delta(&self, delta: RichTextDelta) -> BoxResultFuture<DeltaMD5, FlowyError> {
let tx = self.edit_cmd_tx.clone(); let tx = self.edit_cmd_tx.clone();
Box::pin(async move { Box::pin(async move {

View File

@ -1,4 +1,4 @@
use flowy_block::block_editor::ClientBlockEditor; use flowy_block::editor::ClientTextBlockEditor;
use flowy_block::DOCUMENT_SYNC_INTERVAL_IN_MILLIS; use flowy_block::DOCUMENT_SYNC_INTERVAL_IN_MILLIS;
use flowy_collaboration::entities::revision::RevisionState; use flowy_collaboration::entities::revision::RevisionState;
use flowy_test::{helper::ViewTest, FlowySDKTest}; use flowy_test::{helper::ViewTest, FlowySDKTest};
@ -19,7 +19,7 @@ pub enum EditorScript {
pub struct EditorTest { pub struct EditorTest {
pub sdk: FlowySDKTest, pub sdk: FlowySDKTest,
pub editor: Arc<ClientBlockEditor>, pub editor: Arc<ClientTextBlockEditor>,
} }
impl EditorTest { impl EditorTest {
@ -27,7 +27,7 @@ impl EditorTest {
let sdk = FlowySDKTest::default(); let sdk = FlowySDKTest::default();
let _ = sdk.init_user().await; let _ = sdk.init_user().await;
let test = ViewTest::new(&sdk).await; let test = ViewTest::new(&sdk).await;
let editor = sdk.block_manager.open_block(&test.view.id).await.unwrap(); let editor = sdk.text_block_manager.open_block(&test.view.id).await.unwrap();
Self { sdk, editor } Self { sdk, editor }
} }

View File

@ -1,2 +1,3 @@
-- This file should undo anything in `up.sql` -- This file should undo anything in `up.sql`
DROP TABLE kv_table; DROP TABLE kv_table;
DROP TABLE grid_rev_table;

View File

@ -2,4 +2,13 @@
CREATE TABLE kv_table ( CREATE TABLE kv_table (
key TEXT NOT NULL PRIMARY KEY, key TEXT NOT NULL PRIMARY KEY,
value BLOB NOT NULL DEFAULT (x'') value BLOB NOT NULL DEFAULT (x'')
);
CREATE TABLE grid_rev_table (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
object_id TEXT NOT NULL DEFAULT '',
base_rev_id BIGINT NOT NULL DEFAULT 0,
rev_id BIGINT NOT NULL DEFAULT 0,
data BLOB NOT NULL DEFAULT (x''),
state INTEGER NOT NULL DEFAULT 0
); );

View File

@ -14,8 +14,8 @@ use crate::{
}; };
use bytes::Bytes; use bytes::Bytes;
use flowy_collaboration::entities::{ use flowy_collaboration::entities::{
document_info::BlockId,
revision::{RepeatedRevision, Revision}, revision::{RepeatedRevision, Revision},
text_block_info::TextBlockId,
}; };
use flowy_database::kv::KV; use flowy_database::kv::KV;
use flowy_folder_data_model::entities::view::ViewDataType; use flowy_folder_data_model::entities::view::ViewDataType;
@ -147,7 +147,7 @@ impl ViewController {
} }
#[tracing::instrument(level = "debug", skip(self,params), fields(doc_id = %params.value), err)] #[tracing::instrument(level = "debug", skip(self,params), fields(doc_id = %params.value), err)]
pub(crate) async fn delete_view(&self, params: BlockId) -> Result<(), FlowyError> { pub(crate) async fn delete_view(&self, params: TextBlockId) -> Result<(), FlowyError> {
if let Some(view_id) = KV::get_str(LATEST_VIEW_ID) { if let Some(view_id) = KV::get_str(LATEST_VIEW_ID) {
if view_id == params.value { if view_id == params.value {
let _ = KV::remove(LATEST_VIEW_ID); let _ = KV::remove(LATEST_VIEW_ID);

View File

@ -1,4 +1,4 @@
use flowy_collaboration::entities::document_info::BlockInfo; use flowy_collaboration::entities::text_block_info::TextBlockInfo;
use flowy_folder::event_map::FolderEvent::*; use flowy_folder::event_map::FolderEvent::*;
use flowy_folder_data_model::entities::view::{RepeatedViewId, ViewId}; use flowy_folder_data_model::entities::view::{RepeatedViewId, ViewId};
use flowy_folder_data_model::entities::workspace::WorkspaceId; use flowy_folder_data_model::entities::workspace::WorkspaceId;
@ -161,14 +161,14 @@ pub async fn delete_view(sdk: &FlowySDKTest, view_ids: Vec<String>) {
.await; .await;
} }
pub async fn open_document(sdk: &FlowySDKTest, view_id: &str) -> BlockInfo { pub async fn open_document(sdk: &FlowySDKTest, view_id: &str) -> TextBlockInfo {
let view_id: ViewId = view_id.into(); let view_id: ViewId = view_id.into();
FolderEventBuilder::new(sdk.clone()) FolderEventBuilder::new(sdk.clone())
.event(SetLatestView) .event(SetLatestView)
.payload(view_id) .payload(view_id)
.async_send() .async_send()
.await .await
.parse::<BlockInfo>() .parse::<TextBlockInfo>()
} }
pub async fn read_trash(sdk: &FlowySDKTest) -> RepeatedTrash { pub async fn read_trash(sdk: &FlowySDKTest) -> RepeatedTrash {

View File

@ -1,5 +1,5 @@
use crate::helper::*; use crate::helper::*;
use flowy_collaboration::entities::{document_info::BlockInfo, revision::RevisionState}; use flowy_collaboration::entities::{revision::RevisionState, text_block_info::TextBlockInfo};
use flowy_folder::{errors::ErrorCode, services::folder_editor::ClientFolderEditor}; use flowy_folder::{errors::ErrorCode, services::folder_editor::ClientFolderEditor};
use flowy_folder_data_model::entities::{ use flowy_folder_data_model::entities::{
app::{App, RepeatedApp}, app::{App, RepeatedApp},
@ -58,7 +58,7 @@ pub struct FolderTest {
pub app: App, pub app: App,
pub view: View, pub view: View,
pub trash: Vec<Trash>, pub trash: Vec<Trash>,
pub document_info: Option<BlockInfo>, pub document_info: Option<TextBlockInfo>,
// pub folder_editor: // pub folder_editor:
} }

View File

@ -44,7 +44,7 @@ impl GridBuilder {
let grid_meta = GridMeta { let grid_meta = GridMeta {
grid_id: self.grid_id, grid_id: self.grid_id,
fields: self.fields, fields: self.fields,
rows: self.rows, blocks: vec![],
}; };
// let _ = check_rows(&self.fields, &self.rows)?; // let _ = check_rows(&self.fields, &self.rows)?;

View File

@ -3,7 +3,9 @@ use crate::{
request::{HttpRequestBuilder, ResponseMiddleware}, request::{HttpRequestBuilder, ResponseMiddleware},
}; };
use flowy_block::BlockCloudService; use flowy_block::BlockCloudService;
use flowy_collaboration::entities::document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams}; use flowy_collaboration::entities::text_block_info::{
CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo,
};
use flowy_error::FlowyError; use flowy_error::FlowyError;
use http_flowy::response::FlowyResponse; use http_flowy::response::FlowyResponse;
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -21,26 +23,26 @@ impl BlockHttpCloudService {
} }
impl BlockCloudService for BlockHttpCloudService { impl BlockCloudService for BlockHttpCloudService {
fn create_block(&self, token: &str, params: CreateBlockParams) -> FutureResult<(), FlowyError> { fn create_block(&self, token: &str, params: CreateTextBlockParams) -> FutureResult<(), FlowyError> {
let token = token.to_owned(); let token = token.to_owned();
let url = self.config.doc_url(); let url = self.config.doc_url();
FutureResult::new(async move { create_document_request(&token, params, &url).await }) FutureResult::new(async move { create_document_request(&token, params, &url).await })
} }
fn read_block(&self, token: &str, params: BlockId) -> FutureResult<Option<BlockInfo>, FlowyError> { fn read_block(&self, token: &str, params: TextBlockId) -> FutureResult<Option<TextBlockInfo>, FlowyError> {
let token = token.to_owned(); let token = token.to_owned();
let url = self.config.doc_url(); let url = self.config.doc_url();
FutureResult::new(async move { read_document_request(&token, params, &url).await }) FutureResult::new(async move { read_document_request(&token, params, &url).await })
} }
fn update_block(&self, token: &str, params: ResetBlockParams) -> FutureResult<(), FlowyError> { fn update_block(&self, token: &str, params: ResetTextBlockParams) -> FutureResult<(), FlowyError> {
let token = token.to_owned(); let token = token.to_owned();
let url = self.config.doc_url(); let url = self.config.doc_url();
FutureResult::new(async move { reset_doc_request(&token, params, &url).await }) FutureResult::new(async move { reset_doc_request(&token, params, &url).await })
} }
} }
pub async fn create_document_request(token: &str, params: CreateBlockParams, url: &str) -> Result<(), FlowyError> { pub async fn create_document_request(token: &str, params: CreateTextBlockParams, url: &str) -> Result<(), FlowyError> {
let _ = request_builder() let _ = request_builder()
.post(&url.to_owned()) .post(&url.to_owned())
.header(HEADER_TOKEN, token) .header(HEADER_TOKEN, token)
@ -50,7 +52,11 @@ pub async fn create_document_request(token: &str, params: CreateBlockParams, url
Ok(()) Ok(())
} }
pub async fn read_document_request(token: &str, params: BlockId, url: &str) -> Result<Option<BlockInfo>, FlowyError> { pub async fn read_document_request(
token: &str,
params: TextBlockId,
url: &str,
) -> Result<Option<TextBlockInfo>, FlowyError> {
let doc = request_builder() let doc = request_builder()
.get(&url.to_owned()) .get(&url.to_owned())
.header(HEADER_TOKEN, token) .header(HEADER_TOKEN, token)
@ -61,7 +67,7 @@ pub async fn read_document_request(token: &str, params: BlockId, url: &str) -> R
Ok(doc) Ok(doc)
} }
pub async fn reset_doc_request(token: &str, params: ResetBlockParams, url: &str) -> Result<(), FlowyError> { pub async fn reset_doc_request(token: &str, params: ResetTextBlockParams, url: &str) -> Result<(), FlowyError> {
let _ = request_builder() let _ = request_builder()
.patch(&url.to_owned()) .patch(&url.to_owned())
.header(HEADER_TOKEN, token) .header(HEADER_TOKEN, token)

View File

@ -1,5 +1,5 @@
use flowy_collaboration::{ use flowy_collaboration::{
entities::{document_info::BlockInfo, folder_info::FolderInfo}, entities::{folder_info::FolderInfo, text_block_info::TextBlockInfo},
errors::CollaborateError, errors::CollaborateError,
protobuf::{RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB}, protobuf::{RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB},
server_document::*, server_document::*,
@ -111,7 +111,7 @@ impl FolderCloudPersistence for LocalDocumentCloudPersistence {
} }
impl DocumentCloudPersistence for LocalDocumentCloudPersistence { impl DocumentCloudPersistence for LocalDocumentCloudPersistence {
fn read_document(&self, doc_id: &str) -> BoxResultFuture<BlockInfo, CollaborateError> { fn read_document(&self, doc_id: &str) -> BoxResultFuture<TextBlockInfo, CollaborateError> {
let storage = self.storage.clone(); let storage = self.storage.clone();
let doc_id = doc_id.to_owned(); let doc_id = doc_id.to_owned();
Box::pin(async move { Box::pin(async move {
@ -127,7 +127,7 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence {
&self, &self,
doc_id: &str, doc_id: &str,
repeated_revision: RepeatedRevisionPB, repeated_revision: RepeatedRevisionPB,
) -> BoxResultFuture<Option<BlockInfo>, CollaborateError> { ) -> BoxResultFuture<Option<TextBlockInfo>, CollaborateError> {
let doc_id = doc_id.to_owned(); let doc_id = doc_id.to_owned();
let storage = self.storage.clone(); let storage = self.storage.clone();
Box::pin(async move { Box::pin(async move {

View File

@ -4,7 +4,7 @@ use bytes::Bytes;
use flowy_collaboration::{ use flowy_collaboration::{
client_document::default::initial_quill_delta_string, client_document::default::initial_quill_delta_string,
entities::{ entities::{
document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams}, text_block_info::{CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo},
ws_data::{ClientRevisionWSData, ClientRevisionWSDataType}, ws_data::{ClientRevisionWSData, ClientRevisionWSDataType},
}, },
errors::CollaborateError, errors::CollaborateError,
@ -413,12 +413,12 @@ impl UserCloudService for LocalServer {
} }
impl BlockCloudService for LocalServer { impl BlockCloudService for LocalServer {
fn create_block(&self, _token: &str, _params: CreateBlockParams) -> FutureResult<(), FlowyError> { fn create_block(&self, _token: &str, _params: CreateTextBlockParams) -> FutureResult<(), FlowyError> {
FutureResult::new(async { Ok(()) }) FutureResult::new(async { Ok(()) })
} }
fn read_block(&self, _token: &str, params: BlockId) -> FutureResult<Option<BlockInfo>, FlowyError> { fn read_block(&self, _token: &str, params: TextBlockId) -> FutureResult<Option<TextBlockInfo>, FlowyError> {
let doc = BlockInfo { let doc = TextBlockInfo {
block_id: params.value, block_id: params.value,
text: initial_quill_delta_string(), text: initial_quill_delta_string(),
rev_id: 0, rev_id: 0,
@ -427,7 +427,7 @@ impl BlockCloudService for LocalServer {
FutureResult::new(async { Ok(Some(doc)) }) FutureResult::new(async { Ok(Some(doc)) })
} }
fn update_block(&self, _token: &str, _params: ResetBlockParams) -> FutureResult<(), FlowyError> { fn update_block(&self, _token: &str, _params: ResetTextBlockParams) -> FutureResult<(), FlowyError> {
FutureResult::new(async { Ok(()) }) FutureResult::new(async { Ok(()) })
} }
} }

View File

@ -1,5 +1,5 @@
use bytes::Bytes; use bytes::Bytes;
use flowy_block::BlockManager; use flowy_block::TextBlockManager;
use flowy_collaboration::client_document::default::initial_quill_delta_string; use flowy_collaboration::client_document::default::initial_quill_delta_string;
use flowy_collaboration::entities::revision::RepeatedRevision; use flowy_collaboration::entities::revision::RepeatedRevision;
use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_collaboration::entities::ws_data::ClientRevisionWSData;
@ -32,7 +32,7 @@ impl FolderDepsResolver {
user_session: Arc<UserSession>, user_session: Arc<UserSession>,
server_config: &ClientServerConfiguration, server_config: &ClientServerConfiguration,
ws_conn: &Arc<FlowyWebSocketConnect>, ws_conn: &Arc<FlowyWebSocketConnect>,
block_manager: &Arc<BlockManager>, text_block_manager: &Arc<TextBlockManager>,
grid_manager: &Arc<GridManager>, grid_manager: &Arc<GridManager>,
) -> Arc<FolderManager> { ) -> Arc<FolderManager> {
let user: Arc<dyn WorkspaceUser> = Arc::new(WorkspaceUserImpl(user_session.clone())); let user: Arc<dyn WorkspaceUser> = Arc::new(WorkspaceUserImpl(user_session.clone()));
@ -43,7 +43,7 @@ impl FolderDepsResolver {
Some(local_server) => local_server, Some(local_server) => local_server,
}; };
let view_data_processor = make_view_data_processor(block_manager.clone(), grid_manager.clone()); let view_data_processor = make_view_data_processor(text_block_manager.clone(), grid_manager.clone());
let folder_manager = let folder_manager =
Arc::new(FolderManager::new(user.clone(), cloud_service, database, view_data_processor, web_socket).await); Arc::new(FolderManager::new(user.clone(), cloud_service, database, view_data_processor, web_socket).await);
@ -60,10 +60,13 @@ impl FolderDepsResolver {
} }
} }
fn make_view_data_processor(block_manager: Arc<BlockManager>, grid_manager: Arc<GridManager>) -> ViewDataProcessorMap { fn make_view_data_processor(
text_block_manager: Arc<TextBlockManager>,
grid_manager: Arc<GridManager>,
) -> ViewDataProcessorMap {
let mut map: HashMap<ViewDataType, Arc<dyn ViewDataProcessor + Send + Sync>> = HashMap::new(); let mut map: HashMap<ViewDataType, Arc<dyn ViewDataProcessor + Send + Sync>> = HashMap::new();
let block_data_impl = BlockManagerViewDataImpl(block_manager); let block_data_impl = BlockManagerViewDataImpl(text_block_manager);
map.insert(block_data_impl.data_type(), Arc::new(block_data_impl)); map.insert(block_data_impl.data_type(), Arc::new(block_data_impl));
let grid_data_impl = GridManagerViewDataImpl(grid_manager); let grid_data_impl = GridManagerViewDataImpl(grid_manager);
@ -130,45 +133,45 @@ impl WSMessageReceiver for FolderWSMessageReceiverImpl {
} }
} }
struct BlockManagerViewDataImpl(Arc<BlockManager>); struct BlockManagerViewDataImpl(Arc<TextBlockManager>);
impl ViewDataProcessor for BlockManagerViewDataImpl { impl ViewDataProcessor for BlockManagerViewDataImpl {
fn initialize(&self) -> FutureResult<(), FlowyError> { fn initialize(&self) -> FutureResult<(), FlowyError> {
let block_manager = self.0.clone(); let manager = self.0.clone();
FutureResult::new(async move { block_manager.init() }) FutureResult::new(async move { manager.init() })
} }
fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FutureResult<(), FlowyError> { fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FutureResult<(), FlowyError> {
let block_manager = self.0.clone(); let manager = self.0.clone();
let view_id = view_id.to_string(); let view_id = view_id.to_string();
FutureResult::new(async move { FutureResult::new(async move {
let _ = block_manager.create_block(view_id, repeated_revision).await?; let _ = manager.create_block(view_id, repeated_revision).await?;
Ok(()) Ok(())
}) })
} }
fn delete_container(&self, view_id: &str) -> FutureResult<(), FlowyError> { fn delete_container(&self, view_id: &str) -> FutureResult<(), FlowyError> {
let block_manager = self.0.clone(); let manager = self.0.clone();
let view_id = view_id.to_string(); let view_id = view_id.to_string();
FutureResult::new(async move { FutureResult::new(async move {
let _ = block_manager.delete_block(view_id)?; let _ = manager.delete_block(view_id)?;
Ok(()) Ok(())
}) })
} }
fn close_container(&self, view_id: &str) -> FutureResult<(), FlowyError> { fn close_container(&self, view_id: &str) -> FutureResult<(), FlowyError> {
let block_manager = self.0.clone(); let manager = self.0.clone();
let view_id = view_id.to_string(); let view_id = view_id.to_string();
FutureResult::new(async move { FutureResult::new(async move {
let _ = block_manager.close_block(view_id)?; let _ = manager.close_block(view_id)?;
Ok(()) Ok(())
}) })
} }
fn delta_str(&self, view_id: &str) -> FutureResult<String, FlowyError> { fn delta_str(&self, view_id: &str) -> FutureResult<String, FlowyError> {
let view_id = view_id.to_string(); let view_id = view_id.to_string();
let block_manager = self.0.clone(); let manager = self.0.clone();
FutureResult::new(async move { FutureResult::new(async move {
let editor = block_manager.open_block(view_id).await?; let editor = manager.open_block(view_id).await?;
let delta_str = editor.delta_str().await?; let delta_str = editor.delta_str().await?;
Ok(delta_str) Ok(delta_str)
}) })

View File

@ -1,10 +1,10 @@
mod block_deps;
mod folder_deps; mod folder_deps;
mod grid_deps; mod grid_deps;
mod text_block_deps;
mod user_deps; mod user_deps;
mod util; mod util;
pub use block_deps::*;
pub use folder_deps::*; pub use folder_deps::*;
pub use grid_deps::*; pub use grid_deps::*;
pub use text_block_deps::*;
pub use user_deps::*; pub use user_deps::*;

View File

@ -1,7 +1,7 @@
use bytes::Bytes; use bytes::Bytes;
use flowy_block::{ use flowy_block::{
errors::{internal_error, FlowyError}, errors::{internal_error, FlowyError},
BlockCloudService, BlockManager, BlockUser, BlockCloudService, TextBlockManager, TextBlockUser,
}; };
use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_collaboration::entities::ws_data::ClientRevisionWSData;
use flowy_database::ConnectionPool; use flowy_database::ConnectionPool;
@ -16,22 +16,22 @@ use lib_infra::future::BoxResultFuture;
use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage}; use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage};
use std::{convert::TryInto, path::Path, sync::Arc}; use std::{convert::TryInto, path::Path, sync::Arc};
pub struct BlockDepsResolver(); pub struct TextBlockDepsResolver();
impl BlockDepsResolver { impl TextBlockDepsResolver {
pub fn resolve( pub fn resolve(
local_server: Option<Arc<LocalServer>>, local_server: Option<Arc<LocalServer>>,
ws_conn: Arc<FlowyWebSocketConnect>, ws_conn: Arc<FlowyWebSocketConnect>,
user_session: Arc<UserSession>, user_session: Arc<UserSession>,
server_config: &ClientServerConfiguration, server_config: &ClientServerConfiguration,
) -> Arc<BlockManager> { ) -> Arc<TextBlockManager> {
let user = Arc::new(BlockUserImpl(user_session)); let user = Arc::new(BlockUserImpl(user_session));
let rev_web_socket = Arc::new(BlockWebSocket(ws_conn.clone())); let rev_web_socket = Arc::new(TextBlockWebSocket(ws_conn.clone()));
let cloud_service: Arc<dyn BlockCloudService> = match local_server { let cloud_service: Arc<dyn BlockCloudService> = match local_server {
None => Arc::new(BlockHttpCloudService::new(server_config.clone())), None => Arc::new(BlockHttpCloudService::new(server_config.clone())),
Some(local_server) => local_server, Some(local_server) => local_server,
}; };
let manager = Arc::new(BlockManager::new(cloud_service, user, rev_web_socket)); let manager = Arc::new(TextBlockManager::new(cloud_service, user, rev_web_socket));
let receiver = Arc::new(DocumentWSMessageReceiverImpl(manager.clone())); let receiver = Arc::new(DocumentWSMessageReceiverImpl(manager.clone()));
ws_conn.add_ws_message_receiver(receiver).unwrap(); ws_conn.add_ws_message_receiver(receiver).unwrap();
@ -40,7 +40,7 @@ impl BlockDepsResolver {
} }
struct BlockUserImpl(Arc<UserSession>); struct BlockUserImpl(Arc<UserSession>);
impl BlockUser for BlockUserImpl { impl TextBlockUser for BlockUserImpl {
fn user_dir(&self) -> Result<String, FlowyError> { fn user_dir(&self) -> Result<String, FlowyError> {
let dir = self.0.user_dir().map_err(|e| FlowyError::unauthorized().context(e))?; let dir = self.0.user_dir().map_err(|e| FlowyError::unauthorized().context(e))?;
@ -64,8 +64,8 @@ impl BlockUser for BlockUserImpl {
} }
} }
struct BlockWebSocket(Arc<FlowyWebSocketConnect>); struct TextBlockWebSocket(Arc<FlowyWebSocketConnect>);
impl RevisionWebSocket for BlockWebSocket { impl RevisionWebSocket for TextBlockWebSocket {
fn send(&self, data: ClientRevisionWSData) -> BoxResultFuture<(), FlowyError> { fn send(&self, data: ClientRevisionWSData) -> BoxResultFuture<(), FlowyError> {
let bytes: Bytes = data.try_into().unwrap(); let bytes: Bytes = data.try_into().unwrap();
let msg = WebSocketRawMessage { let msg = WebSocketRawMessage {
@ -90,7 +90,7 @@ impl RevisionWebSocket for BlockWebSocket {
} }
} }
struct DocumentWSMessageReceiverImpl(Arc<BlockManager>); struct DocumentWSMessageReceiverImpl(Arc<TextBlockManager>);
impl WSMessageReceiver for DocumentWSMessageReceiverImpl { impl WSMessageReceiver for DocumentWSMessageReceiverImpl {
fn source(&self) -> WSChannel { fn source(&self) -> WSChannel {
WSChannel::Document WSChannel::Document

View File

@ -3,7 +3,7 @@ pub mod module;
pub use flowy_net::get_client_server_configuration; pub use flowy_net::get_client_server_configuration;
use crate::deps_resolve::*; use crate::deps_resolve::*;
use flowy_block::BlockManager; use flowy_block::TextBlockManager;
use flowy_folder::{errors::FlowyError, manager::FolderManager}; use flowy_folder::{errors::FlowyError, manager::FolderManager};
use flowy_grid::manager::GridManager; use flowy_grid::manager::GridManager;
use flowy_net::ClientServerConfiguration; use flowy_net::ClientServerConfiguration;
@ -88,7 +88,7 @@ pub struct FlowySDK {
#[allow(dead_code)] #[allow(dead_code)]
config: FlowySDKConfig, config: FlowySDKConfig,
pub user_session: Arc<UserSession>, pub user_session: Arc<UserSession>,
pub block_manager: Arc<BlockManager>, pub text_block_manager: Arc<TextBlockManager>,
pub folder_manager: Arc<FolderManager>, pub folder_manager: Arc<FolderManager>,
pub grid_manager: Arc<GridManager>, pub grid_manager: Arc<GridManager>,
pub dispatcher: Arc<EventDispatcher>, pub dispatcher: Arc<EventDispatcher>,
@ -103,9 +103,9 @@ impl FlowySDK {
tracing::debug!("🔥 {:?}", config); tracing::debug!("🔥 {:?}", config);
let runtime = tokio_default_runtime().unwrap(); let runtime = tokio_default_runtime().unwrap();
let (local_server, ws_conn) = mk_local_server(&config.server_config); let (local_server, ws_conn) = mk_local_server(&config.server_config);
let (user_session, block_manager, folder_manager, local_server, grid_manager) = runtime.block_on(async { let (user_session, text_block_manager, folder_manager, local_server, grid_manager) = runtime.block_on(async {
let user_session = mk_user_session(&config, &local_server, &config.server_config); let user_session = mk_user_session(&config, &local_server, &config.server_config);
let block_manager = BlockDepsResolver::resolve( let text_block_manager = TextBlockDepsResolver::resolve(
local_server.clone(), local_server.clone(),
ws_conn.clone(), ws_conn.clone(),
user_session.clone(), user_session.clone(),
@ -119,7 +119,7 @@ impl FlowySDK {
user_session.clone(), user_session.clone(),
&config.server_config, &config.server_config,
&ws_conn, &ws_conn,
&block_manager, &text_block_manager,
&grid_manager, &grid_manager,
) )
.await; .await;
@ -128,11 +128,23 @@ impl FlowySDK {
local_server.run(); local_server.run();
} }
ws_conn.init().await; ws_conn.init().await;
(user_session, block_manager, folder_manager, local_server, grid_manager) (
user_session,
text_block_manager,
folder_manager,
local_server,
grid_manager,
)
}); });
let dispatcher = Arc::new(EventDispatcher::construct(runtime, || { let dispatcher = Arc::new(EventDispatcher::construct(runtime, || {
mk_modules(&ws_conn, &folder_manager, &grid_manager, &user_session, &block_manager) mk_modules(
&ws_conn,
&folder_manager,
&grid_manager,
&user_session,
&text_block_manager,
)
})); }));
_start_listening(&dispatcher, &ws_conn, &user_session, &folder_manager); _start_listening(&dispatcher, &ws_conn, &user_session, &folder_manager);
@ -140,7 +152,7 @@ impl FlowySDK {
Self { Self {
config, config,
user_session, user_session,
block_manager, text_block_manager,
folder_manager, folder_manager,
grid_manager, grid_manager,
dispatcher, dispatcher,

View File

@ -1,4 +1,4 @@
use flowy_block::BlockManager; use flowy_block::TextBlockManager;
use flowy_folder::manager::FolderManager; use flowy_folder::manager::FolderManager;
use flowy_grid::manager::GridManager; use flowy_grid::manager::GridManager;
use flowy_net::ws::connection::FlowyWebSocketConnect; use flowy_net::ws::connection::FlowyWebSocketConnect;
@ -11,14 +11,20 @@ pub fn mk_modules(
folder_manager: &Arc<FolderManager>, folder_manager: &Arc<FolderManager>,
grid_manager: &Arc<GridManager>, grid_manager: &Arc<GridManager>,
user_session: &Arc<UserSession>, user_session: &Arc<UserSession>,
block_manager: &Arc<BlockManager>, text_block_manager: &Arc<TextBlockManager>,
) -> Vec<Module> { ) -> Vec<Module> {
let user_module = mk_user_module(user_session.clone()); let user_module = mk_user_module(user_session.clone());
let folder_module = mk_folder_module(folder_manager.clone()); let folder_module = mk_folder_module(folder_manager.clone());
let network_module = mk_network_module(ws_conn.clone()); let network_module = mk_network_module(ws_conn.clone());
let grid_module = mk_grid_module(grid_manager.clone()); let grid_module = mk_grid_module(grid_manager.clone());
let block_module = mk_block_module(block_manager.clone()); let text_block_module = mk_text_block_module(text_block_manager.clone());
vec![user_module, folder_module, network_module, grid_module, block_module] vec![
user_module,
folder_module,
network_module,
grid_module,
text_block_module,
]
} }
fn mk_user_module(user_session: Arc<UserSession>) -> Module { fn mk_user_module(user_session: Arc<UserSession>) -> Module {
@ -37,6 +43,6 @@ fn mk_grid_module(grid_manager: Arc<GridManager>) -> Module {
flowy_grid::event_map::create(grid_manager) flowy_grid::event_map::create(grid_manager)
} }
fn mk_block_module(block_manager: Arc<BlockManager>) -> Module { fn mk_text_block_module(text_block_manager: Arc<TextBlockManager>) -> Module {
flowy_block::event_map::create(block_manager) flowy_block::event_map::create(text_block_manager)
} }

View File

@ -1,9 +1,14 @@
mod sql_impl; mod folder_rev_impl;
mod grid_rev_impl;
mod text_block_rev_impl;
pub use folder_rev_impl::*;
pub use grid_rev_impl::*;
pub use text_block_rev_impl::*;
use crate::RevisionRecord; use crate::RevisionRecord;
use diesel::SqliteConnection; use diesel::SqliteConnection;
use flowy_collaboration::entities::revision::RevisionRange; use flowy_collaboration::entities::revision::RevisionRange;
pub use sql_impl::*;
use flowy_error::FlowyResult; use flowy_error::FlowyResult;
use std::fmt::Debug; use std::fmt::Debug;

View File

@ -14,12 +14,12 @@ use flowy_database::{
use flowy_error::{internal_error, FlowyError, FlowyResult}; use flowy_error::{internal_error, FlowyError, FlowyResult};
use std::sync::Arc; use std::sync::Arc;
pub struct SQLitePersistence { pub struct SQLiteTextBlockRevisionPersistence {
user_id: String, user_id: String,
pub(crate) pool: Arc<ConnectionPool>, pub(crate) pool: Arc<ConnectionPool>,
} }
impl RevisionDiskCache for SQLitePersistence { impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence {
type Error = FlowyError; type Error = FlowyError;
fn create_revision_records( fn create_revision_records(
@ -83,7 +83,7 @@ impl RevisionDiskCache for SQLitePersistence {
} }
} }
impl SQLitePersistence { impl SQLiteTextBlockRevisionPersistence {
pub(crate) fn new(user_id: &str, pool: Arc<ConnectionPool>) -> Self { pub(crate) fn new(user_id: &str, pool: Arc<ConnectionPool>) -> Self {
Self { Self {
user_id: user_id.to_owned(), user_id: user_id.to_owned(),

View File

@ -1,325 +1,2 @@
mod disk; pub(crate) mod disk;
mod memory; pub(crate) mod memory;
use crate::cache::{
disk::{RevisionChangeset, RevisionDiskCache, RevisionTableState, SQLitePersistence},
memory::{RevisionMemoryCache, RevisionMemoryCacheDelegate},
};
use flowy_collaboration::entities::revision::{Revision, RevisionRange, RevisionState};
use flowy_database::ConnectionPool;
use flowy_error::{internal_error, FlowyError, FlowyResult};
use crate::RevisionCompact;
use std::collections::VecDeque;
use std::{borrow::Cow, sync::Arc};
use tokio::sync::RwLock;
use tokio::task::spawn_blocking;
pub const REVISION_WRITE_INTERVAL_IN_MILLIS: u64 = 600;
pub struct RevisionPersistence {
user_id: String,
object_id: String,
disk_cache: Arc<dyn RevisionDiskCache<Error = FlowyError>>,
memory_cache: Arc<RevisionMemoryCache>,
sync_seq: RwLock<RevisionSyncSequence>,
}
impl RevisionPersistence {
pub fn new(user_id: &str, object_id: &str, pool: Arc<ConnectionPool>) -> RevisionPersistence {
let disk_cache = Arc::new(SQLitePersistence::new(user_id, pool));
let memory_cache = Arc::new(RevisionMemoryCache::new(object_id, Arc::new(disk_cache.clone())));
let object_id = object_id.to_owned();
let user_id = user_id.to_owned();
let sync_seq = RwLock::new(RevisionSyncSequence::new());
Self {
user_id,
object_id,
disk_cache,
memory_cache,
sync_seq,
}
}
/// Save the revision that comes from remote to disk.
#[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, object_id=%self.object_id), err)]
pub(crate) async fn add_ack_revision(&self, revision: &Revision) -> FlowyResult<()> {
tracing::Span::current().record("rev_id", &revision.rev_id);
self.add(revision.clone(), RevisionState::Ack, true).await
}
/// Append the revision that already existed in the local DB state to sync sequence
#[tracing::instrument(level = "trace", skip(self), fields(rev_id, object_id=%self.object_id), err)]
pub(crate) async fn sync_revision(&self, revision: &Revision) -> FlowyResult<()> {
tracing::Span::current().record("rev_id", &revision.rev_id);
self.add(revision.clone(), RevisionState::Sync, false).await?;
self.sync_seq.write().await.add(revision.rev_id)?;
Ok(())
}
/// Save the revision to disk and append it to the end of the sync sequence.
#[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, compact_range, object_id=%self.object_id), err)]
pub(crate) async fn add_sync_revision<C>(&self, revision: &Revision) -> FlowyResult<i64>
where
C: RevisionCompact,
{
let result = self.sync_seq.read().await.compact();
match result {
None => {
tracing::Span::current().record("rev_id", &revision.rev_id);
self.add(revision.clone(), RevisionState::Sync, true).await?;
self.sync_seq.write().await.add(revision.rev_id)?;
Ok(revision.rev_id)
}
Some((range, mut compact_seq)) => {
tracing::Span::current().record("compact_range", &format!("{}", range).as_str());
let mut revisions = self.revisions_in_range(&range).await?;
if range.to_rev_ids().len() != revisions.len() {
debug_assert_eq!(range.to_rev_ids().len(), revisions.len());
}
// append the new revision
revisions.push(revision.clone());
// compact multiple revisions into one
let compact_revision = C::compact_revisions(&self.user_id, &self.object_id, revisions)?;
let rev_id = compact_revision.rev_id;
tracing::Span::current().record("rev_id", &rev_id);
// insert new revision
compact_seq.push_back(rev_id);
// replace the revisions in range with compact revision
self.compact(&range, compact_revision).await?;
debug_assert_eq!(self.sync_seq.read().await.len(), compact_seq.len());
self.sync_seq.write().await.reset(compact_seq);
Ok(rev_id)
}
}
}
/// Remove the revision with rev_id from the sync sequence.
pub(crate) async fn ack_revision(&self, rev_id: i64) -> FlowyResult<()> {
if self.sync_seq.write().await.ack(&rev_id).is_ok() {
self.memory_cache.ack(&rev_id).await;
}
Ok(())
}
pub(crate) async fn next_sync_revision(&self) -> FlowyResult<Option<Revision>> {
match self.sync_seq.read().await.next_rev_id() {
None => Ok(None),
Some(rev_id) => Ok(self.get(rev_id).await.map(|record| record.revision)),
}
}
/// The cache gets reset while it conflicts with the remote revisions.
#[tracing::instrument(level = "trace", skip(self, revisions), err)]
pub(crate) async fn reset(&self, revisions: Vec<Revision>) -> FlowyResult<()> {
let records = revisions
.to_vec()
.into_iter()
.map(|revision| RevisionRecord {
revision,
state: RevisionState::Sync,
write_to_disk: false,
})
.collect::<Vec<_>>();
let _ = self
.disk_cache
.delete_and_insert_records(&self.object_id, None, records.clone())?;
let _ = self.memory_cache.reset_with_revisions(records).await;
self.sync_seq.write().await.clear();
Ok(())
}
async fn add(&self, revision: Revision, state: RevisionState, write_to_disk: bool) -> FlowyResult<()> {
if self.memory_cache.contains(&revision.rev_id) {
tracing::warn!("Duplicate revision: {}:{}-{:?}", self.object_id, revision.rev_id, state);
return Ok(());
}
let record = RevisionRecord {
revision,
state,
write_to_disk,
};
self.memory_cache.add(Cow::Owned(record)).await;
Ok(())
}
async fn compact(&self, range: &RevisionRange, new_revision: Revision) -> FlowyResult<()> {
self.memory_cache.remove_with_range(range);
let rev_ids = range.to_rev_ids();
let _ = self
.disk_cache
.delete_revision_records(&self.object_id, Some(rev_ids))?;
self.add(new_revision, RevisionState::Sync, true).await?;
Ok(())
}
pub async fn get(&self, rev_id: i64) -> Option<RevisionRecord> {
match self.memory_cache.get(&rev_id).await {
None => match self
.disk_cache
.read_revision_records(&self.object_id, Some(vec![rev_id]))
{
Ok(mut records) => {
let record = records.pop()?;
assert!(records.is_empty());
Some(record)
}
Err(e) => {
tracing::error!("{}", e);
None
}
},
Some(revision) => Some(revision),
}
}
pub fn batch_get(&self, doc_id: &str) -> FlowyResult<Vec<RevisionRecord>> {
self.disk_cache.read_revision_records(doc_id, None)
}
// Read the revision which rev_id >= range.start && rev_id <= range.end
pub async fn revisions_in_range(&self, range: &RevisionRange) -> FlowyResult<Vec<Revision>> {
let range = range.clone();
let mut records = self.memory_cache.get_with_range(&range).await?;
let range_len = range.len() as usize;
if records.len() != range_len {
let disk_cache = self.disk_cache.clone();
let object_id = self.object_id.clone();
records = spawn_blocking(move || disk_cache.read_revision_records_with_range(&object_id, &range))
.await
.map_err(internal_error)??;
if records.len() != range_len {
// #[cfg(debug_assertions)]
// records.iter().for_each(|record| {
// let delta = PlainDelta::from_bytes(&record.revision.delta_data).unwrap();
// tracing::trace!("{}", delta.to_string());
// });
tracing::error!("Expect revision len {},but receive {}", range_len, records.len());
}
}
Ok(records
.into_iter()
.map(|record| record.revision)
.collect::<Vec<Revision>>())
}
}
pub fn mk_revision_disk_cache(
user_id: &str,
pool: Arc<ConnectionPool>,
) -> Arc<dyn RevisionDiskCache<Error = FlowyError>> {
Arc::new(SQLitePersistence::new(user_id, pool))
}
impl RevisionMemoryCacheDelegate for Arc<SQLitePersistence> {
#[tracing::instrument(level = "trace", skip(self, records), fields(checkpoint_result), err)]
fn checkpoint_tick(&self, mut records: Vec<RevisionRecord>) -> FlowyResult<()> {
let conn = &*self.pool.get().map_err(internal_error)?;
records.retain(|record| record.write_to_disk);
if !records.is_empty() {
tracing::Span::current().record(
"checkpoint_result",
&format!("{} records were saved", records.len()).as_str(),
);
let _ = self.create_revision_records(records, conn)?;
}
Ok(())
}
fn receive_ack(&self, object_id: &str, rev_id: i64) {
let changeset = RevisionChangeset {
object_id: object_id.to_string(),
rev_id: rev_id.into(),
state: RevisionTableState::Ack,
};
match self.update_revision_record(vec![changeset]) {
Ok(_) => {}
Err(e) => tracing::error!("{}", e),
}
}
}
#[derive(Clone, Debug)]
pub struct RevisionRecord {
pub revision: Revision,
pub state: RevisionState,
pub write_to_disk: bool,
}
impl RevisionRecord {
pub fn ack(&mut self) {
self.state = RevisionState::Ack;
}
}
#[derive(Default)]
struct RevisionSyncSequence(VecDeque<i64>);
impl RevisionSyncSequence {
fn new() -> Self {
RevisionSyncSequence::default()
}
fn add(&mut self, new_rev_id: i64) -> FlowyResult<()> {
// The last revision's rev_id must be greater than the new one.
if let Some(rev_id) = self.0.back() {
if *rev_id >= new_rev_id {
return Err(
FlowyError::internal().context(format!("The new revision's id must be greater than {}", rev_id))
);
}
}
self.0.push_back(new_rev_id);
Ok(())
}
fn ack(&mut self, rev_id: &i64) -> FlowyResult<()> {
let cur_rev_id = self.0.front().cloned();
if let Some(pop_rev_id) = cur_rev_id {
if &pop_rev_id != rev_id {
let desc = format!(
"The ack rev_id:{} is not equal to the current rev_id:{}",
rev_id, pop_rev_id
);
return Err(FlowyError::internal().context(desc));
}
let _ = self.0.pop_front();
}
Ok(())
}
fn next_rev_id(&self) -> Option<i64> {
self.0.front().cloned()
}
fn reset(&mut self, new_seq: VecDeque<i64>) {
self.0 = new_seq;
}
fn clear(&mut self) {
self.0.clear();
}
fn len(&self) -> usize {
self.0.len()
}
// Compact the rev_ids into one except the current synchronizing rev_id.
fn compact(&self) -> Option<(RevisionRange, VecDeque<i64>)> {
self.next_rev_id()?;
let mut new_seq = self.0.clone();
let mut drained = new_seq.drain(1..).collect::<VecDeque<_>>();
let start = drained.pop_front()?;
let end = drained.pop_back().unwrap_or(start);
Some((RevisionRange { start, end }, new_seq))
}
}

View File

@ -1,11 +1,13 @@
mod cache; mod cache;
mod conflict_resolve; mod conflict_resolve;
mod rev_manager; mod rev_manager;
mod rev_persistence;
mod ws_manager; mod ws_manager;
pub use cache::*; pub use cache::*;
pub use conflict_resolve::*; pub use conflict_resolve::*;
pub use rev_manager::*; pub use rev_manager::*;
pub use rev_persistence::*;
pub use ws_manager::*; pub use ws_manager::*;
#[macro_use] #[macro_use]

View File

@ -0,0 +1,322 @@
use crate::cache::{
disk::{RevisionChangeset, RevisionDiskCache, RevisionTableState, SQLiteTextBlockRevisionPersistence},
memory::{RevisionMemoryCache, RevisionMemoryCacheDelegate},
};
use flowy_collaboration::entities::revision::{Revision, RevisionRange, RevisionState};
use flowy_database::ConnectionPool;
use flowy_error::{internal_error, FlowyError, FlowyResult};
use crate::RevisionCompact;
use std::collections::VecDeque;
use std::{borrow::Cow, sync::Arc};
use tokio::sync::RwLock;
use tokio::task::spawn_blocking;
pub const REVISION_WRITE_INTERVAL_IN_MILLIS: u64 = 600;
pub struct RevisionPersistence {
user_id: String,
object_id: String,
disk_cache: Arc<dyn RevisionDiskCache<Error = FlowyError>>,
memory_cache: Arc<RevisionMemoryCache>,
sync_seq: RwLock<RevisionSyncSequence>,
}
impl RevisionPersistence {
pub fn new(user_id: &str, object_id: &str, pool: Arc<ConnectionPool>) -> RevisionPersistence {
let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(user_id, pool));
let memory_cache = Arc::new(RevisionMemoryCache::new(object_id, Arc::new(disk_cache.clone())));
let object_id = object_id.to_owned();
let user_id = user_id.to_owned();
let sync_seq = RwLock::new(RevisionSyncSequence::new());
Self {
user_id,
object_id,
disk_cache,
memory_cache,
sync_seq,
}
}
/// Save the revision that comes from remote to disk.
#[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, object_id=%self.object_id), err)]
pub(crate) async fn add_ack_revision(&self, revision: &Revision) -> FlowyResult<()> {
tracing::Span::current().record("rev_id", &revision.rev_id);
self.add(revision.clone(), RevisionState::Ack, true).await
}
/// Append the revision that already existed in the local DB state to sync sequence
#[tracing::instrument(level = "trace", skip(self), fields(rev_id, object_id=%self.object_id), err)]
pub(crate) async fn sync_revision(&self, revision: &Revision) -> FlowyResult<()> {
tracing::Span::current().record("rev_id", &revision.rev_id);
self.add(revision.clone(), RevisionState::Sync, false).await?;
self.sync_seq.write().await.add(revision.rev_id)?;
Ok(())
}
/// Save the revision to disk and append it to the end of the sync sequence.
#[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, compact_range, object_id=%self.object_id), err)]
pub(crate) async fn add_sync_revision<C>(&self, revision: &Revision) -> FlowyResult<i64>
where
C: RevisionCompact,
{
let result = self.sync_seq.read().await.compact();
match result {
None => {
tracing::Span::current().record("rev_id", &revision.rev_id);
self.add(revision.clone(), RevisionState::Sync, true).await?;
self.sync_seq.write().await.add(revision.rev_id)?;
Ok(revision.rev_id)
}
Some((range, mut compact_seq)) => {
tracing::Span::current().record("compact_range", &format!("{}", range).as_str());
let mut revisions = self.revisions_in_range(&range).await?;
if range.to_rev_ids().len() != revisions.len() {
debug_assert_eq!(range.to_rev_ids().len(), revisions.len());
}
// append the new revision
revisions.push(revision.clone());
// compact multiple revisions into one
let compact_revision = C::compact_revisions(&self.user_id, &self.object_id, revisions)?;
let rev_id = compact_revision.rev_id;
tracing::Span::current().record("rev_id", &rev_id);
// insert new revision
compact_seq.push_back(rev_id);
// replace the revisions in range with compact revision
self.compact(&range, compact_revision).await?;
debug_assert_eq!(self.sync_seq.read().await.len(), compact_seq.len());
self.sync_seq.write().await.reset(compact_seq);
Ok(rev_id)
}
}
}
/// Remove the revision with rev_id from the sync sequence.
pub(crate) async fn ack_revision(&self, rev_id: i64) -> FlowyResult<()> {
if self.sync_seq.write().await.ack(&rev_id).is_ok() {
self.memory_cache.ack(&rev_id).await;
}
Ok(())
}
pub(crate) async fn next_sync_revision(&self) -> FlowyResult<Option<Revision>> {
match self.sync_seq.read().await.next_rev_id() {
None => Ok(None),
Some(rev_id) => Ok(self.get(rev_id).await.map(|record| record.revision)),
}
}
/// The cache gets reset while it conflicts with the remote revisions.
#[tracing::instrument(level = "trace", skip(self, revisions), err)]
pub(crate) async fn reset(&self, revisions: Vec<Revision>) -> FlowyResult<()> {
let records = revisions
.to_vec()
.into_iter()
.map(|revision| RevisionRecord {
revision,
state: RevisionState::Sync,
write_to_disk: false,
})
.collect::<Vec<_>>();
let _ = self
.disk_cache
.delete_and_insert_records(&self.object_id, None, records.clone())?;
let _ = self.memory_cache.reset_with_revisions(records).await;
self.sync_seq.write().await.clear();
Ok(())
}
async fn add(&self, revision: Revision, state: RevisionState, write_to_disk: bool) -> FlowyResult<()> {
if self.memory_cache.contains(&revision.rev_id) {
tracing::warn!("Duplicate revision: {}:{}-{:?}", self.object_id, revision.rev_id, state);
return Ok(());
}
let record = RevisionRecord {
revision,
state,
write_to_disk,
};
self.memory_cache.add(Cow::Owned(record)).await;
Ok(())
}
async fn compact(&self, range: &RevisionRange, new_revision: Revision) -> FlowyResult<()> {
self.memory_cache.remove_with_range(range);
let rev_ids = range.to_rev_ids();
let _ = self
.disk_cache
.delete_revision_records(&self.object_id, Some(rev_ids))?;
self.add(new_revision, RevisionState::Sync, true).await?;
Ok(())
}
pub async fn get(&self, rev_id: i64) -> Option<RevisionRecord> {
match self.memory_cache.get(&rev_id).await {
None => match self
.disk_cache
.read_revision_records(&self.object_id, Some(vec![rev_id]))
{
Ok(mut records) => {
let record = records.pop()?;
assert!(records.is_empty());
Some(record)
}
Err(e) => {
tracing::error!("{}", e);
None
}
},
Some(revision) => Some(revision),
}
}
pub fn batch_get(&self, doc_id: &str) -> FlowyResult<Vec<RevisionRecord>> {
self.disk_cache.read_revision_records(doc_id, None)
}
// Read the revision which rev_id >= range.start && rev_id <= range.end
pub async fn revisions_in_range(&self, range: &RevisionRange) -> FlowyResult<Vec<Revision>> {
let range = range.clone();
let mut records = self.memory_cache.get_with_range(&range).await?;
let range_len = range.len() as usize;
if records.len() != range_len {
let disk_cache = self.disk_cache.clone();
let object_id = self.object_id.clone();
records = spawn_blocking(move || disk_cache.read_revision_records_with_range(&object_id, &range))
.await
.map_err(internal_error)??;
if records.len() != range_len {
// #[cfg(debug_assertions)]
// records.iter().for_each(|record| {
// let delta = PlainDelta::from_bytes(&record.revision.delta_data).unwrap();
// tracing::trace!("{}", delta.to_string());
// });
tracing::error!("Expect revision len {},but receive {}", range_len, records.len());
}
}
Ok(records
.into_iter()
.map(|record| record.revision)
.collect::<Vec<Revision>>())
}
}
pub fn mk_revision_disk_cache(
user_id: &str,
pool: Arc<ConnectionPool>,
) -> Arc<dyn RevisionDiskCache<Error = FlowyError>> {
Arc::new(SQLiteTextBlockRevisionPersistence::new(user_id, pool))
}
impl RevisionMemoryCacheDelegate for Arc<SQLiteTextBlockRevisionPersistence> {
#[tracing::instrument(level = "trace", skip(self, records), fields(checkpoint_result), err)]
fn checkpoint_tick(&self, mut records: Vec<RevisionRecord>) -> FlowyResult<()> {
let conn = &*self.pool.get().map_err(internal_error)?;
records.retain(|record| record.write_to_disk);
if !records.is_empty() {
tracing::Span::current().record(
"checkpoint_result",
&format!("{} records were saved", records.len()).as_str(),
);
let _ = self.create_revision_records(records, conn)?;
}
Ok(())
}
fn receive_ack(&self, object_id: &str, rev_id: i64) {
let changeset = RevisionChangeset {
object_id: object_id.to_string(),
rev_id: rev_id.into(),
state: RevisionTableState::Ack,
};
match self.update_revision_record(vec![changeset]) {
Ok(_) => {}
Err(e) => tracing::error!("{}", e),
}
}
}
#[derive(Clone, Debug)]
pub struct RevisionRecord {
pub revision: Revision,
pub state: RevisionState,
pub write_to_disk: bool,
}
impl RevisionRecord {
pub fn ack(&mut self) {
self.state = RevisionState::Ack;
}
}
#[derive(Default)]
struct RevisionSyncSequence(VecDeque<i64>);
impl RevisionSyncSequence {
fn new() -> Self {
RevisionSyncSequence::default()
}
fn add(&mut self, new_rev_id: i64) -> FlowyResult<()> {
// The last revision's rev_id must be greater than the new one.
if let Some(rev_id) = self.0.back() {
if *rev_id >= new_rev_id {
return Err(
FlowyError::internal().context(format!("The new revision's id must be greater than {}", rev_id))
);
}
}
self.0.push_back(new_rev_id);
Ok(())
}
fn ack(&mut self, rev_id: &i64) -> FlowyResult<()> {
let cur_rev_id = self.0.front().cloned();
if let Some(pop_rev_id) = cur_rev_id {
if &pop_rev_id != rev_id {
let desc = format!(
"The ack rev_id:{} is not equal to the current rev_id:{}",
rev_id, pop_rev_id
);
return Err(FlowyError::internal().context(desc));
}
let _ = self.0.pop_front();
}
Ok(())
}
fn next_rev_id(&self) -> Option<i64> {
self.0.front().cloned()
}
fn reset(&mut self, new_seq: VecDeque<i64>) {
self.0 = new_seq;
}
fn clear(&mut self) {
self.0.clear();
}
fn len(&self) -> usize {
self.0.len()
}
// Compact the rev_ids into one except the current synchronizing rev_id.
fn compact(&self) -> Option<(RevisionRange, VecDeque<i64>)> {
self.next_rev_id()?;
let mut new_seq = self.0.clone();
let mut drained = new_seq.drain(1..).collect::<VecDeque<_>>();
let start = drained.pop_front()?;
let end = drained.pop_back().unwrap_or(start);
Some((RevisionRange { start, end }, new_seq))
}
}

View File

@ -0,0 +1,115 @@
use crate::entities::revision::{md5, RepeatedRevision, Revision};
use crate::errors::{internal_error, CollaborateError, CollaborateResult};
use crate::util::{cal_diff, make_delta_from_revisions};
use flowy_grid_data_model::entities::{BlockMeta, RowMeta, RowOrder};
use lib_infra::uuid;
use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
use std::sync::Arc;
pub type BlockMetaDelta = PlainTextDelta;
pub type BlockDeltaBuilder = PlainTextDeltaBuilder;
pub struct BlockMetaPad {
pub(crate) block_meta: Arc<BlockMeta>,
pub(crate) delta: BlockMetaDelta,
}
impl BlockMetaPad {
pub fn from_delta(delta: BlockMetaDelta) -> CollaborateResult<Self> {
let s = delta.to_str()?;
let block_delta: BlockMeta = serde_json::from_str(&s).map_err(|e| {
CollaborateError::internal().context(format!("Deserialize delta to block meta failed: {}", e))
})?;
Ok(Self {
block_meta: Arc::new(block_delta),
delta,
})
}
pub fn from_revisions(_grid_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
let block_delta: BlockMetaDelta = make_delta_from_revisions::<PlainTextAttributes>(revisions)?;
Self::from_delta(block_delta)
}
pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult<Option<BlockMetaChange>> {
self.modify(|grid| {
grid.rows.push(row);
Ok(Some(()))
})
}
pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult<Option<BlockMetaChange>> {
self.modify(|grid| {
grid.rows.retain(|row| !row_ids.contains(&row.id));
Ok(Some(()))
})
}
pub fn md5(&self) -> String {
md5(&self.delta.to_bytes())
}
pub fn delta_str(&self) -> String {
self.delta.to_delta_str()
}
pub fn modify<F>(&mut self, f: F) -> CollaborateResult<Option<BlockMetaChange>>
where
F: FnOnce(&mut BlockMeta) -> CollaborateResult<Option<()>>,
{
let cloned_meta = self.block_meta.clone();
match f(Arc::make_mut(&mut self.block_meta))? {
None => Ok(None),
Some(_) => {
let old = json_from_grid(&cloned_meta)?;
let new = json_from_grid(&self.block_meta)?;
match cal_diff::<PlainTextAttributes>(old, new) {
None => Ok(None),
Some(delta) => {
self.delta = self.delta.compose(&delta)?;
Ok(Some(BlockMetaChange { delta, md5: self.md5() }))
}
}
}
}
}
}
fn json_from_grid(block_meta: &Arc<BlockMeta>) -> CollaborateResult<String> {
let json = serde_json::to_string(block_meta)
.map_err(|err| internal_error(format!("Serialize grid to json str failed. {:?}", err)))?;
Ok(json)
}
pub struct BlockMetaChange {
pub delta: BlockMetaDelta,
/// md5: the md5 of the grid after applying the change.
pub md5: String,
}
pub fn make_block_meta_delta(block_meta: &BlockMeta) -> BlockMetaDelta {
let json = serde_json::to_string(&block_meta).unwrap();
PlainTextDeltaBuilder::new().insert(&json).build()
}
pub fn make_block_meta_revisions(user_id: &str, block_meta: &BlockMeta) -> RepeatedRevision {
let delta = make_block_meta_delta(block_meta);
let bytes = delta.to_bytes();
let revision = Revision::initial_revision(user_id, &block_meta.block_id, bytes);
revision.into()
}
impl std::default::Default for BlockMetaPad {
fn default() -> Self {
let block_meta = BlockMeta {
block_id: uuid(),
rows: vec![],
};
let delta = make_block_meta_delta(&block_meta);
BlockMetaPad {
block_meta: Arc::new(block_meta),
delta,
}
}
}

View File

@ -33,7 +33,7 @@ impl GridMetaPad {
pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult<Option<GridChange>> { pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult<Option<GridChange>> {
self.modify_grid(|grid| { self.modify_grid(|grid| {
grid.rows.push(row); // grid.rows.push(row);
Ok(Some(())) Ok(Some(()))
}) })
} }
@ -47,7 +47,7 @@ impl GridMetaPad {
pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult<Option<GridChange>> { pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult<Option<GridChange>> {
self.modify_grid(|grid| { self.modify_grid(|grid| {
grid.rows.retain(|row| !row_ids.contains(&row.id)); // grid.rows.retain(|row| !row_ids.contains(&row.id));
Ok(Some(())) Ok(Some(()))
}) })
} }
@ -74,17 +74,17 @@ impl GridMetaPad {
.map(FieldOrder::from) .map(FieldOrder::from)
.collect::<Vec<FieldOrder>>(); .collect::<Vec<FieldOrder>>();
let row_orders = self // let row_orders = self
.grid_meta // .grid_meta
.rows // .rows
.iter() // .iter()
.map(RowOrder::from) // .map(RowOrder::from)
.collect::<Vec<RowOrder>>(); // .collect::<Vec<RowOrder>>();
Grid { Grid {
id: "".to_string(), id: "".to_string(),
field_orders, field_orders,
row_orders, row_orders: vec![],
} }
} }
@ -147,7 +147,7 @@ impl std::default::Default for GridMetaPad {
let grid = GridMeta { let grid = GridMeta {
grid_id: uuid(), grid_id: uuid(),
fields: vec![], fields: vec![],
rows: vec![], blocks: vec![],
}; };
let delta = make_grid_delta(&grid); let delta = make_grid_delta(&grid);
GridMetaPad { GridMetaPad {

View File

@ -1,3 +1,5 @@
mod block_pad;
mod grid_pad; mod grid_pad;
pub use block_pad::*;
pub use grid_pad::*; pub use grid_pad::*;

View File

@ -1,5 +1,5 @@
pub mod document_info;
pub mod folder_info; pub mod folder_info;
pub mod parser; pub mod parser;
pub mod revision; pub mod revision;
pub mod text_block_info;
pub mod ws_data; pub mod ws_data;

View File

@ -6,7 +6,7 @@ use flowy_derive::ProtoBuf;
use lib_ot::{errors::OTError, rich_text::RichTextDelta}; use lib_ot::{errors::OTError, rich_text::RichTextDelta};
#[derive(ProtoBuf, Default, Debug, Clone)] #[derive(ProtoBuf, Default, Debug, Clone)]
pub struct CreateBlockParams { pub struct CreateTextBlockParams {
#[pb(index = 1)] #[pb(index = 1)]
pub id: String, pub id: String,
@ -15,7 +15,7 @@ pub struct CreateBlockParams {
} }
#[derive(ProtoBuf, Default, Debug, Clone, Eq, PartialEq)] #[derive(ProtoBuf, Default, Debug, Clone, Eq, PartialEq)]
pub struct BlockInfo { pub struct TextBlockInfo {
#[pb(index = 1)] #[pb(index = 1)]
pub block_id: String, pub block_id: String,
@ -29,14 +29,14 @@ pub struct BlockInfo {
pub base_rev_id: i64, pub base_rev_id: i64,
} }
impl BlockInfo { impl TextBlockInfo {
pub fn delta(&self) -> Result<RichTextDelta, OTError> { pub fn delta(&self) -> Result<RichTextDelta, OTError> {
let delta = RichTextDelta::from_bytes(&self.text)?; let delta = RichTextDelta::from_bytes(&self.text)?;
Ok(delta) Ok(delta)
} }
} }
impl std::convert::TryFrom<Revision> for BlockInfo { impl std::convert::TryFrom<Revision> for TextBlockInfo {
type Error = CollaborateError; type Error = CollaborateError;
fn try_from(revision: Revision) -> Result<Self, Self::Error> { fn try_from(revision: Revision) -> Result<Self, Self::Error> {
@ -48,7 +48,7 @@ impl std::convert::TryFrom<Revision> for BlockInfo {
let delta = RichTextDelta::from_bytes(&revision.delta_data)?; let delta = RichTextDelta::from_bytes(&revision.delta_data)?;
let doc_json = delta.to_delta_str(); let doc_json = delta.to_delta_str();
Ok(BlockInfo { Ok(TextBlockInfo {
block_id: revision.object_id, block_id: revision.object_id,
text: doc_json, text: doc_json,
rev_id: revision.rev_id, rev_id: revision.rev_id,
@ -58,7 +58,7 @@ impl std::convert::TryFrom<Revision> for BlockInfo {
} }
#[derive(ProtoBuf, Default, Debug, Clone)] #[derive(ProtoBuf, Default, Debug, Clone)]
pub struct ResetBlockParams { pub struct ResetTextBlockParams {
#[pb(index = 1)] #[pb(index = 1)]
pub block_id: String, pub block_id: String,
@ -67,7 +67,7 @@ pub struct ResetBlockParams {
} }
#[derive(ProtoBuf, Default, Debug, Clone)] #[derive(ProtoBuf, Default, Debug, Clone)]
pub struct BlockDelta { pub struct TextBlockDelta {
#[pb(index = 1)] #[pb(index = 1)]
pub block_id: String, pub block_id: String,
@ -88,30 +88,30 @@ pub struct NewDocUser {
} }
#[derive(ProtoBuf, Default, Debug, Clone)] #[derive(ProtoBuf, Default, Debug, Clone)]
pub struct BlockId { pub struct TextBlockId {
#[pb(index = 1)] #[pb(index = 1)]
pub value: String, pub value: String,
} }
impl AsRef<str> for BlockId { impl AsRef<str> for TextBlockId {
fn as_ref(&self) -> &str { fn as_ref(&self) -> &str {
&self.value &self.value
} }
} }
impl std::convert::From<String> for BlockId { impl std::convert::From<String> for TextBlockId {
fn from(value: String) -> Self { fn from(value: String) -> Self {
BlockId { value } TextBlockId { value }
} }
} }
impl std::convert::From<BlockId> for String { impl std::convert::From<TextBlockId> for String {
fn from(block_id: BlockId) -> Self { fn from(block_id: TextBlockId) -> Self {
block_id.value block_id.value
} }
} }
impl std::convert::From<&String> for BlockId { impl std::convert::From<&String> for TextBlockId {
fn from(s: &String) -> Self { fn from(s: &String) -> Self {
BlockId { value: s.to_owned() } TextBlockId { value: s.to_owned() }
} }
} }

View File

@ -7,8 +7,8 @@ pub use folder_info::*;
mod ws_data; mod ws_data;
pub use ws_data::*; pub use ws_data::*;
mod text_block_info;
pub use text_block_info::*;
mod revision; mod revision;
pub use revision::*; pub use revision::*;
mod document_info;
pub use document_info::*;

View File

@ -17,14 +17,14 @@
#![allow(trivial_casts)] #![allow(trivial_casts)]
#![allow(unused_imports)] #![allow(unused_imports)]
#![allow(unused_results)] #![allow(unused_results)]
//! Generated file from `document_info.proto` //! Generated file from `text_block_info.proto`
/// Generated files are compatible only with the same version /// Generated files are compatible only with the same version
/// of protobuf runtime. /// of protobuf runtime.
// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; // const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2;
#[derive(PartialEq,Clone,Default)] #[derive(PartialEq,Clone,Default)]
pub struct CreateBlockParams { pub struct CreateTextBlockParams {
// message fields // message fields
pub id: ::std::string::String, pub id: ::std::string::String,
pub revisions: ::protobuf::SingularPtrField<super::revision::RepeatedRevision>, pub revisions: ::protobuf::SingularPtrField<super::revision::RepeatedRevision>,
@ -33,14 +33,14 @@ pub struct CreateBlockParams {
pub cached_size: ::protobuf::CachedSize, pub cached_size: ::protobuf::CachedSize,
} }
impl<'a> ::std::default::Default for &'a CreateBlockParams { impl<'a> ::std::default::Default for &'a CreateTextBlockParams {
fn default() -> &'a CreateBlockParams { fn default() -> &'a CreateTextBlockParams {
<CreateBlockParams as ::protobuf::Message>::default_instance() <CreateTextBlockParams as ::protobuf::Message>::default_instance()
} }
} }
impl CreateBlockParams { impl CreateTextBlockParams {
pub fn new() -> CreateBlockParams { pub fn new() -> CreateTextBlockParams {
::std::default::Default::default() ::std::default::Default::default()
} }
@ -104,7 +104,7 @@ impl CreateBlockParams {
} }
} }
impl ::protobuf::Message for CreateBlockParams { impl ::protobuf::Message for CreateTextBlockParams {
fn is_initialized(&self) -> bool { fn is_initialized(&self) -> bool {
for v in &self.revisions { for v in &self.revisions {
if !v.is_initialized() { if !v.is_initialized() {
@ -187,8 +187,8 @@ impl ::protobuf::Message for CreateBlockParams {
Self::descriptor_static() Self::descriptor_static()
} }
fn new() -> CreateBlockParams { fn new() -> CreateTextBlockParams {
CreateBlockParams::new() CreateTextBlockParams::new()
} }
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
@ -197,29 +197,29 @@ impl ::protobuf::Message for CreateBlockParams {
let mut fields = ::std::vec::Vec::new(); let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"id", "id",
|m: &CreateBlockParams| { &m.id }, |m: &CreateTextBlockParams| { &m.id },
|m: &mut CreateBlockParams| { &mut m.id }, |m: &mut CreateTextBlockParams| { &mut m.id },
)); ));
fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::revision::RepeatedRevision>>( fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::revision::RepeatedRevision>>(
"revisions", "revisions",
|m: &CreateBlockParams| { &m.revisions }, |m: &CreateTextBlockParams| { &m.revisions },
|m: &mut CreateBlockParams| { &mut m.revisions }, |m: &mut CreateTextBlockParams| { &mut m.revisions },
)); ));
::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateBlockParams>( ::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateTextBlockParams>(
"CreateBlockParams", "CreateTextBlockParams",
fields, fields,
file_descriptor_proto() file_descriptor_proto()
) )
}) })
} }
fn default_instance() -> &'static CreateBlockParams { fn default_instance() -> &'static CreateTextBlockParams {
static instance: ::protobuf::rt::LazyV2<CreateBlockParams> = ::protobuf::rt::LazyV2::INIT; static instance: ::protobuf::rt::LazyV2<CreateTextBlockParams> = ::protobuf::rt::LazyV2::INIT;
instance.get(CreateBlockParams::new) instance.get(CreateTextBlockParams::new)
} }
} }
impl ::protobuf::Clear for CreateBlockParams { impl ::protobuf::Clear for CreateTextBlockParams {
fn clear(&mut self) { fn clear(&mut self) {
self.id.clear(); self.id.clear();
self.revisions.clear(); self.revisions.clear();
@ -227,20 +227,20 @@ impl ::protobuf::Clear for CreateBlockParams {
} }
} }
impl ::std::fmt::Debug for CreateBlockParams { impl ::std::fmt::Debug for CreateTextBlockParams {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f) ::protobuf::text_format::fmt(self, f)
} }
} }
impl ::protobuf::reflect::ProtobufValue for CreateBlockParams { impl ::protobuf::reflect::ProtobufValue for CreateTextBlockParams {
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
::protobuf::reflect::ReflectValueRef::Message(self) ::protobuf::reflect::ReflectValueRef::Message(self)
} }
} }
#[derive(PartialEq,Clone,Default)] #[derive(PartialEq,Clone,Default)]
pub struct BlockInfo { pub struct TextBlockInfo {
// message fields // message fields
pub block_id: ::std::string::String, pub block_id: ::std::string::String,
pub text: ::std::string::String, pub text: ::std::string::String,
@ -251,14 +251,14 @@ pub struct BlockInfo {
pub cached_size: ::protobuf::CachedSize, pub cached_size: ::protobuf::CachedSize,
} }
impl<'a> ::std::default::Default for &'a BlockInfo { impl<'a> ::std::default::Default for &'a TextBlockInfo {
fn default() -> &'a BlockInfo { fn default() -> &'a TextBlockInfo {
<BlockInfo as ::protobuf::Message>::default_instance() <TextBlockInfo as ::protobuf::Message>::default_instance()
} }
} }
impl BlockInfo { impl TextBlockInfo {
pub fn new() -> BlockInfo { pub fn new() -> TextBlockInfo {
::std::default::Default::default() ::std::default::Default::default()
} }
@ -345,7 +345,7 @@ impl BlockInfo {
} }
} }
impl ::protobuf::Message for BlockInfo { impl ::protobuf::Message for TextBlockInfo {
fn is_initialized(&self) -> bool { fn is_initialized(&self) -> bool {
true true
} }
@ -446,8 +446,8 @@ impl ::protobuf::Message for BlockInfo {
Self::descriptor_static() Self::descriptor_static()
} }
fn new() -> BlockInfo { fn new() -> TextBlockInfo {
BlockInfo::new() TextBlockInfo::new()
} }
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
@ -456,39 +456,39 @@ impl ::protobuf::Message for BlockInfo {
let mut fields = ::std::vec::Vec::new(); let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"block_id", "block_id",
|m: &BlockInfo| { &m.block_id }, |m: &TextBlockInfo| { &m.block_id },
|m: &mut BlockInfo| { &mut m.block_id }, |m: &mut TextBlockInfo| { &mut m.block_id },
)); ));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"text", "text",
|m: &BlockInfo| { &m.text }, |m: &TextBlockInfo| { &m.text },
|m: &mut BlockInfo| { &mut m.text }, |m: &mut TextBlockInfo| { &mut m.text },
)); ));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>(
"rev_id", "rev_id",
|m: &BlockInfo| { &m.rev_id }, |m: &TextBlockInfo| { &m.rev_id },
|m: &mut BlockInfo| { &mut m.rev_id }, |m: &mut TextBlockInfo| { &mut m.rev_id },
)); ));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>(
"base_rev_id", "base_rev_id",
|m: &BlockInfo| { &m.base_rev_id }, |m: &TextBlockInfo| { &m.base_rev_id },
|m: &mut BlockInfo| { &mut m.base_rev_id }, |m: &mut TextBlockInfo| { &mut m.base_rev_id },
)); ));
::protobuf::reflect::MessageDescriptor::new_pb_name::<BlockInfo>( ::protobuf::reflect::MessageDescriptor::new_pb_name::<TextBlockInfo>(
"BlockInfo", "TextBlockInfo",
fields, fields,
file_descriptor_proto() file_descriptor_proto()
) )
}) })
} }
fn default_instance() -> &'static BlockInfo { fn default_instance() -> &'static TextBlockInfo {
static instance: ::protobuf::rt::LazyV2<BlockInfo> = ::protobuf::rt::LazyV2::INIT; static instance: ::protobuf::rt::LazyV2<TextBlockInfo> = ::protobuf::rt::LazyV2::INIT;
instance.get(BlockInfo::new) instance.get(TextBlockInfo::new)
} }
} }
impl ::protobuf::Clear for BlockInfo { impl ::protobuf::Clear for TextBlockInfo {
fn clear(&mut self) { fn clear(&mut self) {
self.block_id.clear(); self.block_id.clear();
self.text.clear(); self.text.clear();
@ -498,20 +498,20 @@ impl ::protobuf::Clear for BlockInfo {
} }
} }
impl ::std::fmt::Debug for BlockInfo { impl ::std::fmt::Debug for TextBlockInfo {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f) ::protobuf::text_format::fmt(self, f)
} }
} }
impl ::protobuf::reflect::ProtobufValue for BlockInfo { impl ::protobuf::reflect::ProtobufValue for TextBlockInfo {
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
::protobuf::reflect::ReflectValueRef::Message(self) ::protobuf::reflect::ReflectValueRef::Message(self)
} }
} }
#[derive(PartialEq,Clone,Default)] #[derive(PartialEq,Clone,Default)]
pub struct ResetBlockParams { pub struct ResetTextBlockParams {
// message fields // message fields
pub block_id: ::std::string::String, pub block_id: ::std::string::String,
pub revisions: ::protobuf::SingularPtrField<super::revision::RepeatedRevision>, pub revisions: ::protobuf::SingularPtrField<super::revision::RepeatedRevision>,
@ -520,14 +520,14 @@ pub struct ResetBlockParams {
pub cached_size: ::protobuf::CachedSize, pub cached_size: ::protobuf::CachedSize,
} }
impl<'a> ::std::default::Default for &'a ResetBlockParams { impl<'a> ::std::default::Default for &'a ResetTextBlockParams {
fn default() -> &'a ResetBlockParams { fn default() -> &'a ResetTextBlockParams {
<ResetBlockParams as ::protobuf::Message>::default_instance() <ResetTextBlockParams as ::protobuf::Message>::default_instance()
} }
} }
impl ResetBlockParams { impl ResetTextBlockParams {
pub fn new() -> ResetBlockParams { pub fn new() -> ResetTextBlockParams {
::std::default::Default::default() ::std::default::Default::default()
} }
@ -591,7 +591,7 @@ impl ResetBlockParams {
} }
} }
impl ::protobuf::Message for ResetBlockParams { impl ::protobuf::Message for ResetTextBlockParams {
fn is_initialized(&self) -> bool { fn is_initialized(&self) -> bool {
for v in &self.revisions { for v in &self.revisions {
if !v.is_initialized() { if !v.is_initialized() {
@ -674,8 +674,8 @@ impl ::protobuf::Message for ResetBlockParams {
Self::descriptor_static() Self::descriptor_static()
} }
fn new() -> ResetBlockParams { fn new() -> ResetTextBlockParams {
ResetBlockParams::new() ResetTextBlockParams::new()
} }
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
@ -684,29 +684,29 @@ impl ::protobuf::Message for ResetBlockParams {
let mut fields = ::std::vec::Vec::new(); let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"block_id", "block_id",
|m: &ResetBlockParams| { &m.block_id }, |m: &ResetTextBlockParams| { &m.block_id },
|m: &mut ResetBlockParams| { &mut m.block_id }, |m: &mut ResetTextBlockParams| { &mut m.block_id },
)); ));
fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::revision::RepeatedRevision>>( fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::revision::RepeatedRevision>>(
"revisions", "revisions",
|m: &ResetBlockParams| { &m.revisions }, |m: &ResetTextBlockParams| { &m.revisions },
|m: &mut ResetBlockParams| { &mut m.revisions }, |m: &mut ResetTextBlockParams| { &mut m.revisions },
)); ));
::protobuf::reflect::MessageDescriptor::new_pb_name::<ResetBlockParams>( ::protobuf::reflect::MessageDescriptor::new_pb_name::<ResetTextBlockParams>(
"ResetBlockParams", "ResetTextBlockParams",
fields, fields,
file_descriptor_proto() file_descriptor_proto()
) )
}) })
} }
fn default_instance() -> &'static ResetBlockParams { fn default_instance() -> &'static ResetTextBlockParams {
static instance: ::protobuf::rt::LazyV2<ResetBlockParams> = ::protobuf::rt::LazyV2::INIT; static instance: ::protobuf::rt::LazyV2<ResetTextBlockParams> = ::protobuf::rt::LazyV2::INIT;
instance.get(ResetBlockParams::new) instance.get(ResetTextBlockParams::new)
} }
} }
impl ::protobuf::Clear for ResetBlockParams { impl ::protobuf::Clear for ResetTextBlockParams {
fn clear(&mut self) { fn clear(&mut self) {
self.block_id.clear(); self.block_id.clear();
self.revisions.clear(); self.revisions.clear();
@ -714,20 +714,20 @@ impl ::protobuf::Clear for ResetBlockParams {
} }
} }
impl ::std::fmt::Debug for ResetBlockParams { impl ::std::fmt::Debug for ResetTextBlockParams {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f) ::protobuf::text_format::fmt(self, f)
} }
} }
impl ::protobuf::reflect::ProtobufValue for ResetBlockParams { impl ::protobuf::reflect::ProtobufValue for ResetTextBlockParams {
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
::protobuf::reflect::ReflectValueRef::Message(self) ::protobuf::reflect::ReflectValueRef::Message(self)
} }
} }
#[derive(PartialEq,Clone,Default)] #[derive(PartialEq,Clone,Default)]
pub struct BlockDelta { pub struct TextBlockDelta {
// message fields // message fields
pub block_id: ::std::string::String, pub block_id: ::std::string::String,
pub delta_str: ::std::string::String, pub delta_str: ::std::string::String,
@ -736,14 +736,14 @@ pub struct BlockDelta {
pub cached_size: ::protobuf::CachedSize, pub cached_size: ::protobuf::CachedSize,
} }
impl<'a> ::std::default::Default for &'a BlockDelta { impl<'a> ::std::default::Default for &'a TextBlockDelta {
fn default() -> &'a BlockDelta { fn default() -> &'a TextBlockDelta {
<BlockDelta as ::protobuf::Message>::default_instance() <TextBlockDelta as ::protobuf::Message>::default_instance()
} }
} }
impl BlockDelta { impl TextBlockDelta {
pub fn new() -> BlockDelta { pub fn new() -> TextBlockDelta {
::std::default::Default::default() ::std::default::Default::default()
} }
@ -800,7 +800,7 @@ impl BlockDelta {
} }
} }
impl ::protobuf::Message for BlockDelta { impl ::protobuf::Message for TextBlockDelta {
fn is_initialized(&self) -> bool { fn is_initialized(&self) -> bool {
true true
} }
@ -875,8 +875,8 @@ impl ::protobuf::Message for BlockDelta {
Self::descriptor_static() Self::descriptor_static()
} }
fn new() -> BlockDelta { fn new() -> TextBlockDelta {
BlockDelta::new() TextBlockDelta::new()
} }
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
@ -885,29 +885,29 @@ impl ::protobuf::Message for BlockDelta {
let mut fields = ::std::vec::Vec::new(); let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"block_id", "block_id",
|m: &BlockDelta| { &m.block_id }, |m: &TextBlockDelta| { &m.block_id },
|m: &mut BlockDelta| { &mut m.block_id }, |m: &mut TextBlockDelta| { &mut m.block_id },
)); ));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"delta_str", "delta_str",
|m: &BlockDelta| { &m.delta_str }, |m: &TextBlockDelta| { &m.delta_str },
|m: &mut BlockDelta| { &mut m.delta_str }, |m: &mut TextBlockDelta| { &mut m.delta_str },
)); ));
::protobuf::reflect::MessageDescriptor::new_pb_name::<BlockDelta>( ::protobuf::reflect::MessageDescriptor::new_pb_name::<TextBlockDelta>(
"BlockDelta", "TextBlockDelta",
fields, fields,
file_descriptor_proto() file_descriptor_proto()
) )
}) })
} }
fn default_instance() -> &'static BlockDelta { fn default_instance() -> &'static TextBlockDelta {
static instance: ::protobuf::rt::LazyV2<BlockDelta> = ::protobuf::rt::LazyV2::INIT; static instance: ::protobuf::rt::LazyV2<TextBlockDelta> = ::protobuf::rt::LazyV2::INIT;
instance.get(BlockDelta::new) instance.get(TextBlockDelta::new)
} }
} }
impl ::protobuf::Clear for BlockDelta { impl ::protobuf::Clear for TextBlockDelta {
fn clear(&mut self) { fn clear(&mut self) {
self.block_id.clear(); self.block_id.clear();
self.delta_str.clear(); self.delta_str.clear();
@ -915,13 +915,13 @@ impl ::protobuf::Clear for BlockDelta {
} }
} }
impl ::std::fmt::Debug for BlockDelta { impl ::std::fmt::Debug for TextBlockDelta {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f) ::protobuf::text_format::fmt(self, f)
} }
} }
impl ::protobuf::reflect::ProtobufValue for BlockDelta { impl ::protobuf::reflect::ProtobufValue for TextBlockDelta {
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
::protobuf::reflect::ReflectValueRef::Message(self) ::protobuf::reflect::ReflectValueRef::Message(self)
} }
@ -1164,7 +1164,7 @@ impl ::protobuf::reflect::ProtobufValue for NewDocUser {
} }
#[derive(PartialEq,Clone,Default)] #[derive(PartialEq,Clone,Default)]
pub struct BlockId { pub struct TextBlockId {
// message fields // message fields
pub value: ::std::string::String, pub value: ::std::string::String,
// special fields // special fields
@ -1172,14 +1172,14 @@ pub struct BlockId {
pub cached_size: ::protobuf::CachedSize, pub cached_size: ::protobuf::CachedSize,
} }
impl<'a> ::std::default::Default for &'a BlockId { impl<'a> ::std::default::Default for &'a TextBlockId {
fn default() -> &'a BlockId { fn default() -> &'a TextBlockId {
<BlockId as ::protobuf::Message>::default_instance() <TextBlockId as ::protobuf::Message>::default_instance()
} }
} }
impl BlockId { impl TextBlockId {
pub fn new() -> BlockId { pub fn new() -> TextBlockId {
::std::default::Default::default() ::std::default::Default::default()
} }
@ -1210,7 +1210,7 @@ impl BlockId {
} }
} }
impl ::protobuf::Message for BlockId { impl ::protobuf::Message for TextBlockId {
fn is_initialized(&self) -> bool { fn is_initialized(&self) -> bool {
true true
} }
@ -1276,8 +1276,8 @@ impl ::protobuf::Message for BlockId {
Self::descriptor_static() Self::descriptor_static()
} }
fn new() -> BlockId { fn new() -> TextBlockId {
BlockId::new() TextBlockId::new()
} }
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
@ -1286,57 +1286,57 @@ impl ::protobuf::Message for BlockId {
let mut fields = ::std::vec::Vec::new(); let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"value", "value",
|m: &BlockId| { &m.value }, |m: &TextBlockId| { &m.value },
|m: &mut BlockId| { &mut m.value }, |m: &mut TextBlockId| { &mut m.value },
)); ));
::protobuf::reflect::MessageDescriptor::new_pb_name::<BlockId>( ::protobuf::reflect::MessageDescriptor::new_pb_name::<TextBlockId>(
"BlockId", "TextBlockId",
fields, fields,
file_descriptor_proto() file_descriptor_proto()
) )
}) })
} }
fn default_instance() -> &'static BlockId { fn default_instance() -> &'static TextBlockId {
static instance: ::protobuf::rt::LazyV2<BlockId> = ::protobuf::rt::LazyV2::INIT; static instance: ::protobuf::rt::LazyV2<TextBlockId> = ::protobuf::rt::LazyV2::INIT;
instance.get(BlockId::new) instance.get(TextBlockId::new)
} }
} }
impl ::protobuf::Clear for BlockId { impl ::protobuf::Clear for TextBlockId {
fn clear(&mut self) { fn clear(&mut self) {
self.value.clear(); self.value.clear();
self.unknown_fields.clear(); self.unknown_fields.clear();
} }
} }
impl ::std::fmt::Debug for BlockId { impl ::std::fmt::Debug for TextBlockId {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f) ::protobuf::text_format::fmt(self, f)
} }
} }
impl ::protobuf::reflect::ProtobufValue for BlockId { impl ::protobuf::reflect::ProtobufValue for TextBlockId {
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
::protobuf::reflect::ReflectValueRef::Message(self) ::protobuf::reflect::ReflectValueRef::Message(self)
} }
} }
static file_descriptor_proto_data: &'static [u8] = b"\ static file_descriptor_proto_data: &'static [u8] = b"\
\n\x13document_info.proto\x1a\x0erevision.proto\"T\n\x11CreateBlockParam\ \n\x15text_block_info.proto\x1a\x0erevision.proto\"X\n\x15CreateTextBloc\
s\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12/\n\trevisions\x18\x02\ kParams\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12/\n\trevisions\x18\
\x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"q\n\tBlockInfo\x12\x19\ \x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"u\n\rTextBlockInfo\
\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x12\n\x04text\x18\x02\ \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x12\n\x04text\
\x20\x01(\tR\x04text\x12\x15\n\x06rev_id\x18\x03\x20\x01(\x03R\x05revId\ \x18\x02\x20\x01(\tR\x04text\x12\x15\n\x06rev_id\x18\x03\x20\x01(\x03R\
\x12\x1e\n\x0bbase_rev_id\x18\x04\x20\x01(\x03R\tbaseRevId\"^\n\x10Reset\ \x05revId\x12\x1e\n\x0bbase_rev_id\x18\x04\x20\x01(\x03R\tbaseRevId\"b\n\
BlockParams\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12/\n\ \x14ResetTextBlockParams\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07bl\
\trevisions\x18\x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"D\n\ ockId\x12/\n\trevisions\x18\x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trev\
\nBlockDelta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\ isions\"H\n\x0eTextBlockDelta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\
\x1b\n\tdelta_str\x18\x02\x20\x01(\tR\x08deltaStr\"S\n\nNewDocUser\x12\ \x07blockId\x12\x1b\n\tdelta_str\x18\x02\x20\x01(\tR\x08deltaStr\"S\n\nN\
\x17\n\x07user_id\x18\x01\x20\x01(\tR\x06userId\x12\x15\n\x06rev_id\x18\ ewDocUser\x12\x17\n\x07user_id\x18\x01\x20\x01(\tR\x06userId\x12\x15\n\
\x02\x20\x01(\x03R\x05revId\x12\x15\n\x06doc_id\x18\x03\x20\x01(\tR\x05d\ \x06rev_id\x18\x02\x20\x01(\x03R\x05revId\x12\x15\n\x06doc_id\x18\x03\
ocId\"\x1f\n\x07BlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05valueb\ \x20\x01(\tR\x05docId\"#\n\x0bTextBlockId\x12\x14\n\x05value\x18\x01\x20\
\x06proto3\ \x01(\tR\x05valueb\x06proto3\
"; ";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -1,21 +1,21 @@
syntax = "proto3"; syntax = "proto3";
import "revision.proto"; import "revision.proto";
message CreateBlockParams { message CreateTextBlockParams {
string id = 1; string id = 1;
RepeatedRevision revisions = 2; RepeatedRevision revisions = 2;
} }
message BlockInfo { message TextBlockInfo {
string block_id = 1; string block_id = 1;
string text = 2; string text = 2;
int64 rev_id = 3; int64 rev_id = 3;
int64 base_rev_id = 4; int64 base_rev_id = 4;
} }
message ResetBlockParams { message ResetTextBlockParams {
string block_id = 1; string block_id = 1;
RepeatedRevision revisions = 2; RepeatedRevision revisions = 2;
} }
message BlockDelta { message TextBlockDelta {
string block_id = 1; string block_id = 1;
string delta_str = 2; string delta_str = 2;
} }
@ -24,6 +24,6 @@ message NewDocUser {
int64 rev_id = 2; int64 rev_id = 2;
string doc_id = 3; string doc_id = 3;
} }
message BlockId { message TextBlockId {
string value = 1; string value = 1;
} }

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
entities::{document_info::BlockInfo, ws_data::ServerRevisionWSDataBuilder}, entities::{text_block_info::TextBlockInfo, ws_data::ServerRevisionWSDataBuilder},
errors::{internal_error, CollaborateError, CollaborateResult}, errors::{internal_error, CollaborateError, CollaborateResult},
protobuf::{ClientRevisionWSData, RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB}, protobuf::{ClientRevisionWSData, RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB},
server_document::document_pad::ServerDocument, server_document::document_pad::ServerDocument,
@ -18,13 +18,13 @@ use tokio::{
}; };
pub trait DocumentCloudPersistence: Send + Sync + Debug { pub trait DocumentCloudPersistence: Send + Sync + Debug {
fn read_document(&self, doc_id: &str) -> BoxResultFuture<BlockInfo, CollaborateError>; fn read_document(&self, doc_id: &str) -> BoxResultFuture<TextBlockInfo, CollaborateError>;
fn create_document( fn create_document(
&self, &self,
doc_id: &str, doc_id: &str,
repeated_revision: RepeatedRevisionPB, repeated_revision: RepeatedRevisionPB,
) -> BoxResultFuture<Option<BlockInfo>, CollaborateError>; ) -> BoxResultFuture<Option<TextBlockInfo>, CollaborateError>;
fn read_document_revisions( fn read_document_revisions(
&self, &self,
@ -181,7 +181,7 @@ impl ServerDocumentManager {
} }
} }
async fn create_document_handler(&self, doc: BlockInfo) -> Result<Arc<OpenDocumentHandler>, CollaborateError> { async fn create_document_handler(&self, doc: TextBlockInfo) -> Result<Arc<OpenDocumentHandler>, CollaborateError> {
let persistence = self.persistence.clone(); let persistence = self.persistence.clone();
let handle = spawn_blocking(|| OpenDocumentHandler::new(doc, persistence)) let handle = spawn_blocking(|| OpenDocumentHandler::new(doc, persistence))
.await .await
@ -205,7 +205,7 @@ struct OpenDocumentHandler {
} }
impl OpenDocumentHandler { impl OpenDocumentHandler {
fn new(doc: BlockInfo, persistence: Arc<dyn DocumentCloudPersistence>) -> Result<Self, CollaborateError> { fn new(doc: TextBlockInfo, persistence: Arc<dyn DocumentCloudPersistence>) -> Result<Self, CollaborateError> {
let doc_id = doc.block_id.clone(); let doc_id = doc.block_id.clone();
let (sender, receiver) = mpsc::channel(1000); let (sender, receiver) = mpsc::channel(1000);
let users = DashMap::new(); let users = DashMap::new();

View File

@ -1,13 +1,13 @@
use crate::{ use crate::{
entities::{ entities::{
document_info::BlockInfo,
folder_info::{FolderDelta, FolderInfo}, folder_info::{FolderDelta, FolderInfo},
revision::{RepeatedRevision, Revision}, revision::{RepeatedRevision, Revision},
text_block_info::TextBlockInfo,
}, },
errors::{CollaborateError, CollaborateResult}, errors::{CollaborateError, CollaborateResult},
protobuf::{ protobuf::{
BlockInfo as BlockInfoPB, FolderInfo as FolderInfoPB, RepeatedRevision as RepeatedRevisionPB, FolderInfo as FolderInfoPB, RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB,
Revision as RevisionPB, TextBlockInfo as TextBlockInfoPB,
}, },
}; };
use dissimilar::Chunk; use dissimilar::Chunk;
@ -202,11 +202,11 @@ pub fn make_folder_pb_from_revisions_pb(
pub fn make_document_info_from_revisions_pb( pub fn make_document_info_from_revisions_pb(
doc_id: &str, doc_id: &str,
revisions: RepeatedRevisionPB, revisions: RepeatedRevisionPB,
) -> Result<Option<BlockInfo>, CollaborateError> { ) -> Result<Option<TextBlockInfo>, CollaborateError> {
match make_document_info_pb_from_revisions_pb(doc_id, revisions)? { match make_document_info_pb_from_revisions_pb(doc_id, revisions)? {
None => Ok(None), None => Ok(None),
Some(pb) => { Some(pb) => {
let document_info: BlockInfo = pb.try_into().map_err(|e| { let document_info: TextBlockInfo = pb.try_into().map_err(|e| {
CollaborateError::internal().context(format!("Deserialize document info from pb failed: {}", e)) CollaborateError::internal().context(format!("Deserialize document info from pb failed: {}", e))
})?; })?;
Ok(Some(document_info)) Ok(Some(document_info))
@ -218,7 +218,7 @@ pub fn make_document_info_from_revisions_pb(
pub fn make_document_info_pb_from_revisions_pb( pub fn make_document_info_pb_from_revisions_pb(
doc_id: &str, doc_id: &str,
mut revisions: RepeatedRevisionPB, mut revisions: RepeatedRevisionPB,
) -> Result<Option<BlockInfoPB>, CollaborateError> { ) -> Result<Option<TextBlockInfoPB>, CollaborateError> {
let revisions = revisions.take_items(); let revisions = revisions.take_items();
if revisions.is_empty() { if revisions.is_empty() {
return Ok(None); return Ok(None);
@ -240,7 +240,7 @@ pub fn make_document_info_pb_from_revisions_pb(
} }
let text = document_delta.to_delta_str(); let text = document_delta.to_delta_str();
let mut block_info = BlockInfoPB::new(); let mut block_info = TextBlockInfoPB::new();
block_info.set_block_id(doc_id.to_owned()); block_info.set_block_id(doc_id.to_owned());
block_info.set_text(text); block_info.set_text(text);
block_info.set_base_rev_id(base_rev_id); block_info.set_base_rev_id(base_rev_id);

View File

@ -1,8 +1,6 @@
use crate::entities::{Field, RowMeta}; use crate::entities::{Field, RowMeta};
use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_derive::ProtoBuf;
use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
use strum_macros::{Display, EnumIter, EnumString};
pub const DEFAULT_ROW_HEIGHT: i32 = 36; pub const DEFAULT_ROW_HEIGHT: i32 = 36;
pub const DEFAULT_FIELD_WIDTH: i32 = 150; pub const DEFAULT_FIELD_WIDTH: i32 = 150;

View File

@ -1,4 +1,3 @@
use crate::entities::Row;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
@ -16,14 +15,26 @@ pub struct GridMeta {
pub fields: Vec<Field>, pub fields: Vec<Field>,
#[pb(index = 3)] #[pb(index = 3)]
pub rows: Vec<RowMeta>, pub blocks: Vec<Block>,
} }
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
pub struct GridBlock { pub struct Block {
#[pb(index = 1)] #[pb(index = 1)]
pub id: String, pub id: String,
#[pb(index = 2)]
pub start_row_index: i32,
#[pb(index = 3)]
pub row_count: i32,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
pub struct BlockMeta {
#[pb(index = 1)]
pub block_id: String,
#[pb(index = 2)] #[pb(index = 2)]
pub rows: Vec<RowMeta>, pub rows: Vec<RowMeta>,
} }

View File

@ -28,7 +28,7 @@ pub struct GridMeta {
// message fields // message fields
pub grid_id: ::std::string::String, pub grid_id: ::std::string::String,
pub fields: ::protobuf::RepeatedField<Field>, pub fields: ::protobuf::RepeatedField<Field>,
pub rows: ::protobuf::RepeatedField<RowMeta>, pub blocks: ::protobuf::RepeatedField<Block>,
// special fields // special fields
pub unknown_fields: ::protobuf::UnknownFields, pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize, pub cached_size: ::protobuf::CachedSize,
@ -96,29 +96,29 @@ impl GridMeta {
::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new())
} }
// repeated .RowMeta rows = 3; // repeated .Block blocks = 3;
pub fn get_rows(&self) -> &[RowMeta] { pub fn get_blocks(&self) -> &[Block] {
&self.rows &self.blocks
} }
pub fn clear_rows(&mut self) { pub fn clear_blocks(&mut self) {
self.rows.clear(); self.blocks.clear();
} }
// Param is passed by value, moved // Param is passed by value, moved
pub fn set_rows(&mut self, v: ::protobuf::RepeatedField<RowMeta>) { pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField<Block>) {
self.rows = v; self.blocks = v;
} }
// Mutable pointer to the field. // Mutable pointer to the field.
pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField<RowMeta> { pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField<Block> {
&mut self.rows &mut self.blocks
} }
// Take field // Take field
pub fn take_rows(&mut self) -> ::protobuf::RepeatedField<RowMeta> { pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField<Block> {
::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new())
} }
} }
@ -129,7 +129,7 @@ impl ::protobuf::Message for GridMeta {
return false; return false;
} }
}; };
for v in &self.rows { for v in &self.blocks {
if !v.is_initialized() { if !v.is_initialized() {
return false; return false;
} }
@ -148,7 +148,7 @@ impl ::protobuf::Message for GridMeta {
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.fields)?; ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.fields)?;
}, },
3 => { 3 => {
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; ::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())?; ::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(); let len = value.compute_size();
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
}; };
for value in &self.rows { for value in &self.blocks {
let len = value.compute_size(); let len = value.compute_size();
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; 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())?; os.write_raw_varint32(v.get_cached_size())?;
v.write_to_with_cached_sizes(os)?; v.write_to_with_cached_sizes(os)?;
}; };
for v in &self.rows { for v in &self.blocks {
os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
os.write_raw_varint32(v.get_cached_size())?; os.write_raw_varint32(v.get_cached_size())?;
v.write_to_with_cached_sizes(os)?; v.write_to_with_cached_sizes(os)?;
@ -240,10 +240,10 @@ impl ::protobuf::Message for GridMeta {
|m: &GridMeta| { &m.fields }, |m: &GridMeta| { &m.fields },
|m: &mut GridMeta| { &mut m.fields }, |m: &mut GridMeta| { &mut m.fields },
)); ));
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<RowMeta>>( fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Block>>(
"rows", "blocks",
|m: &GridMeta| { &m.rows }, |m: &GridMeta| { &m.blocks },
|m: &mut GridMeta| { &mut m.rows }, |m: &mut GridMeta| { &mut m.blocks },
)); ));
::protobuf::reflect::MessageDescriptor::new_pb_name::<GridMeta>( ::protobuf::reflect::MessageDescriptor::new_pb_name::<GridMeta>(
"GridMeta", "GridMeta",
@ -263,7 +263,7 @@ impl ::protobuf::Clear for GridMeta {
fn clear(&mut self) { fn clear(&mut self) {
self.grid_id.clear(); self.grid_id.clear();
self.fields.clear(); self.fields.clear();
self.rows.clear(); self.blocks.clear();
self.unknown_fields.clear(); self.unknown_fields.clear();
} }
} }
@ -281,23 +281,24 @@ impl ::protobuf::reflect::ProtobufValue for GridMeta {
} }
#[derive(PartialEq,Clone,Default)] #[derive(PartialEq,Clone,Default)]
pub struct GridBlock { pub struct Block {
// message fields // message fields
pub id: ::std::string::String, pub id: ::std::string::String,
pub rows: ::protobuf::RepeatedField<RowMeta>, pub start_row_index: i32,
pub row_count: i32,
// special fields // special fields
pub unknown_fields: ::protobuf::UnknownFields, pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize, pub cached_size: ::protobuf::CachedSize,
} }
impl<'a> ::std::default::Default for &'a GridBlock { impl<'a> ::std::default::Default for &'a Block {
fn default() -> &'a GridBlock { fn default() -> &'a Block {
<GridBlock as ::protobuf::Message>::default_instance() <Block as ::protobuf::Message>::default_instance()
} }
} }
impl GridBlock { impl Block {
pub fn new() -> GridBlock { pub fn new() -> Block {
::std::default::Default::default() ::std::default::Default::default()
} }
@ -327,6 +328,234 @@ impl GridBlock {
::std::mem::replace(&mut self.id, ::std::string::String::new()) ::std::mem::replace(&mut self.id, ::std::string::String::new())
} }
// int32 start_row_index = 2;
pub fn get_start_row_index(&self) -> i32 {
self.start_row_index
}
pub fn clear_start_row_index(&mut self) {
self.start_row_index = 0;
}
// Param is passed by value, moved
pub fn set_start_row_index(&mut self, v: i32) {
self.start_row_index = v;
}
// int32 row_count = 3;
pub fn get_row_count(&self) -> i32 {
self.row_count
}
pub fn clear_row_count(&mut self) {
self.row_count = 0;
}
// Param is passed by value, moved
pub fn set_row_count(&mut self, v: i32) {
self.row_count = v;
}
}
impl ::protobuf::Message for Block {
fn is_initialized(&self) -> bool {
true
}
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
while !is.eof()? {
let (field_number, wire_type) = is.read_tag_unpack()?;
match field_number {
1 => {
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?;
},
2 => {
if wire_type != ::protobuf::wire_format::WireTypeVarint {
return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
}
let tmp = is.read_int32()?;
self.start_row_index = tmp;
},
3 => {
if wire_type != ::protobuf::wire_format::WireTypeVarint {
return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
}
let tmp = is.read_int32()?;
self.row_count = tmp;
},
_ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
},
};
}
::std::result::Result::Ok(())
}
// Compute sizes of nested messages
#[allow(unused_variables)]
fn compute_size(&self) -> u32 {
let mut my_size = 0;
if !self.id.is_empty() {
my_size += ::protobuf::rt::string_size(1, &self.id);
}
if self.start_row_index != 0 {
my_size += ::protobuf::rt::value_size(2, self.start_row_index, ::protobuf::wire_format::WireTypeVarint);
}
if self.row_count != 0 {
my_size += ::protobuf::rt::value_size(3, self.row_count, ::protobuf::wire_format::WireTypeVarint);
}
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size);
my_size
}
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
if !self.id.is_empty() {
os.write_string(1, &self.id)?;
}
if self.start_row_index != 0 {
os.write_int32(2, self.start_row_index)?;
}
if self.row_count != 0 {
os.write_int32(3, self.row_count)?;
}
os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(())
}
fn get_cached_size(&self) -> u32 {
self.cached_size.get()
}
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
&self.unknown_fields
}
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
&mut self.unknown_fields
}
fn as_any(&self) -> &dyn (::std::any::Any) {
self as &dyn (::std::any::Any)
}
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
self as &mut dyn (::std::any::Any)
}
fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
self
}
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
Self::descriptor_static()
}
fn new() -> Block {
Block::new()
}
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
descriptor.get(|| {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"id",
|m: &Block| { &m.id },
|m: &mut Block| { &mut m.id },
));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
"start_row_index",
|m: &Block| { &m.start_row_index },
|m: &mut Block| { &mut m.start_row_index },
));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
"row_count",
|m: &Block| { &m.row_count },
|m: &mut Block| { &mut m.row_count },
));
::protobuf::reflect::MessageDescriptor::new_pb_name::<Block>(
"Block",
fields,
file_descriptor_proto()
)
})
}
fn default_instance() -> &'static Block {
static instance: ::protobuf::rt::LazyV2<Block> = ::protobuf::rt::LazyV2::INIT;
instance.get(Block::new)
}
}
impl ::protobuf::Clear for Block {
fn clear(&mut self) {
self.id.clear();
self.start_row_index = 0;
self.row_count = 0;
self.unknown_fields.clear();
}
}
impl ::std::fmt::Debug for Block {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for Block {
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
::protobuf::reflect::ReflectValueRef::Message(self)
}
}
#[derive(PartialEq,Clone,Default)]
pub struct BlockMeta {
// message fields
pub block_id: ::std::string::String,
pub rows: ::protobuf::RepeatedField<RowMeta>,
// special fields
pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize,
}
impl<'a> ::std::default::Default for &'a BlockMeta {
fn default() -> &'a BlockMeta {
<BlockMeta as ::protobuf::Message>::default_instance()
}
}
impl BlockMeta {
pub fn new() -> BlockMeta {
::std::default::Default::default()
}
// string block_id = 1;
pub fn get_block_id(&self) -> &str {
&self.block_id
}
pub fn clear_block_id(&mut self) {
self.block_id.clear();
}
// Param is passed by value, moved
pub fn set_block_id(&mut self, v: ::std::string::String) {
self.block_id = v;
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_block_id(&mut self) -> &mut ::std::string::String {
&mut self.block_id
}
// Take field
pub fn take_block_id(&mut self) -> ::std::string::String {
::std::mem::replace(&mut self.block_id, ::std::string::String::new())
}
// repeated .RowMeta rows = 2; // repeated .RowMeta rows = 2;
@ -353,7 +582,7 @@ impl GridBlock {
} }
} }
impl ::protobuf::Message for GridBlock { impl ::protobuf::Message for BlockMeta {
fn is_initialized(&self) -> bool { fn is_initialized(&self) -> bool {
for v in &self.rows { for v in &self.rows {
if !v.is_initialized() { if !v.is_initialized() {
@ -368,7 +597,7 @@ impl ::protobuf::Message for GridBlock {
let (field_number, wire_type) = is.read_tag_unpack()?; let (field_number, wire_type) = is.read_tag_unpack()?;
match field_number { match field_number {
1 => { 1 => {
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?;
}, },
2 => { 2 => {
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?;
@ -385,8 +614,8 @@ impl ::protobuf::Message for GridBlock {
#[allow(unused_variables)] #[allow(unused_variables)]
fn compute_size(&self) -> u32 { fn compute_size(&self) -> u32 {
let mut my_size = 0; let mut my_size = 0;
if !self.id.is_empty() { if !self.block_id.is_empty() {
my_size += ::protobuf::rt::string_size(1, &self.id); my_size += ::protobuf::rt::string_size(1, &self.block_id);
} }
for value in &self.rows { for value in &self.rows {
let len = value.compute_size(); let len = value.compute_size();
@ -398,8 +627,8 @@ impl ::protobuf::Message for GridBlock {
} }
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
if !self.id.is_empty() { if !self.block_id.is_empty() {
os.write_string(1, &self.id)?; os.write_string(1, &self.block_id)?;
} }
for v in &self.rows { for v in &self.rows {
os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
@ -436,8 +665,8 @@ impl ::protobuf::Message for GridBlock {
Self::descriptor_static() Self::descriptor_static()
} }
fn new() -> GridBlock { fn new() -> BlockMeta {
GridBlock::new() BlockMeta::new()
} }
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
@ -445,44 +674,44 @@ impl ::protobuf::Message for GridBlock {
descriptor.get(|| { descriptor.get(|| {
let mut fields = ::std::vec::Vec::new(); let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"id", "block_id",
|m: &GridBlock| { &m.id }, |m: &BlockMeta| { &m.block_id },
|m: &mut GridBlock| { &mut m.id }, |m: &mut BlockMeta| { &mut m.block_id },
)); ));
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<RowMeta>>( fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<RowMeta>>(
"rows", "rows",
|m: &GridBlock| { &m.rows }, |m: &BlockMeta| { &m.rows },
|m: &mut GridBlock| { &mut m.rows }, |m: &mut BlockMeta| { &mut m.rows },
)); ));
::protobuf::reflect::MessageDescriptor::new_pb_name::<GridBlock>( ::protobuf::reflect::MessageDescriptor::new_pb_name::<BlockMeta>(
"GridBlock", "BlockMeta",
fields, fields,
file_descriptor_proto() file_descriptor_proto()
) )
}) })
} }
fn default_instance() -> &'static GridBlock { fn default_instance() -> &'static BlockMeta {
static instance: ::protobuf::rt::LazyV2<GridBlock> = ::protobuf::rt::LazyV2::INIT; static instance: ::protobuf::rt::LazyV2<BlockMeta> = ::protobuf::rt::LazyV2::INIT;
instance.get(GridBlock::new) instance.get(BlockMeta::new)
} }
} }
impl ::protobuf::Clear for GridBlock { impl ::protobuf::Clear for BlockMeta {
fn clear(&mut self) { fn clear(&mut self) {
self.id.clear(); self.block_id.clear();
self.rows.clear(); self.rows.clear();
self.unknown_fields.clear(); self.unknown_fields.clear();
} }
} }
impl ::std::fmt::Debug for GridBlock { impl ::std::fmt::Debug for BlockMeta {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f) ::protobuf::text_format::fmt(self, f)
} }
} }
impl ::protobuf::reflect::ProtobufValue for GridBlock { impl ::protobuf::reflect::ProtobufValue for BlockMeta {
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
::protobuf::reflect::ReflectValueRef::Message(self) ::protobuf::reflect::ReflectValueRef::Message(self)
} }
@ -1997,34 +2226,36 @@ impl ::protobuf::reflect::ProtobufValue for FieldType {
} }
static file_descriptor_proto_data: &'static [u8] = b"\ static file_descriptor_proto_data: &'static [u8] = b"\
\n\nmeta.proto\"a\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ \n\nmeta.proto\"c\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\
\x06gridId\x12\x1e\n\x06fields\x18\x02\x20\x03(\x0b2\x06.FieldR\x06field\ \x06gridId\x12\x1e\n\x06fields\x18\x02\x20\x03(\x0b2\x06.FieldR\x06field\
s\x12\x1c\n\x04rows\x18\x03\x20\x03(\x0b2\x08.RowMetaR\x04rows\"9\n\tGri\ s\x12\x1e\n\x06blocks\x18\x03\x20\x03(\x0b2\x06.BlockR\x06blocks\"\\\n\
dBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x1c\n\x04rows\x18\ \x05Block\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12&\n\x0fstart_row_\
\x02\x20\x03(\x0b2\x08.RowMetaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\ index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\
\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\ \x20\x01(\x05R\x08rowCount\"D\n\tBlockMeta\x12\x19\n\x08block_id\x18\x01\
\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_typ\ \x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.RowM\
e\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\ etaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\
\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\ \x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\
\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\x12+\n\ \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\
\x0ctype_options\x18\x08\x20\x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\ FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\
\rRepeatedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05i\ n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\
tems\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\ idth\x18\x07\x20\x01(\x05R\x05width\x12+\n\x0ctype_options\x18\x08\x20\
\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xfd\x01\n\x07RowMet\ \x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\rRepeatedField\x12\x1c\n\x05\
a\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\ items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"8\n\x07AnyData\x12\x17\
\x20\x01(\tR\x06gridId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\ \n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\
\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\ \x20\x01(\x0cR\x05value\"\xfd\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\
\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\ \x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\
\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\ \x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByFiel\
\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ dIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06he\
value:\x028\x01\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ ight\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\n\x12C\
\tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\ ellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\
field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\ \x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\x82\x01\
\x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05\ \n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06ro\
R\x06height*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\ w_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\
\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\ \tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyDataR\x04d\
\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06prot\ ata\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\n\tFieldType\
o3\ \x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08Date\
Time\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\
\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\
"; ";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -3,10 +3,15 @@ syntax = "proto3";
message GridMeta { message GridMeta {
string grid_id = 1; string grid_id = 1;
repeated Field fields = 2; repeated Field fields = 2;
repeated RowMeta rows = 3; repeated Block blocks = 3;
} }
message GridBlock { message Block {
string id = 1; string id = 1;
int32 start_row_index = 2;
int32 row_count = 3;
}
message BlockMeta {
string block_id = 1;
repeated RowMeta rows = 2; repeated RowMeta rows = 2;
} }
message Field { message Field {

View File

@ -7,14 +7,14 @@ fn grid_serde_test() {
let grid = GridMeta { let grid = GridMeta {
grid_id, grid_id,
fields, fields,
rows: vec![], blocks: vec![],
}; };
let grid_1_json = serde_json::to_string(&grid).unwrap(); let grid_1_json = serde_json::to_string(&grid).unwrap();
let _: Grid = serde_json::from_str(&grid_1_json).unwrap(); let _: GridMeta = serde_json::from_str(&grid_1_json).unwrap();
assert_eq!( assert_eq!(
grid_1_json, grid_1_json,
r#"{"id":"1","fields":[{"id":"1","name":"Text Field","desc":"","field_type":"RichText","frozen":false,"visibility":true,"width":150,"type_options":{"type_id":"","value":[]}}],"rows":[]}"# r#"{"id":"1","fields":[{"id":"1","name":"Text Field","desc":"","field_type":"RichText","frozen":false,"visibility":true,"width":150,"type_options":{"type_id":"","value":[]}}],"blocks":[]}"#
) )
} }
@ -24,11 +24,11 @@ fn grid_default_serde_test() {
let grid = GridMeta { let grid = GridMeta {
grid_id, grid_id,
fields: vec![], fields: vec![],
rows: vec![], blocks: vec![],
}; };
let json = serde_json::to_string(&grid).unwrap(); let json = serde_json::to_string(&grid).unwrap();
assert_eq!(json, r#"{"id":"1","fields":[],"row_orders":[]}"#) assert_eq!(json, r#"{"id":"1","fields":[],"blocks":[]}"#)
} }
fn create_field(field_id: &str) -> Field { fn create_field(field_id: &str) -> Field {