mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[flutter]: restore the doc page from banner
This commit is contained in:
parent
0606cd4ce9
commit
ddfe985065
@ -1,6 +1,8 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:app_flowy/workspace/domain/i_trash.dart';
|
||||
import 'package:app_flowy/workspace/domain/i_view.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||
import 'package:flutter_quill/flutter_quill.dart';
|
||||
import 'package:flowy_log/flowy_log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||
@ -12,12 +14,19 @@ import 'dart:async';
|
||||
part 'doc_bloc.freezed.dart';
|
||||
|
||||
class DocBloc extends Bloc<DocEvent, DocState> {
|
||||
final View view;
|
||||
final IDoc docManager;
|
||||
final IViewListener listener;
|
||||
final ITrash trasnManager;
|
||||
late Document document;
|
||||
late StreamSubscription _subscription;
|
||||
|
||||
DocBloc({required this.docManager, required this.listener}) : super(DocState.initial());
|
||||
DocBloc({
|
||||
required this.view,
|
||||
required this.docManager,
|
||||
required this.listener,
|
||||
required this.trasnManager,
|
||||
}) : super(DocState.initial());
|
||||
|
||||
@override
|
||||
Stream<DocState> mapEventToState(DocEvent event) async* {
|
||||
@ -29,6 +38,17 @@ class DocBloc extends Bloc<DocEvent, DocState> {
|
||||
restore: (Restore value) async* {
|
||||
yield state.copyWith(isDeleted: false);
|
||||
},
|
||||
deletePermanently: (DeletePermanently value) async* {
|
||||
// final result = await trasnManager.deleteViews([e.trash]);
|
||||
// yield* _handleResult(result);
|
||||
yield state;
|
||||
},
|
||||
restorePage: (RestorePage value) async* {
|
||||
final result = await trasnManager.putback(view.id);
|
||||
yield result.fold((l) => state.copyWith(isDeleted: false), (r) {
|
||||
return state;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -107,6 +127,8 @@ class DocEvent with _$DocEvent {
|
||||
const factory DocEvent.initial() = Initial;
|
||||
const factory DocEvent.deleted() = Deleted;
|
||||
const factory DocEvent.restore() = Restore;
|
||||
const factory DocEvent.restorePage() = RestorePage;
|
||||
const factory DocEvent.deletePermanently() = DeletePermanently;
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -27,6 +27,14 @@ class _$DocEventTearOff {
|
||||
Restore restore() {
|
||||
return const Restore();
|
||||
}
|
||||
|
||||
RestorePage restorePage() {
|
||||
return const RestorePage();
|
||||
}
|
||||
|
||||
DeletePermanently deletePermanently() {
|
||||
return const DeletePermanently();
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@ -39,6 +47,8 @@ mixin _$DocEvent {
|
||||
required TResult Function() initial,
|
||||
required TResult Function() deleted,
|
||||
required TResult Function() restore,
|
||||
required TResult Function() restorePage,
|
||||
required TResult Function() deletePermanently,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
@ -46,6 +56,8 @@ mixin _$DocEvent {
|
||||
TResult Function()? initial,
|
||||
TResult Function()? deleted,
|
||||
TResult Function()? restore,
|
||||
TResult Function()? restorePage,
|
||||
TResult Function()? deletePermanently,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@ -54,6 +66,8 @@ mixin _$DocEvent {
|
||||
required TResult Function(Initial value) initial,
|
||||
required TResult Function(Deleted value) deleted,
|
||||
required TResult Function(Restore value) restore,
|
||||
required TResult Function(RestorePage value) restorePage,
|
||||
required TResult Function(DeletePermanently value) deletePermanently,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
@ -61,6 +75,8 @@ mixin _$DocEvent {
|
||||
TResult Function(Initial value)? initial,
|
||||
TResult Function(Deleted value)? deleted,
|
||||
TResult Function(Restore value)? restore,
|
||||
TResult Function(RestorePage value)? restorePage,
|
||||
TResult Function(DeletePermanently value)? deletePermanently,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@ -121,6 +137,8 @@ class _$Initial implements Initial {
|
||||
required TResult Function() initial,
|
||||
required TResult Function() deleted,
|
||||
required TResult Function() restore,
|
||||
required TResult Function() restorePage,
|
||||
required TResult Function() deletePermanently,
|
||||
}) {
|
||||
return initial();
|
||||
}
|
||||
@ -131,6 +149,8 @@ class _$Initial implements Initial {
|
||||
TResult Function()? initial,
|
||||
TResult Function()? deleted,
|
||||
TResult Function()? restore,
|
||||
TResult Function()? restorePage,
|
||||
TResult Function()? deletePermanently,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (initial != null) {
|
||||
@ -145,6 +165,8 @@ class _$Initial implements Initial {
|
||||
required TResult Function(Initial value) initial,
|
||||
required TResult Function(Deleted value) deleted,
|
||||
required TResult Function(Restore value) restore,
|
||||
required TResult Function(RestorePage value) restorePage,
|
||||
required TResult Function(DeletePermanently value) deletePermanently,
|
||||
}) {
|
||||
return initial(this);
|
||||
}
|
||||
@ -155,6 +177,8 @@ class _$Initial implements Initial {
|
||||
TResult Function(Initial value)? initial,
|
||||
TResult Function(Deleted value)? deleted,
|
||||
TResult Function(Restore value)? restore,
|
||||
TResult Function(RestorePage value)? restorePage,
|
||||
TResult Function(DeletePermanently value)? deletePermanently,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (initial != null) {
|
||||
@ -208,6 +232,8 @@ class _$Deleted implements Deleted {
|
||||
required TResult Function() initial,
|
||||
required TResult Function() deleted,
|
||||
required TResult Function() restore,
|
||||
required TResult Function() restorePage,
|
||||
required TResult Function() deletePermanently,
|
||||
}) {
|
||||
return deleted();
|
||||
}
|
||||
@ -218,6 +244,8 @@ class _$Deleted implements Deleted {
|
||||
TResult Function()? initial,
|
||||
TResult Function()? deleted,
|
||||
TResult Function()? restore,
|
||||
TResult Function()? restorePage,
|
||||
TResult Function()? deletePermanently,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (deleted != null) {
|
||||
@ -232,6 +260,8 @@ class _$Deleted implements Deleted {
|
||||
required TResult Function(Initial value) initial,
|
||||
required TResult Function(Deleted value) deleted,
|
||||
required TResult Function(Restore value) restore,
|
||||
required TResult Function(RestorePage value) restorePage,
|
||||
required TResult Function(DeletePermanently value) deletePermanently,
|
||||
}) {
|
||||
return deleted(this);
|
||||
}
|
||||
@ -242,6 +272,8 @@ class _$Deleted implements Deleted {
|
||||
TResult Function(Initial value)? initial,
|
||||
TResult Function(Deleted value)? deleted,
|
||||
TResult Function(Restore value)? restore,
|
||||
TResult Function(RestorePage value)? restorePage,
|
||||
TResult Function(DeletePermanently value)? deletePermanently,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (deleted != null) {
|
||||
@ -295,6 +327,8 @@ class _$Restore implements Restore {
|
||||
required TResult Function() initial,
|
||||
required TResult Function() deleted,
|
||||
required TResult Function() restore,
|
||||
required TResult Function() restorePage,
|
||||
required TResult Function() deletePermanently,
|
||||
}) {
|
||||
return restore();
|
||||
}
|
||||
@ -305,6 +339,8 @@ class _$Restore implements Restore {
|
||||
TResult Function()? initial,
|
||||
TResult Function()? deleted,
|
||||
TResult Function()? restore,
|
||||
TResult Function()? restorePage,
|
||||
TResult Function()? deletePermanently,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (restore != null) {
|
||||
@ -319,6 +355,8 @@ class _$Restore implements Restore {
|
||||
required TResult Function(Initial value) initial,
|
||||
required TResult Function(Deleted value) deleted,
|
||||
required TResult Function(Restore value) restore,
|
||||
required TResult Function(RestorePage value) restorePage,
|
||||
required TResult Function(DeletePermanently value) deletePermanently,
|
||||
}) {
|
||||
return restore(this);
|
||||
}
|
||||
@ -329,6 +367,8 @@ class _$Restore implements Restore {
|
||||
TResult Function(Initial value)? initial,
|
||||
TResult Function(Deleted value)? deleted,
|
||||
TResult Function(Restore value)? restore,
|
||||
TResult Function(RestorePage value)? restorePage,
|
||||
TResult Function(DeletePermanently value)? deletePermanently,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (restore != null) {
|
||||
@ -342,6 +382,200 @@ abstract class Restore implements DocEvent {
|
||||
const factory Restore() = _$Restore;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $RestorePageCopyWith<$Res> {
|
||||
factory $RestorePageCopyWith(
|
||||
RestorePage value, $Res Function(RestorePage) then) =
|
||||
_$RestorePageCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$RestorePageCopyWithImpl<$Res> extends _$DocEventCopyWithImpl<$Res>
|
||||
implements $RestorePageCopyWith<$Res> {
|
||||
_$RestorePageCopyWithImpl(
|
||||
RestorePage _value, $Res Function(RestorePage) _then)
|
||||
: super(_value, (v) => _then(v as RestorePage));
|
||||
|
||||
@override
|
||||
RestorePage get _value => super._value as RestorePage;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$RestorePage implements RestorePage {
|
||||
const _$RestorePage();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DocEvent.restorePage()';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) || (other is RestorePage);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() deleted,
|
||||
required TResult Function() restore,
|
||||
required TResult Function() restorePage,
|
||||
required TResult Function() deletePermanently,
|
||||
}) {
|
||||
return restorePage();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? deleted,
|
||||
TResult Function()? restore,
|
||||
TResult Function()? restorePage,
|
||||
TResult Function()? deletePermanently,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (restorePage != null) {
|
||||
return restorePage();
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(Initial value) initial,
|
||||
required TResult Function(Deleted value) deleted,
|
||||
required TResult Function(Restore value) restore,
|
||||
required TResult Function(RestorePage value) restorePage,
|
||||
required TResult Function(DeletePermanently value) deletePermanently,
|
||||
}) {
|
||||
return restorePage(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(Initial value)? initial,
|
||||
TResult Function(Deleted value)? deleted,
|
||||
TResult Function(Restore value)? restore,
|
||||
TResult Function(RestorePage value)? restorePage,
|
||||
TResult Function(DeletePermanently value)? deletePermanently,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (restorePage != null) {
|
||||
return restorePage(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class RestorePage implements DocEvent {
|
||||
const factory RestorePage() = _$RestorePage;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $DeletePermanentlyCopyWith<$Res> {
|
||||
factory $DeletePermanentlyCopyWith(
|
||||
DeletePermanently value, $Res Function(DeletePermanently) then) =
|
||||
_$DeletePermanentlyCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$DeletePermanentlyCopyWithImpl<$Res> extends _$DocEventCopyWithImpl<$Res>
|
||||
implements $DeletePermanentlyCopyWith<$Res> {
|
||||
_$DeletePermanentlyCopyWithImpl(
|
||||
DeletePermanently _value, $Res Function(DeletePermanently) _then)
|
||||
: super(_value, (v) => _then(v as DeletePermanently));
|
||||
|
||||
@override
|
||||
DeletePermanently get _value => super._value as DeletePermanently;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$DeletePermanently implements DeletePermanently {
|
||||
const _$DeletePermanently();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DocEvent.deletePermanently()';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) || (other is DeletePermanently);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() deleted,
|
||||
required TResult Function() restore,
|
||||
required TResult Function() restorePage,
|
||||
required TResult Function() deletePermanently,
|
||||
}) {
|
||||
return deletePermanently();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? deleted,
|
||||
TResult Function()? restore,
|
||||
TResult Function()? restorePage,
|
||||
TResult Function()? deletePermanently,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (deletePermanently != null) {
|
||||
return deletePermanently();
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(Initial value) initial,
|
||||
required TResult Function(Deleted value) deleted,
|
||||
required TResult Function(Restore value) restore,
|
||||
required TResult Function(RestorePage value) restorePage,
|
||||
required TResult Function(DeletePermanently value) deletePermanently,
|
||||
}) {
|
||||
return deletePermanently(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(Initial value)? initial,
|
||||
TResult Function(Deleted value)? deleted,
|
||||
TResult Function(Restore value)? restore,
|
||||
TResult Function(RestorePage value)? restorePage,
|
||||
TResult Function(DeletePermanently value)? deletePermanently,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (deletePermanently != null) {
|
||||
return deletePermanently(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DeletePermanently implements DocEvent {
|
||||
const factory DeletePermanently() = _$DeletePermanently;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$DocStateTearOff {
|
||||
const _$DocStateTearOff();
|
||||
|
@ -89,8 +89,10 @@ class HomeDepsResolver {
|
||||
// Doc
|
||||
getIt.registerFactoryParam<DocBloc, View, void>(
|
||||
(view, _) => DocBloc(
|
||||
view: view,
|
||||
docManager: getIt<IDoc>(param1: view.id),
|
||||
listener: getIt<IViewListener>(param1: view),
|
||||
trasnManager: getIt<ITrash>(),
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -2,7 +2,7 @@ import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/doc/doc_bloc.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter_quill/flutter_quill.dart';
|
||||
import 'package:flutter_quill/flutter_quill.dart' as quill;
|
||||
import 'package:flowy_infra_ui/style_widget/progress_indicator.dart';
|
||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||
@ -10,6 +10,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'styles.dart';
|
||||
import 'widget/banner.dart';
|
||||
import 'widget/toolbar/tool_bar.dart';
|
||||
|
||||
class DocPage extends StatefulWidget {
|
||||
@ -42,7 +43,7 @@ class _DocPageState extends State<DocPage> {
|
||||
return state.loadState.map(
|
||||
loading: (_) => const FlowyProgressIndicator(),
|
||||
finish: (result) => result.successOrFail.fold(
|
||||
(_) => _renderDoc(context),
|
||||
(_) => _renderDoc(context, state),
|
||||
(err) => FlowyErrorPage(err.toString()),
|
||||
),
|
||||
);
|
||||
@ -56,24 +57,42 @@ class _DocPageState extends State<DocPage> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Widget _renderDoc(BuildContext context) {
|
||||
QuillController controller = QuillController(
|
||||
Widget _renderDoc(BuildContext context, DocState state) {
|
||||
quill.QuillController controller = quill.QuillController(
|
||||
document: context.read<DocBloc>().document,
|
||||
selection: const TextSelection.collapsed(offset: 0),
|
||||
);
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_renderEditor(controller),
|
||||
const VSpace(10),
|
||||
_renderToolbar(controller),
|
||||
const VSpace(10),
|
||||
if (state.isDeleted) _renderBanner(context),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_renderEditor(controller),
|
||||
const VSpace(10),
|
||||
_renderToolbar(controller),
|
||||
const VSpace(10),
|
||||
],
|
||||
).padding(horizontal: 40, top: 28),
|
||||
),
|
||||
],
|
||||
).padding(horizontal: 40, top: 28);
|
||||
);
|
||||
}
|
||||
|
||||
Widget _renderEditor(QuillController controller) {
|
||||
final editor = QuillEditor(
|
||||
Widget _renderBanner(BuildContext context) {
|
||||
return DocBanner(
|
||||
onRestore: () {
|
||||
context.read<DocBloc>().add(const DocEvent.restorePage());
|
||||
},
|
||||
onDelete: () {
|
||||
context.read<DocBloc>().add(const DocEvent.deletePermanently());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _renderEditor(quill.QuillController controller) {
|
||||
final editor = quill.QuillEditor(
|
||||
controller: controller,
|
||||
focusNode: _focusNode,
|
||||
scrollable: true,
|
||||
@ -96,7 +115,7 @@ class _DocPageState extends State<DocPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _renderToolbar(QuillController controller) {
|
||||
Widget _renderToolbar(quill.QuillController controller) {
|
||||
return EditorToolbar.basic(
|
||||
controller: controller,
|
||||
);
|
||||
|
@ -0,0 +1,55 @@
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/widget/buttons/base_styled_button.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class DocBanner extends StatelessWidget {
|
||||
final void Function() onRestore;
|
||||
final void Function() onDelete;
|
||||
const DocBanner({required this.onRestore, required this.onDelete, Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
// [[Row]] CrossAxisAlignment vs mainAxisAlignment
|
||||
// https://stackoverflow.com/questions/53850149/flutter-crossaxisalignment-vs-mainaxisalignment
|
||||
return Container(
|
||||
color: theme.main1,
|
||||
height: 60,
|
||||
child: Row(
|
||||
children: [
|
||||
const FlowyText.medium('This page is in Trash', color: Colors.white),
|
||||
const HSpace(20),
|
||||
BaseStyledButton(
|
||||
minWidth: 160,
|
||||
minHeight: 40,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
bgColor: Colors.transparent,
|
||||
hoverColor: theme.main2,
|
||||
downColor: theme.main1,
|
||||
outlineColor: Colors.white,
|
||||
borderRadius: Corners.s8Border,
|
||||
child: const FlowyText.medium('Restore page', color: Colors.white, fontSize: 14),
|
||||
onPressed: onRestore),
|
||||
const HSpace(20),
|
||||
BaseStyledButton(
|
||||
minWidth: 220,
|
||||
minHeight: 40,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
bgColor: Colors.transparent,
|
||||
hoverColor: theme.main2,
|
||||
downColor: theme.main1,
|
||||
outlineColor: Colors.white,
|
||||
borderRadius: Corners.s8Border,
|
||||
child: const FlowyText.medium('Delete permanently', color: Colors.white, fontSize: 14),
|
||||
onPressed: onDelete),
|
||||
],
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user