appflowy 3 rokov pred
rodič
commit
b16b61f46c
46 zmenil súbory, kde vykonal 495 pridanie a 415 odobranie
  1. 3 2
      .github/workflows/ci.yaml
  2. 36 13
      .github/workflows/dart_test.yml
  3. 2 2
      .github/workflows/release.yml
  4. 2 2
      .github/workflows/rust_lint.yml
  5. 30 12
      .github/workflows/rust_test.yml
  6. 0 0
      frontend/app_flowy/lib/core/helper.dart
  7. 32 22
      frontend/app_flowy/lib/startup/deps_resolver.dart
  8. 1 1
      frontend/app_flowy/lib/startup/startup.dart
  9. 1 58
      frontend/app_flowy/lib/user/application/user_listener.dart
  10. 57 0
      frontend/app_flowy/lib/user/application/user_service.dart
  11. 3 5
      frontend/app_flowy/lib/user/infrastructure/router.dart
  12. 1 1
      frontend/app_flowy/lib/user/presentation/skip_log_in_screen.dart
  13. 4 4
      frontend/app_flowy/lib/user/presentation/welcome_screen.dart
  14. 11 7
      frontend/app_flowy/lib/workspace/application/app/app_bloc.dart
  15. 2 58
      frontend/app_flowy/lib/workspace/application/app/app_listener.dart
  16. 57 0
      frontend/app_flowy/lib/workspace/application/app/app_service.dart
  17. 19 12
      frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart
  18. 24 0
      frontend/app_flowy/lib/workspace/application/doc/doc_service.dart
  19. 5 5
      frontend/app_flowy/lib/workspace/application/doc/share_bloc.dart
  20. 1 1
      frontend/app_flowy/lib/workspace/application/doc/share_service.dart
  21. 1 1
      frontend/app_flowy/lib/workspace/application/home/home_listen_bloc.dart
  22. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/delta_markdown.dart
  23. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/ast.dart
  24. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/block_parser.dart
  25. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/delta_markdown_decoder.dart
  26. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/delta_markdown_encoder.dart
  27. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/document.dart
  28. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/emojis.dart
  29. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/extension_set.dart
  30. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/html_renderer.dart
  31. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/inline_parser.dart
  32. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/util.dart
  33. 0 0
      frontend/app_flowy/lib/workspace/application/markdown/src/version.dart
  34. 8 5
      frontend/app_flowy/lib/workspace/application/menu/menu_bloc.dart
  35. 11 9
      frontend/app_flowy/lib/workspace/application/menu/menu_user_bloc.dart
  36. 9 8
      frontend/app_flowy/lib/workspace/application/trash/trash_bloc.dart
  37. 2 34
      frontend/app_flowy/lib/workspace/application/trash/trash_listener.dart
  38. 37 0
      frontend/app_flowy/lib/workspace/application/trash/trash_service.dart
  39. 13 10
      frontend/app_flowy/lib/workspace/application/view/view_bloc.dart
  40. 1 57
      frontend/app_flowy/lib/workspace/application/view/view_listener.dart
  41. 36 0
      frontend/app_flowy/lib/workspace/application/view/view_service.dart
  42. 11 10
      frontend/app_flowy/lib/workspace/application/workspace/welcome_bloc.dart
  43. 15 63
      frontend/app_flowy/lib/workspace/application/workspace/workspace_listener.dart
  44. 46 0
      frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart
  45. 9 9
      frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart
  46. 5 4
      frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart

+ 3 - 2
.github/workflows/ci.yaml

@@ -27,7 +27,7 @@ jobs:
       - id: rust_toolchain
         uses: actions-rs/toolchain@v1
         with:
-          toolchain: stable
+          toolchain: 'stable-2022-01-20'
       
       - id: flutter
         uses: subosito/flutter-action@v2
@@ -47,7 +47,8 @@ jobs:
         with: 
           path: |
             frontend/rust-lib/target
-          key: ${{ runner.os }}-rust-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}    
+            shared-lib/target
+          key: ${{ runner.os }}-rust-rust-lib-share-lib-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}    
 
       - name: Setup Environment
         run:   |

+ 36 - 13
.github/workflows/dart_test.yml

@@ -2,9 +2,12 @@ name: Unit test(Flutter)
 
 on:
   push:
