refactor: add plugins

This commit is contained in:
appflowy 2022-02-28 22:38:53 +08:00
parent 74831964a6
commit 8747457836
57 changed files with 975 additions and 647 deletions

View 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,
}

View File

@ -0,0 +1 @@
class PluginRunner {}

View 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();
}

View File

@ -1,5 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/startup/tasks/prelude.dart'; import 'package:app_flowy/startup/tasks/prelude.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -41,6 +42,7 @@ class FlowyRunner {
getIt<AppLauncher>().addTask(InitRustSDKTask()); getIt<AppLauncher>().addTask(InitRustSDKTask());
if (!env.isTest()) { if (!env.isTest()) {
getIt<AppLauncher>().addTask(PluginLoadTask());
getIt<AppLauncher>().addTask(InitAppWidgetTask()); getIt<AppLauncher>().addTask(InitAppWidgetTask());
getIt<AppLauncher>().addTask(InitPlatformServiceTask()); getIt<AppLauncher>().addTask(InitPlatformServiceTask());
} }
@ -58,6 +60,7 @@ Future<void> initGetIt(
getIt.registerFactory<EntryPoint>(() => f); getIt.registerFactory<EntryPoint>(() => f);
getIt.registerLazySingleton<FlowySDK>(() => const FlowySDK()); getIt.registerLazySingleton<FlowySDK>(() => const FlowySDK());
getIt.registerLazySingleton<AppLauncher>(() => AppLauncher(env, getIt)); getIt.registerLazySingleton<AppLauncher>(() => AppLauncher(env, getIt));
getIt.registerSingleton<PluginSandbox>(PluginSandbox());
await UserDepsResolver.resolve(getIt); await UserDepsResolver.resolve(getIt);
await HomeDepsResolver.resolve(getIt); await HomeDepsResolver.resolve(getIt);

View 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());
}
}

View File

@ -1,3 +1,4 @@
export 'app_widget.dart'; export 'app_widget.dart';
export 'init_sdk.dart'; export 'rust_sdk.dart';
export 'platform_service.dart'; export 'platform_service.dart';
export 'load_plugin.dart';

View File

