| 
									
										
										
										
											2021-10-20 22:19:01 +08:00
										 |  |  | import 'dart:convert'; | 
					
						
							| 
									
										
										
										
											2022-08-09 10:35:27 +08:00
										 |  |  | import 'package:app_flowy/plugins/trash/application/trash_service.dart'; | 
					
						
							| 
									
										
										
										
											2022-02-28 23:06:36 -05:00
										 |  |  | import 'package:app_flowy/workspace/application/view/view_listener.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-09 10:35:27 +08:00
										 |  |  | import 'package:app_flowy/plugins/doc/application/doc_service.dart'; | 
					
						
							| 
									
										
										
										
											2022-07-04 15:00:54 +08:00
										 |  |  | import 'package:flowy_sdk/protobuf/flowy-folder/trash.pb.dart'; | 
					
						
							| 
									
										
										
										
											2021-12-14 18:04:51 +08:00
										 |  |  | import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; | 
					
						
							| 
									
										
										
										
											2022-07-04 15:00:54 +08:00
										 |  |  | import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart'; | 
					
						
							| 
									
										
										
										
											2022-02-23 22:17:47 +08:00
										 |  |  | import 'package:flutter_quill/flutter_quill.dart' show Document, Delta; | 
					
						
							| 
									
										
										
										
											2022-02-19 13:52:52 +08:00
										 |  |  | import 'package:flowy_sdk/log.dart'; | 
					
						
							| 
									
										
										
										
											2021-09-11 21:30:58 +08:00
										 |  |  | import 'package:flutter_bloc/flutter_bloc.dart'; | 
					
						
							| 
									
										
										
										
											2021-07-24 18:55:13 +08:00
										 |  |  | import 'package:freezed_annotation/freezed_annotation.dart'; | 
					
						
							| 
									
										
										
										
											2021-10-19 13:56:11 +08:00
										 |  |  | import 'package:dartz/dartz.dart'; | 
					
						
							| 
									
										
										
										
											2021-10-20 22:19:01 +08:00
										 |  |  | import 'dart:async'; | 
					
						
							| 
									
										
										
										
											2022-02-28 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-24 18:55:13 +08:00
										 |  |  | part 'doc_bloc.freezed.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 22:17:47 +08:00
										 |  |  | typedef FlutterQuillDocument = Document; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class DocumentBloc extends Bloc<DocumentEvent, DocumentState> { | 
					
						
							| 
									
										
										
										
											2022-07-19 14:11:29 +08:00
										 |  |  |   final ViewPB view; | 
					
						
							| 
									
										
										
										
											2022-02-28 21:02:46 -05:00
										 |  |  |   final DocumentService service; | 
					
						
							| 
									
										
										
										
											2022-03-01 21:09:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-31 09:49:05 +08:00
										 |  |  |   final ViewListener listener; | 
					
						
							| 
									
										
										
										
											2022-02-28 21:17:08 -05:00
										 |  |  |   final TrashService trashService; | 
					
						
							| 
									
										
										
										
											2022-02-23 22:17:47 +08:00
										 |  |  |   late FlutterQuillDocument document; | 
					
						
							| 
									
										
										
										
											2021-11-04 12:47:41 +08:00
										 |  |  |   StreamSubscription? _subscription; | 
					
						
							| 
									
										
										
										
											2021-07-24 18:55:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 22:17:47 +08:00
										 |  |  |   DocumentBloc({ | 
					
						
							| 
									
										
										
										
											2021-10-31 19:48:20 +08:00
										 |  |  |     required this.view, | 
					
						
							| 
									
										
										
										
											2022-02-28 21:02:46 -05:00
										 |  |  |     required this.service, | 
					
						
							| 
									
										
										
										
											2021-10-31 19:48:20 +08:00
										 |  |  |     required this.listener, | 
					
						
							| 
									
										
										
										
											2022-02-28 21:17:08 -05:00
										 |  |  |     required this.trashService, | 
					
						
							| 
									
										
										
										
											2022-02-23 22:17:47 +08:00
										 |  |  |   }) : super(DocumentState.initial()) { | 
					
						
							|  |  |  |     on<DocumentEvent>((event, emit) async { | 
					
						
							| 
									
										
										
										
											2022-01-04 22:44:03 +08:00
										 |  |  |       await event.map( | 
					
						
							|  |  |  |         initial: (Initial value) async { | 
					
						
							|  |  |  |           await _initial(value, emit); | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         deleted: (Deleted value) async { | 
					
						
							|  |  |  |           emit(state.copyWith(isDeleted: true)); | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         restore: (Restore value) async { | 
					
						
							|  |  |  |           emit(state.copyWith(isDeleted: false)); | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         deletePermanently: (DeletePermanently value) async { | 
					
						
							| 
									
										
										
										
											2022-08-09 10:35:27 +08:00
										 |  |  |           final result = await trashService | 
					
						
							|  |  |  |               .deleteViews([Tuple2(view.id, TrashType.TrashView)]); | 
					
						
							| 
									
										
										
										
											2022-03-01 21:09:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-09 10:35:27 +08:00
										 |  |  |           final newState = result.fold( | 
					
						
							|  |  |  |               (l) => state.copyWith(forceClose: true), (r) => state); | 
					
						
							| 
									
										
										
										
											2022-01-04 22:44:03 +08:00
										 |  |  |           emit(newState); | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         restorePage: (RestorePage value) async { | 
					
						
							| 
									
										
										
										
											2022-02-28 21:17:08 -05:00
										 |  |  |           final result = await trashService.putback(view.id); | 
					
						
							| 
									
										
										
										
											2022-08-09 10:35:27 +08:00
										 |  |  |           final newState = result.fold( | 
					
						
							|  |  |  |               (l) => state.copyWith(isDeleted: false), (r) => state); | 
					
						
							| 
									
										
										
										
											2022-01-04 22:44:03 +08:00
										 |  |  |           emit(newState); | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-07-24 18:55:13 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-09-11 21:30:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-19 13:56:11 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   Future<void> close() async { | 
					
						
							| 
									
										
										
										
											2022-05-05 21:15:01 +08:00
										 |  |  |     await listener.stop(); | 
					
						
							| 
									
										
										
										
											2021-11-03 22:04:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-03 23:03:42 +08:00
										 |  |  |     if (_subscription != null) { | 
					
						
							|  |  |  |       await _subscription?.cancel(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-10 16:29:45 +08:00
										 |  |  |     await service.closeDocument(docId: view.id); | 
					
						
							| 
									
										
										
										
											2021-10-19 13:56:11 +08:00
										 |  |  |     return super.close(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 22:17:47 +08:00
										 |  |  |   Future<void> _initial(Initial value, Emitter<DocumentState> emit) async { | 
					
						
							| 
									
										
										
										
											2022-05-05 21:15:01 +08:00
										 |  |  |     listener.start( | 
					
						
							|  |  |  |       onViewDeleted: (result) { | 
					
						
							|  |  |  |         result.fold( | 
					
						
							|  |  |  |           (view) => add(const DocumentEvent.deleted()), | 
					
						
							|  |  |  |           (error) {}, | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       onViewRestored: (result) { | 
					
						
							|  |  |  |         result.fold( | 
					
						
							|  |  |  |           (view) => add(const DocumentEvent.restore()), | 
					
						
							|  |  |  |           (error) {}, | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2022-03-06 21:22:42 +08:00
										 |  |  |     final result = await service.openDocument(docId: view.id); | 
					
						
							| 
									
										
										
										
											2022-01-04 22:44:03 +08:00
										 |  |  |     result.fold( | 
					
						
							| 
									
										
										
										
											2022-02-25 22:27:44 +08:00
										 |  |  |       (block) { | 
					
						
							| 
									
										
										
										
											2022-03-06 09:03:02 +08:00
										 |  |  |         document = _decodeJsonToDocument(block.deltaStr); | 
					
						
							| 
									
										
										
										
											2021-10-20 22:19:01 +08:00
										 |  |  |         _subscription = document.changes.listen((event) { | 
					
						
							|  |  |  |           final delta = event.item2; | 
					
						
							|  |  |  |           final documentDelta = document.toDelta(); | 
					
						
							|  |  |  |           _composeDelta(delta, documentDelta); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2022-08-09 10:35:27 +08:00
										 |  |  |         emit(state.copyWith( | 
					
						
							|  |  |  |             loadingState: DocumentLoadingState.finish(left(unit)))); | 
					
						
							| 
									
										
										
										
											2021-09-11 21:30:58 +08:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2021-10-19 13:56:11 +08:00
										 |  |  |       (err) { | 
					
						
							| 
									
										
										
										
											2022-08-09 10:35:27 +08:00
										 |  |  |         emit(state.copyWith( | 
					
						
							|  |  |  |             loadingState: DocumentLoadingState.finish(right(err)))); | 
					
						
							| 
									
										
										
										
											2021-09-11 21:30:58 +08:00
										 |  |  |       }, | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 11:40:45 +08:00
										 |  |  |   // Document _decodeListToDocument(Uint8List data) {
 | 
					
						
							|  |  |  |   //   final json = jsonDecode(utf8.decode(data));
 | 
					
						
							|  |  |  |   //   final document = Document.fromJson(json);
 | 
					
						
							|  |  |  |   //   return document;
 | 
					
						
							|  |  |  |   // }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-20 22:19:01 +08:00
										 |  |  |   void _composeDelta(Delta composedDelta, Delta documentDelta) async { | 
					
						
							|  |  |  |     final json = jsonEncode(composedDelta.toJson()); | 
					
						
							| 
									
										
										
										
											2021-11-03 22:04:45 +08:00
										 |  |  |     Log.debug("doc_id: $view.id - Send json: $json"); | 
					
						
							| 
									
										
										
										
											2022-02-28 21:02:46 -05:00
										 |  |  |     final result = await service.composeDelta(docId: view.id, data: json); | 
					
						
							| 
									
										
										
										
											2021-10-20 22:19:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     result.fold((rustDoc) { | 
					
						
							|  |  |  |       // final json = utf8.decode(doc.data);
 | 
					
						
							| 
									
										
										
										
											2022-03-06 09:03:02 +08:00
										 |  |  |       final rustDelta = Delta.fromJson(jsonDecode(rustDoc.deltaStr)); | 
					
						
							| 
									
										
										
										
											2021-10-20 22:19:01 +08:00
										 |  |  |       if (documentDelta != rustDelta) { | 
					
						
							|  |  |  |         Log.error("Receive : $rustDelta"); | 
					
						
							|  |  |  |         Log.error("Expected : $documentDelta"); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, (r) => null); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Document _decodeJsonToDocument(String data) { | 
					
						
							|  |  |  |     final json = jsonDecode(data); | 
					
						
							|  |  |  |     final document = Document.fromJson(json); | 
					
						
							|  |  |  |     return document; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-07-24 18:55:13 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @freezed | 
					
						
							| 
									
										
										
										
											2022-02-23 22:17:47 +08:00
										 |  |  | class DocumentEvent with _$DocumentEvent { | 
					
						
							|  |  |  |   const factory DocumentEvent.initial() = Initial; | 
					
						
							|  |  |  |   const factory DocumentEvent.deleted() = Deleted; | 
					
						
							|  |  |  |   const factory DocumentEvent.restore() = Restore; | 
					
						
							|  |  |  |   const factory DocumentEvent.restorePage() = RestorePage; | 
					
						
							|  |  |  |   const factory DocumentEvent.deletePermanently() = DeletePermanently; | 
					
						
							| 
									
										
										
										
											2021-07-24 18:55:13 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @freezed | 
					
						
							| 
									
										
										
										
											2022-02-23 22:17:47 +08:00
										 |  |  | class DocumentState with _$DocumentState { | 
					
						
							|  |  |  |   const factory DocumentState({ | 
					
						
							|  |  |  |     required DocumentLoadingState loadingState, | 
					
						
							| 
									
										
										
										
											2021-10-31 17:24:55 +08:00
										 |  |  |     required bool isDeleted, | 
					
						
							| 
									
										
										
										
											2021-10-31 20:27:37 +08:00
										 |  |  |     required bool forceClose, | 
					
						
							| 
									
										
										
										
											2022-02-23 22:17:47 +08:00
										 |  |  |   }) = _DocumentState; | 
					
						
							| 
									
										
										
										
											2021-10-19 13:56:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 22:17:47 +08:00
										 |  |  |   factory DocumentState.initial() => const DocumentState( | 
					
						
							|  |  |  |         loadingState: _Loading(), | 
					
						
							| 
									
										
										
										
											2021-10-31 17:24:55 +08:00
										 |  |  |         isDeleted: false, | 
					
						
							| 
									
										
										
										
											2021-10-31 20:27:37 +08:00
										 |  |  |         forceClose: false, | 
					
						
							| 
									
										
										
										
											2021-10-31 17:24:55 +08:00
										 |  |  |       ); | 
					
						
							| 
									
										
										
										
											2021-10-19 13:56:11 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @freezed | 
					
						
							| 
									
										
										
										
											2022-02-23 22:17:47 +08:00
										 |  |  | class DocumentLoadingState with _$DocumentLoadingState { | 
					
						
							|  |  |  |   const factory DocumentLoadingState.loading() = _Loading; | 
					
						
							| 
									
										
										
										
											2022-08-09 10:35:27 +08:00
										 |  |  |   const factory DocumentLoadingState.finish( | 
					
						
							|  |  |  |       Either<Unit, FlowyError> successOrFail) = _Finish; | 
					
						
							| 
									
										
										
										
											2021-07-24 18:55:13 +08:00
										 |  |  | } |