From 76e73ea17ba9bcfd4673e08d4afc0f276c379c27 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 30 Aug 2021 16:18:58 +0800 Subject: [PATCH] [fluuter]: create & choose workspace after login --- app_flowy/lib/user/domain/i_auth.dart | 2 +- .../lib/user/infrastructure/i_auth_impl.dart | 13 +- .../presentation/sign_in/sign_in_screen.dart | 2 +- app_flowy/lib/welcome/domain/i_welcome.dart | 2 +- .../infrastructure/i_welcome_impl.dart | 40 +- .../welcome/presentation/welcome_screen.dart | 3 +- .../workspace/workspace_list_bloc.dart | 81 ++ .../workspace_list_bloc.freezed.dart | 732 ++++++++++++++++++ .../infrastructure/deps_resolver.dart | 20 +- .../infrastructure/i_workspace_impl.dart | 2 +- .../infrastructure/repos/user_repo.dart | 34 +- .../infrastructure/repos/workspace_repo.dart | 37 +- .../presentation/app/view_list_page.dart | 1 + .../presentation/home/home_screen.dart | 4 +- .../presentation/widgets/menu/menu_page.dart | 22 +- .../workspace/workspace_select_screen.dart | 236 ++++++ .../flowy_sdk/lib/dispatch/code_gen.dart | 31 +- .../flowy_sdk/lib/dispatch/dispatch.dart | 9 +- .../flowy-workspace/event.pbenum.dart | 8 +- .../flowy-workspace/event.pbjson.dart | 7 +- rust-lib/dart-ffi/src/c.rs | 1 + rust-lib/flowy-dispatch/src/errors/errors.rs | 2 - .../src/sql_tables/doc/doc_sql.rs | 1 + rust-lib/flowy-net/src/request/request.rs | 29 +- .../src/dart/stream_sender.rs | 2 + rust-lib/flowy-sdk/Cargo.toml | 5 +- .../src/deps_resolve/user_deps_impl.rs | 56 +- rust-lib/flowy-test/src/builder.rs | 12 +- rust-lib/flowy-test/src/tester.rs | 1 + .../src/services/user/user_session.rs | 1 + .../src/services/workspace/action.rs | 12 +- .../src/entities/workspace/workspace_query.rs | 1 + rust-lib/flowy-workspace/src/event.rs | 12 +- .../src/handlers/workspace_handler.rs | 11 +- rust-lib/flowy-workspace/src/module.rs | 3 +- .../src/protobuf/model/event.rs | 86 +- .../src/protobuf/proto/event.proto | 5 +- .../src/services/app_controller.rs | 1 + .../src/services/workspace_controller.rs | 12 - .../src/sql_tables/workspace/workspace_sql.rs | 15 - .../flowy-workspace/tests/event/helper.rs | 2 +- .../tests/event/workspace_test.rs | 29 +- 42 files changed, 1303 insertions(+), 282 deletions(-) create mode 100644 app_flowy/lib/workspace/application/workspace/workspace_list_bloc.dart create mode 100644 app_flowy/lib/workspace/application/workspace/workspace_list_bloc.freezed.dart create mode 100644 app_flowy/lib/workspace/presentation/workspace/workspace_select_screen.dart diff --git a/app_flowy/lib/user/domain/i_auth.dart b/app_flowy/lib/user/domain/i_auth.dart index a4fe95d20e..30d13173b2 100644 --- a/app_flowy/lib/user/domain/i_auth.dart +++ b/app_flowy/lib/user/domain/i_auth.dart @@ -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); } diff --git a/app_flowy/lib/user/infrastructure/i_auth_impl.dart b/app_flowy/lib/user/infrastructure/i_auth_impl.dart index 5f660e01e2..e89f4aca01 100644 --- a/app_flowy/lib/user/infrastructure/i_auth_impl.dart +++ b/app_flowy/lib/user/infrastructure/i_auth_impl.dart @@ -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 diff --git a/app_flowy/lib/user/presentation/sign_in/sign_in_screen.dart b/app_flowy/lib/user/presentation/sign_in/sign_in_screen.dart index fd0b6beafa..ddb88b4a3a 100644 --- a/app_flowy/lib/user/presentation/sign_in/sign_in_screen.dart +++ b/app_flowy/lib/user/presentation/sign_in/sign_in_screen.dart @@ -36,7 +36,7 @@ class SignInScreen extends StatelessWidget { void _handleSuccessOrFail( Either result, BuildContext context) { result.fold( - (user) => router.showHomeScreen(context, user), + (user) => router.showWorkspaceSelectScreen(context, user), (error) => _showErrorMessage(context, error.msg), ); } diff --git a/app_flowy/lib/welcome/domain/i_welcome.dart b/app_flowy/lib/welcome/domain/i_welcome.dart index fb2c645770..7fe5266489 100644 --- a/app_flowy/lib/welcome/domain/i_welcome.dart +++ b/app_flowy/lib/welcome/domain/i_welcome.dart @@ -9,5 +9,5 @@ abstract class IWelcomeAuth { abstract class IWelcomeRoute { Widget pushSignInScreen(); - Widget pushHomeScreen(UserDetail userDetail); + Future pushHomeScreen(BuildContext context, UserDetail userDetail); } diff --git a/app_flowy/lib/welcome/infrastructure/i_welcome_impl.dart b/app_flowy/lib/welcome/infrastructure/i_welcome_impl.dart index e6b8e60f3c..8f08467fce 100644 --- a/app_flowy/lib/welcome/infrastructure/i_welcome_impl.dart +++ b/app_flowy/lib/welcome/infrastructure/i_welcome_impl.dart @@ -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 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()); } + + void _pushToScreen(BuildContext context, Widget screen) { + Navigator.push( + context, + PageRoutes.fade( + () => screen, RouteDurations.slow.inMilliseconds * .001)); + } } diff --git a/app_flowy/lib/welcome/presentation/welcome_screen.dart b/app_flowy/lib/welcome/presentation/welcome_screen.dart index 82fc4cfcfa..dad0d78248 100644 --- a/app_flowy/lib/welcome/presentation/welcome_screen.dart +++ b/app_flowy/lib/welcome/presentation/welcome_screen.dart @@ -41,8 +41,7 @@ class WelcomeScreen extends StatelessWidget { } void _handleAuthenticated(BuildContext context, Authenticated result) { - _pushToScreen( - context, getIt().pushHomeScreen(result.userDetail)); + getIt().pushHomeScreen(context, result.userDetail); } void _handleUnauthenticated(BuildContext context, Unauthenticated result) { diff --git a/app_flowy/lib/workspace/application/workspace/workspace_list_bloc.dart b/app_flowy/lib/workspace/application/workspace/workspace_list_bloc.dart new file mode 100644 index 0000000000..b12f1c9b63 --- /dev/null +++ b/app_flowy/lib/workspace/application/workspace/workspace_list_bloc.dart @@ -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 { + UserRepo repo; + WorkspaceListBloc(this.repo) : super(WorkspaceListState.initial()); + + @override + Stream 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 _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 _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 _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 workspaces, + required Either successOrFailure, + }) = _WorkspaceListState; + + factory WorkspaceListState.initial() => WorkspaceListState( + isLoading: false, + workspaces: List.empty(), + successOrFailure: left(unit), + ); +} diff --git a/app_flowy/lib/workspace/application/workspace/workspace_list_bloc.freezed.dart b/app_flowy/lib/workspace/application/workspace/workspace_list_bloc.freezed.dart new file mode 100644 index 0000000000..c9ba029082 --- /dev/null +++ b/app_flowy/lib/workspace/application/workspace/workspace_list_bloc.freezed.dart @@ -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 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({ + 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 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({ + 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 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({ + 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 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({ + 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 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({ + 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 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({ + 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 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 get copyWith => + _$CreateWorkspaceCopyWithImpl(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + 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 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({ + 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 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 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 get copyWith => + _$OpenWorkspaceCopyWithImpl(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + 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 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({ + 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 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 get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +class _$WorkspaceListStateTearOff { + const _$WorkspaceListStateTearOff(); + + _WorkspaceListState call( + {required bool isLoading, + required List workspaces, + required Either successOrFailure}) { + return _WorkspaceListState( + isLoading: isLoading, + workspaces: workspaces, + successOrFailure: successOrFailure, + ); + } +} + +/// @nodoc +const $WorkspaceListState = _$WorkspaceListStateTearOff(); + +/// @nodoc +mixin _$WorkspaceListState { + bool get isLoading => throw _privateConstructorUsedError; + List get workspaces => throw _privateConstructorUsedError; + Either get successOrFailure => + throw _privateConstructorUsedError; + + @JsonKey(ignore: true) + $WorkspaceListStateCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $WorkspaceListStateCopyWith<$Res> { + factory $WorkspaceListStateCopyWith( + WorkspaceListState value, $Res Function(WorkspaceListState) then) = + _$WorkspaceListStateCopyWithImpl<$Res>; + $Res call( + {bool isLoading, + List workspaces, + Either 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, + successOrFailure: successOrFailure == freezed + ? _value.successOrFailure + : successOrFailure // ignore: cast_nullable_to_non_nullable + as Either, + )); + } +} + +/// @nodoc +abstract class _$WorkspaceListStateCopyWith<$Res> + implements $WorkspaceListStateCopyWith<$Res> { + factory _$WorkspaceListStateCopyWith( + _WorkspaceListState value, $Res Function(_WorkspaceListState) then) = + __$WorkspaceListStateCopyWithImpl<$Res>; + @override + $Res call( + {bool isLoading, + List workspaces, + Either 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, + successOrFailure: successOrFailure == freezed + ? _value.successOrFailure + : successOrFailure // ignore: cast_nullable_to_non_nullable + as Either, + )); + } +} + +/// @nodoc + +class _$_WorkspaceListState implements _WorkspaceListState { + const _$_WorkspaceListState( + {required this.isLoading, + required this.workspaces, + required this.successOrFailure}); + + @override + final bool isLoading; + @override + final List workspaces; + @override + final Either 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 workspaces, + required Either successOrFailure}) = + _$_WorkspaceListState; + + @override + bool get isLoading => throw _privateConstructorUsedError; + @override + List get workspaces => throw _privateConstructorUsedError; + @override + Either get successOrFailure => + throw _privateConstructorUsedError; + @override + @JsonKey(ignore: true) + _$WorkspaceListStateCopyWith<_WorkspaceListState> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/app_flowy/lib/workspace/infrastructure/deps_resolver.dart b/app_flowy/lib/workspace/infrastructure/deps_resolver.dart index 47f43b531b..ac6cea5fec 100644 --- a/app_flowy/lib/workspace/infrastructure/deps_resolver.dart +++ b/app_flowy/lib/workspace/infrastructure/deps_resolver.dart @@ -37,10 +37,12 @@ class HomeDepsResolver { (appId, _) => IAppWatchImpl(repo: AppWatchRepository(appId: appId))); //workspace - getIt.registerFactoryParam( - (user, _) => IWorkspaceImpl(repo: WorkspaceRepo(user: user))); - getIt.registerFactoryParam( - (user, _) => IWorkspaceWatchImpl(repo: WorkspaceWatchRepo(user: user))); + getIt.registerFactoryParam( + (user, workspaceId) => IWorkspaceImpl( + repo: WorkspaceRepo(user: user, workspaceId: workspaceId))); + getIt.registerFactoryParam( + (user, workspaceId) => IWorkspaceWatchImpl( + repo: WorkspaceWatchRepo(user: user, workspaceId: workspaceId))); // View getIt.registerFactoryParam( @@ -59,10 +61,12 @@ class HomeDepsResolver { (user, _) => IUserWatchImpl(repo: UserWatchRepo(user: user))); //Menu Bloc - getIt.registerFactoryParam( - (user, _) => MenuBloc(getIt(param1: user))); - getIt.registerFactoryParam( - (user, _) => MenuWatchBloc(getIt(param1: user))); + getIt.registerFactoryParam( + (user, workspaceId) => + MenuBloc(getIt(param1: user, param2: workspaceId))); + getIt.registerFactoryParam( + (user, workspaceId) => MenuWatchBloc( + getIt(param1: user, param2: workspaceId))); getIt.registerFactoryParam( (user, _) => MenuUserBloc(getIt(param1: user))); diff --git a/app_flowy/lib/workspace/infrastructure/i_workspace_impl.dart b/app_flowy/lib/workspace/infrastructure/i_workspace_impl.dart index 08dd8392cf..42a0971697 100644 --- a/app_flowy/lib/workspace/infrastructure/i_workspace_impl.dart +++ b/app_flowy/lib/workspace/infrastructure/i_workspace_impl.dart @@ -20,7 +20,7 @@ class IWorkspaceImpl extends IWorkspace { @override Future, 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), diff --git a/app_flowy/lib/workspace/infrastructure/repos/user_repo.dart b/app_flowy/lib/workspace/infrastructure/repos/user_repo.dart index 7c7c354202..857b5a336d 100644 --- a/app_flowy/lib/workspace/infrastructure/repos/user_repo.dart +++ b/app_flowy/lib/workspace/infrastructure/repos/user_repo.dart @@ -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, 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> 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> 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), ); }); } diff --git a/app_flowy/lib/workspace/infrastructure/repos/workspace_repo.dart b/app_flowy/lib/workspace/infrastructure/repos/workspace_repo.dart index 2f1af36be7..d1db04cee8 100644 --- a/app_flowy/lib/workspace/infrastructure/repos/workspace_repo.dart +++ b/app_flowy/lib/workspace/infrastructure/repos/workspace_repo.dart @@ -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> createApp(String appName, String desc) { @@ -36,16 +39,22 @@ class WorkspaceRepo { }); } - Future> getWorkspace( - {bool readApps = false}) { + Future> 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)), diff --git a/app_flowy/lib/workspace/presentation/app/view_list_page.dart b/app_flowy/lib/workspace/presentation/app/view_list_page.dart index adf1d9deb2..3cff97b2e5 100644 --- a/app_flowy/lib/workspace/presentation/app/view_list_page.dart +++ b/app_flowy/lib/workspace/presentation/app/view_list_page.dart @@ -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( create: (_) => ViewListNotifier( Provider.of( diff --git a/app_flowy/lib/workspace/presentation/home/home_screen.dart b/app_flowy/lib/workspace/presentation/home/home_screen.dart index f641833d53..f135f7d160 100644 --- a/app_flowy/lib/workspace/presentation/home/home_screen.dart +++ b/app_flowy/lib/workspace/presentation/home/home_screen.dart @@ -15,7 +15,8 @@ import 'home_layout.dart'; class HomeScreen extends StatelessWidget { static GlobalKey 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); diff --git a/app_flowy/lib/workspace/presentation/widgets/menu/menu_page.dart b/app_flowy/lib/workspace/presentation/widgets/menu/menu_page.dart index 2a58612c74..b03125d1f4 100644 --- a/app_flowy/lib/workspace/presentation/widgets/menu/menu_page.dart +++ b/app_flowy/lib/workspace/presentation/widgets/menu/menu_page.dart @@ -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( create: (context) => - getIt(param1: user)..add(const MenuEvent.initial())), + getIt(param1: user, param2: workspaceId) + ..add(const MenuEvent.initial())), BlocProvider( - create: (context) => getIt(param1: user) - ..add(const MenuWatchEvent.started())), + create: (context) => + getIt(param1: user, param2: workspaceId) + ..add(const MenuWatchEvent.started())), ], child: MultiBlocListener( listeners: [ diff --git a/app_flowy/lib/workspace/presentation/workspace/workspace_select_screen.dart b/app_flowy/lib/workspace/presentation/workspace/workspace_select_screen.dart new file mode 100644 index 0000000000..e6a3f61f8c --- /dev/null +++ b/app_flowy/lib/workspace/presentation/workspace/workspace_select_screen.dart @@ -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( + 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() + .add(const WorkspaceListEvent.createWorkspace("workspace", "")); + }, + ), + ); + } + + Widget _renderList(List 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() + .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 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(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 { +// UserRepo repo; +// WorkspaceListBloc(this.repo) : super(WorkspaceListState.initial()); + +// @override +// Stream mapEventToState( +// WorkspaceListEvent event, +// ) async* { +// yield* event.map( +// initial: (e) async* { +// yield* _fetchWorkspaces(); +// }, +// ); +// } + +// Stream _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 workspaces, +// required Either 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( +// 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(), +// ); +// }, +// ), +// ); +// } +// } diff --git a/app_flowy/packages/flowy_sdk/lib/dispatch/code_gen.dart b/app_flowy/packages/flowy_sdk/lib/dispatch/code_gen.dart index 944c2820c0..3530e3146a 100644 --- a/app_flowy/packages/flowy_sdk/lib/dispatch/code_gen.dart +++ b/app_flowy/packages/flowy_sdk/lib/dispatch/code_gen.dart @@ -33,18 +33,18 @@ class WorkspaceEventReadCurWorkspace { } } -class WorkspaceEventReadWorkspace { +class WorkspaceEventReadWorkspaces { QueryWorkspaceRequest request; - WorkspaceEventReadWorkspace(this.request); + WorkspaceEventReadWorkspaces(this.request); - Future> send() { + Future> 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> send() { - final request = FFIRequest.create() - ..event = WorkspaceEvent.ReadAllWorkspace.toString(); + Future> 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)), + )); } } diff --git a/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart b/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart index 236796caba..df4af37f06 100644 --- a/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart +++ b/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart @@ -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> _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()); + }, ); }); } diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbenum.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbenum.dart index e058990734..29ec6ef75a 100644 --- a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbenum.dart +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbenum.dart @@ -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 values = [ CreateWorkspace, ReadCurWorkspace, - ReadWorkspace, + ReadWorkspaces, DeleteWorkspace, - ReadAllWorkspace, OpenWorkspace, CreateApp, DeleteApp, diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbjson.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbjson.dart index bba07b1428..943731cba2 100644 --- a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbjson.dart +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbjson.dart @@ -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'); diff --git a/rust-lib/dart-ffi/src/c.rs b/rust-lib/dart-ffi/src/c.rs index 9492f86f1b..a0fbed09dc 100644 --- a/rust-lib/dart-ffi/src/c.rs +++ b/rust-lib/dart-ffi/src/c.rs @@ -8,6 +8,7 @@ pub fn forget_rust(buf: Vec) -> *const u8 { } #[allow(unused_attributes)] +#[allow(dead_code)] pub fn reclaim_rust(ptr: *mut u8, length: u32) { unsafe { let len: usize = length as usize; diff --git a/rust-lib/flowy-dispatch/src/errors/errors.rs b/rust-lib/flowy-dispatch/src/errors/errors.rs index 4ca65400af..4457aa35ab 100644 --- a/rust-lib/flowy-dispatch/src/errors/errors.rs +++ b/rust-lib/flowy-dispatch/src/errors/errors.rs @@ -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), diff --git a/rust-lib/flowy-document/src/sql_tables/doc/doc_sql.rs b/rust-lib/flowy-document/src/sql_tables/doc/doc_sql.rs index bdd4c0515d..d93b5dfccb 100644 --- a/rust-lib/flowy-document/src/sql_tables/doc/doc_sql.rs +++ b/rust-lib/flowy-document/src/sql_tables/doc/doc_sql.rs @@ -36,5 +36,6 @@ impl DocTableSql { Ok(doc_table) } + #[allow(dead_code)] pub(crate) fn delete_doc(&self, _view_id: &str) -> Result<(), DocError> { unimplemented!() } } diff --git a/rust-lib/flowy-net/src/request/request.rs b/rust-lib/flowy-net/src/request/request.rs index 5aa5e8047b..04742bf6e9 100644 --- a/rust-lib/flowy-net/src/request/request.rs +++ b/rust-lib/flowy-net/src/request/request.rs @@ -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(url: &str, data: T1) -> Result -where - T1: TryInto, - T2: TryFrom, -{ - let body: Bytes = data.try_into()?; - let url = url.to_owned(); - let (tx, rx) = oneshot::channel::>(); - - // 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 { if original.status() == http::StatusCode::OK { let bytes = original.bytes().await?; diff --git a/rust-lib/flowy-observable/src/dart/stream_sender.rs b/rust-lib/flowy-observable/src/dart/stream_sender.rs index bbcff5bbf4..a6f289d1fa 100644 --- a/rust-lib/flowy-observable/src/dart/stream_sender.rs +++ b/rust-lib/flowy-observable/src/dart/stream_sender.rs @@ -8,6 +8,7 @@ lazy_static! { } pub struct RustStreamSender { + #[allow(dead_code)] isolate: Option, } @@ -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) => { diff --git a/rust-lib/flowy-sdk/Cargo.toml b/rust-lib/flowy-sdk/Cargo.toml index 25c4e8e187..e2cbc2c717 100644 --- a/rust-lib/flowy-sdk/Cargo.toml +++ b/rust-lib/flowy-sdk/Cargo.toml @@ -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"} diff --git a/rust-lib/flowy-sdk/src/deps_resolve/user_deps_impl.rs b/rust-lib/flowy-sdk/src/deps_resolve/user_deps_impl.rs index 775b96ba1a..8ac0c93ffe 100644 --- a/rust-lib/flowy-sdk/src/deps_resolve/user_deps_impl.rs +++ b/rust-lib/flowy-sdk/src/deps_resolve/user_deps_impl.rs @@ -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> { - 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::() - .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 {} diff --git a/rust-lib/flowy-test/src/builder.rs b/rust-lib/flowy-test/src/builder.rs index ebb924dda8..a0fc8384a8 100644 --- a/rust-lib/flowy-test/src/builder.rs +++ b/rust-lib/flowy-test/src/builder.rs @@ -17,13 +17,15 @@ pub type SingleUserTestBuilder = TestBuilder>; impl SingleUserTestBuilder { pub fn new() -> Self { let mut builder = TestBuilder::test(Box::new(FixedUserTester::::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>; impl UserTestBuilder { diff --git a/rust-lib/flowy-test/src/tester.rs b/rust-lib/flowy-test/src/tester.rs index f92a7fff6b..d8dc0d1d76 100644 --- a/rust-lib/flowy-test/src/tester.rs +++ b/rust-lib/flowy-test/src/tester.rs @@ -15,6 +15,7 @@ use std::{ hash::Hash, }; +#[allow(dead_code)] pub struct TesterContext { request: Option, response: Option, diff --git a/rust-lib/flowy-user/src/services/user/user_session.rs b/rust-lib/flowy-user/src/services/user/user_session.rs index 3ba03ec305..34fd12811e 100644 --- a/rust-lib/flowy-user/src/services/user/user_session.rs +++ b/rust-lib/flowy-user/src/services/user/user_session.rs @@ -34,6 +34,7 @@ impl UserSessionConfig { pub struct UserSession { database: UserDB, config: UserSessionConfig, + #[allow(dead_code)] workspace_controller: Arc, server: Arc, user_id: RwLock>, diff --git a/rust-lib/flowy-user/src/services/workspace/action.rs b/rust-lib/flowy-user/src/services/workspace/action.rs index 43f92af49b..aa2c5763c4 100644 --- a/rust-lib/flowy-user/src/services/workspace/action.rs +++ b/rust-lib/flowy-user/src/services/workspace/action.rs @@ -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>; -} +pub trait UserWorkspaceController {} diff --git a/rust-lib/flowy-workspace/src/entities/workspace/workspace_query.rs b/rust-lib/flowy-workspace/src/entities/workspace/workspace_query.rs index 5b58b79dc9..48158adaa8 100644 --- a/rust-lib/flowy-workspace/src/entities/workspace/workspace_query.rs +++ b/rust-lib/flowy-workspace/src/entities/workspace/workspace_query.rs @@ -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, diff --git a/rust-lib/flowy-workspace/src/event.rs b/rust-lib/flowy-workspace/src/event.rs index 8c5175e20b..3565001d90 100644 --- a/rust-lib/flowy-workspace/src/event.rs +++ b/rust-lib/flowy-workspace/src/event.rs @@ -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")] diff --git a/rust-lib/flowy-workspace/src/handlers/workspace_handler.rs b/rust-lib/flowy-workspace/src/handlers/workspace_handler.rs index 33958e38dc..a0a795780e 100644 --- a/rust-lib/flowy-workspace/src/handlers/workspace_handler.rs +++ b/rust-lib/flowy-workspace/src/handlers/workspace_handler.rs @@ -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, controller: Unit>, ) -> DataResult { @@ -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>, -) -> DataResult { - let workspaces = controller.read_workspaces_belong_to_user().await?; - - data_result(RepeatedWorkspace { items: workspaces }) -} diff --git a/rust-lib/flowy-workspace/src/module.rs b/rust-lib/flowy-workspace/src/module.rs index 519f83f168..ae1b73edca 100644 --- a/rust-lib/flowy-workspace/src/module.rs +++ b/rust-lib/flowy-workspace/src/module.rs @@ -45,10 +45,9 @@ pub fn create(user: Arc, database: Arc .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 diff --git a/rust-lib/flowy-workspace/src/protobuf/model/event.rs b/rust-lib/flowy-workspace/src/protobuf/model/event.rs index 86accf807c..c9e2dd29ca 100644 --- a/rust-lib/flowy-workspace/src/protobuf/model/event.rs +++ b/rust-lib/flowy-workspace/src/protobuf/model/event.rs @@ -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; diff --git a/rust-lib/flowy-workspace/src/protobuf/proto/event.proto b/rust-lib/flowy-workspace/src/protobuf/proto/event.proto index 80508fdb50..4a8e8baf8d 100644 --- a/rust-lib/flowy-workspace/src/protobuf/proto/event.proto +++ b/rust-lib/flowy-workspace/src/protobuf/proto/event.proto @@ -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; diff --git a/rust-lib/flowy-workspace/src/services/app_controller.rs b/rust-lib/flowy-workspace/src/services/app_controller.rs index 158abef93a..90bedc4784 100644 --- a/rust-lib/flowy-workspace/src/services/app_controller.rs +++ b/rust-lib/flowy-workspace/src/services/app_controller.rs @@ -13,6 +13,7 @@ use std::sync::Arc; pub struct AppController { user: Arc, sql: Arc, + #[allow(dead_code)] view_controller: Arc, } diff --git a/rust-lib/flowy-workspace/src/services/workspace_controller.rs b/rust-lib/flowy-workspace/src/services/workspace_controller.rs index d774e18abc..0358f5c4b1 100644 --- a/rust-lib/flowy-workspace/src/services/workspace_controller.rs +++ b/rust-lib/flowy-workspace/src/services/workspace_controller.rs @@ -94,18 +94,6 @@ impl WorkspaceController { Ok(RepeatedWorkspace { items: workspaces }) } - pub async fn read_workspaces_belong_to_user(&self) -> Result, 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::>(); - - Ok(workspace) - } - pub async fn read_cur_workspace(&self) -> Result { let workspace_id = get_current_workspace()?; let mut repeated_workspace = self.read_workspaces(Some(workspace_id.clone())).await?; diff --git a/rust-lib/flowy-workspace/src/sql_tables/workspace/workspace_sql.rs b/rust-lib/flowy-workspace/src/sql_tables/workspace/workspace_sql.rs index 70ca8c000f..1157ca7ec8 100644 --- a/rust-lib/flowy-workspace/src/sql_tables/workspace/workspace_sql.rs +++ b/rust-lib/flowy-workspace/src/sql_tables/workspace/workspace_sql.rs @@ -73,19 +73,4 @@ impl WorkspaceSql { Ok(apps) } - - pub(crate) fn read_workspaces_belong_to_user( - &self, - user_id: &str, - ) -> Result, 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::(&*(conn))?; - Ok(workspaces) - })?; - - Ok(workspaces) - } } diff --git a/rust-lib/flowy-workspace/tests/event/helper.rs b/rust-lib/flowy-workspace/tests/event/helper.rs index 5d700478af..581494e9ea 100644 --- a/rust-lib/flowy-workspace/tests/event/helper.rs +++ b/rust-lib/flowy-workspace/tests/event/helper.rs @@ -32,7 +32,7 @@ pub fn create_workspace(name: &str, desc: &str) -> (String, Workspace) { pub fn read_workspaces(request: QueryWorkspaceRequest) -> Option { let mut repeated_workspace = SingleUserTestBuilder::new() - .event(ReadWorkspace) + .event(ReadWorkspaces) .request(request) .sync_send() .parse::(); diff --git a/rust-lib/flowy-workspace/tests/event/workspace_test.rs b/rust-lib/flowy-workspace/tests/event/workspace_test.rs index 27d90ee22e..8c62a48357 100644 --- a/rust-lib/flowy-workspace/tests/event/workspace_test.rs +++ b/rust-lib/flowy-workspace/tests/event/workspace_test.rs @@ -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::(); - - let workspace = builder - .event(ReadCurWorkspace) - .sync_send() - .parse::(); - - 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::();