浏览代码

[flutter]: restore the doc page from banner

appflowy 3 年之前
父节点
当前提交
ddfe985065

+ 23 - 1
app_flowy/lib/workspace/application/doc/doc_bloc.dart

@@ -1,6 +1,8 @@
 import 'dart:convert';
 import 'dart:convert';
 
 
+import 'package:app_flowy/workspace/domain/i_trash.dart';
 import 'package:app_flowy/workspace/domain/i_view.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:flutter_quill/flutter_quill.dart';
 import 'package:flowy_log/flowy_log.dart';
 import 'package:flowy_log/flowy_log.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
@@ -12,12 +14,19 @@ import 'dart:async';
 part 'doc_bloc.freezed.dart';
 part 'doc_bloc.freezed.dart';
 
 
 class DocBloc extends Bloc<DocEvent, DocState> {
 class DocBloc extends Bloc<DocEvent, DocState> {
+  final View view;
   final IDoc docManager;
   final IDoc docManager;
   final IViewListener listener;
   final IViewListener listener;
+  final ITrash trasnManager;
   late Document document;
   late Document document;
   late StreamSubscription _subscription;
   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
   @override
   Stream<DocState> mapEventToState(DocEvent event) async* {
   Stream<DocState> mapEventToState(DocEvent event) async* {
@@ -29,6 +38,17 @@ class DocBloc extends Bloc<DocEvent, DocState> {
       restore: (Restore value) async* {
       restore: (Restore value) async* {
         yield state.copyWith(isDeleted: false);
         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.initial() = Initial;
   const factory DocEvent.deleted() = Deleted;
   const factory DocEvent.deleted() = Deleted;
   const factory DocEvent.restore() = Restore;
   const factory DocEvent.restore() = Restore;
+  const factory DocEvent.restorePage() = RestorePage;
+  const factory DocEvent.deletePermanently() = DeletePermanently;
 }
 }
 
 
 @freezed
 @freezed

+ 234 - 0
app_flowy/lib/workspace/application/doc/doc_bloc.freezed.dart

@@ -27,6 +27,14 @@ class _$DocEventTearOff {
   Restore restore() {
   Restore restore() {
     return const Restore();
     return const Restore();
   }
   }
+
+  RestorePage restorePage() {
+    return const RestorePage();
+  }
+
+  DeletePermanently deletePermanently() {
+    return const DeletePermanently();
+  }
 }
 }
 
 
 /// @nodoc
 /// @nodoc
@@ -39,6 +47,8 @@ mixin _$DocEvent {
     required TResult Function() initial,
     required TResult Function() initial,
     required TResult Function() deleted,
     required TResult Function() deleted,
     required TResult Function() restore,
     required TResult Function() restore,
+    required TResult Function() restorePage,
+    required TResult Function() deletePermanently,
   }) =>
   }) =>
       throw _privateConstructorUsedError;
       throw _privateConstructorUsedError;
   @optionalTypeArgs
   @optionalTypeArgs
@@ -46,6 +56,8 @@ mixin _$DocEvent {
     TResult Function()? initial,
     TResult Function()? initial,
     TResult Function()? deleted,
     TResult Function()? deleted,
     TResult Function()? restore,
     TResult Function()? restore,
+    TResult Function()? restorePage,
+    TResult Function()? deletePermanently,
     required TResult orElse(),
     required TResult orElse(),
   }) =>
   }) =>
       throw _privateConstructorUsedError;
       throw _privateConstructorUsedError;
@@ -54,6 +66,8 @@ mixin _$DocEvent {
     required TResult Function(Initial value) initial,
     required TResult Function(Initial value) initial,
     required TResult Function(Deleted value) deleted,
     required TResult Function(Deleted value) deleted,
     required TResult Function(Restore value) restore,
     required TResult Function(Restore value) restore,
+    required TResult Function(RestorePage value) restorePage,
+    required TResult Function(DeletePermanently value) deletePermanently,
   }) =>
   }) =>
       throw _privateConstructorUsedError;
       throw _privateConstructorUsedError;
   @optionalTypeArgs
   @optionalTypeArgs
@@ -61,6 +75,8 @@ mixin _$DocEvent {
     TResult Function(Initial value)? initial,
     TResult Function(Initial value)? initial,
     TResult Function(Deleted value)? deleted,
     TResult Function(Deleted value)? deleted,
     TResult Function(Restore value)? restore,
     TResult Function(Restore value)? restore,
+    TResult Function(RestorePage value)? restorePage,
+    TResult Function(DeletePermanently value)? deletePermanently,
     required TResult orElse(),
     required TResult orElse(),
   }) =>
   }) =>
       throw _privateConstructorUsedError;
       throw _privateConstructorUsedError;