-    branches: [ main ]
+    branches:
+      - 'main'
+      
   pull_request:
-    branches: [ main ]
+    branches:
+      - 'main'
 
 env:
   CARGO_TERM_COLOR: always
@@ -13,36 +16,56 @@ jobs:
   tests:
     runs-on: ubuntu-latest
     steps:
-      - name: Checkout
-        uses: actions/checkout@v2
-      - uses: subosito/flutter-action@v1
-        with:
-          channel: "stable"
+      - uses: actions/checkout@v2
+      
       - uses: actions-rs/toolchain@v1
         with:
-          toolchain: stable
+          toolchain: 'stable-2022-01-20'
+      
+      - uses: subosito/flutter-action@v2
+        with:
+          channel: 'stable'
+          cache: true
+
+      - name: Cache Cargo
+        uses: actions/cache@v2
+        with: 
+          path: |
+            ~/.cargo
+          key: ${{ runner.os }}-cargo-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
+
+      - name: Cache Rust
+        uses: actions/cache@v2
+        with: 
+          path: |
+            frontend/rust-lib/target
+            shared-lib/target
+          key: ${{ runner.os }}-rust-rust-lib-share-lib-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}    
+
       - name: Deps Flutter
+        working-directory: frontend/app_flowy
         run: |
           flutter config --enable-linux-desktop
-          flutter doctor
-        working-directory: frontend/app_flowy
+        
       - name: Deps Rust
         working-directory: frontend
         run: |
-          cargo install --force cargo-make
-          cargo install --force duckscript_cli
+          cargo install cargo-make
+          cargo install duckscript_cli
           cargo make flowy_dev
-          echo PATH="$PATH":"$HOME/.pub-cache/bin" >> $GITHUB_PATH
+      
       - name: Code Generation
         working-directory: frontend/app_flowy
         run: |
           flutter packages pub get
           flutter packages pub run easy_localization:generate -S ./assets/translations -f keys -O lib/generated -o locale_keys.g.dart
           flutter packages pub run build_runner build --delete-conflicting-outputs
+      
       - name: Build FlowySDK
         working-directory: frontend
         run: |
           cargo make --profile development-linux-x86 flowy-sdk-dev
+      
       - name: Run bloc tests
         working-directory: frontend/app_flowy
         run: |

+ 2 - 2
.github/workflows/release.yml

@@ -44,7 +44,7 @@ jobs:
       - name: Setup environment - Rust and Cargo
         uses: actions-rs/toolchain@v1
         with:
-          toolchain: stable
+          toolchain: 'stable-2022-01-20'
 
       - name: Setup environment - Flutter
         uses: subosito/flutter-action@v2
@@ -92,7 +92,7 @@ jobs:
       - name: Setup environment - Rust and Cargo
         uses: actions-rs/toolchain@v1
         with:
-          toolchain: stable
+          toolchain: 'stable-2022-01-20'
 
       - name: Setup environment - Flutter
         uses: subosito/flutter-action@v2

+ 2 - 2
.github/workflows/rust_lint.yml

@@ -24,7 +24,7 @@ jobs:
       - uses: actions/checkout@v2
       - uses: actions-rs/toolchain@v1
         with:
-          toolchain: stable
+          toolchain: 'stable-2022-01-20'
           override: true
       - run: rustup component add rustfmt
         working-directory: frontend/rust-lib
@@ -39,7 +39,7 @@ jobs:
       - uses: actions/checkout@v2
       - uses: actions-rs/toolchain@v1
         with:
-          toolchain: stable
+          toolchain: 'stable-2022-01-20'
           override: true
       - run: rustup component add clippy
         working-directory: frontend/rust-lib

+ 30 - 12
.github/workflows/rust_test.yml

@@ -2,12 +2,14 @@ name: Unit test(Rust)
 
 on:
   push:
-    branches: [ main ]
+    branches: 
+      - 'main'
     paths:
       - 'frontend/rust-lib'
       - 'shared-lib'
   pull_request:
-    branches: [ main ]
+    branches: 
+      - 'main'
     paths:
       - 'frontend/rust-lib'
       - 'shared-lib'
@@ -21,19 +23,35 @@ jobs:
     steps:
       - name: Checkout
         uses: actions/checkout@v2
