163 lines
4.9 KiB
Dart
Raw Normal View History

import 'dart:convert';
import 'package:app_flowy/plugins/trash/application/trash_service.dart';
import 'package:app_flowy/workspace/application/view/view_listener.dart';
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';
import 'dart:async';
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;
final DocumentService service;
2022-03-01 21:09:52 +08:00
2022-01-31 09:49:05 +08:00
final ViewListener listener;
final TrashService trashService;
2022-02-23 22:17:47 +08:00
late FlutterQuillDocument document;
StreamSubscription? _subscription;
2021-07-24 18:55:13 +08:00
2022-02-23 22:17:47 +08:00
DocumentBloc({
required this.view,
required this.service,
required this.listener,
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 {
final result = await trashService
.deleteViews([Tuple2(view.id, TrashType.TrashView)]);
2022-03-01 21:09:52 +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 {
final result = await trashService.putback(view.id);
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 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-09-13 20:23:56 +08:00
document = _decodeJsonToDocument(block.snapshot);
_subscription = document.changes.listen((event) {
final delta = event.item2;
final documentDelta = document.toDelta();
_composeDelta(delta, documentDelta);
});
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) {
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;
// }
void _composeDelta(Delta composedDelta, Delta documentDelta) async {
final json = jsonEncode(composedDelta.toJson());
Log.debug("doc_id: $view.id - Send json: $json");
final result = await service.applyEdit(docId: view.id, operations: json);
2022-09-13 20:23:56 +08:00
result.fold(
(_) {},
(r) => Log.error(r),
);
}
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,
required bool isDeleted,
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(),
isDeleted: false,
forceClose: false,
);
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;
const factory DocumentLoadingState.finish(
Either<Unit, FlowyError> successOrFail) = _Finish;
2021-07-24 18:55:13 +08:00
}