浏览代码

config hover background & fix bugs

appflowy 3 年之前
父节点
当前提交
dfcb5059bf
共有 45 个文件被更改,包括 1008 次插入408 次删除
  1. 1 1
      app_flowy/lib/user/application/sign_in/sign_in_bloc.freezed.dart
  2. 1 1
      app_flowy/lib/welcome/application/welcome_bloc.freezed.dart
  3. 1 1
      app_flowy/lib/welcome/domain/auth_state.freezed.dart
  4. 1 1
      app_flowy/lib/workspace/application/app/app_bloc.freezed.dart
  5. 1 1
      app_flowy/lib/workspace/application/app/app_watch_bloc.freezed.dart
  6. 1 1
      app_flowy/lib/workspace/application/doc/doc_bloc.freezed.dart
  7. 1 1
      app_flowy/lib/workspace/application/edit_pannel/edit_pannel_bloc.freezed.dart
  8. 1 1
      app_flowy/lib/workspace/application/home/home_bloc.freezed.dart
  9. 1 1
      app_flowy/lib/workspace/application/home/home_watcher_bloc.freezed.dart
  10. 1 1
      app_flowy/lib/workspace/application/menu/menu_bloc.freezed.dart
  11. 1 1
      app_flowy/lib/workspace/application/menu/menu_user_bloc.freezed.dart
  12. 1 1
      app_flowy/lib/workspace/application/menu/menu_watch.freezed.dart
  13. 1 1
      app_flowy/lib/workspace/application/view/doc_watch_bloc.freezed.dart
  14. 0 1
      app_flowy/lib/workspace/application/view/view_bloc.dart
  15. 1 1
      app_flowy/lib/workspace/application/view/view_bloc.freezed.dart
  16. 44 0
      app_flowy/lib/workspace/application/view/view_list_bloc.dart
  17. 486 0
      app_flowy/lib/workspace/application/view/view_list_bloc.freezed.dart
  18. 1 1
      app_flowy/lib/workspace/domain/page_stack/page_stack_bloc.freezed.dart
  19. 10 4
      app_flowy/lib/workspace/infrastructure/deps_resolver.dart
  20. 1 1
      app_flowy/lib/workspace/infrastructure/repos/app_repo.dart
  21. 7 7
      app_flowy/lib/workspace/infrastructure/repos/view_repo.dart
  22. 22 18
      app_flowy/lib/workspace/presentation/app/app_widget.dart
  23. 41 22
      app_flowy/lib/workspace/presentation/app/view_list.dart
  24. 51 35
      app_flowy/lib/workspace/presentation/view/view_widget.dart
  25. 1 1
      app_flowy/macos/Podfile.lock
  26. 59 24
      app_flowy/packages/flowy_infra_ui/lib/style_widget/styled_hover.dart
  27. 1 0
      app_flowy/packages/flowy_infra_ui/lib/style_widget/styled_icon_button.dart
  28. 3 7
      app_flowy/packages/flowy_infra_ui/lib/style_widget/styled_navigation_list.dart
  29. 3 2
      app_flowy/packages/flowy_infra_ui/lib/style_widget/styled_text_button.dart
  30. 16 16
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/view_create.pb.dart
  31. 5 13
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/view_create.pbenum.dart
  32. 4 4
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/view_create.pbjson.dart
  33. 117 117
      app_flowy/pubspec.lock
  34. 1 1
      rust-lib/flowy-database/migrations/2021-07-09-063045_flowy-user/up.sql
  35. 1 1
      rust-lib/flowy-database/src/schema.rs
  36. 2 2
      rust-lib/flowy-workspace/src/entities/app/app_query.rs
  37. 2 2
      rust-lib/flowy-workspace/src/entities/app/app_update.rs
  38. 4 4
      rust-lib/flowy-workspace/src/entities/app/parser/belong_to_id.rs
  39. 2 2
      rust-lib/flowy-workspace/src/entities/app/parser/mod.rs
  40. 6 6
      rust-lib/flowy-workspace/src/entities/view/view_create.rs
  41. 95 94
      rust-lib/flowy-workspace/src/protobuf/model/view_create.rs
  42. 2 2
      rust-lib/flowy-workspace/src/protobuf/proto/view_create.proto
  43. 1 1
      rust-lib/flowy-workspace/src/services/view_controller.rs
  44. 4 4
      rust-lib/flowy-workspace/src/sql_tables/view/view_table.rs
  45. 2 2
      rust-lib/flowy-workspace/tests/event/app_test.rs

+ 1 - 1
app_flowy/lib/user/application/sign_in/sign_in_bloc.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'sign_in_bloc.dart';
 

+ 1 - 1
app_flowy/lib/welcome/application/welcome_bloc.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'welcome_bloc.dart';
 

+ 1 - 1
app_flowy/lib/welcome/domain/auth_state.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'auth_state.dart';
 

+ 1 - 1
app_flowy/lib/workspace/application/app/app_bloc.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'app_bloc.dart';
 

+ 1 - 1
app_flowy/lib/workspace/application/app/app_watch_bloc.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'app_watch_bloc.dart';
 

+ 1 - 1
app_flowy/lib/workspace/application/doc/doc_bloc.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'doc_bloc.dart';
 

+ 1 - 1
app_flowy/lib/workspace/application/edit_pannel/edit_pannel_bloc.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'edit_pannel_bloc.dart';
 

+ 1 - 1
app_flowy/lib/workspace/application/home/home_bloc.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'home_bloc.dart';
 

+ 1 - 1
app_flowy/lib/workspace/application/home/home_watcher_bloc.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'home_watcher_bloc.dart';
 

+ 1 - 1
app_flowy/lib/workspace/application/menu/menu_bloc.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'menu_bloc.dart';
 

+ 1 - 1
app_flowy/lib/workspace/application/menu/menu_user_bloc.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'menu_user_bloc.dart';
 

+ 1 - 1
app_flowy/lib/workspace/application/menu/menu_watch.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'menu_watch.dart';
 

+ 1 - 1
app_flowy/lib/workspace/application/view/doc_watch_bloc.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'doc_watch_bloc.dart';
 

+ 0 - 1
app_flowy/lib/workspace/application/view/view_bloc.dart

@@ -3,7 +3,6 @@ import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
-
 import 'package:app_flowy/workspace/domain/i_view.dart';
 
 part 'view_bloc.freezed.dart';

+ 1 - 1
app_flowy/lib/workspace/application/view/view_bloc.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'view_bloc.dart';
 

+ 44 - 0
app_flowy/lib/workspace/application/view/view_list_bloc.dart

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

+ 486 - 0
app_flowy/lib/workspace/application/view/view_list_bloc.freezed.dart

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

+ 1 - 1
app_flowy/lib/workspace/domain/page_stack/page_stack_bloc.freezed.dart

@@ -1,5 +1,5 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 
 part of 'page_stack_bloc.dart';
 

+ 10 - 4
app_flowy/lib/workspace/infrastructure/deps_resolver.dart

@@ -6,6 +6,7 @@ import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart';
 import 'package:app_flowy/workspace/application/menu/menu_watch.dart';
 import 'package:app_flowy/workspace/application/view/doc_watch_bloc.dart';
 import 'package:app_flowy/workspace/application/view/view_bloc.dart';
+import 'package:app_flowy/workspace/application/view/view_list_bloc.dart';
 import 'package:app_flowy/workspace/domain/i_doc.dart';
 import 'package:app_flowy/workspace/domain/i_view.dart';
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
@@ -18,6 +19,7 @@ import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
 import 'package:app_flowy/workspace/infrastructure/repos/workspace_repo.dart';
 import 'package:flowy_editor/flowy_editor.dart';
 import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
 import 'package:get_it/get_it.dart';
 
 import 'i_user_impl.dart';
@@ -41,10 +43,10 @@ class HomeDepsResolver {
         (user, _) => IWorkspaceWatchImpl(repo: WorkspaceWatchRepo(user: user)));
 
     // View