-      - name: Install Rust
-        run: |
-          curl \
-            --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
-          source $HOME/.cargo/env
-          rustup toolchain install stable
-          rustup default stable
+      
+      - id: rust_toolchain
+        uses: actions-rs/toolchain@v1
+        with:
+          toolchain: 'stable-2022-01-20'
+
+      - name: Cache Cargo
+        uses: actions/cache@v2
+        with: 
+          path: |
+            ~/.cargo
+          key: ${{ runner.os }}-cargo-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
+
+      - name: Cache Rust
+        uses: actions/cache@v2
+        with: 
+          path: |
+            frontend/rust-lib/target
+            shared-lib/target
+          key: ${{ runner.os }}-rust-rust-lib-share-lib-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}    
+
       - name: Install cargo-make
-        run: cargo install --force cargo-make
         working-directory: frontend
+        run: cargo install cargo-make
+        
       - name: Run rust-lib tests
-        run: cargo test --no-default-features
         working-directory: frontend/rust-lib
-      - name: Run shared-lib tests
         run: cargo test --no-default-features
+        
+      - name: Run shared-lib tests
         working-directory: shared-lib
+        run: cargo test --no-default-features

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


+ 32 - 22
frontend/app_flowy/lib/workspace/infrastructure/deps_resolver.dart → frontend/app_flowy/lib/startup/deps_resolver.dart

@@ -1,23 +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_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_service.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/menu/menu_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_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_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/infrastructure/repos/app_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:app_flowy/workspace/application/workspace/workspace_listener.dart';
+import 'package:app_flowy/workspace/application/workspace/workspace_service.dart';
 import 'package:app_flowy/workspace/presentation/home/home_stack.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-user-data-model/user_profile.pb.dart';
 import 'package:get_it/get_it.dart';
