Quellcode durchsuchen

fix: make sidebar resizing follow cursor more closely (#1202)

* fix: make sidebar resizing follow cursor more closely

* fix: don't animate sidebar size changes when dragging
Richard Shiue vor 2 Jahren
Ursprung
Commit
a4a88959fd

+ 39 - 5
frontend/app_flowy/lib/workspace/application/home/home_bloc.dart

@@ -1,5 +1,6 @@
 import 'package:app_flowy/user/application/user_listener.dart';
 import 'package:app_flowy/workspace/application/edit_panel/edit_context.dart';
+import 'package:flowy_infra/time/duration.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-error-code/code.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
@@ -50,13 +51,24 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
           unauthorized: (_Unauthorized value) {
             emit(state.copyWith(unauthorized: true));
           },
-          collapseMenu: (e) {
+          collapseMenu: (_CollapseMenu e) {
             emit(state.copyWith(isMenuCollapsed: !state.isMenuCollapsed));
           },
-          editPanelResized: (e) {
-            final newOffset =
-                (state.resizeOffset + e.offset).clamp(-50, 200).toDouble();
-            emit(state.copyWith(resizeOffset: newOffset));
+          editPanelResizeStart: (_EditPanelResizeStart e) {
+            emit(state.copyWith(
+              resizeType: MenuResizeType.drag,
+              resizeStart: state.resizeOffset,
+            ));
+          },
+          editPanelResized: (_EditPanelResized e) {
+            final newPosition =
+                (e.offset + state.resizeStart).clamp(-50, 200).toDouble();
+            if (state.resizeOffset != newPosition) {
+              emit(state.copyWith(resizeOffset: newPosition));
+            }
+          },
+          editPanelResizeEnd: (_EditPanelResizeEnd e) {
+            emit(state.copyWith(resizeType: MenuResizeType.slide));
           },
         );
       },
@@ -78,6 +90,22 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
   }
 }
 
+enum MenuResizeType {
+  slide,
+  drag,
+}
+
+extension MenuResizeTypeExtension on MenuResizeType {
+  Duration duration() {
+    switch (this) {
+      case MenuResizeType.drag:
+        return 30.milliseconds;
+      case MenuResizeType.slide:
+        return 350.milliseconds;
+    }
+  }
+}
+
 @freezed
 class HomeEvent with _$HomeEvent {
   const factory HomeEvent.initial() = _Initial;
@@ -91,6 +119,8 @@ class HomeEvent with _$HomeEvent {
   const factory HomeEvent.unauthorized(String msg) = _Unauthorized;
   const factory HomeEvent.collapseMenu() = _CollapseMenu;
   const factory HomeEvent.editPanelResized(double offset) = _EditPanelResized;
+  const factory HomeEvent.editPanelResizeStart() = _EditPanelResizeStart;
+  const factory HomeEvent.editPanelResizeEnd() = _EditPanelResizeEnd;
 }
 
 @freezed
@@ -103,6 +133,8 @@ class HomeState with _$HomeState {
     required bool unauthorized,
     required bool isMenuCollapsed,
     required double resizeOffset,
+    required double resizeStart,
+    required MenuResizeType resizeType,
   }) = _HomeState;
 
   factory HomeState.initial(CurrentWorkspaceSettingPB workspaceSetting) =>
@@ -114,5 +146,7 @@ class HomeState with _$HomeState {
         unauthorized: false,
         isMenuCollapsed: false,
         resizeOffset: 0,
+        resizeStart: 0,
+        resizeType: MenuResizeType.slide,
       );
 }

+ 1 - 2
frontend/app_flowy/lib/workspace/presentation/home/home_layout.dart

@@ -2,7 +2,6 @@ import 'dart:io' show Platform;
 
 import 'package:app_flowy/workspace/application/home/home_bloc.dart';
 import 'package:flowy_infra/size.dart';
-import 'package:flowy_infra/time/duration.dart';
 import 'package:flutter/material.dart';
 // ignore: import_of_legacy_library_into_null_safe
 import 'package:sized_context/sized_context.dart';
@@ -44,7 +43,7 @@ class HomeLayout {
     homePageLOffset = (showMenu && !menuIsDrawer) ? menuWidth : 0.0;
 
     menuSpacing = !showMenu && Platform.isMacOS ? 80.0 : 0.0;
-    animDuration = .35.seconds;
+    animDuration = homeBlocState.resizeType.duration();
 
     editPanelWidth = HomeSizes.editPanelWidth;
     homePageROffset = showEditPanel ? editPanelWidth : 0;

+ 15 - 6
frontend/app_flowy/lib/workspace/presentation/home/home_screen.dart

@@ -176,11 +176,18 @@ class _HomeScreenState extends State<HomeScreen> {
       cursor: SystemMouseCursors.resizeLeftRight,
       child: GestureDetector(
           dragStartBehavior: DragStartBehavior.down,
-          onPanUpdate: ((details) {
-            context
-                .read<HomeBloc>()
-                .add(HomeEvent.editPanelResized(details.delta.dx));
-          }),
+          onHorizontalDragStart: (details) => context
+              .read<HomeBloc>()
+              .add(const HomeEvent.editPanelResizeStart()),
+          onHorizontalDragUpdate: (details) => context
+              .read<HomeBloc>()
+              .add(HomeEvent.editPanelResized(details.localPosition.dx)),
+          onHorizontalDragEnd: (details) => context
+              .read<HomeBloc>()
+              .add(const HomeEvent.editPanelResizeEnd()),
+          onHorizontalDragCancel: () => context
+              .read<HomeBloc>()
+              .add(const HomeEvent.editPanelResizeEnd()),
           behavior: HitTestBehavior.translucent,
           child: SizedBox(
             width: 10,
@@ -208,7 +215,6 @@ class _HomeScreenState extends State<HomeScreen> {
                 top: 0,
                 animate: true)
             .animate(layout.animDuration, Curves.easeOut),
-        homeMenuResizer.positioned(left: layout.homePageLOffset - 5),
         bubble
             .positioned(
               right: 20,
@@ -236,6 +242,9 @@ class _HomeScreenState extends State<HomeScreen> {
                 bottom: 0,
                 animate: true)
             .animate(layout.animDuration, Curves.easeOut),
+        homeMenuResizer
+            .positioned(left: layout.homePageLOffset - 5)
+            .animate(layout.animDuration, Curves.easeOut),
       ],
     );
   }