mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[flutter]: add delete and restore notification
This commit is contained in:
parent
74c1e3fcc6
commit
ded8eb5d1c
@ -20,7 +20,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
|
|||||||
) async* {
|
) async* {
|
||||||
yield* event.map(initial: (e) async* {
|
yield* event.map(initial: (e) async* {
|
||||||
listener.start(
|
listener.start(
|
||||||
viewsChangeCallback: _handleViewsOrFail,
|
viewsChangeCallback: _handleViewsChanged,
|
||||||
updatedCallback: (app) => add(AppEvent.appDidUpdate(app)),
|
updatedCallback: (app) => add(AppEvent.appDidUpdate(app)),
|
||||||
);
|
);
|
||||||
yield* _fetchViews();
|
yield* _fetchViews();
|
||||||
@ -37,11 +37,11 @@ class AppBloc extends Bloc<AppEvent, AppState> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}, didReceiveViews: (e) async* {
|
}, didReceiveViews: (e) async* {
|
||||||
yield state.copyWith(views: e.views);
|
yield* handleDidReceiveViews(e.views);
|
||||||
}, delete: (e) async* {
|
}, delete: (e) async* {
|
||||||
final result = await appManager.delete();
|
final result = await appManager.delete();
|
||||||
yield result.fold(
|
yield result.fold(
|
||||||
(l) => state.copyWith(successOrFailure: left(unit)),
|
(unit) => state.copyWith(successOrFailure: left(unit)),
|
||||||
(error) => state.copyWith(successOrFailure: right(error)),
|
(error) => state.copyWith(successOrFailure: right(error)),
|
||||||
);
|
);
|
||||||
}, rename: (e) async* {
|
}, rename: (e) async* {
|
||||||
@ -61,8 +61,8 @@ class AppBloc extends Bloc<AppEvent, AppState> {
|
|||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleViewsOrFail(Either<List<View>, WorkspaceError> viewsOrFail) {
|
void _handleViewsChanged(Either<List<View>, WorkspaceError> result) {
|
||||||
viewsOrFail.fold(
|
result.fold(
|
||||||
(views) => add(AppEvent.didReceiveViews(views)),
|
(views) => add(AppEvent.didReceiveViews(views)),
|
||||||
(error) {
|
(error) {
|
||||||
Log.error(error);
|
Log.error(error);
|
||||||
@ -70,6 +70,19 @@ class AppBloc extends Bloc<AppEvent, AppState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stream<AppState> handleDidReceiveViews(List<View> views) async* {
|
||||||
|
final selectedView = state.selectedView;
|
||||||
|
AppState newState = state.copyWith(views: views);
|
||||||
|
if (selectedView != null) {
|
||||||
|
final index = views.indexWhere((element) => element.id == selectedView.id);
|
||||||
|
if (index != -1) {
|
||||||
|
newState = newState.copyWith(selectedView: null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yield newState;
|
||||||
|
}
|
||||||
|
|
||||||
Stream<AppState> _fetchViews() async* {
|
Stream<AppState> _fetchViews() async* {
|
||||||
final viewsOrFailed = await appManager.getViews();
|
final viewsOrFailed = await appManager.getViews();
|
||||||
yield viewsOrFailed.fold(
|
yield viewsOrFailed.fold(
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:app_flowy/workspace/domain/i_view.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,24 +13,50 @@ part 'doc_bloc.freezed.dart';
|
|||||||
|
|
||||||
class DocBloc extends Bloc<DocEvent, DocState> {
|
class DocBloc extends Bloc<DocEvent, DocState> {
|
||||||
final IDoc docManager;
|
final IDoc docManager;
|
||||||
|
final IViewListener listener;
|
||||||
late Document document;
|
late Document document;
|
||||||
late StreamSubscription _subscription;
|
late StreamSubscription _subscription;
|
||||||
|
|
||||||
DocBloc({required this.docManager}) : super(DocState.initial());
|
DocBloc({required this.docManager, required this.listener}) : super(DocState.initial());
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<DocState> mapEventToState(DocEvent event) async* {
|
Stream<DocState> mapEventToState(DocEvent event) async* {
|
||||||
yield* event.map(initial: _initial);
|
yield* event.map(
|
||||||
|
initial: _initial,
|
||||||
|
deleted: (Deleted value) async* {
|
||||||
|
yield state.copyWith(isDeleted: true);
|
||||||
|
},
|
||||||
|
restore: (Restore value) async* {
|
||||||
|
yield state.copyWith(isDeleted: false);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
|
await listener.stop();
|
||||||
await _subscription.cancel();
|
await _subscription.cancel();
|
||||||
docManager.closeDoc();
|
docManager.closeDoc();
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<DocState> _initial(Initial value) async* {
|
Stream<DocState> _initial(Initial value) async* {
|
||||||
|
listener.deletedNotifier.addPublishListener((result) {
|
||||||
|
result.fold(
|
||||||
|
(view) => add(const DocEvent.deleted()),
|
||||||
|
(error) {},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
listener.restoredNotifier.addPublishListener((result) {
|
||||||
|
result.fold(
|
||||||
|
(view) => add(const DocEvent.restore()),
|
||||||
|
(error) {},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
listener.start();
|
||||||
|
|
||||||
final result = await docManager.readDoc();
|
final result = await docManager.readDoc();
|
||||||
yield result.fold(
|
yield result.fold(
|
||||||
(doc) {
|
(doc) {
|
||||||
@ -78,15 +105,21 @@ class DocBloc extends Bloc<DocEvent, DocState> {
|
|||||||
@freezed
|
@freezed
|
||||||
class DocEvent with _$DocEvent {
|
class DocEvent with _$DocEvent {
|
||||||
const factory DocEvent.initial() = Initial;
|
const factory DocEvent.initial() = Initial;
|
||||||
|
const factory DocEvent.deleted() = Deleted;
|
||||||
|
const factory DocEvent.restore() = Restore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class DocState with _$DocState {
|
class DocState with _$DocState {
|
||||||
const factory DocState({
|
const factory DocState({
|
||||||
required DocLoadState loadState,
|
required DocLoadState loadState,
|
||||||
|
required bool isDeleted,
|
||||||
}) = _DocState;
|
}) = _DocState;
|
||||||
|
|
||||||
factory DocState.initial() => const DocState(loadState: _Loading());
|
factory DocState.initial() => const DocState(
|
||||||
|
loadState: _Loading(),
|
||||||
|
isDeleted: false,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -19,6 +19,14 @@ class _$DocEventTearOff {
|
|||||||
Initial initial() {
|
Initial initial() {
|
||||||
return const Initial();
|
return const Initial();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Deleted deleted() {
|
||||||
|
return const Deleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
Restore restore() {
|
||||||
|
return const Restore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -29,22 +37,30 @@ mixin _$DocEvent {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() initial,
|
required TResult Function() initial,
|
||||||
|
required TResult Function() deleted,
|
||||||
|
required TResult Function() restore,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? initial,
|
TResult Function()? initial,
|
||||||
|
TResult Function()? deleted,
|
||||||
|
TResult Function()? restore,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult map<TResult extends Object?>({
|
TResult map<TResult extends Object?>({
|
||||||
required TResult Function(Initial value) initial,
|
required TResult Function(Initial value) initial,
|
||||||
|
required TResult Function(Deleted value) deleted,
|
||||||
|
required TResult Function(Restore value) restore,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeMap<TResult extends Object?>({
|
TResult maybeMap<TResult extends Object?>({
|
||||||
TResult Function(Initial value)? initial,
|
TResult Function(Initial value)? initial,
|
||||||
|
TResult Function(Deleted value)? deleted,
|
||||||
|
TResult Function(Restore value)? restore,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@ -103,6 +119,8 @@ class _$Initial implements Initial {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() initial,
|
required TResult Function() initial,
|
||||||
|
required TResult Function() deleted,
|
||||||
|
required TResult Function() restore,
|
||||||
}) {
|
}) {
|
||||||
return initial();
|
return initial();
|
||||||
}
|
}
|
||||||
@ -111,6 +129,8 @@ class _$Initial implements Initial {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? initial,
|
TResult Function()? initial,
|
||||||
|
TResult Function()? deleted,
|
||||||
|
TResult Function()? restore,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
if (initial != null) {
|
if (initial != null) {
|
||||||
@ -123,6 +143,8 @@ class _$Initial implements Initial {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult map<TResult extends Object?>({
|
TResult map<TResult extends Object?>({
|
||||||
required TResult Function(Initial value) initial,
|
required TResult Function(Initial value) initial,
|
||||||
|
required TResult Function(Deleted value) deleted,
|
||||||
|
required TResult Function(Restore value) restore,
|
||||||
}) {
|
}) {
|
||||||
return initial(this);
|
return initial(this);
|
||||||
}
|
}
|
||||||
@ -131,6 +153,8 @@ class _$Initial implements Initial {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeMap<TResult extends Object?>({
|
TResult maybeMap<TResult extends Object?>({
|
||||||
TResult Function(Initial value)? initial,
|
TResult Function(Initial value)? initial,
|
||||||
|
TResult Function(Deleted value)? deleted,
|
||||||
|
TResult Function(Restore value)? restore,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
if (initial != null) {
|
if (initial != null) {
|
||||||
@ -144,13 +168,188 @@ abstract class Initial implements DocEvent {
|
|||||||
const factory Initial() = _$Initial;
|
const factory Initial() = _$Initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $DeletedCopyWith<$Res> {
|
||||||
|
factory $DeletedCopyWith(Deleted value, $Res Function(Deleted) then) =
|
||||||
|
_$DeletedCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$DeletedCopyWithImpl<$Res> extends _$DocEventCopyWithImpl<$Res>
|
||||||
|
implements $DeletedCopyWith<$Res> {
|
||||||
|
_$DeletedCopyWithImpl(Deleted _value, $Res Function(Deleted) _then)
|
||||||
|
: super(_value, (v) => _then(v as Deleted));
|
||||||
|
|
||||||
|
@override
|
||||||
|
Deleted get _value => super._value as Deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$Deleted implements Deleted {
|
||||||
|
const _$Deleted();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'DocEvent.deleted()';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) || (other is Deleted);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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,
|
||||||
|
}) {
|
||||||
|
return deleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? initial,
|
||||||
|
TResult Function()? deleted,
|
||||||
|
TResult Function()? restore,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (deleted != null) {
|
||||||
|
return deleted();
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}) {
|
||||||
|
return deleted(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(Initial value)? initial,
|
||||||
|
TResult Function(Deleted value)? deleted,
|
||||||
|
TResult Function(Restore value)? restore,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (deleted != null) {
|
||||||
|
return deleted(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class Deleted implements DocEvent {
|
||||||
|
const factory Deleted() = _$Deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $RestoreCopyWith<$Res> {
|
||||||
|
factory $RestoreCopyWith(Restore value, $Res Function(Restore) then) =
|
||||||
|
_$RestoreCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$RestoreCopyWithImpl<$Res> extends _$DocEventCopyWithImpl<$Res>
|
||||||
|
implements $RestoreCopyWith<$Res> {
|
||||||
|
_$RestoreCopyWithImpl(Restore _value, $Res Function(Restore) _then)
|
||||||
|
: super(_value, (v) => _then(v as Restore));
|
||||||
|
|
||||||
|
@override
|
||||||
|
Restore get _value => super._value as Restore;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$Restore implements Restore {
|
||||||
|
const _$Restore();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'DocEvent.restore()';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) || (other is Restore);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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,
|
||||||
|
}) {
|
||||||
|
return restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? initial,
|
||||||
|
TResult Function()? deleted,
|
||||||
|
TResult Function()? restore,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (restore != null) {
|
||||||
|
return restore();
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}) {
|
||||||
|
return restore(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(Initial value)? initial,
|
||||||
|
TResult Function(Deleted value)? deleted,
|
||||||
|
TResult Function(Restore value)? restore,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (restore != null) {
|
||||||
|
return restore(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class Restore implements DocEvent {
|
||||||
|
const factory Restore() = _$Restore;
|
||||||
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$DocStateTearOff {
|
class _$DocStateTearOff {
|
||||||
const _$DocStateTearOff();
|
const _$DocStateTearOff();
|
||||||
|
|
||||||
_DocState call({required DocLoadState loadState}) {
|
_DocState call({required DocLoadState loadState, required bool isDeleted}) {
|
||||||
return _DocState(
|
return _DocState(
|
||||||
loadState: loadState,
|
loadState: loadState,
|
||||||
|
isDeleted: isDeleted,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,6 +360,7 @@ const $DocState = _$DocStateTearOff();
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$DocState {
|
mixin _$DocState {
|
||||||
DocLoadState get loadState => throw _privateConstructorUsedError;
|
DocLoadState get loadState => throw _privateConstructorUsedError;
|
||||||
|
bool get isDeleted => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
$DocStateCopyWith<DocState> get copyWith =>
|
$DocStateCopyWith<DocState> get copyWith =>
|
||||||
@ -171,7 +371,7 @@ mixin _$DocState {
|
|||||||
abstract class $DocStateCopyWith<$Res> {
|
abstract class $DocStateCopyWith<$Res> {
|
||||||
factory $DocStateCopyWith(DocState value, $Res Function(DocState) then) =
|
factory $DocStateCopyWith(DocState value, $Res Function(DocState) then) =
|
||||||
_$DocStateCopyWithImpl<$Res>;
|
_$DocStateCopyWithImpl<$Res>;
|
||||||
$Res call({DocLoadState loadState});
|
$Res call({DocLoadState loadState, bool isDeleted});
|
||||||
|
|
||||||
$DocLoadStateCopyWith<$Res> get loadState;
|
$DocLoadStateCopyWith<$Res> get loadState;
|
||||||
}
|
}
|
||||||
@ -187,12 +387,17 @@ class _$DocStateCopyWithImpl<$Res> implements $DocStateCopyWith<$Res> {
|
|||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? loadState = freezed,
|
Object? loadState = freezed,
|
||||||
|
Object? isDeleted = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
loadState: loadState == freezed
|
loadState: loadState == freezed
|
||||||
? _value.loadState
|
? _value.loadState
|
||||||
: loadState // ignore: cast_nullable_to_non_nullable
|
: loadState // ignore: cast_nullable_to_non_nullable
|
||||||
as DocLoadState,
|
as DocLoadState,
|
||||||
|
isDeleted: isDeleted == freezed
|
||||||
|
? _value.isDeleted
|
||||||
|
: isDeleted // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,7 +414,7 @@ abstract class _$DocStateCopyWith<$Res> implements $DocStateCopyWith<$Res> {
|
|||||||
factory _$DocStateCopyWith(_DocState value, $Res Function(_DocState) then) =
|
factory _$DocStateCopyWith(_DocState value, $Res Function(_DocState) then) =
|
||||||
__$DocStateCopyWithImpl<$Res>;
|
__$DocStateCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
$Res call({DocLoadState loadState});
|
$Res call({DocLoadState loadState, bool isDeleted});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
$DocLoadStateCopyWith<$Res> get loadState;
|
$DocLoadStateCopyWith<$Res> get loadState;
|
||||||
@ -227,12 +432,17 @@ class __$DocStateCopyWithImpl<$Res> extends _$DocStateCopyWithImpl<$Res>
|
|||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? loadState = freezed,
|
Object? loadState = freezed,
|
||||||
|
Object? isDeleted = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(_DocState(
|
return _then(_DocState(
|
||||||
loadState: loadState == freezed
|
loadState: loadState == freezed
|
||||||
? _value.loadState
|
? _value.loadState
|
||||||
: loadState // ignore: cast_nullable_to_non_nullable
|
: loadState // ignore: cast_nullable_to_non_nullable
|
||||||
as DocLoadState,
|
as DocLoadState,
|
||||||
|
isDeleted: isDeleted == freezed
|
||||||
|
? _value.isDeleted
|
||||||
|
: isDeleted // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -240,14 +450,16 @@ class __$DocStateCopyWithImpl<$Res> extends _$DocStateCopyWithImpl<$Res>
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
||||||
class _$_DocState implements _DocState {
|
class _$_DocState implements _DocState {
|
||||||
const _$_DocState({required this.loadState});
|
const _$_DocState({required this.loadState, required this.isDeleted});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final DocLoadState loadState;
|
final DocLoadState loadState;
|
||||||
|
@override
|
||||||
|
final bool isDeleted;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'DocState(loadState: $loadState)';
|
return 'DocState(loadState: $loadState, isDeleted: $isDeleted)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -256,12 +468,17 @@ class _$_DocState implements _DocState {
|
|||||||
(other is _DocState &&
|
(other is _DocState &&
|
||||||
(identical(other.loadState, loadState) ||
|
(identical(other.loadState, loadState) ||
|
||||||
const DeepCollectionEquality()
|
const DeepCollectionEquality()
|
||||||
.equals(other.loadState, loadState)));
|
.equals(other.loadState, loadState)) &&
|
||||||
|
(identical(other.isDeleted, isDeleted) ||
|
||||||
|
const DeepCollectionEquality()
|
||||||
|
.equals(other.isDeleted, isDeleted)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
runtimeType.hashCode ^ const DeepCollectionEquality().hash(loadState);
|
runtimeType.hashCode ^
|
||||||
|
const DeepCollectionEquality().hash(loadState) ^
|
||||||
|
const DeepCollectionEquality().hash(isDeleted);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
@ -270,11 +487,14 @@ class _$_DocState implements _DocState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class _DocState implements DocState {
|
abstract class _DocState implements DocState {
|
||||||
const factory _DocState({required DocLoadState loadState}) = _$_DocState;
|
const factory _DocState(
|
||||||
|
{required DocLoadState loadState, required bool isDeleted}) = _$_DocState;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
DocLoadState get loadState => throw _privateConstructorUsedError;
|
DocLoadState get loadState => throw _privateConstructorUsedError;
|
||||||
@override
|
@override
|
||||||
|
bool get isDeleted => throw _privateConstructorUsedError;
|
||||||
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
_$DocStateCopyWith<_DocState> get copyWith =>
|
_$DocStateCopyWith<_DocState> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
|
@ -20,7 +20,10 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
|
|||||||
Stream<ViewState> mapEventToState(ViewEvent event) async* {
|
Stream<ViewState> mapEventToState(ViewEvent event) async* {
|
||||||
yield* event.map(
|
yield* event.map(
|
||||||
initial: (e) async* {
|
initial: (e) async* {
|
||||||
listener.start(updatedCallback: (result) => add(ViewEvent.viewDidUpdate(result)));
|
listener.updatedNotifier.addPublishListener((result) {
|
||||||
|
add(ViewEvent.viewDidUpdate(result));
|
||||||
|
});
|
||||||
|
listener.start();
|
||||||
yield state;
|
yield state;
|
||||||
},
|
},
|
||||||
setIsEditing: (e) async* {
|
setIsEditing: (e) async* {
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_infra/notifier.dart';
|
||||||
|
|
||||||
typedef ViewUpdatedCallback = void Function(Either<View, WorkspaceError>);
|
typedef ViewUpdatedCallback = void Function(Either<View, WorkspaceError>);
|
||||||
|
|
||||||
|
typedef DeleteNotifierValue = Either<View, WorkspaceError>;
|
||||||
|
typedef UpdateNotifierValue = Either<View, WorkspaceError>;
|
||||||
|
typedef RestoreNotifierValue = Either<View, WorkspaceError>;
|
||||||
|
|
||||||
abstract class IView {
|
abstract class IView {
|
||||||
View get view;
|
View get view;
|
||||||
|
|
||||||
@ -15,7 +20,13 @@ abstract class IView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class IViewListener {
|
abstract class IViewListener {
|
||||||
void start({ViewUpdatedCallback? updatedCallback});
|
void start();
|
||||||
|
|
||||||
|
PublishNotifier<UpdateNotifierValue> get updatedNotifier;
|
||||||
|
|
||||||
|
PublishNotifier<DeleteNotifierValue> get deletedNotifier;
|
||||||
|
|
||||||
|
PublishNotifier<RestoreNotifierValue> get restoredNotifier;
|
||||||
|
|
||||||
Future<void> stop();
|
Future<void> stop();
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,12 @@ class HomeDepsResolver {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Doc
|
// Doc
|
||||||
getIt.registerFactoryParam<DocBloc, String, void>((docId, _) => DocBloc(docManager: getIt<IDoc>(param1: docId)));
|
getIt.registerFactoryParam<DocBloc, View, void>(
|
||||||
|
(view, _) => DocBloc(
|
||||||
|
docManager: getIt<IDoc>(param1: view.id),
|
||||||
|
listener: getIt<IViewListener>(param1: view),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
// trash
|
// trash
|
||||||
getIt.registerLazySingleton<TrashRepo>(() => TrashRepo());
|
getIt.registerLazySingleton<TrashRepo>(() => TrashRepo());
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:app_flowy/workspace/domain/i_view.dart';
|
import 'package:app_flowy/workspace/domain/i_view.dart';
|
||||||
import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
|
import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
|
||||||
|
import 'package:flowy_infra/notifier.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||||
@ -40,12 +41,21 @@ class IViewListenerImpl extends IViewListener {
|
|||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void start({ViewUpdatedCallback? updatedCallback}) {
|
void start() {
|
||||||
repo.startWatching(update: updatedCallback);
|
repo.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> stop() async {
|
Future<void> stop() async {
|
||||||
await repo.close();
|
await repo.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
PublishNotifier<DeleteNotifierValue> get deletedNotifier => repo.deletedNotifier;
|
||||||
|
|
||||||
|
@override
|
||||||
|
PublishNotifier<UpdateNotifierValue> get updatedNotifier => repo.updatedNotifier;
|
||||||
|
|
||||||
|
@override
|
||||||
|
PublishNotifier<RestoreNotifierValue> get restoredNotifier => repo.updatedNotifier;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import 'package:flowy_sdk/protobuf/flowy-workspace/view_update.pb.dart';
|
|||||||
import 'package:flowy_sdk/rust_stream.dart';
|
import 'package:flowy_sdk/rust_stream.dart';
|
||||||
|
|
||||||
import 'package:app_flowy/workspace/domain/i_view.dart';
|
import 'package:app_flowy/workspace/domain/i_view.dart';
|
||||||
|
import 'package:flowy_infra/notifier.dart';
|
||||||
|
|
||||||
import 'helper.dart';
|
import 'helper.dart';
|
||||||
|
|
||||||
@ -52,7 +53,9 @@ class ViewRepository {
|
|||||||
|
|
||||||
class ViewListenerRepository {
|
class ViewListenerRepository {
|
||||||
StreamSubscription<SubscribeObject>? _subscription;
|
StreamSubscription<SubscribeObject>? _subscription;
|
||||||
ViewUpdatedCallback? _update;
|
PublishNotifier<UpdateNotifierValue> updatedNotifier = PublishNotifier<UpdateNotifierValue>();
|
||||||
|
PublishNotifier<DeleteNotifierValue> deletedNotifier = PublishNotifier<DeleteNotifierValue>();
|
||||||
|
PublishNotifier<RestoreNotifierValue> restoredNotifier = PublishNotifier<RestoreNotifierValue>();
|
||||||
late WorkspaceNotificationParser _parser;
|
late WorkspaceNotificationParser _parser;
|
||||||
View view;
|
View view;
|
||||||
|
|
||||||
@ -60,10 +63,7 @@ class ViewListenerRepository {
|
|||||||
required this.view,
|
required this.view,
|
||||||
});
|
});
|
||||||
|
|
||||||
void startWatching({
|
void start() {
|
||||||
ViewUpdatedCallback? update,
|
|
||||||
}) {
|
|
||||||
_update = update;
|
|
||||||
_parser = WorkspaceNotificationParser(
|
_parser = WorkspaceNotificationParser(
|
||||||
id: view.id,
|
id: view.id,
|
||||||
callback: (ty, result) {
|
callback: (ty, result) {
|
||||||
@ -77,15 +77,22 @@ class ViewListenerRepository {
|
|||||||
void _handleObservableType(WorkspaceNotification ty, Either<Uint8List, WorkspaceError> result) {
|
void _handleObservableType(WorkspaceNotification ty, Either<Uint8List, WorkspaceError> result) {
|
||||||
switch (ty) {
|
switch (ty) {
|
||||||
case WorkspaceNotification.ViewUpdated:
|
case WorkspaceNotification.ViewUpdated:
|
||||||
if (_update != null) {
|
result.fold(
|
||||||
result.fold(
|
(payload) => updatedNotifier.value = left(View.fromBuffer(payload)),
|
||||||
(payload) {
|
(error) => updatedNotifier.value = right(error),
|
||||||
final view = View.fromBuffer(payload);
|
);
|
||||||
_update!(left(view));
|
break;
|
||||||
},
|
case WorkspaceNotification.ViewDeleted:
|
||||||
(error) => _update!(right(error)),
|
result.fold(
|
||||||
);
|
(payload) => deletedNotifier.value = left(View.fromBuffer(payload)),
|
||||||
}
|
(error) => deletedNotifier.value = right(error),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case WorkspaceNotification.ViewRestored:
|
||||||
|
result.fold(
|
||||||
|
(payload) => restoredNotifier.value = left(View.fromBuffer(payload)),
|
||||||
|
(error) => restoredNotifier.value = right(error),
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -28,7 +28,7 @@ class _DocPageState extends State<DocPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
docBloc = getIt<DocBloc>(param1: super.widget.view.id)..add(const DocEvent.initial());
|
docBloc = getIt<DocBloc>(param1: super.widget.view)..add(const DocEvent.initial());
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ class DocStackContext extends HomeStackContext {
|
|||||||
|
|
||||||
DocStackContext({required View view, Key? key}) : _view = view {
|
DocStackContext({required View view, Key? key}) : _view = view {
|
||||||
_listener = getIt<IViewListener>(param1: view);
|
_listener = getIt<IViewListener>(param1: view);
|
||||||
_listener.start(updatedCallback: (result) {
|
_listener.updatedNotifier.addPublishListener((result) {
|
||||||
result.fold(
|
result.fold(
|
||||||
(newView) {
|
(newView) {
|
||||||
_view = newView;
|
_view = newView;
|
||||||
@ -24,6 +24,7 @@ class DocStackContext extends HomeStackContext {
|
|||||||
(error) {},
|
(error) {},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
_listener.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -68,7 +68,7 @@ class ViewSection extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// The ViewListNotifier will be updated after ViewListData changed passed by parent widget
|
// The ViewSectionNotifier will be updated after AppDataNotifier changed passed by parent widget
|
||||||
return ChangeNotifierProxyProvider<AppDataNotifier, ViewSectionNotifier>(
|
return ChangeNotifierProxyProvider<AppDataNotifier, ViewSectionNotifier>(
|
||||||
create: (_) {
|
create: (_) {
|
||||||
final views = Provider.of<AppDataNotifier>(context, listen: false).views;
|
final views = Provider.of<AppDataNotifier>(context, listen: false).views;
|
||||||
|
20
app_flowy/packages/flowy_infra/lib/notifier.dart
Normal file
20
app_flowy/packages/flowy_infra/lib/notifier.dart
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class PublishNotifier<T> extends ChangeNotifier {
|
||||||
|
T? _value;
|
||||||
|
|
||||||
|
set value(T newValue) {
|
||||||
|
_value = newValue;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
T? get currentValue => _value;
|
||||||
|
|
||||||
|
void addPublishListener(void Function(T) callback) {
|
||||||
|
super.addListener(() {
|
||||||
|
if (_value != null) {
|
||||||
|
callback(_value!);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,8 @@ class WorkspaceNotification extends $pb.ProtobufEnum {
|
|||||||
static const WorkspaceNotification AppUpdated = WorkspaceNotification._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppUpdated');
|
static const WorkspaceNotification AppUpdated = WorkspaceNotification._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppUpdated');
|
||||||
static const WorkspaceNotification AppViewsChanged = WorkspaceNotification._(24, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppViewsChanged');
|
static const WorkspaceNotification AppViewsChanged = WorkspaceNotification._(24, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppViewsChanged');
|
||||||
static const WorkspaceNotification ViewUpdated = WorkspaceNotification._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewUpdated');
|
static const WorkspaceNotification ViewUpdated = WorkspaceNotification._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewUpdated');
|
||||||
|
static const WorkspaceNotification ViewDeleted = WorkspaceNotification._(32, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewDeleted');
|
||||||
|
static const WorkspaceNotification ViewRestored = WorkspaceNotification._(33, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewRestored');
|
||||||
static const WorkspaceNotification UserUnauthorized = WorkspaceNotification._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserUnauthorized');
|
static const WorkspaceNotification UserUnauthorized = WorkspaceNotification._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserUnauthorized');
|
||||||
static const WorkspaceNotification TrashUpdated = WorkspaceNotification._(1000, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TrashUpdated');
|
static const WorkspaceNotification TrashUpdated = WorkspaceNotification._(1000, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TrashUpdated');
|
||||||
|
|
||||||
@ -32,6 +34,8 @@ class WorkspaceNotification extends $pb.ProtobufEnum {
|
|||||||
AppUpdated,
|
AppUpdated,
|
||||||
AppViewsChanged,
|
AppViewsChanged,
|
||||||
ViewUpdated,
|
ViewUpdated,
|
||||||
|
ViewDeleted,
|
||||||
|
ViewRestored,
|
||||||
UserUnauthorized,
|
UserUnauthorized,
|
||||||
TrashUpdated,
|
TrashUpdated,
|
||||||
];
|
];
|
||||||
|
@ -21,10 +21,12 @@ const WorkspaceNotification$json = const {
|
|||||||
const {'1': 'AppUpdated', '2': 21},
|
const {'1': 'AppUpdated', '2': 21},
|
||||||
const {'1': 'AppViewsChanged', '2': 24},
|
const {'1': 'AppViewsChanged', '2': 24},
|
||||||
const {'1': 'ViewUpdated', '2': 31},
|
const {'1': 'ViewUpdated', '2': 31},
|
||||||
|
const {'1': 'ViewDeleted', '2': 32},
|
||||||
|
const {'1': 'ViewRestored', '2': 33},
|
||||||
const {'1': 'UserUnauthorized', '2': 100},
|
const {'1': 'UserUnauthorized', '2': 100},
|
||||||
const {'1': 'TrashUpdated', '2': 1000},
|
const {'1': 'TrashUpdated', '2': 1000},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Descriptor for `WorkspaceNotification`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
/// Descriptor for `WorkspaceNotification`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||||
final $typed_data.Uint8List workspaceNotificationDescriptor = $convert.base64Decode('ChVXb3Jrc3BhY2VOb3RpZmljYXRpb24SCwoHVW5rbm93bhAAEhcKE1VzZXJDcmVhdGVXb3Jrc3BhY2UQChIXChNVc2VyRGVsZXRlV29ya3NwYWNlEAsSFAoQV29ya3NwYWNlVXBkYXRlZBAMEhgKFFdvcmtzcGFjZUxpc3RVcGRhdGVkEA0SGAoUV29ya3NwYWNlQXBwc0NoYW5nZWQQDhIOCgpBcHBVcGRhdGVkEBUSEwoPQXBwVmlld3NDaGFuZ2VkEBgSDwoLVmlld1VwZGF0ZWQQHxIUChBVc2VyVW5hdXRob3JpemVkEGQSEQoMVHJhc2hVcGRhdGVkEOgH');
|
final $typed_data.Uint8List workspaceNotificationDescriptor = $convert.base64Decode('ChVXb3Jrc3BhY2VOb3RpZmljYXRpb24SCwoHVW5rbm93bhAAEhcKE1VzZXJDcmVhdGVXb3Jrc3BhY2UQChIXChNVc2VyRGVsZXRlV29ya3NwYWNlEAsSFAoQV29ya3NwYWNlVXBkYXRlZBAMEhgKFFdvcmtzcGFjZUxpc3RVcGRhdGVkEA0SGAoUV29ya3NwYWNlQXBwc0NoYW5nZWQQDhIOCgpBcHBVcGRhdGVkEBUSEwoPQXBwVmlld3NDaGFuZ2VkEBgSDwoLVmlld1VwZGF0ZWQQHxIPCgtWaWV3RGVsZXRlZBAgEhAKDFZpZXdSZXN0b3JlZBAhEhQKEFVzZXJVbmF1dGhvcml6ZWQQZBIRCgxUcmFzaFVwZGF0ZWQQ6Ac=');
|
||||||
|
@ -1025,5 +1025,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "8.0.0"
|
version: "8.0.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.14.0 <3.0.0"
|
dart: ">=2.15.0-116.0.dev <3.0.0"
|
||||||
flutter: ">=2.5.0"
|
flutter: ">=2.5.0"
|
||||||
|
@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.12.0 <3.0.0"
|
sdk: ">=2.15.0-116.0.dev <3.0.0"
|
||||||
|
|
||||||
# Dependencies specify other packages that your package needs in order to work.
|
# Dependencies specify other packages that your package needs in order to work.
|
||||||
# To automatically upgrade your package dependencies to the latest versions
|
# To automatically upgrade your package dependencies to the latest versions
|
||||||
|
@ -2,6 +2,8 @@ use flowy_dart_notify::DartNotifyBuilder;
|
|||||||
use flowy_derive::ProtoBuf_Enum;
|
use flowy_derive::ProtoBuf_Enum;
|
||||||
const OBSERVABLE_CATEGORY: &'static str = "Workspace";
|
const OBSERVABLE_CATEGORY: &'static str = "Workspace";
|
||||||
|
|
||||||
|
// Opti: Using the Rust macro to generate the serde code automatically that can
|
||||||
|
// be use directly in flutter
|
||||||
#[derive(ProtoBuf_Enum, Debug)]
|
#[derive(ProtoBuf_Enum, Debug)]
|
||||||
pub(crate) enum WorkspaceNotification {
|
pub(crate) enum WorkspaceNotification {
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
@ -13,6 +15,8 @@ pub(crate) enum WorkspaceNotification {
|
|||||||
AppUpdated = 21,
|
AppUpdated = 21,
|
||||||
AppViewsChanged = 24,
|
AppViewsChanged = 24,
|
||||||
ViewUpdated = 31,
|
ViewUpdated = 31,
|
||||||
|
ViewDeleted = 32,
|
||||||
|
ViewRestored = 33,
|
||||||
UserUnauthorized = 100,
|
UserUnauthorized = 100,
|
||||||
TrashUpdated = 1000,
|
TrashUpdated = 1000,
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@ pub enum WorkspaceNotification {
|
|||||||
AppUpdated = 21,
|
AppUpdated = 21,
|
||||||
AppViewsChanged = 24,
|
AppViewsChanged = 24,
|
||||||
ViewUpdated = 31,
|
ViewUpdated = 31,
|
||||||
|
ViewDeleted = 32,
|
||||||
|
ViewRestored = 33,
|
||||||
UserUnauthorized = 100,
|
UserUnauthorized = 100,
|
||||||
TrashUpdated = 1000,
|
TrashUpdated = 1000,
|
||||||
}
|
}
|
||||||
@ -54,6 +56,8 @@ impl ::protobuf::ProtobufEnum for WorkspaceNotification {
|
|||||||
21 => ::std::option::Option::Some(WorkspaceNotification::AppUpdated),
|
21 => ::std::option::Option::Some(WorkspaceNotification::AppUpdated),
|
||||||
24 => ::std::option::Option::Some(WorkspaceNotification::AppViewsChanged),
|
24 => ::std::option::Option::Some(WorkspaceNotification::AppViewsChanged),
|
||||||
31 => ::std::option::Option::Some(WorkspaceNotification::ViewUpdated),
|
31 => ::std::option::Option::Some(WorkspaceNotification::ViewUpdated),
|
||||||
|
32 => ::std::option::Option::Some(WorkspaceNotification::ViewDeleted),
|
||||||
|
33 => ::std::option::Option::Some(WorkspaceNotification::ViewRestored),
|
||||||
100 => ::std::option::Option::Some(WorkspaceNotification::UserUnauthorized),
|
100 => ::std::option::Option::Some(WorkspaceNotification::UserUnauthorized),
|
||||||
1000 => ::std::option::Option::Some(WorkspaceNotification::TrashUpdated),
|
1000 => ::std::option::Option::Some(WorkspaceNotification::TrashUpdated),
|
||||||
_ => ::std::option::Option::None
|
_ => ::std::option::Option::None
|
||||||
@ -71,6 +75,8 @@ impl ::protobuf::ProtobufEnum for WorkspaceNotification {
|
|||||||
WorkspaceNotification::AppUpdated,
|
WorkspaceNotification::AppUpdated,
|
||||||
WorkspaceNotification::AppViewsChanged,
|
WorkspaceNotification::AppViewsChanged,
|
||||||
WorkspaceNotification::ViewUpdated,
|
WorkspaceNotification::ViewUpdated,
|
||||||
|
WorkspaceNotification::ViewDeleted,
|
||||||
|
WorkspaceNotification::ViewRestored,
|
||||||
WorkspaceNotification::UserUnauthorized,
|
WorkspaceNotification::UserUnauthorized,
|
||||||
WorkspaceNotification::TrashUpdated,
|
WorkspaceNotification::TrashUpdated,
|
||||||
];
|
];
|
||||||
@ -101,37 +107,42 @@ impl ::protobuf::reflect::ProtobufValue for WorkspaceNotification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||||
\n\x10observable.proto*\xff\x01\n\x15WorkspaceNotification\x12\x0b\n\x07\
|
\n\x10observable.proto*\xa2\x02\n\x15WorkspaceNotification\x12\x0b\n\x07\
|
||||||
Unknown\x10\0\x12\x17\n\x13UserCreateWorkspace\x10\n\x12\x17\n\x13UserDe\
|
Unknown\x10\0\x12\x17\n\x13UserCreateWorkspace\x10\n\x12\x17\n\x13UserDe\
|
||||||
leteWorkspace\x10\x0b\x12\x14\n\x10WorkspaceUpdated\x10\x0c\x12\x18\n\
|
leteWorkspace\x10\x0b\x12\x14\n\x10WorkspaceUpdated\x10\x0c\x12\x18\n\
|
||||||
\x14WorkspaceListUpdated\x10\r\x12\x18\n\x14WorkspaceAppsChanged\x10\x0e\
|
\x14WorkspaceListUpdated\x10\r\x12\x18\n\x14WorkspaceAppsChanged\x10\x0e\
|
||||||
\x12\x0e\n\nAppUpdated\x10\x15\x12\x13\n\x0fAppViewsChanged\x10\x18\x12\
|
\x12\x0e\n\nAppUpdated\x10\x15\x12\x13\n\x0fAppViewsChanged\x10\x18\x12\
|
||||||
\x0f\n\x0bViewUpdated\x10\x1f\x12\x14\n\x10UserUnauthorized\x10d\x12\x11\
|
\x0f\n\x0bViewUpdated\x10\x1f\x12\x0f\n\x0bViewDeleted\x10\x20\x12\x10\n\
|
||||||
\n\x0cTrashUpdated\x10\xe8\x07J\xed\x03\n\x06\x12\x04\0\0\x0e\x01\n\x08\
|
\x0cViewRestored\x10!\x12\x14\n\x10UserUnauthorized\x10d\x12\x11\n\x0cTr\
|
||||||
\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x05\0\x12\x04\x02\0\x0e\x01\n\n\n\
|
ashUpdated\x10\xe8\x07J\xbf\x04\n\x06\x12\x04\0\0\x10\x01\n\x08\n\x01\
|
||||||
\x03\x05\0\x01\x12\x03\x02\x05\x1a\n\x0b\n\x04\x05\0\x02\0\x12\x03\x03\
|
\x0c\x12\x03\0\0\x12\n\n\n\x02\x05\0\x12\x04\x02\0\x10\x01\n\n\n\x03\x05\
|
||||||
\x04\x10\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x03\x04\x0b\n\x0c\n\x05\x05\
|
\0\x01\x12\x03\x02\x05\x1a\n\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x04\x10\n\
|
||||||
\0\x02\0\x02\x12\x03\x03\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\
|
\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x03\x04\x0b\n\x0c\n\x05\x05\0\x02\0\
|
||||||
\x04\x1d\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x04\x04\x17\n\x0c\n\x05\
|
\x02\x12\x03\x03\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\x04\x1d\n\
|
||||||
\x05\0\x02\x01\x02\x12\x03\x04\x1a\x1c\n\x0b\n\x04\x05\0\x02\x02\x12\x03\
|
\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x04\x04\x17\n\x0c\n\x05\x05\0\x02\
|
||||||
\x05\x04\x1d\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\x05\x04\x17\n\x0c\n\
|
\x01\x02\x12\x03\x04\x1a\x1c\n\x0b\n\x04\x05\0\x02\x02\x12\x03\x05\x04\
|
||||||
\x05\x05\0\x02\x02\x02\x12\x03\x05\x1a\x1c\n\x0b\n\x04\x05\0\x02\x03\x12\
|
\x1d\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\x05\x04\x17\n\x0c\n\x05\x05\0\
|
||||||
\x03\x06\x04\x1a\n\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\x06\x04\x14\n\x0c\
|
\x02\x02\x02\x12\x03\x05\x1a\x1c\n\x0b\n\x04\x05\0\x02\x03\x12\x03\x06\
|
||||||
\n\x05\x05\0\x02\x03\x02\x12\x03\x06\x17\x19\n\x0b\n\x04\x05\0\x02\x04\
|
\x04\x1a\n\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\x06\x04\x14\n\x0c\n\x05\
|
||||||
\x12\x03\x07\x04\x1e\n\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x07\x04\x18\n\
|
\x05\0\x02\x03\x02\x12\x03\x06\x17\x19\n\x0b\n\x04\x05\0\x02\x04\x12\x03\
|
||||||
\x0c\n\x05\x05\0\x02\x04\x02\x12\x03\x07\x1b\x1d\n\x0b\n\x04\x05\0\x02\
|
\x07\x04\x1e\n\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x07\x04\x18\n\x0c\n\
|
||||||
\x05\x12\x03\x08\x04\x1e\n\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x08\x04\
|
\x05\x05\0\x02\x04\x02\x12\x03\x07\x1b\x1d\n\x0b\n\x04\x05\0\x02\x05\x12\
|
||||||
\x18\n\x0c\n\x05\x05\0\x02\x05\x02\x12\x03\x08\x1b\x1d\n\x0b\n\x04\x05\0\
|
\x03\x08\x04\x1e\n\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x08\x04\x18\n\x0c\
|
||||||
\x02\x06\x12\x03\t\x04\x14\n\x0c\n\x05\x05\0\x02\x06\x01\x12\x03\t\x04\
|
\n\x05\x05\0\x02\x05\x02\x12\x03\x08\x1b\x1d\n\x0b\n\x04\x05\0\x02\x06\
|
||||||
\x0e\n\x0c\n\x05\x05\0\x02\x06\x02\x12\x03\t\x11\x13\n\x0b\n\x04\x05\0\
|
\x12\x03\t\x04\x14\n\x0c\n\x05\x05\0\x02\x06\x01\x12\x03\t\x04\x0e\n\x0c\
|
||||||
\x02\x07\x12\x03\n\x04\x19\n\x0c\n\x05\x05\0\x02\x07\x01\x12\x03\n\x04\
|
\n\x05\x05\0\x02\x06\x02\x12\x03\t\x11\x13\n\x0b\n\x04\x05\0\x02\x07\x12\
|
||||||
\x13\n\x0c\n\x05\x05\0\x02\x07\x02\x12\x03\n\x16\x18\n\x0b\n\x04\x05\0\
|
\x03\n\x04\x19\n\x0c\n\x05\x05\0\x02\x07\x01\x12\x03\n\x04\x13\n\x0c\n\
|
||||||
\x02\x08\x12\x03\x0b\x04\x15\n\x0c\n\x05\x05\0\x02\x08\x01\x12\x03\x0b\
|
\x05\x05\0\x02\x07\x02\x12\x03\n\x16\x18\n\x0b\n\x04\x05\0\x02\x08\x12\
|
||||||
\x04\x0f\n\x0c\n\x05\x05\0\x02\x08\x02\x12\x03\x0b\x12\x14\n\x0b\n\x04\
|
\x03\x0b\x04\x15\n\x0c\n\x05\x05\0\x02\x08\x01\x12\x03\x0b\x04\x0f\n\x0c\
|
||||||
\x05\0\x02\t\x12\x03\x0c\x04\x1b\n\x0c\n\x05\x05\0\x02\t\x01\x12\x03\x0c\
|
\n\x05\x05\0\x02\x08\x02\x12\x03\x0b\x12\x14\n\x0b\n\x04\x05\0\x02\t\x12\
|
||||||
\x04\x14\n\x0c\n\x05\x05\0\x02\t\x02\x12\x03\x0c\x17\x1a\n\x0b\n\x04\x05\
|
\x03\x0c\x04\x15\n\x0c\n\x05\x05\0\x02\t\x01\x12\x03\x0c\x04\x0f\n\x0c\n\
|
||||||
\0\x02\n\x12\x03\r\x04\x18\n\x0c\n\x05\x05\0\x02\n\x01\x12\x03\r\x04\x10\
|
\x05\x05\0\x02\t\x02\x12\x03\x0c\x12\x14\n\x0b\n\x04\x05\0\x02\n\x12\x03\
|
||||||
\n\x0c\n\x05\x05\0\x02\n\x02\x12\x03\r\x13\x17b\x06proto3\
|
\r\x04\x16\n\x0c\n\x05\x05\0\x02\n\x01\x12\x03\r\x04\x10\n\x0c\n\x05\x05\
|
||||||
|
\0\x02\n\x02\x12\x03\r\x13\x15\n\x0b\n\x04\x05\0\x02\x0b\x12\x03\x0e\x04\
|
||||||
|
\x1b\n\x0c\n\x05\x05\0\x02\x0b\x01\x12\x03\x0e\x04\x14\n\x0c\n\x05\x05\0\
|
||||||
|
\x02\x0b\x02\x12\x03\x0e\x17\x1a\n\x0b\n\x04\x05\0\x02\x0c\x12\x03\x0f\
|
||||||
|
\x04\x18\n\x0c\n\x05\x05\0\x02\x0c\x01\x12\x03\x0f\x04\x10\n\x0c\n\x05\
|
||||||
|
\x05\0\x02\x0c\x02\x12\x03\x0f\x13\x17b\x06proto3\
|
||||||
";
|
";
|
||||||
|
|
||||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||||
|
@ -10,6 +10,8 @@ enum WorkspaceNotification {
|
|||||||
AppUpdated = 21;
|
AppUpdated = 21;
|
||||||
AppViewsChanged = 24;
|
AppViewsChanged = 24;
|
||||||
ViewUpdated = 31;
|
ViewUpdated = 31;
|
||||||
|
ViewDeleted = 32;
|
||||||
|
ViewRestored = 33;
|
||||||
UserUnauthorized = 100;
|
UserUnauthorized = 100;
|
||||||
TrashUpdated = 1000;
|
TrashUpdated = 1000;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ use flowy_document::{
|
|||||||
|
|
||||||
use crate::{entities::trash::TrashType, errors::WorkspaceResult};
|
use crate::{entities::trash::TrashType, errors::WorkspaceResult};
|
||||||
|
|
||||||
|
use crate::entities::trash::TrashIdentifiers;
|
||||||
use futures::{FutureExt, StreamExt};
|
use futures::{FutureExt, StreamExt};
|
||||||
use std::{collections::HashSet, sync::Arc};
|
use std::{collections::HashSet, sync::Arc};
|
||||||
|
|
||||||
@ -263,16 +264,26 @@ async fn handle_trash_event(
|
|||||||
let db_result = database.db_connection();
|
let db_result = database.db_connection();
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
TrashEvent::NewTrash(identifiers, ret) | TrashEvent::Putback(identifiers, ret) => {
|
TrashEvent::NewTrash(identifiers, ret) => {
|
||||||
let result = || {
|
let result = || {
|
||||||
let conn = &*db_result?;
|
let conn = &*db_result?;
|
||||||
let _ = conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
let view_tables = get_view_table_from(identifiers, conn)?;
|
||||||
for identifier in identifiers.items {
|
for view_table in view_tables {
|
||||||
let view_table = ViewTableSql::read_view(&identifier.id, conn)?;
|
let _ = notify_views_changed(&view_table.belong_to_id, trash_can.clone(), conn)?;
|
||||||
let _ = notify_views_changed(&view_table.belong_to_id, trash_can.clone(), conn)?;
|
notify_dart(view_table, WorkspaceNotification::ViewDeleted);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok::<(), WorkspaceError>(())
|
||||||
})?;
|
};
|
||||||
|
let _ = ret.send(result()).await;
|
||||||
|
},
|
||||||
|
TrashEvent::Putback(identifiers, ret) => {
|
||||||
|
let result = || {
|
||||||
|
let conn = &*db_result?;
|
||||||
|
let view_tables = get_view_table_from(identifiers, conn)?;
|
||||||
|
for view_table in view_tables {
|
||||||
|
let _ = notify_views_changed(&view_table.belong_to_id, trash_can.clone(), conn)?;
|
||||||
|
notify_dart(view_table, WorkspaceNotification::ViewRestored);
|
||||||
|
}
|
||||||
Ok::<(), WorkspaceError>(())
|
Ok::<(), WorkspaceError>(())
|
||||||
};
|
};
|
||||||
let _ = ret.send(result()).await;
|
let _ = ret.send(result()).await;
|
||||||
@ -302,6 +313,26 @@ async fn handle_trash_event(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_view_table_from(
|
||||||
|
identifiers: TrashIdentifiers,
|
||||||
|
conn: &SqliteConnection,
|
||||||
|
) -> Result<Vec<ViewTable>, WorkspaceError> {
|
||||||
|
let mut view_tables = vec![];
|
||||||
|
let _ = conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
||||||
|
for identifier in identifiers.items {
|
||||||
|
let view_table = ViewTableSql::read_view(&identifier.id, conn)?;
|
||||||
|
view_tables.push(view_table);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
Ok(view_tables)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn notify_dart(view_table: ViewTable, notification: WorkspaceNotification) {
|
||||||
|
let view: View = view_table.into();
|
||||||
|
send_dart_notification(&view.id, notification).payload(view).send();
|
||||||
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(belong_to_id, trash_can, conn), fields(view_count), err)]
|
#[tracing::instrument(skip(belong_to_id, trash_can, conn), fields(view_count), err)]
|
||||||
fn notify_views_changed(belong_to_id: &str, trash_can: Arc<TrashCan>, conn: &SqliteConnection) -> WorkspaceResult<()> {
|
fn notify_views_changed(belong_to_id: &str, trash_can: Arc<TrashCan>, conn: &SqliteConnection) -> WorkspaceResult<()> {
|
||||||
let repeated_view = read_local_belonging_view(belong_to_id, trash_can.clone(), conn)?;
|
let repeated_view = read_local_belonging_view(belong_to_id, trash_can.clone(), conn)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user