mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
refactor: add plugins
This commit is contained in:
parent
74831964a6
commit
8747457836
60
frontend/app_flowy/lib/plugin/plugin.dart
Normal file
60
frontend/app_flowy/lib/plugin/plugin.dart
Normal file
@ -0,0 +1,60 @@
|
||||
library flowy_plugin;
|
||||
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
export "./src/sandbox.dart";
|
||||
|
||||
typedef PluginType = String;
|
||||
|
||||
typedef PluginDataType = ViewDataType;
|
||||
|
||||
abstract class Plugin {
|
||||
PluginType get pluginType;
|
||||
|
||||
String get pluginId;
|
||||
|
||||
bool get enable;
|
||||
|
||||
void dispose();
|
||||
|
||||
PluginDisplay get display;
|
||||
}
|
||||
|
||||
abstract class PluginBuilder {
|
||||
Plugin build(dynamic data);
|
||||
|
||||
String get pluginName;
|
||||
|
||||
PluginType get pluginType;
|
||||
|
||||
ViewDataType get dataType;
|
||||
}
|
||||
|
||||
abstract class PluginDisplay with NavigationItem {
|
||||
@override
|
||||
Widget get leftBarItem;
|
||||
|
||||
@override
|
||||
Widget? get rightBarItem;
|
||||
|
||||
List<NavigationItem> get navigationItems;
|
||||
|
||||
Widget buildWidget();
|
||||
}
|
||||
|
||||
void registerPlugin({required PluginBuilder builder}) {
|
||||
getIt<PluginSandbox>().registerPlugin(builder.pluginType, builder);
|
||||
}
|
||||
|
||||
Plugin makePlugin({required String pluginType, dynamic data}) {
|
||||
final plugin = getIt<PluginSandbox>().buildPlugin(pluginType, data);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
enum FlowyPluginException {
|
||||
invalidData,
|
||||
}
|
1
frontend/app_flowy/lib/plugin/src/runner.dart
Normal file
1
frontend/app_flowy/lib/plugin/src/runner.dart
Normal file
@ -0,0 +1 @@
|
||||
class PluginRunner {}
|
40
frontend/app_flowy/lib/plugin/src/sandbox.dart
Normal file
40
frontend/app_flowy/lib/plugin/src/sandbox.dart
Normal file
@ -0,0 +1,40 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import '../plugin.dart';
|
||||
import 'runner.dart';
|
||||
|
||||
class PluginSandbox {
|
||||
final LinkedHashMap<String, PluginBuilder> _pluginMap = LinkedHashMap();
|
||||
late PluginRunner pluginRunner;
|
||||
|
||||
PluginSandbox() {
|
||||
pluginRunner = PluginRunner();
|
||||
}
|
||||
|
||||
int indexOf(String pluginType) {
|
||||
final index = _pluginMap.keys.toList().indexWhere((ty) => ty == pluginType);
|
||||
if (index == -1) {
|
||||
throw PlatformException(code: '-1', message: "Can't find the flowy plugin type: $pluginType");
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
Plugin buildPlugin(String pluginType, dynamic data) {
|
||||
final index = indexOf(pluginType);
|
||||
final plugin = _pluginMap[index]!.build(data);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
void registerPlugin(String pluginType, PluginBuilder builder) {
|
||||
if (_pluginMap.containsKey(pluginType)) {
|
||||
throw PlatformException(code: '-1', message: "$pluginType was registered before");
|
||||
}
|
||||
_pluginMap[pluginType] = builder;
|
||||
}
|
||||
|
||||
List<String> get supportPluginTypes => _pluginMap.keys.toList();
|
||||
|
||||
List<PluginBuilder> get builders => _pluginMap.values.toList();
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/startup/tasks/prelude.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -41,6 +42,7 @@ class FlowyRunner {
|
||||
getIt<AppLauncher>().addTask(InitRustSDKTask());
|
||||
|
||||
if (!env.isTest()) {
|
||||
getIt<AppLauncher>().addTask(PluginLoadTask());
|
||||
getIt<AppLauncher>().addTask(InitAppWidgetTask());
|
||||
getIt<AppLauncher>().addTask(InitPlatformServiceTask());
|
||||
}
|
||||
@ -58,6 +60,7 @@ Future<void> initGetIt(
|
||||
getIt.registerFactory<EntryPoint>(() => f);
|
||||
getIt.registerLazySingleton<FlowySDK>(() => const FlowySDK());
|
||||
getIt.registerLazySingleton<AppLauncher>(() => AppLauncher(env, getIt));
|
||||
getIt.registerSingleton<PluginSandbox>(PluginSandbox());
|
||||
|
||||
await UserDepsResolver.resolve(getIt);
|
||||
await HomeDepsResolver.resolve(getIt);
|
||||
|
39
frontend/app_flowy/lib/startup/tasks/load_plugin.dart
Normal file
39
frontend/app_flowy/lib/startup/tasks/load_plugin.dart
Normal file
@ -0,0 +1,39 @@
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
|
||||
import 'package:app_flowy/workspace/presentation/stack_page/doc/doc_stack_page.dart';
|
||||
import 'package:app_flowy/workspace/presentation/stack_page/trash/trash_page.dart';
|
||||
|
||||
enum DefaultPluginEnum {
|
||||
blank,
|
||||
trash,
|
||||
}
|
||||
|
||||
extension FlowyDefaultPluginExt on DefaultPluginEnum {
|
||||
String type() {
|
||||
switch (this) {
|
||||
case DefaultPluginEnum.blank:
|
||||
return "Blank";
|
||||
case DefaultPluginEnum.trash:
|
||||
return "Trash";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isDefaultPlugin(String pluginType) {
|
||||
return DefaultPluginEnum.values.map((e) => e.type()).contains(pluginType);
|
||||
}
|
||||
|
||||
class PluginLoadTask extends LaunchTask {
|
||||
@override
|
||||
LaunchTaskType get type => LaunchTaskType.dataProcessing;
|
||||
|
||||
@override
|
||||
Future<void> initialize(LaunchContext context) async {
|
||||
registerPlugin(builder: DocumentPluginBuilder());
|
||||
|
||||
registerPlugin(builder: TrashPluginBuilder());
|
||||
|
||||
registerPlugin(builder: BlankPluginBuilder());
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
export 'app_widget.dart';
|
||||
export 'init_sdk.dart';
|
||||
export 'rust_sdk.dart';
|
||||
export 'platform_service.dart';
|
||||
export 'load_plugin.dart';
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/workspace/infrastructure/repos/app_repo.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
|
||||
@ -21,7 +22,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
|
||||
);
|
||||
await _fetchViews(emit);
|
||||
}, createView: (CreateView value) async {
|
||||
final viewOrFailed = await repo.createView(name: value.name, desc: value.desc, viewType: value.viewType);
|
||||
final viewOrFailed = await repo.createView(name: value.name, desc: value.desc, dataType: value.dataType);
|
||||
viewOrFailed.fold(
|
||||
(view) => emit(state.copyWith(
|
||||
latestCreatedView: view,
|
||||
@ -95,7 +96,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
|
||||
@freezed
|
||||
class AppEvent with _$AppEvent {
|
||||
const factory AppEvent.initial() = Initial;
|
||||
const factory AppEvent.createView(String name, String desc, ViewType viewType) = CreateView;
|
||||
const factory AppEvent.createView(String name, String desc, PluginDataType dataType) = CreateView;
|
||||
const factory AppEvent.delete() = Delete;
|
||||
const factory AppEvent.rename(String newName) = Rename;
|
||||
const factory AppEvent.didReceiveViews(List<View> views) = ReceiveViews;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/startup/tasks/load_plugin.dart';
|
||||
import 'package:app_flowy/workspace/infrastructure/repos/workspace_repo.dart';
|
||||
import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
|
||||
@ -26,7 +26,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
|
||||
emit(state.copyWith(isCollapse: !isCollapse));
|
||||
},
|
||||
openPage: (e) async {
|
||||
emit(state.copyWith(stackContext: e.context));
|
||||
emit(state.copyWith(plugin: e.plugin));
|
||||
},
|
||||
createApp: (CreateApp event) async {
|
||||
await _performActionOnCreateApp(event, emit);
|
||||
@ -82,7 +82,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
|
||||
class MenuEvent with _$MenuEvent {
|
||||
const factory MenuEvent.initial() = _Initial;
|
||||
const factory MenuEvent.collapse() = Collapse;
|
||||
const factory MenuEvent.openPage(HomeStackContext context) = OpenPage;
|
||||
const factory MenuEvent.openPage(Plugin plugin) = OpenPage;
|
||||
const factory MenuEvent.createApp(String name, {String? desc}) = CreateApp;
|
||||
const factory MenuEvent.didReceiveApps(Either<List<App>, FlowyError> appsOrFail) = ReceiveApps;
|
||||
}
|
||||
@ -93,13 +93,13 @@ class MenuState with _$MenuState {
|
||||
required bool isCollapse,
|
||||
required Option<List<App>> apps,
|
||||
required Either<Unit, FlowyError> successOrFailure,
|
||||
required HomeStackContext stackContext,
|
||||
required Plugin plugin,
|
||||
}) = _MenuState;
|
||||
|
||||
factory MenuState.initial() => MenuState(
|
||||
isCollapse: false,
|
||||
apps: none(),
|
||||
successOrFailure: left(unit),
|
||||
stackContext: BlankStackContext(),
|
||||
plugin: makePlugin(pluginType: DefaultPluginEnum.blank.type()),
|
||||
);
|
||||
}
|
||||
|
@ -25,9 +25,9 @@ class _$MenuEventTearOff {
|
||||
return const Collapse();
|
||||
}
|
||||
|
||||
OpenPage openPage(HomeStackContext<dynamic, dynamic> context) {
|
||||
OpenPage openPage(Plugin plugin) {
|
||||
return OpenPage(
|
||||
context,
|
||||
plugin,
|
||||
);
|
||||
}
|
||||
|
||||
@ -54,8 +54,7 @@ mixin _$MenuEvent {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() collapse,
|
||||
required TResult Function(HomeStackContext<dynamic, dynamic> context)
|
||||
openPage,
|
||||
required TResult Function(Plugin plugin) openPage,
|
||||
required TResult Function(String name, String? desc) createApp,
|
||||
required TResult Function(Either<List<App>, FlowyError> appsOrFail)
|
||||
didReceiveApps,
|
||||
@ -65,7 +64,7 @@ mixin _$MenuEvent {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? collapse,
|
||||
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
|
||||
TResult Function(Plugin plugin)? openPage,
|
||||
TResult Function(String name, String? desc)? createApp,
|
||||
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
|
||||
}) =>
|
||||
@ -74,7 +73,7 @@ mixin _$MenuEvent {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? collapse,
|
||||
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
|
||||
TResult Function(Plugin plugin)? openPage,
|
||||
TResult Function(String name, String? desc)? createApp,
|
||||
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
|
||||
required TResult orElse(),
|
||||
@ -164,8 +163,7 @@ class _$_Initial implements _Initial {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() collapse,
|
||||
required TResult Function(HomeStackContext<dynamic, dynamic> context)
|
||||
openPage,
|
||||
required TResult Function(Plugin plugin) openPage,
|
||||
required TResult Function(String name, String? desc) createApp,
|
||||
required TResult Function(Either<List<App>, FlowyError> appsOrFail)
|
||||
didReceiveApps,
|
||||
@ -178,7 +176,7 @@ class _$_Initial implements _Initial {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? collapse,
|
||||
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
|
||||
TResult Function(Plugin plugin)? openPage,
|
||||
TResult Function(String name, String? desc)? createApp,
|
||||
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
|
||||
}) {
|
||||
@ -190,7 +188,7 @@ class _$_Initial implements _Initial {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? collapse,
|
||||
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
|
||||
TResult Function(Plugin plugin)? openPage,
|
||||
TResult Function(String name, String? desc)? createApp,
|
||||
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
|
||||
required TResult orElse(),
|
||||
@ -285,8 +283,7 @@ class _$Collapse implements Collapse {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() collapse,
|
||||
required TResult Function(HomeStackContext<dynamic, dynamic> context)
|
||||
openPage,
|
||||
required TResult Function(Plugin plugin) openPage,
|
||||
required TResult Function(String name, String? desc) createApp,
|
||||
required TResult Function(Either<List<App>, FlowyError> appsOrFail)
|
||||
didReceiveApps,
|
||||
@ -299,7 +296,7 @@ class _$Collapse implements Collapse {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? collapse,
|
||||
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
|
||||
TResult Function(Plugin plugin)? openPage,
|
||||
TResult Function(String name, String? desc)? createApp,
|
||||
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
|
||||
}) {
|
||||
@ -311,7 +308,7 @@ class _$Collapse implements Collapse {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? collapse,
|
||||
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
|
||||
TResult Function(Plugin plugin)? openPage,
|
||||
TResult Function(String name, String? desc)? createApp,
|
||||
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
|
||||
required TResult orElse(),
|
||||
@ -371,7 +368,7 @@ abstract class Collapse implements MenuEvent {
|
||||
abstract class $OpenPageCopyWith<$Res> {
|
||||
factory $OpenPageCopyWith(OpenPage value, $Res Function(OpenPage) then) =
|
||||
_$OpenPageCopyWithImpl<$Res>;
|
||||
$Res call({HomeStackContext<dynamic, dynamic> context});
|
||||
$Res call({Plugin plugin});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@ -385,13 +382,13 @@ class _$OpenPageCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res>
|
||||
|
||||
@override
|
||||
$Res call({
|
||||
Object? context = freezed,
|
||||
Object? plugin = freezed,
|
||||
}) {
|
||||
return _then(OpenPage(
|
||||
context == freezed
|
||||
? _value.context
|
||||
: context // ignore: cast_nullable_to_non_nullable
|
||||
as HomeStackContext<dynamic, dynamic>,
|
||||
plugin == freezed
|
||||
? _value.plugin
|
||||
: plugin // ignore: cast_nullable_to_non_nullable
|
||||
as Plugin,
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -399,27 +396,27 @@ class _$OpenPageCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res>
|
||||
/// @nodoc
|
||||
|
||||
class _$OpenPage implements OpenPage {
|
||||
const _$OpenPage(this.context);
|
||||
const _$OpenPage(this.plugin);
|
||||
|
||||
@override
|
||||
final HomeStackContext<dynamic, dynamic> context;
|
||||
final Plugin plugin;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MenuEvent.openPage(context: $context)';
|
||||
return 'MenuEvent.openPage(plugin: $plugin)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) ||
|
||||
(other is OpenPage &&
|
||||
(identical(other.context, context) ||
|
||||
const DeepCollectionEquality().equals(other.context, context)));
|
||||
(identical(other.plugin, plugin) ||
|
||||
const DeepCollectionEquality().equals(other.plugin, plugin)));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
runtimeType.hashCode ^ const DeepCollectionEquality().hash(context);
|
||||
runtimeType.hashCode ^ const DeepCollectionEquality().hash(plugin);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@ -431,13 +428,12 @@ class _$OpenPage implements OpenPage {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() collapse,
|
||||
required TResult Function(HomeStackContext<dynamic, dynamic> context)
|
||||
openPage,
|
||||
required TResult Function(Plugin plugin) openPage,
|
||||
required TResult Function(String name, String? desc) createApp,
|
||||
required TResult Function(Either<List<App>, FlowyError> appsOrFail)
|
||||
didReceiveApps,
|
||||
}) {
|
||||
return openPage(context);
|
||||
return openPage(plugin);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -445,11 +441,11 @@ class _$OpenPage implements OpenPage {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? collapse,
|
||||
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
|
||||
TResult Function(Plugin plugin)? openPage,
|
||||
TResult Function(String name, String? desc)? createApp,
|
||||
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
|
||||
}) {
|
||||
return openPage?.call(context);
|
||||
return openPage?.call(plugin);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -457,13 +453,13 @@ class _$OpenPage implements OpenPage {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? collapse,
|
||||
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
|
||||
TResult Function(Plugin plugin)? openPage,
|
||||
TResult Function(String name, String? desc)? createApp,
|
||||
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (openPage != null) {
|
||||
return openPage(context);
|
||||
return openPage(plugin);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
@ -510,11 +506,9 @@ class _$OpenPage implements OpenPage {
|
||||
}
|
||||
|
||||
abstract class OpenPage implements MenuEvent {
|
||||
const factory OpenPage(HomeStackContext<dynamic, dynamic> context) =
|
||||
_$OpenPage;
|
||||
const factory OpenPage(Plugin plugin) = _$OpenPage;
|
||||
|
||||
HomeStackContext<dynamic, dynamic> get context =>
|
||||
throw _privateConstructorUsedError;
|
||||
Plugin get plugin => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$OpenPageCopyWith<OpenPage> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
@ -595,8 +589,7 @@ class _$CreateApp implements CreateApp {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() collapse,
|
||||
required TResult Function(HomeStackContext<dynamic, dynamic> context)
|
||||
openPage,
|
||||
required TResult Function(Plugin plugin) openPage,
|
||||
required TResult Function(String name, String? desc) createApp,
|
||||
required TResult Function(Either<List<App>, FlowyError> appsOrFail)
|
||||
didReceiveApps,
|
||||
@ -609,7 +602,7 @@ class _$CreateApp implements CreateApp {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? collapse,
|
||||
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
|
||||
TResult Function(Plugin plugin)? openPage,
|
||||
TResult Function(String name, String? desc)? createApp,
|
||||
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
|
||||
}) {
|
||||
@ -621,7 +614,7 @@ class _$CreateApp implements CreateApp {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? collapse,
|
||||
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
|
||||
TResult Function(Plugin plugin)? openPage,
|
||||
TResult Function(String name, String? desc)? createApp,
|
||||
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
|
||||
required TResult orElse(),
|
||||
@ -750,8 +743,7 @@ class _$ReceiveApps implements ReceiveApps {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() collapse,
|
||||
required TResult Function(HomeStackContext<dynamic, dynamic> context)
|
||||
openPage,
|
||||
required TResult Function(Plugin plugin) openPage,
|
||||
required TResult Function(String name, String? desc) createApp,
|
||||
required TResult Function(Either<List<App>, FlowyError> appsOrFail)
|
||||
didReceiveApps,
|
||||
@ -764,7 +756,7 @@ class _$ReceiveApps implements ReceiveApps {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? collapse,
|
||||
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
|
||||
TResult Function(Plugin plugin)? openPage,
|
||||
TResult Function(String name, String? desc)? createApp,
|
||||
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
|
||||
}) {
|
||||
@ -776,7 +768,7 @@ class _$ReceiveApps implements ReceiveApps {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? collapse,
|
||||
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
|
||||
TResult Function(Plugin plugin)? openPage,
|
||||
TResult Function(String name, String? desc)? createApp,
|
||||
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
|
||||
required TResult orElse(),
|
||||
@ -847,12 +839,12 @@ class _$MenuStateTearOff {
|
||||
{required bool isCollapse,
|
||||
required Option<List<App>> apps,
|
||||
required Either<Unit, FlowyError> successOrFailure,
|
||||
required HomeStackContext<dynamic, dynamic> stackContext}) {
|
||||
required Plugin plugin}) {
|
||||
return _MenuState(
|
||||
isCollapse: isCollapse,
|
||||
apps: apps,
|
||||
successOrFailure: successOrFailure,
|
||||
stackContext: stackContext,
|
||||
plugin: plugin,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -866,8 +858,7 @@ mixin _$MenuState {
|
||||
Option<List<App>> get apps => throw _privateConstructorUsedError;
|
||||
Either<Unit, FlowyError> get successOrFailure =>
|
||||
throw _privateConstructorUsedError;
|
||||
HomeStackContext<dynamic, dynamic> get stackContext =>
|
||||
throw _privateConstructorUsedError;
|
||||
Plugin get plugin => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
$MenuStateCopyWith<MenuState> get copyWith =>
|
||||
@ -882,7 +873,7 @@ abstract class $MenuStateCopyWith<$Res> {
|
||||
{bool isCollapse,
|
||||
Option<List<App>> apps,
|
||||
Either<Unit, FlowyError> successOrFailure,
|
||||
HomeStackContext<dynamic, dynamic> stackContext});
|
||||
Plugin plugin});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@ -898,7 +889,7 @@ class _$MenuStateCopyWithImpl<$Res> implements $MenuStateCopyWith<$Res> {
|
||||
Object? isCollapse = freezed,
|
||||
Object? apps = freezed,
|
||||
Object? successOrFailure = freezed,
|
||||
Object? stackContext = freezed,
|
||||
Object? plugin = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
isCollapse: isCollapse == freezed
|
||||
@ -913,10 +904,10 @@ class _$MenuStateCopyWithImpl<$Res> implements $MenuStateCopyWith<$Res> {
|
||||
? _value.successOrFailure
|
||||
: successOrFailure // ignore: cast_nullable_to_non_nullable
|
||||
as Either<Unit, FlowyError>,
|
||||
stackContext: stackContext == freezed
|
||||
? _value.stackContext
|
||||
: stackContext // ignore: cast_nullable_to_non_nullable
|
||||
as HomeStackContext<dynamic, dynamic>,
|
||||
plugin: plugin == freezed
|
||||
? _value.plugin
|
||||
: plugin // ignore: cast_nullable_to_non_nullable
|
||||
as Plugin,
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -931,7 +922,7 @@ abstract class _$MenuStateCopyWith<$Res> implements $MenuStateCopyWith<$Res> {
|
||||
{bool isCollapse,
|
||||
Option<List<App>> apps,
|
||||
Either<Unit, FlowyError> successOrFailure,
|
||||
HomeStackContext<dynamic, dynamic> stackContext});
|
||||
Plugin plugin});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@ -948,7 +939,7 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res>
|
||||
Object? isCollapse = freezed,
|
||||
Object? apps = freezed,
|
||||
Object? successOrFailure = freezed,
|
||||
Object? stackContext = freezed,
|
||||
Object? plugin = freezed,
|
||||
}) {
|
||||
return _then(_MenuState(
|
||||
isCollapse: isCollapse == freezed
|
||||
@ -963,10 +954,10 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res>
|
||||
? _value.successOrFailure
|
||||
: successOrFailure // ignore: cast_nullable_to_non_nullable
|
||||
as Either<Unit, FlowyError>,
|
||||
stackContext: stackContext == freezed
|
||||
? _value.stackContext
|
||||
: stackContext // ignore: cast_nullable_to_non_nullable
|
||||
as HomeStackContext<dynamic, dynamic>,
|
||||
plugin: plugin == freezed
|
||||
? _value.plugin
|
||||
: plugin // ignore: cast_nullable_to_non_nullable
|
||||
as Plugin,
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -978,7 +969,7 @@ class _$_MenuState implements _MenuState {
|
||||
{required this.isCollapse,
|
||||
required this.apps,
|
||||
required this.successOrFailure,
|
||||
required this.stackContext});
|
||||
required this.plugin});
|
||||
|
||||
@override
|
||||
final bool isCollapse;
|
||||
@ -987,11 +978,11 @@ class _$_MenuState implements _MenuState {
|
||||
@override
|
||||
final Either<Unit, FlowyError> successOrFailure;
|
||||
@override
|
||||
final HomeStackContext<dynamic, dynamic> stackContext;
|
||||
final Plugin plugin;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MenuState(isCollapse: $isCollapse, apps: $apps, successOrFailure: $successOrFailure, stackContext: $stackContext)';
|
||||
return 'MenuState(isCollapse: $isCollapse, apps: $apps, successOrFailure: $successOrFailure, plugin: $plugin)';
|
||||
}
|
||||
|
||||
@override
|
||||
@ -1006,9 +997,8 @@ class _$_MenuState implements _MenuState {
|
||||
(identical(other.successOrFailure, successOrFailure) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.successOrFailure, successOrFailure)) &&
|
||||
(identical(other.stackContext, stackContext) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.stackContext, stackContext)));
|
||||
(identical(other.plugin, plugin) ||
|
||||
const DeepCollectionEquality().equals(other.plugin, plugin)));
|
||||
}
|
||||
|
||||
@override
|
||||
@ -1017,7 +1007,7 @@ class _$_MenuState implements _MenuState {
|
||||
const DeepCollectionEquality().hash(isCollapse) ^
|
||||
const DeepCollectionEquality().hash(apps) ^
|
||||
const DeepCollectionEquality().hash(successOrFailure) ^
|
||||
const DeepCollectionEquality().hash(stackContext);
|
||||
const DeepCollectionEquality().hash(plugin);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@ -1030,7 +1020,7 @@ abstract class _MenuState implements MenuState {
|
||||
{required bool isCollapse,
|
||||
required Option<List<App>> apps,
|
||||
required Either<Unit, FlowyError> successOrFailure,
|
||||
required HomeStackContext<dynamic, dynamic> stackContext}) = _$_MenuState;
|
||||
required Plugin plugin}) = _$_MenuState;
|
||||
|
||||
@override
|
||||
bool get isCollapse => throw _privateConstructorUsedError;
|
||||
@ -1040,8 +1030,7 @@ abstract class _MenuState implements MenuState {
|
||||
Either<Unit, FlowyError> get successOrFailure =>
|
||||
throw _privateConstructorUsedError;
|
||||
@override
|
||||
HomeStackContext<dynamic, dynamic> get stackContext =>
|
||||
throw _privateConstructorUsedError;
|
||||
Plugin get plugin => throw _privateConstructorUsedError;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$MenuStateCopyWith<_MenuState> get copyWith =>
|
||||
|
@ -9,7 +9,6 @@ part 'view_bloc.freezed.dart';
|
||||
|
||||
class ViewMenuBloc extends Bloc<ViewEvent, ViewState> {
|
||||
final ViewRepository repo;
|
||||
|
||||
final ViewListener listener;
|
||||
|
||||
ViewMenuBloc({
|
||||
|
@ -1,27 +0,0 @@
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
|
||||
AssetImage assetImageForViewType(ViewType type) {
|
||||
final imageName = _imageNameForViewType(type);
|
||||
return AssetImage('assets/images/$imageName');
|
||||
}
|
||||
|
||||
extension SvgViewType on View {
|
||||
Widget thumbnail({Color? iconColor}) {
|
||||
final imageName = _imageNameForViewType(viewType);
|
||||
final Widget widget = svg(imageName, color: iconColor);
|
||||
return widget;
|
||||
}
|
||||
}
|
||||
|
||||
String _imageNameForViewType(ViewType type) {
|
||||
switch (type) {
|
||||
case ViewType.RichText:
|
||||
return "file_icon";
|
||||
case ViewType.Plugin:
|
||||
return "file_icon";
|
||||
default:
|
||||
return "file_icon";
|
||||
}
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/startup/tasks/load_plugin.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
@ -10,23 +12,13 @@ typedef NavigationCallback = void Function(String id);
|
||||
abstract class NavigationItem {
|
||||
Widget get leftBarItem;
|
||||
Widget? get rightBarItem => null;
|
||||
String get identifier;
|
||||
|
||||
NavigationCallback get action => (id) {
|
||||
getIt<HomeStackManager>().setStackWithId(id);
|
||||
};
|
||||
}
|
||||
|
||||
enum HomeStackType {
|
||||
blank,
|
||||
document,
|
||||
kanban,
|
||||
trash,
|
||||
}
|
||||
|
||||
List<HomeStackType> pages = HomeStackType.values.toList();
|
||||
|
||||
abstract class HomeStackContext<T, S> with NavigationItem {
|
||||
abstract class HomeStackContext<T> with NavigationItem {
|
||||
List<NavigationItem> get navigationItems;
|
||||
|
||||
@override
|
||||
@ -35,40 +27,35 @@ abstract class HomeStackContext<T, S> with NavigationItem {
|
||||
@override
|
||||
Widget? get rightBarItem;
|
||||
|
||||
@override
|
||||
String get identifier;
|
||||
|
||||
ValueNotifier<T> get isUpdated;
|
||||
|
||||
HomeStackType get type;
|
||||
|
||||
Widget buildWidget();
|
||||
|
||||
void dispose();
|
||||
}
|
||||
|
||||
class HomeStackNotifier extends ChangeNotifier {
|
||||
HomeStackContext stackContext;
|
||||
Plugin _plugin;
|
||||
PublishNotifier<bool> collapsedNotifier = PublishNotifier();
|
||||
|
||||
Widget get titleWidget => stackContext.leftBarItem;
|
||||
Widget get titleWidget => _plugin.display.leftBarItem;
|
||||
|
||||
HomeStackNotifier({HomeStackContext? context}) : stackContext = context ?? BlankStackContext();
|
||||
HomeStackNotifier({Plugin? plugin}) : _plugin = plugin ?? makePlugin(pluginType: DefaultPluginEnum.blank.type());
|
||||
|
||||
set context(HomeStackContext context) {
|
||||
if (stackContext.identifier == context.identifier) {
|
||||
set plugin(Plugin newPlugin) {
|
||||
if (newPlugin.pluginId == _plugin.pluginId) {
|
||||
return;
|
||||
}
|
||||
|
||||
stackContext.isUpdated.removeListener(notifyListeners);
|
||||
stackContext.dispose();
|
||||
// stackContext.isUpdated.removeListener(notifyListeners);
|
||||
_plugin.dispose();
|
||||
|
||||
stackContext = context;
|
||||
stackContext.isUpdated.addListener(notifyListeners);
|
||||
_plugin = newPlugin;
|
||||
// stackContext.isUpdated.addListener(notifyListeners);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
HomeStackContext get context => stackContext;
|
||||
Plugin get plugin => _plugin;
|
||||
}
|
||||
|
||||
// HomeStack is initialized as singleton to controll the page stack.
|
||||
@ -77,13 +64,13 @@ class HomeStackManager {
|
||||
HomeStackManager();
|
||||
|
||||
Widget title() {
|
||||
return _notifier.context.leftBarItem;
|
||||
return _notifier.plugin.display.leftBarItem;
|
||||
}
|
||||
|
||||
PublishNotifier<bool> get collapsedNotifier => _notifier.collapsedNotifier;
|
||||
|
||||
void setStack(HomeStackContext context) {
|
||||
_notifier.context = context;
|
||||
void setPlugin(Plugin newPlugin) {
|
||||
_notifier.plugin = newPlugin;
|
||||
}
|
||||
|
||||
void setStackWithId(String id) {}
|
||||
@ -109,10 +96,10 @@ class HomeStackManager {
|
||||
],
|
||||
child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) {
|
||||
return FadingIndexedStack(
|
||||
index: pages.indexOf(notifier.context.type),
|
||||
children: HomeStackType.values.map((viewType) {
|
||||
if (viewType == notifier.context.type) {
|
||||
return notifier.context.buildWidget();
|
||||
index: getIt<PluginSandbox>().indexOf(notifier.plugin.pluginType),
|
||||
children: getIt<PluginSandbox>().supportPluginTypes.map((pluginType) {
|
||||
if (pluginType == notifier.plugin.pluginType) {
|
||||
return notifier.plugin.display.buildWidget();
|
||||
} else {
|
||||
return const BlankStackPage();
|
||||
}
|
||||
|
@ -1,40 +1,18 @@
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
|
||||
import 'package:app_flowy/workspace/presentation/stack_page/doc/doc_stack_page.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
extension ToHomeStackContext on View {
|
||||
HomeStackContext stackContext() {
|
||||
switch (viewType) {
|
||||
case ViewType.RichText:
|
||||
return DocumentStackContext(view: this);
|
||||
case ViewType.Plugin:
|
||||
return DocumentStackContext(view: this);
|
||||
default:
|
||||
return BlankStackContext();
|
||||
}
|
||||
}
|
||||
enum FlowyPlugin {
|
||||
editor,
|
||||
kanban,
|
||||
}
|
||||
|
||||
extension ToHomeStackType on View {
|
||||
HomeStackType stackType() {
|
||||
switch (viewType) {
|
||||
case ViewType.RichText:
|
||||
return HomeStackType.document;
|
||||
case ViewType.PlainText:
|
||||
return HomeStackType.kanban;
|
||||
default:
|
||||
return HomeStackType.blank;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ViewTypeExtension on ViewType {
|
||||
extension FlowyPluginExtension on FlowyPlugin {
|
||||
String displayName() {
|
||||
switch (this) {
|
||||
case ViewType.RichText:
|
||||
case FlowyPlugin.editor:
|
||||
return "Doc";
|
||||
case ViewType.Plugin:
|
||||
case FlowyPlugin.kanban:
|
||||
return "Kanban";
|
||||
default:
|
||||
return "";
|
||||
@ -43,12 +21,24 @@ extension ViewTypeExtension on ViewType {
|
||||
|
||||
bool enable() {
|
||||
switch (this) {
|
||||
case ViewType.RichText:
|
||||
case FlowyPlugin.editor:
|
||||
return true;
|
||||
case ViewType.Plugin:
|
||||
case FlowyPlugin.kanban:
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ViewExtension on View {
|
||||
Widget renderThumbnail({Color? iconColor}) {
|
||||
String thumbnail = this.thumbnail;
|
||||
if (thumbnail.isEmpty) {
|
||||
thumbnail = "file_icon";
|
||||
}
|
||||
|
||||
final Widget widget = svg(thumbnail, color: iconColor);
|
||||
return widget;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
@ -26,13 +27,13 @@ class AppRepository {
|
||||
Future<Either<View, FlowyError>> createView({
|
||||
required String name,
|
||||
required String desc,
|
||||
required ViewType viewType,
|
||||
required PluginDataType dataType,
|
||||
}) {
|
||||
final request = CreateViewPayload.create()
|
||||
..belongToId = appId
|
||||
..name = name
|
||||
..desc = desc
|
||||
..viewType = viewType;
|
||||
..dataType = dataType;
|
||||
|
||||
return FolderEventCreateView(request).send();
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/workspace/application/home/home_bloc.dart';
|
||||
import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
@ -109,7 +110,8 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
Widget _buildHomeMenu({required HomeLayout layout, required BuildContext context}) {
|
||||
if (initialView == null && widget.workspaceSetting.hasLatestView()) {
|
||||
initialView = widget.workspaceSetting.latestView;
|
||||
getIt<HomeStackManager>().setStack(initialView!.stackContext());
|
||||
final plugin = makePlugin(pluginType: "RichText", data: initialView);
|
||||
getIt<HomeStackManager>().setPlugin(plugin);
|
||||
}
|
||||
|
||||
HomeMenu homeMenu = HomeMenu(
|
||||
|
@ -17,8 +17,8 @@ class NavigationNotifier with ChangeNotifier {
|
||||
|
||||
void update(HomeStackNotifier notifier) {
|
||||
bool shouldNotify = false;
|
||||
if (navigationItems != notifier.context.navigationItems) {
|
||||
navigationItems = notifier.context.navigationItems;
|
||||
if (navigationItems != notifier.plugin.display.navigationItems) {
|
||||
navigationItems = notifier.plugin.display.navigationItems;
|
||||
shouldNotify = true;
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ class FlowyNavigation extends StatelessWidget {
|
||||
create: (_) {
|
||||
final notifier = Provider.of<HomeStackNotifier>(context, listen: false);
|
||||
return NavigationNotifier(
|
||||
navigationItems: notifier.context.navigationItems,
|
||||
navigationItems: notifier.plugin.display.navigationItems,
|
||||
collapasedNotifier: notifier.collapsedNotifier,
|
||||
);
|
||||
},
|
||||
|
@ -1,24 +1,60 @@
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:app_flowy/startup/tasks/load_plugin.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pbenum.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
|
||||
class BlankStackContext extends HomeStackContext {
|
||||
final ValueNotifier<bool> _isUpdated = ValueNotifier<bool>(false);
|
||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
|
||||
class BlankPluginBuilder implements PluginBuilder {
|
||||
@override
|
||||
Plugin build(dynamic data) {
|
||||
return BlankPagePlugin(pluginType: pluginType);
|
||||
}
|
||||
|
||||
@override
|
||||
String get identifier => "1";
|
||||
String get pluginName => "Blank";
|
||||
|
||||
@override
|
||||
PluginType get pluginType => DefaultPluginEnum.blank.type();
|
||||
|
||||
@override
|
||||
ViewDataType get dataType => ViewDataType.PlainText;
|
||||
}
|
||||
|
||||
class BlankPagePlugin implements Plugin {
|
||||
late PluginType _pluginType;
|
||||
BlankPagePlugin({
|
||||
required String pluginType,
|
||||
}) {
|
||||
_pluginType = pluginType;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {}
|
||||
|
||||
@override
|
||||
PluginDisplay get display => BlankPagePluginDisplay();
|
||||
|
||||
@override
|
||||
bool get enable => true;
|
||||
|
||||
@override
|
||||
String get pluginId => "BlankStack";
|
||||
|
||||
@override
|
||||
PluginType get pluginType => _pluginType;
|
||||
}
|
||||
|
||||
class BlankPagePluginDisplay extends PluginDisplay {
|
||||
@override
|
||||
Widget get leftBarItem => FlowyText.medium(LocaleKeys.blankPageTitle.tr(), fontSize: 12);
|
||||
|
||||
@override
|
||||
Widget? get rightBarItem => null;
|
||||
|
||||
@override
|
||||
HomeStackType get type => HomeStackType.blank;
|
||||
|
||||
@override
|
||||
Widget buildWidget() {
|
||||
return const BlankStackPage();
|
||||
@ -26,12 +62,6 @@ class BlankStackContext extends HomeStackContext {
|
||||
|
||||
@override
|
||||
List<NavigationItem> get navigationItems => [this];
|
||||
|
||||
@override
|
||||
ValueNotifier<bool> get isUpdated => _isUpdated;
|
||||
|
||||
@override
|
||||
void dispose() {}
|
||||
}
|
||||
|
||||
class BlankStackPage extends StatefulWidget {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/appearance.dart';
|
||||
import 'package:app_flowy/workspace/application/doc/share_bloc.dart';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:app_flowy/workspace/domain/view_ext.dart';
|
||||
import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.dart';
|
||||
@ -24,12 +24,34 @@ import 'package:provider/provider.dart';
|
||||
|
||||
import 'document_page.dart';
|
||||
|
||||
class DocumentStackContext extends HomeStackContext<int, ShareActionWrapper> {
|
||||
View _view;
|
||||
class DocumentPluginBuilder implements PluginBuilder {
|
||||
@override
|
||||
Plugin build(dynamic data) {
|
||||
if (data is View) {
|
||||
return DocumentPlugin(pluginType: pluginType, view: data);
|
||||
} else {
|
||||
throw FlowyPluginException.invalidData;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String get pluginName => "Doc";
|
||||
|
||||
@override
|
||||
PluginType get pluginType => "RichText";
|
||||
|
||||
@override
|
||||
ViewDataType get dataType => ViewDataType.RichText;
|
||||
}
|
||||
|
||||
class DocumentPlugin implements Plugin {
|
||||
late View _view;
|
||||
late ViewListener _listener;
|
||||
final ValueNotifier<int> _isUpdated = ValueNotifier<int>(0);
|
||||
late PluginType _pluginType;
|
||||
|
||||
DocumentStackContext({required View view, Key? key}) : _view = view {
|
||||
DocumentPlugin({required PluginType pluginType, required View view, Key? key}) : _view = view {
|
||||
_pluginType = pluginType;
|
||||
_listener = getIt<ViewListener>(param1: view);
|
||||
_listener.updatedNotifier.addPublishListener((result) {
|
||||
result.fold(
|
||||
@ -43,37 +65,46 @@ class DocumentStackContext extends HomeStackContext<int, ShareActionWrapper> {
|
||||
_listener.start();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener.close();
|
||||
}
|
||||
|
||||
@override
|
||||
PluginDisplay get display => DocumentPluginDisplay(view: _view);
|
||||
|
||||
@override
|
||||
bool get enable => true;
|
||||
|
||||
@override
|
||||
PluginType get pluginType => _pluginType;
|
||||
|
||||
@override
|
||||
String get pluginId => _view.id;
|
||||
}
|
||||
|
||||
class DocumentPluginDisplay extends PluginDisplay {
|
||||
final View _view;
|
||||
|
||||
DocumentPluginDisplay({required View view, Key? key}) : _view = view;
|
||||
|
||||
@override
|
||||
Widget buildWidget() => DocumentPage(view: _view, key: ValueKey(_view.id));
|
||||
|
||||
@override
|
||||
Widget get leftBarItem => DocumentLeftBarItem(view: _view);
|
||||
|
||||
@override
|
||||
Widget? get rightBarItem => DocumentShareButton(view: _view);
|
||||
|
||||
@override
|
||||
String get identifier => _view.id;
|
||||
|
||||
@override
|
||||
HomeStackType get type => _view.stackType();
|
||||
|
||||
@override
|
||||
Widget buildWidget() => DocumentPage(view: _view, key: ValueKey(_view.id));
|
||||
|
||||
@override
|
||||
List<NavigationItem> get navigationItems => _makeNavigationItems();
|
||||
|
||||
@override
|
||||
ValueNotifier<int> get isUpdated => _isUpdated;
|
||||
|
||||
List<NavigationItem> _makeNavigationItems() {
|
||||
return [
|
||||
this,
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener.close();
|
||||
}
|
||||
}
|
||||
|
||||
class DocumentLeftBarItem extends StatefulWidget {
|
||||
|
@ -10,17 +10,6 @@ import 'package:fluttertoast/fluttertoast.dart';
|
||||
|
||||
late FToast fToast;
|
||||
|
||||
// [[diagram: HomeStack's widget structure]]
|
||||
//
|
||||
// ┌──────────────────┐ ┌───────────────┐
|
||||
// ┌──│BlankStackContext │──▶│BlankStackPage │
|
||||
// ┌──────────┐ ┌───────────────────┐ ┌─────────────────┐ │ └──────────────────┘ └───────────────┘
|
||||
// │HomeStack │─▶│ HomeStackManager │──▶│HomeStackContext │◀─┤
|
||||
// └──────────┘ └───────────────────┘ └─────────────────┘ │ ┌─────────────────┐ ┌────────────┐
|
||||
// └──│ DocStackContext │───▶│DocStackPage│
|
||||
// └─────────────────┘ └────────────┘
|
||||
//
|
||||
//
|
||||
class HomeStack extends StatelessWidget {
|
||||
static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
|
||||
// final Size size;
|
||||
|
@ -1,4 +1,6 @@
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/startup/tasks/load_plugin.dart';
|
||||
import 'package:app_flowy/workspace/application/trash/trash_bloc.dart';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:app_flowy/workspace/presentation/stack_page/trash/widget/sizes.dart';
|
||||
@ -12,6 +14,7 @@ import 'package:flowy_infra_ui/style_widget/scrolling/styled_scrollview.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pbenum.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
@ -19,32 +22,57 @@ import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
|
||||
import 'widget/trash_header.dart';
|
||||
|
||||
class TrashStackContext extends HomeStackContext {
|
||||
final ValueNotifier<bool> _isUpdated = ValueNotifier<bool>(false);
|
||||
class TrashPluginBuilder implements PluginBuilder {
|
||||
@override
|
||||
Plugin build(dynamic data) {
|
||||
return TrashPlugin(pluginType: pluginType);
|
||||
}
|
||||
|
||||
@override
|
||||
String get identifier => "TrashStackContext";
|
||||
String get pluginName => "Trash";
|
||||
|
||||
@override
|
||||
PluginType get pluginType => DefaultPluginEnum.trash.type();
|
||||
|
||||
@override
|
||||
ViewDataType get dataType => ViewDataType.PlainText;
|
||||
}
|
||||
|
||||
class TrashPlugin implements Plugin {
|
||||
late PluginType _pluginType;
|
||||
|
||||
TrashPlugin({required PluginType pluginType}) {
|
||||
_pluginType = pluginType;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {}
|
||||
|
||||
@override
|
||||
PluginDisplay get display => TrashPluginDisplay();
|
||||
|
||||
@override
|
||||
bool get enable => true;
|
||||
|
||||
@override
|
||||
String get pluginId => "TrashStack";
|
||||
|
||||
@override
|
||||
PluginType get pluginType => _pluginType;
|
||||
}
|
||||
|
||||
class TrashPluginDisplay extends PluginDisplay {
|
||||
@override
|
||||
Widget get leftBarItem => FlowyText.medium(LocaleKeys.trash_text.tr(), fontSize: 12);
|
||||
|
||||
@override
|
||||
Widget? get rightBarItem => null;
|
||||
|
||||
@override
|
||||
HomeStackType get type => HomeStackType.trash;
|
||||
|
||||
@override
|
||||
Widget buildWidget() => const TrashStackPage(key: ValueKey('TrashStackPage'));
|
||||
|
||||
@override
|
||||
List<NavigationItem> get navigationItems => [this];
|
||||
|
||||
@override
|
||||
ValueNotifier<bool> get isUpdated => _isUpdated;
|
||||
|
||||
@override
|
||||
void dispose() {}
|
||||
}
|
||||
|
||||
class TrashStackPage extends StatefulWidget {
|
||||
|
@ -1,13 +1,10 @@
|
||||
import 'package:app_flowy/workspace/domain/image.dart';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
|
||||
import 'package:app_flowy/workspace/presentation/home/navigation.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/extension.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class HomeTopBar extends StatelessWidget {
|
||||
@ -28,7 +25,7 @@ class HomeTopBar extends StatelessWidget {
|
||||
value: Provider.of<HomeStackNotifier>(context, listen: false),
|
||||
child: Consumer(
|
||||
builder: (BuildContext context, HomeStackNotifier notifier, Widget? child) {
|
||||
return notifier.stackContext.rightBarItem ?? const SizedBox();
|
||||
return notifier.plugin.display.rightBarItem ?? const SizedBox();
|
||||
},
|
||||
),
|
||||
) // _renderMoreButton(),
|
||||
@ -41,27 +38,3 @@ class HomeTopBar extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class HomeTitle extends StatelessWidget {
|
||||
final String title;
|
||||
final ViewType type;
|
||||
|
||||
const HomeTitle({
|
||||
Key? key,
|
||||
required this.title,
|
||||
required this.type,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Flexible(
|
||||
child: Row(
|
||||
children: [
|
||||
Image(fit: BoxFit.scaleDown, width: 15, height: 15, image: assetImageForViewType(type)),
|
||||
const HSpace(6),
|
||||
FlowyText(title, fontSize: 16),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -70,9 +70,9 @@ class HomeMenu extends StatelessWidget {
|
||||
child: MultiBlocListener(
|
||||
listeners: [
|
||||
BlocListener<MenuBloc, MenuState>(
|
||||
listenWhen: (p, c) => p.stackContext != c.stackContext,
|
||||
listenWhen: (p, c) => p.plugin.pluginId != c.plugin.pluginId,
|
||||
listener: (context, state) {
|
||||
getIt<HomeStackManager>().setStack(state.stackContext);
|
||||
getIt<HomeStackManager>().setPlugin(state.plugin);
|
||||
},
|
||||
),
|
||||
BlocListener<MenuBloc, MenuState>(
|
||||
|
@ -1,3 +1,6 @@
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/startup/tasks/load_plugin.dart';
|
||||
import 'package:app_flowy/workspace/domain/view_ext.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
@ -5,13 +8,12 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
class AddButton extends StatelessWidget {
|
||||
final Function(ViewType) onSelected;
|
||||
final Function(PluginBuilder) onSelected;
|
||||
const AddButton({
|
||||
Key? key,
|
||||
required this.onSelected,
|
||||
@ -35,21 +37,29 @@ class AddButton extends StatelessWidget {
|
||||
}
|
||||
|
||||
class ActionList {
|
||||
final Function(ViewType) onSelected;
|
||||
final Function(PluginBuilder) onSelected;
|
||||
final BuildContext anchorContext;
|
||||
final String _identifier = 'DisclosureButtonActionList';
|
||||
|
||||
const ActionList({required this.anchorContext, required this.onSelected});
|
||||
|
||||
void show(BuildContext buildContext) {
|
||||
final items = ViewType.values.where((element) => element.enable()).map((ty) {
|
||||
final items = getIt<PluginSandbox>()
|
||||
.builders
|
||||
.where(
|
||||
(builder) => !isDefaultPlugin(builder.pluginType),
|
||||
)
|
||||
.map(
|
||||
(pluginBuilder) {
|
||||
return CreateItem(
|
||||
viewType: ty,
|
||||
onSelected: (viewType) {
|
||||
pluginBuilder: pluginBuilder,
|
||||
onSelected: (builder) {
|
||||
FlowyOverlay.of(buildContext).remove(_identifier);
|
||||
onSelected(viewType);
|
||||
});
|
||||
}).toList();
|
||||
onSelected(builder);
|
||||
},
|
||||
);
|
||||
},
|
||||
).toList();
|
||||
|
||||
ListOverlay.showWithAnchor(
|
||||
buildContext,
|
||||
@ -65,11 +75,11 @@ class ActionList {
|
||||
}
|
||||
|
||||
class CreateItem extends StatelessWidget {
|
||||
final ViewType viewType;
|
||||
final Function(ViewType) onSelected;
|
||||
final PluginBuilder pluginBuilder;
|
||||
final Function(PluginBuilder) onSelected;
|
||||
const CreateItem({
|
||||
Key? key,
|
||||
required this.viewType,
|
||||
required this.pluginBuilder,
|
||||
required this.onSelected,
|
||||
}) : super(key: key);
|
||||
|
||||
@ -82,9 +92,9 @@ class CreateItem extends StatelessWidget {
|
||||
config: config,
|
||||
builder: (context, onHover) {
|
||||
return GestureDetector(
|
||||
onTap: () => onSelected(viewType),
|
||||
onTap: () => onSelected(pluginBuilder),
|
||||
child: FlowyText.medium(
|
||||
viewType.displayName(),
|
||||
pluginBuilder.pluginName,
|
||||
color: theme.textColor,
|
||||
fontSize: 12,
|
||||
).padding(horizontal: 10, vertical: 6),
|
||||
|
@ -102,10 +102,12 @@ class MenuAppHeader extends StatelessWidget {
|
||||
return Tooltip(
|
||||
message: LocaleKeys.menuAppHeader_addPageTooltip.tr(),
|
||||
child: AddButton(
|
||||
onSelected: (viewType) {
|
||||
context
|
||||
.read<AppBloc>()
|
||||
.add(AppEvent.createView(LocaleKeys.menuAppHeader_defaultNewPageName.tr(), "", viewType));
|
||||
onSelected: (pluginBuilder) {
|
||||
context.read<AppBloc>().add(AppEvent.createView(
|
||||
LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
||||
"",
|
||||
pluginBuilder.dataType,
|
||||
));
|
||||
},
|
||||
).padding(right: MenuAppSizes.headerPadding),
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/view/view_bloc.dart';
|
||||
import 'package:app_flowy/workspace/domain/edit_action/view_edit.dart';
|
||||
import 'package:app_flowy/workspace/domain/view_ext.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:dartz/dartz.dart' as dartz;
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
@ -12,7 +13,6 @@ import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:app_flowy/workspace/domain/image.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/app/menu_app.dart';
|
||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
|
||||
@ -55,7 +55,7 @@ class ViewSectionItem extends StatelessWidget {
|
||||
|
||||
Widget _render(BuildContext context, bool onHover, ViewState state, Color iconColor) {
|
||||
List<Widget> children = [
|
||||
SizedBox(width: 16, height: 16, child: state.view.thumbnail(iconColor: iconColor)),
|
||||
SizedBox(width: 16, height: 16, child: state.view.renderThumbnail(iconColor: iconColor)),
|
||||
const HSpace(2),
|
||||
Expanded(child: FlowyText.regular(state.view.name, fontSize: 12, overflow: TextOverflow.clip)),
|
||||
];
|
||||
|
@ -106,7 +106,7 @@ class ViewSectionNotifier with ChangeNotifier {
|
||||
|
||||
if (view != null) {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((_) {
|
||||
getIt<HomeStackManager>().setStack(view.stackContext());
|
||||
getIt<HomeStackManager>().setPlugin(view.stackContext());
|
||||
});
|
||||
} else {
|
||||
// do nothing
|
||||
|
@ -1,7 +1,8 @@
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/startup/tasks/load_plugin.dart';
|
||||
import 'package:app_flowy/workspace/application/appearance.dart';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:app_flowy/workspace/presentation/stack_page/trash/trash_page.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/menu/menu.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
@ -22,7 +23,7 @@ class MenuTrash extends StatelessWidget {
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Provider.of<MenuSharedState>(context, listen: false).selectedView.value = null;
|
||||
getIt<HomeStackManager>().setStack(TrashStackContext());
|
||||
getIt<HomeStackManager>().setPlugin(makePlugin(pluginType: DefaultPluginEnum.trash.type()));
|
||||
},
|
||||
child: _render(context),
|
||||
),
|
||||
|
@ -20,11 +20,13 @@ class View extends $pb.GeneratedMessage {
|
||||
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongToId')
|
||||
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
|
||||
..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
|
||||
..e<ViewType>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewType', $pb.PbFieldType.OE, defaultOrMaker: ViewType.RichText, valueOf: ViewType.valueOf, enumValues: ViewType.values)
|
||||
..e<ViewDataType>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.RichText, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values)
|
||||
..aInt64(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'version')
|
||||
..aOM<RepeatedView>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongings', subBuilder: RepeatedView.create)
|
||||
..aInt64(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'modifiedTime')
|
||||
..aInt64(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'createTime')
|
||||
..aOS(10, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData')
|
||||
..aOS(11, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail')
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@ -34,11 +36,13 @@ class View extends $pb.GeneratedMessage {
|
||||
$core.String? belongToId,
|
||||
$core.String? name,
|
||||
$core.String? desc,
|
||||
ViewType? viewType,
|
||||
ViewDataType? dataType,
|
||||
$fixnum.Int64? version,
|
||||
RepeatedView? belongings,
|
||||
$fixnum.Int64? modifiedTime,
|
||||
$fixnum.Int64? createTime,
|
||||
$core.String? extData,
|
||||
$core.String? thumbnail,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (id != null) {
|
||||
@ -53,8 +57,8 @@ class View extends $pb.GeneratedMessage {
|
||||
if (desc != null) {
|
||||
_result.desc = desc;
|
||||
}
|
||||
if (viewType != null) {
|
||||
_result.viewType = viewType;
|
||||
if (dataType != null) {
|
||||
_result.dataType = dataType;
|
||||
}
|
||||
if (version != null) {
|
||||
_result.version = version;
|
||||
@ -68,6 +72,12 @@ class View extends $pb.GeneratedMessage {
|
||||
if (createTime != null) {
|
||||
_result.createTime = createTime;
|
||||
}
|
||||
if (extData != null) {
|
||||
_result.extData = extData;
|
||||
}
|
||||
if (thumbnail != null) {
|
||||
_result.thumbnail = thumbnail;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory View.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
@ -128,13 +138,13 @@ class View extends $pb.GeneratedMessage {
|
||||
void clearDesc() => clearField(4);
|
||||
|
||||
@$pb.TagNumber(5)
|
||||
ViewType get viewType => $_getN(4);
|
||||
ViewDataType get dataType => $_getN(4);
|
||||
@$pb.TagNumber(5)
|
||||
set viewType(ViewType v) { setField(5, v); }
|
||||
set dataType(ViewDataType v) { setField(5, v); }
|
||||
@$pb.TagNumber(5)
|
||||
$core.bool hasViewType() => $_has(4);
|
||||
$core.bool hasDataType() => $_has(4);
|
||||
@$pb.TagNumber(5)
|
||||
void clearViewType() => clearField(5);
|
||||
void clearDataType() => clearField(5);
|
||||
|
||||
@$pb.TagNumber(6)
|
||||
$fixnum.Int64 get version => $_getI64(5);
|
||||
@ -173,6 +183,24 @@ class View extends $pb.GeneratedMessage {
|
||||
$core.bool hasCreateTime() => $_has(8);
|
||||
@$pb.TagNumber(9)
|
||||
void clearCreateTime() => clearField(9);
|
||||
|
||||
@$pb.TagNumber(10)
|
||||
$core.String get extData => $_getSZ(9);
|
||||
@$pb.TagNumber(10)
|
||||
set extData($core.String v) { $_setString(9, v); }
|
||||
@$pb.TagNumber(10)
|
||||
$core.bool hasExtData() => $_has(9);
|
||||
@$pb.TagNumber(10)
|
||||
void clearExtData() => clearField(10);
|
||||
|
||||
@$pb.TagNumber(11)
|
||||
$core.String get thumbnail => $_getSZ(10);
|
||||
@$pb.TagNumber(11)
|
||||
set thumbnail($core.String v) { $_setString(10, v); }
|
||||
@$pb.TagNumber(11)
|
||||
$core.bool hasThumbnail() => $_has(10);
|
||||
@$pb.TagNumber(11)
|
||||
void clearThumbnail() => clearField(11);
|
||||
}
|
||||
|
||||
class RepeatedView extends $pb.GeneratedMessage {
|
||||
@ -232,8 +260,8 @@ class CreateViewPayload extends $pb.GeneratedMessage {
|
||||
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
|
||||
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
|
||||
..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail')
|
||||
..e<ViewType>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewType', $pb.PbFieldType.OE, defaultOrMaker: ViewType.RichText, valueOf: ViewType.valueOf, enumValues: ViewType.values)
|
||||
..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ext')
|
||||
..e<ViewDataType>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.RichText, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values)
|
||||
..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData')
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@ -243,8 +271,8 @@ class CreateViewPayload extends $pb.GeneratedMessage {
|
||||
$core.String? name,
|
||||
$core.String? desc,
|
||||
$core.String? thumbnail,
|
||||
ViewType? viewType,
|
||||
$core.String? ext,
|
||||
ViewDataType? dataType,
|
||||
$core.String? extData,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (belongToId != null) {
|
||||
@ -259,11 +287,11 @@ class CreateViewPayload extends $pb.GeneratedMessage {
|
||||
if (thumbnail != null) {
|
||||
_result.thumbnail = thumbnail;
|
||||
}
|
||||
if (viewType != null) {
|
||||
_result.viewType = viewType;
|
||||
if (dataType != null) {
|
||||
_result.dataType = dataType;
|
||||
}
|
||||
if (ext != null) {
|
||||
_result.ext = ext;
|
||||
if (extData != null) {
|
||||
_result.extData = extData;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
@ -328,22 +356,22 @@ class CreateViewPayload extends $pb.GeneratedMessage {
|
||||
void clearThumbnail() => clearField(4);
|
||||
|
||||
@$pb.TagNumber(5)
|
||||
ViewType get viewType => $_getN(4);
|
||||
ViewDataType get dataType => $_getN(4);
|
||||
@$pb.TagNumber(5)
|
||||
set viewType(ViewType v) { setField(5, v); }
|
||||
set dataType(ViewDataType v) { setField(5, v); }
|
||||
@$pb.TagNumber(5)
|
||||
$core.bool hasViewType() => $_has(4);
|
||||
$core.bool hasDataType() => $_has(4);
|
||||
@$pb.TagNumber(5)
|
||||
void clearViewType() => clearField(5);
|
||||
void clearDataType() => clearField(5);
|
||||
|
||||
@$pb.TagNumber(6)
|
||||
$core.String get ext => $_getSZ(5);
|
||||
$core.String get extData => $_getSZ(5);
|
||||
@$pb.TagNumber(6)
|
||||
set ext($core.String v) { $_setString(5, v); }
|
||||
set extData($core.String v) { $_setString(5, v); }
|
||||
@$pb.TagNumber(6)
|
||||
$core.bool hasExt() => $_has(5);
|
||||
$core.bool hasExtData() => $_has(5);
|
||||
@$pb.TagNumber(6)
|
||||
void clearExt() => clearField(6);
|
||||
void clearExtData() => clearField(6);
|
||||
}
|
||||
|
||||
class CreateViewParams extends $pb.GeneratedMessage {
|
||||
@ -352,9 +380,10 @@ class CreateViewParams extends $pb.GeneratedMessage {
|
||||
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
|
||||
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
|
||||
..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail')
|
||||
..e<ViewType>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewType', $pb.PbFieldType.OE, defaultOrMaker: ViewType.RichText, valueOf: ViewType.valueOf, enumValues: ViewType.values)
|
||||
..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ext')
|
||||
..e<ViewDataType>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.RichText, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values)
|
||||
..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData')
|
||||
..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId')
|
||||
..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data')
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@ -364,9 +393,10 @@ class CreateViewParams extends $pb.GeneratedMessage {
|
||||
$core.String? name,
|
||||
$core.String? desc,
|
||||
$core.String? thumbnail,
|
||||
ViewType? viewType,
|
||||
$core.String? ext,
|
||||
ViewDataType? dataType,
|
||||
$core.String? extData,
|
||||
$core.String? viewId,
|
||||
$core.String? data,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (belongToId != null) {
|
||||
@ -381,15 +411,18 @@ class CreateViewParams extends $pb.GeneratedMessage {
|
||||
if (thumbnail != null) {
|
||||
_result.thumbnail = thumbnail;
|
||||
}
|
||||
if (viewType != null) {
|
||||
_result.viewType = viewType;
|
||||
if (dataType != null) {
|
||||
_result.dataType = dataType;
|
||||
}
|
||||
if (ext != null) {
|
||||
_result.ext = ext;
|
||||
if (extData != null) {
|
||||
_result.extData = extData;
|
||||
}
|
||||
if (viewId != null) {
|
||||
_result.viewId = viewId;
|
||||
}
|
||||
if (data != null) {
|
||||
_result.data = data;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory CreateViewParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
@ -450,22 +483,22 @@ class CreateViewParams extends $pb.GeneratedMessage {
|
||||
void clearThumbnail() => clearField(4);
|
||||
|
||||
@$pb.TagNumber(5)
|
||||
ViewType get viewType => $_getN(4);
|
||||
ViewDataType get dataType => $_getN(4);
|
||||
@$pb.TagNumber(5)
|
||||
set viewType(ViewType v) { setField(5, v); }
|
||||
set dataType(ViewDataType v) { setField(5, v); }
|
||||
@$pb.TagNumber(5)
|
||||
$core.bool hasViewType() => $_has(4);
|
||||
$core.bool hasDataType() => $_has(4);
|
||||
@$pb.TagNumber(5)
|
||||
void clearViewType() => clearField(5);
|
||||
void clearDataType() => clearField(5);
|
||||
|
||||
@$pb.TagNumber(6)
|
||||
$core.String get ext => $_getSZ(5);
|
||||
$core.String get extData => $_getSZ(5);
|
||||
@$pb.TagNumber(6)
|
||||
set ext($core.String v) { $_setString(5, v); }
|
||||
set extData($core.String v) { $_setString(5, v); }
|
||||
@$pb.TagNumber(6)
|
||||
$core.bool hasExt() => $_has(5);
|
||||
$core.bool hasExtData() => $_has(5);
|
||||
@$pb.TagNumber(6)
|
||||
void clearExt() => clearField(6);
|
||||
void clearExtData() => clearField(6);
|
||||
|
||||
@$pb.TagNumber(7)
|
||||
$core.String get viewId => $_getSZ(6);
|
||||
@ -475,6 +508,15 @@ class CreateViewParams extends $pb.GeneratedMessage {
|
||||
$core.bool hasViewId() => $_has(6);
|
||||
@$pb.TagNumber(7)
|
||||
void clearViewId() => clearField(7);
|
||||
|
||||
@$pb.TagNumber(8)
|
||||
$core.String get data => $_getSZ(7);
|
||||
@$pb.TagNumber(8)
|
||||
set data($core.String v) { $_setString(7, v); }
|
||||
@$pb.TagNumber(8)
|
||||
$core.bool hasData() => $_has(7);
|
||||
@$pb.TagNumber(8)
|
||||
void clearData() => clearField(8);
|
||||
}
|
||||
|
||||
class ViewId extends $pb.GeneratedMessage {
|
||||
|
@ -9,18 +9,18 @@
|
||||
import 'dart:core' as $core;
|
||||
import 'package:protobuf/protobuf.dart' as $pb;
|
||||
|
||||
class ViewType extends $pb.ProtobufEnum {
|
||||
static const ViewType RichText = ViewType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RichText');
|
||||
static const ViewType PlainText = ViewType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PlainText');
|
||||
class ViewDataType extends $pb.ProtobufEnum {
|
||||
static const ViewDataType RichText = ViewDataType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RichText');
|
||||
static const ViewDataType PlainText = ViewDataType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PlainText');
|
||||
|
||||
static const $core.List<ViewType> values = <ViewType> [
|
||||
static const $core.List<ViewDataType> values = <ViewDataType> [
|
||||
RichText,
|
||||
PlainText,
|
||||
];
|
||||
|
||||
static final $core.Map<$core.int, ViewType> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||
static ViewType? valueOf($core.int value) => _byValue[value];
|
||||
static final $core.Map<$core.int, ViewDataType> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||
static ViewDataType? valueOf($core.int value) => _byValue[value];
|
||||
|
||||
const ViewType._($core.int v, $core.String n) : super(v, n);
|
||||
const ViewDataType._($core.int v, $core.String n) : super(v, n);
|
||||
}
|
||||
|
||||
|
@ -8,17 +8,17 @@
|
||||
import 'dart:core' as $core;
|
||||
import 'dart:convert' as $convert;
|
||||
import 'dart:typed_data' as $typed_data;
|
||||
@$core.Deprecated('Use viewTypeDescriptor instead')
|
||||
const ViewType$json = const {
|
||||
'1': 'ViewType',
|
||||
@$core.Deprecated('Use viewDataTypeDescriptor instead')
|
||||
const ViewDataType$json = const {
|
||||
'1': 'ViewDataType',
|
||||
'2': const [
|
||||
const {'1': 'RichText', '2': 0},
|
||||
const {'1': 'PlainText', '2': 1},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `ViewType`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||
final $typed_data.Uint8List viewTypeDescriptor = $convert.base64Decode('CghWaWV3VHlwZRIMCghSaWNoVGV4dBAAEg0KCVBsYWluVGV4dBAB');
|
||||
/// Descriptor for `ViewDataType`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||
final $typed_data.Uint8List viewDataTypeDescriptor = $convert.base64Decode('CgxWaWV3RGF0YVR5cGUSDAoIUmljaFRleHQQABINCglQbGFpblRleHQQAQ==');
|
||||
@$core.Deprecated('Use viewDescriptor instead')
|
||||
const View$json = const {
|
||||
'1': 'View',
|
||||
@ -27,16 +27,18 @@ const View$json = const {
|
||||
const {'1': 'belong_to_id', '3': 2, '4': 1, '5': 9, '10': 'belongToId'},
|
||||
const {'1': 'name', '3': 3, '4': 1, '5': 9, '10': 'name'},
|
||||
const {'1': 'desc', '3': 4, '4': 1, '5': 9, '10': 'desc'},
|
||||
const {'1': 'view_type', '3': 5, '4': 1, '5': 14, '6': '.ViewType', '10': 'viewType'},
|
||||
const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'},
|
||||
const {'1': 'version', '3': 6, '4': 1, '5': 3, '10': 'version'},
|
||||
const {'1': 'belongings', '3': 7, '4': 1, '5': 11, '6': '.RepeatedView', '10': 'belongings'},
|
||||
const {'1': 'modified_time', '3': 8, '4': 1, '5': 3, '10': 'modifiedTime'},
|
||||
const {'1': 'create_time', '3': 9, '4': 1, '5': 3, '10': 'createTime'},
|
||||
const {'1': 'ext_data', '3': 10, '4': 1, '5': 9, '10': 'extData'},
|
||||
const {'1': 'thumbnail', '3': 11, '4': 1, '5': 9, '10': 'thumbnail'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `View`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List viewDescriptor = $convert.base64Decode('CgRWaWV3Eg4KAmlkGAEgASgJUgJpZBIgCgxiZWxvbmdfdG9faWQYAiABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgDIAEoCVIEbmFtZRISCgRkZXNjGAQgASgJUgRkZXNjEiYKCXZpZXdfdHlwZRgFIAEoDjIJLlZpZXdUeXBlUgh2aWV3VHlwZRIYCgd2ZXJzaW9uGAYgASgDUgd2ZXJzaW9uEi0KCmJlbG9uZ2luZ3MYByABKAsyDS5SZXBlYXRlZFZpZXdSCmJlbG9uZ2luZ3MSIwoNbW9kaWZpZWRfdGltZRgIIAEoA1IMbW9kaWZpZWRUaW1lEh8KC2NyZWF0ZV90aW1lGAkgASgDUgpjcmVhdGVUaW1l');
|
||||
final $typed_data.Uint8List viewDescriptor = $convert.base64Decode('CgRWaWV3Eg4KAmlkGAEgASgJUgJpZBIgCgxiZWxvbmdfdG9faWQYAiABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgDIAEoCVIEbmFtZRISCgRkZXNjGAQgASgJUgRkZXNjEioKCWRhdGFfdHlwZRgFIAEoDjINLlZpZXdEYXRhVHlwZVIIZGF0YVR5cGUSGAoHdmVyc2lvbhgGIAEoA1IHdmVyc2lvbhItCgpiZWxvbmdpbmdzGAcgASgLMg0uUmVwZWF0ZWRWaWV3UgpiZWxvbmdpbmdzEiMKDW1vZGlmaWVkX3RpbWUYCCABKANSDG1vZGlmaWVkVGltZRIfCgtjcmVhdGVfdGltZRgJIAEoA1IKY3JlYXRlVGltZRIZCghleHRfZGF0YRgKIAEoCVIHZXh0RGF0YRIcCgl0aHVtYm5haWwYCyABKAlSCXRodW1ibmFpbA==');
|
||||
@$core.Deprecated('Use repeatedViewDescriptor instead')
|
||||
const RepeatedView$json = const {
|
||||
'1': 'RepeatedView',
|
||||
@ -55,8 +57,8 @@ const CreateViewPayload$json = const {
|
||||
const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
|
||||
const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'},
|
||||
const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'thumbnail'},
|
||||
const {'1': 'view_type', '3': 5, '4': 1, '5': 14, '6': '.ViewType', '10': 'viewType'},
|
||||
const {'1': 'ext', '3': 6, '4': 1, '5': 9, '10': 'ext'},
|
||||
const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'},
|
||||
const {'1': 'ext_data', '3': 6, '4': 1, '5': 9, '10': 'extData'},
|
||||
],
|
||||
'8': const [
|
||||
const {'1': 'one_of_thumbnail'},
|
||||
@ -64,7 +66,7 @@ const CreateViewPayload$json = const {
|
||||
};
|
||||
|
||||
/// Descriptor for `CreateViewPayload`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List createViewPayloadDescriptor = $convert.base64Decode('ChFDcmVhdGVWaWV3UGF5bG9hZBIgCgxiZWxvbmdfdG9faWQYASABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEh4KCXRodW1ibmFpbBgEIAEoCUgAUgl0aHVtYm5haWwSJgoJdmlld190eXBlGAUgASgOMgkuVmlld1R5cGVSCHZpZXdUeXBlEhAKA2V4dBgGIAEoCVIDZXh0QhIKEG9uZV9vZl90aHVtYm5haWw=');
|
||||
final $typed_data.Uint8List createViewPayloadDescriptor = $convert.base64Decode('ChFDcmVhdGVWaWV3UGF5bG9hZBIgCgxiZWxvbmdfdG9faWQYASABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEh4KCXRodW1ibmFpbBgEIAEoCUgAUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIZCghleHRfZGF0YRgGIAEoCVIHZXh0RGF0YUISChBvbmVfb2ZfdGh1bWJuYWls');
|
||||
@$core.Deprecated('Use createViewParamsDescriptor instead')
|
||||
const CreateViewParams$json = const {
|
||||
'1': 'CreateViewParams',
|
||||
@ -73,14 +75,15 @@ const CreateViewParams$json = const {
|
||||
const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
|
||||
const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'},
|
||||
const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '10': 'thumbnail'},
|
||||
const {'1': 'view_type', '3': 5, '4': 1, '5': 14, '6': '.ViewType', '10': 'viewType'},
|
||||
const {'1': 'ext', '3': 6, '4': 1, '5': 9, '10': 'ext'},
|
||||
const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'},
|
||||
const {'1': 'ext_data', '3': 6, '4': 1, '5': 9, '10': 'extData'},
|
||||
const {'1': 'view_id', '3': 7, '4': 1, '5': 9, '10': 'viewId'},
|
||||
const {'1': 'data', '3': 8, '4': 1, '5': 9, '10': 'data'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `CreateViewParams`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List createViewParamsDescriptor = $convert.base64Decode('ChBDcmVhdGVWaWV3UGFyYW1zEiAKDGJlbG9uZ190b19pZBgBIAEoCVIKYmVsb25nVG9JZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSHAoJdGh1bWJuYWlsGAQgASgJUgl0aHVtYm5haWwSJgoJdmlld190eXBlGAUgASgOMgkuVmlld1R5cGVSCHZpZXdUeXBlEhAKA2V4dBgGIAEoCVIDZXh0EhcKB3ZpZXdfaWQYByABKAlSBnZpZXdJZA==');
|
||||
final $typed_data.Uint8List createViewParamsDescriptor = $convert.base64Decode('ChBDcmVhdGVWaWV3UGFyYW1zEiAKDGJlbG9uZ190b19pZBgBIAEoCVIKYmVsb25nVG9JZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSHAoJdGh1bWJuYWlsGAQgASgJUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIZCghleHRfZGF0YRgGIAEoCVIHZXh0RGF0YRIXCgd2aWV3X2lkGAcgASgJUgZ2aWV3SWQSEgoEZGF0YRgIIAEoCVIEZGF0YQ==');
|
||||
@$core.Deprecated('Use viewIdDescriptor instead')
|
||||
const ViewId$json = const {
|
||||
'1': 'ViewId',
|
||||
|
@ -8,7 +8,7 @@ use flowy_collaboration::{
|
||||
errors::CollaborateError,
|
||||
};
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_sync::{DeltaMD5, RevisionCompact, RevisionManager, TransformDeltas};
|
||||
use flowy_sync::{DeltaMD5, RevisionCompact, RevisionManager, RichTextTransformDeltas, TransformDeltas};
|
||||
use futures::stream::StreamExt;
|
||||
use lib_ot::{
|
||||
core::{Interval, OperationTransformable},
|
||||
@ -102,7 +102,7 @@ impl EditBlockQueue {
|
||||
server_prime = Some(s_prime);
|
||||
}
|
||||
drop(read_guard);
|
||||
Ok::<TransformDeltas<RichTextAttributes>, CollaborateError>(TransformDeltas {
|
||||
Ok::<RichTextTransformDeltas, CollaborateError>(TransformDeltas {
|
||||
client_prime,
|
||||
server_prime,
|
||||
})
|
||||
@ -232,7 +232,7 @@ pub(crate) enum EditorCommand {
|
||||
},
|
||||
TransformDelta {
|
||||
delta: RichTextDelta,
|
||||
ret: Ret<TransformDeltas<RichTextAttributes>>,
|
||||
ret: Ret<RichTextTransformDeltas>,
|
||||
},
|
||||
Insert {
|
||||
index: usize,
|
||||
|
@ -10,7 +10,8 @@ use flowy_collaboration::{
|
||||
use flowy_error::{internal_error, FlowyError};
|
||||
use flowy_sync::*;
|
||||
use lib_infra::future::{BoxResultFuture, FutureResult};
|
||||
use lib_ot::{core::Delta, rich_text::RichTextAttributes};
|
||||
use lib_ot::rich_text::RichTextAttributes;
|
||||
use lib_ot::rich_text::RichTextDelta;
|
||||
use lib_ws::WSConnectState;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use tokio::sync::{
|
||||
@ -31,12 +32,8 @@ pub(crate) async fn make_block_ws_manager(
|
||||
) -> 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 conflict_controller = ConflictController::<RichTextAttributes>::new(
|
||||
&user_id,
|
||||
resolver,
|
||||
Arc::new(ws_data_provider.clone()),
|
||||
rev_manager,
|
||||
);
|
||||
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 ping_duration = Duration::from_millis(DOCUMENT_SYNC_INTERVAL_IN_MILLIS);
|
||||
@ -66,11 +63,11 @@ fn listen_document_ws_state(_user_id: &str, _doc_id: &str, mut subscriber: broad
|
||||
}
|
||||
|
||||
pub(crate) struct BlockRevisionWSDataStream {
|
||||
conflict_controller: Arc<ConflictController<RichTextAttributes>>,
|
||||
conflict_controller: Arc<RichTextConflictController>,
|
||||
}
|
||||
|
||||
impl BlockRevisionWSDataStream {
|
||||
pub fn new(conflict_controller: ConflictController<RichTextAttributes>) -> Self {
|
||||
pub fn new(conflict_controller: RichTextConflictController) -> Self {
|
||||
Self {
|
||||
conflict_controller: Arc::new(conflict_controller),
|
||||
}
|
||||
@ -112,7 +109,7 @@ struct BlockConflictResolver {
|
||||
}
|
||||
|
||||
impl ConflictResolver<RichTextAttributes> for BlockConflictResolver {
|
||||
fn compose_delta(&self, delta: Delta<RichTextAttributes>) -> BoxResultFuture<DeltaMD5, FlowyError> {
|
||||
fn compose_delta(&self, delta: RichTextDelta) -> BoxResultFuture<DeltaMD5, FlowyError> {
|
||||
let tx = self.edit_cmd_tx.clone();
|
||||
Box::pin(async move {
|
||||
let (ret, rx) = oneshot::channel();
|
||||
@ -131,11 +128,11 @@ impl ConflictResolver<RichTextAttributes> for BlockConflictResolver {
|
||||
|
||||
fn transform_delta(
|
||||
&self,
|
||||
delta: Delta<RichTextAttributes>,
|
||||
) -> BoxResultFuture<flowy_sync::TransformDeltas<RichTextAttributes>, FlowyError> {
|
||||
delta: RichTextDelta,
|
||||
) -> BoxResultFuture<flowy_sync::RichTextTransformDeltas, FlowyError> {
|
||||
let tx = self.edit_cmd_tx.clone();
|
||||
Box::pin(async move {
|
||||
let (ret, rx) = oneshot::channel::<CollaborateResult<TransformDeltas<RichTextAttributes>>>();
|
||||
let (ret, rx) = oneshot::channel::<CollaborateResult<RichTextTransformDeltas>>();
|
||||
tx.send(EditorCommand::TransformDelta { delta, ret })
|
||||
.await
|
||||
.map_err(internal_error)?;
|
||||
@ -146,7 +143,7 @@ impl ConflictResolver<RichTextAttributes> for BlockConflictResolver {
|
||||
})
|
||||
}
|
||||
|
||||
fn reset_delta(&self, delta: Delta<RichTextAttributes>) -> BoxResultFuture<DeltaMD5, FlowyError> {
|
||||
fn reset_delta(&self, delta: RichTextDelta) -> BoxResultFuture<DeltaMD5, FlowyError> {
|
||||
let tx = self.edit_cmd_tx.clone();
|
||||
Box::pin(async move {
|
||||
let (ret, rx) = oneshot::channel();
|
||||
|
@ -12,7 +12,7 @@ use flowy_sync::{
|
||||
RevisionWebSocket, RevisionWebSocketManager,
|
||||
};
|
||||
use lib_infra::future::FutureResult;
|
||||
use lib_ot::core::PlainAttributes;
|
||||
use lib_ot::core::PlainTextAttributes;
|
||||
use lib_sqlite::ConnectionPool;
|
||||
use parking_lot::RwLock;
|
||||
use std::sync::Arc;
|
||||
@ -144,7 +144,7 @@ impl RevisionCompact for FolderRevisionCompact {
|
||||
|
||||
let (base_rev_id, rev_id) = first_revision.pair_rev_id();
|
||||
let md5 = last_revision.md5.clone();
|
||||
let delta = make_delta_from_revisions::<PlainAttributes>(revisions)?;
|
||||
let delta = make_delta_from_revisions::<PlainTextAttributes>(revisions)?;
|
||||
let delta_data = delta.to_bytes();
|
||||
Ok(Revision::new(object_id, base_rev_id, rev_id, delta_data, user_id, md5))
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
entities::{
|
||||
trash::{Trash, TrashType},
|
||||
view::{RepeatedView, UpdateViewParams, View, ViewType},
|
||||
view::{RepeatedView, UpdateViewParams, View, ViewDataType},
|
||||
},
|
||||
errors::FlowyError,
|
||||
services::persistence::version_1::app_sql::AppTable,
|
||||
@ -119,16 +119,16 @@ pub(crate) struct ViewTable {
|
||||
pub modified_time: i64,
|
||||
pub create_time: i64,
|
||||
pub thumbnail: String,
|
||||
pub view_type: ViewTableType,
|
||||
pub view_type: SqlViewDataType,
|
||||
pub version: i64,
|
||||
pub is_trash: bool,
|
||||
}
|
||||
|
||||
impl ViewTable {
|
||||
pub fn new(view: View) -> Self {
|
||||
let view_type = match view.view_type {
|
||||
ViewType::RichText => ViewTableType::RichText,
|
||||
ViewType::PlainText => ViewTableType::Text,
|
||||
let data_type = match view.data_type {
|
||||
ViewDataType::RichText => SqlViewDataType::RichText,
|
||||
ViewDataType::PlainText => SqlViewDataType::PlainText,
|
||||
};
|
||||
|
||||
ViewTable {
|
||||
@ -138,9 +138,8 @@ impl ViewTable {
|
||||
desc: view.desc,
|
||||
modified_time: view.modified_time,
|
||||
create_time: view.create_time,
|
||||
// TODO: thumbnail
|
||||
thumbnail: "".to_owned(),
|
||||
view_type,
|
||||
thumbnail: view.thumbnail,
|
||||
view_type: data_type,
|
||||
version: 0,
|
||||
is_trash: false,
|
||||
}
|
||||
@ -149,9 +148,9 @@ impl ViewTable {
|
||||
|
||||
impl std::convert::From<ViewTable> for View {
|
||||
fn from(table: ViewTable) -> Self {
|
||||
let view_type = match table.view_type {
|
||||
ViewTableType::RichText => ViewType::RichText,
|
||||
ViewTableType::Text => ViewType::PlainText,
|
||||
let data_type = match table.view_type {
|
||||
SqlViewDataType::RichText => ViewDataType::RichText,
|
||||
SqlViewDataType::PlainText => ViewDataType::PlainText,
|
||||
};
|
||||
|
||||
View {
|
||||
@ -159,11 +158,13 @@ impl std::convert::From<ViewTable> for View {
|
||||
belong_to_id: table.belong_to_id,
|
||||
name: table.name,
|
||||
desc: table.desc,
|
||||
view_type,
|
||||
data_type,
|
||||
belongings: RepeatedView::default(),
|
||||
modified_time: table.modified_time,
|
||||
version: table.version,
|
||||
create_time: table.create_time,
|
||||
ext_data: "".to_string(),
|
||||
thumbnail: table.thumbnail,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -215,34 +216,34 @@ impl ViewChangeset {
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, FromSqlRow, AsExpression)]
|
||||
#[repr(i32)]
|
||||
#[sql_type = "Integer"]
|
||||
pub enum ViewTableType {
|
||||
pub enum SqlViewDataType {
|
||||
RichText = 0,
|
||||
Text = 1,
|
||||
PlainText = 1,
|
||||
}
|
||||
|
||||
impl std::default::Default for ViewTableType {
|
||||
impl std::default::Default for SqlViewDataType {
|
||||
fn default() -> Self {
|
||||
ViewTableType::RichText
|
||||
SqlViewDataType::RichText
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<i32> for ViewTableType {
|
||||
impl std::convert::From<i32> for SqlViewDataType {
|
||||
fn from(value: i32) -> Self {
|
||||
match value {
|
||||
0 => ViewTableType::RichText,
|
||||
1 => ViewTableType::Text,
|
||||
0 => SqlViewDataType::RichText,
|
||||
1 => SqlViewDataType::PlainText,
|
||||
o => {
|
||||
log::error!("Unsupported view type {}, fallback to ViewType::Docs", o);
|
||||
ViewTableType::Text
|
||||
SqlViewDataType::PlainText
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ViewTableType {
|
||||
impl SqlViewDataType {
|
||||
pub fn value(&self) -> i32 {
|
||||
*self as i32
|
||||
}
|
||||
}
|
||||
|
||||
impl_sql_integer_expression!(ViewTableType);
|
||||
impl_sql_integer_expression!(SqlViewDataType);
|
||||
|
@ -24,7 +24,7 @@ use crate::{
|
||||
use flowy_database::kv::KV;
|
||||
use flowy_document::BlockManager;
|
||||
use flowy_folder_data_model::entities::share::{ExportData, ExportParams};
|
||||
use flowy_folder_data_model::entities::view::ViewType;
|
||||
|
||||
use lib_infra::uuid_string;
|
||||
|
||||
const LATEST_VIEW_ID: &str = "latest_view_id";
|
||||
@ -62,10 +62,10 @@ impl ViewController {
|
||||
|
||||
#[tracing::instrument(level = "trace", skip(self, params), fields(name = %params.name), err)]
|
||||
pub(crate) async fn create_view_from_params(&self, params: CreateViewParams) -> Result<View, FlowyError> {
|
||||
let view_data = if params.ext.is_empty() {
|
||||
let view_data = if params.data.is_empty() {
|
||||
initial_delta_string()
|
||||
} else {
|
||||
params.ext.clone()
|
||||
params.data.clone()
|
||||
};
|
||||
|
||||
let delta_data = Bytes::from(view_data);
|
||||
@ -78,12 +78,11 @@ impl ViewController {
|
||||
Ok(view)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self, view_id, view_type, repeated_revision), err)]
|
||||
#[tracing::instrument(level = "debug", skip(self, view_id, repeated_revision), err)]
|
||||
pub(crate) async fn create_view(
|
||||
&self,
|
||||
view_id: &str,
|
||||
repeated_revision: RepeatedRevision,
|
||||
view_type: ViewType,
|
||||
) -> Result<(), FlowyError> {
|
||||
if repeated_revision.is_empty() {
|
||||
return Err(FlowyError::internal().context("The content of the view should not be empty"));
|
||||
@ -173,11 +172,12 @@ impl ViewController {
|
||||
let duplicate_params = CreateViewParams {
|
||||
belong_to_id: view.belong_to_id.clone(),
|
||||
name: format!("{} (copy)", &view.name),
|
||||
desc: view.desc.clone(),
|
||||
thumbnail: "".to_owned(),
|
||||
view_type: view.view_type.clone(),
|
||||
ext: document_json,
|
||||
desc: view.desc,
|
||||
thumbnail: view.thumbnail,
|
||||
data_type: view.data_type,
|
||||
data: document_json,
|
||||
view_id: uuid_string(),
|
||||
ext_data: view.ext_data,
|
||||
};
|
||||
|
||||
let _ = self.create_view_from_params(duplicate_params).await?;
|
||||
|
@ -10,7 +10,7 @@ use flowy_collaboration::{
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_sync::*;
|
||||
use lib_infra::future::{BoxResultFuture, FutureResult};
|
||||
use lib_ot::core::{Delta, OperationTransformable, PlainAttributes, PlainDelta};
|
||||
use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta};
|
||||
use parking_lot::RwLock;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
@ -23,8 +23,12 @@ pub(crate) async fn make_folder_ws_manager(
|
||||
) -> Arc<RevisionWebSocketManager> {
|
||||
let ws_data_provider = Arc::new(WSDataProvider::new(folder_id, Arc::new(rev_manager.clone())));
|
||||
let resolver = Arc::new(FolderConflictResolver { folder_pad });
|
||||
let conflict_controller =
|
||||
ConflictController::<PlainAttributes>::new(user_id, resolver, Arc::new(ws_data_provider.clone()), rev_manager);
|
||||
let conflict_controller = ConflictController::<PlainTextAttributes>::new(
|
||||
user_id,
|
||||
resolver,
|
||||
Arc::new(ws_data_provider.clone()),
|
||||
rev_manager,
|
||||
);
|
||||
let ws_data_stream = Arc::new(FolderRevisionWSDataStream::new(conflict_controller));
|
||||
let ws_data_sink = Arc::new(FolderWSDataSink(ws_data_provider));
|
||||
let ping_duration = Duration::from_millis(FOLDER_SYNC_INTERVAL_IN_MILLIS);
|
||||
@ -50,8 +54,8 @@ struct FolderConflictResolver {
|
||||
folder_pad: Arc<RwLock<FolderPad>>,
|
||||
}
|
||||
|
||||
impl ConflictResolver<PlainAttributes> for FolderConflictResolver {
|
||||
fn compose_delta(&self, delta: Delta<PlainAttributes>) -> BoxResultFuture<DeltaMD5, FlowyError> {
|
||||
impl ConflictResolver<PlainTextAttributes> for FolderConflictResolver {
|
||||
fn compose_delta(&self, delta: PlainTextDelta) -> BoxResultFuture<DeltaMD5, FlowyError> {
|
||||
let folder_pad = self.folder_pad.clone();
|
||||
Box::pin(async move {
|
||||
let md5 = folder_pad.write().compose_remote_delta(delta)?;
|
||||
@ -61,13 +65,13 @@ impl ConflictResolver<PlainAttributes> for FolderConflictResolver {
|
||||
|
||||
fn transform_delta(
|
||||
&self,
|
||||
delta: Delta<PlainAttributes>,
|
||||
) -> BoxResultFuture<TransformDeltas<PlainAttributes>, FlowyError> {
|
||||
delta: PlainTextDelta,
|
||||
) -> BoxResultFuture<TransformDeltas<PlainTextAttributes>, FlowyError> {
|
||||
let folder_pad = self.folder_pad.clone();
|
||||
Box::pin(async move {
|
||||
let read_guard = folder_pad.read();
|
||||
let mut server_prime: Option<PlainDelta> = None;
|
||||
let client_prime: PlainDelta;
|
||||
let mut server_prime: Option<PlainTextDelta> = None;
|
||||
let client_prime: PlainTextDelta;
|
||||
if read_guard.is_empty() {
|
||||
// Do nothing
|
||||
client_prime = delta;
|
||||
@ -84,7 +88,7 @@ impl ConflictResolver<PlainAttributes> for FolderConflictResolver {
|
||||
})
|
||||
}
|
||||
|
||||
fn reset_delta(&self, delta: Delta<PlainAttributes>) -> BoxResultFuture<DeltaMD5, FlowyError> {
|
||||
fn reset_delta(&self, delta: PlainTextDelta) -> BoxResultFuture<DeltaMD5, FlowyError> {
|
||||
let folder_pad = self.folder_pad.clone();
|
||||
Box::pin(async move {
|
||||
let md5 = folder_pad.write().reset_folder(delta)?;
|
||||
@ -94,11 +98,11 @@ impl ConflictResolver<PlainAttributes> for FolderConflictResolver {
|
||||
}
|
||||
|
||||
struct FolderRevisionWSDataStream {
|
||||
conflict_controller: Arc<ConflictController<PlainAttributes>>,
|
||||
conflict_controller: Arc<PlainTextConflictController>,
|
||||
}
|
||||
|
||||
impl FolderRevisionWSDataStream {
|
||||
pub fn new(conflict_controller: ConflictController<PlainAttributes>) -> Self {
|
||||
pub fn new(conflict_controller: PlainTextConflictController) -> Self {
|
||||
Self {
|
||||
conflict_controller: Arc::new(conflict_controller),
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use flowy_folder_data_model::entities::workspace::WorkspaceId;
|
||||
use flowy_folder_data_model::entities::{
|
||||
app::{App, AppId, CreateAppPayload, UpdateAppPayload},
|
||||
trash::{RepeatedTrash, TrashId, TrashType},
|
||||
view::{CreateViewPayload, UpdateViewPayload, View, ViewType},
|
||||
view::{CreateViewPayload, UpdateViewPayload, View, ViewDataType},
|
||||
workspace::{CreateWorkspacePayload, RepeatedWorkspace, Workspace},
|
||||
};
|
||||
use flowy_test::{event_builder::*, FlowySDKTest};
|
||||
@ -109,13 +109,14 @@ pub async fn delete_app(sdk: &FlowySDKTest, app_id: &str) {
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn create_view(sdk: &FlowySDKTest, app_id: &str, name: &str, desc: &str, view_type: ViewType) -> View {
|
||||
pub async fn create_view(sdk: &FlowySDKTest, app_id: &str, name: &str, desc: &str, view_type: ViewDataType) -> View {
|
||||
let request = CreateViewPayload {
|
||||
belong_to_id: app_id.to_string(),
|
||||
name: name.to_string(),
|
||||
desc: desc.to_string(),
|
||||
thumbnail: None,
|
||||
view_type,
|
||||
data_type: view_type,
|
||||
ext_data: "".to_string(),
|
||||
};
|
||||
let view = FolderEventBuilder::new(sdk.clone())
|
||||
.event(CreateView)
|
||||
|
@ -4,7 +4,7 @@ use flowy_folder::{errors::ErrorCode, services::folder_editor::ClientFolderEdito
|
||||
use flowy_folder_data_model::entities::{
|
||||
app::{App, RepeatedApp},
|
||||
trash::Trash,
|
||||
view::{RepeatedView, View, ViewType},
|
||||
view::{RepeatedView, View, ViewDataType},
|
||||
workspace::Workspace,
|
||||
};
|
||||
use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS;
|
||||
@ -68,7 +68,7 @@ impl FolderTest {
|
||||
let _ = sdk.init_user().await;
|
||||
let mut workspace = create_workspace(&sdk, "FolderWorkspace", "Folder test workspace").await;
|
||||
let mut app = create_app(&sdk, &workspace.id, "Folder App", "Folder test app").await;
|
||||
let view = create_view(&sdk, &app.id, "Folder View", "Folder test view", ViewType::RichText).await;
|
||||
let view = create_view(&sdk, &app.id, "Folder View", "Folder test view", ViewDataType::RichText).await;
|
||||
app.belongings = RepeatedView {
|
||||
items: vec![view.clone()],
|
||||
};
|
||||
@ -146,7 +146,7 @@ impl FolderTest {
|
||||
}
|
||||
|
||||
FolderScript::CreateView { name, desc } => {
|
||||
let view = create_view(sdk, &self.app.id, &name, &desc, ViewType::RichText).await;
|
||||
let view = create_view(sdk, &self.app.id, &name, &desc, ViewDataType::RichText).await;
|
||||
self.view = view;
|
||||
}
|
||||
FolderScript::AssertView(view) => {
|
||||
|
@ -300,11 +300,13 @@ impl FolderCouldServiceV1 for LocalServer {
|
||||
belong_to_id: params.belong_to_id,
|
||||
name: params.name,
|
||||
desc: params.desc,
|
||||
view_type: params.view_type,
|
||||
data_type: params.data_type,
|
||||
version: 0,
|
||||
belongings: RepeatedView::default(),
|
||||
modified_time: time,
|
||||
create_time: time,
|
||||
ext_data: params.ext_data,
|
||||
thumbnail: params.thumbnail,
|
||||
};
|
||||
FutureResult::new(async { Ok(view) })
|
||||
}
|
||||
|
@ -9,7 +9,8 @@ use flowy_collaboration::{
|
||||
};
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use lib_infra::future::BoxResultFuture;
|
||||
use lib_ot::core::{Attributes, Delta};
|
||||
use lib_ot::core::{Attributes, Delta, PlainTextAttributes};
|
||||
use lib_ot::rich_text::RichTextAttributes;
|
||||
use serde::de::DeserializeOwned;
|
||||
use std::{convert::TryFrom, sync::Arc};
|
||||
|
||||
@ -29,6 +30,9 @@ pub trait ConflictRevisionSink: Send + Sync + 'static {
|
||||
fn ack(&self, rev_id: String, ty: ServerRevisionWSDataType) -> BoxResultFuture<(), FlowyError>;
|
||||
}
|
||||
|
||||
pub type RichTextConflictController = ConflictController<RichTextAttributes>;
|
||||
pub type PlainTextConflictController = ConflictController<PlainTextAttributes>;
|
||||
|
||||
pub struct ConflictController<T>
|
||||
where
|
||||
T: Attributes + Send + Sync,
|
||||
@ -171,6 +175,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub type RichTextTransformDeltas = TransformDeltas<RichTextAttributes>;
|
||||
|
||||
pub struct TransformDeltas<T>
|
||||
where
|
||||
T: Attributes,
|
||||
|
@ -88,7 +88,8 @@ async fn create_view(sdk: &FlowySDKTest, app_id: &str) -> View {
|
||||
name: "View A".to_string(),
|
||||
desc: "".to_string(),
|
||||
thumbnail: Some("http://1.png".to_string()),
|
||||
view_type: ViewType::RichText,
|
||||
data_type: ViewDataType::RichText,
|
||||
ext_data: "".to_string(),
|
||||
};
|
||||
|
||||
let view = FolderEventBuilder::new(sdk.clone())
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
errors::{CollaborateError, CollaborateResult},
|
||||
};
|
||||
use flowy_folder_data_model::entities::{trash::Trash, workspace::Workspace};
|
||||
use lib_ot::core::{PlainAttributes, PlainDelta, PlainDeltaBuilder};
|
||||
use lib_ot::core::{PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -34,7 +34,7 @@ impl FolderPadBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn build_with_delta(self, mut delta: PlainDelta) -> CollaborateResult<FolderPad> {
|
||||
pub(crate) fn build_with_delta(self, mut delta: PlainTextDelta) -> CollaborateResult<FolderPad> {
|
||||
if delta.is_empty() {
|
||||
delta = default_folder_delta();
|
||||
}
|
||||
@ -47,7 +47,7 @@ impl FolderPadBuilder {
|
||||
}
|
||||
|
||||
pub(crate) fn build_with_revisions(self, revisions: Vec<Revision>) -> CollaborateResult<FolderPad> {
|
||||
let folder_delta: FolderDelta = make_delta_from_revisions::<PlainAttributes>(revisions)?;
|
||||
let folder_delta: FolderDelta = make_delta_from_revisions::<PlainTextAttributes>(revisions)?;
|
||||
self.build_with_delta(folder_delta)
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ impl FolderPadBuilder {
|
||||
Ok(FolderPad {
|
||||
workspaces: self.workspaces,
|
||||
trash: self.trash,
|
||||
root: PlainDeltaBuilder::new().insert(&json).build(),
|
||||
root: PlainTextDeltaBuilder::new().insert(&json).build(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use crate::{
|
||||
};
|
||||
use dissimilar::*;
|
||||
use flowy_folder_data_model::entities::{app::App, trash::Trash, view::View, workspace::Workspace};
|
||||
use lib_ot::core::{Delta, FlowyStr, OperationTransformable, PlainAttributes, PlainDeltaBuilder};
|
||||
use lib_ot::core::{FlowyStr, OperationTransformable, PlainTextDelta, PlainTextDeltaBuilder};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -21,7 +21,7 @@ pub struct FolderPad {
|
||||
}
|
||||
|
||||
pub fn default_folder_delta() -> FolderDelta {
|
||||
PlainDeltaBuilder::new()
|
||||
PlainTextDeltaBuilder::new()
|
||||
.insert(r#"{"workspaces":[],"trash":[]}"#)
|
||||
.build()
|
||||
}
|
||||
@ -385,9 +385,9 @@ impl FolderPad {
|
||||
}
|
||||
}
|
||||
|
||||
fn cal_diff(old: String, new: String) -> Delta<PlainAttributes> {
|
||||
fn cal_diff(old: String, new: String) -> PlainTextDelta {
|
||||
let chunks = dissimilar::diff(&old, &new);
|
||||
let mut delta_builder = PlainDeltaBuilder::new();
|
||||
let mut delta_builder = PlainTextDeltaBuilder::new();
|
||||
for chunk in &chunks {
|
||||
match chunk {
|
||||
Chunk::Equal(s) => {
|
||||
@ -410,7 +410,7 @@ mod tests {
|
||||
use crate::{client_folder::folder_pad::FolderPad, entities::folder_info::FolderDelta};
|
||||
use chrono::Utc;
|
||||
use flowy_folder_data_model::entities::{app::App, trash::Trash, view::View, workspace::Workspace};
|
||||
use lib_ot::core::{OperationTransformable, PlainDelta, PlainDeltaBuilder};
|
||||
use lib_ot::core::{OperationTransformable, PlainTextDelta, PlainTextDeltaBuilder};
|
||||
|
||||
#[test]
|
||||
fn folder_add_workspace() {
|
||||
@ -725,7 +725,7 @@ mod tests {
|
||||
fn test_folder() -> (FolderPad, FolderDelta, Workspace) {
|
||||
let mut folder = FolderPad::default();
|
||||
let folder_json = serde_json::to_string(&folder).unwrap();
|
||||
let mut delta = PlainDeltaBuilder::new().insert(&folder_json).build();
|
||||
let mut delta = PlainTextDeltaBuilder::new().insert(&folder_json).build();
|
||||
|
||||
let mut workspace = Workspace::default();
|
||||
workspace.name = "😁 my first workspace".to_owned();
|
||||
@ -767,7 +767,7 @@ mod tests {
|
||||
fn test_trash() -> (FolderPad, FolderDelta, Trash) {
|
||||
let mut folder = FolderPad::default();
|
||||
let folder_json = serde_json::to_string(&folder).unwrap();
|
||||
let mut delta = PlainDeltaBuilder::new().insert(&folder_json).build();
|
||||
let mut delta = PlainTextDeltaBuilder::new().insert(&folder_json).build();
|
||||
|
||||
let mut trash = Trash::default();
|
||||
trash.name = "🚽 my first trash".to_owned();
|
||||
@ -780,7 +780,7 @@ mod tests {
|
||||
(folder, delta, trash)
|
||||
}
|
||||
|
||||
fn make_folder_from_delta(mut initial_delta: FolderDelta, deltas: Vec<PlainDelta>) -> FolderPad {
|
||||
fn make_folder_from_delta(mut initial_delta: FolderDelta, deltas: Vec<PlainTextDelta>) -> FolderPad {
|
||||
for delta in deltas {
|
||||
initial_delta = initial_delta.compose(&delta).unwrap();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use flowy_derive::ProtoBuf;
|
||||
use lib_ot::core::PlainDelta;
|
||||
use lib_ot::core::PlainTextDelta;
|
||||
|
||||
pub type FolderDelta = PlainDelta;
|
||||
pub type FolderDelta = PlainTextDelta;
|
||||
|
||||
#[derive(ProtoBuf, Default, Debug, Clone, Eq, PartialEq)]
|
||||
pub struct FolderInfo {
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
||||
use async_stream::stream;
|
||||
use futures::stream::StreamExt;
|
||||
use lib_infra::future::BoxResultFuture;
|
||||
use lib_ot::core::PlainAttributes;
|
||||
use lib_ot::core::PlainTextAttributes;
|
||||
use std::{collections::HashMap, fmt::Debug, sync::Arc};
|
||||
use tokio::{
|
||||
sync::{mpsc, oneshot, RwLock},
|
||||
@ -187,7 +187,7 @@ impl ServerFolderManager {
|
||||
}
|
||||
}
|
||||
|
||||
type FolderRevisionSynchronizer = RevisionSynchronizer<PlainAttributes>;
|
||||
type FolderRevisionSynchronizer = RevisionSynchronizer<PlainTextAttributes>;
|
||||
|
||||
struct OpenFolderHandler {
|
||||
folder_id: String,
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{entities::folder_info::FolderDelta, errors::CollaborateError, synchronizer::RevisionSyncObject};
|
||||
use lib_ot::core::{Delta, OperationTransformable, PlainAttributes};
|
||||
use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta};
|
||||
|
||||
pub struct ServerFolder {
|
||||
folder_id: String,
|
||||
@ -15,21 +15,18 @@ impl ServerFolder {
|
||||
}
|
||||
}
|
||||
|
||||
impl RevisionSyncObject<PlainAttributes> for ServerFolder {
|
||||
impl RevisionSyncObject<PlainTextAttributes> for ServerFolder {
|
||||
fn id(&self) -> &str {
|
||||
&self.folder_id
|
||||
}
|
||||
|
||||
fn compose(&mut self, other: &Delta<PlainAttributes>) -> Result<(), CollaborateError> {
|
||||
fn compose(&mut self, other: &PlainTextDelta) -> Result<(), CollaborateError> {
|
||||
let new_delta = self.delta.compose(other)?;
|
||||
self.delta = new_delta;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn transform(
|
||||
&self,
|
||||
other: &Delta<PlainAttributes>,
|
||||
) -> Result<(Delta<PlainAttributes>, Delta<PlainAttributes>), CollaborateError> {
|
||||
fn transform(&self, other: &PlainTextDelta) -> Result<(PlainTextDelta, PlainTextDelta), CollaborateError> {
|
||||
let value = self.delta.transform(other)?;
|
||||
Ok(value)
|
||||
}
|
||||
@ -38,7 +35,7 @@ impl RevisionSyncObject<PlainAttributes> for ServerFolder {
|
||||
self.delta.to_json()
|
||||
}
|
||||
|
||||
fn set_delta(&mut self, new_delta: Delta<PlainAttributes>) {
|
||||
fn set_delta(&mut self, new_delta: PlainTextDelta) {
|
||||
self.delta = new_delta;
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,8 @@ pub struct View {
|
||||
pub desc: String,
|
||||
|
||||
#[pb(index = 5)]
|
||||
pub view_type: ViewType,
|
||||
#[serde(default)]
|
||||
pub data_type: ViewDataType,
|
||||
|
||||
#[pb(index = 6)]
|
||||
pub version: i64,
|
||||
@ -41,6 +42,12 @@ pub struct View {
|
||||
|
||||
#[pb(index = 9)]
|
||||
pub create_time: i64,
|
||||
|
||||
#[pb(index = 10)]
|
||||
pub ext_data: String,
|
||||
|
||||
#[pb(index = 11)]
|
||||
pub thumbnail: String,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Debug, Default, ProtoBuf, Clone, Serialize, Deserialize)]
|
||||
@ -65,25 +72,25 @@ impl std::convert::From<View> for Trash {
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Debug, ProtoBuf_Enum, Clone, Serialize)]
|
||||
pub enum ViewType {
|
||||
pub enum ViewDataType {
|
||||
RichText = 0,
|
||||
PlainText = 1,
|
||||
}
|
||||
|
||||
impl std::default::Default for ViewType {
|
||||
impl std::default::Default for ViewDataType {
|
||||
fn default() -> Self {
|
||||
ViewType::PlainText
|
||||
ViewDataType::PlainText
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<i32> for ViewType {
|
||||
impl std::convert::From<i32> for ViewDataType {
|
||||
fn from(val: i32) -> Self {
|
||||
match val {
|
||||
0 => ViewType::RichText,
|
||||
1 => ViewType::PlainText,
|
||||
0 => ViewDataType::RichText,
|
||||
1 => ViewDataType::PlainText,
|
||||
_ => {
|
||||
log::error!("Invalid view type: {}", val);
|
||||
ViewType::PlainText
|
||||
ViewDataType::PlainText
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -104,10 +111,10 @@ pub struct CreateViewPayload {
|
||||
pub thumbnail: Option<String>,
|
||||
|
||||
#[pb(index = 5)]
|
||||
pub view_type: ViewType,
|
||||
pub data_type: ViewDataType,
|
||||
|
||||
#[pb(index = 6)]
|
||||
pub ext: String,
|
||||
pub ext_data: String,
|
||||
}
|
||||
|
||||
#[derive(Default, ProtoBuf, Debug, Clone)]
|
||||
@ -125,35 +132,16 @@ pub struct CreateViewParams {
|
||||
pub thumbnail: String,
|
||||
|
||||
#[pb(index = 5)]
|
||||
pub view_type: ViewType,
|
||||
pub data_type: ViewDataType,
|
||||
|
||||
#[pb(index = 6)]
|
||||
pub ext: String,
|
||||
pub ext_data: String,
|
||||
|
||||
#[pb(index = 7)]
|
||||
pub view_id: String,
|
||||
}
|
||||
|
||||
impl CreateViewParams {
|
||||
pub fn new(
|
||||
belong_to_id: String,
|
||||
name: String,
|
||||
desc: String,
|
||||
view_type: ViewType,
|
||||
thumbnail: String,
|
||||
ext: String,
|
||||
view_id: String,
|
||||
) -> Self {
|
||||
Self {
|
||||
belong_to_id,
|
||||
name,
|
||||
desc,
|
||||
thumbnail,
|
||||
view_type,
|
||||
ext,
|
||||
view_id,
|
||||
}
|
||||
}
|
||||
#[pb(index = 8)]
|
||||
pub data: String,
|
||||
}
|
||||
|
||||
impl TryInto<CreateViewParams> for CreateViewPayload {
|
||||
@ -163,21 +151,22 @@ impl TryInto<CreateViewParams> for CreateViewPayload {
|
||||
let name = ViewName::parse(self.name)?.0;
|
||||
let belong_to_id = AppIdentify::parse(self.belong_to_id)?.0;
|
||||
let view_id = uuid::Uuid::new_v4().to_string();
|
||||
let ext = ViewExtensionData::parse(self.ext)?.0;
|
||||
let ext_data = ViewExtensionData::parse(self.ext_data)?.0;
|
||||
let thumbnail = match self.thumbnail {
|
||||
None => "".to_string(),
|
||||
Some(thumbnail) => ViewThumbnail::parse(thumbnail)?.0,
|
||||
};
|
||||
|
||||
Ok(CreateViewParams::new(
|
||||
Ok(CreateViewParams {
|
||||
belong_to_id,
|
||||
name,
|
||||
self.desc,
|
||||
self.view_type,
|
||||
desc: self.desc,
|
||||
data_type: self.data_type,
|
||||
thumbnail,
|
||||
ext,
|
||||
ext_data,
|
||||
view_id,
|
||||
))
|
||||
data: "".to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,7 +269,7 @@ impl TryInto<UpdateViewParams> for UpdateViewPayload {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for ViewType {
|
||||
impl<'de> Deserialize<'de> for ViewDataType {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
@ -288,7 +277,7 @@ impl<'de> Deserialize<'de> for ViewType {
|
||||
struct ViewTypeVisitor();
|
||||
|
||||
impl<'de> Visitor<'de> for ViewTypeVisitor {
|
||||
type Value = ViewType;
|
||||
type Value = ViewDataType;
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("Plugin, RichText")
|
||||
}
|
||||
@ -301,10 +290,10 @@ impl<'de> Deserialize<'de> for ViewType {
|
||||
match s {
|
||||
"Doc" | "RichText" => {
|
||||
// Rename ViewType::Doc to ViewType::RichText, So we need to migrate the ViewType manually.
|
||||
view_type = ViewType::RichText;
|
||||
view_type = ViewDataType::RichText;
|
||||
}
|
||||
"Plugin" => {
|
||||
view_type = ViewType::PlainText;
|
||||
view_type = ViewDataType::PlainText;
|
||||
}
|
||||
unknown => {
|
||||
return Err(de::Error::invalid_value(Unexpected::Str(unknown), &self));
|
||||
|
@ -30,11 +30,13 @@ pub struct View {
|
||||
pub belong_to_id: ::std::string::String,
|
||||
pub name: ::std::string::String,
|
||||
pub desc: ::std::string::String,
|
||||
pub view_type: ViewType,
|
||||
pub data_type: ViewDataType,
|
||||
pub version: i64,
|
||||
pub belongings: ::protobuf::SingularPtrField<RepeatedView>,
|
||||
pub modified_time: i64,
|
||||
pub create_time: i64,
|
||||
pub ext_data: ::std::string::String,
|
||||
pub thumbnail: ::std::string::String,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
@ -155,19 +157,19 @@ impl View {
|
||||
::std::mem::replace(&mut self.desc, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// .ViewType view_type = 5;
|
||||
// .ViewDataType data_type = 5;
|
||||
|
||||
|
||||
pub fn get_view_type(&self) -> ViewType {
|
||||
self.view_type
|
||||
pub fn get_data_type(&self) -> ViewDataType {
|
||||
self.data_type
|
||||
}
|
||||
pub fn clear_view_type(&mut self) {
|
||||
self.view_type = ViewType::RichText;
|
||||
pub fn clear_data_type(&mut self) {
|
||||
self.data_type = ViewDataType::RichText;
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_view_type(&mut self, v: ViewType) {
|
||||
self.view_type = v;
|
||||
pub fn set_data_type(&mut self, v: ViewDataType) {
|
||||
self.data_type = v;
|
||||
}
|
||||
|
||||
// int64 version = 6;
|
||||
@ -247,6 +249,58 @@ impl View {
|
||||
pub fn set_create_time(&mut self, v: i64) {
|
||||
self.create_time = v;
|
||||
}
|
||||
|
||||
// string ext_data = 10;
|
||||
|
||||
|
||||
pub fn get_ext_data(&self) -> &str {
|
||||
&self.ext_data
|
||||
}
|
||||
pub fn clear_ext_data(&mut self) {
|
||||
self.ext_data.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_ext_data(&mut self, v: ::std::string::String) {
|
||||
self.ext_data = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
// If field is not initialized, it is initialized with default value first.
|
||||
pub fn mut_ext_data(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.ext_data
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_ext_data(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.ext_data, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// string thumbnail = 11;
|
||||
|
||||
|
||||
pub fn get_thumbnail(&self) -> &str {
|
||||
&self.thumbnail
|
||||
}
|
||||
pub fn clear_thumbnail(&mut self) {
|
||||
self.thumbnail.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_thumbnail(&mut self, v: ::std::string::String) {
|
||||
self.thumbnail = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
// If field is not initialized, it is initialized with default value first.
|
||||
pub fn mut_thumbnail(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.thumbnail
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_thumbnail(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.thumbnail, ::std::string::String::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for View {
|
||||
@ -276,7 +330,7 @@ impl ::protobuf::Message for View {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.desc)?;
|
||||
},
|
||||
5 => {
|
||||
::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.view_type, 5, &mut self.unknown_fields)?
|
||||
::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.data_type, 5, &mut self.unknown_fields)?
|
||||
},
|
||||
6 => {
|
||||
if wire_type != ::protobuf::wire_format::WireTypeVarint {
|
||||
@ -302,6 +356,12 @@ impl ::protobuf::Message for View {
|
||||
let tmp = is.read_int64()?;
|
||||
self.create_time = tmp;
|
||||
},
|
||||
10 => {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.ext_data)?;
|
||||
},
|
||||
11 => {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.thumbnail)?;
|
||||
},
|
||||
_ => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||
},
|
||||
@ -326,8 +386,8 @@ impl ::protobuf::Message for View {
|
||||
if !self.desc.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(4, &self.desc);
|
||||
}
|
||||
if self.view_type != ViewType::RichText {
|
||||
my_size += ::protobuf::rt::enum_size(5, self.view_type);
|
||||
if self.data_type != ViewDataType::RichText {
|
||||
my_size += ::protobuf::rt::enum_size(5, self.data_type);
|
||||
}
|
||||
if self.version != 0 {
|
||||
my_size += ::protobuf::rt::value_size(6, self.version, ::protobuf::wire_format::WireTypeVarint);
|
||||
@ -342,6 +402,12 @@ impl ::protobuf::Message for View {
|
||||
if self.create_time != 0 {
|
||||
my_size += ::protobuf::rt::value_size(9, self.create_time, ::protobuf::wire_format::WireTypeVarint);
|
||||
}
|
||||
if !self.ext_data.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(10, &self.ext_data);
|
||||
}
|
||||
if !self.thumbnail.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(11, &self.thumbnail);
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
||||
self.cached_size.set(my_size);
|
||||
my_size
|
||||
@ -360,8 +426,8 @@ impl ::protobuf::Message for View {
|
||||
if !self.desc.is_empty() {
|
||||
os.write_string(4, &self.desc)?;
|
||||
}
|
||||
if self.view_type != ViewType::RichText {
|
||||
os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.view_type))?;
|
||||
if self.data_type != ViewDataType::RichText {
|
||||
os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?;
|
||||
}
|
||||
if self.version != 0 {
|
||||
os.write_int64(6, self.version)?;
|
||||
@ -377,6 +443,12 @@ impl ::protobuf::Message for View {
|
||||
if self.create_time != 0 {
|
||||
os.write_int64(9, self.create_time)?;
|
||||
}
|
||||
if !self.ext_data.is_empty() {
|
||||
os.write_string(10, &self.ext_data)?;
|
||||
}
|
||||
if !self.thumbnail.is_empty() {
|
||||
os.write_string(11, &self.thumbnail)?;
|
||||
}
|
||||
os.write_unknown_fields(self.get_unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
@ -435,10 +507,10 @@ impl ::protobuf::Message for View {
|
||||
|m: &View| { &m.desc },
|
||||
|m: &mut View| { &mut m.desc },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ViewType>>(
|
||||
"view_type",
|
||||
|m: &View| { &m.view_type },
|
||||
|m: &mut View| { &mut m.view_type },
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ViewDataType>>(
|
||||
"data_type",
|
||||
|m: &View| { &m.data_type },
|
||||
|m: &mut View| { &mut m.data_type },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>(
|
||||
"version",
|
||||
@ -460,6 +532,16 @@ impl ::protobuf::Message for View {
|
||||
|m: &View| { &m.create_time },
|
||||
|m: &mut View| { &mut m.create_time },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"ext_data",
|
||||
|m: &View| { &m.ext_data },
|
||||
|m: &mut View| { &mut m.ext_data },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"thumbnail",
|
||||
|m: &View| { &m.thumbnail },
|
||||
|m: &mut View| { &mut m.thumbnail },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<View>(
|
||||
"View",
|
||||
fields,
|
||||
@ -480,11 +562,13 @@ impl ::protobuf::Clear for View {
|
||||
self.belong_to_id.clear();
|
||||
self.name.clear();
|
||||
self.desc.clear();
|
||||
self.view_type = ViewType::RichText;
|
||||
self.data_type = ViewDataType::RichText;
|
||||
self.version = 0;
|
||||
self.belongings.clear();
|
||||
self.modified_time = 0;
|
||||
self.create_time = 0;
|
||||
self.ext_data.clear();
|
||||
self.thumbnail.clear();
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
@ -673,8 +757,8 @@ pub struct CreateViewPayload {
|
||||
pub belong_to_id: ::std::string::String,
|
||||
pub name: ::std::string::String,
|
||||
pub desc: ::std::string::String,
|
||||
pub view_type: ViewType,
|
||||
pub ext: ::std::string::String,
|
||||
pub data_type: ViewDataType,
|
||||
pub ext_data: ::std::string::String,
|
||||
// message oneof groups
|
||||
pub one_of_thumbnail: ::std::option::Option<CreateViewPayload_oneof_one_of_thumbnail>,
|
||||
// special fields
|
||||
@ -825,45 +909,45 @@ impl CreateViewPayload {
|
||||
}
|
||||
}
|
||||
|
||||
// .ViewType view_type = 5;
|
||||
// .ViewDataType data_type = 5;
|
||||
|
||||
|
||||
pub fn get_view_type(&self) -> ViewType {
|
||||
self.view_type
|
||||
pub fn get_data_type(&self) -> ViewDataType {
|
||||
self.data_type
|
||||
}
|
||||
pub fn clear_view_type(&mut self) {
|
||||
self.view_type = ViewType::RichText;
|
||||
pub fn clear_data_type(&mut self) {
|
||||
self.data_type = ViewDataType::RichText;
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_view_type(&mut self, v: ViewType) {
|
||||
self.view_type = v;
|
||||
pub fn set_data_type(&mut self, v: ViewDataType) {
|
||||
self.data_type = v;
|
||||
}
|
||||
|
||||
// string ext = 6;
|
||||
// string ext_data = 6;
|
||||
|
||||
|
||||
pub fn get_ext(&self) -> &str {
|
||||
&self.ext
|
||||
pub fn get_ext_data(&self) -> &str {
|
||||
&self.ext_data
|
||||
}
|
||||
pub fn clear_ext(&mut self) {
|
||||
self.ext.clear();
|
||||
pub fn clear_ext_data(&mut self) {
|
||||
self.ext_data.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_ext(&mut self, v: ::std::string::String) {
|
||||
self.ext = v;
|
||||
pub fn set_ext_data(&mut self, v: ::std::string::String) {
|
||||
self.ext_data = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
// If field is not initialized, it is initialized with default value first.
|
||||
pub fn mut_ext(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.ext
|
||||
pub fn mut_ext_data(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.ext_data
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_ext(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.ext, ::std::string::String::new())
|
||||
pub fn take_ext_data(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.ext_data, ::std::string::String::new())
|
||||
}
|
||||
}
|
||||
|
||||
@ -892,10 +976,10 @@ impl ::protobuf::Message for CreateViewPayload {
|
||||
self.one_of_thumbnail = ::std::option::Option::Some(CreateViewPayload_oneof_one_of_thumbnail::thumbnail(is.read_string()?));
|
||||
},
|
||||
5 => {
|
||||
::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.view_type, 5, &mut self.unknown_fields)?
|
||||
::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.data_type, 5, &mut self.unknown_fields)?
|
||||
},
|
||||
6 => {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.ext)?;
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.ext_data)?;
|
||||
},
|
||||
_ => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||
@ -918,11 +1002,11 @@ impl ::protobuf::Message for CreateViewPayload {
|
||||
if !self.desc.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(3, &self.desc);
|
||||
}
|
||||
if self.view_type != ViewType::RichText {
|
||||
my_size += ::protobuf::rt::enum_size(5, self.view_type);
|
||||
if self.data_type != ViewDataType::RichText {
|
||||
my_size += ::protobuf::rt::enum_size(5, self.data_type);
|
||||
}
|
||||
if !self.ext.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(6, &self.ext);
|
||||
if !self.ext_data.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(6, &self.ext_data);
|
||||
}
|
||||
if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail {
|
||||
match v {
|
||||
@ -946,11 +1030,11 @@ impl ::protobuf::Message for CreateViewPayload {
|
||||
if !self.desc.is_empty() {
|
||||
os.write_string(3, &self.desc)?;
|
||||
}
|
||||
if self.view_type != ViewType::RichText {
|
||||
os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.view_type))?;
|
||||
if self.data_type != ViewDataType::RichText {
|
||||
os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?;
|
||||
}
|
||||
if !self.ext.is_empty() {
|
||||
os.write_string(6, &self.ext)?;
|
||||
if !self.ext_data.is_empty() {
|
||||
os.write_string(6, &self.ext_data)?;
|
||||
}
|
||||
if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail {
|
||||
match v {
|
||||
@ -1017,15 +1101,15 @@ impl ::protobuf::Message for CreateViewPayload {
|
||||
CreateViewPayload::has_thumbnail,
|
||||
CreateViewPayload::get_thumbnail,
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ViewType>>(
|
||||
"view_type",
|
||||
|m: &CreateViewPayload| { &m.view_type },
|
||||
|m: &mut CreateViewPayload| { &mut m.view_type },
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ViewDataType>>(
|
||||
"data_type",
|
||||
|m: &CreateViewPayload| { &m.data_type },
|
||||
|m: &mut CreateViewPayload| { &mut m.data_type },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"ext",
|
||||
|m: &CreateViewPayload| { &m.ext },
|
||||
|m: &mut CreateViewPayload| { &mut m.ext },
|
||||
"ext_data",
|
||||
|m: &CreateViewPayload| { &m.ext_data },
|
||||
|m: &mut CreateViewPayload| { &mut m.ext_data },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateViewPayload>(
|
||||
"CreateViewPayload",
|
||||
@ -1047,8 +1131,8 @@ impl ::protobuf::Clear for CreateViewPayload {
|
||||
self.name.clear();
|
||||
self.desc.clear();
|
||||
self.one_of_thumbnail = ::std::option::Option::None;
|
||||
self.view_type = ViewType::RichText;
|
||||
self.ext.clear();
|
||||
self.data_type = ViewDataType::RichText;
|
||||
self.ext_data.clear();
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
@ -1072,9 +1156,10 @@ pub struct CreateViewParams {
|
||||
pub name: ::std::string::String,
|
||||
pub desc: ::std::string::String,
|
||||
pub thumbnail: ::std::string::String,
|
||||
pub view_type: ViewType,
|
||||
pub ext: ::std::string::String,
|
||||
pub data_type: ViewDataType,
|
||||
pub ext_data: ::std::string::String,
|
||||
pub view_id: ::std::string::String,
|
||||
pub data: ::std::string::String,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
@ -1195,45 +1280,45 @@ impl CreateViewParams {
|
||||
::std::mem::replace(&mut self.thumbnail, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// .ViewType view_type = 5;
|
||||
// .ViewDataType data_type = 5;
|
||||
|
||||
|
||||
pub fn get_view_type(&self) -> ViewType {
|
||||
self.view_type
|
||||
pub fn get_data_type(&self) -> ViewDataType {
|
||||
self.data_type
|
||||
}
|
||||
pub fn clear_view_type(&mut self) {
|
||||
self.view_type = ViewType::RichText;
|
||||
pub fn clear_data_type(&mut self) {
|
||||
self.data_type = ViewDataType::RichText;
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_view_type(&mut self, v: ViewType) {
|
||||
self.view_type = v;
|
||||
pub fn set_data_type(&mut self, v: ViewDataType) {
|
||||
self.data_type = v;
|
||||
}
|
||||
|
||||
// string ext = 6;
|
||||
// string ext_data = 6;
|
||||
|
||||
|
||||
pub fn get_ext(&self) -> &str {
|
||||
&self.ext
|
||||
pub fn get_ext_data(&self) -> &str {
|
||||
&self.ext_data
|
||||
}
|
||||
pub fn clear_ext(&mut self) {
|
||||
self.ext.clear();
|
||||
pub fn clear_ext_data(&mut self) {
|
||||
self.ext_data.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_ext(&mut self, v: ::std::string::String) {
|
||||
self.ext = v;
|
||||
pub fn set_ext_data(&mut self, v: ::std::string::String) {
|
||||
self.ext_data = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
// If field is not initialized, it is initialized with default value first.
|
||||
pub fn mut_ext(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.ext
|
||||
pub fn mut_ext_data(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.ext_data
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_ext(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.ext, ::std::string::String::new())
|
||||
pub fn take_ext_data(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.ext_data, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// string view_id = 7;
|
||||
@ -1261,6 +1346,32 @@ impl CreateViewParams {
|
||||
pub fn take_view_id(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.view_id, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// string data = 8;
|
||||
|
||||
|
||||
pub fn get_data(&self) -> &str {
|
||||
&self.data
|
||||
}
|
||||
pub fn clear_data(&mut self) {
|
||||
self.data.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_data(&mut self, v: ::std::string::String) {
|
||||
self.data = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
// If field is not initialized, it is initialized with default value first.
|
||||
pub fn mut_data(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.data
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_data(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.data, ::std::string::String::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for CreateViewParams {
|
||||
@ -1285,14 +1396,17 @@ impl ::protobuf::Message for CreateViewParams {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.thumbnail)?;
|
||||
},
|
||||
5 => {
|
||||
::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.view_type, 5, &mut self.unknown_fields)?
|
||||
::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.data_type, 5, &mut self.unknown_fields)?
|
||||
},
|
||||
6 => {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.ext)?;
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.ext_data)?;
|
||||
},
|
||||
7 => {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.view_id)?;
|
||||
},
|
||||
8 => {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?;
|
||||
},
|
||||
_ => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||
},
|
||||
@ -1317,15 +1431,18 @@ impl ::protobuf::Message for CreateViewParams {
|
||||
if !self.thumbnail.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(4, &self.thumbnail);
|
||||
}
|
||||
if self.view_type != ViewType::RichText {
|
||||
my_size += ::protobuf::rt::enum_size(5, self.view_type);
|
||||
if self.data_type != ViewDataType::RichText {
|
||||
my_size += ::protobuf::rt::enum_size(5, self.data_type);
|
||||
}
|
||||
if !self.ext.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(6, &self.ext);
|
||||
if !self.ext_data.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(6, &self.ext_data);
|
||||
}
|
||||
if !self.view_id.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(7, &self.view_id);
|
||||
}
|
||||
if !self.data.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(8, &self.data);
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
||||
self.cached_size.set(my_size);
|
||||
my_size
|
||||
@ -1344,15 +1461,18 @@ impl ::protobuf::Message for CreateViewParams {
|
||||
if !self.thumbnail.is_empty() {
|
||||
os.write_string(4, &self.thumbnail)?;
|
||||
}
|
||||
if self.view_type != ViewType::RichText {
|
||||
os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.view_type))?;
|
||||
if self.data_type != ViewDataType::RichText {
|
||||
os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?;
|
||||
}
|
||||
if !self.ext.is_empty() {
|
||||
os.write_string(6, &self.ext)?;
|
||||
if !self.ext_data.is_empty() {
|
||||
os.write_string(6, &self.ext_data)?;
|
||||
}
|
||||
if !self.view_id.is_empty() {
|
||||
os.write_string(7, &self.view_id)?;
|
||||
}
|
||||
if !self.data.is_empty() {
|
||||
os.write_string(8, &self.data)?;
|
||||
}
|
||||
os.write_unknown_fields(self.get_unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
@ -1411,21 +1531,26 @@ impl ::protobuf::Message for CreateViewParams {
|
||||
|m: &CreateViewParams| { &m.thumbnail },
|
||||
|m: &mut CreateViewParams| { &mut m.thumbnail },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ViewType>>(
|
||||
"view_type",
|
||||
|m: &CreateViewParams| { &m.view_type },
|
||||
|m: &mut CreateViewParams| { &mut m.view_type },
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ViewDataType>>(
|
||||
"data_type",
|
||||
|m: &CreateViewParams| { &m.data_type },
|
||||
|m: &mut CreateViewParams| { &mut m.data_type },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"ext",
|
||||
|m: &CreateViewParams| { &m.ext },
|
||||
|m: &mut CreateViewParams| { &mut m.ext },
|
||||
"ext_data",
|
||||
|m: &CreateViewParams| { &m.ext_data },
|
||||
|m: &mut CreateViewParams| { &mut m.ext_data },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"view_id",
|
||||
|m: &CreateViewParams| { &m.view_id },
|
||||
|m: &mut CreateViewParams| { &mut m.view_id },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"data",
|
||||
|m: &CreateViewParams| { &m.data },
|
||||
|m: &mut CreateViewParams| { &mut m.data },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateViewParams>(
|
||||
"CreateViewParams",
|
||||
fields,
|
||||
@ -1446,9 +1571,10 @@ impl ::protobuf::Clear for CreateViewParams {
|
||||
self.name.clear();
|
||||
self.desc.clear();
|
||||
self.thumbnail.clear();
|
||||
self.view_type = ViewType::RichText;
|
||||
self.ext.clear();
|
||||
self.data_type = ViewDataType::RichText;
|
||||
self.ext_data.clear();
|
||||
self.view_id.clear();
|
||||
self.data.clear();
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
@ -2589,28 +2715,28 @@ impl ::protobuf::reflect::ProtobufValue for UpdateViewParams {
|
||||
}
|
||||
|
||||
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
|
||||
pub enum ViewType {
|
||||
pub enum ViewDataType {
|
||||
RichText = 0,
|
||||
PlainText = 1,
|
||||
}
|
||||
|
||||
impl ::protobuf::ProtobufEnum for ViewType {
|
||||
impl ::protobuf::ProtobufEnum for ViewDataType {
|
||||
fn value(&self) -> i32 {
|
||||
*self as i32
|
||||
}
|
||||
|
||||
fn from_i32(value: i32) -> ::std::option::Option<ViewType> {
|
||||
fn from_i32(value: i32) -> ::std::option::Option<ViewDataType> {
|
||||
match value {
|
||||
0 => ::std::option::Option::Some(ViewType::RichText),
|
||||
1 => ::std::option::Option::Some(ViewType::PlainText),
|
||||
0 => ::std::option::Option::Some(ViewDataType::RichText),
|
||||
1 => ::std::option::Option::Some(ViewDataType::PlainText),
|
||||
_ => ::std::option::Option::None
|
||||
}
|
||||
}
|
||||
|
||||
fn values() -> &'static [Self] {
|
||||
static values: &'static [ViewType] = &[
|
||||
ViewType::RichText,
|
||||
ViewType::PlainText,
|
||||
static values: &'static [ViewDataType] = &[
|
||||
ViewDataType::RichText,
|
||||
ViewDataType::PlainText,
|
||||
];
|
||||
values
|
||||
}
|
||||
@ -2618,58 +2744,61 @@ impl ::protobuf::ProtobufEnum for ViewType {
|
||||
fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
|
||||
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT;
|
||||
descriptor.get(|| {
|
||||
::protobuf::reflect::EnumDescriptor::new_pb_name::<ViewType>("ViewType", file_descriptor_proto())
|
||||
::protobuf::reflect::EnumDescriptor::new_pb_name::<ViewDataType>("ViewDataType", file_descriptor_proto())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::marker::Copy for ViewType {
|
||||
impl ::std::marker::Copy for ViewDataType {
|
||||
}
|
||||
|
||||
impl ::std::default::Default for ViewType {
|
||||
impl ::std::default::Default for ViewDataType {
|
||||
fn default() -> Self {
|
||||
ViewType::RichText
|
||||
ViewDataType::RichText
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for ViewType {
|
||||
impl ::protobuf::reflect::ProtobufValue for ViewDataType {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self))
|
||||
}
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\nview.proto\"\x97\x02\n\x04View\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\
|
||||
\n\nview.proto\"\xd4\x02\n\x04View\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\
|
||||
\x02id\x12\x20\n\x0cbelong_to_id\x18\x02\x20\x01(\tR\nbelongToId\x12\x12\
|
||||
\n\x04name\x18\x03\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x04\x20\x01\
|
||||
(\tR\x04desc\x12&\n\tview_type\x18\x05\x20\x01(\x0e2\t.ViewTypeR\x08view\
|
||||
Type\x12\x18\n\x07version\x18\x06\x20\x01(\x03R\x07version\x12-\n\nbelon\
|
||||
gings\x18\x07\x20\x01(\x0b2\r.RepeatedViewR\nbelongings\x12#\n\rmodified\
|
||||
_time\x18\x08\x20\x01(\x03R\x0cmodifiedTime\x12\x1f\n\x0bcreate_time\x18\
|
||||
\t\x20\x01(\x03R\ncreateTime\"+\n\x0cRepeatedView\x12\x1b\n\x05items\x18\
|
||||
\x01\x20\x03(\x0b2\x05.ViewR\x05items\"\xcb\x01\n\x11CreateViewPayload\
|
||||
\x12\x20\n\x0cbelong_to_id\x18\x01\x20\x01(\tR\nbelongToId\x12\x12\n\x04\
|
||||
name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\
|
||||
\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\0R\tthumbnail\x12&\n\t\
|
||||
view_type\x18\x05\x20\x01(\x0e2\t.ViewTypeR\x08viewType\x12\x10\n\x03ext\
|
||||
\x18\x06\x20\x01(\tR\x03extB\x12\n\x10one_of_thumbnail\"\xcd\x01\n\x10Cr\
|
||||
eateViewParams\x12\x20\n\x0cbelong_to_id\x18\x01\x20\x01(\tR\nbelongToId\
|
||||
\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\
|
||||
\x20\x01(\tR\x04desc\x12\x1c\n\tthumbnail\x18\x04\x20\x01(\tR\tthumbnail\
|
||||
\x12&\n\tview_type\x18\x05\x20\x01(\x0e2\t.ViewTypeR\x08viewType\x12\x10\
|
||||
\n\x03ext\x18\x06\x20\x01(\tR\x03ext\x12\x17\n\x07view_id\x18\x07\x20\
|
||||
\x01(\tR\x06viewId\"\x1e\n\x06ViewId\x12\x14\n\x05value\x18\x01\x20\x01(\
|
||||
\tR\x05value\"&\n\x0eRepeatedViewId\x12\x14\n\x05items\x18\x01\x20\x03(\
|
||||
\tR\x05items\"\xaa\x01\n\x11UpdateViewPayload\x12\x17\n\x07view_id\x18\
|
||||
\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04n\
|
||||
ame\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12\x1e\n\tthumbn\
|
||||
ail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of_nameB\r\n\x0bone_\
|
||||
of_descB\x12\n\x10one_of_thumbnail\"\xa9\x01\n\x10UpdateViewParams\x12\
|
||||
\x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\
|
||||
\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\
|
||||
\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\
|
||||
\x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail*'\n\x08Vi\
|
||||
ewType\x12\x0c\n\x08RichText\x10\0\x12\r\n\tPlainText\x10\x01b\x06proto3\
|
||||
(\tR\x04desc\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTypeR\x08\
|
||||
dataType\x12\x18\n\x07version\x18\x06\x20\x01(\x03R\x07version\x12-\n\nb\
|
||||
elongings\x18\x07\x20\x01(\x0b2\r.RepeatedViewR\nbelongings\x12#\n\rmodi\
|
||||
fied_time\x18\x08\x20\x01(\x03R\x0cmodifiedTime\x12\x1f\n\x0bcreate_time\
|
||||
\x18\t\x20\x01(\x03R\ncreateTime\x12\x19\n\x08ext_data\x18\n\x20\x01(\tR\
|
||||
\x07extData\x12\x1c\n\tthumbnail\x18\x0b\x20\x01(\tR\tthumbnail\"+\n\x0c\
|
||||
RepeatedView\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.ViewR\x05items\
|
||||
\"\xd8\x01\n\x11CreateViewPayload\x12\x20\n\x0cbelong_to_id\x18\x01\x20\
|
||||
\x01(\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\
|
||||
\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1e\n\tthumbnail\x18\x04\
|
||||
\x20\x01(\tH\0R\tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.Vie\
|
||||
wDataTypeR\x08dataType\x12\x19\n\x08ext_data\x18\x06\x20\x01(\tR\x07extD\
|
||||
ataB\x12\n\x10one_of_thumbnail\"\xee\x01\n\x10CreateViewParams\x12\x20\n\
|
||||
\x0cbelong_to_id\x18\x01\x20\x01(\tR\nbelongToId\x12\x12\n\x04name\x18\
|
||||
\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\
|
||||
\x12\x1c\n\tthumbnail\x18\x04\x20\x01(\tR\tthumbnail\x12*\n\tdata_type\
|
||||
\x18\x05\x20\x01(\x0e2\r.ViewDataTypeR\x08dataType\x12\x19\n\x08ext_data\
|
||||
\x18\x06\x20\x01(\tR\x07extData\x12\x17\n\x07view_id\x18\x07\x20\x01(\tR\
|
||||
\x06viewId\x12\x12\n\x04data\x18\x08\x20\x01(\tR\x04data\"\x1e\n\x06View\
|
||||
Id\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"&\n\x0eRepeatedViewI\
|
||||
d\x12\x14\n\x05items\x18\x01\x20\x03(\tR\x05items\"\xaa\x01\n\x11UpdateV\
|
||||
iewPayload\x12\x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\
|
||||
\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\
|
||||
\x01(\tH\x01R\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthu\
|
||||
mbnailB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnai\
|
||||
l\"\xa9\x01\n\x10UpdateViewParams\x12\x17\n\x07view_id\x18\x01\x20\x01(\
|
||||
\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\
|
||||
\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12\x1e\n\tthumbnail\x18\x04\
|
||||
\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\
|
||||
\x12\n\x10one_of_thumbnail*+\n\x0cViewDataType\x12\x0c\n\x08RichText\x10\
|
||||
\0\x12\r\n\tPlainText\x10\x01b\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
@ -5,11 +5,13 @@ message View {
|
||||
string belong_to_id = 2;
|
||||
string name = 3;
|
||||
string desc = 4;
|
||||
ViewType view_type = 5;
|
||||
ViewDataType data_type = 5;
|
||||
int64 version = 6;
|
||||
RepeatedView belongings = 7;
|
||||
int64 modified_time = 8;
|
||||
int64 create_time = 9;
|
||||
string ext_data = 10;
|
||||
string thumbnail = 11;
|
||||
}
|
||||
message RepeatedView {
|
||||
repeated View items = 1;
|
||||
@ -19,17 +21,18 @@ message CreateViewPayload {
|
||||
string name = 2;
|
||||
string desc = 3;
|
||||
oneof one_of_thumbnail { string thumbnail = 4; };
|
||||
ViewType view_type = 5;
|
||||
string ext = 6;
|
||||
ViewDataType data_type = 5;
|
||||
string ext_data = 6;
|
||||
}
|
||||
message CreateViewParams {
|
||||
string belong_to_id = 1;
|
||||
string name = 2;
|
||||
string desc = 3;
|
||||
string thumbnail = 4;
|
||||
ViewType view_type = 5;
|
||||
string ext = 6;
|
||||
ViewDataType data_type = 5;
|
||||
string ext_data = 6;
|
||||
string view_id = 7;
|
||||
string data = 8;
|
||||
}
|
||||
message ViewId {
|
||||
string value = 1;
|
||||
@ -49,7 +52,7 @@ message UpdateViewParams {
|
||||
oneof one_of_desc { string desc = 3; };
|
||||
oneof one_of_thumbnail { string thumbnail = 4; };
|
||||
}
|
||||
enum ViewType {
|
||||
enum ViewDataType {
|
||||
RichText = 0;
|
||||
PlainText = 1;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::entities::{
|
||||
app::{App, RepeatedApp},
|
||||
view::{RepeatedView, View, ViewType},
|
||||
view::{RepeatedView, View, ViewDataType},
|
||||
workspace::Workspace,
|
||||
};
|
||||
use chrono::Utc;
|
||||
@ -49,17 +49,19 @@ fn create_default_view(app_id: String, time: chrono::DateTime<Utc>) -> View {
|
||||
let view_id = uuid::Uuid::new_v4();
|
||||
let name = "Read me".to_string();
|
||||
let desc = "".to_string();
|
||||
let view_type = ViewType::RichText;
|
||||
let data_type = ViewDataType::RichText;
|
||||
|
||||
View {
|
||||
id: view_id.to_string(),
|
||||
belong_to_id: app_id,
|
||||
name,
|
||||
desc,
|
||||
view_type,
|
||||
data_type,
|
||||
version: 0,
|
||||
belongings: Default::default(),
|
||||
modified_time: time.timestamp(),
|
||||
create_time: time.timestamp(),
|
||||
ext_data: "".to_string(),
|
||||
thumbnail: "".to_string(),
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::core::{trim, Attributes, Delta, PlainAttributes};
|
||||
use crate::core::{trim, Attributes, Delta, PlainTextAttributes};
|
||||
|
||||
pub type PlainDeltaBuilder = DeltaBuilder<PlainAttributes>;
|
||||
pub type PlainTextDeltaBuilder = DeltaBuilder<PlainTextAttributes>;
|
||||
|
||||
pub struct DeltaBuilder<T: Attributes> {
|
||||
delta: Delta<T>,
|
||||
|
@ -13,7 +13,7 @@ use std::{
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
pub type PlainDelta = Delta<PlainAttributes>;
|
||||
pub type PlainTextDelta = Delta<PlainTextAttributes>;
|
||||
|
||||
// TODO: optimize the memory usage with Arc::make_mut or Cow
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -1,10 +1,10 @@
|
||||
use crate::{
|
||||
core::{Attributes, Operation, PlainAttributes},
|
||||
core::{Attributes, Operation, PlainTextAttributes},
|
||||
rich_text::RichTextAttributes,
|
||||
};
|
||||
|
||||
pub type RichTextOpBuilder = OpBuilder<RichTextAttributes>;
|
||||
pub type PlainTextOpBuilder = OpBuilder<PlainAttributes>;
|
||||
pub type PlainTextOpBuilder = OpBuilder<PlainTextAttributes>;
|
||||
|
||||
pub struct OpBuilder<T: Attributes> {
|
||||
ty: Operation<T>,
|
||||
|
@ -339,14 +339,14 @@ where
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Default, Serialize, Deserialize)]
|
||||
pub struct PlainAttributes();
|
||||
impl fmt::Display for PlainAttributes {
|
||||
pub struct PlainTextAttributes();
|
||||
impl fmt::Display for PlainTextAttributes {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("PlainAttributes")
|
||||
}
|
||||
}
|
||||
|
||||
impl Attributes for PlainAttributes {
|
||||
impl Attributes for PlainTextAttributes {
|
||||
fn is_empty(&self) -> bool {
|
||||
true
|
||||
}
|
||||
@ -356,7 +356,7 @@ impl Attributes for PlainAttributes {
|
||||
fn extend_other(&mut self, _other: Self) {}
|
||||
}
|
||||
|
||||
impl OperationTransformable for PlainAttributes {
|
||||
impl OperationTransformable for PlainTextAttributes {
|
||||
fn compose(&self, _other: &Self) -> Result<Self, OTError> {
|
||||
Ok(self.clone())
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ impl fmt::Display for RichTextAttributes {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn plain_attributes() -> RichTextAttributes {
|
||||
RichTextAttributes::default()
|
||||
}
|
||||
@ -58,7 +59,7 @@ impl RichTextAttributes {
|
||||
self.inner.insert(key, value);
|
||||
}
|
||||
|
||||
pub fn add_kv(&mut self, key: RichTextAttributeKey, value: RichTextAttributeValue) {
|
||||
pub fn insert(&mut self, key: RichTextAttributeKey, value: RichTextAttributeValue) {
|
||||
self.inner.insert(key, value);
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ impl<'de> Deserialize<'de> for RichTextAttributes {
|
||||
let mut attributes = RichTextAttributes::new();
|
||||
while let Some(key) = map.next_key::<RichTextAttributeKey>()? {
|
||||
let value = map.next_value::<RichTextAttributeValue>()?;
|
||||
attributes.add_kv(key, value);
|
||||
attributes.insert(key, value);
|
||||
}
|
||||
|
||||
Ok(attributes)
|
||||
|
Loading…
Reference in New Issue
Block a user