add flowy icon

This commit is contained in:
appflowy 2021-09-12 22:19:59 +08:00
parent a4338652e0
commit 54136c1018
34 changed files with 168 additions and 280 deletions

View file

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

View file

@ -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);

View file

@ -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);

View file

@ -1,2 +1,2 @@
export 'application_task.dart'; export 'application_task.dart';
export 'rust_sdk_init_task.dart'; export 'sdk_task.dart';

View file

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

View file

@ -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(),
}) { }) {

View file

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

View file

@ -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),

View file

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

View file

@ -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(

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -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() {

View file

@ -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),

View file

@ -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(())

View file

@ -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::*;

View 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(_) => {

View file

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

View file

@ -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(),
}) })
} }