mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: rename struct
This commit is contained in:
parent
e45be3b81e
commit
7ac6a1dc89
@ -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/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:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
|
||||
|
@ -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/meta.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
@ -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/meta.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
@ -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/meta.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
@ -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/meta.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
@ -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/meta.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
@ -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:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
|
||||
|
||||
class GridInfo {
|
||||
List<Row> rows;
|
||||
|
@ -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-grid-data-model/grid.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
|
||||
|
||||
class GridService {
|
||||
Future<Either<Grid, FlowyError>> openGrid({required String gridId}) async {
|
||||
|
@ -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/widget/error_page.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/material.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
@ -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';
|
||||
|
||||
|
@ -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/meta.pb.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'checkbox_cell.dart';
|
||||
import 'date_cell.dart';
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:app_flowy/startup/startup.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/meta.pb.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:app_flowy/startup/startup.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/meta.pb.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:app_flowy/startup/startup.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/meta.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:app_flowy/startup/startup.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/meta.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SingleSelectCell extends StatefulWidget {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:app_flowy/startup/startup.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/meta.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
|
@ -5,7 +5,7 @@ import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.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_bloc/flutter_bloc.dart';
|
||||
|
||||
|
@ -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_ui/style_widget/button.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_bloc/flutter_bloc.dart';
|
||||
|
||||
|
@ -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/flowy-folder-data-model/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';
|
||||
|
||||
// ignore: unused_import
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Auto-generated, do not edit
|
||||
export './folder_info.pb.dart';
|
||||
export './ws_data.pb.dart';
|
||||
export './text_block_info.pb.dart';
|
||||
export './revision.pb.dart';
|
||||
export './document_info.pb.dart';
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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=');
|
@ -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';
|
||||
|
@ -17,7 +17,7 @@ class GridMeta extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create)
|
||||
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
|
||||
..pc<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
|
||||
;
|
||||
|
||||
@ -25,7 +25,7 @@ class GridMeta extends $pb.GeneratedMessage {
|
||||
factory GridMeta({
|
||||
$core.String? gridId,
|
||||
$core.Iterable<Field>? fields,
|
||||
$core.Iterable<RowMeta>? rows,
|
||||
$core.Iterable<Block>? blocks,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (gridId != null) {
|
||||
@ -34,8 +34,8 @@ class GridMeta extends $pb.GeneratedMessage {
|
||||
if (fields != null) {
|
||||
_result.fields.addAll(fields);
|
||||
}
|
||||
if (rows != null) {
|
||||
_result.rows.addAll(rows);
|
||||
if (blocks != null) {
|
||||
_result.blocks.addAll(blocks);
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
@ -73,50 +73,55 @@ class GridMeta extends $pb.GeneratedMessage {
|
||||
$core.List<Field> get fields => $_getList(1);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
$core.List<RowMeta> get rows => $_getList(2);
|
||||
$core.List<Block> get blocks => $_getList(2);
|
||||
}
|
||||
|
||||
class GridBlock extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create)
|
||||
class Block extends $pb.GeneratedMessage {
|
||||
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')
|
||||
..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
|
||||
;
|
||||
|
||||
GridBlock._() : super();
|
||||
factory GridBlock({
|
||||
Block._() : super();
|
||||
factory Block({
|
||||
$core.String? id,
|
||||
$core.Iterable<RowMeta>? rows,
|
||||
$core.int? startRowIndex,
|
||||
$core.int? rowCount,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (id != null) {
|
||||
_result.id = id;
|
||||
}
|
||||
if (rows != null) {
|
||||
_result.rows.addAll(rows);
|
||||
if (startRowIndex != null) {
|
||||
_result.startRowIndex = startRowIndex;
|
||||
}
|
||||
if (rowCount != null) {
|
||||
_result.rowCount = rowCount;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory GridBlock.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.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory Block.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')
|
||||
GridBlock clone() => GridBlock()..mergeFromMessage(this);
|
||||
Block clone() => Block()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'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;
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static GridBlock create() => GridBlock._();
|
||||
GridBlock createEmptyInstance() => create();
|
||||
static $pb.PbList<GridBlock> createRepeated() => $pb.PbList<GridBlock>();
|
||||
static Block create() => Block._();
|
||||
Block createEmptyInstance() => create();
|
||||
static $pb.PbList<Block> createRepeated() => $pb.PbList<Block>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static GridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GridBlock>(create);
|
||||
static GridBlock? _defaultInstance;
|
||||
static Block getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Block>(create);
|
||||
static Block? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.String get id => $_getSZ(0);
|
||||
@ -127,6 +132,76 @@ class GridBlock extends $pb.GeneratedMessage {
|
||||
@$pb.TagNumber(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)
|
||||
$core.List<RowMeta> get rows => $_getList(1);
|
||||
}
|
||||
|
@ -29,23 +29,35 @@ const GridMeta$json = const {
|
||||
'2': const [
|
||||
const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
|
||||
const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.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`.
|
||||
final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIcCgRyb3dzGAMgAygLMgguUm93TWV0YVIEcm93cw==');
|
||||
@$core.Deprecated('Use gridBlockDescriptor instead')
|
||||
const GridBlock$json = const {
|
||||
'1': 'GridBlock',
|
||||
final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIeCgZibG9ja3MYAyADKAsyBi5CbG9ja1IGYmxvY2tz');
|
||||
@$core.Deprecated('Use blockDescriptor instead')
|
||||
const Block$json = const {
|
||||
'1': 'Block',
|
||||
'2': const [
|
||||
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'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSDgoCaWQYASABKAlSAmlkEhwKBHJvd3MYAiADKAsyCC5Sb3dNZXRhUgRyb3dz');
|
||||
/// Descriptor for `BlockMeta`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List blockMetaDescriptor = $convert.base64Decode('CglCbG9ja01ldGESGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSHAoEcm93cxgCIAMoCzIILlJvd01ldGFSBHJvd3M=');
|
||||
@$core.Deprecated('Use fieldDescriptor instead')
|
||||
const Field$json = const {
|
||||
'1': 'Field',
|
||||
|
@ -3,12 +3,12 @@ use crate::web_socket::{make_block_ws_manager, EditorCommandSender};
|
||||
use crate::{
|
||||
errors::FlowyError,
|
||||
queue::{EditBlockQueue, EditorCommand},
|
||||
BlockUser,
|
||||
TextBlockUser,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use flowy_collaboration::entities::ws_data::ServerRevisionWSData;
|
||||
use flowy_collaboration::{
|
||||
entities::{document_info::BlockInfo, revision::Revision},
|
||||
entities::{revision::Revision, text_block_info::TextBlockInfo},
|
||||
errors::CollaborateResult,
|
||||
util::make_delta_from_revisions,
|
||||
};
|
||||
@ -24,7 +24,7 @@ use lib_ws::WSConnectState;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
|
||||
pub struct ClientBlockEditor {
|
||||
pub struct ClientTextBlockEditor {
|
||||
pub doc_id: String,
|
||||
#[allow(dead_code)]
|
||||
rev_manager: Arc<RevisionManager>,
|
||||
@ -32,10 +32,10 @@ pub struct ClientBlockEditor {
|
||||
edit_cmd_tx: EditorCommandSender,
|
||||
}
|
||||
|
||||
impl ClientBlockEditor {
|
||||
impl ClientTextBlockEditor {
|
||||
pub(crate) async fn new(
|
||||
doc_id: &str,
|
||||
user: Arc<dyn BlockUser>,
|
||||
user: Arc<dyn TextBlockUser>,
|
||||
mut rev_manager: RevisionManager,
|
||||
rev_web_socket: Arc<dyn RevisionWebSocket>,
|
||||
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) {
|
||||
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.
|
||||
fn spawn_edit_queue(
|
||||
user: Arc<dyn BlockUser>,
|
||||
user: Arc<dyn TextBlockUser>,
|
||||
rev_manager: Arc<RevisionManager>,
|
||||
delta: RichTextDelta,
|
||||
) -> EditorCommandSender {
|
||||
@ -193,7 +193,7 @@ fn spawn_edit_queue(
|
||||
}
|
||||
|
||||
#[cfg(feature = "flowy_unit_test")]
|
||||
impl ClientBlockEditor {
|
||||
impl ClientTextBlockEditor {
|
||||
pub async fn doc_json(&self) -> FlowyResult<String> {
|
||||
let (ret, rx) = oneshot::channel::<CollaborateResult<String>>();
|
||||
let msg = EditorCommand::ReadDeltaStr { ret };
|
||||
@ -217,14 +217,14 @@ impl ClientBlockEditor {
|
||||
|
||||
struct BlockInfoBuilder();
|
||||
impl RevisionObjectBuilder for BlockInfoBuilder {
|
||||
type Output = BlockInfo;
|
||||
type Output = TextBlockInfo;
|
||||
|
||||
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 mut delta = make_delta_from_revisions(revisions)?;
|
||||
correct_delta(&mut delta);
|
||||
|
||||
Result::<BlockInfo, FlowyError>::Ok(BlockInfo {
|
||||
Result::<TextBlockInfo, FlowyError>::Ok(TextBlockInfo {
|
||||
block_id: object_id.to_owned(),
|
||||
text: delta.to_delta_str(),
|
||||
rev_id,
|
@ -1,28 +1,28 @@
|
||||
use crate::entities::{ExportData, ExportParams, ExportPayload};
|
||||
use crate::BlockManager;
|
||||
use flowy_collaboration::entities::document_info::{BlockDelta, BlockId};
|
||||
use crate::TextBlockManager;
|
||||
use flowy_collaboration::entities::text_block_info::{TextBlockDelta, TextBlockId};
|
||||
use flowy_error::FlowyError;
|
||||
use lib_dispatch::prelude::{data_result, AppData, Data, DataResult};
|
||||
use std::convert::TryInto;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub(crate) async fn get_block_data_handler(
|
||||
data: Data<BlockId>,
|
||||
manager: AppData<Arc<BlockManager>>,
|
||||
) -> DataResult<BlockDelta, FlowyError> {
|
||||
let block_id: BlockId = data.into_inner();
|
||||
data: Data<TextBlockId>,
|
||||
manager: AppData<Arc<TextBlockManager>>,
|
||||
) -> DataResult<TextBlockDelta, FlowyError> {
|
||||
let block_id: TextBlockId = data.into_inner();
|
||||
let editor = manager.open_block(&block_id).await?;
|
||||
let delta_str = editor.delta_str().await?;
|
||||
data_result(BlockDelta {
|
||||
data_result(TextBlockDelta {
|
||||
block_id: block_id.into(),
|
||||
delta_str,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) async fn apply_delta_handler(
|
||||
data: Data<BlockDelta>,
|
||||
manager: AppData<Arc<BlockManager>>,
|
||||
) -> DataResult<BlockDelta, FlowyError> {
|
||||
data: Data<TextBlockDelta>,
|
||||
manager: AppData<Arc<TextBlockManager>>,
|
||||
) -> DataResult<TextBlockDelta, FlowyError> {
|
||||
let block_delta = manager.receive_local_delta(data.into_inner()).await?;
|
||||
data_result(block_delta)
|
||||
}
|
||||
@ -30,7 +30,7 @@ pub(crate) async fn apply_delta_handler(
|
||||
#[tracing::instrument(skip(data, manager), err)]
|
||||
pub(crate) async fn export_handler(
|
||||
data: Data<ExportPayload>,
|
||||
manager: AppData<Arc<BlockManager>>,
|
||||
manager: AppData<Arc<TextBlockManager>>,
|
||||
) -> DataResult<ExportData, FlowyError> {
|
||||
let params: ExportParams = data.into_inner().try_into()?;
|
||||
let editor = manager.open_block(¶ms.view_id).await?;
|
||||
|
@ -1,11 +1,11 @@
|
||||
use crate::event_handler::*;
|
||||
use crate::BlockManager;
|
||||
use crate::TextBlockManager;
|
||||
use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
|
||||
use lib_dispatch::prelude::Module;
|
||||
use std::sync::Arc;
|
||||
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);
|
||||
|
||||
module = module
|
||||
|
@ -1,4 +1,4 @@
|
||||
pub mod block_editor;
|
||||
pub mod editor;
|
||||
mod entities;
|
||||
mod event_handler;
|
||||
pub mod event_map;
|
||||
@ -15,13 +15,15 @@ pub mod errors {
|
||||
pub const DOCUMENT_SYNC_INTERVAL_IN_MILLIS: u64 = 1000;
|
||||
|
||||
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;
|
||||
|
||||
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>;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::{block_editor::ClientBlockEditor, errors::FlowyError, BlockCloudService};
|
||||
use crate::{editor::ClientTextBlockEditor, errors::FlowyError, BlockCloudService};
|
||||
use bytes::Bytes;
|
||||
use dashmap::DashMap;
|
||||
use flowy_collaboration::entities::{
|
||||
document_info::{BlockDelta, BlockId},
|
||||
revision::{md5, RepeatedRevision, Revision},
|
||||
text_block_info::{TextBlockDelta, TextBlockId},
|
||||
ws_data::ServerRevisionWSData,
|
||||
};
|
||||
use flowy_database::ConnectionPool;
|
||||
@ -12,43 +12,42 @@ use flowy_sync::{RevisionCloudService, RevisionManager, RevisionPersistence, Rev
|
||||
use lib_infra::future::FutureResult;
|
||||
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_id(&self) -> Result<String, FlowyError>;
|
||||
fn token(&self) -> Result<String, FlowyError>;
|
||||
fn db_pool(&self) -> Result<Arc<ConnectionPool>, FlowyError>;
|
||||
}
|
||||
|
||||
pub struct BlockManager {
|
||||
pub struct TextBlockManager {
|
||||
cloud_service: Arc<dyn BlockCloudService>,
|
||||
rev_web_socket: Arc<dyn RevisionWebSocket>,
|
||||
block_editors: Arc<BlockEditors>,
|
||||
block_user: Arc<dyn BlockUser>,
|
||||
editor_map: Arc<TextBlockEditorMap>,
|
||||
user: Arc<dyn TextBlockUser>,
|
||||
}
|
||||
|
||||
impl BlockManager {
|
||||
impl TextBlockManager {
|
||||
pub fn new(
|
||||
cloud_service: Arc<dyn BlockCloudService>,
|
||||
block_user: Arc<dyn BlockUser>,
|
||||
text_block_user: Arc<dyn TextBlockUser>,
|
||||
rev_web_socket: Arc<dyn RevisionWebSocket>,
|
||||
) -> Self {
|
||||
let block_editors = Arc::new(BlockEditors::new());
|
||||
Self {
|
||||
cloud_service,
|
||||
rev_web_socket,
|
||||
block_editors,
|
||||
block_user,
|
||||
editor_map: Arc::new(TextBlockEditorMap::new()),
|
||||
user: text_block_user,
|
||||
}
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
#[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();
|
||||
tracing::Span::current().record("block_id", &block_id);
|
||||
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> {
|
||||
let block_id = block_id.as_ref();
|
||||
tracing::Span::current().record("block_id", &block_id);
|
||||
self.block_editors.remove(block_id);
|
||||
self.editor_map.remove(block_id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -66,16 +65,16 @@ impl BlockManager {
|
||||
pub fn delete_block<T: AsRef<str>>(&self, doc_id: T) -> Result<(), FlowyError> {
|
||||
let doc_id = doc_id.as_ref();
|
||||
tracing::Span::current().record("doc_id", &doc_id);
|
||||
self.block_editors.remove(doc_id);
|
||||
self.editor_map.remove(doc_id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[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.compose_local_delta(Bytes::from(delta.delta_str)).await?;
|
||||
let document_json = editor.delta_str().await?;
|
||||
Ok(BlockDelta {
|
||||
Ok(TextBlockDelta {
|
||||
block_id: delta.block_id.clone(),
|
||||
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<()> {
|
||||
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
|
||||
let rev_manager = self.make_block_rev_manager(&doc_id, db_pool)?;
|
||||
let _ = rev_manager.reset_object(revisions).await?;
|
||||
@ -93,9 +92,9 @@ impl BlockManager {
|
||||
pub async fn receive_ws_data(&self, data: Bytes) {
|
||||
let result: Result<ServerRevisionWSData, protobuf::ProtobufError> = data.try_into();
|
||||
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),
|
||||
Some(block_editor) => match block_editor.receive_ws_data(data).await {
|
||||
Some(editor) => match editor.receive_ws_data(data).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => tracing::error!("{}", e),
|
||||
},
|
||||
@ -107,11 +106,11 @@ impl BlockManager {
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockManager {
|
||||
async fn get_block_editor(&self, block_id: &str) -> FlowyResult<Arc<ClientBlockEditor>> {
|
||||
match self.block_editors.get(block_id) {
|
||||
impl TextBlockManager {
|
||||
async fn get_block_editor(&self, block_id: &str) -> FlowyResult<Arc<ClientTextBlockEditor>> {
|
||||
match self.editor_map.get(block_id) {
|
||||
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
|
||||
}
|
||||
Some(editor) => Ok(editor),
|
||||
@ -122,36 +121,36 @@ impl BlockManager {
|
||||
&self,
|
||||
block_id: &str,
|
||||
pool: Arc<ConnectionPool>,
|
||||
) -> Result<Arc<ClientBlockEditor>, FlowyError> {
|
||||
let user = self.block_user.clone();
|
||||
let token = self.block_user.token()?;
|
||||
) -> Result<Arc<ClientTextBlockEditor>, FlowyError> {
|
||||
let user = self.user.clone();
|
||||
let token = self.user.token()?;
|
||||
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,
|
||||
server: self.cloud_service.clone(),
|
||||
});
|
||||
let doc_editor =
|
||||
ClientBlockEditor::new(block_id, user, rev_manager, self.rev_web_socket.clone(), cloud_service).await?;
|
||||
self.block_editors.insert(block_id, &doc_editor);
|
||||
ClientTextBlockEditor::new(block_id, user, rev_manager, self.rev_web_socket.clone(), cloud_service).await?;
|
||||
self.editor_map.insert(block_id, &doc_editor);
|
||||
Ok(doc_editor)
|
||||
}
|
||||
|
||||
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));
|
||||
Ok(RevisionManager::new(&user_id, doc_id, rev_persistence))
|
||||
}
|
||||
}
|
||||
|
||||
struct BlockRevisionCloudService {
|
||||
struct TextBlockRevisionCloudService {
|
||||
token: String,
|
||||
server: Arc<dyn BlockCloudService>,
|
||||
}
|
||||
|
||||
impl RevisionCloudService for BlockRevisionCloudService {
|
||||
impl RevisionCloudService for TextBlockRevisionCloudService {
|
||||
#[tracing::instrument(level = "trace", skip(self))]
|
||||
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 token = self.token.clone();
|
||||
let user_id = user_id.to_string();
|
||||
@ -177,32 +176,24 @@ impl RevisionCloudService for BlockRevisionCloudService {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BlockEditors {
|
||||
inner: DashMap<String, Arc<ClientBlockEditor>>,
|
||||
pub struct TextBlockEditorMap {
|
||||
inner: DashMap<String, Arc<ClientTextBlockEditor>>,
|
||||
}
|
||||
|
||||
impl BlockEditors {
|
||||
impl TextBlockEditorMap {
|
||||
fn new() -> Self {
|
||||
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) {
|
||||
log::warn!("Doc:{} already exists in cache", block_id);
|
||||
}
|
||||
self.inner.insert(block_id.to_string(), doc.clone());
|
||||
}
|
||||
|
||||
pub(crate) fn contains(&self, block_id: &str) -> bool {
|
||||
self.inner.get(block_id).is_some()
|
||||
}
|
||||
|
||||
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 get(&self, block_id: &str) -> Option<Arc<ClientTextBlockEditor>> {
|
||||
Some(self.inner.get(block_id)?.clone())
|
||||
}
|
||||
|
||||
pub(crate) fn remove(&self, block_id: &str) {
|
||||
@ -214,7 +205,7 @@ impl BlockEditors {
|
||||
}
|
||||
|
||||
#[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 {
|
||||
let mut notify = web_socket.subscribe_state_changed().await;
|
||||
while let Ok(state) = notify.recv().await {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::web_socket::EditorCommandReceiver;
|
||||
use crate::BlockUser;
|
||||
use crate::TextBlockUser;
|
||||
use async_stream::stream;
|
||||
use flowy_collaboration::util::make_delta_from_revisions;
|
||||
use flowy_collaboration::{
|
||||
@ -21,14 +21,14 @@ use tokio::sync::{oneshot, RwLock};
|
||||
// serial.
|
||||
pub(crate) struct EditBlockQueue {
|
||||
document: Arc<RwLock<ClientDocument>>,
|
||||
user: Arc<dyn BlockUser>,
|
||||
user: Arc<dyn TextBlockUser>,
|
||||
rev_manager: Arc<RevisionManager>,
|
||||
receiver: Option<EditorCommandReceiver>,
|
||||
}
|
||||
|
||||
impl EditBlockQueue {
|
||||
pub(crate) fn new(
|
||||
user: Arc<dyn BlockUser>,
|
||||
user: Arc<dyn TextBlockUser>,
|
||||
rev_manager: Arc<RevisionManager>,
|
||||
delta: RichTextDelta,
|
||||
receiver: EditorCommandReceiver,
|
||||
|
@ -31,11 +31,11 @@ pub(crate) async fn make_block_ws_manager(
|
||||
rev_web_socket: Arc<dyn RevisionWebSocket>,
|
||||
) -> Arc<RevisionWebSocketManager> {
|
||||
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 =
|
||||
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_sink = Arc::new(BlockWSDataSink(ws_data_provider));
|
||||
let ws_data_stream = Arc::new(TextBlockRevisionWSDataStream::new(conflict_controller));
|
||||
let ws_data_sink = Arc::new(TextBlockWSDataSink(ws_data_provider));
|
||||
let ping_duration = Duration::from_millis(DOCUMENT_SYNC_INTERVAL_IN_MILLIS);
|
||||
let ws_manager = Arc::new(RevisionWebSocketManager::new(
|
||||
"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>,
|
||||
}
|
||||
|
||||
impl BlockRevisionWSDataStream {
|
||||
impl TextBlockRevisionWSDataStream {
|
||||
pub fn new(conflict_controller: RichTextConflictController) -> Self {
|
||||
Self {
|
||||
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> {
|
||||
let resolver = self.conflict_controller.clone();
|
||||
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>);
|
||||
impl RevisionWebSocketSink for BlockWSDataSink {
|
||||
pub(crate) struct TextBlockWSDataSink(pub(crate) Arc<WSDataProvider>);
|
||||
impl RevisionWebSocketSink for TextBlockWSDataSink {
|
||||
fn next(&self) -> FutureResult<Option<ClientRevisionWSData>, FlowyError> {
|
||||
let sink_provider = self.0.clone();
|
||||
FutureResult::new(async move { sink_provider.next().await })
|
||||
}
|
||||
}
|
||||
|
||||
struct BlockConflictResolver {
|
||||
struct TextBlockConflictResolver {
|
||||
edit_cmd_tx: EditorCommandSender,
|
||||
}
|
||||
|
||||
impl ConflictResolver<RichTextAttributes> for BlockConflictResolver {
|
||||
impl ConflictResolver<RichTextAttributes> for TextBlockConflictResolver {
|
||||
fn compose_delta(&self, delta: RichTextDelta) -> BoxResultFuture<DeltaMD5, FlowyError> {
|
||||
let tx = self.edit_cmd_tx.clone();
|
||||
Box::pin(async move {
|
||||
|
@ -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_collaboration::entities::revision::RevisionState;
|
||||
use flowy_test::{helper::ViewTest, FlowySDKTest};
|
||||
@ -19,7 +19,7 @@ pub enum EditorScript {
|
||||
|
||||
pub struct EditorTest {
|
||||
pub sdk: FlowySDKTest,
|
||||
pub editor: Arc<ClientBlockEditor>,
|
||||
pub editor: Arc<ClientTextBlockEditor>,
|
||||
}
|
||||
|
||||
impl EditorTest {
|
||||
@ -27,7 +27,7 @@ impl EditorTest {
|
||||
let sdk = FlowySDKTest::default();
|
||||
let _ = sdk.init_user().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 }
|
||||
}
|
||||
|
||||
|
@ -1,2 +1,3 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE kv_table;
|
||||
DROP TABLE grid_rev_table;
|
@ -3,3 +3,12 @@ CREATE TABLE kv_table (
|
||||
key TEXT NOT NULL PRIMARY KEY,
|
||||
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
|
||||
);
|
@ -14,8 +14,8 @@ use crate::{
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use flowy_collaboration::entities::{
|
||||
document_info::BlockId,
|
||||
revision::{RepeatedRevision, Revision},
|
||||
text_block_info::TextBlockId,
|
||||
};
|
||||
use flowy_database::kv::KV;
|
||||
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)]
|
||||
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 view_id == params.value {
|
||||
let _ = KV::remove(LATEST_VIEW_ID);
|
||||
|
@ -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_data_model::entities::view::{RepeatedViewId, ViewId};
|
||||
use flowy_folder_data_model::entities::workspace::WorkspaceId;
|
||||
@ -161,14 +161,14 @@ pub async fn delete_view(sdk: &FlowySDKTest, view_ids: Vec<String>) {
|
||||
.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();
|
||||
FolderEventBuilder::new(sdk.clone())
|
||||
.event(SetLatestView)
|
||||
.payload(view_id)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<BlockInfo>()
|
||||
.parse::<TextBlockInfo>()
|
||||
}
|
||||
|
||||
pub async fn read_trash(sdk: &FlowySDKTest) -> RepeatedTrash {
|
||||
|
@ -1,5 +1,5 @@
|
||||
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_data_model::entities::{
|
||||
app::{App, RepeatedApp},
|
||||
@ -58,7 +58,7 @@ pub struct FolderTest {
|
||||
pub app: App,
|
||||
pub view: View,
|
||||
pub trash: Vec<Trash>,
|
||||
pub document_info: Option<BlockInfo>,
|
||||
pub document_info: Option<TextBlockInfo>,
|
||||
// pub folder_editor:
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ impl GridBuilder {
|
||||
let grid_meta = GridMeta {
|
||||
grid_id: self.grid_id,
|
||||
fields: self.fields,
|
||||
rows: self.rows,
|
||||
blocks: vec![],
|
||||
};
|
||||
|
||||
// let _ = check_rows(&self.fields, &self.rows)?;
|
||||
|
@ -3,7 +3,9 @@ use crate::{
|
||||
request::{HttpRequestBuilder, ResponseMiddleware},
|
||||
};
|
||||
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 http_flowy::response::FlowyResponse;
|
||||
use lazy_static::lazy_static;
|
||||
@ -21,26 +23,26 @@ impl 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 url = self.config.doc_url();
|
||||
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 url = self.config.doc_url();
|
||||
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 url = self.config.doc_url();
|
||||
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()
|
||||
.post(&url.to_owned())
|
||||
.header(HEADER_TOKEN, token)
|
||||
@ -50,7 +52,11 @@ pub async fn create_document_request(token: &str, params: CreateBlockParams, url
|
||||
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()
|
||||
.get(&url.to_owned())
|
||||
.header(HEADER_TOKEN, token)
|
||||
@ -61,7 +67,7 @@ pub async fn read_document_request(token: &str, params: BlockId, url: &str) -> R
|
||||
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()
|
||||
.patch(&url.to_owned())
|
||||
.header(HEADER_TOKEN, token)
|
||||
|
@ -1,5 +1,5 @@
|
||||
use flowy_collaboration::{
|
||||
entities::{document_info::BlockInfo, folder_info::FolderInfo},
|
||||
entities::{folder_info::FolderInfo, text_block_info::TextBlockInfo},
|
||||
errors::CollaborateError,
|
||||
protobuf::{RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB},
|
||||
server_document::*,
|
||||
@ -111,7 +111,7 @@ impl FolderCloudPersistence 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 doc_id = doc_id.to_owned();
|
||||
Box::pin(async move {
|
||||
@ -127,7 +127,7 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence {
|
||||
&self,
|
||||
doc_id: &str,
|
||||
repeated_revision: RepeatedRevisionPB,
|
||||
) -> BoxResultFuture<Option<BlockInfo>, CollaborateError> {
|
||||
) -> BoxResultFuture<Option<TextBlockInfo>, CollaborateError> {
|
||||
let doc_id = doc_id.to_owned();
|
||||
let storage = self.storage.clone();
|
||||
Box::pin(async move {
|
||||
|
@ -4,7 +4,7 @@ use bytes::Bytes;
|
||||
use flowy_collaboration::{
|
||||
client_document::default::initial_quill_delta_string,
|
||||
entities::{
|
||||
document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams},
|
||||
text_block_info::{CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo},
|
||||
ws_data::{ClientRevisionWSData, ClientRevisionWSDataType},
|
||||
},
|
||||
errors::CollaborateError,
|
||||
@ -413,12 +413,12 @@ impl UserCloudService 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(()) })
|
||||
}
|
||||
|
||||
fn read_block(&self, _token: &str, params: BlockId) -> FutureResult<Option<BlockInfo>, FlowyError> {
|
||||
let doc = BlockInfo {
|
||||
fn read_block(&self, _token: &str, params: TextBlockId) -> FutureResult<Option<TextBlockInfo>, FlowyError> {
|
||||
let doc = TextBlockInfo {
|
||||
block_id: params.value,
|
||||
text: initial_quill_delta_string(),
|
||||
rev_id: 0,
|
||||
@ -427,7 +427,7 @@ impl BlockCloudService for LocalServer {
|
||||
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(()) })
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use bytes::Bytes;
|
||||
use flowy_block::BlockManager;
|
||||
use flowy_block::TextBlockManager;
|
||||
use flowy_collaboration::client_document::default::initial_quill_delta_string;
|
||||
use flowy_collaboration::entities::revision::RepeatedRevision;
|
||||
use flowy_collaboration::entities::ws_data::ClientRevisionWSData;
|
||||
@ -32,7 +32,7 @@ impl FolderDepsResolver {
|
||||
user_session: Arc<UserSession>,
|
||||
server_config: &ClientServerConfiguration,
|
||||
ws_conn: &Arc<FlowyWebSocketConnect>,
|
||||
block_manager: &Arc<BlockManager>,
|
||||
text_block_manager: &Arc<TextBlockManager>,
|
||||
grid_manager: &Arc<GridManager>,
|
||||
) -> Arc<FolderManager> {
|
||||
let user: Arc<dyn WorkspaceUser> = Arc::new(WorkspaceUserImpl(user_session.clone()));
|
||||
@ -43,7 +43,7 @@ impl FolderDepsResolver {
|
||||
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 =
|
||||
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 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));
|
||||
|
||||
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 {
|
||||
fn initialize(&self) -> FutureResult<(), FlowyError> {
|
||||
let block_manager = self.0.clone();
|
||||
FutureResult::new(async move { block_manager.init() })
|
||||
let manager = self.0.clone();
|
||||
FutureResult::new(async move { manager.init() })
|
||||
}
|
||||
|
||||
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();
|
||||
FutureResult::new(async move {
|
||||
let _ = block_manager.create_block(view_id, repeated_revision).await?;
|
||||
let _ = manager.create_block(view_id, repeated_revision).await?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
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();
|
||||
FutureResult::new(async move {
|
||||
let _ = block_manager.delete_block(view_id)?;
|
||||
let _ = manager.delete_block(view_id)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
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();
|
||||
FutureResult::new(async move {
|
||||
let _ = block_manager.close_block(view_id)?;
|
||||
let _ = manager.close_block(view_id)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn delta_str(&self, view_id: &str) -> FutureResult<String, FlowyError> {
|
||||
let view_id = view_id.to_string();
|
||||
let block_manager = self.0.clone();
|
||||
let manager = self.0.clone();
|
||||
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?;
|
||||
Ok(delta_str)
|
||||
})
|
||||
|
@ -1,10 +1,10 @@
|
||||
mod block_deps;
|
||||
mod folder_deps;
|
||||
mod grid_deps;
|
||||
mod text_block_deps;
|
||||
mod user_deps;
|
||||
mod util;
|
||||
|
||||
pub use block_deps::*;
|
||||
pub use folder_deps::*;
|
||||
pub use grid_deps::*;
|
||||
pub use text_block_deps::*;
|
||||
pub use user_deps::*;
|
||||
|
@ -1,7 +1,7 @@
|
||||
use bytes::Bytes;
|
||||
use flowy_block::{
|
||||
errors::{internal_error, FlowyError},
|
||||
BlockCloudService, BlockManager, BlockUser,
|
||||
BlockCloudService, TextBlockManager, TextBlockUser,
|
||||
};
|
||||
use flowy_collaboration::entities::ws_data::ClientRevisionWSData;
|
||||
use flowy_database::ConnectionPool;
|
||||
@ -16,22 +16,22 @@ use lib_infra::future::BoxResultFuture;
|
||||
use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage};
|
||||
use std::{convert::TryInto, path::Path, sync::Arc};
|
||||
|
||||
pub struct BlockDepsResolver();
|
||||
impl BlockDepsResolver {
|
||||
pub struct TextBlockDepsResolver();
|
||||
impl TextBlockDepsResolver {
|
||||
pub fn resolve(
|
||||
local_server: Option<Arc<LocalServer>>,
|
||||
ws_conn: Arc<FlowyWebSocketConnect>,
|
||||
user_session: Arc<UserSession>,
|
||||
server_config: &ClientServerConfiguration,
|
||||
) -> Arc<BlockManager> {
|
||||
) -> Arc<TextBlockManager> {
|
||||
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 {
|
||||
None => Arc::new(BlockHttpCloudService::new(server_config.clone())),
|
||||
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()));
|
||||
ws_conn.add_ws_message_receiver(receiver).unwrap();
|
||||
|
||||
@ -40,7 +40,7 @@ impl BlockDepsResolver {
|
||||
}
|
||||
|
||||
struct BlockUserImpl(Arc<UserSession>);
|
||||
impl BlockUser for BlockUserImpl {
|
||||
impl TextBlockUser for BlockUserImpl {
|
||||
fn user_dir(&self) -> Result<String, FlowyError> {
|
||||
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>);
|
||||
impl RevisionWebSocket for BlockWebSocket {
|
||||
struct TextBlockWebSocket(Arc<FlowyWebSocketConnect>);
|
||||
impl RevisionWebSocket for TextBlockWebSocket {
|
||||
fn send(&self, data: ClientRevisionWSData) -> BoxResultFuture<(), FlowyError> {
|
||||
let bytes: Bytes = data.try_into().unwrap();
|
||||
let msg = WebSocketRawMessage {
|
||||
@ -90,7 +90,7 @@ impl RevisionWebSocket for BlockWebSocket {
|
||||
}
|
||||
}
|
||||
|
||||
struct DocumentWSMessageReceiverImpl(Arc<BlockManager>);
|
||||
struct DocumentWSMessageReceiverImpl(Arc<TextBlockManager>);
|
||||
impl WSMessageReceiver for DocumentWSMessageReceiverImpl {
|
||||
fn source(&self) -> WSChannel {
|
||||
WSChannel::Document
|
@ -3,7 +3,7 @@ pub mod module;
|
||||
pub use flowy_net::get_client_server_configuration;
|
||||
|
||||
use crate::deps_resolve::*;
|
||||
use flowy_block::BlockManager;
|
||||
use flowy_block::TextBlockManager;
|
||||
use flowy_folder::{errors::FlowyError, manager::FolderManager};
|
||||
use flowy_grid::manager::GridManager;
|
||||
use flowy_net::ClientServerConfiguration;
|
||||
@ -88,7 +88,7 @@ pub struct FlowySDK {
|
||||
#[allow(dead_code)]
|
||||
config: FlowySDKConfig,
|
||||
pub user_session: Arc<UserSession>,
|
||||
pub block_manager: Arc<BlockManager>,
|
||||
pub text_block_manager: Arc<TextBlockManager>,
|
||||
pub folder_manager: Arc<FolderManager>,
|
||||
pub grid_manager: Arc<GridManager>,
|
||||
pub dispatcher: Arc<EventDispatcher>,
|
||||
@ -103,9 +103,9 @@ impl FlowySDK {
|
||||
tracing::debug!("🔥 {:?}", config);
|
||||
let runtime = tokio_default_runtime().unwrap();
|
||||
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 block_manager = BlockDepsResolver::resolve(
|
||||
let text_block_manager = TextBlockDepsResolver::resolve(
|
||||
local_server.clone(),
|
||||
ws_conn.clone(),
|
||||
user_session.clone(),
|
||||
@ -119,7 +119,7 @@ impl FlowySDK {
|
||||
user_session.clone(),
|
||||
&config.server_config,
|
||||
&ws_conn,
|
||||
&block_manager,
|
||||
&text_block_manager,
|
||||
&grid_manager,
|
||||
)
|
||||
.await;
|
||||
@ -128,11 +128,23 @@ impl FlowySDK {
|
||||
local_server.run();
|
||||
}
|
||||
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, || {
|
||||
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);
|
||||
@ -140,7 +152,7 @@ impl FlowySDK {
|
||||
Self {
|
||||
config,
|
||||
user_session,
|
||||
block_manager,
|
||||
text_block_manager,
|
||||
folder_manager,
|
||||
grid_manager,
|
||||
dispatcher,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use flowy_block::BlockManager;
|
||||
use flowy_block::TextBlockManager;
|
||||
use flowy_folder::manager::FolderManager;
|
||||
use flowy_grid::manager::GridManager;
|
||||
use flowy_net::ws::connection::FlowyWebSocketConnect;
|
||||
@ -11,14 +11,20 @@ pub fn mk_modules(
|
||||
folder_manager: &Arc<FolderManager>,
|
||||
grid_manager: &Arc<GridManager>,
|
||||
user_session: &Arc<UserSession>,
|
||||
block_manager: &Arc<BlockManager>,
|
||||
text_block_manager: &Arc<TextBlockManager>,
|
||||
) -> Vec<Module> {
|
||||
let user_module = mk_user_module(user_session.clone());
|
||||
let folder_module = mk_folder_module(folder_manager.clone());
|
||||
let network_module = mk_network_module(ws_conn.clone());
|
||||
let grid_module = mk_grid_module(grid_manager.clone());
|
||||
let block_module = mk_block_module(block_manager.clone());
|
||||
vec![user_module, folder_module, network_module, grid_module, block_module]
|
||||
let text_block_module = mk_text_block_module(text_block_manager.clone());
|
||||
vec![
|
||||
user_module,
|
||||
folder_module,
|
||||
network_module,
|
||||
grid_module,
|
||||
text_block_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)
|
||||
}
|
||||
|
||||
fn mk_block_module(block_manager: Arc<BlockManager>) -> Module {
|
||||
flowy_block::event_map::create(block_manager)
|
||||
fn mk_text_block_module(text_block_manager: Arc<TextBlockManager>) -> Module {
|
||||
flowy_block::event_map::create(text_block_manager)
|
||||
}
|
||||
|
0
frontend/rust-lib/flowy-sync/src/cache/disk/folder_rev_impl.rs
vendored
Normal file
0
frontend/rust-lib/flowy-sync/src/cache/disk/folder_rev_impl.rs
vendored
Normal file
0
frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs
vendored
Normal file
0
frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs
vendored
Normal 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 diesel::SqliteConnection;
|
||||
use flowy_collaboration::entities::revision::RevisionRange;
|
||||
pub use sql_impl::*;
|
||||
|
||||
use flowy_error::FlowyResult;
|
||||
use std::fmt::Debug;
|
||||
|
||||
|
@ -14,12 +14,12 @@ use flowy_database::{
|
||||
use flowy_error::{internal_error, FlowyError, FlowyResult};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct SQLitePersistence {
|
||||
pub struct SQLiteTextBlockRevisionPersistence {
|
||||
user_id: String,
|
||||
pub(crate) pool: Arc<ConnectionPool>,
|
||||
}
|
||||
|
||||
impl RevisionDiskCache for SQLitePersistence {
|
||||
impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence {
|
||||
type Error = FlowyError;
|
||||
|
||||
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 {
|
||||
Self {
|
||||
user_id: user_id.to_owned(),
|
327
frontend/rust-lib/flowy-sync/src/cache/mod.rs
vendored
327
frontend/rust-lib/flowy-sync/src/cache/mod.rs
vendored
@ -1,325 +1,2 @@
|
||||
mod disk;
|
||||
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))
|
||||
}
|
||||
}
|
||||
pub(crate) mod disk;
|
||||
pub(crate) mod memory;
|
||||
|
@ -1,11 +1,13 @@
|
||||
mod cache;
|
||||
mod conflict_resolve;
|
||||
mod rev_manager;
|
||||
mod rev_persistence;
|
||||
mod ws_manager;
|
||||
|
||||
pub use cache::*;
|
||||
pub use conflict_resolve::*;
|
||||
pub use rev_manager::*;
|
||||
pub use rev_persistence::*;
|
||||
pub use ws_manager::*;
|
||||
|
||||
#[macro_use]
|
||||
|
322
frontend/rust-lib/flowy-sync/src/rev_persistence.rs
Normal file
322
frontend/rust-lib/flowy-sync/src/rev_persistence.rs
Normal 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))
|
||||
}
|
||||
}
|
115
shared-lib/flowy-collaboration/src/client_grid/block_pad.rs
Normal file
115
shared-lib/flowy-collaboration/src/client_grid/block_pad.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
@ -33,7 +33,7 @@ impl GridMetaPad {
|
||||
|
||||
pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult<Option<GridChange>> {
|
||||
self.modify_grid(|grid| {
|
||||
grid.rows.push(row);
|
||||
// grid.rows.push(row);
|
||||
Ok(Some(()))
|
||||
})
|
||||
}
|
||||
@ -47,7 +47,7 @@ impl GridMetaPad {
|
||||
|
||||
pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult<Option<GridChange>> {
|
||||
self.modify_grid(|grid| {
|
||||
grid.rows.retain(|row| !row_ids.contains(&row.id));
|
||||
// grid.rows.retain(|row| !row_ids.contains(&row.id));
|
||||
Ok(Some(()))
|
||||
})
|
||||
}
|
||||
@ -74,17 +74,17 @@ impl GridMetaPad {
|
||||
.map(FieldOrder::from)
|
||||
.collect::<Vec<FieldOrder>>();
|
||||
|
||||
let row_orders = self
|
||||
.grid_meta
|
||||
.rows
|
||||
.iter()
|
||||
.map(RowOrder::from)
|
||||
.collect::<Vec<RowOrder>>();
|
||||
// let row_orders = self
|
||||
// .grid_meta
|
||||
// .rows
|
||||
// .iter()
|
||||
// .map(RowOrder::from)
|
||||
// .collect::<Vec<RowOrder>>();
|
||||
|
||||
Grid {
|
||||
id: "".to_string(),
|
||||
field_orders,
|
||||
row_orders,
|
||||
row_orders: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ impl std::default::Default for GridMetaPad {
|
||||
let grid = GridMeta {
|
||||
grid_id: uuid(),
|
||||
fields: vec![],
|
||||
rows: vec![],
|
||||
blocks: vec![],
|
||||
};
|
||||
let delta = make_grid_delta(&grid);
|
||||
GridMetaPad {
|
||||
|
@ -1,3 +1,5 @@
|
||||
mod block_pad;
|
||||
mod grid_pad;
|
||||
|
||||
pub use block_pad::*;
|
||||
pub use grid_pad::*;
|
||||
|
@ -1,5 +1,5 @@
|
||||
pub mod document_info;
|
||||
pub mod folder_info;
|
||||
pub mod parser;
|
||||
pub mod revision;
|
||||
pub mod text_block_info;
|
||||
pub mod ws_data;
|
||||
|
@ -6,7 +6,7 @@ use flowy_derive::ProtoBuf;
|
||||
use lib_ot::{errors::OTError, rich_text::RichTextDelta};
|
||||
|
||||
#[derive(ProtoBuf, Default, Debug, Clone)]
|
||||
pub struct CreateBlockParams {
|
||||
pub struct CreateTextBlockParams {
|
||||
#[pb(index = 1)]
|
||||
pub id: String,
|
||||
|
||||
@ -15,7 +15,7 @@ pub struct CreateBlockParams {
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Debug, Clone, Eq, PartialEq)]
|
||||
pub struct BlockInfo {
|
||||
pub struct TextBlockInfo {
|
||||
#[pb(index = 1)]
|
||||
pub block_id: String,
|
||||
|
||||
@ -29,14 +29,14 @@ pub struct BlockInfo {
|
||||
pub base_rev_id: i64,
|
||||
}
|
||||
|
||||
impl BlockInfo {
|
||||
impl TextBlockInfo {
|
||||
pub fn delta(&self) -> Result<RichTextDelta, OTError> {
|
||||
let delta = RichTextDelta::from_bytes(&self.text)?;
|
||||
Ok(delta)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<Revision> for BlockInfo {
|
||||
impl std::convert::TryFrom<Revision> for TextBlockInfo {
|
||||
type Error = CollaborateError;
|
||||
|
||||
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 doc_json = delta.to_delta_str();
|
||||
|
||||
Ok(BlockInfo {
|
||||
Ok(TextBlockInfo {
|
||||
block_id: revision.object_id,
|
||||
text: doc_json,
|
||||
rev_id: revision.rev_id,
|
||||
@ -58,7 +58,7 @@ impl std::convert::TryFrom<Revision> for BlockInfo {
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Debug, Clone)]
|
||||
pub struct ResetBlockParams {
|
||||
pub struct ResetTextBlockParams {
|
||||
#[pb(index = 1)]
|
||||
pub block_id: String,
|
||||
|
||||
@ -67,7 +67,7 @@ pub struct ResetBlockParams {
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Debug, Clone)]
|
||||
pub struct BlockDelta {
|
||||
pub struct TextBlockDelta {
|
||||
#[pb(index = 1)]
|
||||
pub block_id: String,
|
||||
|
||||
@ -88,30 +88,30 @@ pub struct NewDocUser {
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Debug, Clone)]
|
||||
pub struct BlockId {
|
||||
pub struct TextBlockId {
|
||||
#[pb(index = 1)]
|
||||
pub value: String,
|
||||
}
|
||||
impl AsRef<str> for BlockId {
|
||||
impl AsRef<str> for TextBlockId {
|
||||
fn as_ref(&self) -> &str {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<String> for BlockId {
|
||||
impl std::convert::From<String> for TextBlockId {
|
||||
fn from(value: String) -> Self {
|
||||
BlockId { value }
|
||||
TextBlockId { value }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<BlockId> for String {
|
||||
fn from(block_id: BlockId) -> Self {
|
||||
impl std::convert::From<TextBlockId> for String {
|
||||
fn from(block_id: TextBlockId) -> Self {
|
||||
block_id.value
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&String> for BlockId {
|
||||
impl std::convert::From<&String> for TextBlockId {
|
||||
fn from(s: &String) -> Self {
|
||||
BlockId { value: s.to_owned() }
|
||||
TextBlockId { value: s.to_owned() }
|
||||
}
|
||||
}
|
@ -7,8 +7,8 @@ pub use folder_info::*;
|
||||
mod ws_data;
|
||||
pub use ws_data::*;
|
||||
|
||||
mod text_block_info;
|
||||
pub use text_block_info::*;
|
||||
|
||||
mod revision;
|
||||
pub use revision::*;
|
||||
|
||||
mod document_info;
|
||||
pub use document_info::*;
|
||||
|
@ -17,14 +17,14 @@
|
||||
#![allow(trivial_casts)]
|
||||
#![allow(unused_imports)]
|
||||
#![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
|
||||
/// of protobuf runtime.
|
||||
// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2;
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct CreateBlockParams {
|
||||
pub struct CreateTextBlockParams {
|
||||
// message fields
|
||||
pub id: ::std::string::String,
|
||||
pub revisions: ::protobuf::SingularPtrField<super::revision::RepeatedRevision>,
|
||||
@ -33,14 +33,14 @@ pub struct CreateBlockParams {
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a CreateBlockParams {
|
||||
fn default() -> &'a CreateBlockParams {
|
||||
<CreateBlockParams as ::protobuf::Message>::default_instance()
|
||||
impl<'a> ::std::default::Default for &'a CreateTextBlockParams {
|
||||
fn default() -> &'a CreateTextBlockParams {
|
||||
<CreateTextBlockParams as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl CreateBlockParams {
|
||||
pub fn new() -> CreateBlockParams {
|
||||
impl CreateTextBlockParams {
|
||||
pub fn new() -> CreateTextBlockParams {
|
||||
::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 {
|
||||
for v in &self.revisions {
|
||||
if !v.is_initialized() {
|
||||
@ -187,8 +187,8 @@ impl ::protobuf::Message for CreateBlockParams {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> CreateBlockParams {
|
||||
CreateBlockParams::new()
|
||||
fn new() -> CreateTextBlockParams {
|
||||
CreateTextBlockParams::new()
|
||||
}
|
||||
|
||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
@ -197,29 +197,29 @@ impl ::protobuf::Message for CreateBlockParams {
|
||||
let mut fields = ::std::vec::Vec::new();
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"id",
|
||||
|m: &CreateBlockParams| { &m.id },
|
||||
|m: &mut CreateBlockParams| { &mut m.id },
|
||||
|m: &CreateTextBlockParams| { &m.id },
|
||||
|m: &mut CreateTextBlockParams| { &mut m.id },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::revision::RepeatedRevision>>(
|
||||
"revisions",
|
||||
|m: &CreateBlockParams| { &m.revisions },
|
||||
|m: &mut CreateBlockParams| { &mut m.revisions },
|
||||
|m: &CreateTextBlockParams| { &m.revisions },
|
||||
|m: &mut CreateTextBlockParams| { &mut m.revisions },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateBlockParams>(
|
||||
"CreateBlockParams",
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateTextBlockParams>(
|
||||
"CreateTextBlockParams",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static CreateBlockParams {
|
||||
static instance: ::protobuf::rt::LazyV2<CreateBlockParams> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(CreateBlockParams::new)
|
||||
fn default_instance() -> &'static CreateTextBlockParams {
|
||||
static instance: ::protobuf::rt::LazyV2<CreateTextBlockParams> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(CreateTextBlockParams::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for CreateBlockParams {
|
||||
impl ::protobuf::Clear for CreateTextBlockParams {
|
||||
fn clear(&mut self) {
|
||||
self.id.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 {
|
||||
::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 {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct BlockInfo {
|
||||
pub struct TextBlockInfo {
|
||||
// message fields
|
||||
pub block_id: ::std::string::String,
|
||||
pub text: ::std::string::String,
|
||||
@ -251,14 +251,14 @@ pub struct BlockInfo {
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a BlockInfo {
|
||||
fn default() -> &'a BlockInfo {
|
||||
<BlockInfo as ::protobuf::Message>::default_instance()
|
||||
impl<'a> ::std::default::Default for &'a TextBlockInfo {
|
||||
fn default() -> &'a TextBlockInfo {
|
||||
<TextBlockInfo as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockInfo {
|
||||
pub fn new() -> BlockInfo {
|
||||
impl TextBlockInfo {
|
||||
pub fn new() -> TextBlockInfo {
|
||||
::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 {
|
||||
true
|
||||
}
|
||||
@ -446,8 +446,8 @@ impl ::protobuf::Message for BlockInfo {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> BlockInfo {
|
||||
BlockInfo::new()
|
||||
fn new() -> TextBlockInfo {
|
||||
TextBlockInfo::new()
|
||||
}
|
||||
|
||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
@ -456,39 +456,39 @@ impl ::protobuf::Message for BlockInfo {
|
||||
let mut fields = ::std::vec::Vec::new();
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"block_id",
|
||||
|m: &BlockInfo| { &m.block_id },
|
||||
|m: &mut BlockInfo| { &mut m.block_id },
|
||||
|m: &TextBlockInfo| { &m.block_id },
|
||||
|m: &mut TextBlockInfo| { &mut m.block_id },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"text",
|
||||
|m: &BlockInfo| { &m.text },
|
||||
|m: &mut BlockInfo| { &mut m.text },
|
||||
|m: &TextBlockInfo| { &m.text },
|
||||
|m: &mut TextBlockInfo| { &mut m.text },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>(
|
||||
"rev_id",
|
||||
|m: &BlockInfo| { &m.rev_id },
|
||||
|m: &mut BlockInfo| { &mut m.rev_id },
|
||||
|m: &TextBlockInfo| { &m.rev_id },
|
||||
|m: &mut TextBlockInfo| { &mut m.rev_id },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>(
|
||||
"base_rev_id",
|
||||
|m: &BlockInfo| { &m.base_rev_id },
|
||||
|m: &mut BlockInfo| { &mut m.base_rev_id },
|
||||
|m: &TextBlockInfo| { &m.base_rev_id },
|
||||
|m: &mut TextBlockInfo| { &mut m.base_rev_id },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<BlockInfo>(
|
||||
"BlockInfo",
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<TextBlockInfo>(
|
||||
"TextBlockInfo",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static BlockInfo {
|
||||
static instance: ::protobuf::rt::LazyV2<BlockInfo> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(BlockInfo::new)
|
||||
fn default_instance() -> &'static TextBlockInfo {
|
||||
static instance: ::protobuf::rt::LazyV2<TextBlockInfo> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(TextBlockInfo::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for BlockInfo {
|
||||
impl ::protobuf::Clear for TextBlockInfo {
|
||||
fn clear(&mut self) {
|
||||
self.block_id.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 {
|
||||
::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 {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct ResetBlockParams {
|
||||
pub struct ResetTextBlockParams {
|
||||
// message fields
|
||||
pub block_id: ::std::string::String,
|
||||
pub revisions: ::protobuf::SingularPtrField<super::revision::RepeatedRevision>,
|
||||
@ -520,14 +520,14 @@ pub struct ResetBlockParams {
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a ResetBlockParams {
|
||||
fn default() -> &'a ResetBlockParams {
|
||||
<ResetBlockParams as ::protobuf::Message>::default_instance()
|
||||
impl<'a> ::std::default::Default for &'a ResetTextBlockParams {
|
||||
fn default() -> &'a ResetTextBlockParams {
|
||||
<ResetTextBlockParams as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl ResetBlockParams {
|
||||
pub fn new() -> ResetBlockParams {
|
||||
impl ResetTextBlockParams {
|
||||
pub fn new() -> ResetTextBlockParams {
|
||||
::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 {
|
||||
for v in &self.revisions {
|
||||
if !v.is_initialized() {
|
||||
@ -674,8 +674,8 @@ impl ::protobuf::Message for ResetBlockParams {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> ResetBlockParams {
|
||||
ResetBlockParams::new()
|
||||
fn new() -> ResetTextBlockParams {
|
||||
ResetTextBlockParams::new()
|
||||
}
|
||||
|
||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
@ -684,29 +684,29 @@ impl ::protobuf::Message for ResetBlockParams {
|
||||
let mut fields = ::std::vec::Vec::new();
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"block_id",
|
||||
|m: &ResetBlockParams| { &m.block_id },
|
||||
|m: &mut ResetBlockParams| { &mut m.block_id },
|
||||
|m: &ResetTextBlockParams| { &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>>(
|
||||
"revisions",
|
||||
|m: &ResetBlockParams| { &m.revisions },
|
||||
|m: &mut ResetBlockParams| { &mut m.revisions },
|
||||
|m: &ResetTextBlockParams| { &m.revisions },
|
||||
|m: &mut ResetTextBlockParams| { &mut m.revisions },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<ResetBlockParams>(
|
||||
"ResetBlockParams",
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<ResetTextBlockParams>(
|
||||
"ResetTextBlockParams",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static ResetBlockParams {
|
||||
static instance: ::protobuf::rt::LazyV2<ResetBlockParams> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(ResetBlockParams::new)
|
||||
fn default_instance() -> &'static ResetTextBlockParams {
|
||||
static instance: ::protobuf::rt::LazyV2<ResetTextBlockParams> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(ResetTextBlockParams::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for ResetBlockParams {
|
||||
impl ::protobuf::Clear for ResetTextBlockParams {
|
||||
fn clear(&mut self) {
|
||||
self.block_id.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 {
|
||||
::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 {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct BlockDelta {
|
||||
pub struct TextBlockDelta {
|
||||
// message fields
|
||||
pub block_id: ::std::string::String,
|
||||
pub delta_str: ::std::string::String,
|
||||
@ -736,14 +736,14 @@ pub struct BlockDelta {
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a BlockDelta {
|
||||
fn default() -> &'a BlockDelta {
|
||||
<BlockDelta as ::protobuf::Message>::default_instance()
|
||||
impl<'a> ::std::default::Default for &'a TextBlockDelta {
|
||||
fn default() -> &'a TextBlockDelta {
|
||||
<TextBlockDelta as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockDelta {
|
||||
pub fn new() -> BlockDelta {
|
||||
impl TextBlockDelta {
|
||||
pub fn new() -> TextBlockDelta {
|
||||
::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 {
|
||||
true
|
||||
}
|
||||
@ -875,8 +875,8 @@ impl ::protobuf::Message for BlockDelta {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> BlockDelta {
|
||||
BlockDelta::new()
|
||||
fn new() -> TextBlockDelta {
|
||||
TextBlockDelta::new()
|
||||
}
|
||||
|
||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
@ -885,29 +885,29 @@ impl ::protobuf::Message for BlockDelta {
|
||||
let mut fields = ::std::vec::Vec::new();
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"block_id",
|
||||
|m: &BlockDelta| { &m.block_id },
|
||||
|m: &mut BlockDelta| { &mut m.block_id },
|
||||
|m: &TextBlockDelta| { &m.block_id },
|
||||
|m: &mut TextBlockDelta| { &mut m.block_id },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"delta_str",
|
||||
|m: &BlockDelta| { &m.delta_str },
|
||||
|m: &mut BlockDelta| { &mut m.delta_str },
|
||||
|m: &TextBlockDelta| { &m.delta_str },
|
||||
|m: &mut TextBlockDelta| { &mut m.delta_str },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<BlockDelta>(
|
||||
"BlockDelta",
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<TextBlockDelta>(
|
||||
"TextBlockDelta",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static BlockDelta {
|
||||
static instance: ::protobuf::rt::LazyV2<BlockDelta> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(BlockDelta::new)
|
||||
fn default_instance() -> &'static TextBlockDelta {
|
||||
static instance: ::protobuf::rt::LazyV2<TextBlockDelta> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(TextBlockDelta::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for BlockDelta {
|
||||
impl ::protobuf::Clear for TextBlockDelta {
|
||||
fn clear(&mut self) {
|
||||
self.block_id.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 {
|
||||
::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 {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
@ -1164,7 +1164,7 @@ impl ::protobuf::reflect::ProtobufValue for NewDocUser {
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct BlockId {
|
||||
pub struct TextBlockId {
|
||||
// message fields
|
||||
pub value: ::std::string::String,
|
||||
// special fields
|
||||
@ -1172,14 +1172,14 @@ pub struct BlockId {
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a BlockId {
|
||||
fn default() -> &'a BlockId {
|
||||
<BlockId as ::protobuf::Message>::default_instance()
|
||||
impl<'a> ::std::default::Default for &'a TextBlockId {
|
||||
fn default() -> &'a TextBlockId {
|
||||
<TextBlockId as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockId {
|
||||
pub fn new() -> BlockId {
|
||||
impl TextBlockId {
|
||||
pub fn new() -> TextBlockId {
|
||||
::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 {
|
||||
true
|
||||
}
|
||||
@ -1276,8 +1276,8 @@ impl ::protobuf::Message for BlockId {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> BlockId {
|
||||
BlockId::new()
|
||||
fn new() -> TextBlockId {
|
||||
TextBlockId::new()
|
||||
}
|
||||
|
||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
@ -1286,57 +1286,57 @@ impl ::protobuf::Message for BlockId {
|
||||
let mut fields = ::std::vec::Vec::new();
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"value",
|
||||
|m: &BlockId| { &m.value },
|
||||
|m: &mut BlockId| { &mut m.value },
|
||||
|m: &TextBlockId| { &m.value },
|
||||
|m: &mut TextBlockId| { &mut m.value },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<BlockId>(
|
||||
"BlockId",
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<TextBlockId>(
|
||||
"TextBlockId",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static BlockId {
|
||||
static instance: ::protobuf::rt::LazyV2<BlockId> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(BlockId::new)
|
||||
fn default_instance() -> &'static TextBlockId {
|
||||
static instance: ::protobuf::rt::LazyV2<TextBlockId> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(TextBlockId::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for BlockId {
|
||||
impl ::protobuf::Clear for TextBlockId {
|
||||
fn clear(&mut self) {
|
||||
self.value.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 {
|
||||
::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 {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x13document_info.proto\x1a\x0erevision.proto\"T\n\x11CreateBlockParam\
|
||||
s\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12/\n\trevisions\x18\x02\
|
||||
\x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"q\n\tBlockInfo\x12\x19\
|
||||
\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x12\n\x04text\x18\x02\
|
||||
\x20\x01(\tR\x04text\x12\x15\n\x06rev_id\x18\x03\x20\x01(\x03R\x05revId\
|
||||
\x12\x1e\n\x0bbase_rev_id\x18\x04\x20\x01(\x03R\tbaseRevId\"^\n\x10Reset\
|
||||
BlockParams\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12/\n\
|
||||
\trevisions\x18\x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"D\n\
|
||||
\nBlockDelta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\
|
||||
\x1b\n\tdelta_str\x18\x02\x20\x01(\tR\x08deltaStr\"S\n\nNewDocUser\x12\
|
||||
\x17\n\x07user_id\x18\x01\x20\x01(\tR\x06userId\x12\x15\n\x06rev_id\x18\
|
||||
\x02\x20\x01(\x03R\x05revId\x12\x15\n\x06doc_id\x18\x03\x20\x01(\tR\x05d\
|
||||
ocId\"\x1f\n\x07BlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05valueb\
|
||||
\x06proto3\
|
||||
\n\x15text_block_info.proto\x1a\x0erevision.proto\"X\n\x15CreateTextBloc\
|
||||
kParams\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12/\n\trevisions\x18\
|
||||
\x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"u\n\rTextBlockInfo\
|
||||
\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x12\n\x04text\
|
||||
\x18\x02\x20\x01(\tR\x04text\x12\x15\n\x06rev_id\x18\x03\x20\x01(\x03R\
|
||||
\x05revId\x12\x1e\n\x0bbase_rev_id\x18\x04\x20\x01(\x03R\tbaseRevId\"b\n\
|
||||
\x14ResetTextBlockParams\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07bl\
|
||||
ockId\x12/\n\trevisions\x18\x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trev\
|
||||
isions\"H\n\x0eTextBlockDelta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\
|
||||
\x07blockId\x12\x1b\n\tdelta_str\x18\x02\x20\x01(\tR\x08deltaStr\"S\n\nN\
|
||||
ewDocUser\x12\x17\n\x07user_id\x18\x01\x20\x01(\tR\x06userId\x12\x15\n\
|
||||
\x06rev_id\x18\x02\x20\x01(\x03R\x05revId\x12\x15\n\x06doc_id\x18\x03\
|
||||
\x20\x01(\tR\x05docId\"#\n\x0bTextBlockId\x12\x14\n\x05value\x18\x01\x20\
|
||||
\x01(\tR\x05valueb\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
@ -1,21 +1,21 @@
|
||||
syntax = "proto3";
|
||||
import "revision.proto";
|
||||
|
||||
message CreateBlockParams {
|
||||
message CreateTextBlockParams {
|
||||
string id = 1;
|
||||
RepeatedRevision revisions = 2;
|
||||
}
|
||||
message BlockInfo {
|
||||
message TextBlockInfo {
|
||||
string block_id = 1;
|
||||
string text = 2;
|
||||
int64 rev_id = 3;
|
||||
int64 base_rev_id = 4;
|
||||
}
|
||||
message ResetBlockParams {
|
||||
message ResetTextBlockParams {
|
||||
string block_id = 1;
|
||||
RepeatedRevision revisions = 2;
|
||||
}
|
||||
message BlockDelta {
|
||||
message TextBlockDelta {
|
||||
string block_id = 1;
|
||||
string delta_str = 2;
|
||||
}
|
||||
@ -24,6 +24,6 @@ message NewDocUser {
|
||||
int64 rev_id = 2;
|
||||
string doc_id = 3;
|
||||
}
|
||||
message BlockId {
|
||||
message TextBlockId {
|
||||
string value = 1;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
entities::{document_info::BlockInfo, ws_data::ServerRevisionWSDataBuilder},
|
||||
entities::{text_block_info::TextBlockInfo, ws_data::ServerRevisionWSDataBuilder},
|
||||
errors::{internal_error, CollaborateError, CollaborateResult},
|
||||
protobuf::{ClientRevisionWSData, RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB},
|
||||
server_document::document_pad::ServerDocument,
|
||||
@ -18,13 +18,13 @@ use tokio::{
|
||||
};
|
||||
|
||||
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(
|
||||
&self,
|
||||
doc_id: &str,
|
||||
repeated_revision: RepeatedRevisionPB,
|
||||
) -> BoxResultFuture<Option<BlockInfo>, CollaborateError>;
|
||||
) -> BoxResultFuture<Option<TextBlockInfo>, CollaborateError>;
|
||||
|
||||
fn read_document_revisions(
|
||||
&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 handle = spawn_blocking(|| OpenDocumentHandler::new(doc, persistence))
|
||||
.await
|
||||
@ -205,7 +205,7 @@ struct 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 (sender, receiver) = mpsc::channel(1000);
|
||||
let users = DashMap::new();
|
||||
|
@ -1,13 +1,13 @@
|
||||
use crate::{
|
||||
entities::{
|
||||
document_info::BlockInfo,
|
||||
folder_info::{FolderDelta, FolderInfo},
|
||||
revision::{RepeatedRevision, Revision},
|
||||
text_block_info::TextBlockInfo,
|
||||
},
|
||||
errors::{CollaborateError, CollaborateResult},
|
||||
protobuf::{
|
||||
BlockInfo as BlockInfoPB, FolderInfo as FolderInfoPB, RepeatedRevision as RepeatedRevisionPB,
|
||||
Revision as RevisionPB,
|
||||
FolderInfo as FolderInfoPB, RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB,
|
||||
TextBlockInfo as TextBlockInfoPB,
|
||||
},
|
||||
};
|
||||
use dissimilar::Chunk;
|
||||
@ -202,11 +202,11 @@ pub fn make_folder_pb_from_revisions_pb(
|
||||
pub fn make_document_info_from_revisions_pb(
|
||||
doc_id: &str,
|
||||
revisions: RepeatedRevisionPB,
|
||||
) -> Result<Option<BlockInfo>, CollaborateError> {
|
||||
) -> Result<Option<TextBlockInfo>, CollaborateError> {
|
||||
match make_document_info_pb_from_revisions_pb(doc_id, revisions)? {
|
||||
None => Ok(None),
|
||||
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))
|
||||
})?;
|
||||
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(
|
||||
doc_id: &str,
|
||||
mut revisions: RepeatedRevisionPB,
|
||||
) -> Result<Option<BlockInfoPB>, CollaborateError> {
|
||||
) -> Result<Option<TextBlockInfoPB>, CollaborateError> {
|
||||
let revisions = revisions.take_items();
|
||||
if revisions.is_empty() {
|
||||
return Ok(None);
|
||||
@ -240,7 +240,7 @@ pub fn make_document_info_pb_from_revisions_pb(
|
||||
}
|
||||
|
||||
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_text(text);
|
||||
block_info.set_base_rev_id(base_rev_id);
|
||||
|
@ -1,8 +1,6 @@
|
||||
use crate::entities::{Field, RowMeta};
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use flowy_derive::ProtoBuf;
|
||||
use std::collections::HashMap;
|
||||
use strum_macros::{Display, EnumIter, EnumString};
|
||||
|
||||
pub const DEFAULT_ROW_HEIGHT: i32 = 36;
|
||||
pub const DEFAULT_FIELD_WIDTH: i32 = 150;
|
||||
|
@ -1,4 +1,3 @@
|
||||
use crate::entities::Row;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
@ -16,14 +15,26 @@ pub struct GridMeta {
|
||||
pub fields: Vec<Field>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub rows: Vec<RowMeta>,
|
||||
pub blocks: Vec<Block>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
|
||||
pub struct GridBlock {
|
||||
pub struct Block {
|
||||
#[pb(index = 1)]
|
||||
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)]
|
||||
pub rows: Vec<RowMeta>,
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ pub struct GridMeta {
|
||||
// message fields
|
||||
pub grid_id: ::std::string::String,
|
||||
pub fields: ::protobuf::RepeatedField<Field>,
|
||||
pub rows: ::protobuf::RepeatedField<RowMeta>,
|
||||
pub blocks: ::protobuf::RepeatedField<Block>,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
@ -96,29 +96,29 @@ impl GridMeta {
|
||||
::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new())
|
||||
}
|
||||
|
||||
// repeated .RowMeta rows = 3;
|
||||
// repeated .Block blocks = 3;
|
||||
|
||||
|
||||
pub fn get_rows(&self) -> &[RowMeta] {
|
||||
&self.rows
|
||||
pub fn get_blocks(&self) -> &[Block] {
|
||||
&self.blocks
|
||||
}
|
||||
pub fn clear_rows(&mut self) {
|
||||
self.rows.clear();
|
||||
pub fn clear_blocks(&mut self) {
|
||||
self.blocks.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_rows(&mut self, v: ::protobuf::RepeatedField<RowMeta>) {
|
||||
self.rows = v;
|
||||
pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField<Block>) {
|
||||
self.blocks = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField<RowMeta> {
|
||||
&mut self.rows
|
||||
pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField<Block> {
|
||||
&mut self.blocks
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_rows(&mut self) -> ::protobuf::RepeatedField<RowMeta> {
|
||||
::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new())
|
||||
pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField<Block> {
|
||||
::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new())
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ impl ::protobuf::Message for GridMeta {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
for v in &self.rows {
|
||||
for v in &self.blocks {
|
||||
if !v.is_initialized() {
|
||||
return false;
|
||||
}
|
||||
@ -148,7 +148,7 @@ impl ::protobuf::Message for GridMeta {
|
||||
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.fields)?;
|
||||
},
|
||||
3 => {
|
||||
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.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())?;
|
||||
@ -169,7 +169,7 @@ impl ::protobuf::Message for GridMeta {
|
||||
let len = value.compute_size();
|
||||
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
|
||||
};
|
||||
for value in &self.rows {
|
||||
for value in &self.blocks {
|
||||
let len = value.compute_size();
|
||||
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
|
||||
};
|
||||
@ -187,7 +187,7 @@ impl ::protobuf::Message for GridMeta {
|
||||
os.write_raw_varint32(v.get_cached_size())?;
|
||||
v.write_to_with_cached_sizes(os)?;
|
||||
};
|
||||
for v in &self.rows {
|
||||
for v in &self.blocks {
|
||||
os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
|
||||
os.write_raw_varint32(v.get_cached_size())?;
|
||||
v.write_to_with_cached_sizes(os)?;
|
||||
@ -240,10 +240,10 @@ impl ::protobuf::Message for GridMeta {
|
||||
|m: &GridMeta| { &m.fields },
|
||||
|m: &mut GridMeta| { &mut m.fields },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<RowMeta>>(
|
||||
"rows",
|
||||
|m: &GridMeta| { &m.rows },
|
||||
|m: &mut GridMeta| { &mut m.rows },
|
||||
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Block>>(
|
||||
"blocks",
|
||||
|m: &GridMeta| { &m.blocks },
|
||||
|m: &mut GridMeta| { &mut m.blocks },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<GridMeta>(
|
||||
"GridMeta",
|
||||
@ -263,7 +263,7 @@ impl ::protobuf::Clear for GridMeta {
|
||||
fn clear(&mut self) {
|
||||
self.grid_id.clear();
|
||||
self.fields.clear();
|
||||
self.rows.clear();
|
||||
self.blocks.clear();
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
@ -281,23 +281,24 @@ impl ::protobuf::reflect::ProtobufValue for GridMeta {
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct GridBlock {
|
||||
pub struct Block {
|
||||
// message fields
|
||||
pub id: ::std::string::String,
|
||||
pub rows: ::protobuf::RepeatedField<RowMeta>,
|
||||
pub start_row_index: i32,
|
||||
pub row_count: i32,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a GridBlock {
|
||||
fn default() -> &'a GridBlock {
|
||||
<GridBlock as ::protobuf::Message>::default_instance()
|
||||
impl<'a> ::std::default::Default for &'a Block {
|
||||
fn default() -> &'a Block {
|
||||
<Block as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl GridBlock {
|
||||
pub fn new() -> GridBlock {
|
||||
impl Block {
|
||||
pub fn new() -> Block {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
@ -327,6 +328,234 @@ impl GridBlock {
|
||||
::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;
|
||||
|
||||
|
||||
@ -353,7 +582,7 @@ impl GridBlock {
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for GridBlock {
|
||||
impl ::protobuf::Message for BlockMeta {
|
||||
fn is_initialized(&self) -> bool {
|
||||
for v in &self.rows {
|
||||
if !v.is_initialized() {
|
||||
@ -368,7 +597,7 @@ impl ::protobuf::Message for GridBlock {
|
||||
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)?;
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?;
|
||||
},
|
||||
2 => {
|
||||
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?;
|
||||
@ -385,8 +614,8 @@ impl ::protobuf::Message for GridBlock {
|
||||
#[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.block_id.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(1, &self.block_id);
|
||||
}
|
||||
for value in &self.rows {
|
||||
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<()> {
|
||||
if !self.id.is_empty() {
|
||||
os.write_string(1, &self.id)?;
|
||||
if !self.block_id.is_empty() {
|
||||
os.write_string(1, &self.block_id)?;
|
||||
}
|
||||
for v in &self.rows {
|
||||
os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
|
||||
@ -436,8 +665,8 @@ impl ::protobuf::Message for GridBlock {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> GridBlock {
|
||||
GridBlock::new()
|
||||
fn new() -> BlockMeta {
|
||||
BlockMeta::new()
|
||||
}
|
||||
|
||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
@ -445,44 +674,44 @@ impl ::protobuf::Message for GridBlock {
|
||||
descriptor.get(|| {
|
||||
let mut fields = ::std::vec::Vec::new();
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"id",
|
||||
|m: &GridBlock| { &m.id },
|
||||
|m: &mut GridBlock| { &mut m.id },
|
||||
"block_id",
|
||||
|m: &BlockMeta| { &m.block_id },
|
||||
|m: &mut BlockMeta| { &mut m.block_id },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<RowMeta>>(
|
||||
"rows",
|
||||
|m: &GridBlock| { &m.rows },
|
||||
|m: &mut GridBlock| { &mut m.rows },
|
||||
|m: &BlockMeta| { &m.rows },
|
||||
|m: &mut BlockMeta| { &mut m.rows },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<GridBlock>(
|
||||
"GridBlock",
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<BlockMeta>(
|
||||
"BlockMeta",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static GridBlock {
|
||||
static instance: ::protobuf::rt::LazyV2<GridBlock> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(GridBlock::new)
|
||||
fn default_instance() -> &'static BlockMeta {
|
||||
static instance: ::protobuf::rt::LazyV2<BlockMeta> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(BlockMeta::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for GridBlock {
|
||||
impl ::protobuf::Clear for BlockMeta {
|
||||
fn clear(&mut self) {
|
||||
self.id.clear();
|
||||
self.block_id.clear();
|
||||
self.rows.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 {
|
||||
::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 {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
@ -1997,34 +2226,36 @@ impl ::protobuf::reflect::ProtobufValue for FieldType {
|
||||
}
|
||||
|
||||
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\
|
||||
s\x12\x1c\n\x04rows\x18\x03\x20\x03(\x0b2\x08.RowMetaR\x04rows\"9\n\tGri\
|
||||
dBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x1c\n\x04rows\x18\
|
||||
\x02\x20\x03(\x0b2\x08.RowMetaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\
|
||||
\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\
|
||||
\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_typ\
|
||||
e\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\
|
||||
\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\
|
||||
\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\x12+\n\
|
||||
\x0ctype_options\x18\x08\x20\x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\
|
||||
\rRepeatedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05i\
|
||||
tems\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\
|
||||
\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xfd\x01\n\x07RowMet\
|
||||
a\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\
|
||||
\x20\x01(\tR\x06gridId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\
|
||||
\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\
|
||||
\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\
|
||||
\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\
|
||||
\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\
|
||||
value:\x028\x01\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\
|
||||
\tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\
|
||||
field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\
|
||||
\x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05\
|
||||
R\x06height*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\
|
||||
\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\
|
||||
\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06prot\
|
||||
o3\
|
||||
s\x12\x1e\n\x06blocks\x18\x03\x20\x03(\x0b2\x06.BlockR\x06blocks\"\\\n\
|
||||
\x05Block\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12&\n\x0fstart_row_\
|
||||
index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\
|
||||
\x20\x01(\x05R\x08rowCount\"D\n\tBlockMeta\x12\x19\n\x08block_id\x18\x01\
|
||||
\x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.RowM\
|
||||
etaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\
|
||||
\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\
|
||||
\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\
|
||||
FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\
|
||||
n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\
|
||||
idth\x18\x07\x20\x01(\x05R\x05width\x12+\n\x0ctype_options\x18\x08\x20\
|
||||
\x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\rRepeatedField\x12\x1c\n\x05\
|
||||
items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"8\n\x07AnyData\x12\x17\
|
||||
\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\
|
||||
\x20\x01(\x0cR\x05value\"\xfd\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\
|
||||
\x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\
|
||||
\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByFiel\
|
||||
dIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06he\
|
||||
ight\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\n\x12C\
|
||||
ellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\
|
||||
\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\x82\x01\
|
||||
\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06ro\
|
||||
w_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\
|
||||
\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyDataR\x04d\
|
||||
ata\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\n\tFieldType\
|
||||
\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;
|
||||
|
@ -3,10 +3,15 @@ syntax = "proto3";
|
||||
message GridMeta {
|
||||
string grid_id = 1;
|
||||
repeated Field fields = 2;
|
||||
repeated RowMeta rows = 3;
|
||||
repeated Block blocks = 3;
|
||||
}
|
||||
message GridBlock {
|
||||
message Block {
|
||||
string id = 1;
|
||||
int32 start_row_index = 2;
|
||||
int32 row_count = 3;
|
||||
}
|
||||
message BlockMeta {
|
||||
string block_id = 1;
|
||||
repeated RowMeta rows = 2;
|
||||
}
|
||||
message Field {
|
||||
|
@ -7,14 +7,14 @@ fn grid_serde_test() {
|
||||
let grid = GridMeta {
|
||||
grid_id,
|
||||
fields,
|
||||
rows: vec![],
|
||||
blocks: vec![],
|
||||
};
|
||||
|
||||
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!(
|
||||
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 {
|
||||
grid_id,
|
||||
fields: vec![],
|
||||
rows: vec![],
|
||||
blocks: vec![],
|
||||
};
|
||||
|
||||
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 {
|
||||
|
Loading…
Reference in New Issue
Block a user