-    getIt.registerFactoryParam<IView, String, void>(
-        (viewId, _) => IViewImpl(repo: ViewRepository(viewId: viewId)));
-    getIt.registerFactoryParam<IViewWatch, String, void>((viewId, _) =>
-        IViewWatchImpl(repo: ViewWatchRepository(viewId: viewId)));
+    getIt.registerFactoryParam<IView, View, void>(
+        (view, _) => IViewImpl(repo: ViewRepository(view: view)));
+    getIt.registerFactoryParam<IViewWatch, View, void>(
+        (view, _) => IViewWatchImpl(repo: ViewWatchRepository(view: view)));
 
     // Doc
     getIt.registerFactoryParam<IDoc, String, void>(
@@ -81,6 +83,10 @@ class HomeDepsResolver {
     // editor
     getIt.registerFactoryParam<EditorPersistence, String, void>(
         (docId, _) => EditorPersistenceImpl(repo: DocRepository(docId: docId)));
+
+    getIt.registerFactoryParam<ViewListBloc, List<View>, void>(
+        (views, _) => ViewListBloc(views: views));
+
     // getIt.registerFactoryParam<ViewBloc, String, void>(
     //     (viewId, _) => ViewBloc(iViewImpl: getIt<IView>(param1: viewId)));
   }

+ 1 - 1
app_flowy/lib/workspace/infrastructure/repos/app_repo.dart

@@ -29,7 +29,7 @@ class AppRepository {
   Future<Either<View, WorkspaceError>> createView(
       String name, String desc, ViewType viewType) {
     final request = CreateViewRequest.create()
-      ..appId = appId
+      ..belongToId = appId
       ..name = name
       ..desc = desc
       ..viewType = viewType;

+ 7 - 7
app_flowy/lib/workspace/infrastructure/repos/view_repo.dart

@@ -13,13 +13,13 @@ import 'package:flowy_sdk/rust_stream.dart';
 import 'package:app_flowy/workspace/domain/i_view.dart';
 
 class ViewRepository {
-  String viewId;
+  View view;
   ViewRepository({
-    required this.viewId,
+    required this.view,
   });
 
   Future<Either<View, WorkspaceError>> readView() {
-    final request = QueryViewRequest.create()..viewId = viewId;
+    final request = QueryViewRequest.create()..viewId = view.id;
     return WorkspaceEventReadView(request).send();
   }
 }
@@ -27,12 +27,12 @@ class ViewRepository {
 class ViewWatchRepository {
   StreamSubscription<ObservableSubject>? _subscription;
   ViewUpdatedCallback? _updatedCallback;
-  String viewId;
+  View view;
   late ViewRepository _repo;
   ViewWatchRepository({
-    required this.viewId,
+    required this.view,
   }) {
-    _repo = ViewRepository(viewId: viewId);
+    _repo = ViewRepository(view: view);
   }
 
   void startWatching({
@@ -40,7 +40,7 @@ class ViewWatchRepository {
   }) {
     _updatedCallback = updatedCallback;
     _subscription = RustStreamReceiver.listen((observable) {
-      if (observable.subjectId != viewId) {
+      if (observable.subjectId != view.id) {
         return;
       }
 

+ 22 - 18
app_flowy/lib/workspace/presentation/app/app_widget.dart

@@ -85,11 +85,15 @@ class AppWidget extends MenuItem {
     );
   }
 
-  Widget _renderViewList(Option<List<View>> views) {
-    return Padding(
-      padding: const EdgeInsets.symmetric(vertical: 8),
-      child: ViewList(views),
+  Widget _renderViewList(Option<List<View>> some) {
+    List<View> views = some.fold(
+      () => List.empty(growable: true),
+      (views) => views,
     );
+
+    return Padding(
+        padding: const EdgeInsets.symmetric(vertical: 8),
+        child: ViewList(views, key: UniqueKey()));
   }
 
   @override
@@ -135,24 +139,24 @@ class AppHeader extends StatelessWidget {
             },
           ),
         ),
-        StyledIconButton(
-          icon: const Icon(Icons.add),
-          onPressed: () {
-            debugPrint('add view');
-          },
-        ),
+        // StyledIconButton(
+        //   icon: const Icon(Icons.add),
+        //   onPressed: () {
+        //     debugPrint('add view');
+        //   },
+        // ),
+        PopupMenuButton(
+            iconSize: 20,
+            tooltip: 'create new view',
+            icon: const Icon(Icons.add),
+            padding: EdgeInsets.zero,
+            onSelected: (viewType) =>
+                _createView(viewType as ViewType, context),
+            itemBuilder: (context) => menuItemBuilder())
       ],
     );
   }
 
-  // return PopupMenuButton(
-  //     iconSize: 20,
-  //     tooltip: 'create new view',
-  //     icon: const Icon(Icons.add),
-  //     padding: EdgeInsets.zero,
-  //     onSelected: (viewType) => _createView(viewType as ViewType, context),
-  //     itemBuilder: (context) => menuItemBuilder());
-
   List<PopupMenuEntry> menuItemBuilder() {
     return ViewType.values
         .where((element) => element != ViewType.Blank)

+ 41 - 22
app_flowy/lib/workspace/presentation/app/view_list.dart

@@ -1,43 +1,62 @@
+import 'package:app_flowy/startup/startup.dart';
+import 'package:app_flowy/workspace/application/view/view_list_bloc.dart';
 import 'package:app_flowy/workspace/presentation/view/view_widget.dart';
-import 'package:flowy_infra/flowy_logger.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
+import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
-import 'package:dartz/dartz.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
 
 class ViewList extends StatelessWidget {
-  final Option<List<View>> views;
+  final List<View> views;
   const ViewList(this.views, {Key? key}) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
-    Log.info('ViewList build');
-    return views.fold(
-      () => const SizedBox(),
-      (views) {
-        return Column(
-          children: _renderViews(views),
-        );
-      },
+    return BlocProvider(
+      create: (context) =>
+          getIt<ViewListBloc>(param1: views)..add(ViewListEvent.initial(views)),
+      child: BlocBuilder<ViewListBloc, ViewListState>(
+        builder: (context, state) {
+          return state.views.fold(
+            () => const SizedBox(),
+            (views) => _renderViews(context, views),
+          );
+        },
+      ),
     );
   }
 
-  List<Widget> _renderViews(List<View> views) {
-    var targetViews = views.map((view) {
+  Widget _renderViews(BuildContext context, List<View> views) {
+    var viewWidgets = views.map((view) {
+      final viewCtx = ViewWidgetContext(view,
+          isSelected: _isViewSelected(context, view.id));
+
+      final viewWidget = ViewWidget(
+        viewCtx: viewCtx,
+        onOpen: (view) {
+          context.read<ViewListBloc>().add(ViewListEvent.openView(view));
+          final stackView = stackViewFromView(viewCtx.view);
+          getIt<HomePageStack>().setStackView(stackView);
+        },
+      );
+
       return Padding(
         padding: const EdgeInsets.symmetric(vertical: 2),
-        child: ViewWidget(
-          view: view,
-        ),
+        child: viewWidget,
       );
     }).toList(growable: false);
-    return targetViews;
+
+    return Column(
+      children: viewWidgets,
+    );
   }
 
-  @override
-  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
-    super.debugFillProperties(properties);
-    views.fold(() => {},
-        (views) => properties.add(IterableProperty<View>('views', views)));
+  bool _isViewSelected(BuildContext context, String viewId) {
+    return context
+        .read<ViewListBloc>()
+        .state
+        .selectedView
+        .fold(() => false, (selectedViewId) => viewId == selectedViewId);
   }
 }

+ 51 - 35
app_flowy/lib/workspace/presentation/view/view_widget.dart

@@ -1,74 +1,90 @@
-import 'package:app_flowy/startup/startup.dart';
-import 'package:app_flowy/workspace/domain/image.dart';
-import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
-import 'package:app_flowy/workspace/presentation/app/app_widget.dart';
+import 'package:flowy_infra_ui/style_widget/styled_hover.dart';
+import 'package:flowy_infra_ui/style_widget/styled_icon_button.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
 import 'package:flutter/material.dart';
-import 'package:flowy_infra_ui/style_widget/styled_icon_button.dart';
-import 'package:flowy_infra_ui/style_widget/styled_hover.dart';
+import 'package:app_flowy/workspace/domain/image.dart';
+import 'package:app_flowy/workspace/presentation/app/app_widget.dart';
+import 'package:styled_widget/styled_widget.dart';
 
-class ViewWidget extends StatelessWidget {
+class ViewWidgetContext {
   final View view;
-  const ViewWidget({Key? key, required this.view}) : super(key: key);
+  bool isSelected;
+
+  ViewWidgetContext(
+    this.view, {
+    this.isSelected = false,
+  });
+}
+
+typedef OpenViewCallback = void Function(View);
+
+class ViewWidget extends StatelessWidget {
+  final ViewWidgetContext viewCtx;
+  final OpenViewCallback onOpen;
+  const ViewWidget({Key? key, required this.viewCtx, required this.onOpen})
+      : super(key: key);
 
   @override
   Widget build(BuildContext context) {
+    final config = HoverDisplayConfig(hoverColor: Colors.grey.shade200);
     return InkWell(
       onTap: _openView(context),
       child: StyledHover(
-        color: Colors.grey.shade300,
-        borderRadius: BorderRadius.circular(8),
-        builder: (context, onHover) => _render(context, onHover),
+        config: config,
+        builder: (context, onHover) => _render(context, onHover, config),
       ),
     );
   }
 
-  Widget _render(BuildContext context, bool onHover) {
-    const double width = 20;
+  Widget _render(
+      BuildContext context, bool onHover, HoverDisplayConfig config) {
+    const double width = 22;
     List<Widget> children = [
       Image(
           fit: BoxFit.cover,
           width: width,
           height: width,
-          image: assetImageForViewType(view.viewType)),
+          image: assetImageForViewType(viewCtx.view.viewType)),
       const HSpace(6),
       Text(
-        view.name,
+        viewCtx.view.name,
         textAlign: TextAlign.start,
         style: const TextStyle(fontSize: 15),
       ),
     ];
 
     if (onHover) {
-      children.add(const Spacer());
-
-      children.add(Align(
-        alignment: Alignment.center,
-        child: StyledMore(
-          width: width,
-          onPressed: () {},
-        ),
-      ));
+      _addedHover(children, width);
     }
 
-    final padding = EdgeInsets.only(
+    Widget widget = Row(children: children).padding(
+      vertical: 5,
       left: AppWidgetSize.expandedPadding,
-      top: 5,
-      bottom: 5,
       right: 5,
     );
 
-    return Padding(
-      padding: padding,
-      child: Row(children: children),
-    );
+    if (viewCtx.isSelected) {
+      widget = HoverBackground(child: widget, config: config);
+    }
+
+    return widget;
   }
 
   Function() _openView(BuildContext context) {
-    return () {
-      final stackView = stackViewFromView(view);
-      getIt<HomePageStack>().setStackView(stackView);
-    };
+    return () => onOpen(viewCtx.view);
+  }
+
+  void _addedHover(List<Widget> children, double hoverWidth) {
+    children.add(const Spacer());
+    children.add(Align(
+      alignment: Alignment.center,
+      child: StyledMore(
+        width: hoverWidth,
+        onPressed: () {
+          debugPrint('show view setting');
+        },
+      ),
+    ));
   }
 }

+ 1 - 1
app_flowy/macos/Podfile.lock

@@ -43,7 +43,7 @@ SPEC CHECKSUMS:
   flowy_infra_ui: 9d5021b1610fe0476eb1191bf7cd41c4a4138d8f
   flowy_sdk: c302ac0a22dea596db0df8073b9637b2bf2ff6fd
   FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424
-  path_provider_macos: a0a3fd666cb7cd0448e936fb4abad4052961002b
+  path_provider_macos: 160cab0d5461f0c0e02995469a98f24bdb9a3f1f
   url_launcher_macos: 45af3d61de06997666568a7149c1be98b41c95d4
   window_size: 339dafa0b27a95a62a843042038fa6c3c48de195
 

+ 59 - 24
app_flowy/packages/flowy_infra_ui/lib/style_widget/styled_hover.dart

@@ -5,19 +5,13 @@ import 'package:flowy_infra/time/duration.dart';
 typedef HoverBuilder = Widget Function(BuildContext context, bool onHover);
 
 class StyledHover extends StatefulWidget {
-  final Color color;
-  final Color borderColor;
-  final double borderWidth;
-  final BorderRadius borderRadius;
+  final HoverDisplayConfig config;
   final HoverBuilder builder;
 
   const StyledHover({
     Key? key,
-    required this.color,
-    this.borderColor = Colors.transparent,
-    this.borderWidth = 0,
-    this.borderRadius = BorderRadius.zero,
     required this.builder,
+    this.config = const HoverDisplayConfig(),
   }) : super(key: key);
 
   @override
@@ -29,29 +23,70 @@ class _StyledHoverState extends State<StyledHover> {
 
   @override
   Widget build(BuildContext context) {
-    final hoverColor =
-        _onHover ? widget.color : Theme.of(context).colorScheme.background;
-
-    final hoverBorder = Border.all(
-      color: widget.borderColor,
-      width: widget.borderWidth,
-    );
+    final hoverColor = _onHover
+        ? widget.config.hoverColor
+        : Theme.of(context).colorScheme.background;
+    final config = widget.config.copyWith(hoverColor: hoverColor);
 
     return MouseRegion(
       cursor: SystemMouseCursors.click,
       onEnter: (p) => setOnHover(true),
       onExit: (p) => setOnHover(false),
-      child: Container(
-        decoration: BoxDecoration(
-          border: hoverBorder,
-          color: hoverColor,
-          borderRadius: widget.borderRadius,
-        ),
-        // duration: .1.seconds,
-        child: widget.builder(context, _onHover),
-      ),
+      child: HoverBackground(
+          config: config, child: widget.builder(context, _onHover)),
     );
   }
 
   void setOnHover(bool value) => setState(() => _onHover = value);
 }
+
+class HoverDisplayConfig {
+  final Color borderColor;
+  final double borderWidth;
+  final Color? hoverColor;
+  final BorderRadius borderRadius;
+
+  const HoverDisplayConfig(
+      {this.borderColor = Colors.transparent,
+      this.borderWidth = 0,
+      this.borderRadius = const BorderRadius.all(Radius.circular(8)),
+      this.hoverColor});
+
+  HoverDisplayConfig copyWith({Color? hoverColor}) {
+    return HoverDisplayConfig(
+        borderColor: borderColor,
+        borderWidth: borderWidth,
+        borderRadius: borderRadius,
+        hoverColor: hoverColor);
+  }
+}
+
+class HoverBackground extends StatelessWidget {
+  final HoverDisplayConfig config;
+
+  final Widget child;
+
+  const HoverBackground({
+    Key? key,
+    required this.child,
+    this.config = const HoverDisplayConfig(),
+  }) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    final color = config.hoverColor ?? Theme.of(context).colorScheme.background;
+    final hoverBorder = Border.all(
+      color: config.borderColor,
+      width: config.borderWidth,
+    );
+
+    return Container(
+      decoration: BoxDecoration(
+        border: hoverBorder,
+        color: color,
+        borderRadius: config.borderRadius,
+      ),
+      child: child,
+    );
+  }
+}

+ 1 - 0
app_flowy/packages/flowy_infra_ui/lib/style_widget/styled_icon_button.dart

@@ -50,6 +50,7 @@ class StyledMore extends StatelessWidget {
       width: width,
       height: height,
       icon: const Icon(Icons.more_vert),
+      onPressed: onPressed,
     );
   }
 }

+ 3 - 7
app_flowy/packages/flowy_infra_ui/lib/style_widget/styled_navigation_list.dart

@@ -35,15 +35,11 @@ class StyledNavigationList extends StatelessWidget {
       return [];
     }
 
-    List<NaviItem> newItems = _selectNaviItem(items);
+    List<NaviItem> newItems = _filter(items);
     Widget last = NaviItemWidget(newItems.removeLast());
 
     List<Widget> widgets = newItems
-        .map(
-          (item) => NaviItemDivider(
-            child: NaviItemWidget(item),
-          ),
-        )
+        .map((item) => NaviItemDivider(child: NaviItemWidget(item)))
         .toList();
 
     widgets.add(last);
@@ -51,7 +47,7 @@ class StyledNavigationList extends StatelessWidget {
     return widgets;
   }
 
-  List<NaviItem> _selectNaviItem(List<NaviItem> items) {
+  List<NaviItem> _filter(List<NaviItem> items) {
     final length = items.length;
     if (length > 4) {
       final ellipsisItems = items.getRange(1, length - 2).toList();

+ 3 - 2
app_flowy/packages/flowy_infra_ui/lib/style_widget/styled_text_button.dart

@@ -20,8 +20,9 @@ class StyledTextButton extends StatelessWidget {
     return InkWell(
       onTap: onPressed,
       child: StyledHover(
-        color: Colors.grey.shade300,
-        borderRadius: BorderRadius.circular(8),
+        config: HoverDisplayConfig(
+            borderRadius: BorderRadius.circular(8),
+            hoverColor: Colors.grey.shade300),
         builder: (context, onHover) => _render(),
       ),
     );

+ 16 - 16
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/view_create.pb.dart

@@ -25,7 +25,7 @@ class CreateViewRequest extends $pb.GeneratedMessage {
   };
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateViewRequest', createEmptyInstance: create)
     ..oo(0, [4])
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'appId')
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongToId')
     ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
     ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
     ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail')
@@ -35,15 +35,15 @@ class CreateViewRequest extends $pb.GeneratedMessage {
 
   CreateViewRequest._() : super();
   factory CreateViewRequest({
-    $core.String? appId,
+    $core.String? belongToId,
     $core.String? name,
     $core.String? desc,
     $core.String? thumbnail,
     ViewType? viewType,
   }) {
     final _result = create();
-    if (appId != null) {
-      _result.appId = appId;
+    if (belongToId != null) {
+      _result.belongToId = belongToId;
     }
     if (name != null) {
       _result.name = name;
@@ -84,13 +84,13 @@ class CreateViewRequest extends $pb.GeneratedMessage {
   void clearOneOfThumbnail() => clearField($_whichOneof(0));
 
   @$pb.TagNumber(1)
-  $core.String get appId => $_getSZ(0);
+  $core.String get belongToId => $_getSZ(0);
   @$pb.TagNumber(1)
-  set appId($core.String v) { $_setString(0, v); }
+  set belongToId($core.String v) { $_setString(0, v); }
   @$pb.TagNumber(1)
-  $core.bool hasAppId() => $_has(0);
+  $core.bool hasBelongToId() => $_has(0);
   @$pb.TagNumber(1)
-  void clearAppId() => clearField(1);
+  void clearBelongToId() => clearField(1);
 
   @$pb.TagNumber(2)
   $core.String get name => $_getSZ(1);
@@ -132,7 +132,7 @@ class CreateViewRequest extends $pb.GeneratedMessage {
 class View extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'View', createEmptyInstance: create)
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
-    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'appId')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongToId')
     ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
     ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
     ..e<ViewType>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewType', $pb.PbFieldType.OE, defaultOrMaker: ViewType.Blank, valueOf: ViewType.valueOf, enumValues: ViewType.values)
@@ -142,7 +142,7 @@ class View extends $pb.GeneratedMessage {
   View._() : super();
   factory View({
     $core.String? id,
-    $core.String? appId,
+    $core.String? belongToId,
     $core.String? name,
     $core.String? desc,
     ViewType? viewType,
@@ -151,8 +151,8 @@ class View extends $pb.GeneratedMessage {
     if (id != null) {
       _result.id = id;
     }
-    if (appId != null) {
-      _result.appId = appId;
+    if (belongToId != null) {
+      _result.belongToId = belongToId;
     }
     if (name != null) {
       _result.name = name;
@@ -196,13 +196,13 @@ class View extends $pb.GeneratedMessage {
   void clearId() => clearField(1);
 
   @$pb.TagNumber(2)
-  $core.String get appId => $_getSZ(1);
+  $core.String get belongToId => $_getSZ(1);
   @$pb.TagNumber(2)
-  set appId($core.String v) { $_setString(1, v); }
+  set belongToId($core.String v) { $_setString(1, v); }
   @$pb.TagNumber(2)
-  $core.bool hasAppId() => $_has(1);
+  $core.bool hasBelongToId() => $_has(1);
   @$pb.TagNumber(2)
-  void clearAppId() => clearField(2);
+  void clearBelongToId() => clearField(2);
 
   @$pb.TagNumber(3)
   $core.String get name => $_getSZ(2);

+ 5 - 13
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/view_create.pbenum.dart

@@ -10,25 +10,17 @@ import 'dart:core' as $core;
 import 'package:protobuf/protobuf.dart' as $pb;
 
 class ViewType extends $pb.ProtobufEnum {
-  static const ViewType Blank = ViewType._(
-      0,
-      const $core.bool.fromEnvironment('protobuf.omit_enum_names')
-          ? ''
-          : 'Blank');
-  static const ViewType Doc = ViewType._(
-      1,
-      const $core.bool.fromEnvironment('protobuf.omit_enum_names')
-          ? ''
-          : 'Doc');
+  static const ViewType Blank = ViewType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Blank');
+  static const ViewType Doc = ViewType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Doc');
 
-  static const $core.List<ViewType> values = <ViewType>[
+  static const $core.List<ViewType> values = <ViewType> [
     Blank,
     Doc,
   ];
 
-  static final $core.Map<$core.int, ViewType> _byValue =
-      $pb.ProtobufEnum.initByValue(values);
+  static final $core.Map<$core.int, ViewType> _byValue = $pb.ProtobufEnum.initByValue(values);
   static ViewType? valueOf($core.int value) => _byValue[value];
 
   const ViewType._($core.int v, $core.String n) : super(v, n);
 }
+

+ 4 - 4
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/view_create.pbjson.dart

@@ -23,7 +23,7 @@ final $typed_data.Uint8List viewTypeDescriptor = $convert.base64Decode('CghWaWV3
 const CreateViewRequest$json = const {
   '1': 'CreateViewRequest',
   '2': const [
-    const {'1': 'app_id', '3': 1, '4': 1, '5': 9, '10': 'appId'},
+    const {'1': 'belong_to_id', '3': 1, '4': 1, '5': 9, '10': 'belongToId'},
     const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
     const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'},
     const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'thumbnail'},
@@ -35,13 +35,13 @@ const CreateViewRequest$json = const {
 };
 
 /// Descriptor for `CreateViewRequest`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List createViewRequestDescriptor = $convert.base64Decode('ChFDcmVhdGVWaWV3UmVxdWVzdBIVCgZhcHBfaWQYASABKAlSBWFwcElkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIeCgl0aHVtYm5haWwYBCABKAlIAFIJdGh1bWJuYWlsEiYKCXZpZXdfdHlwZRgFIAEoDjIJLlZpZXdUeXBlUgh2aWV3VHlwZUISChBvbmVfb2ZfdGh1bWJuYWls');
+final $typed_data.Uint8List createViewRequestDescriptor = $convert.base64Decode('ChFDcmVhdGVWaWV3UmVxdWVzdBIgCgxiZWxvbmdfdG9faWQYASABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEh4KCXRodW1ibmFpbBgEIAEoCUgAUgl0aHVtYm5haWwSJgoJdmlld190eXBlGAUgASgOMgkuVmlld1R5cGVSCHZpZXdUeXBlQhIKEG9uZV9vZl90aHVtYm5haWw=');
 @$core.Deprecated('Use viewDescriptor instead')
 const View$json = const {
   '1': 'View',
   '2': const [
     const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
-    const {'1': 'app_id', '3': 2, '4': 1, '5': 9, '10': 'appId'},
+    const {'1': 'belong_to_id', '3': 2, '4': 1, '5': 9, '10': 'belongToId'},
     const {'1': 'name', '3': 3, '4': 1, '5': 9, '10': 'name'},
     const {'1': 'desc', '3': 4, '4': 1, '5': 9, '10': 'desc'},
     const {'1': 'view_type', '3': 5, '4': 1, '5': 14, '6': '.ViewType', '10': 'viewType'},
@@ -49,7 +49,7 @@ const View$json = const {
 };
 
 /// Descriptor for `View`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List viewDescriptor = $convert.base64Decode('CgRWaWV3Eg4KAmlkGAEgASgJUgJpZBIVCgZhcHBfaWQYAiABKAlSBWFwcElkEhIKBG5hbWUYAyABKAlSBG5hbWUSEgoEZGVzYxgEIAEoCVIEZGVzYxImCgl2aWV3X3R5cGUYBSABKA4yCS5WaWV3VHlwZVIIdmlld1R5cGU=');
+final $typed_data.Uint8List viewDescriptor = $convert.base64Decode('CgRWaWV3Eg4KAmlkGAEgASgJUgJpZBIgCgxiZWxvbmdfdG9faWQYAiABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgDIAEoCVIEbmFtZRISCgRkZXNjGAQgASgJUgRkZXNjEiYKCXZpZXdfdHlwZRgFIAEoDjIJLlZpZXdUeXBlUgh2aWV3VHlwZQ==');
 @$core.Deprecated('Use repeatedViewDescriptor instead')
 const RepeatedView$json = const {
   '1': 'RepeatedView',

+ 117 - 117
app_flowy/pubspec.lock

@@ -5,231 +5,231 @@ packages:
     dependency: transitive
     description:
       name: _fe_analyzer_shared
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "23.0.0"
   analyzer:
     dependency: transitive
     description:
       name: analyzer
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.0"
   animations:
     dependency: transitive
     description:
       name: animations
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.1"
   args:
     dependency: transitive
     description:
       name: args
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.2.0"
   async:
     dependency: transitive
     description:
       name: async
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.7.0"
   bloc:
     dependency: transitive
     description:
       name: bloc
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "7.0.0"
   boolean_selector:
     dependency: transitive
     description:
       name: boolean_selector
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.1.0"
   build:
     dependency: transitive
     description:
       name: build
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.3"
   build_config:
     dependency: transitive
     description:
       name: build_config
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.0"
   build_daemon:
     dependency: transitive
     description:
       name: build_daemon
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "3.0.0"
   build_resolvers:
     dependency: transitive
     description:
       name: build_resolvers
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.4"
   build_runner:
     dependency: "direct dev"
     description:
       name: build_runner
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.6"
   build_runner_core:
     dependency: transitive
     description:
       name: build_runner_core
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "7.0.1"
   built_collection:
     dependency: transitive
     description:
       name: built_collection
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "5.1.0"
   built_value:
     dependency: transitive
     description:
       name: built_value
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "8.1.1"
   characters:
     dependency: transitive
     description:
       name: characters
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.1.0"
   charcode:
     dependency: transitive
     description:
       name: charcode
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.3.1"
   checked_yaml:
     dependency: transitive
     description:
       name: checked_yaml
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.1"
   cli_util:
     dependency: transitive
     description:
       name: cli_util
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "0.3.3"
   clock:
     dependency: transitive
     description:
       name: clock
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.1.0"
   code_builder:
     dependency: transitive
     description:
       name: code_builder
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "4.1.0"
   collection:
     dependency: transitive
     description:
       name: collection
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.15.0"
   convert:
     dependency: transitive
     description:
       name: convert
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "3.0.1"
   crypto:
     dependency: transitive
     description:
       name: crypto
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "3.0.1"
   cupertino_icons:
     dependency: "direct main"
     description:
       name: cupertino_icons
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.3"
   dart_style:
     dependency: transitive
     description:
       name: dart_style
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.3"
   dartz:
     dependency: transitive
     description:
       name: dartz
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "0.10.0-nullsafety.2"
   equatable:
     dependency: "direct main"
     description:
       name: equatable
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.3"
   expandable:
     dependency: "direct main"
     description:
       name: expandable
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "5.0.1"
   fake_async:
     dependency: transitive
     description:
       name: fake_async
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.2.0"
   ffi:
     dependency: transitive
     description:
       name: ffi
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.1.2"
   file:
     dependency: transitive
     description:
       name: file
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "6.1.2"
   fixnum:
     dependency: transitive
     description:
       name: fixnum
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.0"
   flowy_editor:
@@ -283,42 +283,42 @@ packages:
     dependency: "direct main"
     description:
       name: flutter_bloc
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "7.0.1"
   flutter_colorpicker:
     dependency: transitive
     description:
       name: flutter_colorpicker
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "0.5.0"
   flutter_keyboard_visibility:
     dependency: transitive
     description:
       name: flutter_keyboard_visibility
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "5.0.3"
   flutter_keyboard_visibility_platform_interface:
     dependency: transitive
     description:
       name: flutter_keyboard_visibility_platform_interface
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.0"
   flutter_keyboard_visibility_web:
     dependency: transitive
     description:
       name: flutter_keyboard_visibility_web
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.0"
   flutter_lints:
     dependency: "direct dev"
     description:
       name: flutter_lints
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.4"
   flutter_test:
@@ -335,203 +335,203 @@ packages:
     dependency: "direct dev"
     description:
       name: freezed
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "0.14.3"
   freezed_annotation:
     dependency: "direct main"
     description:
       name: freezed_annotation
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "0.14.3"
   frontend_server_client:
     dependency: transitive
     description:
       name: frontend_server_client
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.1.0"
   get_it:
     dependency: "direct main"
     description:
       name: get_it
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "7.2.0"
   glob:
     dependency: transitive
     description:
       name: glob
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.1"
   graphs:
     dependency: transitive
     description:
       name: graphs
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.0"
   http_multi_server:
     dependency: transitive
     description:
       name: http_multi_server
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "3.0.1"
   http_parser:
     dependency: transitive
     description:
       name: http_parser
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "4.0.0"
   io:
     dependency: transitive
     description:
       name: io
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.3"
   isolates:
     dependency: transitive
     description:
       name: isolates
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "3.0.3+8"
   js:
     dependency: transitive
     description:
       name: js
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "0.6.3"
   json_annotation:
     dependency: transitive
     description:
       name: json_annotation
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "4.1.0"
   lint:
     dependency: transitive
     description:
       name: lint
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.5.3"
   lints:
     dependency: transitive
     description:
       name: lints
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.1"
   loading_indicator:
     dependency: transitive
     description:
       name: loading_indicator
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "3.0.1"
   logger:
     dependency: transitive
     description:
       name: logger
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.0"
   logging:
     dependency: transitive
     description:
       name: logging
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.1"
   matcher:
     dependency: transitive
     description:
       name: matcher
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "0.12.10"
   meta:
     dependency: transitive
     description:
       name: meta
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.7.0"
   mime:
     dependency: transitive
     description:
       name: mime
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.0"
   nested:
     dependency: transitive
     description:
       name: nested
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.0"
   package_config:
     dependency: transitive
     description:
       name: package_config
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.0"
   path:
     dependency: transitive
     description:
       name: path
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.8.0"
   path_provider:
     dependency: "direct main"
     description:
       name: path_provider
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.2"
   path_provider_linux:
     dependency: transitive
     description:
       name: path_provider_linux
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.0.0"
+    version: "2.0.2"
   path_provider_macos:
     dependency: transitive
     description:
       name: path_provider_macos
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.0.0"
+    version: "2.0.2"
   path_provider_platform_interface:
     dependency: transitive
     description:
       name: path_provider_platform_interface
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.1"
   path_provider_windows:
     dependency: transitive
     description:
       name: path_provider_windows
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.0.1"
+    version: "2.0.3"
   pedantic:
     dependency: transitive
     description:
       name: pedantic
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.11.1"
   photo_view:
@@ -547,91 +547,91 @@ packages:
     dependency: transitive
     description:
       name: platform
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "3.0.0"
   plugin_platform_interface:
     dependency: transitive
     description:
       name: plugin_platform_interface
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.1"
   pool:
     dependency: transitive
     description:
       name: pool
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.5.0"
   process:
     dependency: transitive
     description:
       name: process
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "4.2.3"
   protobuf:
     dependency: transitive
     description:
       name: protobuf
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.0"
   provider:
     dependency: transitive
     description:
       name: provider
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "5.0.0"
   pub_semver:
     dependency: transitive
     description:
       name: pub_semver
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.0"
   pubspec_parse:
     dependency: transitive
     description:
       name: pubspec_parse
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.0"
   quiver:
     dependency: transitive
     description:
       name: quiver
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "3.0.1"
   quiver_hashcode:
     dependency: transitive
     description:
       name: quiver_hashcode
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.0"
   shelf:
     dependency: transitive
     description:
       name: shelf
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.2.0"
   shelf_web_socket:
     dependency: transitive
     description:
       name: shelf_web_socket
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.1"
   sized_context:
     dependency: "direct main"
     description:
       name: sized_context
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.0+1"
   sky_engine:
@@ -643,189 +643,189 @@ packages:
     dependency: transitive
     description:
       name: source_gen
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.5"
   source_span:
     dependency: transitive
     description:
       name: source_span
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.8.1"
   stack_trace:
     dependency: transitive
     description:
       name: stack_trace
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.10.0"
   stream_channel:
     dependency: transitive
     description:
       name: stream_channel
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.1.0"
   stream_transform:
     dependency: transitive
     description:
       name: stream_transform
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.0"
   string_scanner:
     dependency: transitive
     description:
       name: string_scanner
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.1.0"
   string_validator:
     dependency: transitive
     description:
       name: string_validator
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "0.3.0"
   styled_widget:
     dependency: "direct main"
     description:
       name: styled_widget
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "0.3.1+2"
   term_glyph:
     dependency: transitive
     description:
       name: term_glyph
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.2.0"
   test_api:
     dependency: transitive
     description:
       name: test_api
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "0.4.1"
   textstyle_extensions:
     dependency: transitive
     description:
       name: textstyle_extensions
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.0-nullsafety"
   time:
     dependency: "direct main"
     description:
       name: time
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.0"
   timing:
     dependency: transitive
     description:
       name: timing
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.0"
   tuple:
     dependency: transitive
     description:
       name: tuple
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.0"
   typed_data:
     dependency: transitive
     description:
       name: typed_data
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.3.0"
   universal_platform:
     dependency: transitive
     description:
       name: universal_platform
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.0+1"
   url_launcher:
     dependency: transitive
     description:
       name: url_launcher
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "6.0.9"
   url_launcher_linux:
     dependency: transitive
     description:
       name: url_launcher_linux
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.0.0"
+    version: "2.0.1"
   url_launcher_macos:
     dependency: transitive
     description:
       name: url_launcher_macos
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.0.0"
+    version: "2.0.1"
   url_launcher_platform_interface:
     dependency: transitive
     description:
       name: url_launcher_platform_interface
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.4"
   url_launcher_web:
     dependency: transitive
     description:
       name: url_launcher_web
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.0.1"
+    version: "2.0.2"
   url_launcher_windows:
     dependency: transitive
     description:
       name: url_launcher_windows
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.0.0"
+    version: "2.0.1"
   uuid:
     dependency: transitive
     description:
       name: uuid
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "3.0.4"
   vector_math:
     dependency: transitive
     description:
       name: vector_math
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.1.0"
   watcher:
     dependency: transitive
     description:
       name: watcher
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.0"
   web_socket_channel:
     dependency: transitive
     description:
       name: web_socket_channel
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.1.0"
   win32:
     dependency: transitive
     description:
       name: win32
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "2.2.5"
   window_size:
@@ -841,14 +841,14 @@ packages:
     dependency: transitive
     description:
       name: xdg_directories
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "0.2.0"
   yaml:
     dependency: transitive
     description:
       name: yaml
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dartlang.org"
     source: hosted
     version: "3.1.0"
 sdks:

+ 1 - 1
rust-lib/flowy-database/migrations/2021-07-09-063045_flowy-user/up.sql

@@ -31,7 +31,7 @@ CREATE TABLE app_table (
 
 CREATE TABLE view_table (
     id TEXT NOT NULL PRIMARY KEY,
-    app_id TEXT NOT NULL DEFAULT '',
+    belong_to_id TEXT NOT NULL DEFAULT '',
     name TEXT NOT NULL DEFAULT '',
     desc TEXT NOT NULL DEFAULT '',
     modified_time BIGINT NOT NULL DEFAULT 0,

+ 1 - 1
rust-lib/flowy-database/src/schema.rs

@@ -37,7 +37,7 @@ table! {
 table! {
     view_table (id) {
         id -> Text,
-        app_id -> Text,
+        belong_to_id -> Text,
         name -> Text,
         desc -> Text,
         modified_time -> BigInt,

+ 2 - 2
rust-lib/flowy-workspace/src/entities/app/app_query.rs

@@ -1,4 +1,4 @@
-use crate::{entities::app::parser::AppId, errors::*};
+use crate::{entities::app::parser::BelongToId, errors::*};
 use flowy_derive::ProtoBuf;
 use std::convert::TryInto;
 
@@ -20,7 +20,7 @@ impl TryInto<QueryAppParams> for QueryAppRequest {
     type Error = WorkspaceError;
 
     fn try_into(self) -> Result<QueryAppParams, Self::Error> {
-        let app_id = AppId::parse(self.app_id)
+        let app_id = BelongToId::parse(self.app_id)
             .map_err(|e| ErrorBuilder::new(WsErrCode::AppIdInvalid).msg(e).build())?
             .0;
 

+ 2 - 2
rust-lib/flowy-workspace/src/entities/app/app_update.rs

@@ -1,7 +1,7 @@
 use crate::{
     entities::{
         app::{
-            parser::{AppColorStyle, AppId, AppName},
+            parser::{AppColorStyle, AppName, BelongToId},
             ColorStyle,
         },
         workspace::parser::WorkspaceId,
@@ -41,7 +41,7 @@ impl TryInto<UpdateAppParams> for UpdateAppRequest {
     type Error = WorkspaceError;
 
     fn try_into(self) -> Result<UpdateAppParams, Self::Error> {
-        let app_id = AppId::parse(self.app_id)
+        let app_id = BelongToId::parse(self.app_id)
             .map_err(|e| ErrorBuilder::new(WsErrCode::AppIdInvalid).msg(e).build())?
             .0;
 

+ 4 - 4
rust-lib/flowy-workspace/src/entities/app/parser/app_id.rs → rust-lib/flowy-workspace/src/entities/app/parser/belong_to_id.rs

@@ -1,8 +1,8 @@
 #[derive(Debug)]
-pub struct AppId(pub String);
+pub struct BelongToId(pub String);
 
-impl AppId {
-    pub fn parse(s: String) -> Result<AppId, String> {
+impl BelongToId {
+    pub fn parse(s: String) -> Result<BelongToId, String> {
         if s.trim().is_empty() {
             return Err(format!("App id can not be empty or whitespace"));
         }
@@ -11,6 +11,6 @@ impl AppId {
     }
 }
 
-impl AsRef<str> for AppId {
+impl AsRef<str> for BelongToId {
     fn as_ref(&self) -> &str { &self.0 }
 }

+ 2 - 2
rust-lib/flowy-workspace/src/entities/app/parser/mod.rs

@@ -1,7 +1,7 @@
 mod app_color_style;
-mod app_id;
 mod app_name;
+mod belong_to_id;
 
 pub use app_color_style::*;
-pub use app_id::*;
 pub use app_name::*;
+pub use belong_to_id::*;

+ 6 - 6
rust-lib/flowy-workspace/src/entities/view/view_create.rs

@@ -1,5 +1,5 @@
 use crate::{
-    entities::{app::parser::AppId, view::parser::*},
+    entities::{app::parser::BelongToId, view::parser::*},
     errors::{ErrorBuilder, WorkspaceError, WsErrCode},
     impl_def_and_def_mut,
     sql_tables::view::ViewTableType,
@@ -20,7 +20,7 @@ impl std::default::Default for ViewType {
 #[derive(Default, ProtoBuf)]
 pub struct CreateViewRequest {
     #[pb(index = 1)]
-    pub app_id: String,
+    pub belong_to_id: String,
 
     #[pb(index = 2)]
     pub name: String,
@@ -36,7 +36,7 @@ pub struct CreateViewRequest {
 }
 
 pub struct CreateViewParams {
-    pub app_id: String,
+    pub belong_to_id: String,
     pub name: String,
     pub desc: String,
     pub thumbnail: String,
@@ -51,7 +51,7 @@ impl TryInto<CreateViewParams> for CreateViewRequest {
             .map_err(|e| ErrorBuilder::new(WsErrCode::ViewNameInvalid).msg(e).build())?
             .0;
 
-        let app_id = AppId::parse(self.app_id)
+        let belong_to_id = BelongToId::parse(self.belong_to_id)
             .map_err(|e| ErrorBuilder::new(WsErrCode::AppIdInvalid).msg(e).build())?
             .0;
 
@@ -70,7 +70,7 @@ impl TryInto<CreateViewParams> for CreateViewRequest {
 
         let view_type = ViewTypeCheck::parse(self.view_type).unwrap().0;
         Ok(CreateViewParams {
-            app_id,
+            belong_to_id,
             name,
             desc: self.desc,
             thumbnail,
@@ -85,7 +85,7 @@ pub struct View {
     pub id: String,
 
     #[pb(index = 2)]
-    pub app_id: String,
+    pub belong_to_id: String,
 
     #[pb(index = 3)]
     pub name: String,

+ 95 - 94
rust-lib/flowy-workspace/src/protobuf/model/view_create.rs

@@ -26,7 +26,7 @@
 #[derive(PartialEq,Clone,Default)]
 pub struct CreateViewRequest {
     // message fields
-    pub app_id: ::std::string::String,
+    pub belong_to_id: ::std::string::String,
     pub name: ::std::string::String,
     pub desc: ::std::string::String,
     pub view_type: ViewType,
@@ -53,30 +53,30 @@ impl CreateViewRequest {
         ::std::default::Default::default()
     }
 
-    // string app_id = 1;
+    // string belong_to_id = 1;
 
 
-    pub fn get_app_id(&self) -> &str {
-        &self.app_id
+    pub fn get_belong_to_id(&self) -> &str {
+        &self.belong_to_id
     }
-    pub fn clear_app_id(&mut self) {
-        self.app_id.clear();
+    pub fn clear_belong_to_id(&mut self) {
+        self.belong_to_id.clear();
     }
 
     // Param is passed by value, moved
-    pub fn set_app_id(&mut self, v: ::std::string::String) {
-        self.app_id = v;
+    pub fn set_belong_to_id(&mut self, v: ::std::string::String) {
+        self.belong_to_id = v;
     }
 
     // Mutable pointer to the field.
     // If field is not initialized, it is initialized with default value first.
-    pub fn mut_app_id(&mut self) -> &mut ::std::string::String {
-        &mut self.app_id
+    pub fn mut_belong_to_id(&mut self) -> &mut ::std::string::String {
+        &mut self.belong_to_id
     }
 
     // Take field
-    pub fn take_app_id(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.app_id, ::std::string::String::new())
+    pub fn take_belong_to_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.belong_to_id, ::std::string::String::new())
     }
 
     // string name = 2;
@@ -206,7 +206,7 @@ impl ::protobuf::Message for CreateViewRequest {
             let (field_number, wire_type) = is.read_tag_unpack()?;
             match field_number {
                 1 => {
-                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.app_id)?;
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.belong_to_id)?;
                 },
                 2 => {
                     ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
@@ -235,8 +235,8 @@ impl ::protobuf::Message for CreateViewRequest {
     #[allow(unused_variables)]
     fn compute_size(&self) -> u32 {
         let mut my_size = 0;
-        if !self.app_id.is_empty() {
-            my_size += ::protobuf::rt::string_size(1, &self.app_id);
+        if !self.belong_to_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.belong_to_id);
         }
         if !self.name.is_empty() {
             my_size += ::protobuf::rt::string_size(2, &self.name);
@@ -260,8 +260,8 @@ impl ::protobuf::Message for CreateViewRequest {
     }
 
     fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
-        if !self.app_id.is_empty() {
-            os.write_string(1, &self.app_id)?;
+        if !self.belong_to_id.is_empty() {
+            os.write_string(1, &self.belong_to_id)?;
         }
         if !self.name.is_empty() {
             os.write_string(2, &self.name)?;
@@ -318,9 +318,9 @@ impl ::protobuf::Message for CreateViewRequest {
         descriptor.get(|| {
             let mut fields = ::std::vec::Vec::new();
             fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
-                "app_id",
-                |m: &CreateViewRequest| { &m.app_id },
-                |m: &mut CreateViewRequest| { &mut m.app_id },
+                "belong_to_id",
+                |m: &CreateViewRequest| { &m.belong_to_id },
+                |m: &mut CreateViewRequest| { &mut m.belong_to_id },
             ));
             fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
                 "name",
@@ -358,7 +358,7 @@ impl ::protobuf::Message for CreateViewRequest {
 
 impl ::protobuf::Clear for CreateViewRequest {
     fn clear(&mut self) {
-        self.app_id.clear();
+        self.belong_to_id.clear();
         self.name.clear();
         self.desc.clear();
         self.one_of_thumbnail = ::std::option::Option::None;
@@ -383,7 +383,7 @@ impl ::protobuf::reflect::ProtobufValue for CreateViewRequest {
 pub struct View {
     // message fields
     pub id: ::std::string::String,
-    pub app_id: ::std::string::String,
+    pub belong_to_id: ::std::string::String,
     pub name: ::std::string::String,
     pub desc: ::std::string::String,
     pub view_type: ViewType,
@@ -429,30 +429,30 @@ impl View {
         ::std::mem::replace(&mut self.id, ::std::string::String::new())
     }
 
-    // string app_id = 2;
+    // string belong_to_id = 2;
 
 
-    pub fn get_app_id(&self) -> &str {
-        &self.app_id
+    pub fn get_belong_to_id(&self) -> &str {
+        &self.belong_to_id
     }
-    pub fn clear_app_id(&mut self) {
-        self.app_id.clear();
+    pub fn clear_belong_to_id(&mut self) {
+        self.belong_to_id.clear();
     }
 
     // Param is passed by value, moved
-    pub fn set_app_id(&mut self, v: ::std::string::String) {
-        self.app_id = v;
+    pub fn set_belong_to_id(&mut self, v: ::std::string::String) {
+        self.belong_to_id = v;
     }
 
     // Mutable pointer to the field.
     // If field is not initialized, it is initialized with default value first.
-    pub fn mut_app_id(&mut self) -> &mut ::std::string::String {
-        &mut self.app_id
+    pub fn mut_belong_to_id(&mut self) -> &mut ::std::string::String {
+        &mut self.belong_to_id
     }
 
     // Take field
-    pub fn take_app_id(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.app_id, ::std::string::String::new())
+    pub fn take_belong_to_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.belong_to_id, ::std::string::String::new())
     }
 
     // string name = 3;
@@ -536,7 +536,7 @@ impl ::protobuf::Message for View {
                     ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?;
                 },
                 2 => {
-                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.app_id)?;
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.belong_to_id)?;
                 },
                 3 => {
                     ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
@@ -562,8 +562,8 @@ impl ::protobuf::Message for View {
         if !self.id.is_empty() {
             my_size += ::protobuf::rt::string_size(1, &self.id);
         }
-        if !self.app_id.is_empty() {
-            my_size += ::protobuf::rt::string_size(2, &self.app_id);
+        if !self.belong_to_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.belong_to_id);
         }
         if !self.name.is_empty() {
             my_size += ::protobuf::rt::string_size(3, &self.name);
@@ -583,8 +583,8 @@ impl ::protobuf::Message for View {
         if !self.id.is_empty() {
             os.write_string(1, &self.id)?;
         }
-        if !self.app_id.is_empty() {
-            os.write_string(2, &self.app_id)?;
+        if !self.belong_to_id.is_empty() {
+            os.write_string(2, &self.belong_to_id)?;
         }
         if !self.name.is_empty() {
             os.write_string(3, &self.name)?;
@@ -639,9 +639,9 @@ impl ::protobuf::Message for View {
                 |m: &mut View| { &mut m.id },
             ));
             fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
-                "app_id",
-                |m: &View| { &m.app_id },
-                |m: &mut View| { &mut m.app_id },
+                "belong_to_id",
+                |m: &View| { &m.belong_to_id },
+                |m: &mut View| { &mut m.belong_to_id },
             ));
             fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
                 "name",
@@ -675,7 +675,7 @@ impl ::protobuf::Message for View {
 impl ::protobuf::Clear for View {
     fn clear(&mut self) {
         self.id.clear();
-        self.app_id.clear();
+        self.belong_to_id.clear();
         self.name.clear();
         self.desc.clear();
         self.view_type = ViewType::Blank;
@@ -912,58 +912,59 @@ impl ::protobuf::reflect::ProtobufValue for ViewType {
 }
 
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\x11view_create.proto\"\xae\x01\n\x11CreateViewRequest\x12\x15\n\x06ap\
-    p_id\x18\x01\x20\x01(\tR\x05appId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\
-    \x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1e\n\tthumbn\
-    ail\x18\x04\x20\x01(\tH\0R\tthumbnail\x12&\n\tview_type\x18\x05\x20\x01(\
-    \x0e2\t.ViewTypeR\x08viewTypeB\x12\n\x10one_of_thumbnail\"}\n\x04View\
-    \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06app_id\x18\x02\
-    \x20\x01(\tR\x05appId\x12\x12\n\x04name\x18\x03\x20\x01(\tR\x04name\x12\
-    \x12\n\x04desc\x18\x04\x20\x01(\tR\x04desc\x12&\n\tview_type\x18\x05\x20\
-    \x01(\x0e2\t.ViewTypeR\x08viewType\"+\n\x0cRepeatedView\x12\x1b\n\x05ite\
-    ms\x18\x01\x20\x03(\x0b2\x05.ViewR\x05items*\x1e\n\x08ViewType\x12\t\n\
-    \x05Blank\x10\0\x12\x07\n\x03Doc\x10\x01J\xca\x06\n\x06\x12\x04\0\0\x16\
-    \x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x08\
-    \x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x19\n\x0b\n\x04\x04\0\x02\0\x12\
-    \x03\x03\x04\x16\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\
-    \x05\x04\0\x02\0\x01\x12\x03\x03\x0b\x11\n\x0c\n\x05\x04\0\x02\0\x03\x12\
-    \x03\x03\x14\x15\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x14\n\x0c\n\
-    \x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\
-    \x12\x03\x04\x0b\x0f\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x12\x13\n\
-    \x0b\n\x04\x04\0\x02\x02\x12\x03\x05\x04\x14\n\x0c\n\x05\x04\0\x02\x02\
-    \x05\x12\x03\x05\x04\n\n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\x05\x0b\x0f\
-    \n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\x05\x12\x13\n\x0b\n\x04\x04\0\x08\
-    \0\x12\x03\x06\x044\n\x0c\n\x05\x04\0\x08\0\x01\x12\x03\x06\n\x1a\n\x0b\
-    \n\x04\x04\0\x02\x03\x12\x03\x06\x1d2\n\x0c\n\x05\x04\0\x02\x03\x05\x12\
-    \x03\x06\x1d#\n\x0c\n\x05\x04\0\x02\x03\x01\x12\x03\x06$-\n\x0c\n\x05\
-    \x04\0\x02\x03\x03\x12\x03\x0601\n\x0b\n\x04\x04\0\x02\x04\x12\x03\x07\
-    \x04\x1b\n\x0c\n\x05\x04\0\x02\x04\x06\x12\x03\x07\x04\x0c\n\x0c\n\x05\
-    \x04\0\x02\x04\x01\x12\x03\x07\r\x16\n\x0c\n\x05\x04\0\x02\x04\x03\x12\
-    \x03\x07\x19\x1a\n\n\n\x02\x04\x01\x12\x04\t\0\x0f\x01\n\n\n\x03\x04\x01\
-    \x01\x12\x03\t\x08\x0c\n\x0b\n\x04\x04\x01\x02\0\x12\x03\n\x04\x12\n\x0c\
-    \n\x05\x04\x01\x02\0\x05\x12\x03\n\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\
-    \x12\x03\n\x0b\r\n\x0c\n\x05\x04\x01\x02\0\x03\x12\x03\n\x10\x11\n\x0b\n\
-    \x04\x04\x01\x02\x01\x12\x03\x0b\x04\x16\n\x0c\n\x05\x04\x01\x02\x01\x05\
-    \x12\x03\x0b\x04\n\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\x0b\x0b\x11\n\
-    \x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\x0b\x14\x15\n\x0b\n\x04\x04\x01\
-    \x02\x02\x12\x03\x0c\x04\x14\n\x0c\n\x05\x04\x01\x02\x02\x05\x12\x03\x0c\
-    \x04\n\n\x0c\n\x05\x04\x01\x02\x02\x01\x12\x03\x0c\x0b\x0f\n\x0c\n\x05\
-    \x04\x01\x02\x02\x03\x12\x03\x0c\x12\x13\n\x0b\n\x04\x04\x01\x02\x03\x12\
-    \x03\r\x04\x14\n\x0c\n\x05\x04\x01\x02\x03\x05\x12\x03\r\x04\n\n\x0c\n\
-    \x05\x04\x01\x02\x03\x01\x12\x03\r\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x03\
-    \x03\x12\x03\r\x12\x13\n\x0b\n\x04\x04\x01\x02\x04\x12\x03\x0e\x04\x1b\n\
-    \x0c\n\x05\x04\x01\x02\x04\x06\x12\x03\x0e\x04\x0c\n\x0c\n\x05\x04\x01\
-    \x02\x04\x01\x12\x03\x0e\r\x16\n\x0c\n\x05\x04\x01\x02\x04\x03\x12\x03\
-    \x0e\x19\x1a\n\n\n\x02\x04\x02\x12\x04\x10\0\x12\x01\n\n\n\x03\x04\x02\
-    \x01\x12\x03\x10\x08\x14\n\x0b\n\x04\x04\x02\x02\0\x12\x03\x11\x04\x1c\n\
-    \x0c\n\x05\x04\x02\x02\0\x04\x12\x03\x11\x04\x0c\n\x0c\n\x05\x04\x02\x02\
-    \0\x06\x12\x03\x11\r\x11\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\x11\x12\
-    \x17\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\x11\x1a\x1b\n\n\n\x02\x05\0\
-    \x12\x04\x13\0\x16\x01\n\n\n\x03\x05\0\x01\x12\x03\x13\x05\r\n\x0b\n\x04\
-    \x05\0\x02\0\x12\x03\x14\x04\x0e\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x14\
-    \x04\t\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x14\x0c\r\n\x0b\n\x04\x05\0\
-    \x02\x01\x12\x03\x15\x04\x0c\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x15\
-    \x04\x07\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x15\n\x0bb\x06proto3\
+    \n\x11view_create.proto\"\xb9\x01\n\x11CreateViewRequest\x12\x20\n\x0cbe\
+    long_to_id\x18\x01\x20\x01(\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\
+    \x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1e\n\
+    \tthumbnail\x18\x04\x20\x01(\tH\0R\tthumbnail\x12&\n\tview_type\x18\x05\
+    \x20\x01(\x0e2\t.ViewTypeR\x08viewTypeB\x12\n\x10one_of_thumbnail\"\x88\
+    \x01\n\x04View\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x20\n\x0cbe\
+    long_to_id\x18\x02\x20\x01(\tR\nbelongToId\x12\x12\n\x04name\x18\x03\x20\
+    \x01(\tR\x04name\x12\x12\n\x04desc\x18\x04\x20\x01(\tR\x04desc\x12&\n\tv\
+    iew_type\x18\x05\x20\x01(\x0e2\t.ViewTypeR\x08viewType\"+\n\x0cRepeatedV\
+    iew\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.ViewR\x05items*\x1e\n\
+    \x08ViewType\x12\t\n\x05Blank\x10\0\x12\x07\n\x03Doc\x10\x01J\xca\x06\n\
+    \x06\x12\x04\0\0\x16\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\
+    \x12\x04\x02\0\x08\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x19\n\x0b\n\
+    \x04\x04\0\x02\0\x12\x03\x03\x04\x1c\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\
+    \x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0b\x17\n\x0c\n\x05\
+    \x04\0\x02\0\x03\x12\x03\x03\x1a\x1b\n\x0b\n\x04\x04\0\x02\x01\x12\x03\
+    \x04\x04\x14\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\
+    \x04\0\x02\x01\x01\x12\x03\x04\x0b\x0f\n\x0c\n\x05\x04\0\x02\x01\x03\x12\
+    \x03\x04\x12\x13\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x05\x04\x14\n\x0c\n\
+    \x05\x04\0\x02\x02\x05\x12\x03\x05\x04\n\n\x0c\n\x05\x04\0\x02\x02\x01\
+    \x12\x03\x05\x0b\x0f\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\x05\x12\x13\n\
+    \x0b\n\x04\x04\0\x08\0\x12\x03\x06\x044\n\x0c\n\x05\x04\0\x08\0\x01\x12\
+    \x03\x06\n\x1a\n\x0b\n\x04\x04\0\x02\x03\x12\x03\x06\x1d2\n\x0c\n\x05\
+    \x04\0\x02\x03\x05\x12\x03\x06\x1d#\n\x0c\n\x05\x04\0\x02\x03\x01\x12\
+    \x03\x06$-\n\x0c\n\x05\x04\0\x02\x03\x03\x12\x03\x0601\n\x0b\n\x04\x04\0\
+    \x02\x04\x12\x03\x07\x04\x1b\n\x0c\n\x05\x04\0\x02\x04\x06\x12\x03\x07\
+    \x04\x0c\n\x0c\n\x05\x04\0\x02\x04\x01\x12\x03\x07\r\x16\n\x0c\n\x05\x04\
+    \0\x02\x04\x03\x12\x03\x07\x19\x1a\n\n\n\x02\x04\x01\x12\x04\t\0\x0f\x01\
+    \n\n\n\x03\x04\x01\x01\x12\x03\t\x08\x0c\n\x0b\n\x04\x04\x01\x02\0\x12\
+    \x03\n\x04\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\n\x04\n\n\x0c\n\x05\
+    \x04\x01\x02\0\x01\x12\x03\n\x0b\r\n\x0c\n\x05\x04\x01\x02\0\x03\x12\x03\
+    \n\x10\x11\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\x0b\x04\x1c\n\x0c\n\x05\
+    \x04\x01\x02\x01\x05\x12\x03\x0b\x04\n\n\x0c\n\x05\x04\x01\x02\x01\x01\
+    \x12\x03\x0b\x0b\x17\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\x0b\x1a\x1b\
+    \n\x0b\n\x04\x04\x01\x02\x02\x12\x03\x0c\x04\x14\n\x0c\n\x05\x04\x01\x02\
+    \x02\x05\x12\x03\x0c\x04\n\n\x0c\n\x05\x04\x01\x02\x02\x01\x12\x03\x0c\
+    \x0b\x0f\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\x0c\x12\x13\n\x0b\n\x04\
+    \x04\x01\x02\x03\x12\x03\r\x04\x14\n\x0c\n\x05\x04\x01\x02\x03\x05\x12\
+    \x03\r\x04\n\n\x0c\n\x05\x04\x01\x02\x03\x01\x12\x03\r\x0b\x0f\n\x0c\n\
+    \x05\x04\x01\x02\x03\x03\x12\x03\r\x12\x13\n\x0b\n\x04\x04\x01\x02\x04\
+    \x12\x03\x0e\x04\x1b\n\x0c\n\x05\x04\x01\x02\x04\x06\x12\x03\x0e\x04\x0c\
+    \n\x0c\n\x05\x04\x01\x02\x04\x01\x12\x03\x0e\r\x16\n\x0c\n\x05\x04\x01\
+    \x02\x04\x03\x12\x03\x0e\x19\x1a\n\n\n\x02\x04\x02\x12\x04\x10\0\x12\x01\
+    \n\n\n\x03\x04\x02\x01\x12\x03\x10\x08\x14\n\x0b\n\x04\x04\x02\x02\0\x12\
+    \x03\x11\x04\x1c\n\x0c\n\x05\x04\x02\x02\0\x04\x12\x03\x11\x04\x0c\n\x0c\
+    \n\x05\x04\x02\x02\0\x06\x12\x03\x11\r\x11\n\x0c\n\x05\x04\x02\x02\0\x01\
+    \x12\x03\x11\x12\x17\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\x11\x1a\x1b\n\
+    \n\n\x02\x05\0\x12\x04\x13\0\x16\x01\n\n\n\x03\x05\0\x01\x12\x03\x13\x05\
+    \r\n\x0b\n\x04\x05\0\x02\0\x12\x03\x14\x04\x0e\n\x0c\n\x05\x05\0\x02\0\
+    \x01\x12\x03\x14\x04\t\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x14\x0c\r\n\
+    \x0b\n\x04\x05\0\x02\x01\x12\x03\x15\x04\x0c\n\x0c\n\x05\x05\0\x02\x01\
+    \x01\x12\x03\x15\x04\x07\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x15\n\x0b\
+    b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 2 - 2
rust-lib/flowy-workspace/src/protobuf/proto/view_create.proto

@@ -1,7 +1,7 @@
 syntax = "proto3";
 
 message CreateViewRequest {
-    string app_id = 1;
+    string belong_to_id = 1;
     string name = 2;
     string desc = 3;
     oneof one_of_thumbnail { string thumbnail = 4; };
@@ -9,7 +9,7 @@ message CreateViewRequest {
 }
 message View {
     string id = 1;
-    string app_id = 2;
+    string belong_to_id = 2;
     string name = 3;
     string desc = 4;
     ViewType view_type = 5;

+ 1 - 1
rust-lib/flowy-workspace/src/services/view_controller.rs

@@ -22,7 +22,7 @@ impl ViewController {
         let view: View = view_table.clone().into();
         let _ = self.sql.create_view(view_table)?;
 
-        send_observable(&view.app_id, WorkspaceObservable::AppAddView);
+        send_observable(&view.belong_to_id, WorkspaceObservable::AppAddView);
         Ok(view)
     }
 

+ 4 - 4
rust-lib/flowy-workspace/src/sql_tables/view/view_table.rs

@@ -8,11 +8,11 @@ use flowy_database::schema::view_table;
 use flowy_infra::{timestamp, uuid};
 
 #[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)]
-#[belongs_to(AppTable, foreign_key = "app_id")]
+#[belongs_to(AppTable, foreign_key = "belong_to_id")]
 #[table_name = "view_table"]
 pub(crate) struct ViewTable {
     pub id: String,
-    pub app_id: String,
+    pub belong_to_id: String,
     pub name: String,
     pub desc: String,
     pub modified_time: i64,
@@ -28,7 +28,7 @@ impl ViewTable {
         let time = timestamp();
         ViewTable {
             id: view_id,
-            app_id: params.app_id,
+            belong_to_id: params.belong_to_id,
             name: params.name,
             desc: params.desc,
             modified_time: time,
@@ -48,7 +48,7 @@ impl std::convert::Into<View> for ViewTable {
 
         View {
             id: self.id,
-            app_id: self.app_id,
+            belong_to_id: self.belong_to_id,
             name: self.name,
             desc: self.desc,
             view_type,

+ 2 - 2
rust-lib/flowy-workspace/tests/event/app_test.rs

@@ -26,7 +26,7 @@ fn app_create_with_view_and_then_get_success() {
     let workspace = create_workspace("Workspace", "");
     let app = create_app("App A", "AppFlowy Github Project", &workspace.id);
     let request_a = CreateViewRequest {
-        app_id: app.id.clone(),
+        belong_to_id: app.id.clone(),
         name: "View A".to_string(),
         desc: "".to_string(),
         thumbnail: None,
@@ -34,7 +34,7 @@ fn app_create_with_view_and_then_get_success() {
     };
 
     let request_b = CreateViewRequest {
-        app_id: app.id.clone(),
+        belong_to_id: app.id.clone(),
         name: "View B".to_string(),
         desc: "".to_string(),
         thumbnail: None,