Quellcode durchsuchen

Merge pull request #401 from MikeWallaceDev/put_business_logic_in_services

Put business logic in services
Nathan.fooo vor 3 Jahren
Ursprung
Commit
cace6248e0
40 geänderte Dateien mit 383 neuen und 361 gelöschten Zeilen
  1. 0 0
      frontend/app_flowy/lib/core/helper.dart
  2. 29 21
      frontend/app_flowy/lib/startup/deps_resolver.dart
  3. 1 1
      frontend/app_flowy/lib/startup/startup.dart
  4. 1 58
      frontend/app_flowy/lib/user/application/user_listener.dart
  5. 57 0
      frontend/app_flowy/lib/user/application/user_service.dart
  6. 3 5
      frontend/app_flowy/lib/user/infrastructure/router.dart
  7. 1 1
      frontend/app_flowy/lib/user/presentation/skip_log_in_screen.dart
  8. 4 4
      frontend/app_flowy/lib/user/presentation/welcome_screen.dart
  9. 12 7
      frontend/app_flowy/lib/workspace/application/app/app_bloc.dart
  10. 2 55
      frontend/app_flowy/lib/workspace/application/app/app_listener.dart
  11. 57 0
      frontend/app_flowy/lib/workspace/application/app/app_service.dart
  12. 13 12
      frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart
  13. 4 9
      frontend/app_flowy/lib/workspace/application/doc/doc_service.dart
  14. 5 5
      frontend/app_flowy/lib/workspace/application/doc/share_bloc.dart
  15. 1 1
      frontend/app_flowy/lib/workspace/application/doc/share_service.dart
  16. 1 1
      frontend/app_flowy/lib/workspace/application/home/home_listen_bloc.dart
  17. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/delta_markdown.dart
  18. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/ast.dart
  19. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/block_parser.dart
  20. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/delta_markdown_decoder.dart
  21. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/delta_markdown_encoder.dart
  22. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/document.dart
  23. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/emojis.dart
  24. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/extension_set.dart
  25. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/html_renderer.dart
  26. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/inline_parser.dart
  27. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/util.dart
  28. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/version.dart
  29. 8 5
      frontend/app_flowy/lib/workspace/application/menu/menu_bloc.dart
  30. 11 9
      frontend/app_flowy/lib/workspace/application/menu/menu_user_bloc.dart
  31. 9 8
      frontend/app_flowy/lib/workspace/application/trash/trash_bloc.dart
  32. 2 34
      frontend/app_flowy/lib/workspace/application/trash/trash_listener.dart
  33. 37 0
      frontend/app_flowy/lib/workspace/application/trash/trash_service.dart
  34. 11 9
      frontend/app_flowy/lib/workspace/application/view/view_bloc.dart
  35. 1 39
      frontend/app_flowy/lib/workspace/application/view/view_listener.dart
  36. 36 0
      frontend/app_flowy/lib/workspace/application/view/view_service.dart
  37. 11 10
      frontend/app_flowy/lib/workspace/application/workspace/welcome_bloc.dart
  38. 15 63
      frontend/app_flowy/lib/workspace/application/workspace/workspace_listener.dart
  39. 46 0
      frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart
  40. 5 4
      frontend/app_flowy/lib/workspace/presentation/stack_page/doc/doc_stack_page.dart

+ 0 - 0
frontend/app_flowy/lib/workspace/infrastructure/repos/helper.dart → frontend/app_flowy/lib/core/helper.dart


+ 29 - 21
frontend/app_flowy/lib/workspace/infrastructure/deps_resolver.dart → frontend/app_flowy/lib/startup/deps_resolver.dart

@@ -1,24 +1,29 @@
+import 'package:app_flowy/user/application/user_listener.dart';
+import 'package:app_flowy/user/application/user_service.dart';
 import 'package:app_flowy/workspace/application/app/app_bloc.dart';
 import 'package:app_flowy/workspace/application/app/app_bloc.dart';
+import 'package:app_flowy/workspace/application/app/app_listener.dart';
+import 'package:app_flowy/workspace/application/app/app_service.dart';
 import 'package:app_flowy/workspace/application/doc/doc_bloc.dart';
 import 'package:app_flowy/workspace/application/doc/doc_bloc.dart';
+import 'package:app_flowy/workspace/application/doc/doc_service.dart';
 import 'package:app_flowy/workspace/application/doc/share_bloc.dart';
 import 'package:app_flowy/workspace/application/doc/share_bloc.dart';
+import 'package:app_flowy/workspace/application/doc/share_service.dart';
 import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart';
 import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart';
 import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
 import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
 import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart';
 import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart';
 import 'package:app_flowy/workspace/application/trash/trash_bloc.dart';
 import 'package:app_flowy/workspace/application/trash/trash_bloc.dart';
+import 'package:app_flowy/workspace/application/trash/trash_listener.dart';
+import 'package:app_flowy/workspace/application/trash/trash_service.dart';
 import 'package:app_flowy/workspace/application/view/view_bloc.dart';
 import 'package:app_flowy/workspace/application/view/view_bloc.dart';
+import 'package:app_flowy/workspace/application/view/view_listener.dart';
+import 'package:app_flowy/workspace/application/view/view_service.dart';
 import 'package:app_flowy/workspace/application/workspace/welcome_bloc.dart';
 import 'package:app_flowy/workspace/application/workspace/welcome_bloc.dart';
+import 'package:app_flowy/workspace/application/workspace/workspace_listener.dart';
+import 'package:app_flowy/workspace/application/workspace/workspace_service.dart';
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/app_repo.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/document_repo.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/trash_repo.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/workspace_repo.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
 import 'package:get_it/get_it.dart';
 import 'package:get_it/get_it.dart';
