add flowy icon
|
@ -2,7 +2,7 @@ import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/welcome/presentation/splash_screen.dart';
|
import 'package:app_flowy/welcome/presentation/splash_screen.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class FlowyAppFactory implements AppFactory {
|
class FlowyApp implements EntryPoint {
|
||||||
@override
|
@override
|
||||||
Widget create() {
|
Widget create() {
|
||||||
return const SplashScreen();
|
return const SplashScreen();
|
||||||
|
@ -10,5 +10,5 @@ class FlowyAppFactory implements AppFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
Application.run(FlowyAppFactory());
|
System.run(FlowyApp());
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,17 +10,17 @@ enum IntegrationEnv {
|
||||||
pro,
|
pro,
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class AppFactory {
|
abstract class EntryPoint {
|
||||||
Widget create();
|
Widget create();
|
||||||
}
|
}
|
||||||
|
|
||||||
class Application {
|
class System {
|
||||||
static void run(AppFactory f) {
|
static void run(EntryPoint f) {
|
||||||
// Specify the evn
|
// Specify the evn
|
||||||
const env = IntegrationEnv.dev;
|
const env = IntegrationEnv.dev;
|
||||||
|
|
||||||
// Config the deps graph
|
// Config the deps graph
|
||||||
getIt.registerFactory<AppFactory>(() => f);
|
getIt.registerFactory<EntryPoint>(() => f);
|
||||||
|
|
||||||
resolveDependencies(env);
|
resolveDependencies(env);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ class AppWidgetTask extends LaunchTask {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> initialize(LaunchContext context) {
|
Future<void> initialize(LaunchContext context) {
|
||||||
final widget = context.getIt<AppFactory>().create();
|
final widget = context.getIt<EntryPoint>().create();
|
||||||
final app = ApplicationWidget(child: widget);
|
final app = ApplicationWidget(child: widget);
|
||||||
runApp(app);
|
runApp(app);
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
export 'application_task.dart';
|
export 'application_task.dart';
|
||||||
export 'rust_sdk_init_task.dart';
|
export 'sdk_task.dart';
|
||||||
|
|
|
@ -16,7 +16,7 @@ class DocBloc extends Bloc<DocEvent, DocState> {
|
||||||
@override
|
@override
|
||||||
Stream<DocState> mapEventToState(DocEvent event) async* {
|
Stream<DocState> mapEventToState(DocEvent event) async* {
|
||||||
yield* event.map(
|
yield* event.map(
|
||||||
started: (_) async* {
|
loadDoc: (_) async* {
|
||||||
yield* _readDoc();
|
yield* _readDoc();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -44,12 +44,12 @@ class DocBloc extends Bloc<DocEvent, DocState> {
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class DocEvent with _$DocEvent {
|
class DocEvent with _$DocEvent {
|
||||||
const factory DocEvent.started() = Started;
|
const factory DocEvent.loadDoc() = LoadDoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class DocState with _$DocState {
|
class DocState with _$DocState {
|
||||||
const factory DocState.loading() = Loading;
|
const factory DocState.loading() = Loading;
|
||||||
const factory DocState.loadDoc(FlowyDoc doc) = LoadDoc;
|
const factory DocState.loadDoc(FlowyDoc doc) = LoadedDoc;
|
||||||
const factory DocState.loadFail(WorkspaceError error) = LoadFail;
|
const factory DocState.loadFail(WorkspaceError error) = LoadFail;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,8 @@ final _privateConstructorUsedError = UnsupportedError(
|
||||||
class _$DocEventTearOff {
|
class _$DocEventTearOff {
|
||||||
const _$DocEventTearOff();
|
const _$DocEventTearOff();
|
||||||
|
|
||||||
Started started() {
|
LoadDoc loadDoc() {
|
||||||
return const Started();
|
return const LoadDoc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,23 +28,23 @@ const $DocEvent = _$DocEventTearOff();
|
||||||
mixin _$DocEvent {
|
mixin _$DocEvent {
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() started,
|
required TResult Function() loadDoc,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? started,
|
TResult Function()? loadDoc,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult map<TResult extends Object?>({
|
TResult map<TResult extends Object?>({
|
||||||
required TResult Function(Started value) started,
|
required TResult Function(LoadDoc value) loadDoc,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeMap<TResult extends Object?>({
|
TResult maybeMap<TResult extends Object?>({
|
||||||
TResult Function(Started value)? started,
|
TResult Function(LoadDoc value)? loadDoc,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
|
@ -66,34 +66,34 @@ class _$DocEventCopyWithImpl<$Res> implements $DocEventCopyWith<$Res> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class $StartedCopyWith<$Res> {
|
abstract class $LoadDocCopyWith<$Res> {
|
||||||
factory $StartedCopyWith(Started value, $Res Function(Started) then) =
|
factory $LoadDocCopyWith(LoadDoc value, $Res Function(LoadDoc) then) =
|
||||||
_$StartedCopyWithImpl<$Res>;
|
_$LoadDocCopyWithImpl<$Res>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$StartedCopyWithImpl<$Res> extends _$DocEventCopyWithImpl<$Res>
|
class _$LoadDocCopyWithImpl<$Res> extends _$DocEventCopyWithImpl<$Res>
|
||||||
implements $StartedCopyWith<$Res> {
|
implements $LoadDocCopyWith<$Res> {
|
||||||
_$StartedCopyWithImpl(Started _value, $Res Function(Started) _then)
|
_$LoadDocCopyWithImpl(LoadDoc _value, $Res Function(LoadDoc) _then)
|
||||||
: super(_value, (v) => _then(v as Started));
|
: super(_value, (v) => _then(v as LoadDoc));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Started get _value => super._value as Started;
|
LoadDoc get _value => super._value as LoadDoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
||||||
class _$Started implements Started {
|
class _$LoadDoc implements LoadDoc {
|
||||||
const _$Started();
|
const _$LoadDoc();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'DocEvent.started()';
|
return 'DocEvent.loadDoc()';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(dynamic other) {
|
bool operator ==(dynamic other) {
|
||||||
return identical(this, other) || (other is Started);
|
return identical(this, other) || (other is LoadDoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -102,19 +102,19 @@ class _$Started implements Started {
|
||||||
@override
|
@override
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() started,
|
required TResult Function() loadDoc,
|
||||||
}) {
|
}) {
|
||||||
return started();
|
return loadDoc();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? started,
|
TResult Function()? loadDoc,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
if (started != null) {
|
if (loadDoc != null) {
|
||||||
return started();
|
return loadDoc();
|
||||||
}
|
}
|
||||||
return orElse();
|
return orElse();
|
||||||
}
|
}
|
||||||
|
@ -122,26 +122,26 @@ class _$Started implements Started {
|
||||||
@override
|
@override
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult map<TResult extends Object?>({
|
TResult map<TResult extends Object?>({
|
||||||
required TResult Function(Started value) started,
|
required TResult Function(LoadDoc value) loadDoc,
|
||||||
}) {
|
}) {
|
||||||
return started(this);
|
return loadDoc(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeMap<TResult extends Object?>({
|
TResult maybeMap<TResult extends Object?>({
|
||||||
TResult Function(Started value)? started,
|
TResult Function(LoadDoc value)? loadDoc,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
if (started != null) {
|
if (loadDoc != null) {
|
||||||
return started(this);
|
return loadDoc(this);
|
||||||
}
|
}
|
||||||
return orElse();
|
return orElse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class Started implements DocEvent {
|
abstract class LoadDoc implements DocEvent {
|
||||||
const factory Started() = _$Started;
|
const factory LoadDoc() = _$LoadDoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
@ -152,8 +152,8 @@ class _$DocStateTearOff {
|
||||||
return const Loading();
|
return const Loading();
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadDoc loadDoc(FlowyDoc doc) {
|
LoadedDoc loadDoc(FlowyDoc doc) {
|
||||||
return LoadDoc(
|
return LoadedDoc(
|
||||||
doc,
|
doc,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -188,14 +188,14 @@ mixin _$DocState {
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult map<TResult extends Object?>({
|
TResult map<TResult extends Object?>({
|
||||||
required TResult Function(Loading value) loading,
|
required TResult Function(Loading value) loading,
|
||||||
required TResult Function(LoadDoc value) loadDoc,
|
required TResult Function(LoadedDoc value) loadDoc,
|
||||||
required TResult Function(LoadFail value) loadFail,
|
required TResult Function(LoadFail value) loadFail,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeMap<TResult extends Object?>({
|
TResult maybeMap<TResult extends Object?>({
|
||||||
TResult Function(Loading value)? loading,
|
TResult Function(Loading value)? loading,
|
||||||
TResult Function(LoadDoc value)? loadDoc,
|
TResult Function(LoadedDoc value)? loadDoc,
|
||||||
TResult Function(LoadFail value)? loadFail,
|
TResult Function(LoadFail value)? loadFail,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) =>
|
}) =>
|
||||||
|
@ -279,7 +279,7 @@ class _$Loading implements Loading {
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult map<TResult extends Object?>({
|
TResult map<TResult extends Object?>({
|
||||||
required TResult Function(Loading value) loading,
|
required TResult Function(Loading value) loading,
|
||||||
required TResult Function(LoadDoc value) loadDoc,
|
required TResult Function(LoadedDoc value) loadDoc,
|
||||||
required TResult Function(LoadFail value) loadFail,
|
required TResult Function(LoadFail value) loadFail,
|
||||||
}) {
|
}) {
|
||||||
return loading(this);
|
return loading(this);
|
||||||
|
@ -289,7 +289,7 @@ class _$Loading implements Loading {
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeMap<TResult extends Object?>({
|
TResult maybeMap<TResult extends Object?>({
|
||||||
TResult Function(Loading value)? loading,
|
TResult Function(Loading value)? loading,
|
||||||
TResult Function(LoadDoc value)? loadDoc,
|
TResult Function(LoadedDoc value)? loadDoc,
|
||||||
TResult Function(LoadFail value)? loadFail,
|
TResult Function(LoadFail value)? loadFail,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
|
@ -305,26 +305,26 @@ abstract class Loading implements DocState {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class $LoadDocCopyWith<$Res> {
|
abstract class $LoadedDocCopyWith<$Res> {
|
||||||
factory $LoadDocCopyWith(LoadDoc value, $Res Function(LoadDoc) then) =
|
factory $LoadedDocCopyWith(LoadedDoc value, $Res Function(LoadedDoc) then) =
|
||||||
_$LoadDocCopyWithImpl<$Res>;
|
_$LoadedDocCopyWithImpl<$Res>;
|
||||||
$Res call({FlowyDoc doc});
|
$Res call({FlowyDoc doc});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$LoadDocCopyWithImpl<$Res> extends _$DocStateCopyWithImpl<$Res>
|
class _$LoadedDocCopyWithImpl<$Res> extends _$DocStateCopyWithImpl<$Res>
|
||||||
implements $LoadDocCopyWith<$Res> {
|
implements $LoadedDocCopyWith<$Res> {
|
||||||
_$LoadDocCopyWithImpl(LoadDoc _value, $Res Function(LoadDoc) _then)
|
_$LoadedDocCopyWithImpl(LoadedDoc _value, $Res Function(LoadedDoc) _then)
|
||||||
: super(_value, (v) => _then(v as LoadDoc));
|
: super(_value, (v) => _then(v as LoadedDoc));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
LoadDoc get _value => super._value as LoadDoc;
|
LoadedDoc get _value => super._value as LoadedDoc;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? doc = freezed,
|
Object? doc = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(LoadDoc(
|
return _then(LoadedDoc(
|
||||||
doc == freezed
|
doc == freezed
|
||||||
? _value.doc
|
? _value.doc
|
||||||
: doc // ignore: cast_nullable_to_non_nullable
|
: doc // ignore: cast_nullable_to_non_nullable
|
||||||
|
@ -335,8 +335,8 @@ class _$LoadDocCopyWithImpl<$Res> extends _$DocStateCopyWithImpl<$Res>
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
||||||
class _$LoadDoc implements LoadDoc {
|
class _$LoadedDoc implements LoadedDoc {
|
||||||
const _$LoadDoc(this.doc);
|
const _$LoadedDoc(this.doc);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final FlowyDoc doc;
|
final FlowyDoc doc;
|
||||||
|
@ -349,7 +349,7 @@ class _$LoadDoc implements LoadDoc {
|
||||||
@override
|
@override
|
||||||
bool operator ==(dynamic other) {
|
bool operator ==(dynamic other) {
|
||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other is LoadDoc &&
|
(other is LoadedDoc &&
|
||||||
(identical(other.doc, doc) ||
|
(identical(other.doc, doc) ||
|
||||||
const DeepCollectionEquality().equals(other.doc, doc)));
|
const DeepCollectionEquality().equals(other.doc, doc)));
|
||||||
}
|
}
|
||||||
|
@ -360,8 +360,8 @@ class _$LoadDoc implements LoadDoc {
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
$LoadDocCopyWith<LoadDoc> get copyWith =>
|
$LoadedDocCopyWith<LoadedDoc> get copyWith =>
|
||||||
_$LoadDocCopyWithImpl<LoadDoc>(this, _$identity);
|
_$LoadedDocCopyWithImpl<LoadedDoc>(this, _$identity);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
|
@ -391,7 +391,7 @@ class _$LoadDoc implements LoadDoc {
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult map<TResult extends Object?>({
|
TResult map<TResult extends Object?>({
|
||||||
required TResult Function(Loading value) loading,
|
required TResult Function(Loading value) loading,
|
||||||
required TResult Function(LoadDoc value) loadDoc,
|
required TResult Function(LoadedDoc value) loadDoc,
|
||||||
required TResult Function(LoadFail value) loadFail,
|
required TResult Function(LoadFail value) loadFail,
|
||||||
}) {
|
}) {
|
||||||
return loadDoc(this);
|
return loadDoc(this);
|
||||||
|
@ -401,7 +401,7 @@ class _$LoadDoc implements LoadDoc {
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeMap<TResult extends Object?>({
|
TResult maybeMap<TResult extends Object?>({
|
||||||
TResult Function(Loading value)? loading,
|
TResult Function(Loading value)? loading,
|
||||||
TResult Function(LoadDoc value)? loadDoc,
|
TResult Function(LoadedDoc value)? loadDoc,
|
||||||
TResult Function(LoadFail value)? loadFail,
|
TResult Function(LoadFail value)? loadFail,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
|
@ -412,12 +412,13 @@ class _$LoadDoc implements LoadDoc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class LoadDoc implements DocState {
|
abstract class LoadedDoc implements DocState {
|
||||||
const factory LoadDoc(FlowyDoc doc) = _$LoadDoc;
|
const factory LoadedDoc(FlowyDoc doc) = _$LoadedDoc;
|
||||||
|
|
||||||
FlowyDoc get doc => throw _privateConstructorUsedError;
|
FlowyDoc get doc => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
$LoadDocCopyWith<LoadDoc> get copyWith => throw _privateConstructorUsedError;
|
$LoadedDocCopyWith<LoadedDoc> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
@ -507,7 +508,7 @@ class _$LoadFail implements LoadFail {
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult map<TResult extends Object?>({
|
TResult map<TResult extends Object?>({
|
||||||
required TResult Function(Loading value) loading,
|
required TResult Function(Loading value) loading,
|
||||||
required TResult Function(LoadDoc value) loadDoc,
|
required TResult Function(LoadedDoc value) loadDoc,
|
||||||
required TResult Function(LoadFail value) loadFail,
|
required TResult Function(LoadFail value) loadFail,
|
||||||
}) {
|
}) {
|
||||||
return loadFail(this);
|
return loadFail(this);
|
||||||
|
@ -517,7 +518,7 @@ class _$LoadFail implements LoadFail {
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeMap<TResult extends Object?>({
|
TResult maybeMap<TResult extends Object?>({
|
||||||
TResult Function(Loading value)? loading,
|
TResult Function(Loading value)? loading,
|
||||||
TResult Function(LoadDoc value)? loadDoc,
|
TResult Function(LoadedDoc value)? loadDoc,
|
||||||
TResult Function(LoadFail value)? loadFail,
|
TResult Function(LoadFail value)? loadFail,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'package:equatable/equatable.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/doc/doc_page.dart';
|
import 'package:app_flowy/workspace/presentation/doc/doc_stack_page.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/widgets/blank_page.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/blank_page.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/widgets/fading_index_stack.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/fading_index_stack.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
|
||||||
|
@ -78,17 +78,18 @@ List<Widget> _buildStackWidget(HomeStackView stackView) {
|
||||||
if (viewType == stackView.type) {
|
if (viewType == stackView.type) {
|
||||||
switch (stackView.type) {
|
switch (stackView.type) {
|
||||||
case ViewType.Blank:
|
case ViewType.Blank:
|
||||||
return AnnouncementPage(
|
return AnnouncementStackPage(
|
||||||
stackView: stackView as AnnouncementStackView);
|
stackView: stackView as AnnouncementStackView);
|
||||||
case ViewType.Doc:
|
case ViewType.Doc:
|
||||||
final docView = stackView as DocPageStackView;
|
final docView = stackView as DocPageStackView;
|
||||||
return DocPage(key: ValueKey(docView.view.id), stackView: docView);
|
return DocStackPage(
|
||||||
|
key: ValueKey(docView.view.id), stackView: docView);
|
||||||
default:
|
default:
|
||||||
return AnnouncementPage(
|
return AnnouncementStackPage(
|
||||||
stackView: stackView as AnnouncementStackView);
|
stackView: stackView as AnnouncementStackView);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return const AnnouncementPage(stackView: AnnouncementStackView());
|
return const AnnouncementStackPage(stackView: AnnouncementStackView());
|
||||||
}
|
}
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,12 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class EditorPage extends StatelessWidget {
|
class DocPage extends StatelessWidget {
|
||||||
final FocusNode _focusNode = FocusNode();
|
final FocusNode _focusNode = FocusNode();
|
||||||
late EditorController controller;
|
late EditorController controller;
|
||||||
final FlowyDoc doc;
|
final FlowyDoc doc;
|
||||||
|
|
||||||
EditorPage({Key? key, required this.doc}) : super(key: key) {
|
DocPage({Key? key, required this.doc}) : super(key: key) {
|
||||||
controller = EditorController(
|
controller = EditorController(
|
||||||
document: doc.data,
|
document: doc.data,
|
||||||
selection: const TextSelection.collapsed(offset: 0),
|
selection: const TextSelection.collapsed(offset: 0),
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/workspace/application/view/doc_watch_bloc.dart';
|
import 'package:app_flowy/workspace/application/doc/doc_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/doc/editor_page.dart';
|
import 'package:app_flowy/workspace/presentation/doc/doc_page.dart';
|
||||||
import 'package:flowy_infra/flowy_logger.dart';
|
import 'package:flowy_infra/flowy_logger.dart';
|
||||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||||
|
@ -9,30 +9,29 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/progress_indicator.dart';
|
import 'package:flowy_infra_ui/style_widget/progress_indicator.dart';
|
||||||
|
|
||||||
class DocPage extends HomeStackWidget {
|
class DocStackPage extends HomeStackWidget {
|
||||||
const DocPage({Key? key, required DocPageStackView stackView})
|
const DocStackPage({Key? key, required DocPageStackView stackView})
|
||||||
: super(key: key, stackView: stackView);
|
: super(key: key, stackView: stackView);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_DocPageState createState() => _DocPageState();
|
_DocStackPageState createState() => _DocStackPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DocPageState extends State<DocPage> {
|
class _DocStackPageState extends State<DocStackPage> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final stackView = widget.stackView as DocPageStackView;
|
final stackView = widget.stackView as DocPageStackView;
|
||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider<DocWatchBloc>(
|
BlocProvider<DocBloc>(
|
||||||
create: (context) => getIt<DocWatchBloc>(param1: stackView.view.id)
|
create: (context) => getIt<DocBloc>(param1: stackView.view.id)
|
||||||
..add(const DocWatchEvent.started())),
|
..add(const DocEvent.loadDoc())),
|
||||||
],
|
],
|
||||||
child:
|
child: BlocBuilder<DocBloc, DocState>(builder: (context, state) {
|
||||||
BlocBuilder<DocWatchBloc, DocWatchState>(builder: (context, state) {
|
|
||||||
assert(widget.stackView is DocPageStackView);
|
assert(widget.stackView is DocPageStackView);
|
||||||
return state.map(
|
return state.map(
|
||||||
loading: (_) => const FlowyProgressIndicator(),
|
loading: (_) => const FlowyProgressIndicator(),
|
||||||
loadDoc: (s) => EditorPage(doc: s.doc),
|
loadDoc: (s) => DocPage(doc: s.doc),
|
||||||
loadFail: (s) {
|
loadFail: (s) {
|
||||||
Log.error("$s");
|
Log.error("$s");
|
||||||
return FlowyErrorPage(s.error.toString());
|
return FlowyErrorPage(s.error.toString());
|
||||||
|
@ -53,7 +52,7 @@ class _DocPageState extends State<DocPage> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didUpdateWidget(covariant DocPage oldWidget) {
|
void didUpdateWidget(covariant DocStackPage oldWidget) {
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,21 +3,23 @@ import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class AnnouncementStackView extends HomeStackView {
|
class AnnouncementStackView extends HomeStackView {
|
||||||
const AnnouncementStackView() : super(type: ViewType.Blank, title: 'Blank', identifier: "Announcement");
|
const AnnouncementStackView()
|
||||||
|
: super(type: ViewType.Blank, title: 'Blank', identifier: "Announcement");
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [];
|
List<Object> get props => [];
|
||||||
}
|
}
|
||||||
|
|
||||||
class AnnouncementPage extends HomeStackWidget {
|
class AnnouncementStackPage extends HomeStackWidget {
|
||||||
const AnnouncementPage({Key? key, required AnnouncementStackView stackView})
|
const AnnouncementStackPage(
|
||||||
|
{Key? key, required AnnouncementStackView stackView})
|
||||||
: super(key: key, stackView: stackView);
|
: super(key: key, stackView: stackView);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _AnnouncementPage();
|
State<StatefulWidget> createState() => _AnnouncementPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AnnouncementPage extends State<AnnouncementPage> {
|
class _AnnouncementPage extends State<AnnouncementStackPage> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SizedBox.expand(
|
return SizedBox.expand(
|
||||||
|
|
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 6.7 KiB |
BIN
app_flowy/macos/Runner/Assets.xcassets/AppIcon.appiconset/16.png
Normal file
After Width: | Height: | Size: 662 B |
After Width: | Height: | Size: 15 KiB |
BIN
app_flowy/macos/Runner/Assets.xcassets/AppIcon.appiconset/32.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 37 KiB |
BIN
app_flowy/macos/Runner/Assets.xcassets/AppIcon.appiconset/64.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
|
@ -1,68 +1 @@
|
||||||
{
|
{"images":[{"size":"128x128","expected-size":"128","filename":"128.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"256x256","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"128x128","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"256x256","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"512x512","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"16","filename":"16.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"64","filename":"64.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"512x512","expected-size":"1024","filename":"1024.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"}]}
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"size" : "16x16",
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "app_icon_16.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "16x16",
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "app_icon_32.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "32x32",
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "app_icon_32.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "32x32",
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "app_icon_64.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "128x128",
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "app_icon_128.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "128x128",
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "app_icon_256.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "256x256",
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "app_icon_256.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "256x256",
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "app_icon_512.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "512x512",
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "app_icon_512.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "512x512",
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "app_icon_1024.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 1.8 KiB |
|
@ -19,7 +19,9 @@ class Block extends Container<Line?> {
|
||||||
|
|
||||||
/// Creates new unmounted [Block].
|
/// Creates new unmounted [Block].
|
||||||
@override
|
@override
|
||||||
Node newInstance() => Block();
|
Node newInstance() {
|
||||||
|
return Block();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Delta toDelta() {
|
Delta toDelta() {
|
||||||
|
|
|
@ -67,6 +67,7 @@ class EditorController extends ChangeNotifier {
|
||||||
|
|
||||||
void save() {
|
void save() {
|
||||||
if (persistence != null) {
|
if (persistence != null) {
|
||||||
|
final a = document.toPlainText();
|
||||||
persistence!.save(document.toDelta().toJson());
|
persistence!.save(document.toDelta().toJson());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,8 +94,9 @@ class EditorController extends ChangeNotifier {
|
||||||
toggledStyle = toggledStyle.put(attribute);
|
toggledStyle = toggledStyle.put(attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
final change =
|
// final change =
|
||||||
document.format(index, length, LinkAttribute("www.baidu.com"));
|
// document.format(index, length, LinkAttribute("www.baidu.com"));
|
||||||
|
final change = document.format(index, length, attribute);
|
||||||
final adjustedSelection = selection.copyWith(
|
final adjustedSelection = selection.copyWith(
|
||||||
baseOffset: change.transformPosition(selection.baseOffset),
|
baseOffset: change.transformPosition(selection.baseOffset),
|
||||||
extentOffset: change.transformPosition(selection.extentOffset),
|
extentOffset: change.transformPosition(selection.extentOffset),
|
||||||
|
|
|
@ -32,6 +32,13 @@ impl Document {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_json(json: &str) -> Result<Self, OTError> {
|
||||||
|
let delta = Delta::from_json(json)?;
|
||||||
|
Ok(Self::from_delta(delta))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_json(&self) -> String { self.delta.to_json() }
|
||||||
|
|
||||||
pub fn insert<T: DocumentData>(&mut self, index: usize, data: T) -> Result<Delta, OTError> {
|
pub fn insert<T: DocumentData>(&mut self, index: usize, data: T) -> Result<Delta, OTError> {
|
||||||
let interval = Interval::new(index, index);
|
let interval = Interval::new(index, index);
|
||||||
let _ = validate_interval(&self.delta, &interval)?;
|
let _ = validate_interval(&self.delta, &interval)?;
|
||||||
|
@ -57,21 +64,14 @@ impl Document {
|
||||||
pub fn format(&mut self, interval: Interval, attribute: Attribute) -> Result<(), OTError> {
|
pub fn format(&mut self, interval: Interval, attribute: Attribute) -> Result<(), OTError> {
|
||||||
let _ = validate_interval(&self.delta, &interval)?;
|
let _ = validate_interval(&self.delta, &interval)?;
|
||||||
log::debug!("format with {} at {}", attribute, interval);
|
log::debug!("format with {} at {}", attribute, interval);
|
||||||
let format_delta = self
|
let format_delta = self.view.format(&self.delta, attribute.clone(), interval).unwrap();
|
||||||
.view
|
|
||||||
.format(&self.delta, attribute.clone(), interval)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
log::debug!("👉 receive change: {}", format_delta);
|
log::debug!("👉 receive change: {}", format_delta);
|
||||||
self.add_delta(&format_delta)?;
|
self.add_delta(&format_delta)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn replace<T: DocumentData>(
|
pub fn replace<T: DocumentData>(&mut self, interval: Interval, data: T) -> Result<Delta, OTError> {
|
||||||
&mut self,
|
|
||||||
interval: Interval,
|
|
||||||
data: T,
|
|
||||||
) -> Result<Delta, OTError> {
|
|
||||||
let _ = validate_interval(&self.delta, &interval)?;
|
let _ = validate_interval(&self.delta, &interval)?;
|
||||||
let mut delta = Delta::default();
|
let mut delta = Delta::default();
|
||||||
let text = data.into_string()?;
|
let text = data.into_string()?;
|
||||||
|
@ -95,9 +95,7 @@ impl Document {
|
||||||
|
|
||||||
pub fn undo(&mut self) -> Result<UndoResult, OTError> {
|
pub fn undo(&mut self) -> Result<UndoResult, OTError> {
|
||||||
match self.history.undo() {
|
match self.history.undo() {
|
||||||
None => Err(ErrorBuilder::new(UndoFail)
|
None => Err(ErrorBuilder::new(UndoFail).msg("Undo stack is empty").build()),
|
||||||
.msg("Undo stack is empty")
|
|
||||||
.build()),
|
|
||||||
Some(undo_delta) => {
|
Some(undo_delta) => {
|
||||||
let (new_delta, inverted_delta) = self.invert_change(&undo_delta)?;
|
let (new_delta, inverted_delta) = self.invert_change(&undo_delta)?;
|
||||||
let result = UndoResult::success(new_delta.target_len as usize);
|
let result = UndoResult::success(new_delta.target_len as usize);
|
||||||
|
@ -123,8 +121,6 @@ impl Document {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_json(&self) -> String { self.delta.to_json() }
|
|
||||||
|
|
||||||
pub fn to_string(&self) -> String { self.delta.apply("").unwrap() }
|
pub fn to_string(&self) -> String { self.delta.apply("").unwrap() }
|
||||||
|
|
||||||
pub fn data(&self) -> &Delta { &self.delta }
|
pub fn data(&self) -> &Delta { &self.delta }
|
||||||
|
@ -176,11 +172,7 @@ impl Document {
|
||||||
|
|
||||||
fn validate_interval(delta: &Delta, interval: &Interval) -> Result<(), OTError> {
|
fn validate_interval(delta: &Delta, interval: &Interval) -> Result<(), OTError> {
|
||||||
if delta.target_len < interval.end {
|
if delta.target_len < interval.end {
|
||||||
log::error!(
|
log::error!("{:?} out of bounds. should 0..{}", interval, delta.target_len);
|
||||||
"{:?} out of bounds. should 0..{}",
|
|
||||||
interval,
|
|
||||||
delta.target_len
|
|
||||||
);
|
|
||||||
return Err(ErrorBuilder::new(OTErrorCode::IntervalOutOfBound).build());
|
return Err(ErrorBuilder::new(OTErrorCode::IntervalOutOfBound).build());
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
mod data;
|
mod data;
|
||||||
mod document;
|
mod document;
|
||||||
|
mod selection;
|
||||||
|
|
||||||
pub use data::*;
|
pub use data::*;
|
||||||
pub use document::*;
|
pub use document::*;
|
||||||
|
|
0
rust-lib/flowy-ot/src/client/document/selection.rs
Normal file
|
@ -66,6 +66,13 @@ impl FromIterator<Operation> for Delta {
|
||||||
impl Delta {
|
impl Delta {
|
||||||
pub fn new() -> Self { Self::default() }
|
pub fn new() -> Self { Self::default() }
|
||||||
|
|
||||||
|
pub fn to_json(&self) -> String { serde_json::to_string(self).unwrap_or("".to_owned()) }
|
||||||
|
|
||||||
|
pub fn from_json(json: &str) -> Result<Self, OTError> {
|
||||||
|
let delta: Delta = serde_json::from_str(json)?;
|
||||||
|
Ok(delta)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_capacity(capacity: usize) -> Self {
|
pub fn with_capacity(capacity: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -136,8 +143,7 @@ impl Delta {
|
||||||
self.ops.push(new_op);
|
self.ops.push(new_op);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.ops
|
self.ops.push(OpBuilder::retain(n).attributes(attrs).build());
|
||||||
.push(OpBuilder::retain(n).attributes(attrs).build());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,39 +173,21 @@ impl Delta {
|
||||||
other_iter.next_op_len().unwrap_or(MAX_IV_LEN),
|
other_iter.next_op_len().unwrap_or(MAX_IV_LEN),
|
||||||
);
|
);
|
||||||
|
|
||||||
let op = iter
|
let op = iter.next_op_with_len(length).unwrap_or(OpBuilder::retain(length).build());
|
||||||
.next_op_with_len(length)
|
|
||||||
.unwrap_or(OpBuilder::retain(length).build());
|
|
||||||
|
|
||||||
let other_op = other_iter
|
let other_op = other_iter.next_op_with_len(length).unwrap_or(OpBuilder::retain(length).build());
|
||||||
.next_op_with_len(length)
|
|
||||||
.unwrap_or(OpBuilder::retain(length).build());
|
|
||||||
|
|
||||||
debug_assert_eq!(op.len(), other_op.len());
|
debug_assert_eq!(op.len(), other_op.len());
|
||||||
|
|
||||||
match (&op, &other_op) {
|
match (&op, &other_op) {
|
||||||
(Operation::Retain(retain), Operation::Retain(other_retain)) => {
|
(Operation::Retain(retain), Operation::Retain(other_retain)) => {
|
||||||
let composed_attrs = compose_attributes(
|
let composed_attrs = compose_attributes(retain.attributes.clone(), other_retain.attributes.clone());
|
||||||
retain.attributes.clone(),
|
new_delta.add(OpBuilder::retain(retain.n).attributes(composed_attrs).build())
|
||||||
other_retain.attributes.clone(),
|
|
||||||
);
|
|
||||||
new_delta.add(
|
|
||||||
OpBuilder::retain(retain.n)
|
|
||||||
.attributes(composed_attrs)
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
(Operation::Insert(insert), Operation::Retain(other_retain)) => {
|
(Operation::Insert(insert), Operation::Retain(other_retain)) => {
|
||||||
let mut composed_attrs = compose_attributes(
|
let mut composed_attrs = compose_attributes(insert.attributes.clone(), other_retain.attributes.clone());
|
||||||
insert.attributes.clone(),
|
|
||||||
other_retain.attributes.clone(),
|
|
||||||
);
|
|
||||||
composed_attrs.remove_empty();
|
composed_attrs.remove_empty();
|
||||||
new_delta.add(
|
new_delta.add(OpBuilder::insert(op.get_data()).attributes(composed_attrs).build())
|
||||||
OpBuilder::insert(op.get_data())
|
|
||||||
.attributes(composed_attrs)
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
(Operation::Retain(_), Operation::Delete(_)) => {
|
(Operation::Retain(_), Operation::Delete(_)) => {
|
||||||
new_delta.add(other_op);
|
new_delta.add(other_op);
|
||||||
|
@ -215,9 +203,7 @@ impl Delta {
|
||||||
Ok(new_delta)
|
Ok(new_delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deprecated(
|
#[deprecated(note = "The same as compose except it requires the target_len of self must equal to other's base_len")]
|
||||||
note = "The same as compose except it requires the target_len of self must equal to other's base_len"
|
|
||||||
)]
|
|
||||||
pub fn compose2(&self, other: &Self) -> Result<Self, OTError> {
|
pub fn compose2(&self, other: &Self) -> Result<Self, OTError> {
|
||||||
if self.target_len != other.base_len {
|
if self.target_len != other.base_len {
|
||||||
return Err(ErrorBuilder::new(OTErrorCode::IncompatibleLength).build());
|
return Err(ErrorBuilder::new(OTErrorCode::IncompatibleLength).build());
|
||||||
|
@ -245,12 +231,7 @@ impl Delta {
|
||||||
},
|
},
|
||||||
(Some(Operation::Retain(retain)), Some(Operation::Retain(o_retain))) => {
|
(Some(Operation::Retain(retain)), Some(Operation::Retain(o_retain))) => {
|
||||||
let composed_attrs = compose_operation(&next_op1, &next_op2);
|
let composed_attrs = compose_operation(&next_op1, &next_op2);
|
||||||
log::debug!(
|
log::debug!("[retain:{} - retain:{}]: {:?}", retain.n, o_retain.n, composed_attrs);
|
||||||
"[retain:{} - retain:{}]: {:?}",
|
|
||||||
retain.n,
|
|
||||||
o_retain.n,
|
|
||||||
composed_attrs
|
|
||||||
);
|
|
||||||
match retain.cmp(&o_retain) {
|
match retain.cmp(&o_retain) {
|
||||||
Ordering::Less => {
|
Ordering::Less => {
|
||||||
new_delta.retain(retain.n, composed_attrs);
|
new_delta.retain(retain.n, composed_attrs);
|
||||||
|
@ -288,12 +269,7 @@ impl Delta {
|
||||||
next_op2 = ops2.next();
|
next_op2 = ops2.next();
|
||||||
},
|
},
|
||||||
Ordering::Greater => {
|
Ordering::Greater => {
|
||||||
next_op1 = Some(
|
next_op1 = Some(OpBuilder::insert(&insert.chars().skip(*o_num as usize).collect::<String>()).build());
|
||||||
OpBuilder::insert(
|
|
||||||
&insert.chars().skip(*o_num as usize).collect::<String>(),
|
|
||||||
)
|
|
||||||
.build(),
|
|
||||||
);
|
|
||||||
next_op2 = ops2.next();
|
next_op2 = ops2.next();
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -302,12 +278,7 @@ impl Delta {
|
||||||
let mut composed_attrs = compose_operation(&next_op1, &next_op2);
|
let mut composed_attrs = compose_operation(&next_op1, &next_op2);
|
||||||
composed_attrs.remove_empty();
|
composed_attrs.remove_empty();
|
||||||
|
|
||||||
log::debug!(
|
log::debug!("compose: [{} - {}], composed_attrs: {}", insert, o_retain, composed_attrs);
|
||||||
"compose: [{} - {}], composed_attrs: {}",
|
|
||||||
insert,
|
|
||||||
o_retain,
|
|
||||||
composed_attrs
|
|
||||||
);
|
|
||||||
match (insert.num_chars()).cmp(o_retain) {
|
match (insert.num_chars()).cmp(o_retain) {
|
||||||
Ordering::Less => {
|
Ordering::Less => {
|
||||||
new_delta.insert(&insert.s, composed_attrs.clone());
|
new_delta.insert(&insert.s, composed_attrs.clone());
|
||||||
|
@ -325,33 +296,28 @@ impl Delta {
|
||||||
},
|
},
|
||||||
Ordering::Greater => {
|
Ordering::Greater => {
|
||||||
let chars = &mut insert.chars();
|
let chars = &mut insert.chars();
|
||||||
new_delta.insert(
|
new_delta.insert(&chars.take(o_retain.n as usize).collect::<String>(), composed_attrs);
|
||||||
&chars.take(o_retain.n as usize).collect::<String>(),
|
|
||||||
composed_attrs,
|
|
||||||
);
|
|
||||||
next_op1 = Some(OpBuilder::insert(&chars.collect::<String>()).build());
|
next_op1 = Some(OpBuilder::insert(&chars.collect::<String>()).build());
|
||||||
next_op2 = ops2.next();
|
next_op2 = ops2.next();
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(Some(Operation::Retain(retain)), Some(Operation::Delete(o_num))) => {
|
(Some(Operation::Retain(retain)), Some(Operation::Delete(o_num))) => match retain.cmp(&o_num) {
|
||||||
match retain.cmp(&o_num) {
|
Ordering::Less => {
|
||||||
Ordering::Less => {
|
new_delta.delete(retain.n);
|
||||||
new_delta.delete(retain.n);
|
next_op2 = Some(OpBuilder::delete(*o_num - retain.n).build());
|
||||||
next_op2 = Some(OpBuilder::delete(*o_num - retain.n).build());
|
next_op1 = ops1.next();
|
||||||
next_op1 = ops1.next();
|
},
|
||||||
},
|
Ordering::Equal => {
|
||||||
Ordering::Equal => {
|
new_delta.delete(*o_num);
|
||||||
new_delta.delete(*o_num);
|
next_op2 = ops2.next();
|
||||||
next_op2 = ops2.next();
|
next_op1 = ops1.next();
|
||||||
next_op1 = ops1.next();
|
},
|
||||||
},
|
Ordering::Greater => {
|
||||||
Ordering::Greater => {
|
new_delta.delete(*o_num);
|
||||||
new_delta.delete(*o_num);
|
next_op1 = Some(OpBuilder::retain(retain.n - *o_num).build());
|
||||||
next_op1 = Some(OpBuilder::retain(retain.n - *o_num).build());
|
next_op2 = ops2.next();
|
||||||
next_op2 = ops2.next();
|
},
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -534,10 +500,7 @@ impl Delta {
|
||||||
inverted.delete(insert.num_chars());
|
inverted.delete(insert.num_chars());
|
||||||
},
|
},
|
||||||
Operation::Delete(delete) => {
|
Operation::Delete(delete) => {
|
||||||
inverted.insert(
|
inverted.insert(&chars.take(*delete as usize).collect::<String>(), op.get_attributes());
|
||||||
&chars.take(*delete as usize).collect::<String>(),
|
|
||||||
op.get_attributes(),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -564,12 +527,7 @@ impl Delta {
|
||||||
match op.has_attribute() {
|
match op.has_attribute() {
|
||||||
true => invert_from_other(&mut inverted, other, op, index, index + len),
|
true => invert_from_other(&mut inverted, other, op, index, index + len),
|
||||||
false => {
|
false => {
|
||||||
log::debug!(
|
log::debug!("invert retain: {} by retain {} {}", op, len, op.get_attributes());
|
||||||
"invert retain: {} by retain {} {}",
|
|
||||||
op,
|
|
||||||
len,
|
|
||||||
op.get_attributes()
|
|
||||||
);
|
|
||||||
inverted.retain(len as usize, op.get_attributes())
|
inverted.retain(len as usize, op.get_attributes())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -598,18 +556,10 @@ impl Delta {
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool { self.ops.is_empty() }
|
pub fn is_empty(&self) -> bool { self.ops.is_empty() }
|
||||||
|
|
||||||
pub fn to_json(&self) -> String { serde_json::to_string(self).unwrap_or("".to_owned()) }
|
|
||||||
|
|
||||||
pub fn extend(&mut self, other: Self) { other.ops.into_iter().for_each(|op| self.add(op)); }
|
pub fn extend(&mut self, other: Self) { other.ops.into_iter().for_each(|op| self.add(op)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invert_from_other(
|
fn invert_from_other(base: &mut Delta, other: &Delta, operation: &Operation, start: usize, end: usize) {
|
||||||
base: &mut Delta,
|
|
||||||
other: &Delta,
|
|
||||||
operation: &Operation,
|
|
||||||
start: usize,
|
|
||||||
end: usize,
|
|
||||||
) {
|
|
||||||
log::debug!("invert op: {} [{}:{}]", operation, start, end);
|
log::debug!("invert op: {} [{}:{}]", operation, start, end);
|
||||||
let other_ops = DeltaIter::from_interval(other, Interval::new(start, end)).ops();
|
let other_ops = DeltaIter::from_interval(other, Interval::new(start, end)).ops();
|
||||||
other_ops.into_iter().for_each(|other_op| match operation {
|
other_ops.into_iter().for_each(|other_op| match operation {
|
||||||
|
@ -623,15 +573,9 @@ fn invert_from_other(
|
||||||
operation.get_attributes(),
|
operation.get_attributes(),
|
||||||
other_op.get_attributes()
|
other_op.get_attributes()
|
||||||
);
|
);
|
||||||
let inverted_attrs =
|
let inverted_attrs = invert_attributes(operation.get_attributes(), other_op.get_attributes());
|
||||||
invert_attributes(operation.get_attributes(), other_op.get_attributes());
|
|
||||||
log::debug!("invert attributes result: {:?}", inverted_attrs);
|
log::debug!("invert attributes result: {:?}", inverted_attrs);
|
||||||
log::debug!(
|
log::debug!("invert retain: {} by retain len: {}, {}", retain, other_op.len(), inverted_attrs);
|
||||||
"invert retain: {} by retain len: {}, {}",
|
|
||||||
retain,
|
|
||||||
other_op.len(),
|
|
||||||
inverted_attrs
|
|
||||||
);
|
|
||||||
base.retain(other_op.len(), inverted_attrs);
|
base.retain(other_op.len(), inverted_attrs);
|
||||||
},
|
},
|
||||||
Operation::Insert(_) => {
|
Operation::Insert(_) => {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use flowy_ot::core::*;
|
use flowy_ot::{client::Document, core::*};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn operation_insert_serialize_test() {
|
fn operation_insert_serialize_test() {
|
||||||
|
@ -42,6 +42,16 @@ fn delta_serialize_test() {
|
||||||
let json = serde_json::to_string(&delta).unwrap();
|
let json = serde_json::to_string(&delta).unwrap();
|
||||||
eprintln!("{}", json);
|
eprintln!("{}", json);
|
||||||
|
|
||||||
let delta_from_json: Delta = serde_json::from_str(&json).unwrap();
|
let delta_from_json = Delta::from_json(&json).unwrap();
|
||||||
assert_eq!(delta_from_json, delta);
|
assert_eq!(delta_from_json, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn document_insert_serde_test() {
|
||||||
|
let mut document = Document::new();
|
||||||
|
document.insert(0, "\n");
|
||||||
|
document.insert(0, "123");
|
||||||
|
let json = document.to_json();
|
||||||
|
assert_eq!(r#"[{"insert":"123\n"}]"#, json);
|
||||||
|
assert_eq!(r#"[{"insert":"123\n"}]"#, Document::from_json(&json).unwrap().to_json());
|
||||||
|
}
|
||||||
|
|
|
@ -95,6 +95,7 @@ impl TryInto<CreateViewParams> for CreateViewRequest {
|
||||||
desc: self.desc,
|
desc: self.desc,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
view_type: self.view_type,
|
view_type: self.view_type,
|
||||||
|
// TODO: replace the placeholder
|
||||||
data: "[{\"insert\":\"\\n\"}]".to_owned(),
|
data: "[{\"insert\":\"\\n\"}]".to_owned(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|