doc_bloc.dart 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import 'dart:convert';
  2. import 'package:editor/flutter_quill.dart';
  3. import 'package:flowy_log/flowy_log.dart';
  4. import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
  5. import 'package:flutter_bloc/flutter_bloc.dart';
  6. import 'package:app_flowy/workspace/domain/i_doc.dart';
  7. import 'package:freezed_annotation/freezed_annotation.dart';
  8. import 'package:dartz/dartz.dart';
  9. import 'dart:async';
  10. part 'doc_bloc.freezed.dart';
  11. class DocBloc extends Bloc<DocEvent, DocState> {
  12. final IDoc docManager;
  13. late Document document;
  14. late StreamSubscription _subscription;
  15. DocBloc({required this.docManager}) : super(DocState.initial());
  16. @override
  17. Stream<DocState> mapEventToState(DocEvent event) async* {
  18. yield* event.map(initial: _initial);
  19. }
  20. @override
  21. Future<void> close() async {
  22. await _subscription.cancel();
  23. docManager.closeDoc();
  24. return super.close();
  25. }
  26. Stream<DocState> _initial(Initial value) async* {
  27. final result = await docManager.readDoc();
  28. yield result.fold(
  29. (doc) {
  30. document = _decodeJsonToDocument(doc.data);
  31. _subscription = document.changes.listen((event) {
  32. final delta = event.item2;
  33. final documentDelta = document.toDelta();
  34. _composeDelta(delta, documentDelta);
  35. });
  36. return state.copyWith(loadState: DocLoadState.finish(left(unit)));
  37. },
  38. (err) {
  39. return state.copyWith(loadState: DocLoadState.finish(right(err)));
  40. },
  41. );
  42. }
  43. // Document _decodeListToDocument(Uint8List data) {
  44. // final json = jsonDecode(utf8.decode(data));
  45. // final document = Document.fromJson(json);
  46. // return document;
  47. // }
  48. void _composeDelta(Delta composedDelta, Delta documentDelta) async {
  49. final json = jsonEncode(composedDelta.toJson());
  50. Log.debug("Send json: $json");
  51. final result = await docManager.composeDelta(json: json);
  52. result.fold((rustDoc) {
  53. // final json = utf8.decode(doc.data);
  54. final rustDelta = Delta.fromJson(jsonDecode(rustDoc.data));
  55. if (documentDelta != rustDelta) {
  56. Log.error("Receive : $rustDelta");
  57. Log.error("Expected : $documentDelta");
  58. }
  59. }, (r) => null);
  60. }
  61. Document _decodeJsonToDocument(String data) {
  62. final json = jsonDecode(data);
  63. final document = Document.fromJson(json);
  64. return document;
  65. }
  66. }
  67. @freezed
  68. class DocEvent with _$DocEvent {
  69. const factory DocEvent.initial() = Initial;
  70. }
  71. @freezed
  72. class DocState with _$DocState {
  73. const factory DocState({
  74. required DocLoadState loadState,
  75. }) = _DocState;
  76. factory DocState.initial() => const DocState(loadState: _Loading());
  77. }
  78. @freezed
  79. class DocLoadState with _$DocLoadState {
  80. const factory DocLoadState.loading() = _Loading;
  81. const factory DocLoadState.finish(Either<Unit, WorkspaceError> successOrFail) = _Finish;
  82. }