@ -1,3 +1,4 @@
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/workspace/infrastructure/repos/app_repo.dart'; import 'package:app_flowy/workspace/infrastructure/repos/app_repo.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
@ -21,7 +22,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
); );
await _fetchViews(emit); await _fetchViews(emit);
}, createView: (CreateView value) async { }, 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( viewOrFailed.fold(
(view) => emit(state.copyWith( (view) => emit(state.copyWith(
latestCreatedView: view, latestCreatedView: view,
@ -95,7 +96,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
@freezed @freezed
class AppEvent with _$AppEvent { class AppEvent with _$AppEvent {
const factory AppEvent.initial() = Initial; 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.delete() = Delete;
const factory AppEvent.rename(String newName) = Rename; const factory AppEvent.rename(String newName) = Rename;
const factory AppEvent.didReceiveViews(List<View> views) = ReceiveViews; const factory AppEvent.didReceiveViews(List<View> views) = ReceiveViews;

View File

@ -1,7 +1,7 @@
import 'dart:async'; 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/infrastructure/repos/workspace_repo.dart';
import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
@ -26,7 +26,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
emit(state.copyWith(isCollapse: !isCollapse)); emit(state.copyWith(isCollapse: !isCollapse));
}, },
openPage: (e) async { openPage: (e) async {
emit(state.copyWith(stackContext: e.context)); emit(state.copyWith(plugin: e.plugin));
}, },
createApp: (CreateApp event) async { createApp: (CreateApp event) async {
await _performActionOnCreateApp(event, emit); await _performActionOnCreateApp(event, emit);
@ -82,7 +82,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
class MenuEvent with _$MenuEvent { class MenuEvent with _$MenuEvent {
const factory MenuEvent.initial() = _Initial; const factory MenuEvent.initial() = _Initial;
const factory MenuEvent.collapse() = Collapse; 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.createApp(String name, {String? desc}) = CreateApp;
const factory MenuEvent.didReceiveApps(Either<List<App>, FlowyError> appsOrFail) = ReceiveApps; const factory MenuEvent.didReceiveApps(Either<List<App>, FlowyError> appsOrFail) = ReceiveApps;
} }
@ -93,13 +93,13 @@ class MenuState with _$MenuState {
required bool isCollapse, required bool isCollapse,
required Option<List<App>> apps, required Option<List<App>> apps,
required Either<Unit, FlowyError> successOrFailure, required Either<Unit, FlowyError> successOrFailure,
required HomeStackContext stackContext, required Plugin plugin,
}) = _MenuState; }) = _MenuState;
factory MenuState.initial() => MenuState( factory MenuState.initial() => MenuState(
isCollapse: false, isCollapse: false,
apps: none(), apps: none(),
successOrFailure: left(unit), successOrFailure: left(unit),
stackContext: BlankStackContext(), plugin: makePlugin(pluginType: DefaultPluginEnum.blank.type()),
); );
} }

View File

@ -25,9 +25,9 @@ class _$MenuEventTearOff {
return const Collapse(); return const Collapse();
} }
OpenPage openPage(HomeStackContext<dynamic, dynamic> context) { OpenPage openPage(Plugin plugin) {
return OpenPage( return OpenPage(
context, plugin,
); );
} }
@ -54,8 +54,7 @@ mixin _$MenuEvent {
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function() initial, required TResult Function() initial,
required TResult Function() collapse, required TResult Function() collapse,
required TResult Function(HomeStackContext<dynamic, dynamic> context) required TResult Function(Plugin plugin) openPage,
openPage,
required TResult Function(String name, String? desc) createApp, required TResult Function(String name, String? desc) createApp,
required TResult Function(Either<List<App>, FlowyError> appsOrFail) required TResult Function(Either<List<App>, FlowyError> appsOrFail)
didReceiveApps, didReceiveApps,
@ -65,7 +64,7 @@ mixin _$MenuEvent {
TResult? whenOrNull<TResult extends Object?>({ TResult? whenOrNull<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage, TResult Function(Plugin plugin)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps, TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
}) => }) =>
@ -74,7 +73,7 @@ mixin _$MenuEvent {
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage, TResult Function(Plugin plugin)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps, TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
required TResult orElse(), required TResult orElse(),
@ -164,8 +163,7 @@ class _$_Initial implements _Initial {
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function() initial, required TResult Function() initial,
required TResult Function() collapse, required TResult Function() collapse,
required TResult Function(HomeStackContext<dynamic, dynamic> context) required TResult Function(Plugin plugin) openPage,
openPage,
required TResult Function(String name, String? desc) createApp, required TResult Function(String name, String? desc) createApp,
required TResult Function(Either<List<App>, FlowyError> appsOrFail) required TResult Function(Either<List<App>, FlowyError> appsOrFail)
didReceiveApps, didReceiveApps,
@ -178,7 +176,7 @@ class _$_Initial implements _Initial {
TResult? whenOrNull<TResult extends Object?>({ TResult? whenOrNull<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage, TResult Function(Plugin plugin)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps, TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
}) { }) {
@ -190,7 +188,7 @@ class _$_Initial implements _Initial {
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage, TResult Function(Plugin plugin)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps, TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
required TResult orElse(), required TResult orElse(),
@ -285,8 +283,7 @@ class _$Collapse implements Collapse {
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function() initial, required TResult Function() initial,
required TResult Function() collapse, required TResult Function() collapse,
required TResult Function(HomeStackContext<dynamic, dynamic> context) required TResult Function(Plugin plugin) openPage,
openPage,
required TResult Function(String name, String? desc) createApp, required TResult Function(String name, String? desc) createApp,
required TResult Function(Either<List<App>, FlowyError> appsOrFail) required TResult Function(Either<List<App>, FlowyError> appsOrFail)
didReceiveApps, didReceiveApps,
@ -299,7 +296,7 @@ class _$Collapse implements Collapse {
TResult? whenOrNull<TResult extends Object?>({ TResult? whenOrNull<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage, TResult Function(Plugin plugin)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps, TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
}) { }) {
@ -311,7 +308,7 @@ class _$Collapse implements Collapse {
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage, TResult Function(Plugin plugin)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps, TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
required TResult orElse(), required TResult orElse(),
@ -371,7 +368,7 @@ abstract class Collapse implements MenuEvent {
abstract class $OpenPageCopyWith<$Res> { abstract class $OpenPageCopyWith<$Res> {
factory $OpenPageCopyWith(OpenPage value, $Res Function(OpenPage) then) = factory $OpenPageCopyWith(OpenPage value, $Res Function(OpenPage) then) =
_$OpenPageCopyWithImpl<$Res>; _$OpenPageCopyWithImpl<$Res>;
$Res call({HomeStackContext<dynamic, dynamic> context}); $Res call({Plugin plugin});
} }
/// @nodoc /// @nodoc
@ -385,13 +382,13 @@ class _$OpenPageCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res>
@override @override
$Res call({ $Res call({
Object? context = freezed, Object? plugin = freezed,
}) { }) {
return _then(OpenPage( return _then(OpenPage(
context == freezed plugin == freezed
? _value.context ? _value.plugin
: context // ignore: cast_nullable_to_non_nullable : plugin // ignore: cast_nullable_to_non_nullable
as HomeStackContext<dynamic, dynamic>, as Plugin,
)); ));
} }
} }
@ -399,27 +396,27 @@ class _$OpenPageCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$OpenPage implements OpenPage { class _$OpenPage implements OpenPage {
const _$OpenPage(this.context); const _$OpenPage(this.plugin);
@override @override
final HomeStackContext<dynamic, dynamic> context; final Plugin plugin;
@override @override
String toString() { String toString() {
return 'MenuEvent.openPage(context: $context)'; return 'MenuEvent.openPage(plugin: $plugin)';
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
return identical(this, other) || return identical(this, other) ||
(other is OpenPage && (other is OpenPage &&
(identical(other.context, context) || (identical(other.plugin, plugin) ||
const DeepCollectionEquality().equals(other.context, context))); const DeepCollectionEquality().equals(other.plugin, plugin)));
} }
@override @override
int get hashCode => int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(context); runtimeType.hashCode ^ const DeepCollectionEquality().hash(plugin);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@ -431,13 +428,12 @@ class _$OpenPage implements OpenPage {
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function() initial, required TResult Function() initial,
required TResult Function() collapse, required TResult Function() collapse,
required TResult Function(HomeStackContext<dynamic, dynamic> context) required TResult Function(Plugin plugin) openPage,
openPage,
required TResult Function(String name, String? desc) createApp, required TResult Function(String name, String? desc) createApp,
required TResult Function(Either<List<App>, FlowyError> appsOrFail) required TResult Function(Either<List<App>, FlowyError> appsOrFail)
didReceiveApps, didReceiveApps,
}) { }) {
return openPage(context); return openPage(plugin);
} }
@override @override
@ -445,11 +441,11 @@ class _$OpenPage implements OpenPage {
TResult? whenOrNull<TResult extends Object?>({ TResult? whenOrNull<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage, TResult Function(Plugin plugin)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps, TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
}) { }) {
return openPage?.call(context); return openPage?.call(plugin);
} }
@override @override
@ -457,13 +453,13 @@ class _$OpenPage implements OpenPage {
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage, TResult Function(Plugin plugin)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps, TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
required TResult orElse(), required TResult orElse(),
}) { }) {
if (openPage != null) { if (openPage != null) {
return openPage(context); return openPage(plugin);
} }
return orElse(); return orElse();
} }
@ -510,11 +506,9 @@ class _$OpenPage implements OpenPage {
} }
abstract class OpenPage implements MenuEvent { abstract class OpenPage implements MenuEvent {
const factory OpenPage(HomeStackContext<dynamic, dynamic> context) = const factory OpenPage(Plugin plugin) = _$OpenPage;
_$OpenPage;
HomeStackContext<dynamic, dynamic> get context => Plugin get plugin => throw _privateConstructorUsedError;
throw _privateConstructorUsedError;
@JsonKey(ignore: true) @JsonKey(ignore: true)
$OpenPageCopyWith<OpenPage> get copyWith => $OpenPageCopyWith<OpenPage> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@ -595,8 +589,7 @@ class _$CreateApp implements CreateApp {
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function() initial, required TResult Function() initial,
required TResult Function() collapse, required TResult Function() collapse,
required TResult Function(HomeStackContext<dynamic, dynamic> context) required TResult Function(Plugin plugin) openPage,
openPage,
required TResult Function(String name, String? desc) createApp, required TResult Function(String name, String? desc) createApp,
required TResult Function(Either<List<App>, FlowyError> appsOrFail) required TResult Function(Either<List<App>, FlowyError> appsOrFail)
didReceiveApps, didReceiveApps,
@ -609,7 +602,7 @@ class _$CreateApp implements CreateApp {
TResult? whenOrNull<TResult extends Object?>({ TResult? whenOrNull<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage, TResult Function(Plugin plugin)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps, TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
}) { }) {
@ -621,7 +614,7 @@ class _$CreateApp implements CreateApp {
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage, TResult Function(Plugin plugin)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps, TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
required TResult orElse(), required TResult orElse(),
@ -750,8 +743,7 @@ class _$ReceiveApps implements ReceiveApps {
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function() initial, required TResult Function() initial,
required TResult Function() collapse, required TResult Function() collapse,
required TResult Function(HomeStackContext<dynamic, dynamic> context) required TResult Function(Plugin plugin) openPage,
openPage,
required TResult Function(String name, String? desc) createApp, required TResult Function(String name, String? desc) createApp,
required TResult Function(Either<List<App>, FlowyError> appsOrFail) required TResult Function(Either<List<App>, FlowyError> appsOrFail)
didReceiveApps, didReceiveApps,
@ -764,7 +756,7 @@ class _$ReceiveApps implements ReceiveApps {
TResult? whenOrNull<TResult extends Object?>({ TResult? whenOrNull<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage, TResult Function(Plugin plugin)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps, TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
}) { }) {
@ -776,7 +768,7 @@ class _$ReceiveApps implements ReceiveApps {
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage, TResult Function(Plugin plugin)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps, TResult Function(Either<List<App>, FlowyError> appsOrFail)? didReceiveApps,
required TResult orElse(), required TResult orElse(),
@ -847,12 +839,12 @@ class _$MenuStateTearOff {
{required bool isCollapse, {required bool isCollapse,
required Option<List<App>> apps, required Option<List<App>> apps,
required Either<Unit, FlowyError> successOrFailure, required Either<Unit, FlowyError> successOrFailure,
required HomeStackContext<dynamic, dynamic> stackContext}) { required Plugin plugin}) {
return _MenuState( return _MenuState(
isCollapse: isCollapse, isCollapse: isCollapse,
apps: apps, apps: apps,
successOrFailure: successOrFailure, successOrFailure: successOrFailure,
stackContext: stackContext, plugin: plugin,
); );
} }
} }
@ -866,8 +858,7 @@ mixin _$MenuState {
Option<List<App>> get apps => throw _privateConstructorUsedError; Option<List<App>> get apps => throw _privateConstructorUsedError;
Either<Unit, FlowyError> get successOrFailure => Either<Unit, FlowyError> get successOrFailure =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
HomeStackContext<dynamic, dynamic> get stackContext => Plugin get plugin => throw _privateConstructorUsedError;
throw _privateConstructorUsedError;
@JsonKey(ignore: true) @JsonKey(ignore: true)
$MenuStateCopyWith<MenuState> get copyWith => $MenuStateCopyWith<MenuState> get copyWith =>
@ -882,7 +873,7 @@ abstract class $MenuStateCopyWith<$Res> {
{bool isCollapse, {bool isCollapse,
Option<List<App>> apps, Option<List<App>> apps,
Either<Unit, FlowyError> successOrFailure, Either<Unit, FlowyError> successOrFailure,
HomeStackContext<dynamic, dynamic> stackContext}); Plugin plugin});
} }
/// @nodoc /// @nodoc
@ -898,7 +889,7 @@ class _$MenuStateCopyWithImpl<$Res> implements $MenuStateCopyWith<$Res> {
Object? isCollapse = freezed, Object? isCollapse = freezed,
Object? apps = freezed, Object? apps = freezed,
Object? successOrFailure = freezed, Object? successOrFailure = freezed,
Object? stackContext = freezed, Object? plugin = freezed,
}) { }) {
return _then(_value.copyWith( return _then(_value.copyWith(
isCollapse: isCollapse == freezed isCollapse: isCollapse == freezed
@ -913,10 +904,10 @@ class _$MenuStateCopyWithImpl<$Res> implements $MenuStateCopyWith<$Res> {
? _value.successOrFailure ? _value.successOrFailure
: successOrFailure // ignore: cast_nullable_to_non_nullable : successOrFailure // ignore: cast_nullable_to_non_nullable
as Either<Unit, FlowyError>, as Either<Unit, FlowyError>,
stackContext: stackContext == freezed plugin: plugin == freezed
? _value.stackContext ? _value.plugin
: stackContext // ignore: cast_nullable_to_non_nullable : plugin // ignore: cast_nullable_to_non_nullable
as HomeStackContext<dynamic, dynamic>, as Plugin,
)); ));
} }
} }
@ -931,7 +922,7 @@ abstract class _$MenuStateCopyWith<$Res> implements $MenuStateCopyWith<$Res> {
{bool isCollapse, {bool isCollapse,
Option<List<App>> apps, Option<List<App>> apps,
Either<Unit, FlowyError> successOrFailure, Either<Unit, FlowyError> successOrFailure,
HomeStackContext<dynamic, dynamic> stackContext}); Plugin plugin});
} }
/// @nodoc /// @nodoc
@ -948,7 +939,7 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res>
Object? isCollapse = freezed, Object? isCollapse = freezed,
Object? apps = freezed, Object? apps = freezed,
Object? successOrFailure = freezed, Object? successOrFailure = freezed,
Object? stackContext = freezed, Object? plugin = freezed,
}) { }) {
return _then(_MenuState( return _then(_MenuState(
isCollapse: isCollapse == freezed isCollapse: isCollapse == freezed
@ -963,10 +954,10 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res>
? _value.successOrFailure ? _value.successOrFailure
: successOrFailure // ignore: cast_nullable_to_non_nullable : successOrFailure // ignore: cast_nullable_to_non_nullable
as Either<Unit, FlowyError>, as Either<Unit, FlowyError>,
stackContext: stackContext == freezed plugin: plugin == freezed
? _value.stackContext ? _value.plugin
: stackContext // ignore: cast_nullable_to_non_nullable : plugin // ignore: cast_nullable_to_non_nullable
as HomeStackContext<dynamic, dynamic>, as Plugin,
)); ));
} }
} }
@ -978,7 +969,7 @@ class _$_MenuState implements _MenuState {
{required this.isCollapse, {required this.isCollapse,
required this.apps, required this.apps,
required this.successOrFailure, required this.successOrFailure,
required this.stackContext}); required this.plugin});
@override @override
final bool isCollapse; final bool isCollapse;
@ -987,11 +978,11 @@ class _$_MenuState implements _MenuState {
@override @override
final Either<Unit, FlowyError> successOrFailure; final Either<Unit, FlowyError> successOrFailure;
@override @override
final HomeStackContext<dynamic, dynamic> stackContext; final Plugin plugin;
@override @override
String toString() { String toString() {
return 'MenuState(isCollapse: $isCollapse, apps: $apps, successOrFailure: $successOrFailure, stackContext: $stackContext)'; return 'MenuState(isCollapse: $isCollapse, apps: $apps, successOrFailure: $successOrFailure, plugin: $plugin)';
} }
@override @override
@ -1006,9 +997,8 @@ class _$_MenuState implements _MenuState {
(identical(other.successOrFailure, successOrFailure) || (identical(other.successOrFailure, successOrFailure) ||
const DeepCollectionEquality() const DeepCollectionEquality()
.equals(other.successOrFailure, successOrFailure)) && .equals(other.successOrFailure, successOrFailure)) &&
(identical(other.stackContext, stackContext) || (identical(other.plugin, plugin) ||
const DeepCollectionEquality() const DeepCollectionEquality().equals(other.plugin, plugin)));
.equals(other.stackContext, stackContext)));
} }
@override @override
@ -1017,7 +1007,7 @@ class _$_MenuState implements _MenuState {
const DeepCollectionEquality().hash(isCollapse) ^ const DeepCollectionEquality().hash(isCollapse) ^
const DeepCollectionEquality().hash(apps) ^ const DeepCollectionEquality().hash(apps) ^
const DeepCollectionEquality().hash(successOrFailure) ^ const DeepCollectionEquality().hash(successOrFailure) ^
const DeepCollectionEquality().hash(stackContext); const DeepCollectionEquality().hash(plugin);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@ -1030,7 +1020,7 @@ abstract class _MenuState implements MenuState {
{required bool isCollapse, {required bool isCollapse,
required Option<List<App>> apps, required Option<List<App>> apps,
required Either<Unit, FlowyError> successOrFailure, required Either<Unit, FlowyError> successOrFailure,
required HomeStackContext<dynamic, dynamic> stackContext}) = _$_MenuState; required Plugin plugin}) = _$_MenuState;
@override @override
bool get isCollapse => throw _privateConstructorUsedError; bool get isCollapse => throw _privateConstructorUsedError;
@ -1040,8 +1030,7 @@ abstract class _MenuState implements MenuState {
Either<Unit, FlowyError> get successOrFailure => Either<Unit, FlowyError> get successOrFailure =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@override @override
HomeStackContext<dynamic, dynamic> get stackContext => Plugin get plugin => throw _privateConstructorUsedError;
throw _privateConstructorUsedError;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$MenuStateCopyWith<_MenuState> get copyWith => _$MenuStateCopyWith<_MenuState> get copyWith =>

View File

@ -9,7 +9,6 @@ part 'view_bloc.freezed.dart';
class ViewMenuBloc extends Bloc<ViewEvent, ViewState> { class ViewMenuBloc extends Bloc<ViewEvent, ViewState> {
final ViewRepository repo; final ViewRepository repo;
final ViewListener listener; final ViewListener listener;
ViewMenuBloc({ ViewMenuBloc({

View File

@ -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";
}
}

View File

@ -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:flowy_infra/notifier.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -10,23 +12,13 @@ typedef NavigationCallback = void Function(String id);
abstract class NavigationItem { abstract class NavigationItem {
Widget get leftBarItem; Widget get leftBarItem;
Widget? get rightBarItem => null; Widget? get rightBarItem => null;
String get identifier;
NavigationCallback get action => (id) { NavigationCallback get action => (id) {
getIt<HomeStackManager>().setStackWithId(id); getIt<HomeStackManager>().setStackWithId(id);
}; };
} }
enum HomeStackType { abstract class HomeStackContext<T> with NavigationItem {
blank,
document,
kanban,
trash,
}
List<HomeStackType> pages = HomeStackType.values.toList();
abstract class HomeStackContext<T, S> with NavigationItem {
List<NavigationItem> get navigationItems; List<NavigationItem> get navigationItems;
@override @override
@ -35,40 +27,35 @@ abstract class HomeStackContext<T, S> with NavigationItem {
@override @override
Widget? get rightBarItem; Widget? get rightBarItem;
@override
String get identifier;
ValueNotifier<T> get isUpdated; ValueNotifier<T> get isUpdated;
HomeStackType get type;
Widget buildWidget(); Widget buildWidget();
void dispose(); void dispose();
} }
class HomeStackNotifier extends ChangeNotifier { class HomeStackNotifier extends ChangeNotifier {
HomeStackContext stackContext; Plugin _plugin;
PublishNotifier<bool> collapsedNotifier = PublishNotifier(); 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) { set plugin(Plugin newPlugin) {
if (stackContext.identifier == context.identifier) { if (newPlugin.pluginId == _plugin.pluginId) {
return; return;
} }
stackContext.isUpdated.removeListener(notifyListeners); // stackContext.isUpdated.removeListener(notifyListeners);
stackContext.dispose(); _plugin.dispose();
stackContext = context; _plugin = newPlugin;
stackContext.isUpdated.addListener(notifyListeners); // stackContext.isUpdated.addListener(notifyListeners);
notifyListeners(); notifyListeners();
} }
HomeStackContext get context => stackContext; Plugin get plugin => _plugin;
} }
// HomeStack is initialized as singleton to controll the page stack. // HomeStack is initialized as singleton to controll the page stack.
@ -77,13 +64,13 @@ class HomeStackManager {
HomeStackManager(); HomeStackManager();
Widget title() { Widget title() {
return _notifier.context.leftBarItem; return _notifier.plugin.display.leftBarItem;
} }
PublishNotifier<bool> get collapsedNotifier => _notifier.collapsedNotifier; PublishNotifier<bool> get collapsedNotifier => _notifier.collapsedNotifier;
void setStack(HomeStackContext context) { void setPlugin(Plugin newPlugin) {
_notifier.context = context; _notifier.plugin = newPlugin;
} }
void setStackWithId(String id) {} void setStackWithId(String id) {}
@ -109,10 +96,10 @@ class HomeStackManager {
], ],
child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) { child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) {
return FadingIndexedStack( return FadingIndexedStack(
index: pages.indexOf(notifier.context.type), index: getIt<PluginSandbox>().indexOf(notifier.plugin.pluginType),
children: HomeStackType.values.map((viewType) { children: getIt<PluginSandbox>().supportPluginTypes.map((pluginType) {
if (viewType == notifier.context.type) { if (pluginType == notifier.plugin.pluginType) {
return notifier.context.buildWidget(); return notifier.plugin.display.buildWidget();
} else { } else {
return const BlankStackPage(); return const BlankStackPage();
} }

View File

@ -1,40 +1,18 @@
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart'; import 'package:flowy_infra/image.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_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flutter/material.dart';
extension ToHomeStackContext on View { enum FlowyPlugin {
HomeStackContext stackContext() { editor,
switch (viewType) { kanban,
case ViewType.RichText:
return DocumentStackContext(view: this);
case ViewType.Plugin:
return DocumentStackContext(view: this);
default:
return BlankStackContext();
}
}
} }
extension ToHomeStackType on View { extension FlowyPluginExtension on FlowyPlugin {
HomeStackType stackType() {
switch (viewType) {
case ViewType.RichText:
return HomeStackType.document;
case ViewType.PlainText:
return HomeStackType.kanban;
default:
return HomeStackType.blank;
}
}
}
extension ViewTypeExtension on ViewType {
String displayName() { String displayName() {
switch (this) { switch (this) {
case ViewType.RichText: case FlowyPlugin.editor:
return "Doc"; return "Doc";
case ViewType.Plugin: case FlowyPlugin.kanban:
return "Kanban"; return "Kanban";
default: default:
return ""; return "";
@ -43,12 +21,24 @@ extension ViewTypeExtension on ViewType {
bool enable() { bool enable() {
switch (this) { switch (this) {
case ViewType.RichText: case FlowyPlugin.editor:
return true; return true;
case ViewType.Plugin: case FlowyPlugin.kanban:
return false; return false;
default: default:
return false; 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;
}
}

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:app_flowy/plugin/plugin.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart';
@ -26,13 +27,13 @@ class AppRepository {
Future<Either<View, FlowyError>> createView({ Future<Either<View, FlowyError>> createView({
required String name, required String name,
required String desc, required String desc,
required ViewType viewType, required PluginDataType dataType,
}) { }) {
final request = CreateViewPayload.create() final request = CreateViewPayload.create()
..belongToId = appId ..belongToId = appId
..name = name ..name = name
..desc = desc ..desc = desc
..viewType = viewType; ..dataType = dataType;
return FolderEventCreateView(request).send(); return FolderEventCreateView(request).send();
} }

View File

@ -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_bloc.dart';
import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart'; import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.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}) { Widget _buildHomeMenu({required HomeLayout layout, required BuildContext context}) {
if (initialView == null && widget.workspaceSetting.hasLatestView()) { if (initialView == null && widget.workspaceSetting.hasLatestView()) {
initialView = widget.workspaceSetting.latestView; initialView = widget.workspaceSetting.latestView;
getIt<HomeStackManager>().setStack(initialView!.stackContext()); final plugin = makePlugin(pluginType: "RichText", data: initialView);
getIt<HomeStackManager>().setPlugin(plugin);
} }
HomeMenu homeMenu = HomeMenu( HomeMenu homeMenu = HomeMenu(

View File

@ -17,8 +17,8 @@ class NavigationNotifier with ChangeNotifier {
void update(HomeStackNotifier notifier) { void update(HomeStackNotifier notifier) {
bool shouldNotify = false; bool shouldNotify = false;
if (navigationItems != notifier.context.navigationItems) { if (navigationItems != notifier.plugin.display.navigationItems) {
navigationItems = notifier.context.navigationItems; navigationItems = notifier.plugin.display.navigationItems;
shouldNotify = true; shouldNotify = true;
} }
@ -59,7 +59,7 @@ class FlowyNavigation extends StatelessWidget {
create: (_) { create: (_) {
final notifier = Provider.of<HomeStackNotifier>(context, listen: false); final notifier = Provider.of<HomeStackNotifier>(context, listen: false);
return NavigationNotifier( return NavigationNotifier(
navigationItems: notifier.context.navigationItems, navigationItems: notifier.plugin.display.navigationItems,
collapasedNotifier: notifier.collapsedNotifier, collapasedNotifier: notifier.collapsedNotifier,
); );
}, },

View File

@ -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:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pbenum.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:app_flowy/generated/locale_keys.g.dart';
class BlankStackContext extends HomeStackContext { import 'package:app_flowy/generated/locale_keys.g.dart';
final ValueNotifier<bool> _isUpdated = ValueNotifier<bool>(false); 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 @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 @override
Widget get leftBarItem => FlowyText.medium(LocaleKeys.blankPageTitle.tr(), fontSize: 12); Widget get leftBarItem => FlowyText.medium(LocaleKeys.blankPageTitle.tr(), fontSize: 12);
@override @override
Widget? get rightBarItem => null; Widget? get rightBarItem => null;
@override
HomeStackType get type => HomeStackType.blank;
@override @override
Widget buildWidget() { Widget buildWidget() {
return const BlankStackPage(); return const BlankStackPage();
@ -26,12 +62,6 @@ class BlankStackContext extends HomeStackContext {
@override @override
List<NavigationItem> get navigationItems => [this]; List<NavigationItem> get navigationItems => [this];
@override
ValueNotifier<bool> get isUpdated => _isUpdated;
@override
void dispose() {}
} }
class BlankStackPage extends StatefulWidget { class BlankStackPage extends StatefulWidget {

View File

@ -1,8 +1,8 @@
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/appearance.dart'; import 'package:app_flowy/workspace/application/appearance.dart';
import 'package:app_flowy/workspace/application/doc/share_bloc.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/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/infrastructure/repos/view_repo.dart';
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart'; import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.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'; import 'document_page.dart';
class DocumentStackContext extends HomeStackContext<int, ShareActionWrapper> { class DocumentPluginBuilder implements PluginBuilder {
View _view; @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; late ViewListener _listener;
final ValueNotifier<int> _isUpdated = ValueNotifier<int>(0); 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 = getIt<ViewListener>(param1: view);
_listener.updatedNotifier.addPublishListener((result) { _listener.updatedNotifier.addPublishListener((result) {
result.fold( result.fold(
@ -43,37 +65,46 @@ class DocumentStackContext extends HomeStackContext<int, ShareActionWrapper> {
_listener.start(); _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 @override
Widget get leftBarItem => DocumentLeftBarItem(view: _view); Widget get leftBarItem => DocumentLeftBarItem(view: _view);
@override @override
Widget? get rightBarItem => DocumentShareButton(view: _view); 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 @override
List<NavigationItem> get navigationItems => _makeNavigationItems(); List<NavigationItem> get navigationItems => _makeNavigationItems();
@override
ValueNotifier<int> get isUpdated => _isUpdated;
List<NavigationItem> _makeNavigationItems() { List<NavigationItem> _makeNavigationItems() {
return [ return [
this, this,
]; ];
} }
@override
void dispose() {
_listener.close();
}
} }
class DocumentLeftBarItem extends StatefulWidget { class DocumentLeftBarItem extends StatefulWidget {

View File

@ -10,17 +10,6 @@ import 'package:fluttertoast/fluttertoast.dart';
late FToast fToast; late FToast fToast;
// [[diagram: HomeStack's widget structure]]
//
//
// BlankStackContext BlankStackPage
//
// HomeStack HomeStackManager HomeStackContext
//
// DocStackContext DocStackPage
//
//
//
class HomeStack extends StatelessWidget { class HomeStack extends StatelessWidget {
static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey(); static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
// final Size size; // final Size size;

View File

@ -1,4 +1,6 @@
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/startup/startup.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/application/trash/trash_bloc.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart'; import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/stack_page/trash/widget/sizes.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/text.dart';
import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/widget/spacing.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/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:styled_widget/styled_widget.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'; import 'widget/trash_header.dart';
class TrashStackContext extends HomeStackContext { class TrashPluginBuilder implements PluginBuilder {
final ValueNotifier<bool> _isUpdated = ValueNotifier<bool>(false); @override
Plugin build(dynamic data) {
return TrashPlugin(pluginType: pluginType);
}
@override @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 @override
Widget get leftBarItem => FlowyText.medium(LocaleKeys.trash_text.tr(), fontSize: 12); Widget get leftBarItem => FlowyText.medium(LocaleKeys.trash_text.tr(), fontSize: 12);
@override @override
Widget? get rightBarItem => null; Widget? get rightBarItem => null;
@override
HomeStackType get type => HomeStackType.trash;
@override @override
Widget buildWidget() => const TrashStackPage(key: ValueKey('TrashStackPage')); Widget buildWidget() => const TrashStackPage(key: ValueKey('TrashStackPage'));
@override @override
List<NavigationItem> get navigationItems => [this]; List<NavigationItem> get navigationItems => [this];
@override
ValueNotifier<bool> get isUpdated => _isUpdated;
@override
void dispose() {}
} }
class TrashStackPage extends StatefulWidget { class TrashStackPage extends StatefulWidget {

View File

@ -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/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart'; import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
import 'package:app_flowy/workspace/presentation/home/navigation.dart'; import 'package:app_flowy/workspace/presentation/home/navigation.dart';
import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/widget/spacing.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:flutter/material.dart';
import 'package:flowy_infra_ui/style_widget/extension.dart'; import 'package:flowy_infra_ui/style_widget/extension.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class HomeTopBar extends StatelessWidget { class HomeTopBar extends StatelessWidget {
@ -28,7 +25,7 @@ class HomeTopBar extends StatelessWidget {
value: Provider.of<HomeStackNotifier>(context, listen: false), value: Provider.of<HomeStackNotifier>(context, listen: false),
child: Consumer( child: Consumer(
builder: (BuildContext context, HomeStackNotifier notifier, Widget? child) { builder: (BuildContext context, HomeStackNotifier notifier, Widget? child) {
return notifier.stackContext.rightBarItem ?? const SizedBox(); return notifier.plugin.display.rightBarItem ?? const SizedBox();
}, },
), ),
) // _renderMoreButton(), ) // _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),
],
),
);
}
}

View File

@ -70,9 +70,9 @@ class HomeMenu extends StatelessWidget {
child: MultiBlocListener( child: MultiBlocListener(
listeners: [ listeners: [
BlocListener<MenuBloc, MenuState>( BlocListener<MenuBloc, MenuState>(
listenWhen: (p, c) => p.stackContext != c.stackContext, listenWhen: (p, c) => p.plugin.pluginId != c.plugin.pluginId,
listener: (context, state) { listener: (context, state) {
getIt<HomeStackManager>().setStack(state.stackContext); getIt<HomeStackManager>().setPlugin(state.plugin);
}, },
), ),
BlocListener<MenuBloc, MenuState>( BlocListener<MenuBloc, MenuState>(

View File

@ -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:app_flowy/workspace/domain/view_ext.dart';
import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme.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/hover.dart';
import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
class AddButton extends StatelessWidget { class AddButton extends StatelessWidget {
final Function(ViewType) onSelected; final Function(PluginBuilder) onSelected;
const AddButton({ const AddButton({
Key? key, Key? key,
required this.onSelected, required this.onSelected,
@ -35,21 +37,29 @@ class AddButton extends StatelessWidget {
} }
class ActionList { class ActionList {
final Function(ViewType) onSelected; final Function(PluginBuilder) onSelected;
final BuildContext anchorContext; final BuildContext anchorContext;
final String _identifier = 'DisclosureButtonActionList'; final String _identifier = 'DisclosureButtonActionList';
const ActionList({required this.anchorContext, required this.onSelected}); const ActionList({required this.anchorContext, required this.onSelected});
void show(BuildContext buildContext) { 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( return CreateItem(
viewType: ty, pluginBuilder: pluginBuilder,
onSelected: (viewType) { onSelected: (builder) {
FlowyOverlay.of(buildContext).remove(_identifier); FlowyOverlay.of(buildContext).remove(_identifier);
onSelected(viewType); onSelected(builder);
}); },
}).toList(); );
},
).toList();
ListOverlay.showWithAnchor( ListOverlay.showWithAnchor(
buildContext, buildContext,
@ -65,11 +75,11 @@ class ActionList {
} }
class CreateItem extends StatelessWidget { class CreateItem extends StatelessWidget {
final ViewType viewType; final PluginBuilder pluginBuilder;
final Function(ViewType) onSelected; final Function(PluginBuilder) onSelected;
const CreateItem({ const CreateItem({
Key? key, Key? key,
required this.viewType, required this.pluginBuilder,
required this.onSelected, required this.onSelected,
}) : super(key: key); }) : super(key: key);
@ -82,9 +92,9 @@ class CreateItem extends StatelessWidget {
config: config, config: config,
builder: (context, onHover) { builder: (context, onHover) {
return GestureDetector( return GestureDetector(
onTap: () => onSelected(viewType), onTap: () => onSelected(pluginBuilder),
child: FlowyText.medium( child: FlowyText.medium(
viewType.displayName(), pluginBuilder.pluginName,
color: theme.textColor, color: theme.textColor,
fontSize: 12, fontSize: 12,
).padding(horizontal: 10, vertical: 6), ).padding(horizontal: 10, vertical: 6),

View File

@ -102,10 +102,12 @@ class MenuAppHeader extends StatelessWidget {
return Tooltip( return Tooltip(
message: LocaleKeys.menuAppHeader_addPageTooltip.tr(), message: LocaleKeys.menuAppHeader_addPageTooltip.tr(),
child: AddButton( child: AddButton(
onSelected: (viewType) { onSelected: (pluginBuilder) {
context context.read<AppBloc>().add(AppEvent.createView(
.read<AppBloc>() LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
.add(AppEvent.createView(LocaleKeys.menuAppHeader_defaultNewPageName.tr(), "", viewType)); "",
pluginBuilder.dataType,
));
}, },
).padding(right: MenuAppSizes.headerPadding), ).padding(right: MenuAppSizes.headerPadding),
); );

View File

@ -1,6 +1,7 @@
import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/view/view_bloc.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/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:app_flowy/workspace/presentation/widgets/dialogs.dart';
import 'package:dartz/dartz.dart' as dartz; import 'package:dartz/dartz.dart' as dartz;
import 'package:easy_localization/easy_localization.dart'; 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/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:styled_widget/styled_widget.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/workspace/presentation/widgets/menu/widget/app/menu_app.dart';
import 'package:app_flowy/generated/locale_keys.g.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) { Widget _render(BuildContext context, bool onHover, ViewState state, Color iconColor) {
List<Widget> children = [ 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), const HSpace(2),
Expanded(child: FlowyText.regular(state.view.name, fontSize: 12, overflow: TextOverflow.clip)), Expanded(child: FlowyText.regular(state.view.name, fontSize: 12, overflow: TextOverflow.clip)),
]; ];

View File

@ -106,7 +106,7 @@ class ViewSectionNotifier with ChangeNotifier {
if (view != null) { if (view != null) {
WidgetsBinding.instance?.addPostFrameCallback((_) { WidgetsBinding.instance?.addPostFrameCallback((_) {
getIt<HomeStackManager>().setStack(view.stackContext()); getIt<HomeStackManager>().setPlugin(view.stackContext());
}); });
} else { } else {
// do nothing // do nothing

View File

@ -1,7 +1,8 @@
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/startup/startup.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/application/appearance.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.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:app_flowy/workspace/presentation/widgets/menu/menu.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/image.dart';
@ -22,7 +23,7 @@ class MenuTrash extends StatelessWidget {
child: InkWell( child: InkWell(
onTap: () { onTap: () {
Provider.of<MenuSharedState>(context, listen: false).selectedView.value = null; Provider.of<MenuSharedState>(context, listen: false).selectedView.value = null;
getIt<HomeStackManager>().setStack(TrashStackContext()); getIt<HomeStackManager>().setPlugin(makePlugin(pluginType: DefaultPluginEnum.trash.type()));
}, },
child: _render(context), child: _render(context),
), ),

View File

@ -20,11 +20,13 @@ class View extends $pb.GeneratedMessage {
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongToId') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongToId')
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') ..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') ..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) ..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(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'modifiedTime')
..aInt64(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'createTime') ..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 ..hasRequiredFields = false
; ;
@ -34,11 +36,13 @@ class View extends $pb.GeneratedMessage {
$core.String? belongToId, $core.String? belongToId,
$core.String? name, $core.String? name,
$core.String? desc, $core.String? desc,
ViewType? viewType, ViewDataType? dataType,
$fixnum.Int64? version, $fixnum.Int64? version,
RepeatedView? belongings, RepeatedView? belongings,
$fixnum.Int64? modifiedTime, $fixnum.Int64? modifiedTime,
$fixnum.Int64? createTime, $fixnum.Int64? createTime,
$core.String? extData,
$core.String? thumbnail,
}) { }) {
final _result = create(); final _result = create();
if (id != null) { if (id != null) {
@ -53,8 +57,8 @@ class View extends $pb.GeneratedMessage {
if (desc != null) { if (desc != null) {
_result.desc = desc; _result.desc = desc;
} }
if (viewType != null) { if (dataType != null) {
_result.viewType = viewType; _result.dataType = dataType;
} }
if (version != null) { if (version != null) {
_result.version = version; _result.version = version;
@ -68,6 +72,12 @@ class View extends $pb.GeneratedMessage {
if (createTime != null) { if (createTime != null) {
_result.createTime = createTime; _result.createTime = createTime;
} }
if (extData != null) {
_result.extData = extData;
}
if (thumbnail != null) {
_result.thumbnail = thumbnail;
}
return _result; return _result;
} }
factory View.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); 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); void clearDesc() => clearField(4);
@$pb.TagNumber(5) @$pb.TagNumber(5)
ViewType get viewType => $_getN(4); ViewDataType get dataType => $_getN(4);
@$pb.TagNumber(5) @$pb.TagNumber(5)
set viewType(ViewType v) { setField(5, v); } set dataType(ViewDataType v) { setField(5, v); }
@$pb.TagNumber(5) @$pb.TagNumber(5)
$core.bool hasViewType() => $_has(4); $core.bool hasDataType() => $_has(4);
@$pb.TagNumber(5) @$pb.TagNumber(5)
void clearViewType() => clearField(5); void clearDataType() => clearField(5);
@$pb.TagNumber(6) @$pb.TagNumber(6)
$fixnum.Int64 get version => $_getI64(5); $fixnum.Int64 get version => $_getI64(5);
@ -173,6 +183,24 @@ class View extends $pb.GeneratedMessage {
$core.bool hasCreateTime() => $_has(8); $core.bool hasCreateTime() => $_has(8);
@$pb.TagNumber(9) @$pb.TagNumber(9)
void clearCreateTime() => clearField(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 { 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(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') ..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) ..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') ? '' : 'ext') ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData')
..hasRequiredFields = false ..hasRequiredFields = false
; ;
@ -243,8 +271,8 @@ class CreateViewPayload extends $pb.GeneratedMessage {
$core.String? name, $core.String? name,
$core.String? desc, $core.String? desc,
$core.String? thumbnail, $core.String? thumbnail,
ViewType? viewType, ViewDataType? dataType,
$core.String? ext, $core.String? extData,
}) { }) {
final _result = create(); final _result = create();
if (belongToId != null) { if (belongToId != null) {
@ -259,11 +287,11 @@ class CreateViewPayload extends $pb.GeneratedMessage {
if (thumbnail != null) { if (thumbnail != null) {
_result.thumbnail = thumbnail; _result.thumbnail = thumbnail;
} }
if (viewType != null) { if (dataType != null) {
_result.viewType = viewType; _result.dataType = dataType;
} }
if (ext != null) { if (extData != null) {
_result.ext = ext; _result.extData = extData;
} }
return _result; return _result;
} }
@ -328,22 +356,22 @@ class CreateViewPayload extends $pb.GeneratedMessage {
void clearThumbnail() => clearField(4); void clearThumbnail() => clearField(4);
@$pb.TagNumber(5) @$pb.TagNumber(5)
ViewType get viewType => $_getN(4); ViewDataType get dataType => $_getN(4);
@$pb.TagNumber(5) @$pb.TagNumber(5)
set viewType(ViewType v) { setField(5, v); } set dataType(ViewDataType v) { setField(5, v); }
@$pb.TagNumber(5) @$pb.TagNumber(5)
$core.bool hasViewType() => $_has(4); $core.bool hasDataType() => $_has(4);
@$pb.TagNumber(5) @$pb.TagNumber(5)
void clearViewType() => clearField(5); void clearDataType() => clearField(5);
@$pb.TagNumber(6) @$pb.TagNumber(6)
$core.String get ext => $_getSZ(5); $core.String get extData => $_getSZ(5);
@$pb.TagNumber(6) @$pb.TagNumber(6)
set ext($core.String v) { $_setString(5, v); } set extData($core.String v) { $_setString(5, v); }
@$pb.TagNumber(6) @$pb.TagNumber(6)
$core.bool hasExt() => $_has(5); $core.bool hasExtData() => $_has(5);
@$pb.TagNumber(6) @$pb.TagNumber(6)
void clearExt() => clearField(6); void clearExtData() => clearField(6);
} }
class CreateViewParams extends $pb.GeneratedMessage { 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(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') ..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) ..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') ? '' : 'ext') ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData')
..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId') ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId')
..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data')
..hasRequiredFields = false ..hasRequiredFields = false
; ;
@ -364,9 +393,10 @@ class CreateViewParams extends $pb.GeneratedMessage {
$core.String? name, $core.String? name,
$core.String? desc, $core.String? desc,
$core.String? thumbnail, $core.String? thumbnail,
ViewType? viewType, ViewDataType? dataType,
$core.String? ext, $core.String? extData,
$core.String? viewId, $core.String? viewId,
$core.String? data,
}) { }) {
final _result = create(); final _result = create();
if (belongToId != null) { if (belongToId != null) {
@ -381,15 +411,18 @@ class CreateViewParams extends $pb.GeneratedMessage {
if (thumbnail != null) { if (thumbnail != null) {
_result.thumbnail = thumbnail; _result.thumbnail = thumbnail;
} }
if (viewType != null) { if (dataType != null) {
_result.viewType = viewType; _result.dataType = dataType;
} }
if (ext != null) { if (extData != null) {
_result.ext = ext; _result.extData = extData;
} }
if (viewId != null) { if (viewId != null) {
_result.viewId = viewId; _result.viewId = viewId;
} }
if (data != null) {
_result.data = data;
}
return _result; return _result;
} }
factory CreateViewParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); 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); void clearThumbnail() => clearField(4);
@$pb.TagNumber(5) @$pb.TagNumber(5)
ViewType get viewType => $_getN(4); ViewDataType get dataType => $_getN(4);
@$pb.TagNumber(5) @$pb.TagNumber(5)
set viewType(ViewType v) { setField(5, v); } set dataType(ViewDataType v) { setField(5, v); }
@$pb.TagNumber(5) @$pb.TagNumber(5)
$core.bool hasViewType() => $_has(4); $core.bool hasDataType() => $_has(4);
@$pb.TagNumber(5) @$pb.TagNumber(5)
void clearViewType() => clearField(5); void clearDataType() => clearField(5);
@$pb.TagNumber(6) @$pb.TagNumber(6)
$core.String get ext => $_getSZ(5); $core.String get extData => $_getSZ(5);
@$pb.TagNumber(6) @$pb.TagNumber(6)
set ext($core.String v) { $_setString(5, v); } set extData($core.String v) { $_setString(5, v); }
@$pb.TagNumber(6) @$pb.TagNumber(6)
$core.bool hasExt() => $_has(5); $core.bool hasExtData() => $_has(5);
@$pb.TagNumber(6) @$pb.TagNumber(6)
void clearExt() => clearField(6); void clearExtData() => clearField(6);
@$pb.TagNumber(7) @$pb.TagNumber(7)
$core.String get viewId => $_getSZ(6); $core.String get viewId => $_getSZ(6);
@ -475,6 +508,15 @@ class CreateViewParams extends $pb.GeneratedMessage {
$core.bool hasViewId() => $_has(6); $core.bool hasViewId() => $_has(6);
@$pb.TagNumber(7) @$pb.TagNumber(7)
void clearViewId() => clearField(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 { class ViewId extends $pb.GeneratedMessage {

View File

@ -9,18 +9,18 @@
import 'dart:core' as $core; import 'dart:core' as $core;
import 'package:protobuf/protobuf.dart' as $pb; import 'package:protobuf/protobuf.dart' as $pb;
class ViewType extends $pb.ProtobufEnum { class ViewDataType extends $pb.ProtobufEnum {
static const ViewType RichText = ViewType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RichText'); static const ViewDataType RichText = ViewDataType._(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'); 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, RichText,
PlainText, PlainText,
]; ];
static final $core.Map<$core.int, ViewType> _byValue = $pb.ProtobufEnum.initByValue(values); static final $core.Map<$core.int, ViewDataType> _byValue = $pb.ProtobufEnum.initByValue(values);
static ViewType? valueOf($core.int value) => _byValue[value]; 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);
} }

View File

@ -8,17 +8,17 @@
import 'dart:core' as $core; import 'dart:core' as $core;
import 'dart:convert' as $convert; import 'dart:convert' as $convert;
import 'dart:typed_data' as $typed_data; import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use viewTypeDescriptor instead') @$core.Deprecated('Use viewDataTypeDescriptor instead')
const ViewType$json = const { const ViewDataType$json = const {
'1': 'ViewType', '1': 'ViewDataType',
'2': const [ '2': const [
const {'1': 'RichText', '2': 0}, const {'1': 'RichText', '2': 0},
const {'1': 'PlainText', '2': 1}, const {'1': 'PlainText', '2': 1},
], ],
}; };
/// Descriptor for `ViewType`. Decode as a `google.protobuf.EnumDescriptorProto`. /// Descriptor for `ViewDataType`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List viewTypeDescriptor = $convert.base64Decode('CghWaWV3VHlwZRIMCghSaWNoVGV4dBAAEg0KCVBsYWluVGV4dBAB'); final $typed_data.Uint8List viewDataTypeDescriptor = $convert.base64Decode('CgxWaWV3RGF0YVR5cGUSDAoIUmljaFRleHQQABINCglQbGFpblRleHQQAQ==');
@$core.Deprecated('Use viewDescriptor instead') @$core.Deprecated('Use viewDescriptor instead')
const View$json = const { const View$json = const {
'1': 'View', '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': 'belong_to_id', '3': 2, '4': 1, '5': 9, '10': 'belongToId'},
const {'1': 'name', '3': 3, '4': 1, '5': 9, '10': 'name'}, const {'1': 'name', '3': 3, '4': 1, '5': 9, '10': 'name'},
const {'1': 'desc', '3': 4, '4': 1, '5': 9, '10': 'desc'}, 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': 'version', '3': 6, '4': 1, '5': 3, '10': 'version'},
const {'1': 'belongings', '3': 7, '4': 1, '5': 11, '6': '.RepeatedView', '10': 'belongings'}, 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': 'modified_time', '3': 8, '4': 1, '5': 3, '10': 'modifiedTime'},
const {'1': 'create_time', '3': 9, '4': 1, '5': 3, '10': 'createTime'}, 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`. /// 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') @$core.Deprecated('Use repeatedViewDescriptor instead')
const RepeatedView$json = const { const RepeatedView$json = const {
'1': 'RepeatedView', '1': 'RepeatedView',
@ -55,8 +57,8 @@ const CreateViewPayload$json = const {
const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'}, 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': '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': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'},
const {'1': 'ext', '3': 6, '4': 1, '5': 9, '10': 'ext'}, const {'1': 'ext_data', '3': 6, '4': 1, '5': 9, '10': 'extData'},
], ],
'8': const [ '8': const [
const {'1': 'one_of_thumbnail'}, const {'1': 'one_of_thumbnail'},
@ -64,7 +66,7 @@ const CreateViewPayload$json = const {
}; };
/// Descriptor for `CreateViewPayload`. Decode as a `google.protobuf.DescriptorProto`. /// 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') @$core.Deprecated('Use createViewParamsDescriptor instead')
const CreateViewParams$json = const { const CreateViewParams$json = const {
'1': 'CreateViewParams', '1': 'CreateViewParams',
@ -73,14 +75,15 @@ const CreateViewParams$json = const {
const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'}, const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'},
const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '10': 'thumbnail'}, 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': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'},
const {'1': 'ext', '3': 6, '4': 1, '5': 9, '10': 'ext'}, 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': '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`. /// 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') @$core.Deprecated('Use viewIdDescriptor instead')
const ViewId$json = const { const ViewId$json = const {
'1': 'ViewId', '1': 'ViewId',

View File

@ -8,7 +8,7 @@ use flowy_collaboration::{
errors::CollaborateError, errors::CollaborateError,
}; };
use flowy_error::{FlowyError, FlowyResult}; 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 futures::stream::StreamExt;
use lib_ot::{ use lib_ot::{
core::{Interval, OperationTransformable}, core::{Interval, OperationTransformable},
@ -102,7 +102,7 @@ impl EditBlockQueue {
server_prime = Some(s_prime); server_prime = Some(s_prime);
} }
drop(read_guard); drop(read_guard);
Ok::<TransformDeltas<RichTextAttributes>, CollaborateError>(TransformDeltas { Ok::<RichTextTransformDeltas, CollaborateError>(TransformDeltas {
client_prime, client_prime,
server_prime, server_prime,
}) })
@ -232,7 +232,7 @@ pub(crate) enum EditorCommand {
}, },
TransformDelta { TransformDelta {
delta: RichTextDelta, delta: RichTextDelta,
ret: Ret<TransformDeltas<RichTextAttributes>>, ret: Ret<RichTextTransformDeltas>,
}, },
Insert { Insert {
index: usize, index: usize,

View File

@ -10,7 +10,8 @@ use flowy_collaboration::{
use flowy_error::{internal_error, FlowyError}; use flowy_error::{internal_error, FlowyError};
use flowy_sync::*; use flowy_sync::*;
use lib_infra::future::{BoxResultFuture, FutureResult}; 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 lib_ws::WSConnectState;
use std::{sync::Arc, time::Duration}; use std::{sync::Arc, time::Duration};
use tokio::sync::{ use tokio::sync::{
@ -31,12 +32,8 @@ pub(crate) async fn make_block_ws_manager(
) -> Arc<RevisionWebSocketManager> { ) -> Arc<RevisionWebSocketManager> {
let ws_data_provider = Arc::new(WSDataProvider::new(&doc_id, Arc::new(rev_manager.clone()))); let ws_data_provider = Arc::new(WSDataProvider::new(&doc_id, Arc::new(rev_manager.clone())));
let resolver = Arc::new(BlockConflictResolver { edit_cmd_tx }); let resolver = Arc::new(BlockConflictResolver { edit_cmd_tx });
let conflict_controller = ConflictController::<RichTextAttributes>::new( let conflict_controller =
&user_id, RichTextConflictController::new(&user_id, resolver, Arc::new(ws_data_provider.clone()), rev_manager);
resolver,
Arc::new(ws_data_provider.clone()),
rev_manager,
);
let ws_data_stream = Arc::new(BlockRevisionWSDataStream::new(conflict_controller)); let ws_data_stream = Arc::new(BlockRevisionWSDataStream::new(conflict_controller));
let ws_data_sink = Arc::new(BlockWSDataSink(ws_data_provider)); let ws_data_sink = Arc::new(BlockWSDataSink(ws_data_provider));
let ping_duration = Duration::from_millis(DOCUMENT_SYNC_INTERVAL_IN_MILLIS); let ping_duration = Duration::from_millis(DOCUMENT_SYNC_INTERVAL_IN_MILLIS);
@ -66,11 +63,11 @@ fn listen_document_ws_state(_user_id: &str, _doc_id: &str, mut subscriber: broad
} }
pub(crate) struct BlockRevisionWSDataStream { pub(crate) struct BlockRevisionWSDataStream {
conflict_controller: Arc<ConflictController<RichTextAttributes>>, conflict_controller: Arc<RichTextConflictController>,
} }
impl BlockRevisionWSDataStream { impl BlockRevisionWSDataStream {
pub fn new(conflict_controller: ConflictController<RichTextAttributes>) -> Self { pub fn new(conflict_controller: RichTextConflictController) -> Self {
Self { Self {
conflict_controller: Arc::new(conflict_controller), conflict_controller: Arc::new(conflict_controller),
} }
@ -112,7 +109,7 @@ struct BlockConflictResolver {
} }
impl ConflictResolver<RichTextAttributes> for 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(); let tx = self.edit_cmd_tx.clone();
Box::pin(async move { Box::pin(async move {
let (ret, rx) = oneshot::channel(); let (ret, rx) = oneshot::channel();
@ -131,11 +128,11 @@ impl ConflictResolver<RichTextAttributes> for BlockConflictResolver {
fn transform_delta( fn transform_delta(
&self, &self,
delta: Delta<RichTextAttributes>, delta: RichTextDelta,
) -> BoxResultFuture<flowy_sync::TransformDeltas<RichTextAttributes>, FlowyError> { ) -> BoxResultFuture<flowy_sync::RichTextTransformDeltas, FlowyError> {
let tx = self.edit_cmd_tx.clone(); let tx = self.edit_cmd_tx.clone();
Box::pin(async move { 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 }) tx.send(EditorCommand::TransformDelta { delta, ret })
.await .await
.map_err(internal_error)?; .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(); let tx = self.edit_cmd_tx.clone();
Box::pin(async move { Box::pin(async move {
let (ret, rx) = oneshot::channel(); let (ret, rx) = oneshot::channel();

View File

@ -12,7 +12,7 @@ use flowy_sync::{
RevisionWebSocket, RevisionWebSocketManager, RevisionWebSocket, RevisionWebSocketManager,
}; };
use lib_infra::future::FutureResult; use lib_infra::future::FutureResult;
use lib_ot::core::PlainAttributes; use lib_ot::core::PlainTextAttributes;
use lib_sqlite::ConnectionPool; use lib_sqlite::ConnectionPool;
use parking_lot::RwLock; use parking_lot::RwLock;
use std::sync::Arc; use std::sync::Arc;
@ -144,7 +144,7 @@ impl RevisionCompact for FolderRevisionCompact {
let (base_rev_id, rev_id) = first_revision.pair_rev_id(); let (base_rev_id, rev_id) = first_revision.pair_rev_id();
let md5 = last_revision.md5.clone(); 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(); let delta_data = delta.to_bytes();
Ok(Revision::new(object_id, base_rev_id, rev_id, delta_data, user_id, md5)) Ok(Revision::new(object_id, base_rev_id, rev_id, delta_data, user_id, md5))
} }

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
entities::{ entities::{
trash::{Trash, TrashType}, trash::{Trash, TrashType},
view::{RepeatedView, UpdateViewParams, View, ViewType}, view::{RepeatedView, UpdateViewParams, View, ViewDataType},
}, },
errors::FlowyError, errors::FlowyError,
services::persistence::version_1::app_sql::AppTable, services::persistence::version_1::app_sql::AppTable,
@ -119,16 +119,16 @@ pub(crate) struct ViewTable {
pub modified_time: i64, pub modified_time: i64,
pub create_time: i64, pub create_time: i64,
pub thumbnail: String, pub thumbnail: String,
pub view_type: ViewTableType, pub view_type: SqlViewDataType,
pub version: i64, pub version: i64,
pub is_trash: bool, pub is_trash: bool,
} }
impl ViewTable { impl ViewTable {
pub fn new(view: View) -> Self { pub fn new(view: View) -> Self {
let view_type = match view.view_type { let data_type = match view.data_type {
ViewType::RichText => ViewTableType::RichText, ViewDataType::RichText => SqlViewDataType::RichText,
ViewType::PlainText => ViewTableType::Text, ViewDataType::PlainText => SqlViewDataType::PlainText,
}; };
ViewTable { ViewTable {
@ -138,9 +138,8 @@ impl ViewTable {
desc: view.desc, desc: view.desc,
modified_time: view.modified_time, modified_time: view.modified_time,
create_time: view.create_time, create_time: view.create_time,
// TODO: thumbnail thumbnail: view.thumbnail,
thumbnail: "".to_owned(), view_type: data_type,
view_type,
version: 0, version: 0,
is_trash: false, is_trash: false,
} }
@ -149,9 +148,9 @@ impl ViewTable {
impl std::convert::From<ViewTable> for View { impl std::convert::From<ViewTable> for View {
fn from(table: ViewTable) -> Self { fn from(table: ViewTable) -> Self {
let view_type = match table.view_type { let data_type = match table.view_type {
ViewTableType::RichText => ViewType::RichText, SqlViewDataType::RichText => ViewDataType::RichText,
ViewTableType::Text => ViewType::PlainText, SqlViewDataType::PlainText => ViewDataType::PlainText,
}; };
View { View {
@ -159,11 +158,13 @@ impl std::convert::From<ViewTable> for View {
belong_to_id: table.belong_to_id, belong_to_id: table.belong_to_id,
name: table.name, name: table.name,
desc: table.desc, desc: table.desc,
view_type, data_type,
belongings: RepeatedView::default(), belongings: RepeatedView::default(),
modified_time: table.modified_time, modified_time: table.modified_time,
version: table.version, version: table.version,
create_time: table.create_time, 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)] #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, FromSqlRow, AsExpression)]
#[repr(i32)] #[repr(i32)]
#[sql_type = "Integer"] #[sql_type = "Integer"]
pub enum ViewTableType { pub enum SqlViewDataType {
RichText = 0, RichText = 0,
Text = 1, PlainText = 1,
} }
impl std::default::Default for ViewTableType { impl std::default::Default for SqlViewDataType {
fn default() -> Self { 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 { fn from(value: i32) -> Self {
match value { match value {
0 => ViewTableType::RichText, 0 => SqlViewDataType::RichText,
1 => ViewTableType::Text, 1 => SqlViewDataType::PlainText,
o => { o => {
log::error!("Unsupported view type {}, fallback to ViewType::Docs", o); log::error!("Unsupported view type {}, fallback to ViewType::Docs", o);
ViewTableType::Text SqlViewDataType::PlainText
} }
} }
} }
} }
impl ViewTableType { impl SqlViewDataType {
pub fn value(&self) -> i32 { pub fn value(&self) -> i32 {
*self as i32 *self as i32
} }
} }
impl_sql_integer_expression!(ViewTableType); impl_sql_integer_expression!(SqlViewDataType);

View File

@ -24,7 +24,7 @@ use crate::{
use flowy_database::kv::KV; use flowy_database::kv::KV;
use flowy_document::BlockManager; use flowy_document::BlockManager;
use flowy_folder_data_model::entities::share::{ExportData, ExportParams}; use flowy_folder_data_model::entities::share::{ExportData, ExportParams};
use flowy_folder_data_model::entities::view::ViewType;
use lib_infra::uuid_string; use lib_infra::uuid_string;
const LATEST_VIEW_ID: &str = "latest_view_id"; 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)] #[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> { 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() initial_delta_string()
} else { } else {
params.ext.clone() params.data.clone()
}; };
let delta_data = Bytes::from(view_data); let delta_data = Bytes::from(view_data);
@ -78,12 +78,11 @@ impl ViewController {
Ok(view) 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( pub(crate) async fn create_view(
&self, &self,
view_id: &str, view_id: &str,
repeated_revision: RepeatedRevision, repeated_revision: RepeatedRevision,
view_type: ViewType,
) -> Result<(), FlowyError> { ) -> Result<(), FlowyError> {
if repeated_revision.is_empty() { if repeated_revision.is_empty() {
return Err(FlowyError::internal().context("The content of the view should not be 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 { let duplicate_params = CreateViewParams {
belong_to_id: view.belong_to_id.clone(), belong_to_id: view.belong_to_id.clone(),
name: format!("{} (copy)", &view.name), name: format!("{} (copy)", &view.name),
desc: view.desc.clone(), desc: view.desc,
thumbnail: "".to_owned(), thumbnail: view.thumbnail,
view_type: view.view_type.clone(), data_type: view.data_type,
ext: document_json, data: document_json,
view_id: uuid_string(), view_id: uuid_string(),
ext_data: view.ext_data,
}; };
let _ = self.create_view_from_params(duplicate_params).await?; let _ = self.create_view_from_params(duplicate_params).await?;

View File

@ -10,7 +10,7 @@ use flowy_collaboration::{
use flowy_error::FlowyError; use flowy_error::FlowyError;
use flowy_sync::*; use flowy_sync::*;
use lib_infra::future::{BoxResultFuture, FutureResult}; 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 parking_lot::RwLock;
use std::{sync::Arc, time::Duration}; use std::{sync::Arc, time::Duration};
@ -23,8 +23,12 @@ pub(crate) async fn make_folder_ws_manager(
) -> Arc<RevisionWebSocketManager> { ) -> Arc<RevisionWebSocketManager> {
let ws_data_provider = Arc::new(WSDataProvider::new(folder_id, Arc::new(rev_manager.clone()))); let ws_data_provider = Arc::new(WSDataProvider::new(folder_id, Arc::new(rev_manager.clone())));
let resolver = Arc::new(FolderConflictResolver { folder_pad }); let resolver = Arc::new(FolderConflictResolver { folder_pad });
let conflict_controller = let conflict_controller = ConflictController::<PlainTextAttributes>::new(
ConflictController::<PlainAttributes>::new(user_id, resolver, Arc::new(ws_data_provider.clone()), rev_manager); user_id,
resolver,
Arc::new(ws_data_provider.clone()),
rev_manager,
);
let ws_data_stream = Arc::new(FolderRevisionWSDataStream::new(conflict_controller)); let ws_data_stream = Arc::new(FolderRevisionWSDataStream::new(conflict_controller));
let ws_data_sink = Arc::new(FolderWSDataSink(ws_data_provider)); let ws_data_sink = Arc::new(FolderWSDataSink(ws_data_provider));
let ping_duration = Duration::from_millis(FOLDER_SYNC_INTERVAL_IN_MILLIS); let ping_duration = Duration::from_millis(FOLDER_SYNC_INTERVAL_IN_MILLIS);
@ -50,8 +54,8 @@ struct FolderConflictResolver {
folder_pad: Arc<RwLock<FolderPad>>, folder_pad: Arc<RwLock<FolderPad>>,
} }
impl ConflictResolver<PlainAttributes> for FolderConflictResolver { impl ConflictResolver<PlainTextAttributes> for FolderConflictResolver {
fn compose_delta(&self, delta: Delta<PlainAttributes>) -> BoxResultFuture<DeltaMD5, FlowyError> { fn compose_delta(&self, delta: PlainTextDelta) -> BoxResultFuture<DeltaMD5, FlowyError> {
let folder_pad = self.folder_pad.clone(); let folder_pad = self.folder_pad.clone();
Box::pin(async move { Box::pin(async move {
let md5 = folder_pad.write().compose_remote_delta(delta)?; let md5 = folder_pad.write().compose_remote_delta(delta)?;
@ -61,13 +65,13 @@ impl ConflictResolver<PlainAttributes> for FolderConflictResolver {
fn transform_delta( fn transform_delta(
&self, &self,
delta: Delta<PlainAttributes>, delta: PlainTextDelta,
) -> BoxResultFuture<TransformDeltas<PlainAttributes>, FlowyError> { ) -> BoxResultFuture<TransformDeltas<PlainTextAttributes>, FlowyError> {
let folder_pad = self.folder_pad.clone(); let folder_pad = self.folder_pad.clone();
Box::pin(async move { Box::pin(async move {
let read_guard = folder_pad.read(); let read_guard = folder_pad.read();
let mut server_prime: Option<PlainDelta> = None; let mut server_prime: Option<PlainTextDelta> = None;
let client_prime: PlainDelta; let client_prime: PlainTextDelta;
if read_guard.is_empty() { if read_guard.is_empty() {
// Do nothing // Do nothing
client_prime = delta; 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(); let folder_pad = self.folder_pad.clone();
Box::pin(async move { Box::pin(async move {
let md5 = folder_pad.write().reset_folder(delta)?; let md5 = folder_pad.write().reset_folder(delta)?;
@ -94,11 +98,11 @@ impl ConflictResolver<PlainAttributes> for FolderConflictResolver {
} }
struct FolderRevisionWSDataStream { struct FolderRevisionWSDataStream {
conflict_controller: Arc<ConflictController<PlainAttributes>>, conflict_controller: Arc<PlainTextConflictController>,
} }
impl FolderRevisionWSDataStream { impl FolderRevisionWSDataStream {
pub fn new(conflict_controller: ConflictController<PlainAttributes>) -> Self { pub fn new(conflict_controller: PlainTextConflictController) -> Self {
Self { Self {
conflict_controller: Arc::new(conflict_controller), conflict_controller: Arc::new(conflict_controller),
} }

View File

@ -5,7 +5,7 @@ use flowy_folder_data_model::entities::workspace::WorkspaceId;
use flowy_folder_data_model::entities::{ use flowy_folder_data_model::entities::{
app::{App, AppId, CreateAppPayload, UpdateAppPayload}, app::{App, AppId, CreateAppPayload, UpdateAppPayload},
trash::{RepeatedTrash, TrashId, TrashType}, trash::{RepeatedTrash, TrashId, TrashType},
view::{CreateViewPayload, UpdateViewPayload, View, ViewType}, view::{CreateViewPayload, UpdateViewPayload, View, ViewDataType},
workspace::{CreateWorkspacePayload, RepeatedWorkspace, Workspace}, workspace::{CreateWorkspacePayload, RepeatedWorkspace, Workspace},
}; };
use flowy_test::{event_builder::*, FlowySDKTest}; use flowy_test::{event_builder::*, FlowySDKTest};
@ -109,13 +109,14 @@ pub async fn delete_app(sdk: &FlowySDKTest, app_id: &str) {
.await; .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 { let request = CreateViewPayload {
belong_to_id: app_id.to_string(), belong_to_id: app_id.to_string(),
name: name.to_string(), name: name.to_string(),
desc: desc.to_string(), desc: desc.to_string(),
thumbnail: None, thumbnail: None,
view_type, data_type: view_type,
ext_data: "".to_string(),
}; };
let view = FolderEventBuilder::new(sdk.clone()) let view = FolderEventBuilder::new(sdk.clone())
.event(CreateView) .event(CreateView)

View File

@ -4,7 +4,7 @@ use flowy_folder::{errors::ErrorCode, services::folder_editor::ClientFolderEdito
use flowy_folder_data_model::entities::{ use flowy_folder_data_model::entities::{
app::{App, RepeatedApp}, app::{App, RepeatedApp},
trash::Trash, trash::Trash,
view::{RepeatedView, View, ViewType}, view::{RepeatedView, View, ViewDataType},
workspace::Workspace, workspace::Workspace,
}; };
use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS;
@ -68,7 +68,7 @@ impl FolderTest {
let _ = sdk.init_user().await; let _ = sdk.init_user().await;
let mut workspace = create_workspace(&sdk, "FolderWorkspace", "Folder test workspace").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 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 { app.belongings = RepeatedView {
items: vec![view.clone()], items: vec![view.clone()],
}; };
@ -146,7 +146,7 @@ impl FolderTest {
} }
FolderScript::CreateView { name, desc } => { 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; self.view = view;
} }
FolderScript::AssertView(view) => { FolderScript::AssertView(view) => {

View File

@ -300,11 +300,13 @@ impl FolderCouldServiceV1 for LocalServer {
belong_to_id: params.belong_to_id, belong_to_id: params.belong_to_id,
name: params.name, name: params.name,
desc: params.desc, desc: params.desc,
view_type: params.view_type, data_type: params.data_type,
version: 0, version: 0,
belongings: RepeatedView::default(), belongings: RepeatedView::default(),
modified_time: time, modified_time: time,
create_time: time, create_time: time,
ext_data: params.ext_data,
thumbnail: params.thumbnail,
}; };
FutureResult::new(async { Ok(view) }) FutureResult::new(async { Ok(view) })
} }

View File

@ -9,7 +9,8 @@ use flowy_collaboration::{
}; };
use flowy_error::{FlowyError, FlowyResult}; use flowy_error::{FlowyError, FlowyResult};
use lib_infra::future::BoxResultFuture; 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 serde::de::DeserializeOwned;
use std::{convert::TryFrom, sync::Arc}; 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>; fn ack(&self, rev_id: String, ty: ServerRevisionWSDataType) -> BoxResultFuture<(), FlowyError>;
} }
pub type RichTextConflictController = ConflictController<RichTextAttributes>;
pub type PlainTextConflictController = ConflictController<PlainTextAttributes>;
pub struct ConflictController<T> pub struct ConflictController<T>
where where
T: Attributes + Send + Sync, T: Attributes + Send + Sync,
@ -171,6 +175,8 @@ where
} }
} }
pub type RichTextTransformDeltas = TransformDeltas<RichTextAttributes>;
pub struct TransformDeltas<T> pub struct TransformDeltas<T>
where where
T: Attributes, T: Attributes,

View File

@ -88,7 +88,8 @@ async fn create_view(sdk: &FlowySDKTest, app_id: &str) -> View {
name: "View A".to_string(), name: "View A".to_string(),
desc: "".to_string(), desc: "".to_string(),
thumbnail: Some("http://1.png".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()) let view = FolderEventBuilder::new(sdk.clone())

View File

@ -6,7 +6,7 @@ use crate::{
errors::{CollaborateError, CollaborateResult}, errors::{CollaborateError, CollaborateResult},
}; };
use flowy_folder_data_model::entities::{trash::Trash, workspace::Workspace}; 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 serde::{Deserialize, Serialize};
use std::sync::Arc; use std::sync::Arc;
@ -34,7 +34,7 @@ impl FolderPadBuilder {
self 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() { if delta.is_empty() {
delta = default_folder_delta(); delta = default_folder_delta();
} }
@ -47,7 +47,7 @@ impl FolderPadBuilder {
} }
pub(crate) fn build_with_revisions(self, revisions: Vec<Revision>) -> CollaborateResult<FolderPad> { 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) self.build_with_delta(folder_delta)
} }
@ -57,7 +57,7 @@ impl FolderPadBuilder {
Ok(FolderPad { Ok(FolderPad {
workspaces: self.workspaces, workspaces: self.workspaces,
trash: self.trash, trash: self.trash,
root: PlainDeltaBuilder::new().insert(&json).build(), root: PlainTextDeltaBuilder::new().insert(&json).build(),
}) })
} }
} }

View File

@ -8,7 +8,7 @@ use crate::{
}; };
use dissimilar::*; use dissimilar::*;
use flowy_folder_data_model::entities::{app::App, trash::Trash, view::View, workspace::Workspace}; 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 serde::{Deserialize, Serialize};
use std::sync::Arc; use std::sync::Arc;
@ -21,7 +21,7 @@ pub struct FolderPad {
} }
pub fn default_folder_delta() -> FolderDelta { pub fn default_folder_delta() -> FolderDelta {
PlainDeltaBuilder::new() PlainTextDeltaBuilder::new()
.insert(r#"{"workspaces":[],"trash":[]}"#) .insert(r#"{"workspaces":[],"trash":[]}"#)
.build() .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 chunks = dissimilar::diff(&old, &new);
let mut delta_builder = PlainDeltaBuilder::new(); let mut delta_builder = PlainTextDeltaBuilder::new();
for chunk in &chunks { for chunk in &chunks {
match chunk { match chunk {
Chunk::Equal(s) => { Chunk::Equal(s) => {
@ -410,7 +410,7 @@ mod tests {
use crate::{client_folder::folder_pad::FolderPad, entities::folder_info::FolderDelta}; use crate::{client_folder::folder_pad::FolderPad, entities::folder_info::FolderDelta};
use chrono::Utc; use chrono::Utc;
use flowy_folder_data_model::entities::{app::App, trash::Trash, view::View, workspace::Workspace}; 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] #[test]
fn folder_add_workspace() { fn folder_add_workspace() {
@ -725,7 +725,7 @@ mod tests {
fn test_folder() -> (FolderPad, FolderDelta, Workspace) { fn test_folder() -> (FolderPad, FolderDelta, Workspace) {
let mut folder = FolderPad::default(); let mut folder = FolderPad::default();
let folder_json = serde_json::to_string(&folder).unwrap(); 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(); let mut workspace = Workspace::default();
workspace.name = "😁 my first workspace".to_owned(); workspace.name = "😁 my first workspace".to_owned();
@ -767,7 +767,7 @@ mod tests {
fn test_trash() -> (FolderPad, FolderDelta, Trash) { fn test_trash() -> (FolderPad, FolderDelta, Trash) {
let mut folder = FolderPad::default(); let mut folder = FolderPad::default();
let folder_json = serde_json::to_string(&folder).unwrap(); 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(); let mut trash = Trash::default();
trash.name = "🚽 my first trash".to_owned(); trash.name = "🚽 my first trash".to_owned();
@ -780,7 +780,7 @@ mod tests {
(folder, delta, trash) (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 { for delta in deltas {
initial_delta = initial_delta.compose(&delta).unwrap(); initial_delta = initial_delta.compose(&delta).unwrap();
} }

View File

@ -1,7 +1,7 @@
use flowy_derive::ProtoBuf; 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)] #[derive(ProtoBuf, Default, Debug, Clone, Eq, PartialEq)]
pub struct FolderInfo { pub struct FolderInfo {

View File

@ -12,7 +12,7 @@ use crate::{
use async_stream::stream; use async_stream::stream;
use futures::stream::StreamExt; use futures::stream::StreamExt;
use lib_infra::future::BoxResultFuture; use lib_infra::future::BoxResultFuture;
use lib_ot::core::PlainAttributes; use lib_ot::core::PlainTextAttributes;
use std::{collections::HashMap, fmt::Debug, sync::Arc}; use std::{collections::HashMap, fmt::Debug, sync::Arc};
use tokio::{ use tokio::{
sync::{mpsc, oneshot, RwLock}, sync::{mpsc, oneshot, RwLock},
@ -187,7 +187,7 @@ impl ServerFolderManager {
} }
} }
type FolderRevisionSynchronizer = RevisionSynchronizer<PlainAttributes>; type FolderRevisionSynchronizer = RevisionSynchronizer<PlainTextAttributes>;
struct OpenFolderHandler { struct OpenFolderHandler {
folder_id: String, folder_id: String,

View File

@ -1,5 +1,5 @@
use crate::{entities::folder_info::FolderDelta, errors::CollaborateError, synchronizer::RevisionSyncObject}; 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 { pub struct ServerFolder {
folder_id: String, folder_id: String,
@ -15,21 +15,18 @@ impl ServerFolder {
} }
} }
impl RevisionSyncObject<PlainAttributes> for ServerFolder { impl RevisionSyncObject<PlainTextAttributes> for ServerFolder {
fn id(&self) -> &str { fn id(&self) -> &str {
&self.folder_id &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)?; let new_delta = self.delta.compose(other)?;
self.delta = new_delta; self.delta = new_delta;
Ok(()) Ok(())
} }
fn transform( fn transform(&self, other: &PlainTextDelta) -> Result<(PlainTextDelta, PlainTextDelta), CollaborateError> {
&self,
other: &Delta<PlainAttributes>,
) -> Result<(Delta<PlainAttributes>, Delta<PlainAttributes>), CollaborateError> {
let value = self.delta.transform(other)?; let value = self.delta.transform(other)?;
Ok(value) Ok(value)
} }
@ -38,7 +35,7 @@ impl RevisionSyncObject<PlainAttributes> for ServerFolder {
self.delta.to_json() 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; self.delta = new_delta;
} }
} }

View File

@ -28,7 +28,8 @@ pub struct View {
pub desc: String, pub desc: String,
#[pb(index = 5)] #[pb(index = 5)]
pub view_type: ViewType, #[serde(default)]
pub data_type: ViewDataType,
#[pb(index = 6)] #[pb(index = 6)]
pub version: i64, pub version: i64,
@ -41,6 +42,12 @@ pub struct View {
#[pb(index = 9)] #[pb(index = 9)]
pub create_time: i64, 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)] #[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)] #[derive(Eq, PartialEq, Debug, ProtoBuf_Enum, Clone, Serialize)]
pub enum ViewType { pub enum ViewDataType {
RichText = 0, RichText = 0,
PlainText = 1, PlainText = 1,
} }
impl std::default::Default for ViewType { impl std::default::Default for ViewDataType {
fn default() -> Self { 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 { fn from(val: i32) -> Self {
match val { match val {
0 => ViewType::RichText, 0 => ViewDataType::RichText,
1 => ViewType::PlainText, 1 => ViewDataType::PlainText,
_ => { _ => {
log::error!("Invalid view type: {}", val); log::error!("Invalid view type: {}", val);
ViewType::PlainText ViewDataType::PlainText
} }
} }
} }
@ -104,10 +111,10 @@ pub struct CreateViewPayload {
pub thumbnail: Option<String>, pub thumbnail: Option<String>,
#[pb(index = 5)] #[pb(index = 5)]
pub view_type: ViewType, pub data_type: ViewDataType,
#[pb(index = 6)] #[pb(index = 6)]
pub ext: String, pub ext_data: String,
} }
#[derive(Default, ProtoBuf, Debug, Clone)] #[derive(Default, ProtoBuf, Debug, Clone)]
@ -125,35 +132,16 @@ pub struct CreateViewParams {
pub thumbnail: String, pub thumbnail: String,
#[pb(index = 5)] #[pb(index = 5)]
pub view_type: ViewType, pub data_type: ViewDataType,
#[pb(index = 6)] #[pb(index = 6)]
pub ext: String, pub ext_data: String,
#[pb(index = 7)] #[pb(index = 7)]
pub view_id: String, pub view_id: String,
}
impl CreateViewParams { #[pb(index = 8)]
pub fn new( pub data: String,
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,
}
}
} }
impl TryInto<CreateViewParams> for CreateViewPayload { impl TryInto<CreateViewParams> for CreateViewPayload {
@ -163,21 +151,22 @@ impl TryInto<CreateViewParams> for CreateViewPayload {
let name = ViewName::parse(self.name)?.0; let name = ViewName::parse(self.name)?.0;
let belong_to_id = AppIdentify::parse(self.belong_to_id)?.0; let belong_to_id = AppIdentify::parse(self.belong_to_id)?.0;
let view_id = uuid::Uuid::new_v4().to_string(); 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 { let thumbnail = match self.thumbnail {
None => "".to_string(), None => "".to_string(),
Some(thumbnail) => ViewThumbnail::parse(thumbnail)?.0, Some(thumbnail) => ViewThumbnail::parse(thumbnail)?.0,
}; };
Ok(CreateViewParams::new( Ok(CreateViewParams {
belong_to_id, belong_to_id,
name, name,
self.desc, desc: self.desc,
self.view_type, data_type: self.data_type,
thumbnail, thumbnail,
ext, ext_data,
view_id, 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> fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
where where
D: Deserializer<'de>, D: Deserializer<'de>,
@ -288,7 +277,7 @@ impl<'de> Deserialize<'de> for ViewType {
struct ViewTypeVisitor(); struct ViewTypeVisitor();
impl<'de> Visitor<'de> for ViewTypeVisitor { impl<'de> Visitor<'de> for ViewTypeVisitor {
type Value = ViewType; type Value = ViewDataType;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("Plugin, RichText") formatter.write_str("Plugin, RichText")
} }
@ -301,10 +290,10 @@ impl<'de> Deserialize<'de> for ViewType {
match s { match s {
"Doc" | "RichText" => { "Doc" | "RichText" => {
// Rename ViewType::Doc to ViewType::RichText, So we need to migrate the ViewType manually. // Rename ViewType::Doc to ViewType::RichText, So we need to migrate the ViewType manually.
view_type = ViewType::RichText; view_type = ViewDataType::RichText;
} }
"Plugin" => { "Plugin" => {
view_type = ViewType::PlainText; view_type = ViewDataType::PlainText;
} }
unknown => { unknown => {
return Err(de::Error::invalid_value(Unexpected::Str(unknown), &self)); return Err(de::Error::invalid_value(Unexpected::Str(unknown), &self));

View File

@ -30,11 +30,13 @@ pub struct View {
pub belong_to_id: ::std::string::String, pub belong_to_id: ::std::string::String,
pub name: ::std::string::String, pub name: ::std::string::String,
pub desc: ::std::string::String, pub desc: ::std::string::String,
pub view_type: ViewType, pub data_type: ViewDataType,
pub version: i64, pub version: i64,
pub belongings: ::protobuf::SingularPtrField<RepeatedView>, pub belongings: ::protobuf::SingularPtrField<RepeatedView>,
pub modified_time: i64, pub modified_time: i64,
pub create_time: i64, pub create_time: i64,
pub ext_data: ::std::string::String,
pub thumbnail: ::std::string::String,
// special fields // special fields
pub unknown_fields: ::protobuf::UnknownFields, pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize, pub cached_size: ::protobuf::CachedSize,
@ -155,19 +157,19 @@ impl View {
::std::mem::replace(&mut self.desc, ::std::string::String::new()) ::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 { pub fn get_data_type(&self) -> ViewDataType {
self.view_type self.data_type
} }
pub fn clear_view_type(&mut self) { pub fn clear_data_type(&mut self) {
self.view_type = ViewType::RichText; self.data_type = ViewDataType::RichText;
} }
// Param is passed by value, moved // Param is passed by value, moved
pub fn set_view_type(&mut self, v: ViewType) { pub fn set_data_type(&mut self, v: ViewDataType) {
self.view_type = v; self.data_type = v;
} }
// int64 version = 6; // int64 version = 6;
@ -247,6 +249,58 @@ impl View {
pub fn set_create_time(&mut self, v: i64) { pub fn set_create_time(&mut self, v: i64) {
self.create_time = v; 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 { 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)?; ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.desc)?;
}, },
5 => { 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 => { 6 => {
if wire_type != ::protobuf::wire_format::WireTypeVarint { if wire_type != ::protobuf::wire_format::WireTypeVarint {
@ -302,6 +356,12 @@ impl ::protobuf::Message for View {
let tmp = is.read_int64()?; let tmp = is.read_int64()?;
self.create_time = tmp; 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())?; ::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() { if !self.desc.is_empty() {
my_size += ::protobuf::rt::string_size(4, &self.desc); my_size += ::protobuf::rt::string_size(4, &self.desc);
} }
if self.view_type != ViewType::RichText { if self.data_type != ViewDataType::RichText {
my_size += ::protobuf::rt::enum_size(5, self.view_type); my_size += ::protobuf::rt::enum_size(5, self.data_type);
} }
if self.version != 0 { if self.version != 0 {
my_size += ::protobuf::rt::value_size(6, self.version, ::protobuf::wire_format::WireTypeVarint); 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 { if self.create_time != 0 {
my_size += ::protobuf::rt::value_size(9, self.create_time, ::protobuf::wire_format::WireTypeVarint); 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()); my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size); self.cached_size.set(my_size);
my_size my_size
@ -360,8 +426,8 @@ impl ::protobuf::Message for View {
if !self.desc.is_empty() { if !self.desc.is_empty() {
os.write_string(4, &self.desc)?; os.write_string(4, &self.desc)?;
} }
if self.view_type != ViewType::RichText { if self.data_type != ViewDataType::RichText {
os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.view_type))?; os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?;
} }
if self.version != 0 { if self.version != 0 {
os.write_int64(6, self.version)?; os.write_int64(6, self.version)?;
@ -377,6 +443,12 @@ impl ::protobuf::Message for View {
if self.create_time != 0 { if self.create_time != 0 {
os.write_int64(9, self.create_time)?; 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())?; os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(()) ::std::result::Result::Ok(())
} }
@ -435,10 +507,10 @@ impl ::protobuf::Message for View {
|m: &View| { &m.desc }, |m: &View| { &m.desc },
|m: &mut View| { &mut m.desc }, |m: &mut View| { &mut m.desc },
)); ));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ViewType>>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ViewDataType>>(
"view_type", "data_type",
|m: &View| { &m.view_type }, |m: &View| { &m.data_type },
|m: &mut View| { &mut m.view_type }, |m: &mut View| { &mut m.data_type },
)); ));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>(
"version", "version",
@ -460,6 +532,16 @@ impl ::protobuf::Message for View {
|m: &View| { &m.create_time }, |m: &View| { &m.create_time },
|m: &mut View| { &mut 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>( ::protobuf::reflect::MessageDescriptor::new_pb_name::<View>(
"View", "View",
fields, fields,
@ -480,11 +562,13 @@ impl ::protobuf::Clear for View {
self.belong_to_id.clear(); self.belong_to_id.clear();
self.name.clear(); self.name.clear();
self.desc.clear(); self.desc.clear();
self.view_type = ViewType::RichText; self.data_type = ViewDataType::RichText;
self.version = 0; self.version = 0;
self.belongings.clear(); self.belongings.clear();
self.modified_time = 0; self.modified_time = 0;
self.create_time = 0; self.create_time = 0;
self.ext_data.clear();
self.thumbnail.clear();
self.unknown_fields.clear(); self.unknown_fields.clear();
} }
} }
@ -673,8 +757,8 @@ pub struct CreateViewPayload {
pub belong_to_id: ::std::string::String, pub belong_to_id: ::std::string::String,
pub name: ::std::string::String, pub name: ::std::string::String,
pub desc: ::std::string::String, pub desc: ::std::string::String,
pub view_type: ViewType, pub data_type: ViewDataType,
pub ext: ::std::string::String, pub ext_data: ::std::string::String,
// message oneof groups // message oneof groups
pub one_of_thumbnail: ::std::option::Option<CreateViewPayload_oneof_one_of_thumbnail>, pub one_of_thumbnail: ::std::option::Option<CreateViewPayload_oneof_one_of_thumbnail>,
// special fields // special fields
@ -825,45 +909,45 @@ impl CreateViewPayload {
} }
} }
// .ViewType view_type = 5; // .ViewDataType data_type = 5;
pub fn get_view_type(&self) -> ViewType { pub fn get_data_type(&self) -> ViewDataType {
self.view_type self.data_type
} }
pub fn clear_view_type(&mut self) { pub fn clear_data_type(&mut self) {
self.view_type = ViewType::RichText; self.data_type = ViewDataType::RichText;
} }
// Param is passed by value, moved // Param is passed by value, moved
pub fn set_view_type(&mut self, v: ViewType) { pub fn set_data_type(&mut self, v: ViewDataType) {
self.view_type = v; self.data_type = v;
} }
// string ext = 6; // string ext_data = 6;
pub fn get_ext(&self) -> &str { pub fn get_ext_data(&self) -> &str {
&self.ext &self.ext_data
} }
pub fn clear_ext(&mut self) { pub fn clear_ext_data(&mut self) {
self.ext.clear(); self.ext_data.clear();
} }
// Param is passed by value, moved // Param is passed by value, moved
pub fn set_ext(&mut self, v: ::std::string::String) { pub fn set_ext_data(&mut self, v: ::std::string::String) {
self.ext = v; self.ext_data = v;
} }
// Mutable pointer to the field. // Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first. // If field is not initialized, it is initialized with default value first.
pub fn mut_ext(&mut self) -> &mut ::std::string::String { pub fn mut_ext_data(&mut self) -> &mut ::std::string::String {
&mut self.ext &mut self.ext_data
} }
// Take field // Take field
pub fn take_ext(&mut self) -> ::std::string::String { pub fn take_ext_data(&mut self) -> ::std::string::String {
::std::mem::replace(&mut self.ext, ::std::string::String::new()) ::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()?)); self.one_of_thumbnail = ::std::option::Option::Some(CreateViewPayload_oneof_one_of_thumbnail::thumbnail(is.read_string()?));
}, },
5 => { 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 => { 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())?; ::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() { if !self.desc.is_empty() {
my_size += ::protobuf::rt::string_size(3, &self.desc); my_size += ::protobuf::rt::string_size(3, &self.desc);
} }
if self.view_type != ViewType::RichText { if self.data_type != ViewDataType::RichText {
my_size += ::protobuf::rt::enum_size(5, self.view_type); my_size += ::protobuf::rt::enum_size(5, self.data_type);
} }
if !self.ext.is_empty() { if !self.ext_data.is_empty() {
my_size += ::protobuf::rt::string_size(6, &self.ext); my_size += ::protobuf::rt::string_size(6, &self.ext_data);
} }
if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail { if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail {
match v { match v {
@ -946,11 +1030,11 @@ impl ::protobuf::Message for CreateViewPayload {
if !self.desc.is_empty() { if !self.desc.is_empty() {
os.write_string(3, &self.desc)?; os.write_string(3, &self.desc)?;
} }
if self.view_type != ViewType::RichText { if self.data_type != ViewDataType::RichText {
os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.view_type))?; os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?;
} }
if !self.ext.is_empty() { if !self.ext_data.is_empty() {
os.write_string(6, &self.ext)?; os.write_string(6, &self.ext_data)?;
} }
if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail { if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail {
match v { match v {
@ -1017,15 +1101,15 @@ impl ::protobuf::Message for CreateViewPayload {
CreateViewPayload::has_thumbnail, CreateViewPayload::has_thumbnail,
CreateViewPayload::get_thumbnail, CreateViewPayload::get_thumbnail,
)); ));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ViewType>>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ViewDataType>>(
"view_type", "data_type",
|m: &CreateViewPayload| { &m.view_type }, |m: &CreateViewPayload| { &m.data_type },
|m: &mut CreateViewPayload| { &mut m.view_type }, |m: &mut CreateViewPayload| { &mut m.data_type },
)); ));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"ext", "ext_data",
|m: &CreateViewPayload| { &m.ext }, |m: &CreateViewPayload| { &m.ext_data },
|m: &mut CreateViewPayload| { &mut m.ext }, |m: &mut CreateViewPayload| { &mut m.ext_data },
)); ));
::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateViewPayload>( ::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateViewPayload>(
"CreateViewPayload", "CreateViewPayload",
@ -1047,8 +1131,8 @@ impl ::protobuf::Clear for CreateViewPayload {
self.name.clear(); self.name.clear();
self.desc.clear(); self.desc.clear();
self.one_of_thumbnail = ::std::option::Option::None; self.one_of_thumbnail = ::std::option::Option::None;
self.view_type = ViewType::RichText; self.data_type = ViewDataType::RichText;
self.ext.clear(); self.ext_data.clear();
self.unknown_fields.clear(); self.unknown_fields.clear();
} }
} }
@ -1072,9 +1156,10 @@ pub struct CreateViewParams {
pub name: ::std::string::String, pub name: ::std::string::String,
pub desc: ::std::string::String, pub desc: ::std::string::String,
pub thumbnail: ::std::string::String, pub thumbnail: ::std::string::String,
pub view_type: ViewType, pub data_type: ViewDataType,
pub ext: ::std::string::String, pub ext_data: ::std::string::String,
pub view_id: ::std::string::String, pub view_id: ::std::string::String,
pub data: ::std::string::String,
// special fields // special fields
pub unknown_fields: ::protobuf::UnknownFields, pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize, pub cached_size: ::protobuf::CachedSize,
@ -1195,45 +1280,45 @@ impl CreateViewParams {
::std::mem::replace(&mut self.thumbnail, ::std::string::String::new()) ::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 { pub fn get_data_type(&self) -> ViewDataType {
self.view_type self.data_type
} }
pub fn clear_view_type(&mut self) { pub fn clear_data_type(&mut self) {
self.view_type = ViewType::RichText; self.data_type = ViewDataType::RichText;
} }
// Param is passed by value, moved // Param is passed by value, moved
pub fn set_view_type(&mut self, v: ViewType) { pub fn set_data_type(&mut self, v: ViewDataType) {
self.view_type = v; self.data_type = v;
} }
// string ext = 6; // string ext_data = 6;
pub fn get_ext(&self) -> &str { pub fn get_ext_data(&self) -> &str {
&self.ext &self.ext_data
} }
pub fn clear_ext(&mut self) { pub fn clear_ext_data(&mut self) {
self.ext.clear(); self.ext_data.clear();
} }
// Param is passed by value, moved // Param is passed by value, moved
pub fn set_ext(&mut self, v: ::std::string::String) { pub fn set_ext_data(&mut self, v: ::std::string::String) {
self.ext = v; self.ext_data = v;
} }
// Mutable pointer to the field. // Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first. // If field is not initialized, it is initialized with default value first.
pub fn mut_ext(&mut self) -> &mut ::std::string::String { pub fn mut_ext_data(&mut self) -> &mut ::std::string::String {
&mut self.ext &mut self.ext_data
} }
// Take field // Take field
pub fn take_ext(&mut self) -> ::std::string::String { pub fn take_ext_data(&mut self) -> ::std::string::String {
::std::mem::replace(&mut self.ext, ::std::string::String::new()) ::std::mem::replace(&mut self.ext_data, ::std::string::String::new())
} }
// string view_id = 7; // string view_id = 7;
@ -1261,6 +1346,32 @@ impl CreateViewParams {
pub fn take_view_id(&mut self) -> ::std::string::String { pub fn take_view_id(&mut self) -> ::std::string::String {
::std::mem::replace(&mut self.view_id, ::std::string::String::new()) ::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 { 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)?; ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.thumbnail)?;
}, },
5 => { 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 => { 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 => { 7 => {
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.view_id)?; ::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())?; ::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() { if !self.thumbnail.is_empty() {
my_size += ::protobuf::rt::string_size(4, &self.thumbnail); my_size += ::protobuf::rt::string_size(4, &self.thumbnail);
} }
if self.view_type != ViewType::RichText { if self.data_type != ViewDataType::RichText {
my_size += ::protobuf::rt::enum_size(5, self.view_type); my_size += ::protobuf::rt::enum_size(5, self.data_type);
} }
if !self.ext.is_empty() { if !self.ext_data.is_empty() {
my_size += ::protobuf::rt::string_size(6, &self.ext); my_size += ::protobuf::rt::string_size(6, &self.ext_data);
} }
if !self.view_id.is_empty() { if !self.view_id.is_empty() {
my_size += ::protobuf::rt::string_size(7, &self.view_id); 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()); my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size); self.cached_size.set(my_size);
my_size my_size
@ -1344,15 +1461,18 @@ impl ::protobuf::Message for CreateViewParams {
if !self.thumbnail.is_empty() { if !self.thumbnail.is_empty() {
os.write_string(4, &self.thumbnail)?; os.write_string(4, &self.thumbnail)?;
} }
if self.view_type != ViewType::RichText { if self.data_type != ViewDataType::RichText {
os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.view_type))?; os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?;
} }
if !self.ext.is_empty() { if !self.ext_data.is_empty() {
os.write_string(6, &self.ext)?; os.write_string(6, &self.ext_data)?;
} }
if !self.view_id.is_empty() { if !self.view_id.is_empty() {
os.write_string(7, &self.view_id)?; 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())?; os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(()) ::std::result::Result::Ok(())
} }
@ -1411,21 +1531,26 @@ impl ::protobuf::Message for CreateViewParams {
|m: &CreateViewParams| { &m.thumbnail }, |m: &CreateViewParams| { &m.thumbnail },
|m: &mut CreateViewParams| { &mut m.thumbnail }, |m: &mut CreateViewParams| { &mut m.thumbnail },
)); ));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ViewType>>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ViewDataType>>(
"view_type", "data_type",
|m: &CreateViewParams| { &m.view_type }, |m: &CreateViewParams| { &m.data_type },
|m: &mut CreateViewParams| { &mut m.view_type }, |m: &mut CreateViewParams| { &mut m.data_type },
)); ));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"ext", "ext_data",
|m: &CreateViewParams| { &m.ext }, |m: &CreateViewParams| { &m.ext_data },
|m: &mut CreateViewParams| { &mut m.ext }, |m: &mut CreateViewParams| { &mut m.ext_data },
)); ));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"view_id", "view_id",
|m: &CreateViewParams| { &m.view_id }, |m: &CreateViewParams| { &m.view_id },
|m: &mut CreateViewParams| { &mut 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>( ::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateViewParams>(
"CreateViewParams", "CreateViewParams",
fields, fields,
@ -1446,9 +1571,10 @@ impl ::protobuf::Clear for CreateViewParams {
self.name.clear(); self.name.clear();
self.desc.clear(); self.desc.clear();
self.thumbnail.clear(); self.thumbnail.clear();
self.view_type = ViewType::RichText; self.data_type = ViewDataType::RichText;
self.ext.clear(); self.ext_data.clear();
self.view_id.clear(); self.view_id.clear();
self.data.clear();
self.unknown_fields.clear(); self.unknown_fields.clear();
} }
} }
@ -2589,28 +2715,28 @@ impl ::protobuf::reflect::ProtobufValue for UpdateViewParams {
} }
#[derive(Clone,PartialEq,Eq,Debug,Hash)] #[derive(Clone,PartialEq,Eq,Debug,Hash)]
pub enum ViewType { pub enum ViewDataType {
RichText = 0, RichText = 0,
PlainText = 1, PlainText = 1,
} }
impl ::protobuf::ProtobufEnum for ViewType { impl ::protobuf::ProtobufEnum for ViewDataType {
fn value(&self) -> i32 { fn value(&self) -> i32 {
*self as i32 *self as i32
} }
fn from_i32(value: i32) -> ::std::option::Option<ViewType> { fn from_i32(value: i32) -> ::std::option::Option<ViewDataType> {
match value { match value {
0 => ::std::option::Option::Some(ViewType::RichText), 0 => ::std::option::Option::Some(ViewDataType::RichText),
1 => ::std::option::Option::Some(ViewType::PlainText), 1 => ::std::option::Option::Some(ViewDataType::PlainText),
_ => ::std::option::Option::None _ => ::std::option::Option::None
} }
} }
fn values() -> &'static [Self] { fn values() -> &'static [Self] {
static values: &'static [ViewType] = &[ static values: &'static [ViewDataType] = &[
ViewType::RichText, ViewDataType::RichText,
ViewType::PlainText, ViewDataType::PlainText,
]; ];
values values
} }
@ -2618,58 +2744,61 @@ impl ::protobuf::ProtobufEnum for ViewType {
fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT;
descriptor.get(|| { 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 { 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 { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self))
} }
} }
static file_descriptor_proto_data: &'static [u8] = b"\ 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\ \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\ \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\ (\tR\x04desc\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTypeR\x08\
Type\x12\x18\n\x07version\x18\x06\x20\x01(\x03R\x07version\x12-\n\nbelon\ dataType\x12\x18\n\x07version\x18\x06\x20\x01(\x03R\x07version\x12-\n\nb\
gings\x18\x07\x20\x01(\x0b2\r.RepeatedViewR\nbelongings\x12#\n\rmodified\ elongings\x18\x07\x20\x01(\x0b2\r.RepeatedViewR\nbelongings\x12#\n\rmodi\
_time\x18\x08\x20\x01(\x03R\x0cmodifiedTime\x12\x1f\n\x0bcreate_time\x18\ fied_time\x18\x08\x20\x01(\x03R\x0cmodifiedTime\x12\x1f\n\x0bcreate_time\
\t\x20\x01(\x03R\ncreateTime\"+\n\x0cRepeatedView\x12\x1b\n\x05items\x18\ \x18\t\x20\x01(\x03R\ncreateTime\x12\x19\n\x08ext_data\x18\n\x20\x01(\tR\
\x01\x20\x03(\x0b2\x05.ViewR\x05items\"\xcb\x01\n\x11CreateViewPayload\ \x07extData\x12\x1c\n\tthumbnail\x18\x0b\x20\x01(\tR\tthumbnail\"+\n\x0c\
\x12\x20\n\x0cbelong_to_id\x18\x01\x20\x01(\tR\nbelongToId\x12\x12\n\x04\ RepeatedView\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.ViewR\x05items\
name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\ \"\xd8\x01\n\x11CreateViewPayload\x12\x20\n\x0cbelong_to_id\x18\x01\x20\
\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\0R\tthumbnail\x12&\n\t\ \x01(\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\
view_type\x18\x05\x20\x01(\x0e2\t.ViewTypeR\x08viewType\x12\x10\n\x03ext\ \x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1e\n\tthumbnail\x18\x04\
\x18\x06\x20\x01(\tR\x03extB\x12\n\x10one_of_thumbnail\"\xcd\x01\n\x10Cr\ \x20\x01(\tH\0R\tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.Vie\
eateViewParams\x12\x20\n\x0cbelong_to_id\x18\x01\x20\x01(\tR\nbelongToId\ wDataTypeR\x08dataType\x12\x19\n\x08ext_data\x18\x06\x20\x01(\tR\x07extD\
\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\ ataB\x12\n\x10one_of_thumbnail\"\xee\x01\n\x10CreateViewParams\x12\x20\n\
\x20\x01(\tR\x04desc\x12\x1c\n\tthumbnail\x18\x04\x20\x01(\tR\tthumbnail\ \x0cbelong_to_id\x18\x01\x20\x01(\tR\nbelongToId\x12\x12\n\x04name\x18\
\x12&\n\tview_type\x18\x05\x20\x01(\x0e2\t.ViewTypeR\x08viewType\x12\x10\ \x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\
\n\x03ext\x18\x06\x20\x01(\tR\x03ext\x12\x17\n\x07view_id\x18\x07\x20\ \x12\x1c\n\tthumbnail\x18\x04\x20\x01(\tR\tthumbnail\x12*\n\tdata_type\
\x01(\tR\x06viewId\"\x1e\n\x06ViewId\x12\x14\n\x05value\x18\x01\x20\x01(\ \x18\x05\x20\x01(\x0e2\r.ViewDataTypeR\x08dataType\x12\x19\n\x08ext_data\
\tR\x05value\"&\n\x0eRepeatedViewId\x12\x14\n\x05items\x18\x01\x20\x03(\ \x18\x06\x20\x01(\tR\x07extData\x12\x17\n\x07view_id\x18\x07\x20\x01(\tR\
\tR\x05items\"\xaa\x01\n\x11UpdateViewPayload\x12\x17\n\x07view_id\x18\ \x06viewId\x12\x12\n\x04data\x18\x08\x20\x01(\tR\x04data\"\x1e\n\x06View\
\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04n\ Id\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"&\n\x0eRepeatedViewI\
ame\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12\x1e\n\tthumbn\ d\x12\x14\n\x05items\x18\x01\x20\x03(\tR\x05items\"\xaa\x01\n\x11UpdateV\
ail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of_nameB\r\n\x0bone_\ iewPayload\x12\x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\
of_descB\x12\n\x10one_of_thumbnail\"\xa9\x01\n\x10UpdateViewParams\x12\ \x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\
\x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\ \x01(\tH\x01R\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthu\
\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\ mbnailB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnai\
\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\ l\"\xa9\x01\n\x10UpdateViewParams\x12\x17\n\x07view_id\x18\x01\x20\x01(\
\x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail*'\n\x08Vi\ \tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\
ewType\x12\x0c\n\x08RichText\x10\0\x12\r\n\tPlainText\x10\x01b\x06proto3\ \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; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -5,11 +5,13 @@ message View {
string belong_to_id = 2; string belong_to_id = 2;
string name = 3; string name = 3;
string desc = 4; string desc = 4;
ViewType view_type = 5; ViewDataType data_type = 5;
int64 version = 6; int64 version = 6;
RepeatedView belongings = 7; RepeatedView belongings = 7;
int64 modified_time = 8; int64 modified_time = 8;
int64 create_time = 9; int64 create_time = 9;
string ext_data = 10;
string thumbnail = 11;
} }
message RepeatedView { message RepeatedView {
repeated View items = 1; repeated View items = 1;
@ -19,17 +21,18 @@ message CreateViewPayload {
string name = 2; string name = 2;
string desc = 3; string desc = 3;
oneof one_of_thumbnail { string thumbnail = 4; }; oneof one_of_thumbnail { string thumbnail = 4; };
ViewType view_type = 5; ViewDataType data_type = 5;
string ext = 6; string ext_data = 6;
} }
message CreateViewParams { message CreateViewParams {
string belong_to_id = 1; string belong_to_id = 1;
string name = 2; string name = 2;
string desc = 3; string desc = 3;
string thumbnail = 4; string thumbnail = 4;
ViewType view_type = 5; ViewDataType data_type = 5;
string ext = 6; string ext_data = 6;
string view_id = 7; string view_id = 7;
string data = 8;
} }
message ViewId { message ViewId {
string value = 1; string value = 1;
@ -49,7 +52,7 @@ message UpdateViewParams {
oneof one_of_desc { string desc = 3; }; oneof one_of_desc { string desc = 3; };
oneof one_of_thumbnail { string thumbnail = 4; }; oneof one_of_thumbnail { string thumbnail = 4; };
} }
enum ViewType { enum ViewDataType {
RichText = 0; RichText = 0;
PlainText = 1; PlainText = 1;
} }

View File

@ -1,6 +1,6 @@
use crate::entities::{ use crate::entities::{
app::{App, RepeatedApp}, app::{App, RepeatedApp},
view::{RepeatedView, View, ViewType}, view::{RepeatedView, View, ViewDataType},
workspace::Workspace, workspace::Workspace,
}; };
use chrono::Utc; 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 view_id = uuid::Uuid::new_v4();
let name = "Read me".to_string(); let name = "Read me".to_string();
let desc = "".to_string(); let desc = "".to_string();
let view_type = ViewType::RichText; let data_type = ViewDataType::RichText;
View { View {
id: view_id.to_string(), id: view_id.to_string(),
belong_to_id: app_id, belong_to_id: app_id,
name, name,
desc, desc,
view_type, data_type,
version: 0, version: 0,
belongings: Default::default(), belongings: Default::default(),
modified_time: time.timestamp(), modified_time: time.timestamp(),
create_time: time.timestamp(), create_time: time.timestamp(),
ext_data: "".to_string(),
thumbnail: "".to_string(),
} }
} }

View File

@ -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> { pub struct DeltaBuilder<T: Attributes> {
delta: Delta<T>, delta: Delta<T>,

View File

@ -13,7 +13,7 @@ use std::{
str::FromStr, str::FromStr,
}; };
pub type PlainDelta = Delta<PlainAttributes>; pub type PlainTextDelta = Delta<PlainTextAttributes>;
// TODO: optimize the memory usage with Arc::make_mut or Cow // TODO: optimize the memory usage with Arc::make_mut or Cow
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]

View File

@ -1,10 +1,10 @@
use crate::{ use crate::{
core::{Attributes, Operation, PlainAttributes}, core::{Attributes, Operation, PlainTextAttributes},
rich_text::RichTextAttributes, rich_text::RichTextAttributes,
}; };
pub type RichTextOpBuilder = OpBuilder<RichTextAttributes>; pub type RichTextOpBuilder = OpBuilder<RichTextAttributes>;
pub type PlainTextOpBuilder = OpBuilder<PlainAttributes>; pub type PlainTextOpBuilder = OpBuilder<PlainTextAttributes>;
pub struct OpBuilder<T: Attributes> { pub struct OpBuilder<T: Attributes> {
ty: Operation<T>, ty: Operation<T>,

View File

@ -339,14 +339,14 @@ where
} }
#[derive(Debug, Clone, Eq, PartialEq, Default, Serialize, Deserialize)] #[derive(Debug, Clone, Eq, PartialEq, Default, Serialize, Deserialize)]
pub struct PlainAttributes(); pub struct PlainTextAttributes();
impl fmt::Display for PlainAttributes { impl fmt::Display for PlainTextAttributes {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("PlainAttributes") f.write_str("PlainAttributes")
} }
} }
impl Attributes for PlainAttributes { impl Attributes for PlainTextAttributes {
fn is_empty(&self) -> bool { fn is_empty(&self) -> bool {
true true
} }
@ -356,7 +356,7 @@ impl Attributes for PlainAttributes {
fn extend_other(&mut self, _other: Self) {} fn extend_other(&mut self, _other: Self) {}
} }
impl OperationTransformable for PlainAttributes { impl OperationTransformable for PlainTextAttributes {
fn compose(&self, _other: &Self) -> Result<Self, OTError> { fn compose(&self, _other: &Self) -> Result<Self, OTError> {
Ok(self.clone()) Ok(self.clone())
} }

View File

@ -40,6 +40,7 @@ impl fmt::Display for RichTextAttributes {
} }
} }
#[inline(always)]
pub fn plain_attributes() -> RichTextAttributes { pub fn plain_attributes() -> RichTextAttributes {
RichTextAttributes::default() RichTextAttributes::default()
} }
@ -58,7 +59,7 @@ impl RichTextAttributes {
self.inner.insert(key, value); 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); self.inner.insert(key, value);
} }

View File

@ -101,7 +101,7 @@ impl<'de> Deserialize<'de> for RichTextAttributes {
let mut attributes = RichTextAttributes::new(); let mut attributes = RichTextAttributes::new();
while let Some(key) = map.next_key::<RichTextAttributeKey>()? { while let Some(key) = map.next_key::<RichTextAttributeKey>()? {
let value = map.next_value::<RichTextAttributeValue>()?; let value = map.next_value::<RichTextAttributeValue>()?;
attributes.add_kv(key, value); attributes.insert(key, value);
} }
Ok(attributes) Ok(attributes)