Browse Source

fix: reorder bugs

appflowy 3 years ago
parent
commit
ecd2dc3e72

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

@@ -161,11 +161,12 @@ class AppViewDataContext extends ChangeNotifier {
   final String appId;
   final ValueNotifier<List<View>> _viewsNotifier = ValueNotifier([]);
   final ValueNotifier<View?> _selectedViewNotifier = ValueNotifier(null);
+  VoidCallback? _menuSharedStateListener;
   ExpandableController expandController = ExpandableController(initialExpanded: false);
 
   AppViewDataContext({required this.appId}) {
     _setLatestView(getIt<MenuSharedState>().latestOpenView);
-    getIt<MenuSharedState>().addLatestViewListener((view) {
+    _menuSharedStateListener = getIt<MenuSharedState>().addLatestViewListener((view) {
       _setLatestView(view);
     });
   }
@@ -234,4 +235,12 @@ class AppViewDataContext extends ChangeNotifier {
       });
     }
   }
+
+  @override
+  void dispose() {
+    if (_menuSharedStateListener != null) {
+      getIt<MenuSharedState>().removeLatestViewListener(_menuSharedStateListener!);
+    }
+    super.dispose();
+  }
 }

+ 3 - 0
frontend/app_flowy/lib/workspace/application/menu/menu_bloc.dart

@@ -45,6 +45,9 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
           if (state.apps.length > value.fromIndex) {
             final app = state.apps[value.fromIndex];
             _workspaceService.moveApp(appId: app.id, fromIndex: value.fromIndex, toIndex: value.toIndex);
+            final apps = List<App>.from(state.apps);
+            apps.insert(value.toIndex, apps.removeAt(value.fromIndex));
+            emit(state.copyWith(apps: apps));
           }
         },
       );

+ 9 - 1
frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart

@@ -8,6 +8,7 @@ import 'package:flowy_infra/size.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
+import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile;
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
@@ -116,7 +117,14 @@ class HomeMenu extends StatelessWidget {
                   padding: EdgeInsets.only(bottom: 20.0 - MenuAppSizes.appVPadding),
                   child: MenuUser(user),
                 ),
-                onReorder: (oldIndex, newIndex) => context.read<MenuBloc>().add(MenuEvent.moveApp(oldIndex, newIndex)),
+                onReorder: (oldIndex, newIndex) {
+                  // Moving item1 from index 0 to index 1
+                  //  expect:   oldIndex: 0, newIndex: 1
+                  //  receive:  oldIndex: 0, newIndex: 2
+                  //  Workaround: if newIndex > oldIndex, we just minus one
+                  int index = newIndex > oldIndex ? newIndex - 1 : newIndex;
+                  context.read<MenuBloc>().add(MenuEvent.moveApp(oldIndex, index));
+                },
                 physics: StyledScrollPhysics(),
                 itemBuilder: (BuildContext context, int index) {
                   return ReorderableDragStartListener(

+ 1 - 1
frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs

@@ -12,7 +12,7 @@ use flowy_database::{
     schema::{view_table, view_table::dsl},
     SqliteConnection,
 };
-use lib_infra::timestamp;
+use lib_infra::util::timestamp;
 
 pub struct ViewTableSql();
 impl ViewTableSql {

+ 1 - 1
frontend/rust-lib/flowy-net/src/local_server/server.rs

@@ -265,7 +265,7 @@ use flowy_user::event_map::UserCloudService;
 use flowy_user_data_model::entities::{
     SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile,
 };
-use lib_infra::{future::FutureResult, timestamp};
+use lib_infra::{future::FutureResult, util::timestamp};
 
 impl FolderCouldServiceV1 for LocalServer {
     fn init(&self) {}

+ 10 - 16
shared-lib/flowy-sync/src/client_folder/folder_pad.rs

@@ -10,6 +10,8 @@ use crate::{
 use flowy_folder_data_model::entities::{app::App, trash::Trash, view::View, workspace::Workspace};
 use lib_ot::core::*;
 
+use crate::errors::internal_error;
+use lib_infra::util::move_vec_element;
 use serde::{Deserialize, Serialize};
 use std::sync::Arc;
 
@@ -170,16 +172,12 @@ impl FolderPad {
     }
 
     #[tracing::instrument(level = "trace", skip(self), err)]
-    pub fn move_app(&mut self, app_id: &str, _from: usize, to: usize) -> CollaborateResult<Option<FolderChange>> {
+    pub fn move_app(&mut self, app_id: &str, from: usize, to: usize) -> CollaborateResult<Option<FolderChange>> {
         let app = self.read_app(app_id)?;
         self.with_workspace(&app.workspace_id, |workspace| {
-            match workspace.apps.iter().position(|app| app.id == app_id) {
-                None => Ok(None),
-                Some(index) => {
-                    let app = workspace.apps.remove(index);
-                    workspace.apps.insert(to, app);
-                    Ok(Some(()))
-                }
+            match move_vec_element(&mut workspace.apps, |app| app.id == app_id, from, to).map_err(internal_error)? {
+                true => Ok(Some(())),
+                false => Ok(None),
             }
         })
     }
@@ -251,16 +249,12 @@ impl FolderPad {
     }
 
     #[tracing::instrument(level = "trace", skip(self), err)]
-    pub fn move_view(&mut self, view_id: &str, _from: usize, to: usize) -> CollaborateResult<Option<FolderChange>> {
+    pub fn move_view(&mut self, view_id: &str, from: usize, to: usize) -> CollaborateResult<Option<FolderChange>> {
         let view = self.read_view(view_id)?;
         self.with_app(&view.belong_to_id, |app| {
-            match app.belongings.iter().position(|view| view.id == view_id) {
-                None => Ok(None),
-                Some(index) => {
-                    let view = app.belongings.remove(index);
-                    app.belongings.insert(to, view);
-                    Ok(Some(()))
-                }
+            match move_vec_element(&mut app.belongings, |view| view.id == view_id, from, to).map_err(internal_error)? {
+                true => Ok(Some(())),
+                false => Ok(None),
             }
         })
     }

+ 1 - 5
shared-lib/lib-infra/src/lib.rs

@@ -1,8 +1,4 @@
 pub mod code_gen;
 pub mod future;
 pub mod retry;
-
-#[allow(dead_code)]
-pub fn timestamp() -> i64 {
-    chrono::Utc::now().timestamp()
-}
+pub mod util;

+ 32 - 0
shared-lib/lib-infra/src/util.rs

@@ -0,0 +1,32 @@
+pub fn move_vec_element<T, F>(
+    vec: &mut Vec<T>,
+    filter: F,
+    _from_index: usize,
+    mut to_index: usize,
+) -> Result<bool, String>
+where
+    F: FnMut(&T) -> bool,
+{
+    match vec.iter().position(filter) {
+        None => Ok(false),
+        Some(index) => {
+            if vec.len() > to_index {
+                let removed_element = vec.remove(index);
+                vec.insert(to_index, removed_element);
+                Ok(true)
+            } else {
+                let msg = format!(
+                    "Move element to invalid index: {}, current len: {}",
+                    to_index,
+                    vec.len()
+                );
+                Err(msg)
+            }
+        }
+    }
+}
+
+#[allow(dead_code)]
+pub fn timestamp() -> i64 {
+    chrono::Utc::now().timestamp()
+}