@@ -121,6 +137,8 @@ class _$Initial implements Initial {
     required TResult Function() initial,
     required TResult Function() initial,
     required TResult Function() deleted,
     required TResult Function() deleted,
     required TResult Function() restore,
     required TResult Function() restore,
+    required TResult Function() restorePage,
+    required TResult Function() deletePermanently,
   }) {
   }) {
     return initial();
     return initial();
   }
   }
@@ -131,6 +149,8 @@ class _$Initial implements Initial {
     TResult Function()? initial,
     TResult Function()? initial,
     TResult Function()? deleted,
     TResult Function()? deleted,
     TResult Function()? restore,
     TResult Function()? restore,
+    TResult Function()? restorePage,
+    TResult Function()? deletePermanently,
     required TResult orElse(),
     required TResult orElse(),
   }) {
   }) {
     if (initial != null) {
     if (initial != null) {
@@ -145,6 +165,8 @@ class _$Initial implements Initial {
     required TResult Function(Initial value) initial,
     required TResult Function(Initial value) initial,
     required TResult Function(Deleted value) deleted,
     required TResult Function(Deleted value) deleted,
     required TResult Function(Restore value) restore,
     required TResult Function(Restore value) restore,
+    required TResult Function(RestorePage value) restorePage,
+    required TResult Function(DeletePermanently value) deletePermanently,
   }) {
   }) {
     return initial(this);
     return initial(this);
   }
   }
@@ -155,6 +177,8 @@ class _$Initial implements Initial {
     TResult Function(Initial value)? initial,
     TResult Function(Initial value)? initial,
     TResult Function(Deleted value)? deleted,
     TResult Function(Deleted value)? deleted,
     TResult Function(Restore value)? restore,
     TResult Function(Restore value)? restore,
+    TResult Function(RestorePage value)? restorePage,
+    TResult Function(DeletePermanently value)? deletePermanently,
     required TResult orElse(),
     required TResult orElse(),
   }) {
   }) {
     if (initial != null) {
     if (initial != null) {
@@ -208,6 +232,8 @@ class _$Deleted implements Deleted {
     required TResult Function() initial,
     required TResult Function() initial,
     required TResult Function() deleted,
     required TResult Function() deleted,
     required TResult Function() restore,
     required TResult Function() restore,
+    required TResult Function() restorePage,
+    required TResult Function() deletePermanently,
   }) {
   }) {
     return deleted();
     return deleted();
   }
   }
@@ -218,6 +244,8 @@ class _$Deleted implements Deleted {
     TResult Function()? initial,
     TResult Function()? initial,
     TResult Function()? deleted,
     TResult Function()? deleted,
     TResult Function()? restore,
     TResult Function()? restore,
+    TResult Function()? restorePage,
+    TResult Function()? deletePermanently,
     required TResult orElse(),
     required TResult orElse(),
   }) {
   }) {
     if (deleted != null) {
     if (deleted != null) {
@@ -232,6 +260,8 @@ class _$Deleted implements Deleted {
     required TResult Function(Initial value) initial,
     required TResult Function(Initial value) initial,
     required TResult Function(Deleted value) deleted,
     required TResult Function(Deleted value) deleted,
     required TResult Function(Restore value) restore,
     required TResult Function(Restore value) restore,
+    required TResult Function(RestorePage value) restorePage,
+    required TResult Function(DeletePermanently value) deletePermanently,
   }) {
   }) {
     return deleted(this);
     return deleted(this);
   }
   }
@@ -242,6 +272,8 @@ class _$Deleted implements Deleted {
     TResult Function(Initial value)? initial,
     TResult Function(Initial value)? initial,
     TResult Function(Deleted value)? deleted,
     TResult Function(Deleted value)? deleted,
     TResult Function(Restore value)? restore,
     TResult Function(Restore value)? restore,
+    TResult Function(RestorePage value)? restorePage,
+    TResult Function(DeletePermanently value)? deletePermanently,
     required TResult orElse(),
     required TResult orElse(),
   }) {
   }) {
     if (deleted != null) {
     if (deleted != null) {
@@ -295,6 +327,8 @@ class _$Restore implements Restore {
     required TResult Function() initial,
     required TResult Function() initial,
     required TResult Function() deleted,
     required TResult Function() deleted,
     required TResult Function() restore,
     required TResult Function() restore,
+    required TResult Function() restorePage,
+    required TResult Function() deletePermanently,
   }) {
   }) {
     return restore();
     return restore();
   }
   }
@@ -305,6 +339,8 @@ class _$Restore implements Restore {
     TResult Function()? initial,
     TResult Function()? initial,
     TResult Function()? deleted,
     TResult Function()? deleted,
     TResult Function()? restore,
     TResult Function()? restore,
+    TResult Function()? restorePage,
+    TResult Function()? deletePermanently,
     required TResult orElse(),
     required TResult orElse(),
   }) {
   }) {
     if (restore != null) {
     if (restore != null) {
@@ -319,6 +355,8 @@ class _$Restore implements Restore {
     required TResult Function(Initial value) initial,
     required TResult Function(Initial value) initial,
     required TResult Function(Deleted value) deleted,
     required TResult Function(Deleted value) deleted,
     required TResult Function(Restore value) restore,
     required TResult Function(Restore value) restore,
+    required TResult Function(RestorePage value) restorePage,
+    required TResult Function(DeletePermanently value) deletePermanently,
   }) {
   }) {
     return restore(this);
     return restore(this);
   }
   }