-import 'repos/share_repo.dart';
 
 class HomeDepsResolver {
   static Future<void> resolve(GetIt getIt) async {
@@ -33,23 +39,24 @@ class HomeDepsResolver {
     getIt.registerLazySingleton<HomeStackManager>(() => HomeStackManager());
     getIt.registerFactoryParam<WelcomeBloc, UserProfile, void>(
       (user, _) => WelcomeBloc(
-        repo: UserRepo(user: user),
-        listener: getIt<UserListener>(param1: user),
+        userService: UserService(),
+        userListener: getIt<UserListener>(param1: user),
       ),
     );
 
     //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
     getIt.registerFactoryParam<ViewListener, View, void>(
       (view, _) => ViewListener(view: view),
     );
 
-    getIt.registerFactoryParam<ViewMenuBloc, View, void>(
-      (view, _) => ViewMenuBloc(
-        repo: ViewRepository(view: view),
+    getIt.registerFactoryParam<ViewBloc, View, void>(
+      (view, _) => ViewBloc(
+        view: view,
+        service: ViewService(),
         listener: getIt<ViewListener>(param1: view),
       ),
     );
@@ -57,14 +64,16 @@ class HomeDepsResolver {
     //Menu Bloc
     getIt.registerFactoryParam<MenuBloc, UserProfile, String>(
       (user, workspaceId) => MenuBloc(
-        repo: WorkspaceRepo(user: user, workspaceId: workspaceId),
+        workspaceId: workspaceId,
+        service: WorkspaceService(),
         listener: getIt<WorkspaceListener>(param1: user, param2: workspaceId),
       ),
     );
 
     getIt.registerFactoryParam<MenuUserBloc, UserProfile, void>(
       (user, _) => MenuUserBloc(
-        UserRepo(user: user),
+        user,
+        UserService(),
         getIt<UserListener>(param1: user),
       ),
     );
@@ -73,7 +82,7 @@ class HomeDepsResolver {
     getIt.registerFactoryParam<AppBloc, App, void>(
       (app, _) => AppBloc(
         app: app,
-        repo: AppRepository(appId: app.id),
+        service: AppService(),
         listener: AppListener(appId: app.id),
       ),
     );
@@ -81,25 +90,26 @@ class HomeDepsResolver {
     // Doc
     getIt.registerFactoryParam<DocumentBloc, View, void>(
       (view, _) => DocumentBloc(
-        repo: ViewRepository(view: view),
+        view: view,
+        service: DocumentService(),
         listener: getIt<ViewListener>(param1: view),
-        trashRepo: getIt<TrashRepo>(),
+        trashService: getIt<TrashService>(),
       ),
     );
 
     // trash
-    getIt.registerLazySingleton<TrashRepo>(() => TrashRepo());
+    getIt.registerLazySingleton<TrashService>(() => TrashService());
     getIt.registerLazySingleton<TrashListener>(() => TrashListener());
     getIt.registerFactory<TrashBloc>(
       () => TrashBloc(
-        repo: getIt<TrashRepo>(),
+        service: getIt<TrashService>(),
         listener: getIt<TrashListener>(),
       ),
     );
 
     // share
-    getIt.registerLazySingleton<ShareRepo>(() => ShareRepo());
+    getIt.registerLazySingleton<ShareService>(() => ShareService());
     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

@@ -5,7 +5,7 @@ import 'package:app_flowy/startup/tasks/prelude.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.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: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 '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 '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_sdk/protobuf/dart-notify/protobuf.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/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/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 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/skip_log_in_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:flowy_infra/time/duration.dart';
 import 'package:flowy_infra_ui/widget/route/animation.dart';
@@ -38,9 +37,8 @@ class AuthRouter {
 }
 
 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(
       PageRoutes.fade(
         () => screen,
@@ -48,7 +46,7 @@ class SplashRoute {
       ),
     );
 
-    pushHomeScreen(context, repo.user, workspaceId);
+    pushHomeScreen(context, userProfile, workspaceId);
   }
 
   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/repos/auth_repo.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:flowy_infra/size.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/widget/error_page.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_bloc/flutter_bloc.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
 
 class WelcomeScreen extends StatelessWidget {
-  final UserRepo repo;
+  final UserProfile userProfile;
   const WelcomeScreen({
     Key? key,
-    required this.repo,
+    required this.userProfile,
   }) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
     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>(
         builder: (context, state) {
           return Scaffold(

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

@@ -1,5 +1,6 @@
 import 'package:app_flowy/plugin/plugin.dart';
-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/protobuf/flowy-folder-data-model/app.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
@@ -11,9 +12,11 @@ import 'package:dartz/dartz.dart';
 part 'app_bloc.freezed.dart';
 
 class AppBloc extends Bloc<AppEvent, AppState> {
-  final AppRepository repo;
+  final App app;
+  final AppService service;
   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 {
       await event.map(initial: (e) async {
         listener.startListening(
@@ -22,7 +25,8 @@ class AppBloc extends Bloc<AppEvent, AppState> {
         );
         await _fetchViews(emit);
       }, createView: (CreateView value) async {
-        final viewOrFailed = await repo.createView(
+        final viewOrFailed = await service.createView(
+          appId: app.id,
           name: value.name,
           desc: value.desc,
           dataType: value.dataType,
@@ -41,13 +45,13 @@ class AppBloc extends Bloc<AppEvent, AppState> {
       }, didReceiveViews: (e) async {
         await handleDidReceiveViews(e.views, emit);
       }, delete: (e) async {
-        final result = await repo.delete();
+        final result = await service.delete(appId: app.id);
         result.fold(
           (unit) => emit(state.copyWith(successOrFailure: left(unit))),
           (error) => emit(state.copyWith(successOrFailure: right(error))),
         );
       }, rename: (e) async {
-        final result = await repo.updateApp(name: e.newName);
+        final result = await service.updateApp(appId: app.id, name: e.newName);
         result.fold(
           (l) => emit(state.copyWith(successOrFailure: left(unit))),
           (error) => emit(state.copyWith(successOrFailure: right(error))),
@@ -87,7 +91,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
   }
 
   Future<void> _fetchViews(Emitter<AppState> emit) async {
-    final viewsOrFailed = await repo.getViews();
+    final viewsOrFailed = await service.getViews(appId: app.id);
     viewsOrFailed.fold(
       (apps) => emit(state.copyWith(views: apps)),
       (error) {

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

@@ -1,70 +1,14 @@
 import 'dart:async';
 import 'dart:typed_data';
-import 'package:app_flowy/plugin/plugin.dart';
 import 'package:dartz/dartz.dart';
+import 'package:app_flowy/core/helper.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/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/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/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 PluginDataType dataType,
-    required PluginType pluginType,
-  }) {
-    final request = CreateViewPayload.create()
-      ..belongToId = appId
-      ..name = name
-      ..desc = desc
-      ..dataType = dataType
-      ..pluginType = pluginType;
-
-    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 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';
+import 'package:app_flowy/plugin/plugin.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 PluginDataType dataType,
+    required PluginType pluginType,
+  }) {
+    final request = CreateViewPayload.create()
+      ..belongToId = appId
+      ..name = name
+      ..desc = desc
+      ..dataType = dataType
+      ..pluginType = pluginType;
+
+    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();
+  }
+}

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

@@ -1,29 +1,35 @@
 import 'dart:convert';
-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-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flutter_quill/flutter_quill.dart' show Document, Delta;
 import 'package:flowy_sdk/log.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:dartz/dartz.dart';
 import 'dart:async';
+
 part 'doc_bloc.freezed.dart';
 
 typedef FlutterQuillDocument = Document;
 
 class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
-  final ViewRepository repo;
+  final View view;
+  final DocumentService service;
+
   final ViewListener listener;
-  final TrashRepo trashRepo;
+  final TrashService trashService;
   late FlutterQuillDocument document;
   StreamSubscription? _subscription;
 
   DocumentBloc({
-    required this.repo,
+    required this.view,
+    required this.service,
     required this.listener,
-    required this.trashRepo,
+    required this.trashService,
   }) : super(DocumentState.initial()) {
     on<DocumentEvent>((event, emit) async {
       await event.map(
@@ -37,12 +43,13 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
           emit(state.copyWith(isDeleted: false));
         },
         deletePermanently: (DeletePermanently value) async {
-          final result = await trashRepo.deleteViews([Tuple2(repo.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);
           emit(newState);
         },
         restorePage: (RestorePage value) async {
-          final result = await trashRepo.putback(repo.view.id);
+          final result = await trashService.putback(view.id);
           final newState = result.fold((l) => state.copyWith(isDeleted: false), (r) => state);
           emit(newState);
         },
@@ -58,7 +65,7 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
       await _subscription?.cancel();
     }
 
-    repo.closeDocument();
+    service.closeDocument(docId: view.id);
     return super.close();
   }
 
@@ -78,7 +85,7 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
     });
 
     listener.start();
-    final result = await repo.openDocument();
+    final result = await service.openDocument(docId: view.id);
     result.fold(
       (block) {
         document = _decodeJsonToDocument(block.deltaJson);
@@ -103,8 +110,8 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
 
   void _composeDelta(Delta composedDelta, Delta documentDelta) async {
     final json = jsonEncode(composedDelta.toJson());
-    Log.debug("doc_id: $repo.view.id - Send json: $json");
-    final result = await repo.composeDelta(data: json);
+    Log.debug("doc_id: $view.id - Send json: $json");
+    final result = await service.composeDelta(docId: view.id, data: json);
 
     result.fold((rustDoc) {
       // final json = utf8.decode(doc.data);

+ 24 - 0
frontend/app_flowy/lib/workspace/application/doc/doc_service.dart

@@ -0,0 +1,24 @@
+import 'package:dartz/dartz.dart';
+import 'package:flowy_sdk/dispatch/dispatch.dart';
+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-error/errors.pb.dart';
+
+class DocumentService {
+  Future<Either<BlockDelta, FlowyError>> openDocument({required String docId}) {
+    final request = ViewId(value: docId);
+    return FolderEventOpenView(request).send();
+  }
+
+  Future<Either<BlockDelta, FlowyError>> composeDelta({required String docId, required String data}) {
+    final request = BlockDelta.create()
+      ..blockId = docId
+      ..deltaJson = data;
+    return FolderEventApplyDocDelta(request).send();
+  }
+
+  Future<Either<Unit, FlowyError>> closeDocument({required String docId}) {
+    final request = ViewId(value: docId);
+    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/view.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';
 
 class DocShareBloc extends Bloc<DocShareEvent, DocShareState> {
-  ShareRepo repo;
+  ShareService service;
   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 {
       await event.map(
         shareMarkdown: (ShareMarkdown value) async {
-          await repo.exportMarkdown(view.id).then((result) {
+          await service.exportMarkdown(view.id).then((result) {
             result.fold(
               (value) => emit(DocShareState.finish(left(_convertDeltaToMarkdown(value)))),
               (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-error/errors.pb.dart';
 
-class ShareRepo {
+class ShareService {
   Future<Either<ExportData, FlowyError>> export(String docId, ExportType type) {
     final request = ExportPayload.create()
       ..viewId = 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-error/errors.pb.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,7 +1,8 @@
 import 'dart:async';
 import 'package:app_flowy/plugin/plugin.dart';
 import 'package:app_flowy/startup/tasks/load_plugin.dart';
-import 'package:app_flowy/workspace/infrastructure/repos/workspace_repo.dart';
+import 'package:app_flowy/workspace/application/workspace/workspace_listener.dart';
+import 'package:app_flowy/workspace/application/workspace/workspace_service.dart';
 import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
@@ -12,9 +13,11 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 part 'menu_bloc.freezed.dart';
 
 class MenuBloc extends Bloc<MenuEvent, MenuState> {
-  final WorkspaceRepo repo;
+  final WorkspaceService service;
   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 {
       await event.map(
         initial: (e) async {
@@ -48,7 +51,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
   }
 
   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(
       (app) => {},
       (error) {
@@ -60,7 +63,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
 
   // ignore: unused_element
   Future<void> _fetchApps(Emitter<MenuState> emit) async {
-    final appsOrFail = await repo.getApps();
+    final appsOrFail = await service.getApps(workspaceId: workspaceId);
     emit(appsOrFail.fold(
       (apps) => state.copyWith(apps: some(apps)),
       (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/protobuf/flowy-folder-data-model/workspace.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';
 
 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 {
       await event.map(
         initial: (_) async {
-          listener.profileUpdatedNotifier.addPublishListener(_profileUpdated);
-          listener.workspaceUpdatedNotifier.addPublishListener(_workspacesUpdated);
-          listener.start();
+          userListener.profileUpdatedNotifier.addPublishListener(_profileUpdated);
+          userListener.workspaceUpdatedNotifier.addPublishListener(_workspacesUpdated);
+          userListener.start();
           await _initUser();
         },
         fetchWorkspaces: (_FetchWorkspaces value) async {},
@@ -29,12 +31,12 @@ class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
 
   @override
   Future<void> close() async {
-    await listener.stop();
+    await userListener.stop();
     super.close();
   }
 
   Future<void> _initUser() async {
-    final result = await repo.initUser();
+    final result = await userService.initUser();
     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:flowy_sdk/log.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:flutter_bloc/flutter_bloc.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';
 
 class TrashBloc extends Bloc<TrashEvent, TrashState> {
-  final TrashRepo repo;
+  final TrashService service;
   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 {
       await event.map(initial: (e) async {
         listener.startListening(trashUpdated: _listenTrashUpdated);
-        final result = await repo.readTrash();
+        final result = await service.readTrash();
         emit(result.fold(
           (object) => state.copyWith(objects: object.items, successOrFailure: left(unit)),
           (error) => state.copyWith(successOrFailure: right(error)),
@@ -22,16 +23,16 @@ class TrashBloc extends Bloc<TrashEvent, TrashState> {
       }, didReceiveTrash: (e) async {
         emit(state.copyWith(objects: e.trash));
       }, putback: (e) async {
-        final result = await repo.putback(e.trashId);
+        final result = await service.putback(e.trashId);
         await _handleResult(result, emit);
       }, 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);
       }, deleteAll: (e) async {
-        final result = await repo.deleteAll();
+        final result = await service.deleteAll();
         await _handleResult(result, emit);
       }, restoreAll: (e) async {
-        final result = await repo.restoreAll();
+        final result = await service.restoreAll();
         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:typed_data';
-import 'package:app_flowy/workspace/infrastructure/repos/helper.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/flowy-folder/dart_notification.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/dart_notification.pb.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);
 
 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();
+  }
+}
+

+ 13 - 10
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:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
@@ -7,18 +8,20 @@ import 'package:freezed_annotation/freezed_annotation.dart';
 
 part 'view_bloc.freezed.dart';
 
-class ViewMenuBloc extends Bloc<ViewEvent, ViewState> {
-  final ViewRepository repo;
+class ViewBloc extends Bloc<ViewEvent, ViewState> {
+  final ViewService service;
   final ViewListener listener;
+  final View view;
 
-  ViewMenuBloc({
-    required this.repo,
+  ViewBloc({
+    required this.view,
+    required this.service,
     required this.listener,
-  }) : super(ViewState.init(repo.view)) {
+  }) : super(ViewState.init(view)) {
     on<ViewEvent>((event, emit) async {
       await event.map(
         initial: (e) {
-          // TODO: Listener can be refctored to a stream.
+          // TODO: Listener can be refactored to a stream.
           listener.updatedNotifier.addPublishListener((result) {
             // emit.forEach(stream, onData: onData)
             add(ViewEvent.viewDidUpdate(result));
@@ -36,7 +39,7 @@ class ViewMenuBloc extends Bloc<ViewEvent, ViewState> {
           );
         },
         rename: (e) async {
-          final result = await repo.updateView(name: e.newName);
+          final result = await service.updateView(viewId: view.id, name: e.newName);
           emit(
             result.fold(
               (l) => state.copyWith(successOrFailure: left(unit)),
@@ -45,7 +48,7 @@ class ViewMenuBloc extends Bloc<ViewEvent, ViewState> {
           );
         },
         delete: (e) async {
-          final result = await repo.delete();
+          final result = await service.delete(viewId: view.id);
           emit(
             result.fold(
               (l) => state.copyWith(successOrFailure: left(unit)),
@@ -54,7 +57,7 @@ class ViewMenuBloc extends Bloc<ViewEvent, ViewState> {
           );
         },
         duplicate: (e) async {
-          final result = await repo.duplicate();
+          final result = await service.duplicate(viewId: view.id);
           emit(
             result.fold(
               (l) => state.copyWith(successOrFailure: left(unit)),

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

@@ -1,70 +1,14 @@
 import 'dart:async';
 import 'dart:typed_data';
+import 'package:app_flowy/core/helper.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/flowy-collaboration/document_info.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/rust_stream.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();
-  }
-
-  Future<Either<BlockDelta, FlowyError>> openDocument() {
-    final request = ViewId(value: view.id);
-    return FolderEventOpenView(request).send();
-  }
-
-  Future<Either<BlockDelta, FlowyError>> composeDelta({required String data}) {
-    final request = BlockDelta.create()
-      ..blockId = view.id
-      ..deltaJson = data;
-    return FolderEventApplyDocDelta(request).send();
-  }
-
-  Future<Either<Unit, FlowyError>> closeDocument() {
-    final request = ViewId(value: view.id);
-    return FolderEventCloseView(request).send();
-  }
-}
-
 typedef DeleteNotifierValue = Either<View, FlowyError>;
 typedef UpdateNotifierValue = 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/protobuf/flowy-folder-data-model/workspace.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';
 
 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>(
       (event, emit) async {
         await event.map(initial: (e) async {
-          listener.workspaceUpdatedNotifier.addPublishListener(_workspacesUpdated);
-          listener.start();
+          userListener.workspaceUpdatedNotifier.addPublishListener(_workspacesUpdated);
+          userListener.start();
           //
           await _fetchWorkspaces(emit);
         }, openWorkspace: (e) async {
@@ -35,12 +36,12 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
 
   @override
   Future<void> close() async {
-    await listener.stop();
+    await userListener.stop();
     super.close();
   }
 
   Future<void> _fetchWorkspaces(Emitter<WelcomeState> emit) async {
-    final workspacesOrFailed = await repo.getWorkspaces();
+    final workspacesOrFailed = await userService.getWorkspaces();
     emit(workspacesOrFailed.fold(
       (workspaces) => state.copyWith(workspaces: workspaces, successOrFailure: left(unit)),
       (error) {
@@ -51,7 +52,7 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
   }
 
   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(
       (workspaces) => state.copyWith(successOrFailure: left(unit)),
       (error) {
@@ -62,7 +63,7 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
   }
 
   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(
       (workspace) {
         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:typed_data';
 
+import 'package:app_flowy/core/helper.dart';
 import 'package:dartz/dartz.dart';
-import 'package:easy_localization/easy_localization.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/flowy-user-data-model/protobuf.dart' show UserProfile;
 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-folder/dart_notification.pb.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;
   WorkspaceAppsChangedCallback? _appsChanged;
   WorkspaceUpdatedCallback? _update;
@@ -69,7 +40,7 @@ class WorkspaceListenerRepo {
   final UserProfile user;
   final String workspaceId;
 
-  WorkspaceListenerRepo({
+  WorkspaceListenerService({
     required this.user,
     required this.workspaceId,
   });
@@ -125,22 +96,3 @@ class WorkspaceListenerRepo {
     // _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),
+      );
+    });
+  }
+}

+ 9 - 9
frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart

@@ -36,12 +36,12 @@ class ViewSectionItem extends StatelessWidget {
     final theme = context.watch<AppTheme>();
     return MultiBlocProvider(
       providers: [
-        BlocProvider(create: (ctx) => getIt<ViewMenuBloc>(param1: view)..add(const ViewEvent.initial())),
+        BlocProvider(create: (ctx) => getIt<ViewBloc>(param1: view)..add(const ViewEvent.initial())),
       ],
-      child: BlocBuilder<ViewMenuBloc, ViewState>(
+      child: BlocBuilder<ViewBloc, ViewState>(
         builder: (context, state) {
           return InkWell(
-            onTap: () => onSelected(context.read<ViewMenuBloc>().state.view),
+            onTap: () => onSelected(context.read<ViewBloc>().state.view),
             child: FlowyHover(
               config: HoverDisplayConfig(hoverColor: theme.bg3),
               builder: (_, onHover) => _render(context, onHover, state, theme.iconColor),
@@ -63,9 +63,9 @@ class ViewSectionItem extends StatelessWidget {
     if (onHover || state.isEditing) {
       children.add(
         ViewDisclosureButton(
-          onTap: () => context.read<ViewMenuBloc>().add(const ViewEvent.setIsEditing(true)),
+          onTap: () => context.read<ViewBloc>().add(const ViewEvent.setIsEditing(true)),
           onSelected: (action) {
-            context.read<ViewMenuBloc>().add(const ViewEvent.setIsEditing(false));
+            context.read<ViewBloc>().add(const ViewEvent.setIsEditing(false));
             _handleAction(context, action);
           },
         ),
@@ -87,18 +87,18 @@ class ViewSectionItem extends StatelessWidget {
         case ViewDisclosureAction.rename:
           TextFieldDialog(
             title: LocaleKeys.disclosureAction_rename.tr(),
-            value: context.read<ViewMenuBloc>().state.view.name,
+            value: context.read<ViewBloc>().state.view.name,
             confirm: (newValue) {
-              context.read<ViewMenuBloc>().add(ViewEvent.rename(newValue));
+              context.read<ViewBloc>().add(ViewEvent.rename(newValue));
             },
           ).show(context);
 
           break;
         case ViewDisclosureAction.delete:
-          context.read<ViewMenuBloc>().add(const ViewEvent.delete());
+          context.read<ViewBloc>().add(const ViewEvent.delete());
           break;
         case ViewDisclosureAction.duplicate:
-          context.read<ViewMenuBloc>().add(const ViewEvent.duplicate());
+          context.read<ViewBloc>().add(const ViewEvent.duplicate());
           break;
       }
     });

+ 5 - 4
frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart

@@ -10,7 +10,8 @@ import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/startup/tasks/load_plugin.dart';
 import 'package:app_flowy/workspace/application/appearance.dart';
 import 'package:app_flowy/workspace/application/doc/share_bloc.dart';
-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:app_flowy/workspace/presentation/home/home_stack.dart';
 import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
 import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.dart';
@@ -128,11 +129,11 @@ class DocumentLeftBarItem extends StatefulWidget {
 class _DocumentLeftBarItemState extends State<DocumentLeftBarItem> {
   final _controller = TextEditingController();
   final _focusNode = FocusNode();
-  late ViewRepository repo;
+  late ViewService service;
 
   @override
   void initState() {
-    repo = ViewRepository(view: widget.view);
+    service = ViewService(/*view: widget.view*/);
     _focusNode.addListener(_handleFocusChanged);
     super.initState();
   }
@@ -179,7 +180,7 @@ class _DocumentLeftBarItemState extends State<DocumentLeftBarItem> {
     }
 
     if (_controller.text != widget.view.name) {
-      repo.updateView(name: _controller.text);
+      service.updateView(viewId: widget.view.id, name: _controller.text);
     }
   }
 }