replace ViewSectionItem stateful with bloc

This commit is contained in:
appflowy 2021-10-12 13:07:41 +08:00
parent c8a8910b70
commit 9898b8bd24
21 changed files with 1007 additions and 801 deletions

View File

@ -10,14 +10,14 @@ import 'package:dartz/dartz.dart';
part 'menu_listen.freezed.dart';
class MenuListenBloc extends Bloc<MenuListenEvent, MenuListenState> {
final IWorkspaceWatch watch;
MenuListenBloc(this.watch) : super(const MenuListenState.initial());
final IWorkspaceListener listener;
MenuListenBloc(this.listener) : super(const MenuListenState.initial());
@override
Stream<MenuListenState> mapEventToState(MenuListenEvent event) async* {
yield* event.map(
started: (_) async* {
watch.startWatching(
listener.start(
addAppCallback: (appsOrFail) => _handleAppsOrFail(appsOrFail),
);
},
@ -32,7 +32,7 @@ class MenuListenBloc extends Bloc<MenuListenEvent, MenuListenState> {
@override
Future<void> close() async {
await watch.stopWatching();
await listener.stop();
return super.close();
}

View File

@ -1,3 +1,4 @@
import 'package:app_flowy/workspace/domain/view_edit.dart';
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
@ -12,32 +13,46 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
ViewBloc({
required this.iViewImpl,
}) : super(ViewState.initial());
}) : super(ViewState.initial(iViewImpl.view));
@override
Stream<ViewState> mapEventToState(ViewEvent event) async* {
yield* event.map(initial: (_) async* {
yield state;
});
yield* event.map(
setIsSelected: (e) async* {
yield state.copyWith(isSelected: e.isSelected);
},
setIsEditing: (e) async* {
yield state.copyWith(isEditing: e.isEditing);
},
setAction: (e) async* {
yield state.copyWith(action: e.action);
},
);
}
}
@freezed
class ViewEvent with _$ViewEvent {
const factory ViewEvent.initial() = Initial;
const factory ViewEvent.setIsSelected(bool isSelected) = SetSelected;
const factory ViewEvent.setIsEditing(bool isEditing) = SetEditing;
const factory ViewEvent.setAction(Option<ViewAction> action) = SetAction;
}
@freezed
class ViewState with _$ViewState {
const factory ViewState({
required bool isLoading,
required Option<View> view,
required View view,
required bool isSelected,
required bool isEditing,
required Option<ViewAction> action,
required Either<Unit, WorkspaceError> successOrFailure,
}) = _ViewState;
factory ViewState.initial() => ViewState(
isLoading: false,
view: none(),
factory ViewState.initial(View view) => ViewState(
view: view,
isSelected: false,
isEditing: false,
action: none(),
successOrFailure: left(unit),
);
}

View File

@ -16,8 +16,22 @@ final _privateConstructorUsedError = UnsupportedError(
class _$ViewEventTearOff {
const _$ViewEventTearOff();
Initial initial() {
return const Initial();
SetSelected setIsSelected(bool isSelected) {
return SetSelected(
isSelected,
);
}
SetEditing setIsEditing(bool isEditing) {
return SetEditing(
isEditing,
);
}
SetAction setAction(Option<ViewAction> action) {
return SetAction(
action,
);
}
}
@ -28,23 +42,31 @@ const $ViewEvent = _$ViewEventTearOff();
mixin _$ViewEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function(bool isSelected) setIsSelected,
required TResult Function(bool isEditing) setIsEditing,
required TResult Function(Option<ViewAction> action) setAction,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function(bool isSelected)? setIsSelected,
TResult Function(bool isEditing)? setIsEditing,
TResult Function(Option<ViewAction> action)? setAction,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(Initial value) initial,
required TResult Function(SetSelected value) setIsSelected,
required TResult Function(SetEditing value) setIsEditing,
required TResult Function(SetAction value) setAction,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(Initial value)? initial,
TResult Function(SetSelected value)? setIsSelected,
TResult Function(SetEditing value)? setIsEditing,
TResult Function(SetAction value)? setAction,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@ -66,55 +88,87 @@ class _$ViewEventCopyWithImpl<$Res> implements $ViewEventCopyWith<$Res> {
}
/// @nodoc
abstract class $InitialCopyWith<$Res> {
factory $InitialCopyWith(Initial value, $Res Function(Initial) then) =
_$InitialCopyWithImpl<$Res>;
abstract class $SetSelectedCopyWith<$Res> {
factory $SetSelectedCopyWith(
SetSelected value, $Res Function(SetSelected) then) =
_$SetSelectedCopyWithImpl<$Res>;
$Res call({bool isSelected});
}
/// @nodoc
class _$InitialCopyWithImpl<$Res> extends _$ViewEventCopyWithImpl<$Res>
implements $InitialCopyWith<$Res> {
_$InitialCopyWithImpl(Initial _value, $Res Function(Initial) _then)
: super(_value, (v) => _then(v as Initial));
class _$SetSelectedCopyWithImpl<$Res> extends _$ViewEventCopyWithImpl<$Res>
implements $SetSelectedCopyWith<$Res> {
_$SetSelectedCopyWithImpl(
SetSelected _value, $Res Function(SetSelected) _then)
: super(_value, (v) => _then(v as SetSelected));
@override
Initial get _value => super._value as Initial;
SetSelected get _value => super._value as SetSelected;
@override
$Res call({
Object? isSelected = freezed,
}) {
return _then(SetSelected(
isSelected == freezed
? _value.isSelected
: isSelected // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
/// @nodoc
class _$Initial implements Initial {
const _$Initial();
class _$SetSelected implements SetSelected {
const _$SetSelected(this.isSelected);
@override
final bool isSelected;
@override
String toString() {
return 'ViewEvent.initial()';
return 'ViewEvent.setIsSelected(isSelected: $isSelected)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) || (other is Initial);
return identical(this, other) ||
(other is SetSelected &&
(identical(other.isSelected, isSelected) ||
const DeepCollectionEquality()
.equals(other.isSelected, isSelected)));
}
@override
int get hashCode => runtimeType.hashCode;
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(isSelected);
@JsonKey(ignore: true)
@override
$SetSelectedCopyWith<SetSelected> get copyWith =>
_$SetSelectedCopyWithImpl<SetSelected>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function(bool isSelected) setIsSelected,
required TResult Function(bool isEditing) setIsEditing,
required TResult Function(Option<ViewAction> action) setAction,
}) {
return initial();
return setIsSelected(isSelected);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function(bool isSelected)? setIsSelected,
TResult Function(bool isEditing)? setIsEditing,
TResult Function(Option<ViewAction> action)? setAction,
required TResult orElse(),
}) {
if (initial != null) {
return initial();
if (setIsSelected != null) {
return setIsSelected(isSelected);
}
return orElse();
}
@ -122,26 +176,271 @@ class _$Initial implements Initial {
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(Initial value) initial,
required TResult Function(SetSelected value) setIsSelected,
required TResult Function(SetEditing value) setIsEditing,
required TResult Function(SetAction value) setAction,
}) {
return initial(this);
return setIsSelected(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(Initial value)? initial,
TResult Function(SetSelected value)? setIsSelected,
TResult Function(SetEditing value)? setIsEditing,
TResult Function(SetAction value)? setAction,
required TResult orElse(),
}) {
if (initial != null) {
return initial(this);
if (setIsSelected != null) {
return setIsSelected(this);
}
return orElse();
}
}
abstract class Initial implements ViewEvent {
const factory Initial() = _$Initial;
abstract class SetSelected implements ViewEvent {
const factory SetSelected(bool isSelected) = _$SetSelected;
bool get isSelected => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$SetSelectedCopyWith<SetSelected> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $SetEditingCopyWith<$Res> {
factory $SetEditingCopyWith(
SetEditing value, $Res Function(SetEditing) then) =
_$SetEditingCopyWithImpl<$Res>;
$Res call({bool isEditing});
}
/// @nodoc
class _$SetEditingCopyWithImpl<$Res> extends _$ViewEventCopyWithImpl<$Res>
implements $SetEditingCopyWith<$Res> {
_$SetEditingCopyWithImpl(SetEditing _value, $Res Function(SetEditing) _then)
: super(_value, (v) => _then(v as SetEditing));
@override
SetEditing get _value => super._value as SetEditing;
@override
$Res call({
Object? isEditing = freezed,
}) {
return _then(SetEditing(
isEditing == freezed
? _value.isEditing
: isEditing // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
/// @nodoc
class _$SetEditing implements SetEditing {
const _$SetEditing(this.isEditing);
@override
final bool isEditing;
@override
String toString() {
return 'ViewEvent.setIsEditing(isEditing: $isEditing)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is SetEditing &&
(identical(other.isEditing, isEditing) ||
const DeepCollectionEquality()
.equals(other.isEditing, isEditing)));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(isEditing);
@JsonKey(ignore: true)
@override
$SetEditingCopyWith<SetEditing> get copyWith =>
_$SetEditingCopyWithImpl<SetEditing>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(bool isSelected) setIsSelected,
required TResult Function(bool isEditing) setIsEditing,
required TResult Function(Option<ViewAction> action) setAction,
}) {
return setIsEditing(isEditing);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(bool isSelected)? setIsSelected,
TResult Function(bool isEditing)? setIsEditing,
TResult Function(Option<ViewAction> action)? setAction,
required TResult orElse(),
}) {
if (setIsEditing != null) {
return setIsEditing(isEditing);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(SetSelected value) setIsSelected,
required TResult Function(SetEditing value) setIsEditing,
required TResult Function(SetAction value) setAction,
}) {
return setIsEditing(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(SetSelected value)? setIsSelected,
TResult Function(SetEditing value)? setIsEditing,
TResult Function(SetAction value)? setAction,
required TResult orElse(),
}) {
if (setIsEditing != null) {
return setIsEditing(this);
}
return orElse();
}
}
abstract class SetEditing implements ViewEvent {
const factory SetEditing(bool isEditing) = _$SetEditing;
bool get isEditing => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$SetEditingCopyWith<SetEditing> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $SetActionCopyWith<$Res> {
factory $SetActionCopyWith(SetAction value, $Res Function(SetAction) then) =
_$SetActionCopyWithImpl<$Res>;
$Res call({Option<ViewAction> action});
}
/// @nodoc
class _$SetActionCopyWithImpl<$Res> extends _$ViewEventCopyWithImpl<$Res>
implements $SetActionCopyWith<$Res> {
_$SetActionCopyWithImpl(SetAction _value, $Res Function(SetAction) _then)
: super(_value, (v) => _then(v as SetAction));
@override
SetAction get _value => super._value as SetAction;
@override
$Res call({
Object? action = freezed,
}) {
return _then(SetAction(
action == freezed
? _value.action
: action // ignore: cast_nullable_to_non_nullable
as Option<ViewAction>,
));
}
}
/// @nodoc
class _$SetAction implements SetAction {
const _$SetAction(this.action);
@override
final Option<ViewAction> action;
@override
String toString() {
return 'ViewEvent.setAction(action: $action)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is SetAction &&
(identical(other.action, action) ||
const DeepCollectionEquality().equals(other.action, action)));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(action);
@JsonKey(ignore: true)
@override
$SetActionCopyWith<SetAction> get copyWith =>
_$SetActionCopyWithImpl<SetAction>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(bool isSelected) setIsSelected,
required TResult Function(bool isEditing) setIsEditing,
required TResult Function(Option<ViewAction> action) setAction,
}) {
return setAction(action);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(bool isSelected)? setIsSelected,
TResult Function(bool isEditing)? setIsEditing,
TResult Function(Option<ViewAction> action)? setAction,
required TResult orElse(),
}) {
if (setAction != null) {
return setAction(action);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(SetSelected value) setIsSelected,
required TResult Function(SetEditing value) setIsEditing,
required TResult Function(SetAction value) setAction,
}) {
return setAction(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(SetSelected value)? setIsSelected,
TResult Function(SetEditing value)? setIsEditing,
TResult Function(SetAction value)? setAction,
required TResult orElse(),
}) {
if (setAction != null) {
return setAction(this);
}
return orElse();
}
}
abstract class SetAction implements ViewEvent {
const factory SetAction(Option<ViewAction> action) = _$SetAction;
Option<ViewAction> get action => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$SetActionCopyWith<SetAction> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
@ -149,12 +448,16 @@ class _$ViewStateTearOff {
const _$ViewStateTearOff();
_ViewState call(
{required bool isLoading,
required Option<View> view,
{required View view,
required bool isSelected,
required bool isEditing,
required Option<ViewAction> action,
required Either<Unit, WorkspaceError> successOrFailure}) {
return _ViewState(
isLoading: isLoading,
view: view,
isSelected: isSelected,
isEditing: isEditing,
action: action,
successOrFailure: successOrFailure,
);
}
@ -165,8 +468,10 @@ const $ViewState = _$ViewStateTearOff();
/// @nodoc
mixin _$ViewState {
bool get isLoading => throw _privateConstructorUsedError;
Option<View> get view => throw _privateConstructorUsedError;
View get view => throw _privateConstructorUsedError;
bool get isSelected => throw _privateConstructorUsedError;
bool get isEditing => throw _privateConstructorUsedError;
Option<ViewAction> get action => throw _privateConstructorUsedError;
Either<Unit, WorkspaceError> get successOrFailure =>
throw _privateConstructorUsedError;
@ -180,8 +485,10 @@ abstract class $ViewStateCopyWith<$Res> {
factory $ViewStateCopyWith(ViewState value, $Res Function(ViewState) then) =
_$ViewStateCopyWithImpl<$Res>;
$Res call(
{bool isLoading,
Option<View> view,
{View view,
bool isSelected,
bool isEditing,
Option<ViewAction> action,
Either<Unit, WorkspaceError> successOrFailure});
}
@ -195,19 +502,29 @@ class _$ViewStateCopyWithImpl<$Res> implements $ViewStateCopyWith<$Res> {
@override
$Res call({
Object? isLoading = freezed,
Object? view = freezed,
Object? isSelected = freezed,
Object? isEditing = freezed,
Object? action = freezed,
Object? successOrFailure = freezed,
}) {
return _then(_value.copyWith(
isLoading: isLoading == freezed
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
view: view == freezed
? _value.view
: view // ignore: cast_nullable_to_non_nullable
as Option<View>,
as View,
isSelected: isSelected == freezed
? _value.isSelected
: isSelected // ignore: cast_nullable_to_non_nullable
as bool,
isEditing: isEditing == freezed
? _value.isEditing
: isEditing // ignore: cast_nullable_to_non_nullable
as bool,
action: action == freezed
? _value.action
: action // ignore: cast_nullable_to_non_nullable
as Option<ViewAction>,
successOrFailure: successOrFailure == freezed
? _value.successOrFailure
: successOrFailure // ignore: cast_nullable_to_non_nullable
@ -223,8 +540,10 @@ abstract class _$ViewStateCopyWith<$Res> implements $ViewStateCopyWith<$Res> {
__$ViewStateCopyWithImpl<$Res>;
@override
$Res call(
{bool isLoading,
Option<View> view,
{View view,
bool isSelected,
bool isEditing,
Option<ViewAction> action,
Either<Unit, WorkspaceError> successOrFailure});
}
@ -239,19 +558,29 @@ class __$ViewStateCopyWithImpl<$Res> extends _$ViewStateCopyWithImpl<$Res>
@override
$Res call({
Object? isLoading = freezed,
Object? view = freezed,
Object? isSelected = freezed,
Object? isEditing = freezed,
Object? action = freezed,
Object? successOrFailure = freezed,
}) {
return _then(_ViewState(
isLoading: isLoading == freezed
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
view: view == freezed
? _value.view
: view // ignore: cast_nullable_to_non_nullable
as Option<View>,
as View,
isSelected: isSelected == freezed
? _value.isSelected
: isSelected // ignore: cast_nullable_to_non_nullable
as bool,
isEditing: isEditing == freezed
? _value.isEditing
: isEditing // ignore: cast_nullable_to_non_nullable
as bool,
action: action == freezed
? _value.action
: action // ignore: cast_nullable_to_non_nullable
as Option<ViewAction>,
successOrFailure: successOrFailure == freezed
? _value.successOrFailure
: successOrFailure // ignore: cast_nullable_to_non_nullable
@ -264,31 +593,42 @@ class __$ViewStateCopyWithImpl<$Res> extends _$ViewStateCopyWithImpl<$Res>
class _$_ViewState implements _ViewState {
const _$_ViewState(
{required this.isLoading,
required this.view,
{required this.view,
required this.isSelected,
required this.isEditing,
required this.action,
required this.successOrFailure});
@override
final bool isLoading;
final View view;
@override
final Option<View> view;
final bool isSelected;
@override
final bool isEditing;
@override
final Option<ViewAction> action;
@override
final Either<Unit, WorkspaceError> successOrFailure;
@override
String toString() {
return 'ViewState(isLoading: $isLoading, view: $view, successOrFailure: $successOrFailure)';
return 'ViewState(view: $view, isSelected: $isSelected, isEditing: $isEditing, action: $action, successOrFailure: $successOrFailure)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _ViewState &&
(identical(other.isLoading, isLoading) ||
const DeepCollectionEquality()
.equals(other.isLoading, isLoading)) &&
(identical(other.view, view) ||
const DeepCollectionEquality().equals(other.view, view)) &&
(identical(other.isSelected, isSelected) ||
const DeepCollectionEquality()
.equals(other.isSelected, isSelected)) &&
(identical(other.isEditing, isEditing) ||
const DeepCollectionEquality()
.equals(other.isEditing, isEditing)) &&
(identical(other.action, action) ||
const DeepCollectionEquality().equals(other.action, action)) &&
(identical(other.successOrFailure, successOrFailure) ||
const DeepCollectionEquality()
.equals(other.successOrFailure, successOrFailure)));
@ -297,8 +637,10 @@ class _$_ViewState implements _ViewState {
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(isLoading) ^
const DeepCollectionEquality().hash(view) ^
const DeepCollectionEquality().hash(isSelected) ^
const DeepCollectionEquality().hash(isEditing) ^
const DeepCollectionEquality().hash(action) ^
const DeepCollectionEquality().hash(successOrFailure);
@JsonKey(ignore: true)
@ -309,14 +651,20 @@ class _$_ViewState implements _ViewState {
abstract class _ViewState implements ViewState {
const factory _ViewState(
{required bool isLoading,
required Option<View> view,
{required View view,
required bool isSelected,
required bool isEditing,
required Option<ViewAction> action,
required Either<Unit, WorkspaceError> successOrFailure}) = _$_ViewState;
@override
bool get isLoading => throw _privateConstructorUsedError;
View get view => throw _privateConstructorUsedError;
@override
Option<View> get view => throw _privateConstructorUsedError;
bool get isSelected => throw _privateConstructorUsedError;
@override
bool get isEditing => throw _privateConstructorUsedError;
@override
Option<ViewAction> get action => throw _privateConstructorUsedError;
@override
Either<Unit, WorkspaceError> get successOrFailure =>
throw _privateConstructorUsedError;

View File

@ -0,0 +1,43 @@
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:app_flowy/workspace/domain/i_view.dart';
part 'view_edit_bloc.freezed.dart';
class ViewEditBloc extends Bloc<ViewEditEvent, ViewEditState> {
final IView iViewImpl;
ViewEditBloc({
required this.iViewImpl,
}) : super(ViewEditState.initial());
@override
Stream<ViewEditState> mapEventToState(ViewEditEvent event) async* {
yield* event.map(initial: (_) async* {
yield state;
});
}
}
@freezed
class ViewEditEvent with _$ViewEditEvent {
const factory ViewEditEvent.initial() = Initial;
}
@freezed
class ViewEditState with _$ViewEditState {
const factory ViewEditState({
required bool isLoading,
required Option<View> view,
required Either<Unit, WorkspaceError> successOrFailure,
}) = _ViewState;
factory ViewEditState.initial() => ViewEditState(
isLoading: false,
view: none(),
successOrFailure: left(unit),
);
}

View File

@ -0,0 +1,332 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
part of 'view_edit_bloc.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
/// @nodoc
class _$ViewEditEventTearOff {
const _$ViewEditEventTearOff();
Initial initial() {
return const Initial();
}
}
/// @nodoc
const $ViewEditEvent = _$ViewEditEventTearOff();
/// @nodoc
mixin _$ViewEditEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(Initial value) initial,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(Initial value)? initial,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ViewEditEventCopyWith<$Res> {
factory $ViewEditEventCopyWith(
ViewEditEvent value, $Res Function(ViewEditEvent) then) =
_$ViewEditEventCopyWithImpl<$Res>;
}
/// @nodoc
class _$ViewEditEventCopyWithImpl<$Res>
implements $ViewEditEventCopyWith<$Res> {
_$ViewEditEventCopyWithImpl(this._value, this._then);
final ViewEditEvent _value;
// ignore: unused_field
final $Res Function(ViewEditEvent) _then;
}
/// @nodoc
abstract class $InitialCopyWith<$Res> {
factory $InitialCopyWith(Initial value, $Res Function(Initial) then) =
_$InitialCopyWithImpl<$Res>;
}
/// @nodoc
class _$InitialCopyWithImpl<$Res> extends _$ViewEditEventCopyWithImpl<$Res>
implements $InitialCopyWith<$Res> {
_$InitialCopyWithImpl(Initial _value, $Res Function(Initial) _then)
: super(_value, (v) => _then(v as Initial));
@override
Initial get _value => super._value as Initial;
}
/// @nodoc
class _$Initial implements Initial {
const _$Initial();
@override
String toString() {
return 'ViewEditEvent.initial()';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) || (other is Initial);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
}) {
return initial();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
required TResult orElse(),
}) {
if (initial != null) {
return initial();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(Initial value) initial,
}) {
return initial(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(Initial value)? initial,
required TResult orElse(),
}) {
if (initial != null) {
return initial(this);
}
return orElse();
}
}
abstract class Initial implements ViewEditEvent {
const factory Initial() = _$Initial;
}
/// @nodoc
class _$ViewEditStateTearOff {
const _$ViewEditStateTearOff();
_ViewState call(
{required bool isLoading,
required Option<View> view,
required Either<Unit, WorkspaceError> successOrFailure}) {
return _ViewState(
isLoading: isLoading,
view: view,
successOrFailure: successOrFailure,
);
}
}
/// @nodoc
const $ViewEditState = _$ViewEditStateTearOff();
/// @nodoc
mixin _$ViewEditState {
bool get isLoading => throw _privateConstructorUsedError;
Option<View> get view => throw _privateConstructorUsedError;
Either<Unit, WorkspaceError> get successOrFailure =>
throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$ViewEditStateCopyWith<ViewEditState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ViewEditStateCopyWith<$Res> {
factory $ViewEditStateCopyWith(
ViewEditState value, $Res Function(ViewEditState) then) =
_$ViewEditStateCopyWithImpl<$Res>;
$Res call(
{bool isLoading,
Option<View> view,
Either<Unit, WorkspaceError> successOrFailure});
}
/// @nodoc
class _$ViewEditStateCopyWithImpl<$Res>
implements $ViewEditStateCopyWith<$Res> {
_$ViewEditStateCopyWithImpl(this._value, this._then);
final ViewEditState _value;
// ignore: unused_field
final $Res Function(ViewEditState) _then;
@override
$Res call({
Object? isLoading = freezed,
Object? view = freezed,
Object? successOrFailure = freezed,
}) {
return _then(_value.copyWith(
isLoading: isLoading == freezed
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
view: view == freezed
? _value.view
: view // ignore: cast_nullable_to_non_nullable
as Option<View>,
successOrFailure: successOrFailure == freezed
? _value.successOrFailure
: successOrFailure // ignore: cast_nullable_to_non_nullable
as Either<Unit, WorkspaceError>,
));
}
}
/// @nodoc
abstract class _$ViewStateCopyWith<$Res>
implements $ViewEditStateCopyWith<$Res> {
factory _$ViewStateCopyWith(
_ViewState value, $Res Function(_ViewState) then) =
__$ViewStateCopyWithImpl<$Res>;
@override
$Res call(
{bool isLoading,
Option<View> view,
Either<Unit, WorkspaceError> successOrFailure});
}
/// @nodoc
class __$ViewStateCopyWithImpl<$Res> extends _$ViewEditStateCopyWithImpl<$Res>
implements _$ViewStateCopyWith<$Res> {
__$ViewStateCopyWithImpl(_ViewState _value, $Res Function(_ViewState) _then)
: super(_value, (v) => _then(v as _ViewState));
@override
_ViewState get _value => super._value as _ViewState;
@override
$Res call({
Object? isLoading = freezed,
Object? view = freezed,
Object? successOrFailure = freezed,
}) {
return _then(_ViewState(
isLoading: isLoading == freezed
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
view: view == freezed
? _value.view
: view // ignore: cast_nullable_to_non_nullable
as Option<View>,
successOrFailure: successOrFailure == freezed
? _value.successOrFailure
: successOrFailure // ignore: cast_nullable_to_non_nullable
as Either<Unit, WorkspaceError>,
));
}
}
/// @nodoc
class _$_ViewState implements _ViewState {
const _$_ViewState(
{required this.isLoading,
required this.view,
required this.successOrFailure});
@override
final bool isLoading;
@override
final Option<View> view;
@override
final Either<Unit, WorkspaceError> successOrFailure;
@override
String toString() {
return 'ViewEditState(isLoading: $isLoading, view: $view, successOrFailure: $successOrFailure)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _ViewState &&
(identical(other.isLoading, isLoading) ||
const DeepCollectionEquality()
.equals(other.isLoading, isLoading)) &&
(identical(other.view, view) ||
const DeepCollectionEquality().equals(other.view, view)) &&
(identical(other.successOrFailure, successOrFailure) ||
const DeepCollectionEquality()
.equals(other.successOrFailure, successOrFailure)));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(isLoading) ^
const DeepCollectionEquality().hash(view) ^
const DeepCollectionEquality().hash(successOrFailure);
@JsonKey(ignore: true)
@override
_$ViewStateCopyWith<_ViewState> get copyWith =>
__$ViewStateCopyWithImpl<_ViewState>(this, _$identity);
}
abstract class _ViewState implements ViewEditState {
const factory _ViewState(
{required bool isLoading,
required Option<View> view,
required Either<Unit, WorkspaceError> successOrFailure}) = _$_ViewState;
@override
bool get isLoading => throw _privateConstructorUsedError;
@override
Option<View> get view => throw _privateConstructorUsedError;
@override
Either<Unit, WorkspaceError> get successOrFailure =>
throw _privateConstructorUsedError;
@override
@JsonKey(ignore: true)
_$ViewStateCopyWith<_ViewState> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -1,44 +0,0 @@
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:dartz/dartz.dart';
part 'view_list_bloc.freezed.dart';
class ViewListBloc extends Bloc<ViewListEvent, ViewListState> {
final List<View> views;
ViewListBloc({required this.views}) : super(ViewListState.initial(views));
@override
Stream<ViewListState> mapEventToState(ViewListEvent event) async* {
yield* event.map(
initial: (s) async* {
yield ViewListState.initial(s.views);
},
openView: (s) async* {
yield state.copyWith(openedView: some(s.view.id));
},
);
}
}
@freezed
class ViewListEvent with _$ViewListEvent {
const factory ViewListEvent.initial(List<View> views) = Initial;
const factory ViewListEvent.openView(View view) = OpenView;
}
@freezed
class ViewListState with _$ViewListState {
const factory ViewListState({
required bool isLoading,
required Option<String> openedView,
required Option<List<View>> views,
}) = _ViewListState;
factory ViewListState.initial(List<View> views) => ViewListState(
isLoading: false,
openedView: none(),
views: some(views),
);
}

View File

@ -1,484 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
part of 'view_list_bloc.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
/// @nodoc
class _$ViewListEventTearOff {
const _$ViewListEventTearOff();
Initial initial(List<View> views) {
return Initial(
views,
);
}
OpenView openView(View view) {
return OpenView(
view,
);
}
}
/// @nodoc
const $ViewListEvent = _$ViewListEventTearOff();
/// @nodoc
mixin _$ViewListEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(List<View> views) initial,
required TResult Function(View view) openView,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(List<View> views)? initial,
TResult Function(View view)? openView,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(Initial value) initial,
required TResult Function(OpenView value) openView,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(Initial value)? initial,
TResult Function(OpenView value)? openView,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ViewListEventCopyWith<$Res> {
factory $ViewListEventCopyWith(
ViewListEvent value, $Res Function(ViewListEvent) then) =
_$ViewListEventCopyWithImpl<$Res>;
}
/// @nodoc
class _$ViewListEventCopyWithImpl<$Res>
implements $ViewListEventCopyWith<$Res> {
_$ViewListEventCopyWithImpl(this._value, this._then);
final ViewListEvent _value;
// ignore: unused_field
final $Res Function(ViewListEvent) _then;
}
/// @nodoc
abstract class $InitialCopyWith<$Res> {
factory $InitialCopyWith(Initial value, $Res Function(Initial) then) =
_$InitialCopyWithImpl<$Res>;
$Res call({List<View> views});
}
/// @nodoc
class _$InitialCopyWithImpl<$Res> extends _$ViewListEventCopyWithImpl<$Res>
implements $InitialCopyWith<$Res> {
_$InitialCopyWithImpl(Initial _value, $Res Function(Initial) _then)
: super(_value, (v) => _then(v as Initial));
@override
Initial get _value => super._value as Initial;
@override
$Res call({
Object? views = freezed,
}) {
return _then(Initial(
views == freezed
? _value.views
: views // ignore: cast_nullable_to_non_nullable
as List<View>,
));
}
}
/// @nodoc
class _$Initial implements Initial {
const _$Initial(this.views);
@override
final List<View> views;
@override
String toString() {
return 'ViewListEvent.initial(views: $views)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is Initial &&
(identical(other.views, views) ||
const DeepCollectionEquality().equals(other.views, views)));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(views);
@JsonKey(ignore: true)
@override
$InitialCopyWith<Initial> get copyWith =>
_$InitialCopyWithImpl<Initial>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(List<View> views) initial,
required TResult Function(View view) openView,
}) {
return initial(views);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(List<View> views)? initial,
TResult Function(View view)? openView,
required TResult orElse(),
}) {
if (initial != null) {
return initial(views);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(Initial value) initial,
required TResult Function(OpenView value) openView,
}) {
return initial(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(Initial value)? initial,
TResult Function(OpenView value)? openView,
required TResult orElse(),
}) {
if (initial != null) {
return initial(this);
}
return orElse();
}
}
abstract class Initial implements ViewListEvent {
const factory Initial(List<View> views) = _$Initial;
List<View> get views => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$InitialCopyWith<Initial> get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $OpenViewCopyWith<$Res> {
factory $OpenViewCopyWith(OpenView value, $Res Function(OpenView) then) =
_$OpenViewCopyWithImpl<$Res>;
$Res call({View view});
}
/// @nodoc
class _$OpenViewCopyWithImpl<$Res> extends _$ViewListEventCopyWithImpl<$Res>
implements $OpenViewCopyWith<$Res> {
_$OpenViewCopyWithImpl(OpenView _value, $Res Function(OpenView) _then)
: super(_value, (v) => _then(v as OpenView));
@override
OpenView get _value => super._value as OpenView;
@override
$Res call({
Object? view = freezed,
}) {
return _then(OpenView(
view == freezed
? _value.view
: view // ignore: cast_nullable_to_non_nullable
as View,
));
}
}
/// @nodoc
class _$OpenView implements OpenView {
const _$OpenView(this.view);
@override
final View view;
@override
String toString() {
return 'ViewListEvent.openView(view: $view)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is OpenView &&
(identical(other.view, view) ||
const DeepCollectionEquality().equals(other.view, view)));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(view);
@JsonKey(ignore: true)
@override
$OpenViewCopyWith<OpenView> get copyWith =>
_$OpenViewCopyWithImpl<OpenView>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(List<View> views) initial,
required TResult Function(View view) openView,
}) {
return openView(view);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(List<View> views)? initial,
TResult Function(View view)? openView,
required TResult orElse(),
}) {
if (openView != null) {
return openView(view);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(Initial value) initial,
required TResult Function(OpenView value) openView,
}) {
return openView(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(Initial value)? initial,
TResult Function(OpenView value)? openView,
required TResult orElse(),
}) {
if (openView != null) {
return openView(this);
}
return orElse();
}
}
abstract class OpenView implements ViewListEvent {
const factory OpenView(View view) = _$OpenView;
View get view => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$OpenViewCopyWith<OpenView> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
class _$ViewListStateTearOff {
const _$ViewListStateTearOff();
_ViewListState call(
{required bool isLoading,
required Option<String> openedView,
required Option<List<View>> views}) {
return _ViewListState(
isLoading: isLoading,
openedView: openedView,
views: views,
);
}
}
/// @nodoc
const $ViewListState = _$ViewListStateTearOff();
/// @nodoc
mixin _$ViewListState {
bool get isLoading => throw _privateConstructorUsedError;
Option<String> get openedView => throw _privateConstructorUsedError;
Option<List<View>> get views => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$ViewListStateCopyWith<ViewListState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ViewListStateCopyWith<$Res> {
factory $ViewListStateCopyWith(
ViewListState value, $Res Function(ViewListState) then) =
_$ViewListStateCopyWithImpl<$Res>;
$Res call(
{bool isLoading, Option<String> openedView, Option<List<View>> views});
}
/// @nodoc
class _$ViewListStateCopyWithImpl<$Res>
implements $ViewListStateCopyWith<$Res> {
_$ViewListStateCopyWithImpl(this._value, this._then);
final ViewListState _value;
// ignore: unused_field
final $Res Function(ViewListState) _then;
@override
$Res call({
Object? isLoading = freezed,
Object? openedView = freezed,
Object? views = freezed,
}) {
return _then(_value.copyWith(
isLoading: isLoading == freezed
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
openedView: openedView == freezed
? _value.openedView
: openedView // ignore: cast_nullable_to_non_nullable
as Option<String>,
views: views == freezed
? _value.views
: views // ignore: cast_nullable_to_non_nullable
as Option<List<View>>,
));
}
}
/// @nodoc
abstract class _$ViewListStateCopyWith<$Res>
implements $ViewListStateCopyWith<$Res> {
factory _$ViewListStateCopyWith(
_ViewListState value, $Res Function(_ViewListState) then) =
__$ViewListStateCopyWithImpl<$Res>;
@override
$Res call(
{bool isLoading, Option<String> openedView, Option<List<View>> views});
}
/// @nodoc
class __$ViewListStateCopyWithImpl<$Res>
extends _$ViewListStateCopyWithImpl<$Res>
implements _$ViewListStateCopyWith<$Res> {
__$ViewListStateCopyWithImpl(
_ViewListState _value, $Res Function(_ViewListState) _then)
: super(_value, (v) => _then(v as _ViewListState));
@override
_ViewListState get _value => super._value as _ViewListState;
@override
$Res call({
Object? isLoading = freezed,
Object? openedView = freezed,
Object? views = freezed,
}) {
return _then(_ViewListState(
isLoading: isLoading == freezed
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
openedView: openedView == freezed
? _value.openedView
: openedView // ignore: cast_nullable_to_non_nullable
as Option<String>,
views: views == freezed
? _value.views
: views // ignore: cast_nullable_to_non_nullable
as Option<List<View>>,
));
}
}
/// @nodoc
class _$_ViewListState implements _ViewListState {
const _$_ViewListState(
{required this.isLoading, required this.openedView, required this.views});
@override
final bool isLoading;
@override
final Option<String> openedView;
@override
final Option<List<View>> views;
@override
String toString() {
return 'ViewListState(isLoading: $isLoading, openedView: $openedView, views: $views)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _ViewListState &&
(identical(other.isLoading, isLoading) ||
const DeepCollectionEquality()
.equals(other.isLoading, isLoading)) &&
(identical(other.openedView, openedView) ||
const DeepCollectionEquality()
.equals(other.openedView, openedView)) &&
(identical(other.views, views) ||
const DeepCollectionEquality().equals(other.views, views)));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(isLoading) ^
const DeepCollectionEquality().hash(openedView) ^
const DeepCollectionEquality().hash(views);
@JsonKey(ignore: true)
@override
_$ViewListStateCopyWith<_ViewListState> get copyWith =>
__$ViewListStateCopyWithImpl<_ViewListState>(this, _$identity);
}
abstract class _ViewListState implements ViewListState {
const factory _ViewListState(
{required bool isLoading,
required Option<String> openedView,
required Option<List<View>> views}) = _$_ViewListState;
@override
bool get isLoading => throw _privateConstructorUsedError;
@override
Option<String> get openedView => throw _privateConstructorUsedError;
@override
Option<List<View>> get views => throw _privateConstructorUsedError;
@override
@JsonKey(ignore: true)
_$ViewListStateCopyWith<_ViewListState> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -5,11 +5,15 @@ import 'package:dartz/dartz.dart';
typedef ViewUpdatedCallback = void Function(Either<View, WorkspaceError>);
abstract class IView {
Future<Either<View, WorkspaceError>> readView();
View get view;
Future<Either<Unit, WorkspaceError>> pushIntoTrash();
Future<Either<Unit, WorkspaceError>> rename(String newName);
}
abstract class IViewWatch {
void startWatching({ViewUpdatedCallback? updatedCallback});
abstract class IViewListener {
void start({ViewUpdatedCallback? updatedCallback});
Future<void> stopWatching();
Future<void> stop();
}

View File

@ -1,25 +1,20 @@
import 'package:flowy_sdk/protobuf/flowy-workspace/protobuf.dart';
import 'package:dartz/dartz.dart';
typedef WorkspaceCreateAppCallback = void Function(
Either<List<App>, WorkspaceError> appsOrFail);
typedef WorkspaceCreateAppCallback = void Function(Either<List<App>, WorkspaceError> appsOrFail);
typedef WorkspaceUpdatedCallback = void Function(String name, String desc);
typedef WorkspaceDeleteAppCallback = void Function(
Either<List<App>, WorkspaceError> appsOrFail);
typedef WorkspaceDeleteAppCallback = void Function(Either<List<App>, WorkspaceError> appsOrFail);
abstract class IWorkspace {
Future<Either<App, WorkspaceError>> createApp(
{required String name, String? desc});
Future<Either<App, WorkspaceError>> createApp({required String name, String? desc});
Future<Either<List<App>, WorkspaceError>> getApps();
}
abstract class IWorkspaceWatch {
void startWatching(
{WorkspaceCreateAppCallback? addAppCallback,
WorkspaceUpdatedCallback? updatedCallback});
abstract class IWorkspaceListener {
void start({WorkspaceCreateAppCallback? addAppCallback, WorkspaceUpdatedCallback? updatedCallback});
Future<void> stopWatching();
Future<void> stop();
}

View File

@ -3,17 +3,19 @@ import 'package:flutter/material.dart';
import 'package:flowy_infra/image.dart';
AssetImage assetImageForViewType(ViewType type) {
final imageName = imageNameForViewType(type);
final imageName = _imageNameForViewType(type);
return AssetImage('assets/images/$imageName');
}
Widget svgForViewType(ViewType type) {
final imageName = imageNameForViewType(type);
final Widget widget = svg(imageName);
return widget;
extension SvgViewType on View {
Widget thumbnail() {
final imageName = _imageNameForViewType(viewType);
final Widget widget = svg(imageName);
return widget;
}
}
String imageNameForViewType(ViewType type) {
String _imageNameForViewType(ViewType type) {
switch (type) {
case ViewType.Doc:
return "file_icon";

View File

@ -34,14 +34,16 @@ abstract class HomeStackContext extends Equatable with NavigationItem {
Widget render();
}
HomeStackContext stackCtxFromView(View view) {
switch (view.viewType) {
case ViewType.Blank:
return BlankStackContext();
case ViewType.Doc:
return DocStackContext(view: view);
default:
return BlankStackContext();
extension ViewStackContext on View {
HomeStackContext intoStackContext() {
switch (viewType) {
case ViewType.Blank:
return BlankStackContext();
case ViewType.Doc:
return DocStackContext(view: this);
default:
return BlankStackContext();
}
}
}

View File

@ -6,7 +6,7 @@ import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart';
import 'package:app_flowy/workspace/application/menu/menu_listen.dart';
import 'package:app_flowy/workspace/application/view/view_bloc.dart';
import 'package:app_flowy/workspace/application/view/view_list_bloc.dart';
import 'package:app_flowy/workspace/application/view/view_edit_bloc.dart';
import 'package:app_flowy/workspace/application/workspace/welcome_bloc.dart';
import 'package:app_flowy/workspace/domain/i_doc.dart';
import 'package:app_flowy/workspace/domain/i_view.dart';
@ -33,31 +33,31 @@ class HomeDepsResolver {
//App
getIt.registerFactoryParam<IApp, String, void>((appId, _) => IAppImpl(repo: AppRepository(appId: appId)));
getIt.registerFactoryParam<IAppListenr, String, void>(
(appId, _) => IAppWatchImpl(repo: AppWatchRepository(appId: appId)));
(appId, _) => IAppListenerhImpl(repo: AppListenerRepository(appId: appId)));
//workspace
getIt.registerFactoryParam<IWorkspace, UserProfile, String>(
(user, workspaceId) => IWorkspaceImpl(repo: WorkspaceRepo(user: user, workspaceId: workspaceId)));
getIt.registerFactoryParam<IWorkspaceWatch, UserProfile, String>(
(user, workspaceId) => IWorkspaceWatchImpl(repo: WorkspaceWatchRepo(user: user, workspaceId: workspaceId)));
getIt.registerFactoryParam<IWorkspaceListener, UserProfile, String>((user, workspaceId) =>
IWorkspaceListenerImpl(repo: WorkspaceListenerRepo(user: user, workspaceId: workspaceId)));
// View
getIt.registerFactoryParam<IView, View, void>((view, _) => IViewImpl(repo: ViewRepository(view: view)));
getIt.registerFactoryParam<IViewWatch, View, void>(
(view, _) => IViewWatchImpl(repo: ViewWatchRepository(view: view)));
getIt.registerFactoryParam<IViewListener, View, void>(
(view, _) => IViewListenerImpl(repo: ViewListenerRepository(view: view)));
// Doc
getIt.registerFactoryParam<IDoc, String, void>((docId, _) => IDocImpl(repo: DocRepository(docId: docId)));
// User
getIt.registerFactoryParam<IUser, UserProfile, void>((user, _) => IUserImpl(repo: UserRepo(user: user)));
getIt.registerFactoryParam<IUserListener, UserProfile, void>((user, _) => IUserWatchImpl(user: user));
getIt.registerFactoryParam<IUserListener, UserProfile, void>((user, _) => IUserListenerImpl(user: user));
//Menu Bloc
getIt.registerFactoryParam<MenuBloc, UserProfile, String>(
(user, workspaceId) => MenuBloc(getIt<IWorkspace>(param1: user, param2: workspaceId)));
getIt.registerFactoryParam<MenuListenBloc, UserProfile, String>(
(user, workspaceId) => MenuListenBloc(getIt<IWorkspaceWatch>(param1: user, param2: workspaceId)));
(user, workspaceId) => MenuListenBloc(getIt<IWorkspaceListener>(param1: user, param2: workspaceId)));
getIt.registerFactoryParam<MenuUserBloc, UserProfile, void>(
(user, _) => MenuUserBloc(getIt<IUser>(param1: user), getIt<IUserListener>(param1: user)));
@ -67,24 +67,17 @@ class HomeDepsResolver {
getIt.registerFactoryParam<AppListenBloc, String, void>(
(appId, _) => AppListenBloc(getIt<IAppListenr>(param1: appId)));
getIt
.registerFactoryParam<ViewBloc, String, void>((viewId, _) => ViewBloc(iViewImpl: getIt<IView>(param1: viewId)));
getIt.registerFactoryParam<ViewBloc, View, void>((view, _) => ViewBloc(iViewImpl: getIt<IView>(param1: view)));
getIt.registerFactoryParam<DocBloc, String, void>((docId, _) => DocBloc(iDocImpl: getIt<IDoc>(param1: docId)));
getIt.registerFactoryParam<DocEditBloc, String, void>((docId, _) => DocEditBloc(getIt<IDoc>(param1: docId)));
// editor
getIt.registerFactoryParam<ViewListBloc, List<View>, void>((views, _) => ViewListBloc(views: views));
getIt.registerFactoryParam<WelcomeBloc, UserProfile, void>(
(user, _) => WelcomeBloc(
repo: UserRepo(user: user),
watch: getIt<IUserListener>(param1: user),
),
);
// getIt.registerFactoryParam<ViewBloc, String, void>(
// (viewId, _) => ViewBloc(iViewImpl: getIt<IView>(param1: viewId)));
}
}

View File

@ -28,15 +28,15 @@ class IAppImpl extends IApp {
}
}
class IAppWatchImpl extends IAppListenr {
AppWatchRepository repo;
IAppWatchImpl({
class IAppListenerhImpl extends IAppListenr {
AppListenerRepository repo;
IAppListenerhImpl({
required this.repo,
});
@override
void start({AppCreateViewCallback? addViewCallback, AppUpdatedCallback? updatedCallback}) {
repo.startWatching(createView: addViewCallback, update: updatedCallback);
repo.startListen(createView: addViewCallback, update: updatedCallback);
}
@override

View File

@ -49,7 +49,7 @@ class IUserImpl extends IUser {
}
}
class IUserWatchImpl extends IUserListener {
class IUserListenerImpl extends IUserListener {
StreamSubscription<ObservableSubject>? _subscription;
WorkspacesUpdatedCallback? _workspacesUpdated;
AuthChangedCallback? _authChanged;
@ -58,7 +58,7 @@ class IUserWatchImpl extends IUserListener {
late WorkspaceObservableParser _workspaceParser;
late UserObservableParser _userParser;
late UserProfile _user;
IUserWatchImpl({
IUserListenerImpl({
required UserProfile user,
}) {
_user = user;

View File

@ -1,8 +1,8 @@
import 'package:app_flowy/workspace/domain/i_view.dart';
import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
class IViewImpl extends IView {
ViewRepository repo;
@ -10,24 +10,32 @@ class IViewImpl extends IView {
IViewImpl({required this.repo});
@override
Future<Either<View, WorkspaceError>> readView() {
return repo.readView();
View get view => repo.view;
@override
Future<Either<Unit, WorkspaceError>> pushIntoTrash() {
return repo.updateView(isTrash: true);
}
@override
Future<Either<Unit, WorkspaceError>> rename(String newName) {
return repo.updateView(name: newName);
}
}
class IViewWatchImpl extends IViewWatch {
final ViewWatchRepository repo;
IViewWatchImpl({
class IViewListenerImpl extends IViewListener {
final ViewListenerRepository repo;
IViewListenerImpl({
required this.repo,
});
@override
void startWatching({ViewUpdatedCallback? updatedCallback}) {
void start({ViewUpdatedCallback? updatedCallback}) {
repo.startWatching(update: updatedCallback);
}
@override
Future<void> stopWatching() async {
Future<void> stop() async {
await repo.close();
}
}

View File

@ -13,8 +13,7 @@ class IWorkspaceImpl extends IWorkspace {
});
@override
Future<Either<App, WorkspaceError>> createApp(
{required String name, String? desc}) {
Future<Either<App, WorkspaceError>> createApp({required String name, String? desc}) {
return repo.createApp(name, desc ?? "");
}
@ -29,21 +28,19 @@ class IWorkspaceImpl extends IWorkspace {
}
}
class IWorkspaceWatchImpl extends IWorkspaceWatch {
WorkspaceWatchRepo repo;
IWorkspaceWatchImpl({
class IWorkspaceListenerImpl extends IWorkspaceListener {
WorkspaceListenerRepo repo;
IWorkspaceListenerImpl({
required this.repo,
});
@override
void startWatching(
{WorkspaceCreateAppCallback? addAppCallback,
WorkspaceUpdatedCallback? updatedCallback}) {
repo.startWatching(createApp: addAppCallback, update: updatedCallback);
void start({WorkspaceCreateAppCallback? addAppCallback, WorkspaceUpdatedCallback? updatedCallback}) {
repo.startListen(createApp: addAppCallback, update: updatedCallback);
}
@override
Future<void> stopWatching() async {
Future<void> stop() async {
await repo.close();
}
}

View File

@ -28,8 +28,7 @@ class AppRepository {
return WorkspaceEventReadApp(request).send();
}
Future<Either<View, WorkspaceError>> createView(
String name, String desc, ViewType viewType) {
Future<Either<View, WorkspaceError>> createView(String name, String desc, ViewType viewType) {
final request = CreateViewRequest.create()
..belongToId = appId
..name = name
@ -53,7 +52,7 @@ class AppRepository {
}
}
class AppWatchRepository {
class AppListenerRepository {
StreamSubscription<ObservableSubject>? _subscription;
AppCreateViewCallback? _createView;
AppDeleteViewCallback? _deleteView;
@ -61,25 +60,19 @@ class AppWatchRepository {
late WorkspaceObservableParser _extractor;
String appId;
AppWatchRepository({
AppListenerRepository({
required this.appId,
});
void startWatching(
{AppCreateViewCallback? createView,
AppDeleteViewCallback? deleteView,
AppUpdatedCallback? update}) {
void startListen({AppCreateViewCallback? createView, AppDeleteViewCallback? deleteView, AppUpdatedCallback? update}) {
_createView = createView;
_deleteView = deleteView;
_update = update;
_extractor =
WorkspaceObservableParser(id: appId, callback: _bservableCallback);
_subscription =
RustStreamReceiver.listen((observable) => _extractor.parse(observable));
_extractor = WorkspaceObservableParser(id: appId, callback: _bservableCallback);
_subscription = RustStreamReceiver.listen((observable) => _extractor.parse(observable));
}
void _bservableCallback(
WorkspaceObservable ty, Either<Uint8List, WorkspaceError> result) {
void _bservableCallback(WorkspaceObservable ty, Either<Uint8List, WorkspaceError> result) {
switch (ty) {
case WorkspaceObservable.AppCreateView:
if (_createView != null) {

View File

@ -6,7 +6,9 @@ import 'package:flowy_sdk/protobuf/flowy-dart-notify/subject.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/observable.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_delete.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_query.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_update.pb.dart';
import 'package:flowy_sdk/rust_stream.dart';
import 'package:app_flowy/workspace/domain/i_view.dart';
@ -23,15 +25,38 @@ class ViewRepository {
final request = QueryViewRequest.create()..viewId = view.id;
return WorkspaceEventReadView(request).send();
}
Future<Either<Unit, WorkspaceError>> updateView({String? name, String? desc, bool? isTrash}) {
final request = UpdateViewRequest.create()..viewId = view.id;
if (name != null) {
request.name = name;
}
if (desc != null) {
request.desc = desc;
}
if (isTrash != null) {
request.isTrash = isTrash;
}
return WorkspaceEventUpdateView(request).send();
}
Future<Either<Unit, WorkspaceError>> delete() {
final request = DeleteViewRequest.create()..viewId = view.id;
return WorkspaceEventDeleteView(request).send();
}
}
class ViewWatchRepository {
class ViewListenerRepository {
StreamSubscription<ObservableSubject>? _subscription;
ViewUpdatedCallback? _update;
late WorkspaceObservableParser _extractor;
View view;
ViewWatchRepository({
ViewListenerRepository({
required this.view,
});
@ -46,12 +71,10 @@ class ViewWatchRepository {
},
);
_subscription =
RustStreamReceiver.listen((observable) => _extractor.parse(observable));
_subscription = RustStreamReceiver.listen((observable) => _extractor.parse(observable));
}
void _handleObservableType(
WorkspaceObservable ty, Either<Uint8List, WorkspaceError> result) {
void _handleObservableType(WorkspaceObservable ty, Either<Uint8List, WorkspaceError> result) {
switch (ty) {
case WorkspaceObservable.ViewUpdated:
if (_update != null) {

View File

@ -62,7 +62,7 @@ class WorkspaceRepo {
}
}
class WorkspaceWatchRepo {
class WorkspaceListenerRepo {
StreamSubscription<ObservableSubject>? _subscription;
WorkspaceCreateAppCallback? _createApp;
WorkspaceDeleteAppCallback? _deleteApp;
@ -71,12 +71,12 @@ class WorkspaceWatchRepo {
final UserProfile user;
final String workspaceId;
WorkspaceWatchRepo({
WorkspaceListenerRepo({
required this.user,
required this.workspaceId,
});
void startWatching({
void startListen({
WorkspaceCreateAppCallback? createApp,
WorkspaceDeleteAppCallback? deleteApp,
WorkspaceUpdatedCallback? update,
@ -92,12 +92,10 @@ class WorkspaceWatchRepo {
},
);
_subscription =
RustStreamReceiver.listen((observable) => _extractor.parse(observable));
_subscription = RustStreamReceiver.listen((observable) => _extractor.parse(observable));
}
void _handleObservableType(
WorkspaceObservable ty, Either<Uint8List, WorkspaceError> result) {
void _handleObservableType(WorkspaceObservable ty, Either<Uint8List, WorkspaceError> result) {
switch (ty) {
case WorkspaceObservable.WorkspaceUpdated:
if (_update != null) {

View File

@ -1,3 +1,6 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/view/view_bloc.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:dartz/dartz.dart' as dartz;
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme.dart';
@ -6,8 +9,10 @@ import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_log/flowy_log.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart';
import 'package:styled_widget/styled_widget.dart';
@ -15,105 +20,92 @@ import 'package:app_flowy/workspace/domain/image.dart';
import 'package:app_flowy/workspace/domain/view_edit.dart';
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/app/menu_app.dart';
class ViewWidgetContext {
final View view;
ViewWidgetContext(this.view);
Key valueKey() => ValueKey("${view.id}${view.version}");
}
typedef OpenViewCallback = void Function(View);
// ignore: must_be_immutable
class ViewSectionItem extends StatefulWidget {
final ViewWidgetContext viewCtx;
final bool isSelected;
final OpenViewCallback onOpen;
class ViewSectionItem extends StatelessWidget {
final ViewBloc bloc;
final void Function(View) onSelected;
ViewSectionItem({
Key? key,
required this.viewCtx,
required this.isSelected,
required this.onOpen,
}) : super(key: viewCtx.valueKey());
@override
State<ViewSectionItem> createState() => _ViewSectionItemState();
}
// [[Widget: LifeCycle]]
// https://flutterbyexample.com/lesson/stateful-widget-lifecycle
class _ViewSectionItemState extends State<ViewSectionItem> {
bool isOnSelected = false;
required View view,
required bool isSelected,
required this.onSelected,
}) : bloc = getIt<ViewBloc>(param1: view),
super(key: ValueKey(view.id)) {
bloc.add(ViewEvent.setIsSelected(isSelected));
}
@override
Widget build(BuildContext context) {
final theme = context.watch<AppTheme>();
final config = HoverDisplayConfig(hoverColor: theme.bg3);
return InkWell(
onTap: _openView(context),
child: FlowyHover(
config: config,
builder: (context, onHover) => _render(context, onHover, config),
isOnSelected: () => isOnSelected || widget.isSelected,
return BlocProvider.value(
value: bloc,
child: BlocListener<ViewBloc, ViewState>(
listenWhen: (p, c) => p.action != c.action,
listener: (context, state) {
state.action.fold(() => null, (action) {
Log.info('$action');
});
},
child: BlocBuilder<ViewBloc, ViewState>(
builder: (context, state) {
return InkWell(
onTap: () => onSelected(context.read<ViewBloc>().state.view),
child: FlowyHover(
config: HoverDisplayConfig(hoverColor: theme.bg3),
builder: (context, onHover) => _render(context, onHover),
isOnSelected: () => state.isEditing || state.isSelected,
),
);
},
),
),
);
}
Widget _render(BuildContext context, bool onHover, HoverDisplayConfig config) {
Widget _render(BuildContext context, bool onHover) {
final state = context.read<ViewBloc>().state;
List<Widget> children = [
SizedBox(
width: 16,
height: 16,
child: svgForViewType(widget.viewCtx.view.viewType),
),
SizedBox(width: 16, height: 16, child: state.view.thumbnail()),
const HSpace(6),
FlowyText.regular(
widget.viewCtx.view.name,
fontSize: 12,
),
FlowyText.regular(state.view.name, fontSize: 12),
];
if (onHover || isOnSelected) {
if (onHover || state.isEditing) {
children.add(const Spacer());
children.add(ViewDisclosureButton(
onTap: () {
setState(
() => isOnSelected = true,
);
context.read<ViewBloc>().add(const ViewEvent.setIsEditing(true));
getIt<HomeStackManager>().setStack(state.view.intoStackContext());
},
onSelected: (selected) {
selected.fold(() => null, (action) {
debugPrint('$action.name');
});
setState(() {
isOnSelected = false;
});
onSelected: (action) {
context.read<ViewBloc>().add(const ViewEvent.setIsEditing(false));
context.read<ViewBloc>().add(ViewEvent.setAction(action));
},
));
}
return Container(
return SizedBox(
height: 24,
child: Row(children: children).padding(
left: MenuAppSizes.expandedPadding,
right: MenuAppSizes.expandedIconPadding,
),
height: 24,
alignment: Alignment.centerLeft,
);
}
Function() _openView(BuildContext context) {
return () => widget.onOpen(widget.viewCtx.view);
}
}
// [[Widget: LifeCycle]]
// https://flutterbyexample.com/lesson/stateful-widget-lifecycle
class ViewDisclosureButton extends StatelessWidget {
final Function(dartz.Option<ViewAction>) onSelected;
final Function() onTap;
final Function(dartz.Option<ViewAction>) onSelected;
const ViewDisclosureButton({
Key? key,
required this.onSelected,
required this.onTap,
required this.onSelected,
}) : super(key: key);
@override
@ -140,16 +132,15 @@ class ViewActionList implements FlowyOverlayDelegate {
const ViewActionList({required this.anchorContext, required this.onSelected});
void show(BuildContext buildContext) {
final items = ViewAction.values.map((action) {
return ActionItem(
action: action,
onSelected: (action) {
FlowyOverlay.of(buildContext).remove(_identifier);
onSelected(dartz.some(action));
});
}).toList();
final items = ViewAction.values
.map((action) => ActionItem(
action: action,
onSelected: (action) {
FlowyOverlay.of(buildContext).remove(_identifier);
onSelected(dartz.some(action));
}))
.toList();
// TODO: make sure the delegate of this wouldn't cause retain cycle
ListOverlay.showWithAnchor(
buildContext,
identifier: _identifier,
@ -181,17 +172,19 @@ class ActionItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = context.watch<AppTheme>();
final config = HoverDisplayConfig(hoverColor: theme.hover);
return FlowyHover(
config: config,
config: HoverDisplayConfig(hoverColor: theme.hover),
builder: (context, onHover) {
return GestureDetector(
onTap: () => onSelected(action),
child: FlowyText.medium(
action.name,
fontSize: 12,
).padding(horizontal: 10, vertical: 6),
).padding(
horizontal: 10,
vertical: 6,
),
);
},
);

View File

@ -1,11 +1,8 @@
import 'package:flowy_log/flowy_log.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'item.dart';
class ViewListNotifier extends ChangeNotifier {
@ -49,32 +46,26 @@ class ViewSection extends StatelessWidget {
Widget build(BuildContext context) {
// The ViewListNotifier will be updated after ViewListData changed passed by parent widget
return ChangeNotifierProxyProvider<ViewListNotifier, ViewSectionNotifier>(
create: (_) => ViewSectionNotifier(
Provider.of<ViewListNotifier>(
create: (_) {
final views = Provider.of<ViewListNotifier>(
context,
listen: false,
).items,
),
).items;
return ViewSectionNotifier(views);
},
update: (_, notifier, controller) => controller!..update(notifier),
child: Consumer(builder: (context, ViewSectionNotifier notifier, child) {
return _renderItems(context, notifier.views);
return _renderSectionItems(context, notifier.views);
}),
);
}
Widget _renderItems(BuildContext context, List<View> views) {
Widget _renderSectionItems(BuildContext context, List<View> views) {
var viewWidgets = views.map((view) {
final viewCtx = ViewWidgetContext(view);
final item = ViewSectionItem(
viewCtx: viewCtx,
view: view,
isSelected: _isViewSelected(context, view.id),
onOpen: (view) {
Log.debug("Open: $view");
context.read<ViewSectionNotifier>().setSelectedView(view);
final stackView = stackCtxFromView(viewCtx.view);
getIt<HomeStackManager>().setStack(stackView);
},
onSelected: (view) => context.read<ViewSectionNotifier>().setSelectedView(view),
);
return Padding(
@ -83,17 +74,14 @@ class ViewSection extends StatelessWidget {
);
}).toList(growable: false);
return Column(
children: viewWidgets,
);
return Column(children: viewWidgets);
}
bool _isViewSelected(BuildContext context, String viewId) {
final view = context.read<ViewSectionNotifier>().selectedView;
if (view != null) {
return view.id == viewId;
} else {
if (view == null) {
return false;
}
return view.id == viewId;
}
}