@@ -329,6 +367,8 @@ class _$Restore implements Restore {
     TResult Function(Initial value)? initial,
     TResult Function(Initial value)? initial,
     TResult Function(Deleted value)? deleted,
     TResult Function(Deleted value)? deleted,
     TResult Function(Restore value)? restore,
     TResult Function(Restore value)? restore,
+    TResult Function(RestorePage value)? restorePage,
+    TResult Function(DeletePermanently value)? deletePermanently,
     required TResult orElse(),
     required TResult orElse(),
   }) {
   }) {
     if (restore != null) {
     if (restore != null) {
@@ -342,6 +382,200 @@ abstract class Restore implements DocEvent {
   const factory Restore() = _$Restore;
   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
 /// @nodoc
 class _$DocStateTearOff {
 class _$DocStateTearOff {
   const _$DocStateTearOff();
   const _$DocStateTearOff();

+ 2 - 0
app_flowy/lib/workspace/infrastructure/deps_resolver.dart

@@ -89,8 +89,10 @@ class HomeDepsResolver {
     // Doc
     // Doc
     getIt.registerFactoryParam<DocBloc, View, void>(
     getIt.registerFactoryParam<DocBloc, View, void>(
       (view, _) => DocBloc(
       (view, _) => DocBloc(
+        view: view,
         docManager: getIt<IDoc>(param1: view.id),
         docManager: getIt<IDoc>(param1: view.id),
         listener: getIt<IViewListener>(param1: view),
         listener: getIt<IViewListener>(param1: view),
+        trasnManager: getIt<ITrash>(),
       ),
       ),
     );
     );
 
 

+ 32 - 13
app_flowy/lib/workspace/presentation/stack_page/doc/doc_page.dart

@@ -2,7 +2,7 @@ import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/workspace/application/doc/doc_bloc.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/style_widget/scrolling/styled_scroll_bar.dart';
 import 'package:flowy_infra_ui/widget/spacing.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/style_widget/progress_indicator.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';
@@ -10,6 +10,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:styled_widget/styled_widget.dart';
 import 'package:styled_widget/styled_widget.dart';
 import 'styles.dart';
 import 'styles.dart';
+import 'widget/banner.dart';
 import 'widget/toolbar/tool_bar.dart';
 import 'widget/toolbar/tool_bar.dart';
 
 
 class DocPage extends StatefulWidget {
 class DocPage extends StatefulWidget {
@@ -42,7 +43,7 @@ class _DocPageState extends State<DocPage> {
         return state.loadState.map(
         return state.loadState.map(
           loading: (_) => const FlowyProgressIndicator(),
           loading: (_) => const FlowyProgressIndicator(),
           finish: (result) => result.successOrFail.fold(
           finish: (result) => result.successOrFail.fold(
-            (_) => _renderDoc(context),
+            (_) => _renderDoc(context, state),
             (err) => FlowyErrorPage(err.toString()),
             (err) => FlowyErrorPage(err.toString()),
           ),
           ),
         );
         );
@@ -56,24 +57,42 @@ class _DocPageState extends State<DocPage> {
     super.dispose();
     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,
       document: context.read<DocBloc>().document,
       selection: const TextSelection.collapsed(offset: 0),
       selection: const TextSelection.collapsed(offset: 0),
     );
     );
     return Column(
     return Column(
-      mainAxisAlignment: MainAxisAlignment.spaceBetween,
       children: [
       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 _renderBanner(BuildContext context) {
+    return DocBanner(
+      onRestore: () {
+        context.read<DocBloc>().add(const DocEvent.restorePage());
+      },
+      onDelete: () {
+        context.read<DocBloc>().add(const DocEvent.deletePermanently());
+      },
+    );
   }
   }
 
 
-  Widget _renderEditor(QuillController controller) {
-    final editor = QuillEditor(
+  Widget _renderEditor(quill.QuillController controller) {
+    final editor = quill.QuillEditor(
       controller: controller,
       controller: controller,
       focusNode: _focusNode,
       focusNode: _focusNode,
       scrollable: true,
       scrollable: true,
@@ -96,7 +115,7 @@ class _DocPageState extends State<DocPage> {
     );
     );
   }
   }
 
 
-  Widget _renderToolbar(QuillController controller) {
+  Widget _renderToolbar(quill.QuillController controller) {
     return EditorToolbar.basic(
     return EditorToolbar.basic(
       controller: controller,
       controller: controller,
     );
     );

+ 55 - 0
app_flowy/lib/workspace/presentation/stack_page/doc/widget/banner.dart

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