-import 'repos/share_repo.dart';
 
 
 class HomeDepsResolver {
 class HomeDepsResolver {
   static Future<void> resolve(GetIt getIt) async {
   static Future<void> resolve(GetIt getIt) async {
@@ -34,14 +39,14 @@ class HomeDepsResolver {
     getIt.registerLazySingleton<HomeStackManager>(() => HomeStackManager());
     getIt.registerLazySingleton<HomeStackManager>(() => HomeStackManager());
     getIt.registerFactoryParam<WelcomeBloc, UserProfile, void>(
     getIt.registerFactoryParam<WelcomeBloc, UserProfile, void>(
       (user, _) => WelcomeBloc(
       (user, _) => WelcomeBloc(
-        repo: UserRepo(user: user),
-        listener: getIt<UserListener>(param1: user),
+        userService: UserService(),
+        userListener: getIt<UserListener>(param1: user),
       ),
       ),
     );
     );
 
 
     //workspace
     //workspace
-    getIt.registerFactoryParam<WorkspaceListener, UserProfile, String>(
-        (user, workspaceId) => WorkspaceListener(repo: WorkspaceListenerRepo(user: user, workspaceId: workspaceId)));
+    getIt.registerFactoryParam<WorkspaceListener, UserProfile, String>((user, workspaceId) =>
+        WorkspaceListener(service: WorkspaceListenerService(user: user, workspaceId: workspaceId)));
 
 
     // View
     // View
     getIt.registerFactoryParam<ViewListener, View, void>(
     getIt.registerFactoryParam<ViewListener, View, void>(
@@ -50,7 +55,8 @@ class HomeDepsResolver {
 
 
     getIt.registerFactoryParam<ViewBloc, View, void>(
     getIt.registerFactoryParam<ViewBloc, View, void>(
       (view, _) => ViewBloc(
       (view, _) => ViewBloc(
-        repo: ViewRepository(view: view),
+        view: view, 
+        service: ViewService(),
         listener: getIt<ViewListener>(param1: view),
         listener: getIt<ViewListener>(param1: view),
       ),
       ),
     );
     );
@@ -58,14 +64,16 @@ class HomeDepsResolver {
     //Menu Bloc
     //Menu Bloc
     getIt.registerFactoryParam<MenuBloc, UserProfile, String>(
     getIt.registerFactoryParam<MenuBloc, UserProfile, String>(
       (user, workspaceId) => MenuBloc(
       (user, workspaceId) => MenuBloc(
-        repo: WorkspaceRepo(user: user, workspaceId: workspaceId),
+        workspaceId: workspaceId,
+        service: WorkspaceService(),
         listener: getIt<WorkspaceListener>(param1: user, param2: workspaceId),
         listener: getIt<WorkspaceListener>(param1: user, param2: workspaceId),
       ),
       ),
     );
     );
 
 
     getIt.registerFactoryParam<MenuUserBloc, UserProfile, void>(
     getIt.registerFactoryParam<MenuUserBloc, UserProfile, void>(
       (user, _) => MenuUserBloc(
       (user, _) => MenuUserBloc(
-        UserRepo(user: user),
+        user,
+        UserService(),
         getIt<UserListener>(param1: user),
         getIt<UserListener>(param1: user),
       ),
       ),
     );
     );
@@ -74,7 +82,7 @@ class HomeDepsResolver {
     getIt.registerFactoryParam<AppBloc, App, void>(
     getIt.registerFactoryParam<AppBloc, App, void>(
       (app, _) => AppBloc(
       (app, _) => AppBloc(
         app: app,
         app: app,
-        repo: AppRepository(appId: app.id),
+        service: AppService(),
         listener: AppListener(appId: app.id),
         listener: AppListener(appId: app.id),
       ),
       ),
     );
     );
@@ -83,25 +91,25 @@ class HomeDepsResolver {
     getIt.registerFactoryParam<DocumentBloc, View, void>(
     getIt.registerFactoryParam<DocumentBloc, View, void>(
       (view, _) => DocumentBloc(
       (view, _) => DocumentBloc(
         view: view,
         view: view,
-        repo: DocumentRepository(docId: view.id),
+        service: DocumentService(),
         listener: getIt<ViewListener>(param1: view),
         listener: getIt<ViewListener>(param1: view),
-        trashRepo: getIt<TrashRepo>(),
+        trashService: getIt<TrashService>(),
       ),
       ),
     );
     );
 
 
     // trash
     // trash
-    getIt.registerLazySingleton<TrashRepo>(() => TrashRepo());
+    getIt.registerLazySingleton<TrashService>(() => TrashService());
     getIt.registerLazySingleton<TrashListener>(() => TrashListener());
     getIt.registerLazySingleton<TrashListener>(() => TrashListener());
     getIt.registerFactory<TrashBloc>(
     getIt.registerFactory<TrashBloc>(
       () => TrashBloc(
       () => TrashBloc(
-        repo: getIt<TrashRepo>(),
+        service: getIt<TrashService>(),
         listener: getIt<TrashListener>(),
         listener: getIt<TrashListener>(),
       ),
       ),
     );
     );
 
 
     // share
     // share
-    getIt.registerLazySingleton<ShareRepo>(() => ShareRepo());
+    getIt.registerLazySingleton<ShareService>(() => ShareService());
     getIt.registerFactoryParam<DocShareBloc, View, void>(
     getIt.registerFactoryParam<DocShareBloc, View, void>(
-        (view, _) => DocShareBloc(view: view, repo: getIt<ShareRepo>()));
+        (view, _) => DocShareBloc(view: view, service: getIt<ShareService>()));
   }
   }
 }
 }

+ 1 - 1
frontend/app_flowy/lib/startup/startup.dart

@@ -4,7 +4,7 @@ import 'package:app_flowy/startup/tasks/prelude.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:get_it/get_it.dart';
 import 'package:get_it/get_it.dart';
-import 'package:app_flowy/workspace/infrastructure/deps_resolver.dart';
+import 'package:app_flowy/startup/deps_resolver.dart';
 import 'package:app_flowy/user/infrastructure/deps_resolver.dart';
 import 'package:app_flowy/user/infrastructure/deps_resolver.dart';
 import 'package:flowy_sdk/flowy_sdk.dart';
 import 'package:flowy_sdk/flowy_sdk.dart';
 
 

+ 1 - 58
frontend/app_flowy/lib/workspace/infrastructure/repos/user_repo.dart → frontend/app_flowy/lib/user/application/user_listener.dart

@@ -1,74 +1,17 @@
 import 'dart:async';
 import 'dart:async';
 import 'package:dartz/dartz.dart';
 import 'package:dartz/dartz.dart';
-import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'dart:typed_data';
 import 'dart:typed_data';
-import 'package:app_flowy/workspace/infrastructure/repos/helper.dart';
+import 'package:app_flowy/core/helper.dart';
 import 'package:flowy_infra/notifier.dart';
 import 'package:flowy_infra/notifier.dart';
 import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
 import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-user-data-model/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-user-data-model/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
-// import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart' as user_error;
 import 'package:flowy_sdk/protobuf/flowy-user/dart_notification.pb.dart' as user;
 import 'package:flowy_sdk/protobuf/flowy-user/dart_notification.pb.dart' as user;
 import 'package:flowy_sdk/rust_stream.dart';
 import 'package:flowy_sdk/rust_stream.dart';
 
 
-class UserRepo {
-  final UserProfile user;
-  UserRepo({
-    required this.user,
-  });
-
-  Future<Either<UserProfile, FlowyError>> fetchUserProfile({required String userId}) {
-    return UserEventGetUserProfile().send();
-  }
-
-  Future<Either<Unit, FlowyError>> deleteWorkspace({required String workspaceId}) {
-    throw UnimplementedError();
-  }
-
-  Future<Either<Unit, FlowyError>> signOut() {
-    return UserEventSignOut().send();
-  }
-
-  Future<Either<Unit, FlowyError>> initUser() async {
-    return UserEventInitUser().send();
-  }
-
-  Future<Either<List<Workspace>, FlowyError>> getWorkspaces() {
-    final request = WorkspaceId.create();
-
-    return FolderEventReadWorkspaces(request).send().then((result) {
-      return result.fold(
-        (workspaces) => left(workspaces.items),
-        (error) => right(error),
-      );
-    });
-  }
-
-  Future<Either<Workspace, FlowyError>> openWorkspace(String workspaceId) {
-    final request = WorkspaceId.create()..value = workspaceId;
-    return FolderEventOpenWorkspace(request).send().then((result) {
-      return result.fold(
-        (workspace) => left(workspace),
-        (error) => right(error),
-      );
-    });
-  }
-
-  Future<Either<Workspace, FlowyError>> createWorkspace(String name, String desc) {
-    final request = CreateWorkspacePayload.create()
-      ..name = name
-      ..desc = desc;
-    return FolderEventCreateWorkspace(request).send().then((result) {
-      return result.fold(
-        (workspace) => left(workspace),
-        (error) => right(error),
-      );
-    });
-  }
-}
 
 
 typedef UserProfileUpdatedNotifierValue = Either<UserProfile, FlowyError>;
 typedef UserProfileUpdatedNotifierValue = Either<UserProfile, FlowyError>;
 typedef AuthNotifierValue = Either<Unit, FlowyError>;
 typedef AuthNotifierValue = Either<Unit, FlowyError>;

+ 57 - 0
frontend/app_flowy/lib/user/application/user_service.dart

@@ -0,0 +1,57 @@
+import 'dart:async';
+import 'package:dartz/dartz.dart';
+import 'package:flowy_sdk/dispatch/dispatch.dart';
+import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
+
+class UserService {
+  Future<Either<UserProfile, FlowyError>> fetchUserProfile({required String userId}) {
+    return UserEventGetUserProfile().send();
+  }
+
+  Future<Either<Unit, FlowyError>> deleteWorkspace({required String workspaceId}) {
+    throw UnimplementedError();
+  }
+
+  Future<Either<Unit, FlowyError>> signOut() {
+    return UserEventSignOut().send();
+  }
+
+  Future<Either<Unit, FlowyError>> initUser() async {
+    return UserEventInitUser().send();
+  }
+
+  Future<Either<List<Workspace>, FlowyError>> getWorkspaces() {
+    final request = WorkspaceId.create();
+
+    return FolderEventReadWorkspaces(request).send().then((result) {
+      return result.fold(
+        (workspaces) => left(workspaces.items),
+        (error) => right(error),
+      );
+    });
+  }
+
+  Future<Either<Workspace, FlowyError>> openWorkspace(String workspaceId) {
+    final request = WorkspaceId.create()..value = workspaceId;
+    return FolderEventOpenWorkspace(request).send().then((result) {
+      return result.fold(
+        (workspace) => left(workspace),
+        (error) => right(error),
+      );
+    });
+  }
+
+  Future<Either<Workspace, FlowyError>> createWorkspace(String name, String desc) {
+    final request = CreateWorkspacePayload.create()
+      ..name = name
+      ..desc = desc;
+    return FolderEventCreateWorkspace(request).send().then((result) {
+      return result.fold(
+        (workspace) => left(workspace),
+        (error) => right(error),
+      );
+    });
+  }
+}

+ 3 - 5
frontend/app_flowy/lib/user/infrastructure/router.dart

@@ -4,7 +4,6 @@ import 'package:app_flowy/user/presentation/sign_in_screen.dart';
 import 'package:app_flowy/user/presentation/sign_up_screen.dart';
 import 'package:app_flowy/user/presentation/sign_up_screen.dart';
 import 'package:app_flowy/user/presentation/skip_log_in_screen.dart';
 import 'package:app_flowy/user/presentation/skip_log_in_screen.dart';
 import 'package:app_flowy/user/presentation/welcome_screen.dart';
 import 'package:app_flowy/user/presentation/welcome_screen.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/home/home_screen.dart';
 import 'package:flowy_infra/time/duration.dart';
 import 'package:flowy_infra/time/duration.dart';
 import 'package:flowy_infra_ui/widget/route/animation.dart';
 import 'package:flowy_infra_ui/widget/route/animation.dart';
@@ -38,9 +37,8 @@ class AuthRouter {
 }
 }
 
 
 class SplashRoute {
 class SplashRoute {
-  Future<void> pushWelcomeScreen(BuildContext context, UserProfile user) async {
-    final repo = UserRepo(user: user);
-    final screen = WelcomeScreen(repo: repo);
+  Future<void> pushWelcomeScreen(BuildContext context, UserProfile userProfile) async {
+    final screen = WelcomeScreen(userProfile: userProfile);
     final workspaceId = await Navigator.of(context).push(
     final workspaceId = await Navigator.of(context).push(
       PageRoutes.fade(
       PageRoutes.fade(
         () => screen,
         () => screen,
@@ -48,7 +46,7 @@ class SplashRoute {
       ),
       ),
     );
     );
 
 
-    pushHomeScreen(context, repo.user, workspaceId);
+    pushHomeScreen(context, userProfile, workspaceId);
   }
   }
 
 
   void pushHomeScreen(BuildContext context, UserProfile userProfile, CurrentWorkspaceSetting workspaceSetting) {
   void pushHomeScreen(BuildContext context, UserProfile userProfile, CurrentWorkspaceSetting workspaceSetting) {

+ 1 - 1
frontend/app_flowy/lib/user/presentation/skip_log_in_screen.dart

@@ -1,7 +1,7 @@
+import 'package:app_flowy/user/application/user_listener.dart';
 import 'package:app_flowy/user/infrastructure/router.dart';
 import 'package:app_flowy/user/infrastructure/router.dart';
 import 'package:app_flowy/user/infrastructure/repos/auth_repo.dart';
 import 'package:app_flowy/user/infrastructure/repos/auth_repo.dart';
 import 'package:app_flowy/user/presentation/widgets/background.dart';
 import 'package:app_flowy/user/presentation/widgets/background.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flowy_infra/size.dart';
 import 'package:flowy_infra/size.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra/theme.dart';

+ 4 - 4
frontend/app_flowy/lib/user/presentation/welcome_screen.dart

@@ -6,22 +6,22 @@ import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
 import 'package:flowy_infra_ui/style_widget/button.dart';
 import 'package:flowy_infra_ui/style_widget/button.dart';
 import 'package:flowy_infra_ui/widget/error_page.dart';
 import 'package:flowy_infra_ui/widget/error_page.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
 
 
 class WelcomeScreen extends StatelessWidget {
 class WelcomeScreen extends StatelessWidget {
-  final UserRepo repo;
+  final UserProfile userProfile;
   const WelcomeScreen({
   const WelcomeScreen({
     Key? key,
     Key? key,
-    required this.repo,
+    required this.userProfile,
   }) : super(key: key);
   }) : super(key: key);
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
     return BlocProvider(
     return BlocProvider(
-      create: (_) => getIt<WelcomeBloc>(param1: repo.user)..add(const WelcomeEvent.initial()),
+      create: (_) => getIt<WelcomeBloc>(param1: userProfile)..add(const WelcomeEvent.initial()),
       child: BlocBuilder<WelcomeBloc, WelcomeState>(
       child: BlocBuilder<WelcomeBloc, WelcomeState>(
         builder: (context, state) {
         builder: (context, state) {
           return Scaffold(
           return Scaffold(

+ 12 - 7
frontend/app_flowy/lib/workspace/application/app/app_bloc.dart

@@ -1,4 +1,5 @@
-import 'package:app_flowy/workspace/infrastructure/repos/app_repo.dart';
+import 'package:app_flowy/workspace/application/app/app_listener.dart';
+import 'package:app_flowy/workspace/application/app/app_service.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
@@ -10,9 +11,12 @@ import 'package:dartz/dartz.dart';
 part 'app_bloc.freezed.dart';
 part 'app_bloc.freezed.dart';
 
 
 class AppBloc extends Bloc<AppEvent, AppState> {
 class AppBloc extends Bloc<AppEvent, AppState> {
-  final AppRepository repo;
+  final App app;
+  final AppService service;
   final AppListener listener;
   final AppListener listener;
-  AppBloc({required App app, required this.repo, required this.listener}) : super(AppState.initial(app)) {
+
+  AppBloc({required this.app, required this.service, required this.listener})
+      : super(AppState.initial(app)) {
     on<AppEvent>((event, emit) async {
     on<AppEvent>((event, emit) async {
       await event.map(initial: (e) async {
       await event.map(initial: (e) async {
         listener.startListening(
         listener.startListening(
@@ -21,7 +25,8 @@ class AppBloc extends Bloc<AppEvent, AppState> {
         );
         );
         await _fetchViews(emit);
         await _fetchViews(emit);
       }, createView: (CreateView value) async {
       }, createView: (CreateView value) async {
-        final viewOrFailed = await repo.createView(name: value.name, desc: value.desc, viewType: value.viewType);
+        final viewOrFailed =
+            await service.createView(appId: app.id, name: value.name, desc: value.desc, viewType: value.viewType);
         viewOrFailed.fold(
         viewOrFailed.fold(
           (view) => emit(state.copyWith(
           (view) => emit(state.copyWith(
             latestCreatedView: view,
             latestCreatedView: view,
@@ -35,13 +40,13 @@ class AppBloc extends Bloc<AppEvent, AppState> {
       }, didReceiveViews: (e) async {
       }, didReceiveViews: (e) async {
         await handleDidReceiveViews(e.views, emit);
         await handleDidReceiveViews(e.views, emit);
       }, delete: (e) async {
       }, delete: (e) async {
-        final result = await repo.delete();
+        final result = await service.delete(appId: app.id);
         result.fold(
         result.fold(
           (unit) => emit(state.copyWith(successOrFailure: left(unit))),
           (unit) => emit(state.copyWith(successOrFailure: left(unit))),
           (error) => emit(state.copyWith(successOrFailure: right(error))),
           (error) => emit(state.copyWith(successOrFailure: right(error))),
         );
         );
       }, rename: (e) async {
       }, rename: (e) async {
-        final result = await repo.updateApp(name: e.newName);
+        final result = await service.updateApp(appId: app.id, name: e.newName);
         result.fold(
         result.fold(
           (l) => emit(state.copyWith(successOrFailure: left(unit))),
           (l) => emit(state.copyWith(successOrFailure: left(unit))),
           (error) => emit(state.copyWith(successOrFailure: right(error))),
           (error) => emit(state.copyWith(successOrFailure: right(error))),
@@ -81,7 +86,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
   }
   }
 
 
   Future<void> _fetchViews(Emitter<AppState> emit) async {
   Future<void> _fetchViews(Emitter<AppState> emit) async {
-    final viewsOrFailed = await repo.getViews();
+    final viewsOrFailed = await service.getViews(appId: app.id);
     viewsOrFailed.fold(
     viewsOrFailed.fold(
       (apps) => emit(state.copyWith(views: apps)),
       (apps) => emit(state.copyWith(views: apps)),
       (error) {
       (error) {

+ 2 - 55
frontend/app_flowy/lib/workspace/infrastructure/repos/app_repo.dart → frontend/app_flowy/lib/workspace/application/app/app_listener.dart

@@ -1,67 +1,14 @@
 import 'dart:async';
 import 'dart:async';
 import 'dart:typed_data';
 import 'dart:typed_data';
 import 'package:dartz/dartz.dart';
 import 'package:dartz/dartz.dart';
+import 'package:app_flowy/core/helper.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/log.dart';
-import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
 import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
 import 'package:flowy_sdk/rust_stream.dart';
 import 'package:flowy_sdk/rust_stream.dart';
-import 'helper.dart';
-
-class AppRepository {
-  String appId;
-  AppRepository({
-    required this.appId,
-  });
-
-  Future<Either<App, FlowyError>> getAppDesc() {
-    final request = AppId.create()..value = appId;
-
-    return FolderEventReadApp(request).send();
-  }
-
-  Future<Either<View, FlowyError>> createView({
-    required String name,
-    required String desc,
-    required ViewType viewType,
-  }) {
-    final request = CreateViewPayload.create()
-      ..belongToId = appId
-      ..name = name
-      ..desc = desc
-      ..viewType = viewType;
-
-    return FolderEventCreateView(request).send();
-  }
-
-  Future<Either<List<View>, FlowyError>> getViews() {
-    final request = AppId.create()..value = appId;
-
-    return FolderEventReadApp(request).send().then((result) {
-      return result.fold(
-        (app) => left(app.belongings.items),
-        (error) => right(error),
-      );
-    });
-  }
-
-  Future<Either<Unit, FlowyError>> delete() {
-    final request = AppId.create()..value = appId;
-    return FolderEventDeleteApp(request).send();
-  }
-
-  Future<Either<Unit, FlowyError>> updateApp({String? name}) {
-    UpdateAppPayload request = UpdateAppPayload.create()..appId = appId;
-
-    if (name != null) {
-      request.name = name;
-    }
-    return FolderEventUpdateApp(request).send();
-  }
-}
 
 
 typedef AppDidUpdateCallback = void Function(App app);
 typedef AppDidUpdateCallback = void Function(App app);
 typedef ViewsDidChangeCallback = void Function(Either<List<View>, FlowyError> viewsOrFailed);
 typedef ViewsDidChangeCallback = void Function(Either<List<View>, FlowyError> viewsOrFailed);

+ 57 - 0
frontend/app_flowy/lib/workspace/application/app/app_service.dart

@@ -0,0 +1,57 @@
+import 'dart:async';
+import 'package:dartz/dartz.dart';
+import 'package:flowy_sdk/dispatch/dispatch.dart';
+import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+
+class AppService {
+
+  Future<Either<App, FlowyError>> getAppDesc({required String appId}) {
+    final request = AppId.create()..value = appId;
+
+    return FolderEventReadApp(request).send();
+  }
+
+  Future<Either<View, FlowyError>> createView({
+    required String appId,
+    required String name,
+    required String desc,
+    required ViewType viewType,
+  }) {
+    final request = CreateViewPayload.create()
+      ..belongToId = appId
+      ..name = name
+      ..desc = desc
+      ..viewType = viewType;
+
+    return FolderEventCreateView(request).send();
+  }
+
+  Future<Either<List<View>, FlowyError>> getViews({required String appId}) {
+    final request = AppId.create()..value = appId;
+
+    return FolderEventReadApp(request).send().then((result) {
+      return result.fold(
+        (app) => left(app.belongings.items),
+        (error) => right(error),
+      );
+    });
+  }
+
+  Future<Either<Unit, FlowyError>> delete({required String appId}) {
+    final request = AppId.create()..value = appId;
+    return FolderEventDeleteApp(request).send();
+  }
+
+  Future<Either<Unit, FlowyError>> updateApp({required String appId, String? name}) {
+    UpdateAppPayload request = UpdateAppPayload.create()..appId = appId;
+
+    if (name != null) {
+      request.name = name;
+    }
+    return FolderEventUpdateApp(request).send();
+  }
+}
+
+

+ 13 - 12
frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart

@@ -1,7 +1,7 @@
 import 'dart:convert';
 import 'dart:convert';
-import 'package:app_flowy/workspace/infrastructure/repos/document_repo.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/trash_repo.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
+import 'package:app_flowy/workspace/application/doc/doc_service.dart';
+import 'package:app_flowy/workspace/application/trash/trash_service.dart';
+import 'package:app_flowy/workspace/application/view/view_listener.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/trash.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/trash.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
@@ -11,23 +11,24 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:dartz/dartz.dart';
 import 'package:dartz/dartz.dart';
 import 'dart:async';
 import 'dart:async';
+
 part 'doc_bloc.freezed.dart';
 part 'doc_bloc.freezed.dart';
 
 
 typedef FlutterQuillDocument = Document;
 typedef FlutterQuillDocument = Document;
 
 
 class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
 class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
   final View view;
   final View view;
-  final DocumentRepository repo;
+  final DocumentService service;
   final ViewListener listener;
   final ViewListener listener;
-  final TrashRepo trashRepo;
+  final TrashService trashService;
   late FlutterQuillDocument document;
   late FlutterQuillDocument document;
   StreamSubscription? _subscription;
   StreamSubscription? _subscription;
 
 
   DocumentBloc({
   DocumentBloc({
     required this.view,
     required this.view,
-    required this.repo,
+    required this.service,
     required this.listener,
     required this.listener,
-    required this.trashRepo,
+    required this.trashService,
   }) : super(DocumentState.initial()) {
   }) : super(DocumentState.initial()) {
     on<DocumentEvent>((event, emit) async {
     on<DocumentEvent>((event, emit) async {
       await event.map(
       await event.map(
@@ -41,12 +42,12 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
           emit(state.copyWith(isDeleted: false));
           emit(state.copyWith(isDeleted: false));
         },
         },
         deletePermanently: (DeletePermanently value) async {
         deletePermanently: (DeletePermanently value) async {
-          final result = await trashRepo.deleteViews([Tuple2(view.id, TrashType.TrashView)]);
+          final result = await trashService.deleteViews([Tuple2(view.id, TrashType.TrashView)]);
           final newState = result.fold((l) => state.copyWith(forceClose: true), (r) => state);
           final newState = result.fold((l) => state.copyWith(forceClose: true), (r) => state);
           emit(newState);
           emit(newState);
         },
         },
         restorePage: (RestorePage value) async {
         restorePage: (RestorePage value) async {
-          final result = await trashRepo.putback(view.id);
+          final result = await trashService.putback(view.id);
           final newState = result.fold((l) => state.copyWith(isDeleted: false), (r) => state);
           final newState = result.fold((l) => state.copyWith(isDeleted: false), (r) => state);
           emit(newState);
           emit(newState);
         },
         },
@@ -62,7 +63,7 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
       await _subscription?.cancel();
       await _subscription?.cancel();
     }
     }
 
 
-    repo.closeDocument();
+    service.closeDocument(docId: view.id);
     return super.close();
     return super.close();
   }
   }
 
 
@@ -82,7 +83,7 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
     });
     });
 
 
     listener.start();
     listener.start();
-    final result = await repo.openDocument();
+    final result = await service.openDocument(docId: view.id);
     result.fold(
     result.fold(
       (doc) {
       (doc) {
         document = _decodeJsonToDocument(doc.deltaJson);
         document = _decodeJsonToDocument(doc.deltaJson);
@@ -108,7 +109,7 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
   void _composeDelta(Delta composedDelta, Delta documentDelta) async {
   void _composeDelta(Delta composedDelta, Delta documentDelta) async {
     final json = jsonEncode(composedDelta.toJson());
     final json = jsonEncode(composedDelta.toJson());
     Log.debug("doc_id: $view.id - Send json: $json");
     Log.debug("doc_id: $view.id - Send json: $json");
-    final result = await repo.composeDelta(data: json);
+    final result = await service.composeDelta(docId: view.id, data: json);
 
 
     result.fold((rustDoc) {
     result.fold((rustDoc) {
       // final json = utf8.decode(doc.data);
       // final json = utf8.decode(doc.data);

+ 4 - 9
frontend/app_flowy/lib/workspace/infrastructure/repos/document_repo.dart → frontend/app_flowy/lib/workspace/application/doc/doc_service.dart

@@ -4,25 +4,20 @@ import 'package:flowy_sdk/protobuf/flowy-collaboration/document_info.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 
 
-class DocumentRepository {
-  final String docId;
-  DocumentRepository({
-    required this.docId,
-  });
-
-  Future<Either<DocumentDelta, FlowyError>> openDocument() {
+class DocumentService {
+  Future<Either<DocumentDelta, FlowyError>> openDocument({required String docId}) {
     final request = ViewId(value: docId);
     final request = ViewId(value: docId);
     return FolderEventOpenView(request).send();
     return FolderEventOpenView(request).send();
   }
   }
 
 
-  Future<Either<DocumentDelta, FlowyError>> composeDelta({required String data}) {
+  Future<Either<DocumentDelta, FlowyError>> composeDelta({required String docId, required String data}) {
     final request = DocumentDelta.create()
     final request = DocumentDelta.create()
       ..docId = docId
       ..docId = docId
       ..deltaJson = data;
       ..deltaJson = data;
     return FolderEventApplyDocDelta(request).send();
     return FolderEventApplyDocDelta(request).send();
   }
   }
 
 
-  Future<Either<Unit, FlowyError>> closeDocument() {
+  Future<Either<Unit, FlowyError>> closeDocument({required String docId}) {
     final request = ViewId(value: docId);
     final request = ViewId(value: docId);
     return FolderEventCloseView(request).send();
     return FolderEventCloseView(request).send();
   }
   }

+ 5 - 5
frontend/app_flowy/lib/workspace/application/doc/share_bloc.dart

@@ -1,5 +1,5 @@
-import 'package:app_flowy/workspace/infrastructure/markdown/delta_markdown.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/share_repo.dart';
+import 'package:app_flowy/workspace/application/doc/share_service.dart';
+import 'package:app_flowy/workspace/application/markdown/delta_markdown.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/share.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/share.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
@@ -9,13 +9,13 @@ import 'package:dartz/dartz.dart';
 part 'share_bloc.freezed.dart';
 part 'share_bloc.freezed.dart';
 
 
 class DocShareBloc extends Bloc<DocShareEvent, DocShareState> {
 class DocShareBloc extends Bloc<DocShareEvent, DocShareState> {
-  ShareRepo repo;
+  ShareService service;
   View view;
   View view;
-  DocShareBloc({required this.view, required this.repo}) : super(const DocShareState.initial()) {
+  DocShareBloc({required this.view, required this.service}) : super(const DocShareState.initial()) {
     on<DocShareEvent>((event, emit) async {
     on<DocShareEvent>((event, emit) async {
       await event.map(
       await event.map(
         shareMarkdown: (ShareMarkdown value) async {
         shareMarkdown: (ShareMarkdown value) async {
-          await repo.exportMarkdown(view.id).then((result) {
+          await service.exportMarkdown(view.id).then((result) {
             result.fold(
             result.fold(
               (value) => emit(DocShareState.finish(left(_convertDeltaToMarkdown(value)))),
               (value) => emit(DocShareState.finish(left(_convertDeltaToMarkdown(value)))),
               (error) => emit(DocShareState.finish(right(error))),
               (error) => emit(DocShareState.finish(right(error))),

+ 1 - 1
frontend/app_flowy/lib/workspace/infrastructure/repos/share_repo.dart → frontend/app_flowy/lib/workspace/application/doc/share_service.dart

@@ -4,7 +4,7 @@ import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/protobuf.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/protobuf.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 
 
-class ShareRepo {
+class ShareService {
   Future<Either<ExportData, FlowyError>> export(String docId, ExportType type) {
   Future<Either<ExportData, FlowyError>> export(String docId, ExportType type) {
     final request = ExportPayload.create()
     final request = ExportPayload.create()
       ..docId = docId
       ..docId = docId

+ 1 - 1
frontend/app_flowy/lib/workspace/application/home/home_listen_bloc.dart

@@ -1,4 +1,4 @@
-import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
+import 'package:app_flowy/user/application/user_listener.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';

+ 0 - 0
frontend/app_flowy/lib/workspace/infrastructure/markdown/delta_markdown.dart → frontend/app_flowy/lib/workspace/application/markdown/delta_markdown.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/infrastructure/markdown/src/ast.dart → frontend/app_flowy/lib/workspace/application/markdown/src/ast.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/infrastructure/markdown/src/block_parser.dart → frontend/app_flowy/lib/workspace/application/markdown/src/block_parser.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/infrastructure/markdown/src/delta_markdown_decoder.dart → frontend/app_flowy/lib/workspace/application/markdown/src/delta_markdown_decoder.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/infrastructure/markdown/src/delta_markdown_encoder.dart → frontend/app_flowy/lib/workspace/application/markdown/src/delta_markdown_encoder.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/infrastructure/markdown/src/document.dart → frontend/app_flowy/lib/workspace/application/markdown/src/document.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/infrastructure/markdown/src/emojis.dart → frontend/app_flowy/lib/workspace/application/markdown/src/emojis.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/infrastructure/markdown/src/extension_set.dart → frontend/app_flowy/lib/workspace/application/markdown/src/extension_set.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/infrastructure/markdown/src/html_renderer.dart → frontend/app_flowy/lib/workspace/application/markdown/src/html_renderer.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/infrastructure/markdown/src/inline_parser.dart → frontend/app_flowy/lib/workspace/application/markdown/src/inline_parser.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/infrastructure/markdown/src/util.dart → frontend/app_flowy/lib/workspace/application/markdown/src/util.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/infrastructure/markdown/src/version.dart → frontend/app_flowy/lib/workspace/application/markdown/src/version.dart


+ 8 - 5
frontend/app_flowy/lib/workspace/application/menu/menu_bloc.dart

@@ -1,6 +1,7 @@
 import 'dart:async';
 import 'dart:async';
+import 'package:app_flowy/workspace/application/workspace/workspace_listener.dart';
+import 'package:app_flowy/workspace/application/workspace/workspace_service.dart';
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/workspace_repo.dart';
 import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
 import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
 import 'package:dartz/dartz.dart';
 import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/log.dart';
@@ -12,9 +13,11 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 part 'menu_bloc.freezed.dart';
 part 'menu_bloc.freezed.dart';
 
 
 class MenuBloc extends Bloc<MenuEvent, MenuState> {
 class MenuBloc extends Bloc<MenuEvent, MenuState> {
-  final WorkspaceRepo repo;
+  final WorkspaceService service;
   final WorkspaceListener listener;
   final WorkspaceListener listener;
-  MenuBloc({required this.repo, required this.listener}) : super(MenuState.initial()) {
+  final String workspaceId;
+
+  MenuBloc({required this.workspaceId, required this.service, required this.listener}) : super(MenuState.initial()) {
     on<MenuEvent>((event, emit) async {
     on<MenuEvent>((event, emit) async {
       await event.map(
       await event.map(
         initial: (e) async {
         initial: (e) async {
@@ -48,7 +51,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
   }
   }
 
 
   Future<void> _performActionOnCreateApp(CreateApp event, Emitter<MenuState> emit) async {
   Future<void> _performActionOnCreateApp(CreateApp event, Emitter<MenuState> emit) async {
-    final result = await repo.createApp(event.name, event.desc ?? "");
+    final result = await service.createApp(workspaceId: workspaceId, name: event.name, desc: event.desc ?? "");
     result.fold(
     result.fold(
       (app) => {},
       (app) => {},
       (error) {
       (error) {
@@ -60,7 +63,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
 
 
   // ignore: unused_element
   // ignore: unused_element
   Future<void> _fetchApps(Emitter<MenuState> emit) async {
   Future<void> _fetchApps(Emitter<MenuState> emit) async {
-    final appsOrFail = await repo.getApps();
+    final appsOrFail = await service.getApps(workspaceId: workspaceId);
     emit(appsOrFail.fold(
     emit(appsOrFail.fold(
       (apps) => state.copyWith(apps: some(apps)),
       (apps) => state.copyWith(apps: some(apps)),
       (error) {
       (error) {

+ 11 - 9
frontend/app_flowy/lib/workspace/application/menu/menu_user_bloc.dart

@@ -1,4 +1,5 @@
-import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
+import 'package:app_flowy/user/application/user_listener.dart';
+import 'package:app_flowy/user/application/user_service.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
@@ -10,16 +11,17 @@ import 'package:dartz/dartz.dart';
 part 'menu_user_bloc.freezed.dart';
 part 'menu_user_bloc.freezed.dart';
 
 
 class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
 class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
-  final UserRepo repo;
-  final UserListener listener;
+  final UserService userService;
+  final UserListener userListener;
+  final UserProfile userProfile;
 
 
-  MenuUserBloc(this.repo, this.listener) : super(MenuUserState.initial(repo.user)) {
+  MenuUserBloc(this.userProfile, this.userService, this.userListener) : super(MenuUserState.initial(userProfile)) {
     on<MenuUserEvent>((event, emit) async {
     on<MenuUserEvent>((event, emit) async {
       await event.map(
       await event.map(
         initial: (_) async {
         initial: (_) async {
-          listener.profileUpdatedNotifier.addPublishListener(_profileUpdated);
-          listener.workspaceUpdatedNotifier.addPublishListener(_workspacesUpdated);
-          listener.start();
+          userListener.profileUpdatedNotifier.addPublishListener(_profileUpdated);
+          userListener.workspaceUpdatedNotifier.addPublishListener(_workspacesUpdated);
+          userListener.start();
           await _initUser();
           await _initUser();
         },
         },
         fetchWorkspaces: (_FetchWorkspaces value) async {},
         fetchWorkspaces: (_FetchWorkspaces value) async {},
@@ -29,12 +31,12 @@ class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
 
 
   @override
   @override
   Future<void> close() async {
   Future<void> close() async {
-    await listener.stop();
+    await userListener.stop();
     super.close();
     super.close();
   }
   }
 
 
   Future<void> _initUser() async {
   Future<void> _initUser() async {
-    final result = await repo.initUser();
+    final result = await userService.initUser();
     result.fold((l) => null, (error) => Log.error(error));
     result.fold((l) => null, (error) => Log.error(error));
   }
   }
 
 

+ 9 - 8
frontend/app_flowy/lib/workspace/application/trash/trash_bloc.dart

@@ -1,20 +1,21 @@
-import 'package:app_flowy/workspace/infrastructure/repos/trash_repo.dart';
 import 'package:dartz/dartz.dart';
 import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/trash.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/trash.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
+import 'package:app_flowy/workspace/application/trash/trash_service.dart';
+import 'package:app_flowy/workspace/application/trash/trash_listener.dart';
 part 'trash_bloc.freezed.dart';
 part 'trash_bloc.freezed.dart';
 
 
 class TrashBloc extends Bloc<TrashEvent, TrashState> {
 class TrashBloc extends Bloc<TrashEvent, TrashState> {
-  final TrashRepo repo;
+  final TrashService service;
   final TrashListener listener;
   final TrashListener listener;
-  TrashBloc({required this.repo, required this.listener}) : super(TrashState.init()) {
+  TrashBloc({required this.service, required this.listener}) : super(TrashState.init()) {
     on<TrashEvent>((event, emit) async {
     on<TrashEvent>((event, emit) async {
       await event.map(initial: (e) async {
       await event.map(initial: (e) async {
         listener.startListening(trashUpdated: _listenTrashUpdated);
         listener.startListening(trashUpdated: _listenTrashUpdated);
-        final result = await repo.readTrash();
+        final result = await service.readTrash();
         emit(result.fold(
         emit(result.fold(
           (object) => state.copyWith(objects: object.items, successOrFailure: left(unit)),
           (object) => state.copyWith(objects: object.items, successOrFailure: left(unit)),
           (error) => state.copyWith(successOrFailure: right(error)),
           (error) => state.copyWith(successOrFailure: right(error)),
@@ -22,16 +23,16 @@ class TrashBloc extends Bloc<TrashEvent, TrashState> {
       }, didReceiveTrash: (e) async {
       }, didReceiveTrash: (e) async {
         emit(state.copyWith(objects: e.trash));
         emit(state.copyWith(objects: e.trash));
       }, putback: (e) async {
       }, putback: (e) async {
-        final result = await repo.putback(e.trashId);
+        final result = await service.putback(e.trashId);
         await _handleResult(result, emit);
         await _handleResult(result, emit);
       }, delete: (e) async {
       }, delete: (e) async {
-        final result = await repo.deleteViews([Tuple2(e.trash.id, e.trash.ty)]);
+        final result = await service.deleteViews([Tuple2(e.trash.id, e.trash.ty)]);
         await _handleResult(result, emit);
         await _handleResult(result, emit);
       }, deleteAll: (e) async {
       }, deleteAll: (e) async {
-        final result = await repo.deleteAll();
+        final result = await service.deleteAll();
         await _handleResult(result, emit);
         await _handleResult(result, emit);
       }, restoreAll: (e) async {
       }, restoreAll: (e) async {
-        final result = await repo.restoreAll();
+        final result = await service.restoreAll();
         await _handleResult(result, emit);
         await _handleResult(result, emit);
       });
       });
     });
     });

+ 2 - 34
frontend/app_flowy/lib/workspace/infrastructure/repos/trash_repo.dart → frontend/app_flowy/lib/workspace/application/trash/trash_listener.dart

@@ -1,45 +1,13 @@
 import 'dart:async';
 import 'dart:async';
 import 'dart:typed_data';
 import 'dart:typed_data';
-import 'package:app_flowy/workspace/infrastructure/repos/helper.dart';
 import 'package:dartz/dartz.dart';
 import 'package:dartz/dartz.dart';
-import 'package:flowy_sdk/dispatch/dispatch.dart';
+import 'package:app_flowy/core/helper.dart';
 import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
 import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/trash.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/trash.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
 import 'package:flowy_sdk/rust_stream.dart';
 import 'package:flowy_sdk/rust_stream.dart';
 
 
-class TrashRepo {
-  Future<Either<RepeatedTrash, FlowyError>> readTrash() {
-    return FolderEventReadTrash().send();
-  }
-
-  Future<Either<Unit, FlowyError>> putback(String trashId) {
-    final id = TrashId.create()..id = trashId;
-
-    return FolderEventPutbackTrash(id).send();
-  }
-
-  Future<Either<Unit, FlowyError>> deleteViews(List<Tuple2<String, TrashType>> trashList) {
-    final items = trashList.map((trash) {
-      return TrashId.create()
-        ..id = trash.value1
-        ..ty = trash.value2;
-    });
-
-    final ids = RepeatedTrashId(items: items);
-    return FolderEventDeleteTrash(ids).send();
-  }
-
-  Future<Either<Unit, FlowyError>> restoreAll() {
-    return FolderEventRestoreAllTrash().send();
-  }
-
-  Future<Either<Unit, FlowyError>> deleteAll() {
-    return FolderEventDeleteAllTrash().send();
-  }
-}
-
 typedef TrashUpdatedCallback = void Function(Either<List<Trash>, FlowyError> trashOrFailed);
 typedef TrashUpdatedCallback = void Function(Either<List<Trash>, FlowyError> trashOrFailed);
 
 
 class TrashListener {
 class TrashListener {

+ 37 - 0
frontend/app_flowy/lib/workspace/application/trash/trash_service.dart

@@ -0,0 +1,37 @@
+import 'dart:async';
+import 'package:dartz/dartz.dart';
+import 'package:flowy_sdk/dispatch/dispatch.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-folder-data-model/trash.pb.dart';
+
+class TrashService {
+  Future<Either<RepeatedTrash, FlowyError>> readTrash() {
+    return FolderEventReadTrash().send();
+  }
+
+  Future<Either<Unit, FlowyError>> putback(String trashId) {
+    final id = TrashId.create()..id = trashId;
+
+    return FolderEventPutbackTrash(id).send();
+  }
+
+  Future<Either<Unit, FlowyError>> deleteViews(List<Tuple2<String, TrashType>> trashList) {
+    final items = trashList.map((trash) {
+      return TrashId.create()
+        ..id = trash.value1
+        ..ty = trash.value2;
+    });
+
+    final ids = RepeatedTrashId(items: items);
+    return FolderEventDeleteTrash(ids).send();
+  }
+
+  Future<Either<Unit, FlowyError>> restoreAll() {
+    return FolderEventRestoreAllTrash().send();
+  }
+
+  Future<Either<Unit, FlowyError>> deleteAll() {
+    return FolderEventDeleteAllTrash().send();
+  }
+}
+

+ 11 - 9
frontend/app_flowy/lib/workspace/application/view/view_bloc.dart

@@ -1,4 +1,5 @@
-import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
+import 'package:app_flowy/workspace/application/view/view_listener.dart';
+import 'package:app_flowy/workspace/application/view/view_service.dart';
 import 'package:dartz/dartz.dart';
 import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
@@ -8,18 +9,19 @@ import 'package:freezed_annotation/freezed_annotation.dart';
 part 'view_bloc.freezed.dart';
 part 'view_bloc.freezed.dart';
 
 
 class ViewBloc extends Bloc<ViewEvent, ViewState> {
 class ViewBloc extends Bloc<ViewEvent, ViewState> {
-  final ViewRepository repo;
-
+  final ViewService service;
   final ViewListener listener;
   final ViewListener listener;
+  final View view;
 
 
   ViewBloc({
   ViewBloc({
-    required this.repo,
+    required this.view,
+    required this.service,
     required this.listener,
     required this.listener,
-  }) : super(ViewState.init(repo.view)) {
+  }) : super(ViewState.init(view)) {
     on<ViewEvent>((event, emit) async {
     on<ViewEvent>((event, emit) async {
       await event.map(
       await event.map(
         initial: (e) {
         initial: (e) {
-          // TODO: Listener can be refctored to a stream.
+          // TODO: Listener can be refactored to a stream.
           listener.updatedNotifier.addPublishListener((result) {
           listener.updatedNotifier.addPublishListener((result) {
             // emit.forEach(stream, onData: onData)
             // emit.forEach(stream, onData: onData)
             add(ViewEvent.viewDidUpdate(result));
             add(ViewEvent.viewDidUpdate(result));
@@ -37,7 +39,7 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
           );
           );
         },
         },
         rename: (e) async {
         rename: (e) async {
-          final result = await repo.updateView(name: e.newName);
+          final result = await service.updateView(viewId: view.id, name: e.newName);
           emit(
           emit(
             result.fold(
             result.fold(
               (l) => state.copyWith(successOrFailure: left(unit)),
               (l) => state.copyWith(successOrFailure: left(unit)),
@@ -46,7 +48,7 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
           );
           );
         },
         },
         delete: (e) async {
         delete: (e) async {
-          final result = await repo.delete();
+          final result = await service.delete(viewId: view.id);
           emit(
           emit(
             result.fold(
             result.fold(
               (l) => state.copyWith(successOrFailure: left(unit)),
               (l) => state.copyWith(successOrFailure: left(unit)),
@@ -55,7 +57,7 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
           );
           );
         },
         },
         duplicate: (e) async {
         duplicate: (e) async {
-          final result = await repo.duplicate();
+          final result = await service.duplicate(viewId: view.id);
           emit(
           emit(
             result.fold(
             result.fold(
               (l) => state.copyWith(successOrFailure: left(unit)),
               (l) => state.copyWith(successOrFailure: left(unit)),

+ 1 - 39
frontend/app_flowy/lib/workspace/infrastructure/repos/view_repo.dart → frontend/app_flowy/lib/workspace/application/view/view_listener.dart

@@ -1,7 +1,7 @@
 import 'dart:async';
 import 'dart:async';
 import 'dart:typed_data';
 import 'dart:typed_data';
+import 'package:app_flowy/core/helper.dart';
 import 'package:dartz/dartz.dart';
 import 'package:dartz/dartz.dart';
-import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
 import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
@@ -9,44 +9,6 @@ import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
 import 'package:flowy_sdk/rust_stream.dart';
 import 'package:flowy_sdk/rust_stream.dart';
 import 'package:flowy_infra/notifier.dart';
 import 'package:flowy_infra/notifier.dart';
 
 
-import 'helper.dart';
-
-class ViewRepository {
-  View view;
-  ViewRepository({
-    required this.view,
-  });
-
-  Future<Either<View, FlowyError>> readView() {
-    final request = ViewId(value: view.id);
-    return FolderEventReadView(request).send();
-  }
-
-  Future<Either<View, FlowyError>> updateView({String? name, String? desc}) {
-    final request = UpdateViewPayload.create()..viewId = view.id;
-
-    if (name != null) {
-      request.name = name;
-    }
-
-    if (desc != null) {
-      request.desc = desc;
-    }
-
-    return FolderEventUpdateView(request).send();
-  }
-
-  Future<Either<Unit, FlowyError>> delete() {
-    final request = RepeatedViewId.create()..items.add(view.id);
-    return FolderEventDeleteView(request).send();
-  }
-
-  Future<Either<Unit, FlowyError>> duplicate() {
-    final request = ViewId(value: view.id);
-    return FolderEventDuplicateView(request).send();
-  }
-}
-
 typedef DeleteNotifierValue = Either<View, FlowyError>;
 typedef DeleteNotifierValue = Either<View, FlowyError>;
 typedef UpdateNotifierValue = Either<View, FlowyError>;
 typedef UpdateNotifierValue = Either<View, FlowyError>;
 typedef RestoreNotifierValue = Either<View, FlowyError>;
 typedef RestoreNotifierValue = Either<View, FlowyError>;

+ 36 - 0
frontend/app_flowy/lib/workspace/application/view/view_service.dart

@@ -0,0 +1,36 @@
+import 'dart:async';
+import 'package:dartz/dartz.dart';
+import 'package:flowy_sdk/dispatch/dispatch.dart';
+import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+
+class ViewService {
+  Future<Either<View, FlowyError>> readView({required String viewId}) {
+    final request = ViewId(value: viewId);
+    return FolderEventReadView(request).send();
+  }
+
+  Future<Either<View, FlowyError>> updateView({required String viewId, String? name, String? desc}) {
+    final request = UpdateViewPayload.create()..viewId = viewId;
+
+    if (name != null) {
+      request.name = name;
+    }
+
+    if (desc != null) {
+      request.desc = desc;
+    }
+
+    return FolderEventUpdateView(request).send();
+  }
+
+  Future<Either<Unit, FlowyError>> delete({required String viewId}) {
+    final request = RepeatedViewId.create()..items.add(viewId);
+    return FolderEventDeleteView(request).send();
+  }
+
+  Future<Either<Unit, FlowyError>> duplicate({required String viewId}) {
+    final request = ViewId(value: viewId);
+    return FolderEventDuplicateView(request).send();
+  }
+}

+ 11 - 10
frontend/app_flowy/lib/workspace/application/workspace/welcome_bloc.dart

@@ -1,4 +1,5 @@
-import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
+import 'package:app_flowy/user/application/user_listener.dart';
+import 'package:app_flowy/user/application/user_service.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
@@ -9,14 +10,14 @@ import 'package:dartz/dartz.dart';
 part 'welcome_bloc.freezed.dart';
 part 'welcome_bloc.freezed.dart';
 
 
 class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
 class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
-  final UserRepo repo;
-  final UserListener listener;
-  WelcomeBloc({required this.repo, required this.listener}) : super(WelcomeState.initial()) {
+  final UserService userService;
+  final UserListener userListener;
+  WelcomeBloc({required this.userService, required this.userListener}) : super(WelcomeState.initial()) {
     on<WelcomeEvent>(
     on<WelcomeEvent>(
       (event, emit) async {
       (event, emit) async {
         await event.map(initial: (e) async {
         await event.map(initial: (e) async {
-          listener.workspaceUpdatedNotifier.addPublishListener(_workspacesUpdated);
-          listener.start();
+          userListener.workspaceUpdatedNotifier.addPublishListener(_workspacesUpdated);
+          userListener.start();
           //
           //
           await _fetchWorkspaces(emit);
           await _fetchWorkspaces(emit);
         }, openWorkspace: (e) async {
         }, openWorkspace: (e) async {
@@ -35,12 +36,12 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
 
 
   @override
   @override
   Future<void> close() async {
   Future<void> close() async {
-    await listener.stop();
+    await userListener.stop();
     super.close();
     super.close();
   }
   }
 
 
   Future<void> _fetchWorkspaces(Emitter<WelcomeState> emit) async {
   Future<void> _fetchWorkspaces(Emitter<WelcomeState> emit) async {
-    final workspacesOrFailed = await repo.getWorkspaces();
+    final workspacesOrFailed = await userService.getWorkspaces();
     emit(workspacesOrFailed.fold(
     emit(workspacesOrFailed.fold(
       (workspaces) => state.copyWith(workspaces: workspaces, successOrFailure: left(unit)),
       (workspaces) => state.copyWith(workspaces: workspaces, successOrFailure: left(unit)),
       (error) {
       (error) {
@@ -51,7 +52,7 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
   }
   }
 
 
   Future<void> _openWorkspace(Workspace workspace, Emitter<WelcomeState> emit) async {
   Future<void> _openWorkspace(Workspace workspace, Emitter<WelcomeState> emit) async {
-    final result = await repo.openWorkspace(workspace.id);
+    final result = await userService.openWorkspace(workspace.id);
     emit(result.fold(
     emit(result.fold(
       (workspaces) => state.copyWith(successOrFailure: left(unit)),
       (workspaces) => state.copyWith(successOrFailure: left(unit)),
       (error) {
       (error) {
@@ -62,7 +63,7 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
   }
   }
 
 
   Future<void> _createWorkspace(String name, String desc, Emitter<WelcomeState> emit) async {
   Future<void> _createWorkspace(String name, String desc, Emitter<WelcomeState> emit) async {
-    final result = await repo.createWorkspace(name, desc);
+    final result = await userService.createWorkspace(name, desc);
     emit(result.fold(
     emit(result.fold(
       (workspace) {
       (workspace) {
         return state.copyWith(successOrFailure: left(unit));
         return state.copyWith(successOrFailure: left(unit));

+ 15 - 63
frontend/app_flowy/lib/workspace/infrastructure/repos/workspace_repo.dart → frontend/app_flowy/lib/workspace/application/workspace/workspace_listener.dart

@@ -1,10 +1,9 @@
 import 'dart:async';
 import 'dart:async';
 import 'dart:typed_data';
 import 'dart:typed_data';
 
 
+import 'package:app_flowy/core/helper.dart';
 import 'package:dartz/dartz.dart';
 import 'package:dartz/dartz.dart';
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/log.dart';
-import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
 import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile;
 import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile;
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
@@ -12,56 +11,28 @@ import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
 import 'package:flowy_sdk/rust_stream.dart';
 import 'package:flowy_sdk/rust_stream.dart';
-import 'package:app_flowy/generated/locale_keys.g.dart';
 
 
-import 'helper.dart';
 
 
-class WorkspaceRepo {
-  UserProfile user;
-  String workspaceId;
-  WorkspaceRepo({
-    required this.user,
-    required this.workspaceId,
-  });
-
-  Future<Either<App, FlowyError>> createApp(String name, String desc) {
-    final request = CreateAppPayload.create()
-      ..name = name
-      ..workspaceId = workspaceId
-      ..desc = desc;
-    return FolderEventCreateApp(request).send();
-  }
+typedef WorkspaceAppsChangedCallback = void Function(Either<List<App>, FlowyError> appsOrFail);
+typedef WorkspaceUpdatedCallback = void Function(String name, String desc);
 
 
-  Future<Either<Workspace, FlowyError>> getWorkspace() {
-    final request = WorkspaceId.create()..value = workspaceId;
-    return FolderEventReadWorkspaces(request).send().then((result) {
-      return result.fold(
-        (workspaces) {
-          assert(workspaces.items.length == 1);
+class WorkspaceListener {
+  WorkspaceListenerService service;
+  WorkspaceListener({
+    required this.service,
+  });
 
 
-          if (workspaces.items.isEmpty) {
-            return right(FlowyError.create()..msg = LocaleKeys.workspace_notFoundError.tr());
-          } else {
-            return left(workspaces.items[0]);
-          }
-        },
-        (error) => right(error),
-      );
-    });
+  void start({WorkspaceAppsChangedCallback? addAppCallback, WorkspaceUpdatedCallback? updatedCallback}) {
+    service.startListening(appsChanged: addAppCallback, update: updatedCallback);
   }
   }
 
 
-  Future<Either<List<App>, FlowyError>> getApps() {
-    final request = WorkspaceId.create()..value = workspaceId;
-    return FolderEventReadWorkspaceApps(request).send().then((result) {
-      return result.fold(
-        (apps) => left(apps.items),
-        (error) => right(error),
-      );
-    });
+  Future<void> stop() async {
+    await service.close();
   }
   }
 }
 }
 
 
-class WorkspaceListenerRepo {
+
+class WorkspaceListenerService {
   StreamSubscription<SubscribeObject>? _subscription;
   StreamSubscription<SubscribeObject>? _subscription;
   WorkspaceAppsChangedCallback? _appsChanged;
   WorkspaceAppsChangedCallback? _appsChanged;
   WorkspaceUpdatedCallback? _update;
   WorkspaceUpdatedCallback? _update;
@@ -69,7 +40,7 @@ class WorkspaceListenerRepo {
   final UserProfile user;
   final UserProfile user;
   final String workspaceId;
   final String workspaceId;
 
 
-  WorkspaceListenerRepo({
+  WorkspaceListenerService({
     required this.user,
     required this.user,
     required this.workspaceId,
     required this.workspaceId,
   });
   });
@@ -125,22 +96,3 @@ class WorkspaceListenerRepo {
     // _update = null;
     // _update = null;
   }
   }
 }
 }
-
-typedef WorkspaceAppsChangedCallback = void Function(Either<List<App>, FlowyError> appsOrFail);
-
-typedef WorkspaceUpdatedCallback = void Function(String name, String desc);
-
-class WorkspaceListener {
-  WorkspaceListenerRepo repo;
-  WorkspaceListener({
-    required this.repo,
-  });
-
-  void start({WorkspaceAppsChangedCallback? addAppCallback, WorkspaceUpdatedCallback? updatedCallback}) {
-    repo.startListening(appsChanged: addAppCallback, update: updatedCallback);
-  }
-
-  Future<void> stop() async {
-    await repo.close();
-  }
-}

+ 46 - 0
frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart

@@ -0,0 +1,46 @@
+import 'dart:async';
+import 'package:dartz/dartz.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flowy_sdk/dispatch/dispatch.dart';
+import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:app_flowy/generated/locale_keys.g.dart';
+
+class WorkspaceService {
+  Future<Either<App, FlowyError>> createApp({required String workspaceId, required String name, required String desc}) {
+    final request = CreateAppPayload.create()
+      ..name = name
+      ..workspaceId = workspaceId
+      ..desc = desc;
+    return FolderEventCreateApp(request).send();
+  }
+
+  Future<Either<Workspace, FlowyError>> getWorkspace({required String workspaceId}) {
+    final request = WorkspaceId.create()..value = workspaceId;
+    return FolderEventReadWorkspaces(request).send().then((result) {
+      return result.fold(
+        (workspaces) {
+          assert(workspaces.items.length == 1);
+
+          if (workspaces.items.isEmpty) {
+            return right(FlowyError.create()..msg = LocaleKeys.workspace_notFoundError.tr());
+          } else {
+            return left(workspaces.items[0]);
+          }
+        },
+        (error) => right(error),
+      );
+    });
+  }
+
+  Future<Either<List<App>, FlowyError>> getApps({required String workspaceId}) {
+    final request = WorkspaceId.create()..value = workspaceId;
+    return FolderEventReadWorkspaceApps(request).send().then((result) {
+      return result.fold(
+        (apps) => left(apps.items),
+        (error) => right(error),
+      );
+    });
+  }
+}

+ 5 - 4
frontend/app_flowy/lib/workspace/presentation/stack_page/doc/doc_stack_page.dart

@@ -1,9 +1,10 @@
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/workspace/application/appearance.dart';
 import 'package:app_flowy/workspace/application/appearance.dart';
 import 'package:app_flowy/workspace/application/doc/share_bloc.dart';
 import 'package:app_flowy/workspace/application/doc/share_bloc.dart';
+import 'package:app_flowy/workspace/application/view/view_listener.dart';
+import 'package:app_flowy/workspace/application/view/view_service.dart';
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
 import 'package:app_flowy/workspace/domain/view_ext.dart';
 import 'package:app_flowy/workspace/domain/view_ext.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
 import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
 import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
 import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.dart';
 import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:easy_localization/easy_localization.dart';
@@ -92,11 +93,11 @@ class DocumentLeftBarItem extends StatefulWidget {
 class _DocumentLeftBarItemState extends State<DocumentLeftBarItem> {
 class _DocumentLeftBarItemState extends State<DocumentLeftBarItem> {
   final _controller = TextEditingController();
   final _controller = TextEditingController();
   final _focusNode = FocusNode();
   final _focusNode = FocusNode();
-  late ViewRepository repo;
+  late ViewService service;
 
 
   @override
   @override
   void initState() {
   void initState() {
-    repo = ViewRepository(view: widget.view);
+    service = ViewService(/*view: widget.view*/);
     _focusNode.addListener(_handleFocusChanged);
     _focusNode.addListener(_handleFocusChanged);
     super.initState();
     super.initState();
   }
   }
@@ -143,7 +144,7 @@ class _DocumentLeftBarItemState extends State<DocumentLeftBarItem> {
     }
     }
 
 
     if (_controller.text != widget.view.name) {
     if (_controller.text != widget.view.name) {
-      repo.updateView(name: _controller.text);
+      service.updateView(viewId: widget.view.id, name: _controller.text);
     }
     }
   }
   }
 }
 }