document_page.dart 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import 'package:app_flowy/startup/startup.dart';
  2. import 'package:app_flowy/workspace/application/appearance.dart';
  3. import 'package:app_flowy/plugins/doc/presentation/banner.dart';
  4. import 'package:app_flowy/plugins/doc/presentation/toolbar/tool_bar.dart';
  5. import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
  6. import 'package:flowy_infra_ui/widget/spacing.dart';
  7. import 'package:flutter_quill/flutter_quill.dart' as quill;
  8. import 'package:flowy_infra_ui/widget/error_page.dart';
  9. import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
  10. import 'package:flutter/material.dart';
  11. import 'package:flutter_bloc/flutter_bloc.dart';
  12. import 'package:provider/provider.dart';
  13. import 'application/doc_bloc.dart';
  14. import 'styles.dart';
  15. class DocumentPage extends StatefulWidget {
  16. final VoidCallback onDeleted;
  17. final ViewPB view;
  18. DocumentPage({
  19. required this.view,
  20. required this.onDeleted,
  21. Key? key,
  22. }) : super(key: ValueKey(view.id));
  23. @override
  24. State<DocumentPage> createState() => _DocumentPageState();
  25. }
  26. class _DocumentPageState extends State<DocumentPage> {
  27. late DocumentBloc documentBloc;
  28. final scrollController = ScrollController();
  29. final FocusNode _focusNode = FocusNode();
  30. @override
  31. void initState() {
  32. documentBloc = getIt<DocumentBloc>(param1: super.widget.view)
  33. ..add(const DocumentEvent.initial());
  34. super.initState();
  35. }
  36. @override
  37. Widget build(BuildContext context) {
  38. return MultiBlocProvider(
  39. providers: [
  40. BlocProvider<DocumentBloc>.value(value: documentBloc),
  41. ],
  42. child:
  43. BlocBuilder<DocumentBloc, DocumentState>(builder: (context, state) {
  44. return state.loadingState.map(
  45. // loading: (_) => const FlowyProgressIndicator(),
  46. loading: (_) =>
  47. SizedBox.expand(child: Container(color: Colors.transparent)),
  48. finish: (result) => result.successOrFail.fold(
  49. (_) {
  50. if (state.forceClose) {
  51. widget.onDeleted();
  52. return const SizedBox();
  53. } else {
  54. return _renderDocument(context, state);
  55. }
  56. },
  57. (err) => FlowyErrorPage(err.toString()),
  58. ),
  59. );
  60. }),
  61. );
  62. }
  63. @override
  64. Future<void> dispose() async {
  65. documentBloc.close();
  66. _focusNode.dispose();
  67. super.dispose();
  68. }
  69. Widget _renderDocument(BuildContext context, DocumentState state) {
  70. quill.QuillController controller = quill.QuillController(
  71. document: context.read<DocumentBloc>().document,
  72. selection: const TextSelection.collapsed(offset: 0),
  73. );
  74. return Column(
  75. children: [
  76. if (state.isDeleted) _renderBanner(context),
  77. Expanded(
  78. child: Column(
  79. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  80. children: [
  81. _renderEditor(controller),
  82. const VSpace(10),
  83. _renderToolbar(controller),
  84. const VSpace(10),
  85. ],
  86. ),
  87. ),
  88. ],
  89. );
  90. }
  91. Widget _renderBanner(BuildContext context) {
  92. return DocumentBanner(
  93. onRestore: () =>
  94. context.read<DocumentBloc>().add(const DocumentEvent.restorePage()),
  95. onDelete: () => context
  96. .read<DocumentBloc>()
  97. .add(const DocumentEvent.deletePermanently()),
  98. );
  99. }
  100. Widget _renderEditor(quill.QuillController controller) {
  101. final editor = quill.QuillEditor(
  102. controller: controller,
  103. focusNode: _focusNode,
  104. scrollable: true,
  105. paintCursorAboveText: true,
  106. autoFocus: controller.document.isEmpty(),
  107. expands: false,
  108. padding: const EdgeInsets.symmetric(horizontal: 8.0),
  109. readOnly: false,
  110. scrollBottomInset: 0,
  111. scrollController: scrollController,
  112. customStyles: customStyles(context),
  113. );
  114. return Expanded(
  115. child: ScrollbarListStack(
  116. axis: Axis.vertical,
  117. controller: scrollController,
  118. barSize: 6.0,
  119. child: SizedBox.expand(child: editor),
  120. ),
  121. );
  122. }
  123. Widget _renderToolbar(quill.QuillController controller) {
  124. return ChangeNotifierProvider.value(
  125. value: Provider.of<AppearanceSetting>(context, listen: true),
  126. child: EditorToolbar.basic(
  127. controller: controller,
  128. ),
  129. );
  130. }
  131. }