[fluuter]: create & choose workspace after login

This commit is contained in:
appflowy 2021-08-30 16:18:58 +08:00
parent 99a4beb781
commit 76e73ea17b
42 changed files with 1303 additions and 282 deletions

View File

@ -11,7 +11,7 @@ abstract class IAuth {
}
abstract class IAuthRouter {
void showHomeScreen(BuildContext context, UserDetail user);
void showWorkspaceSelectScreen(BuildContext context, UserDetail user);
void showSignUpScreen(BuildContext context);
void showForgetPasswordScreen(BuildContext context);
}

View File

@ -1,4 +1,5 @@
import 'package:app_flowy/workspace/presentation/home/home_screen.dart';
import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
import 'package:app_flowy/workspace/presentation/workspace/workspace_select_screen.dart';
import 'package:dartz/dartz.dart';
import 'package:flowy_infra_ui/widget/route/animation.dart';
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
@ -37,8 +38,14 @@ class AuthRouterImpl extends IAuthRouter {
}
@override
void showHomeScreen(BuildContext context, UserDetail user) {
Navigator.of(context).push(PageRoutes.fade(() => HomeScreen(user)));
void showWorkspaceSelectScreen(BuildContext context, UserDetail user) {
Navigator.of(context).push(
PageRoutes.fade(
() => WorkspaceSelectScreen(
repo: UserRepo(user: user),
),
),
);
}
@override

View File

@ -36,7 +36,7 @@ class SignInScreen extends StatelessWidget {
void _handleSuccessOrFail(
Either<UserDetail, UserError> result, BuildContext context) {
result.fold(
(user) => router.showHomeScreen(context, user),
(user) => router.showWorkspaceSelectScreen(context, user),
(error) => _showErrorMessage(context, error.msg),
);
}

View File

@ -9,5 +9,5 @@ abstract class IWelcomeAuth {
abstract class IWelcomeRoute {
Widget pushSignInScreen();
Widget pushHomeScreen(UserDetail userDetail);
Future<void> pushHomeScreen(BuildContext context, UserDetail userDetail);
}

View File

@ -3,9 +3,15 @@ import 'package:app_flowy/user/domain/i_auth.dart';
import 'package:app_flowy/user/presentation/sign_in/sign_in_screen.dart';
import 'package:app_flowy/welcome/domain/auth_state.dart';
import 'package:app_flowy/welcome/domain/i_welcome.dart';
import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
import 'package:app_flowy/workspace/presentation/home/home_screen.dart';
import 'package:app_flowy/workspace/presentation/workspace/workspace_select_screen.dart';
import 'package:flowy_infra/flowy_logger.dart';
import 'package:flowy_infra/time/duration.dart';
import 'package:flowy_infra_ui/widget/route/animation.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
@ -30,12 +36,42 @@ class WelcomeAuthImpl implements IWelcomeAuth {
class WelcomeRoute implements IWelcomeRoute {
@override
Widget pushHomeScreen(UserDetail user) {
return HomeScreen(user);
Future<void> pushHomeScreen(BuildContext context, UserDetail user) async {
final repo = UserRepo(user: user);
return WorkspaceEventReadCurWorkspace().send().then(
(result) {
return result.fold(
(workspace) =>
_pushToScreen(context, HomeScreen(repo.user, workspace.id)),
(error) async {
// assert(error.code == WsErrCode.RecordNotFound);
// error shoule be RecordNotFound
Log.error(error);
final screen = WorkspaceSelectScreen(repo: repo);
final workspaceId = await Navigator.of(context).push(
PageRoutes.fade(
() => screen,
RouteDurations.slow.inMilliseconds * .001,
),
);
_pushToScreen(context, HomeScreen(repo.user, workspaceId));
},
);
},
);
}
@override
Widget pushSignInScreen() {
return SignInScreen(router: getIt<IAuthRouter>());
}
void _pushToScreen(BuildContext context, Widget screen) {
Navigator.push(
context,
PageRoutes.fade(
() => screen, RouteDurations.slow.inMilliseconds * .001));
}
}

View File

@ -41,8 +41,7 @@ class WelcomeScreen extends StatelessWidget {
}
void _handleAuthenticated(BuildContext context, Authenticated result) {
_pushToScreen(
context, getIt<IWelcomeRoute>().pushHomeScreen(result.userDetail));
getIt<IWelcomeRoute>().pushHomeScreen(context, result.userDetail);
}
void _handleUnauthenticated(BuildContext context, Unauthenticated result) {

View File

@ -0,0 +1,81 @@
import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/workspace_create.pb.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:dartz/dartz.dart';
part 'workspace_list_bloc.freezed.dart';
class WorkspaceListBloc extends Bloc<WorkspaceListEvent, WorkspaceListState> {
UserRepo repo;
WorkspaceListBloc(this.repo) : super(WorkspaceListState.initial());
@override
Stream<WorkspaceListState> mapEventToState(
WorkspaceListEvent event,
) async* {
yield* event.map(initial: (e) async* {
yield* _fetchWorkspaces();
}, openWorkspace: (e) async* {
yield* _openWorkspace(e.workspace);
}, createWorkspace: (e) async* {
yield* _createWorkspace(e.name, e.desc);
}, fetchWorkspaces: (e) async* {
yield* _fetchWorkspaces();
});
}
Stream<WorkspaceListState> _fetchWorkspaces() async* {
final workspacesOrFailed = await repo.fetchWorkspaces();
yield workspacesOrFailed.fold(
(workspaces) =>
state.copyWith(workspaces: workspaces, successOrFailure: left(unit)),
(error) => state.copyWith(successOrFailure: right(error)),
);
}
Stream<WorkspaceListState> _openWorkspace(Workspace workspace) async* {
final result = await repo.openWorkspace(workspace.id);
yield result.fold(
(workspaces) => state.copyWith(successOrFailure: left(unit)),
(error) => state.copyWith(successOrFailure: right(error)),
);
}
Stream<WorkspaceListState> _createWorkspace(String name, String desc) async* {
final result = await repo.createWorkspace(name, desc);
yield result.fold(
(workspace) {
add(const WorkspaceListEvent.fetchWorkspaces());
return state.copyWith(successOrFailure: left(unit));
},
(error) => state.copyWith(successOrFailure: right(error)),
);
}
}
@freezed
abstract class WorkspaceListEvent with _$WorkspaceListEvent {
const factory WorkspaceListEvent.initial() = Initial;
const factory WorkspaceListEvent.fetchWorkspaces() = FetchWorkspace;
const factory WorkspaceListEvent.createWorkspace(String name, String desc) =
CreateWorkspace;
const factory WorkspaceListEvent.openWorkspace(Workspace workspace) =
OpenWorkspace;
}
@freezed
abstract class WorkspaceListState implements _$WorkspaceListState {
const factory WorkspaceListState({
required bool isLoading,
required List<Workspace> workspaces,
required Either<Unit, WorkspaceError> successOrFailure,
}) = _WorkspaceListState;
factory WorkspaceListState.initial() => WorkspaceListState(
isLoading: false,
workspaces: List.empty(),
successOrFailure: left(unit),
);
}

View File

@ -0,0 +1,732 @@
// 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 'workspace_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 _$WorkspaceListEventTearOff {
const _$WorkspaceListEventTearOff();
Initial initial() {
return const Initial();
}
FetchWorkspace fetchWorkspaces() {
return const FetchWorkspace();
}
CreateWorkspace createWorkspace(String name, String desc) {
return CreateWorkspace(
name,
desc,
);
}
OpenWorkspace openWorkspace(Workspace workspace) {
return OpenWorkspace(
workspace,
);
}
}
/// @nodoc
const $WorkspaceListEvent = _$WorkspaceListEventTearOff();
/// @nodoc
mixin _$WorkspaceListEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() fetchWorkspaces,
required TResult Function(String name, String desc) createWorkspace,
required TResult Function(Workspace workspace) openWorkspace,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? fetchWorkspaces,
TResult Function(String name, String desc)? createWorkspace,
TResult Function(Workspace workspace)? openWorkspace,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(Initial value) initial,
required TResult Function(FetchWorkspace value) fetchWorkspaces,
required TResult Function(CreateWorkspace value) createWorkspace,
required TResult Function(OpenWorkspace value) openWorkspace,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(Initial value)? initial,
TResult Function(FetchWorkspace value)? fetchWorkspaces,
TResult Function(CreateWorkspace value)? createWorkspace,
TResult Function(OpenWorkspace value)? openWorkspace,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $WorkspaceListEventCopyWith<$Res> {
factory $WorkspaceListEventCopyWith(
WorkspaceListEvent value, $Res Function(WorkspaceListEvent) then) =
_$WorkspaceListEventCopyWithImpl<$Res>;
}
/// @nodoc
class _$WorkspaceListEventCopyWithImpl<$Res>
implements $WorkspaceListEventCopyWith<$Res> {
_$WorkspaceListEventCopyWithImpl(this._value, this._then);
final WorkspaceListEvent _value;
// ignore: unused_field
final $Res Function(WorkspaceListEvent) _then;
}
/// @nodoc
abstract class $InitialCopyWith<$Res> {
factory $InitialCopyWith(Initial value, $Res Function(Initial) then) =
_$InitialCopyWithImpl<$Res>;
}
/// @nodoc
class _$InitialCopyWithImpl<$Res> extends _$WorkspaceListEventCopyWithImpl<$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 'WorkspaceListEvent.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,
required TResult Function() fetchWorkspaces,
required TResult Function(String name, String desc) createWorkspace,
required TResult Function(Workspace workspace) openWorkspace,
}) {
return initial();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? fetchWorkspaces,
TResult Function(String name, String desc)? createWorkspace,
TResult Function(Workspace workspace)? openWorkspace,
required TResult orElse(),
}) {
if (initial != null) {
return initial();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(Initial value) initial,
required TResult Function(FetchWorkspace value) fetchWorkspaces,
required TResult Function(CreateWorkspace value) createWorkspace,
required TResult Function(OpenWorkspace value) openWorkspace,
}) {
return initial(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(Initial value)? initial,
TResult Function(FetchWorkspace value)? fetchWorkspaces,
TResult Function(CreateWorkspace value)? createWorkspace,
TResult Function(OpenWorkspace value)? openWorkspace,
required TResult orElse(),
}) {
if (initial != null) {
return initial(this);
}
return orElse();
}
}
abstract class Initial implements WorkspaceListEvent {
const factory Initial() = _$Initial;
}
/// @nodoc
abstract class $FetchWorkspaceCopyWith<$Res> {
factory $FetchWorkspaceCopyWith(
FetchWorkspace value, $Res Function(FetchWorkspace) then) =
_$FetchWorkspaceCopyWithImpl<$Res>;
}
/// @nodoc
class _$FetchWorkspaceCopyWithImpl<$Res>
extends _$WorkspaceListEventCopyWithImpl<$Res>
implements $FetchWorkspaceCopyWith<$Res> {
_$FetchWorkspaceCopyWithImpl(
FetchWorkspace _value, $Res Function(FetchWorkspace) _then)
: super(_value, (v) => _then(v as FetchWorkspace));
@override
FetchWorkspace get _value => super._value as FetchWorkspace;
}
/// @nodoc
class _$FetchWorkspace implements FetchWorkspace {
const _$FetchWorkspace();
@override
String toString() {
return 'WorkspaceListEvent.fetchWorkspaces()';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) || (other is FetchWorkspace);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() fetchWorkspaces,
required TResult Function(String name, String desc) createWorkspace,
required TResult Function(Workspace workspace) openWorkspace,
}) {
return fetchWorkspaces();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? fetchWorkspaces,
TResult Function(String name, String desc)? createWorkspace,
TResult Function(Workspace workspace)? openWorkspace,
required TResult orElse(),
}) {
if (fetchWorkspaces != null) {
return fetchWorkspaces();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(Initial value) initial,
required TResult Function(FetchWorkspace value) fetchWorkspaces,
required TResult Function(CreateWorkspace value) createWorkspace,
required TResult Function(OpenWorkspace value) openWorkspace,
}) {
return fetchWorkspaces(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(Initial value)? initial,
TResult Function(FetchWorkspace value)? fetchWorkspaces,
TResult Function(CreateWorkspace value)? createWorkspace,
TResult Function(OpenWorkspace value)? openWorkspace,
required TResult orElse(),
}) {
if (fetchWorkspaces != null) {
return fetchWorkspaces(this);
}
return orElse();
}
}
abstract class FetchWorkspace implements WorkspaceListEvent {
const factory FetchWorkspace() = _$FetchWorkspace;
}
/// @nodoc
abstract class $CreateWorkspaceCopyWith<$Res> {
factory $CreateWorkspaceCopyWith(
CreateWorkspace value, $Res Function(CreateWorkspace) then) =
_$CreateWorkspaceCopyWithImpl<$Res>;
$Res call({String name, String desc});
}
/// @nodoc
class _$CreateWorkspaceCopyWithImpl<$Res>
extends _$WorkspaceListEventCopyWithImpl<$Res>
implements $CreateWorkspaceCopyWith<$Res> {
_$CreateWorkspaceCopyWithImpl(
CreateWorkspace _value, $Res Function(CreateWorkspace) _then)
: super(_value, (v) => _then(v as CreateWorkspace));
@override
CreateWorkspace get _value => super._value as CreateWorkspace;
@override
$Res call({
Object? name = freezed,
Object? desc = freezed,
}) {
return _then(CreateWorkspace(
name == freezed
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
desc == freezed
? _value.desc
: desc // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class _$CreateWorkspace implements CreateWorkspace {
const _$CreateWorkspace(this.name, this.desc);
@override
final String name;
@override
final String desc;
@override
String toString() {
return 'WorkspaceListEvent.createWorkspace(name: $name, desc: $desc)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is CreateWorkspace &&
(identical(other.name, name) ||
const DeepCollectionEquality().equals(other.name, name)) &&
(identical(other.desc, desc) ||
const DeepCollectionEquality().equals(other.desc, desc)));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(name) ^
const DeepCollectionEquality().hash(desc);
@JsonKey(ignore: true)
@override
$CreateWorkspaceCopyWith<CreateWorkspace> get copyWith =>
_$CreateWorkspaceCopyWithImpl<CreateWorkspace>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() fetchWorkspaces,
required TResult Function(String name, String desc) createWorkspace,
required TResult Function(Workspace workspace) openWorkspace,
}) {
return createWorkspace(name, desc);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? fetchWorkspaces,
TResult Function(String name, String desc)? createWorkspace,
TResult Function(Workspace workspace)? openWorkspace,
required TResult orElse(),
}) {
if (createWorkspace != null) {
return createWorkspace(name, desc);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(Initial value) initial,
required TResult Function(FetchWorkspace value) fetchWorkspaces,
required TResult Function(CreateWorkspace value) createWorkspace,
required TResult Function(OpenWorkspace value) openWorkspace,
}) {
return createWorkspace(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(Initial value)? initial,
TResult Function(FetchWorkspace value)? fetchWorkspaces,
TResult Function(CreateWorkspace value)? createWorkspace,
TResult Function(OpenWorkspace value)? openWorkspace,
required TResult orElse(),
}) {
if (createWorkspace != null) {
return createWorkspace(this);
}
return orElse();
}
}
abstract class CreateWorkspace implements WorkspaceListEvent {
const factory CreateWorkspace(String name, String desc) = _$CreateWorkspace;
String get name => throw _privateConstructorUsedError;
String get desc => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$CreateWorkspaceCopyWith<CreateWorkspace> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $OpenWorkspaceCopyWith<$Res> {
factory $OpenWorkspaceCopyWith(
OpenWorkspace value, $Res Function(OpenWorkspace) then) =
_$OpenWorkspaceCopyWithImpl<$Res>;
$Res call({Workspace workspace});
}
/// @nodoc
class _$OpenWorkspaceCopyWithImpl<$Res>
extends _$WorkspaceListEventCopyWithImpl<$Res>
implements $OpenWorkspaceCopyWith<$Res> {
_$OpenWorkspaceCopyWithImpl(
OpenWorkspace _value, $Res Function(OpenWorkspace) _then)
: super(_value, (v) => _then(v as OpenWorkspace));
@override
OpenWorkspace get _value => super._value as OpenWorkspace;
@override
$Res call({
Object? workspace = freezed,
}) {
return _then(OpenWorkspace(
workspace == freezed
? _value.workspace
: workspace // ignore: cast_nullable_to_non_nullable
as Workspace,
));
}
}
/// @nodoc
class _$OpenWorkspace implements OpenWorkspace {
const _$OpenWorkspace(this.workspace);
@override
final Workspace workspace;
@override
String toString() {
return 'WorkspaceListEvent.openWorkspace(workspace: $workspace)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is OpenWorkspace &&
(identical(other.workspace, workspace) ||
const DeepCollectionEquality()
.equals(other.workspace, workspace)));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(workspace);
@JsonKey(ignore: true)
@override
$OpenWorkspaceCopyWith<OpenWorkspace> get copyWith =>
_$OpenWorkspaceCopyWithImpl<OpenWorkspace>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() fetchWorkspaces,
required TResult Function(String name, String desc) createWorkspace,
required TResult Function(Workspace workspace) openWorkspace,
}) {
return openWorkspace(workspace);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? fetchWorkspaces,
TResult Function(String name, String desc)? createWorkspace,
TResult Function(Workspace workspace)? openWorkspace,
required TResult orElse(),
}) {
if (openWorkspace != null) {
return openWorkspace(workspace);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(Initial value) initial,
required TResult Function(FetchWorkspace value) fetchWorkspaces,
required TResult Function(CreateWorkspace value) createWorkspace,
required TResult Function(OpenWorkspace value) openWorkspace,
}) {
return openWorkspace(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(Initial value)? initial,
TResult Function(FetchWorkspace value)? fetchWorkspaces,
TResult Function(CreateWorkspace value)? createWorkspace,
TResult Function(OpenWorkspace value)? openWorkspace,
required TResult orElse(),
}) {
if (openWorkspace != null) {
return openWorkspace(this);
}
return orElse();
}
}
abstract class OpenWorkspace implements WorkspaceListEvent {
const factory OpenWorkspace(Workspace workspace) = _$OpenWorkspace;
Workspace get workspace => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$OpenWorkspaceCopyWith<OpenWorkspace> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
class _$WorkspaceListStateTearOff {
const _$WorkspaceListStateTearOff();
_WorkspaceListState call(
{required bool isLoading,
required List<Workspace> workspaces,
required Either<Unit, WorkspaceError> successOrFailure}) {
return _WorkspaceListState(
isLoading: isLoading,
workspaces: workspaces,
successOrFailure: successOrFailure,
);
}
}
/// @nodoc
const $WorkspaceListState = _$WorkspaceListStateTearOff();
/// @nodoc
mixin _$WorkspaceListState {
bool get isLoading => throw _privateConstructorUsedError;
List<Workspace> get workspaces => throw _privateConstructorUsedError;
Either<Unit, WorkspaceError> get successOrFailure =>
throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$WorkspaceListStateCopyWith<WorkspaceListState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $WorkspaceListStateCopyWith<$Res> {
factory $WorkspaceListStateCopyWith(
WorkspaceListState value, $Res Function(WorkspaceListState) then) =
_$WorkspaceListStateCopyWithImpl<$Res>;
$Res call(
{bool isLoading,
List<Workspace> workspaces,
Either<Unit, WorkspaceError> successOrFailure});
}
/// @nodoc
class _$WorkspaceListStateCopyWithImpl<$Res>
implements $WorkspaceListStateCopyWith<$Res> {
_$WorkspaceListStateCopyWithImpl(this._value, this._then);
final WorkspaceListState _value;
// ignore: unused_field
final $Res Function(WorkspaceListState) _then;
@override
$Res call({
Object? isLoading = freezed,
Object? workspaces = freezed,
Object? successOrFailure = freezed,
}) {
return _then(_value.copyWith(
isLoading: isLoading == freezed
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
workspaces: workspaces == freezed
? _value.workspaces
: workspaces // ignore: cast_nullable_to_non_nullable
as List<Workspace>,
successOrFailure: successOrFailure == freezed
? _value.successOrFailure
: successOrFailure // ignore: cast_nullable_to_non_nullable
as Either<Unit, WorkspaceError>,
));
}
}
/// @nodoc
abstract class _$WorkspaceListStateCopyWith<$Res>
implements $WorkspaceListStateCopyWith<$Res> {
factory _$WorkspaceListStateCopyWith(
_WorkspaceListState value, $Res Function(_WorkspaceListState) then) =
__$WorkspaceListStateCopyWithImpl<$Res>;
@override
$Res call(
{bool isLoading,
List<Workspace> workspaces,
Either<Unit, WorkspaceError> successOrFailure});
}
/// @nodoc
class __$WorkspaceListStateCopyWithImpl<$Res>
extends _$WorkspaceListStateCopyWithImpl<$Res>
implements _$WorkspaceListStateCopyWith<$Res> {
__$WorkspaceListStateCopyWithImpl(
_WorkspaceListState _value, $Res Function(_WorkspaceListState) _then)
: super(_value, (v) => _then(v as _WorkspaceListState));
@override
_WorkspaceListState get _value => super._value as _WorkspaceListState;
@override
$Res call({
Object? isLoading = freezed,
Object? workspaces = freezed,
Object? successOrFailure = freezed,
}) {
return _then(_WorkspaceListState(
isLoading: isLoading == freezed
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
workspaces: workspaces == freezed
? _value.workspaces
: workspaces // ignore: cast_nullable_to_non_nullable
as List<Workspace>,
successOrFailure: successOrFailure == freezed
? _value.successOrFailure
: successOrFailure // ignore: cast_nullable_to_non_nullable
as Either<Unit, WorkspaceError>,
));
}
}
/// @nodoc
class _$_WorkspaceListState implements _WorkspaceListState {
const _$_WorkspaceListState(
{required this.isLoading,
required this.workspaces,
required this.successOrFailure});
@override
final bool isLoading;
@override
final List<Workspace> workspaces;
@override
final Either<Unit, WorkspaceError> successOrFailure;
@override
String toString() {
return 'WorkspaceListState(isLoading: $isLoading, workspaces: $workspaces, successOrFailure: $successOrFailure)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _WorkspaceListState &&
(identical(other.isLoading, isLoading) ||
const DeepCollectionEquality()
.equals(other.isLoading, isLoading)) &&
(identical(other.workspaces, workspaces) ||
const DeepCollectionEquality()
.equals(other.workspaces, workspaces)) &&
(identical(other.successOrFailure, successOrFailure) ||
const DeepCollectionEquality()
.equals(other.successOrFailure, successOrFailure)));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(isLoading) ^
const DeepCollectionEquality().hash(workspaces) ^
const DeepCollectionEquality().hash(successOrFailure);
@JsonKey(ignore: true)
@override
_$WorkspaceListStateCopyWith<_WorkspaceListState> get copyWith =>
__$WorkspaceListStateCopyWithImpl<_WorkspaceListState>(this, _$identity);
}
abstract class _WorkspaceListState implements WorkspaceListState {
const factory _WorkspaceListState(
{required bool isLoading,
required List<Workspace> workspaces,
required Either<Unit, WorkspaceError> successOrFailure}) =
_$_WorkspaceListState;
@override
bool get isLoading => throw _privateConstructorUsedError;
@override
List<Workspace> get workspaces => throw _privateConstructorUsedError;
@override
Either<Unit, WorkspaceError> get successOrFailure =>
throw _privateConstructorUsedError;
@override
@JsonKey(ignore: true)
_$WorkspaceListStateCopyWith<_WorkspaceListState> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -37,10 +37,12 @@ class HomeDepsResolver {
(appId, _) => IAppWatchImpl(repo: AppWatchRepository(appId: appId)));
//workspace
getIt.registerFactoryParam<IWorkspace, UserDetail, void>(
(user, _) => IWorkspaceImpl(repo: WorkspaceRepo(user: user)));
getIt.registerFactoryParam<IWorkspaceWatch, UserDetail, void>(
(user, _) => IWorkspaceWatchImpl(repo: WorkspaceWatchRepo(user: user)));
getIt.registerFactoryParam<IWorkspace, UserDetail, String>(
(user, workspaceId) => IWorkspaceImpl(
repo: WorkspaceRepo(user: user, workspaceId: workspaceId)));
getIt.registerFactoryParam<IWorkspaceWatch, UserDetail, String>(
(user, workspaceId) => IWorkspaceWatchImpl(
repo: WorkspaceWatchRepo(user: user, workspaceId: workspaceId)));
// View
getIt.registerFactoryParam<IView, View, void>(
@ -59,10 +61,12 @@ class HomeDepsResolver {
(user, _) => IUserWatchImpl(repo: UserWatchRepo(user: user)));
//Menu Bloc
getIt.registerFactoryParam<MenuBloc, UserDetail, void>(
(user, _) => MenuBloc(getIt<IWorkspace>(param1: user)));
getIt.registerFactoryParam<MenuWatchBloc, UserDetail, void>(
(user, _) => MenuWatchBloc(getIt<IWorkspaceWatch>(param1: user)));
getIt.registerFactoryParam<MenuBloc, UserDetail, String>(
(user, workspaceId) =>
MenuBloc(getIt<IWorkspace>(param1: user, param2: workspaceId)));
getIt.registerFactoryParam<MenuWatchBloc, UserDetail, String>(
(user, workspaceId) => MenuWatchBloc(
getIt<IWorkspaceWatch>(param1: user, param2: workspaceId)));
getIt.registerFactoryParam<MenuUserBloc, UserDetail, void>(
(user, _) => MenuUserBloc(getIt<IUser>(param1: user)));

View File

@ -20,7 +20,7 @@ class IWorkspaceImpl extends IWorkspace {
@override
Future<Either<List<App>, WorkspaceError>> getApps() {
return repo.getWorkspace(readApps: true).then((result) {
return repo.getWorkspace().then((result) {
return result.fold(
(workspace) => left(workspace.apps.items),
(error) => right(error),

View File

@ -8,8 +8,8 @@ import 'package:flowy_sdk/protobuf/flowy-user/user_detail.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/workspace_create.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/workspace_query.pb.dart';
import 'package:flowy_sdk/rust_stream.dart';
import 'package:app_flowy/workspace/domain/i_user.dart';
class UserRepo {
@ -33,10 +33,38 @@ class UserRepo {
}
Future<Either<List<Workspace>, WorkspaceError>> fetchWorkspaces() {
return WorkspaceEventReadAllWorkspace().send().then((result) {
final request = QueryWorkspaceRequest.create()..userId = user.id;
return WorkspaceEventReadWorkspaces(request).send().then((result) {
return result.fold(
(workspaces) => left(workspaces.items),
(r) => right(r),
(error) => right(error),
);
});
}
Future<Either<Workspace, WorkspaceError>> openWorkspace(String workspaceId) {
final request = QueryWorkspaceRequest.create()
..userId = user.id
..workspaceId = workspaceId;
return WorkspaceEventOpenWorkspace(request).send().then((result) {
return result.fold(
(workspace) => left(workspace),
(error) => right(error),
);
});
}
Future<Either<Workspace, WorkspaceError>> createWorkspace(
String name, String desc) {
final request = CreateWorkspaceRequest.create()
..userId = user.id
..name = name
..desc = desc;
return WorkspaceEventCreateWorkspace(request).send().then((result) {
return result.fold(
(workspace) => left(workspace),
(error) => right(error),
);
});
}

View File

@ -1,6 +1,5 @@
import 'dart:async';
import 'package:app_flowy/workspace/domain/i_workspace.dart';
import 'package:dartz/dartz.dart';
import 'package:flowy_infra/flowy_logger.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart';
@ -13,10 +12,14 @@ import 'package:flowy_sdk/protobuf/flowy-workspace/workspace_create.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/workspace_query.pb.dart';
import 'package:flowy_sdk/rust_stream.dart';
import 'package:app_flowy/workspace/domain/i_workspace.dart';
class WorkspaceRepo {
UserDetail user;
String workspaceId;
WorkspaceRepo({
required this.user,
required this.workspaceId,
});
Future<Either<App, WorkspaceError>> createApp(String appName, String desc) {
@ -36,16 +39,22 @@ class WorkspaceRepo {
});
}
Future<Either<Workspace, WorkspaceError>> getWorkspace(
{bool readApps = false}) {
Future<Either<Workspace, WorkspaceError>> getWorkspace() {
final request = QueryWorkspaceRequest.create()
..workspaceId = user.workspace
..user_id = user.id
..readApps = readApps;
..userId = user.id
..workspaceId = workspaceId;
return WorkspaceEventReadWorkspace(request).send().then((result) {
return WorkspaceEventReadWorkspaces(request).send().then((result) {
return result.fold(
(workspace) => left(workspace),
(workspaces) {
assert(workspaces.items.length == 1);
if (workspaces.items.isEmpty) {
return right(WorkspaceError.create()..msg = "Workspace not found");
} else {
return left(workspaces.items[0]);
}
},
(error) => right(error),
);
});
@ -58,12 +67,14 @@ class WorkspaceWatchRepo {
WorkspaceDeleteAppCallback? _deleteApp;
WorkspaceUpdatedCallback? _update;
final UserDetail user;
final String workspaceId;
late WorkspaceRepo _repo;
WorkspaceWatchRepo({
required this.user,
required this.workspaceId,
}) {
_repo = WorkspaceRepo(user: user);
_repo = WorkspaceRepo(user: user, workspaceId: workspaceId);
}
void startWatching({
@ -76,7 +87,7 @@ class WorkspaceWatchRepo {
_update = update;
_subscription = RustStreamReceiver.listen((observable) {
if (observable.subjectId != user.workspace) {
if (observable.subjectId != workspaceId) {
return;
}
@ -104,18 +115,20 @@ class WorkspaceWatchRepo {
if (_createApp == null) {
return;
}
_repo.getWorkspace(readApps: true).then((result) {
_repo.getWorkspace().then((result) {
result.fold(
(workspace) => _createApp!(left(workspace.apps.items)),
(error) => _createApp!(right(error)),
);
});
break;
case WorkspaceObservable.WorkspaceDeleteApp:
if (_deleteApp == null) {
return;
}
_repo.getWorkspace(readApps: true).then((result) {
_repo.getWorkspace().then((result) {
result.fold(
(workspace) => _deleteApp!(left(workspace.apps.items)),
(error) => _deleteApp!(right(error)),

View File

@ -35,6 +35,7 @@ class ViewListPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// The ViewListNotifier will be updated after ViewListData changed passed by parent widget
return ChangeNotifierProxyProvider<ViewListData, ViewListNotifier>(
create: (_) => ViewListNotifier(
Provider.of<ViewListData>(

View File

@ -15,7 +15,8 @@ import 'home_layout.dart';
class HomeScreen extends StatelessWidget {
static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
final UserDetail user;
const HomeScreen(this.user, {Key? key}) : super(key: key);
final String workspaceId;
const HomeScreen(this.user, this.workspaceId, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -76,6 +77,7 @@ class HomeScreen extends StatelessWidget {
homeBloc.add(HomeEvent.forceCollapse(isCollapse));
},
user: user,
workspaceId: workspaceId,
);
homeMenu = RepaintBoundary(child: homeMenu);
homeMenu = FocusTraversalGroup(child: homeMenu);

View File

@ -23,13 +23,15 @@ class HomeMenu extends StatelessWidget {
final Function(HomeStackView?) pageContextChanged;
final Function(bool) isCollapseChanged;
final UserDetail user;
final String workspaceId;
const HomeMenu(
{Key? key,
required this.pageContextChanged,
required this.isCollapseChanged,
required this.user})
: super(key: key);
const HomeMenu({
Key? key,
required this.pageContextChanged,
required this.isCollapseChanged,
required this.user,
required this.workspaceId,
}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -37,10 +39,12 @@ class HomeMenu extends StatelessWidget {
providers: [
BlocProvider<MenuBloc>(
create: (context) =>
getIt<MenuBloc>(param1: user)..add(const MenuEvent.initial())),
getIt<MenuBloc>(param1: user, param2: workspaceId)
..add(const MenuEvent.initial())),
BlocProvider(
create: (context) => getIt<MenuWatchBloc>(param1: user)
..add(const MenuWatchEvent.started())),
create: (context) =>
getIt<MenuWatchBloc>(param1: user, param2: workspaceId)
..add(const MenuWatchEvent.started())),
],
child: MultiBlocListener(
listeners: [

View File

@ -0,0 +1,236 @@
import 'package:app_flowy/workspace/application/workspace/workspace_list_bloc.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
import 'package:flowy_infra_ui/style_widget/text_button.dart';
import 'package:flowy_infra_ui/widget/error_page.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/workspace_create.pb.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
class WorkspaceSelectScreen extends StatelessWidget {
final UserRepo repo;
const WorkspaceSelectScreen({
Key? key,
required this.repo,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) =>
WorkspaceListBloc(repo)..add(const WorkspaceListEvent.initial()),
child: BlocBuilder<WorkspaceListBloc, WorkspaceListState>(
builder: (context, state) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(60.0),
child: Column(
children: [
_renderBody(state),
_renderCreateButton(context),
],
),
),
);
},
),
);
}
Widget _renderBody(WorkspaceListState state) {
final body = state.successOrFailure.fold(
(_) => _renderList(state.workspaces),
(error) => FlowyErrorPage(error.toString()),
);
return body;
}
Widget _renderCreateButton(BuildContext context) {
return SizedBox(
width: 200,
height: 40,
child: FlowyTextButton(
"Create workspace",
fontSize: 14,
onPressed: () {
context
.read<WorkspaceListBloc>()
.add(const WorkspaceListEvent.createWorkspace("workspace", ""));
},
),
);
}
Widget _renderList(List<Workspace> workspaces) {
return Expanded(
child: StyledListView(
itemBuilder: (BuildContext context, int index) {
final workspace = workspaces[index];
return WorkspaceItem(
workspace: workspace,
onPressed: (workspace) => _handleOnPress(context, workspace),
);
},
itemCount: workspaces.length,
),
);
}
void _handleOnPress(BuildContext context, Workspace workspace) {
context
.read<WorkspaceListBloc>()
.add(WorkspaceListEvent.openWorkspace(workspace));
Navigator.of(context).pop(workspace.id);
}
}
class WorkspaceItem extends StatelessWidget {
final Workspace workspace;
final void Function(Workspace workspace) onPressed;
const WorkspaceItem(
{Key? key, required this.workspace, required this.onPressed})
: super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
height: 46,
child: FlowyTextButton(
workspace.name,
fontSize: 14,
onPressed: () => onPressed(workspace),
),
);
}
}
// Bloc and Provider
// *************Provider***************
// class WorkspaceListNotifier with ChangeNotifier {
// UserRepo repo;
// List<Workspace> workspaces = [];
// WorkspaceListNotifier({
// required this.repo,
// }) {
// fetch();
// }
// void fetch() {
// repo.fetchWorkspaces().then((result) {
// result.fold((workspaces) {
// this.workspaces = workspaces;
// notifyListeners();
// }, (error) {
// Log.error(error);
// });
// });
// }
// }
// class WorkspaceSelectScreen extends StatelessWidget {
// final UserDetail user;
// const WorkspaceSelectScreen({
// Key? key,
// required this.user,
// }) : super(key: key);
// @override
// Widget build(BuildContext context) {
// return MultiProvider(
// providers: [
// ChangeNotifierProvider(
// create: (_) => WorkspaceListNotifier(repo: UserRepo(user: user)),
// )
// ],
// child: Consumer<WorkspaceListNotifier>(builder: (ctx, notifier, child) {
// return StyledListView(
// itemBuilder: (BuildContext context, int index) {
// final workspace = notifier.workspaces[index];
// return WorkspaceItem(workspace);
// },
// itemCount: notifier.workspaces.length,
// );
// }));
// }
// }
// *************Bloc***************
//
// class WorkspaceListBloc extends Bloc<WorkspaceListEvent, WorkspaceListState> {
// UserRepo repo;
// WorkspaceListBloc(this.repo) : super(WorkspaceListState.initial());
// @override
// Stream<WorkspaceListState> mapEventToState(
// WorkspaceListEvent event,
// ) async* {
// yield* event.map(
// initial: (e) async* {
// yield* _fetchWorkspaces();
// },
// );
// }
// Stream<WorkspaceListState> _fetchWorkspaces() async* {
// final workspacesOrFailed = await repo.fetchWorkspaces();
// yield workspacesOrFailed.fold(
// (workspaces) => state.copyWith(
// workspaces: workspaces, successOrFailure: left(unit)),
// (error) => state.copyWith(successOrFailure: right(error)));
// }
// }
// @freezed
// abstract class WorkspaceListEvent with _$WorkspaceListEvent {
// const factory WorkspaceListEvent.initial() = Initial;
// }
// @freezed
// abstract class WorkspaceListState implements _$WorkspaceListState {
// const factory WorkspaceListState({
// required bool isLoading,
// required List<Workspace> workspaces,
// required Either<Unit, WorkspaceError> successOrFailure,
// }) = _WorkspaceListState;
// factory WorkspaceListState.initial() => WorkspaceListState(
// isLoading: false,
// workspaces: List.empty(),
// successOrFailure: left(unit),
// );
// }
//
// class WorkspaceSelectScreen extends StatelessWidget {
// final UserDetail user;
// const WorkspaceSelectScreen({
// Key? key,
// required this.user,
// }) : super(key: key);
// @override
// Widget build(BuildContext context) {
// return BlocProvider(
// create: (_) => WorkspaceListBloc(UserRepo(user: user))
// ..add(const WorkspaceListEvent.initial()),
// child: BlocBuilder<WorkspaceListBloc, WorkspaceListState>(
// builder: (context, state) {
// return state.successOrFailure.fold(
// (_) => StyledListView(
// itemBuilder: (BuildContext context, int index) {
// final workspace = state.workspaces[index];
// return WorkspaceItem(workspace);
// },
// itemCount: state.workspaces.length,
// ),
// (error) => Container(),
// );
// },
// ),
// );
// }
// }

View File

@ -33,18 +33,18 @@ class WorkspaceEventReadCurWorkspace {
}
}
class WorkspaceEventReadWorkspace {
class WorkspaceEventReadWorkspaces {
QueryWorkspaceRequest request;
WorkspaceEventReadWorkspace(this.request);
WorkspaceEventReadWorkspaces(this.request);
Future<Either<Workspace, WorkspaceError>> send() {
Future<Either<RepeatedWorkspace, WorkspaceError>> send() {
final request = FFIRequest.create()
..event = WorkspaceEvent.ReadWorkspace.toString()
..event = WorkspaceEvent.ReadWorkspaces.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(Workspace.fromBuffer(okBytes)),
(okBytes) => left(RepeatedWorkspace.fromBuffer(okBytes)),
(errBytes) => right(WorkspaceError.fromBuffer(errBytes)),
));
}
@ -67,17 +67,20 @@ class WorkspaceEventDeleteWorkspace {
}
}
class WorkspaceEventReadAllWorkspace {
WorkspaceEventReadAllWorkspace();
class WorkspaceEventOpenWorkspace {
QueryWorkspaceRequest request;
WorkspaceEventOpenWorkspace(this.request);
Future<Either<RepeatedWorkspace, WorkspaceError>> send() {
final request = FFIRequest.create()
..event = WorkspaceEvent.ReadAllWorkspace.toString();
Future<Either<Workspace, WorkspaceError>> send() {
final request = FFIRequest.create()
..event = WorkspaceEvent.OpenWorkspace.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
(okBytes) => left(RepeatedWorkspace.fromBuffer(okBytes)),
(errBytes) => right(WorkspaceError.fromBuffer(errBytes)),
));
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(Workspace.fromBuffer(okBytes)),
(errBytes) => right(WorkspaceError.fromBuffer(errBytes)),
));
}
}

View File

@ -17,7 +17,7 @@ import 'package:flowy_sdk/protobuf/flowy-document/protobuf.dart';
// ignore: unused_import
import 'package:flowy_sdk/protobuf/flowy-infra/protobuf.dart';
import 'package:protobuf/protobuf.dart';
import 'dart:convert' show utf8;
import 'error.dart';
part 'code_gen.dart';
@ -54,10 +54,15 @@ Future<Either<Uint8List, Uint8List>> _extractPayload(
if (response.code == FFIStatusCode.Ok) {
return left(Uint8List.fromList(response.payload));
} else {
// final error = utf8.decode(response.payload);
// Log.error("Dispatch error: $error");
return right(Uint8List.fromList(response.payload));
}
},
(error) => right(emptyBytes()),
(error) {
Log.error("Response should not be empty $error");
return right(emptyBytes());
},
);
});
}

View File

@ -12,10 +12,9 @@ import 'package:protobuf/protobuf.dart' as $pb;
class WorkspaceEvent extends $pb.ProtobufEnum {
static const WorkspaceEvent CreateWorkspace = WorkspaceEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateWorkspace');
static const WorkspaceEvent ReadCurWorkspace = WorkspaceEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadCurWorkspace');
static const WorkspaceEvent ReadWorkspace = WorkspaceEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadWorkspace');
static const WorkspaceEvent ReadWorkspaces = WorkspaceEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadWorkspaces');
static const WorkspaceEvent DeleteWorkspace = WorkspaceEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteWorkspace');
static const WorkspaceEvent ReadAllWorkspace = WorkspaceEvent._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadAllWorkspace');
static const WorkspaceEvent OpenWorkspace = WorkspaceEvent._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'OpenWorkspace');
static const WorkspaceEvent OpenWorkspace = WorkspaceEvent._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'OpenWorkspace');
static const WorkspaceEvent CreateApp = WorkspaceEvent._(101, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateApp');
static const WorkspaceEvent DeleteApp = WorkspaceEvent._(102, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteApp');
static const WorkspaceEvent ReadApp = WorkspaceEvent._(103, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadApp');
@ -28,9 +27,8 @@ class WorkspaceEvent extends $pb.ProtobufEnum {
static const $core.List<WorkspaceEvent> values = <WorkspaceEvent> [
CreateWorkspace,
ReadCurWorkspace,
ReadWorkspace,
ReadWorkspaces,
DeleteWorkspace,
ReadAllWorkspace,
OpenWorkspace,
CreateApp,
DeleteApp,

View File

@ -14,10 +14,9 @@ const WorkspaceEvent$json = const {
'2': const [
const {'1': 'CreateWorkspace', '2': 0},
const {'1': 'ReadCurWorkspace', '2': 1},
const {'1': 'ReadWorkspace', '2': 2},
const {'1': 'ReadWorkspaces', '2': 2},
const {'1': 'DeleteWorkspace', '2': 3},
const {'1': 'ReadAllWorkspace', '2': 4},
const {'1': 'OpenWorkspace', '2': 5},
const {'1': 'OpenWorkspace', '2': 4},
const {'1': 'CreateApp', '2': 101},
const {'1': 'DeleteApp', '2': 102},
const {'1': 'ReadApp', '2': 103},
@ -30,4 +29,4 @@ const WorkspaceEvent$json = const {
};
/// Descriptor for `WorkspaceEvent`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List workspaceEventDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIUChBSZWFkQ3VyV29ya3NwYWNlEAESEQoNUmVhZFdvcmtzcGFjZRACEhMKD0RlbGV0ZVdvcmtzcGFjZRADEhQKEFJlYWRBbGxXb3Jrc3BhY2UQBBIRCg1PcGVuV29ya3NwYWNlEAUSDQoJQ3JlYXRlQXBwEGUSDQoJRGVsZXRlQXBwEGYSCwoHUmVhZEFwcBBnEg0KCVVwZGF0ZUFwcBBoEg8KCkNyZWF0ZVZpZXcQyQESDQoIUmVhZFZpZXcQygESDwoKVXBkYXRlVmlldxDLARIPCgpEZWxldGVWaWV3EMwB');
final $typed_data.Uint8List workspaceEventDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIUChBSZWFkQ3VyV29ya3NwYWNlEAESEgoOUmVhZFdvcmtzcGFjZXMQAhITCg9EZWxldGVXb3Jrc3BhY2UQAxIRCg1PcGVuV29ya3NwYWNlEAQSDQoJQ3JlYXRlQXBwEGUSDQoJRGVsZXRlQXBwEGYSCwoHUmVhZEFwcBBnEg0KCVVwZGF0ZUFwcBBoEg8KCkNyZWF0ZVZpZXcQyQESDQoIUmVhZFZpZXcQygESDwoKVXBkYXRlVmlldxDLARIPCgpEZWxldGVWaWV3EMwB');

View File

@ -8,6 +8,7 @@ pub fn forget_rust(buf: Vec<u8>) -> *const u8 {
}
#[allow(unused_attributes)]
#[allow(dead_code)]
pub fn reclaim_rust(ptr: *mut u8, length: u32) {
unsafe {
let len: usize = length as usize;

View File

@ -89,7 +89,6 @@ pub(crate) enum InternalError {
ProtobufError(String),
UnexpectedNone(String),
DeserializeFromBytes(String),
SerializeToBytes(String),
JoinError(String),
Lock(String),
ServiceNotFound(String),
@ -103,7 +102,6 @@ impl fmt::Display for InternalError {
InternalError::ProtobufError(s) => fmt::Display::fmt(&s, f),
InternalError::UnexpectedNone(s) => fmt::Display::fmt(&s, f),
InternalError::DeserializeFromBytes(s) => fmt::Display::fmt(&s, f),
InternalError::SerializeToBytes(s) => fmt::Display::fmt(&s, f),
InternalError::JoinError(s) => fmt::Display::fmt(&s, f),
InternalError::Lock(s) => fmt::Display::fmt(&s, f),
InternalError::ServiceNotFound(s) => fmt::Display::fmt(&s, f),

View File

@ -36,5 +36,6 @@ impl DocTableSql {
Ok(doc_table)
}
#[allow(dead_code)]
pub(crate) fn delete_doc(&self, _view_id: &str) -> Result<(), DocError> { unimplemented!() }
}

View File

@ -79,7 +79,12 @@ impl HttpRequestBuilder {
}
let response = builder.send().await;
tx.send(response);
match tx.send(response) {
Ok(_) => {},
Err(e) => {
log::error!("Send http response failed: {:?}", e)
},
}
});
let response = rx.await??;
@ -104,28 +109,6 @@ impl HttpRequestBuilder {
}
}
#[allow(dead_code)]
pub async fn http_post<T1, T2>(url: &str, data: T1) -> Result<T2, ServerError>
where
T1: TryInto<Bytes, Error = ProtobufError>,
T2: TryFrom<Bytes, Error = ProtobufError>,
{
let body: Bytes = data.try_into()?;
let url = url.to_owned();
let (tx, rx) = oneshot::channel::<Result<Response, _>>();
// reqwest client is not 'Sync' by channel is.
tokio::spawn(async move {
let client = default_client();
let response = client.post(&url).body(body).send().await;
tx.send(response);
});
let response = rx.await??;
let data = get_response_data(response).await?;
Ok(T2::try_from(data)?)
}
async fn get_response_data(original: Response) -> Result<Bytes, ServerError> {
if original.status() == http::StatusCode::OK {
let bytes = original.bytes().await?;

View File

@ -8,6 +8,7 @@ lazy_static! {
}
pub struct RustStreamSender {
#[allow(dead_code)]
isolate: Option<allo_isolate::Isolate>,
}
@ -19,6 +20,7 @@ impl RustStreamSender {
self.isolate = Some(allo_isolate::Isolate::new(port));
}
#[allow(dead_code)]
fn inner_post(&self, observable_subject: ObservableSubject) -> Result<(), String> {
match self.isolate {
Some(ref isolate) => {

View File

@ -7,8 +7,8 @@ edition = "2018"
[dependencies]
flowy-dispatch = { path = "../flowy-dispatch", features = ["use_tracing"]}
flowy-log = { path = "../flowy-log" }
#flowy-log = { path = "../flowy-log", features = ["use_bunyan"] }
#flowy-log = { path = "../flowy-log" }
flowy-log = { path = "../flowy-log", features = ["use_bunyan"] }
flowy-user = { path = "../flowy-user" }
flowy-infra = { path = "../flowy-infra" }
flowy-workspace = { path = "../flowy-workspace" }
@ -19,7 +19,6 @@ log = "0.4.14"
futures-core = { version = "0.3", default-features = false }
color-eyre = { version = "0.5", default-features = false }
bytes = "1.0"
[dev-dependencies]
serde = { version = "1.0", features = ["derive"] }
bincode = { version = "1.3"}

View File

@ -1,56 +1,4 @@
use bytes::Bytes;
use flowy_dispatch::prelude::{
DispatchError,
DispatchFuture,
EventDispatch,
ModuleRequest,
ToBytes,
};
use flowy_user::{
errors::{ErrorBuilder, UserErrCode, UserError},
prelude::UserWorkspaceController,
};
use flowy_workspace::{
entities::workspace::{CreateWorkspaceRequest, Workspace},
event::WorkspaceEvent::CreateWorkspace,
};
use flowy_user::services::workspace::UserWorkspaceController;
pub struct UserWorkspaceControllerImpl {}
impl UserWorkspaceController for UserWorkspaceControllerImpl {
fn create_workspace(
&self,
name: &str,
desc: &str,
user_id: &str,
) -> DispatchFuture<Result<String, UserError>> {
log::info!("Create new workspace: {:?}", name);
let payload: Bytes = CreateWorkspaceRequest {
name: name.to_string(),
desc: desc.to_string(),
user_id: user_id.to_string(),
}
.into_bytes()
.unwrap();
let request = ModuleRequest::new(CreateWorkspace).payload(payload);
DispatchFuture {
fut: Box::pin(async move {
let result = EventDispatch::async_send(request)
.await
.parse::<Workspace, DispatchError>()
.map_err(|e| {
ErrorBuilder::new(UserErrCode::CreateDefaultWorkspaceFailed)
.error(e)
.build()
})?;
let workspace = result.map_err(|e| {
ErrorBuilder::new(UserErrCode::CreateDefaultWorkspaceFailed)
.error(e)
.build()
})?;
Ok(workspace.id)
}),
}
}
}
impl UserWorkspaceController for UserWorkspaceControllerImpl {}

View File

@ -17,13 +17,15 @@ pub type SingleUserTestBuilder = TestBuilder<FixedUserTester<WorkspaceError>>;
impl SingleUserTestBuilder {
pub fn new() -> Self {
let mut builder = TestBuilder::test(Box::new(FixedUserTester::<WorkspaceError>::new()));
builder.login_if_need();
let user_id = builder.user_detail.as_ref().unwrap().id.clone();
let _ = create_default_workspace_if_need(&user_id);
builder.setup_default_workspace();
builder
}
pub fn setup_default_workspace(&mut self) {
self.login_if_need();
let user_id = self.user_detail.as_ref().unwrap().id.clone();
let _ = create_default_workspace_if_need(&user_id);
}
}
pub type UserTestBuilder = TestBuilder<RandomUserTester<UserError>>;
impl UserTestBuilder {

View File

@ -15,6 +15,7 @@ use std::{
hash::Hash,
};
#[allow(dead_code)]
pub struct TesterContext {
request: Option<ModuleRequest>,
response: Option<EventResponse>,

View File

@ -34,6 +34,7 @@ impl UserSessionConfig {
pub struct UserSession {
database: UserDB,
config: UserSessionConfig,
#[allow(dead_code)]
workspace_controller: Arc<dyn UserWorkspaceController + Send + Sync>,
server: Arc<dyn UserServerAPI + Send + Sync>,
user_id: RwLock<Option<String>>,

View File

@ -1,11 +1 @@
use crate::errors::UserError;
use flowy_dispatch::prelude::DispatchFuture;
pub trait UserWorkspaceController {
fn create_workspace(
&self,
name: &str,
desc: &str,
user_id: &str,
) -> DispatchFuture<Result<String, UserError>>;
}
pub trait UserWorkspaceController {}

View File

@ -4,6 +4,7 @@ use std::convert::TryInto;
#[derive(Default, ProtoBuf)]
pub struct QueryWorkspaceRequest {
// return all workspace if workspace_id is None
#[pb(index = 1, one_of)]
pub workspace_id: Option<String>,

View File

@ -12,21 +12,17 @@ pub enum WorkspaceEvent {
#[event(output = "Workspace")]
ReadCurWorkspace = 1,
#[display(fmt = "ReadWorkspace")]
#[event(input = "QueryWorkspaceRequest", output = "Workspace")]
ReadWorkspace = 2,
#[display(fmt = "ReadWorkspaces")]
#[event(input = "QueryWorkspaceRequest", output = "RepeatedWorkspace")]
ReadWorkspaces = 2,
#[display(fmt = "DeleteWorkspace")]
#[event(input = "DeleteWorkspaceRequest")]
DeleteWorkspace = 3,
#[display(fmt = "ReadAllWorkspace")]
#[event(output = "RepeatedWorkspace")]
ReadAllWorkspace = 4,
#[display(fmt = "OpenWorkspace")]
#[event(input = "QueryWorkspaceRequest", output = "Workspace")]
OpenWorkspace = 5,
OpenWorkspace = 4,
#[display(fmt = "CreateApp")]
#[event(input = "CreateAppRequest", output = "App")]

View File

@ -26,7 +26,7 @@ pub async fn read_cur_workspace(
}
#[tracing::instrument(name = "read_workspace", skip(data, controller))]
pub async fn read_workspace(
pub async fn read_workspaces(
data: Data<QueryWorkspaceRequest>,
controller: Unit<Arc<WorkspaceController>>,
) -> DataResult<RepeatedWorkspace, WorkspaceError> {
@ -49,12 +49,3 @@ pub async fn open_workspace(
},
}
}
#[tracing::instrument(name = "get_all_workspaces", skip(controller))]
pub async fn read_all_workspaces(
controller: Unit<Arc<WorkspaceController>>,
) -> DataResult<RepeatedWorkspace, WorkspaceError> {
let workspaces = controller.read_workspaces_belong_to_user().await?;
data_result(RepeatedWorkspace { items: workspaces })
}

View File

@ -45,10 +45,9 @@ pub fn create(user: Arc<dyn WorkspaceUser>, database: Arc<dyn WorkspaceDatabase>
.data(view_controller);
module = module
.event(WorkspaceEvent::ReadAllWorkspace, read_all_workspaces)
.event(WorkspaceEvent::CreateWorkspace, create_workspace)
.event(WorkspaceEvent::ReadCurWorkspace, read_cur_workspace)
.event(WorkspaceEvent::ReadWorkspace, read_workspace)
.event(WorkspaceEvent::ReadWorkspaces, read_workspaces)
.event(WorkspaceEvent::OpenWorkspace, open_workspace);
module = module

View File

@ -27,10 +27,9 @@
pub enum WorkspaceEvent {
CreateWorkspace = 0,
ReadCurWorkspace = 1,
ReadWorkspace = 2,
ReadWorkspaces = 2,
DeleteWorkspace = 3,
ReadAllWorkspace = 4,
OpenWorkspace = 5,
OpenWorkspace = 4,
CreateApp = 101,
DeleteApp = 102,
ReadApp = 103,
@ -50,10 +49,9 @@ impl ::protobuf::ProtobufEnum for WorkspaceEvent {
match value {
0 => ::std::option::Option::Some(WorkspaceEvent::CreateWorkspace),
1 => ::std::option::Option::Some(WorkspaceEvent::ReadCurWorkspace),
2 => ::std::option::Option::Some(WorkspaceEvent::ReadWorkspace),
2 => ::std::option::Option::Some(WorkspaceEvent::ReadWorkspaces),
3 => ::std::option::Option::Some(WorkspaceEvent::DeleteWorkspace),
4 => ::std::option::Option::Some(WorkspaceEvent::ReadAllWorkspace),
5 => ::std::option::Option::Some(WorkspaceEvent::OpenWorkspace),
4 => ::std::option::Option::Some(WorkspaceEvent::OpenWorkspace),
101 => ::std::option::Option::Some(WorkspaceEvent::CreateApp),
102 => ::std::option::Option::Some(WorkspaceEvent::DeleteApp),
103 => ::std::option::Option::Some(WorkspaceEvent::ReadApp),
@ -70,9 +68,8 @@ impl ::protobuf::ProtobufEnum for WorkspaceEvent {
static values: &'static [WorkspaceEvent] = &[
WorkspaceEvent::CreateWorkspace,
WorkspaceEvent::ReadCurWorkspace,
WorkspaceEvent::ReadWorkspace,
WorkspaceEvent::ReadWorkspaces,
WorkspaceEvent::DeleteWorkspace,
WorkspaceEvent::ReadAllWorkspace,
WorkspaceEvent::OpenWorkspace,
WorkspaceEvent::CreateApp,
WorkspaceEvent::DeleteApp,
@ -110,44 +107,41 @@ impl ::protobuf::reflect::ProtobufValue for WorkspaceEvent {
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x0bevent.proto*\x88\x02\n\x0eWorkspaceEvent\x12\x13\n\x0fCreateWorksp\
ace\x10\0\x12\x14\n\x10ReadCurWorkspace\x10\x01\x12\x11\n\rReadWorkspace\
\x10\x02\x12\x13\n\x0fDeleteWorkspace\x10\x03\x12\x14\n\x10ReadAllWorksp\
ace\x10\x04\x12\x11\n\rOpenWorkspace\x10\x05\x12\r\n\tCreateApp\x10e\x12\
\r\n\tDeleteApp\x10f\x12\x0b\n\x07ReadApp\x10g\x12\r\n\tUpdateApp\x10h\
\x12\x0f\n\nCreateView\x10\xc9\x01\x12\r\n\x08ReadView\x10\xca\x01\x12\
\x0f\n\nUpdateView\x10\xcb\x01\x12\x0f\n\nDeleteView\x10\xcc\x01J\xe8\
\x04\n\x06\x12\x04\0\0\x11\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\
\x05\0\x12\x04\x02\0\x11\x01\n\n\n\x03\x05\0\x01\x12\x03\x02\x05\x13\n\
\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x04\x18\n\x0c\n\x05\x05\0\x02\0\x01\
\x12\x03\x03\x04\x13\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x03\x16\x17\n\
\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\x04\x19\n\x0c\n\x05\x05\0\x02\x01\
\x01\x12\x03\x04\x04\x14\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x04\x17\
\x18\n\x0b\n\x04\x05\0\x02\x02\x12\x03\x05\x04\x16\n\x0c\n\x05\x05\0\x02\
\x02\x01\x12\x03\x05\x04\x11\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\x05\
\x14\x15\n\x0b\n\x04\x05\0\x02\x03\x12\x03\x06\x04\x18\n\x0c\n\x05\x05\0\
\x02\x03\x01\x12\x03\x06\x04\x13\n\x0c\n\x05\x05\0\x02\x03\x02\x12\x03\
\x06\x16\x17\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x07\x04\x19\n\x0c\n\x05\
\x05\0\x02\x04\x01\x12\x03\x07\x04\x14\n\x0c\n\x05\x05\0\x02\x04\x02\x12\
\x03\x07\x17\x18\n\x0b\n\x04\x05\0\x02\x05\x12\x03\x08\x04\x16\n\x0c\n\
\x05\x05\0\x02\x05\x01\x12\x03\x08\x04\x11\n\x0c\n\x05\x05\0\x02\x05\x02\
\x12\x03\x08\x14\x15\n\x0b\n\x04\x05\0\x02\x06\x12\x03\t\x04\x14\n\x0c\n\
\x05\x05\0\x02\x06\x01\x12\x03\t\x04\r\n\x0c\n\x05\x05\0\x02\x06\x02\x12\
\x03\t\x10\x13\n\x0b\n\x04\x05\0\x02\x07\x12\x03\n\x04\x14\n\x0c\n\x05\
\x05\0\x02\x07\x01\x12\x03\n\x04\r\n\x0c\n\x05\x05\0\x02\x07\x02\x12\x03\
\n\x10\x13\n\x0b\n\x04\x05\0\x02\x08\x12\x03\x0b\x04\x12\n\x0c\n\x05\x05\
\0\x02\x08\x01\x12\x03\x0b\x04\x0b\n\x0c\n\x05\x05\0\x02\x08\x02\x12\x03\
\x0b\x0e\x11\n\x0b\n\x04\x05\0\x02\t\x12\x03\x0c\x04\x14\n\x0c\n\x05\x05\
\0\x02\t\x01\x12\x03\x0c\x04\r\n\x0c\n\x05\x05\0\x02\t\x02\x12\x03\x0c\
\x10\x13\n\x0b\n\x04\x05\0\x02\n\x12\x03\r\x04\x15\n\x0c\n\x05\x05\0\x02\
\n\x01\x12\x03\r\x04\x0e\n\x0c\n\x05\x05\0\x02\n\x02\x12\x03\r\x11\x14\n\
\x0b\n\x04\x05\0\x02\x0b\x12\x03\x0e\x04\x13\n\x0c\n\x05\x05\0\x02\x0b\
\x01\x12\x03\x0e\x04\x0c\n\x0c\n\x05\x05\0\x02\x0b\x02\x12\x03\x0e\x0f\
\x12\n\x0b\n\x04\x05\0\x02\x0c\x12\x03\x0f\x04\x15\n\x0c\n\x05\x05\0\x02\
\x0c\x01\x12\x03\x0f\x04\x0e\n\x0c\n\x05\x05\0\x02\x0c\x02\x12\x03\x0f\
\x11\x14\n\x0b\n\x04\x05\0\x02\r\x12\x03\x10\x04\x15\n\x0c\n\x05\x05\0\
\x02\r\x01\x12\x03\x10\x04\x0e\n\x0c\n\x05\x05\0\x02\r\x02\x12\x03\x10\
\x11\x14b\x06proto3\
\n\x0bevent.proto*\xf3\x01\n\x0eWorkspaceEvent\x12\x13\n\x0fCreateWorksp\
ace\x10\0\x12\x14\n\x10ReadCurWorkspace\x10\x01\x12\x12\n\x0eReadWorkspa\
ces\x10\x02\x12\x13\n\x0fDeleteWorkspace\x10\x03\x12\x11\n\rOpenWorkspac\
e\x10\x04\x12\r\n\tCreateApp\x10e\x12\r\n\tDeleteApp\x10f\x12\x0b\n\x07R\
eadApp\x10g\x12\r\n\tUpdateApp\x10h\x12\x0f\n\nCreateView\x10\xc9\x01\
\x12\r\n\x08ReadView\x10\xca\x01\x12\x0f\n\nUpdateView\x10\xcb\x01\x12\
\x0f\n\nDeleteView\x10\xcc\x01J\xbf\x04\n\x06\x12\x04\0\0\x10\x01\n\x08\
\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x05\0\x12\x04\x02\0\x10\x01\n\n\n\
\x03\x05\0\x01\x12\x03\x02\x05\x13\n\x0b\n\x04\x05\0\x02\0\x12\x03\x03\
\x04\x18\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x03\x04\x13\n\x0c\n\x05\x05\
\0\x02\0\x02\x12\x03\x03\x16\x17\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\
\x04\x19\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x04\x04\x14\n\x0c\n\x05\
\x05\0\x02\x01\x02\x12\x03\x04\x17\x18\n\x0b\n\x04\x05\0\x02\x02\x12\x03\
\x05\x04\x17\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\x05\x04\x12\n\x0c\n\
\x05\x05\0\x02\x02\x02\x12\x03\x05\x15\x16\n\x0b\n\x04\x05\0\x02\x03\x12\
\x03\x06\x04\x18\n\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\x06\x04\x13\n\x0c\
\n\x05\x05\0\x02\x03\x02\x12\x03\x06\x16\x17\n\x0b\n\x04\x05\0\x02\x04\
\x12\x03\x07\x04\x16\n\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x07\x04\x11\n\
\x0c\n\x05\x05\0\x02\x04\x02\x12\x03\x07\x14\x15\n\x0b\n\x04\x05\0\x02\
\x05\x12\x03\x08\x04\x14\n\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x08\x04\r\
\n\x0c\n\x05\x05\0\x02\x05\x02\x12\x03\x08\x10\x13\n\x0b\n\x04\x05\0\x02\
\x06\x12\x03\t\x04\x14\n\x0c\n\x05\x05\0\x02\x06\x01\x12\x03\t\x04\r\n\
\x0c\n\x05\x05\0\x02\x06\x02\x12\x03\t\x10\x13\n\x0b\n\x04\x05\0\x02\x07\
\x12\x03\n\x04\x12\n\x0c\n\x05\x05\0\x02\x07\x01\x12\x03\n\x04\x0b\n\x0c\
\n\x05\x05\0\x02\x07\x02\x12\x03\n\x0e\x11\n\x0b\n\x04\x05\0\x02\x08\x12\
\x03\x0b\x04\x14\n\x0c\n\x05\x05\0\x02\x08\x01\x12\x03\x0b\x04\r\n\x0c\n\
\x05\x05\0\x02\x08\x02\x12\x03\x0b\x10\x13\n\x0b\n\x04\x05\0\x02\t\x12\
\x03\x0c\x04\x15\n\x0c\n\x05\x05\0\x02\t\x01\x12\x03\x0c\x04\x0e\n\x0c\n\
\x05\x05\0\x02\t\x02\x12\x03\x0c\x11\x14\n\x0b\n\x04\x05\0\x02\n\x12\x03\
\r\x04\x13\n\x0c\n\x05\x05\0\x02\n\x01\x12\x03\r\x04\x0c\n\x0c\n\x05\x05\
\0\x02\n\x02\x12\x03\r\x0f\x12\n\x0b\n\x04\x05\0\x02\x0b\x12\x03\x0e\x04\
\x15\n\x0c\n\x05\x05\0\x02\x0b\x01\x12\x03\x0e\x04\x0e\n\x0c\n\x05\x05\0\
\x02\x0b\x02\x12\x03\x0e\x11\x14\n\x0b\n\x04\x05\0\x02\x0c\x12\x03\x0f\
\x04\x15\n\x0c\n\x05\x05\0\x02\x0c\x01\x12\x03\x0f\x04\x0e\n\x0c\n\x05\
\x05\0\x02\x0c\x02\x12\x03\x0f\x11\x14b\x06proto3\
";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -3,10 +3,9 @@ syntax = "proto3";
enum WorkspaceEvent {
CreateWorkspace = 0;
ReadCurWorkspace = 1;
ReadWorkspace = 2;
ReadWorkspaces = 2;
DeleteWorkspace = 3;
ReadAllWorkspace = 4;
OpenWorkspace = 5;
OpenWorkspace = 4;
CreateApp = 101;
DeleteApp = 102;
ReadApp = 103;

View File

@ -13,6 +13,7 @@ use std::sync::Arc;
pub struct AppController {
user: Arc<dyn WorkspaceUser>,
sql: Arc<AppTableSql>,
#[allow(dead_code)]
view_controller: Arc<ViewController>,
}

View File

@ -94,18 +94,6 @@ impl WorkspaceController {
Ok(RepeatedWorkspace { items: workspaces })
}
pub async fn read_workspaces_belong_to_user(&self) -> Result<Vec<Workspace>, WorkspaceError> {
let user_id = self.user.user_id()?;
let workspace = self
.sql
.read_workspaces_belong_to_user(&user_id)?
.into_iter()
.map(|workspace_table| workspace_table.into())
.collect::<Vec<Workspace>>();
Ok(workspace)
}
pub async fn read_cur_workspace(&self) -> Result<Workspace, WorkspaceError> {
let workspace_id = get_current_workspace()?;
let mut repeated_workspace = self.read_workspaces(Some(workspace_id.clone())).await?;

View File

@ -73,19 +73,4 @@ impl WorkspaceSql {
Ok(apps)
}
pub(crate) fn read_workspaces_belong_to_user(
&self,
user_id: &str,
) -> Result<Vec<WorkspaceTable>, WorkspaceError> {
let conn = self.database.db_connection()?;
let workspaces = conn.immediate_transaction::<_, WorkspaceError, _>(|| {
let workspaces = dsl::workspace_table
.filter(workspace_table::user_id.eq(user_id))
.load::<WorkspaceTable>(&*(conn))?;
Ok(workspaces)
})?;
Ok(workspaces)
}
}

View File

@ -32,7 +32,7 @@ pub fn create_workspace(name: &str, desc: &str) -> (String, Workspace) {
pub fn read_workspaces(request: QueryWorkspaceRequest) -> Option<Workspace> {
let mut repeated_workspace = SingleUserTestBuilder::new()
.event(ReadWorkspace)
.event(ReadWorkspaces)
.request(request)
.sync_send()
.parse::<RepeatedWorkspace>();

View File

@ -13,27 +13,20 @@ use flowy_workspace::{
#[test]
fn workspace_create_success() { let _ = create_workspace("First workspace", ""); }
#[test]
fn workspace_get_success() {
let builder = SingleUserTestBuilder::new();
let _workspaces = SingleUserTestBuilder::new()
.event(ReadAllWorkspace)
.sync_send()
.parse::<RepeatedWorkspace>();
let workspace = builder
.event(ReadCurWorkspace)
.sync_send()
.parse::<Workspace>();
dbg!(&workspace);
}
#[test]
fn workspace_read_all_success() {
let (user_id, _) = create_workspace(
"Workspace A",
"workspace_create_and_then_get_workspace_success",
);
let request = QueryWorkspaceRequest {
workspace_id: None,
user_id,
};
let workspaces = SingleUserTestBuilder::new()
.event(ReadAllWorkspace)
.event(ReadWorkspaces)
.request(request)
.sync_send()
.parse::<RepeatedWorkspace>();