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