mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: reorder bugs
This commit is contained in:
parent
f972cdd3fb
commit
ecd2dc3e72
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -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(
|
||||
|
@ -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 {
|
||||
|
@ -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,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,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
shared-lib/lib-infra/src/util.rs
Normal file
32
shared-lib/lib-infra/src/util.rs
Normal file
@ -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()
|
||||
}
|
Loading…
Reference in New Issue
Block a user