Add space order controls
This commit is contained in:
@@ -20,6 +20,7 @@ mod plugins;
|
||||
mod profiles;
|
||||
mod reading_list;
|
||||
mod site_permissions;
|
||||
mod spaces;
|
||||
mod splits;
|
||||
mod sync;
|
||||
mod tab_groups;
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
use ely_domain::SpaceId;
|
||||
|
||||
use super::BrowserCore;
|
||||
use crate::CoreError;
|
||||
|
||||
impl BrowserCore {
|
||||
pub fn move_space_up(&mut self, space_id: &SpaceId) -> Result<bool, CoreError> {
|
||||
let mut ordered_ids = self.sorted_space_ids();
|
||||
let Some(index) = ordered_ids.iter().position(|id| id == space_id) else {
|
||||
return Err(CoreError::SpaceNotFound { id: space_id.clone() });
|
||||
};
|
||||
|
||||
if index == 0 {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
ordered_ids.swap(index, index - 1);
|
||||
self.apply_space_order(&ordered_ids)?;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn move_space_down(&mut self, space_id: &SpaceId) -> Result<bool, CoreError> {
|
||||
let mut ordered_ids = self.sorted_space_ids();
|
||||
let Some(index) = ordered_ids.iter().position(|id| id == space_id) else {
|
||||
return Err(CoreError::SpaceNotFound { id: space_id.clone() });
|
||||
};
|
||||
|
||||
if index + 1 == ordered_ids.len() {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
ordered_ids.swap(index, index + 1);
|
||||
self.apply_space_order(&ordered_ids)?;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn sorted_space_ids(&self) -> Vec<SpaceId> {
|
||||
self.sorted_spaces().iter().map(|space| space.id().clone()).collect()
|
||||
}
|
||||
|
||||
fn apply_space_order(&mut self, ordered_ids: &[SpaceId]) -> Result<(), CoreError> {
|
||||
for (sort_key, space_id) in ordered_ids.iter().enumerate() {
|
||||
let Some(space) = self.spaces.iter_mut().find(|space| space.id() == space_id) else {
|
||||
return Err(CoreError::SpaceNotFound { id: space_id.clone() });
|
||||
};
|
||||
|
||||
let sort_key = sort_key as u64;
|
||||
if space.sort_key() != sort_key {
|
||||
space.set_sort_key(sort_key);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::error::Error;
|
||||
|
||||
use ely_browser_core::{BrowserCore, CoreError, InitialBrowserConfig};
|
||||
use ely_domain::{ArchivePolicy, DEFAULT_SIDEBAR_WIDTH_PX, ProfileId, ProfileKind};
|
||||
use ely_domain::{ArchivePolicy, DEFAULT_SIDEBAR_WIDTH_PX, ProfileId, ProfileKind, SpaceId};
|
||||
|
||||
#[test]
|
||||
fn created_space_binds_current_profile_as_default() -> Result<(), Box<dyn Error>> {
|
||||
@@ -87,6 +87,49 @@ fn snapshot_orders_spaces_by_sort_key() -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn moving_spaces_updates_visible_order() -> Result<(), Box<dyn Error>> {
|
||||
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
|
||||
let work_space_id = core.snapshot()?.active_space_id;
|
||||
let research_space_id = core.create_space("Research", "R", 0x9fc9a2)?;
|
||||
let personal_space_id = core.create_space("Personal", "P", 0x8eb7d4)?;
|
||||
|
||||
core.set_space_sort_key(&work_space_id, 20)?;
|
||||
core.set_space_sort_key(&research_space_id, 10)?;
|
||||
core.set_space_sort_key(&personal_space_id, 30)?;
|
||||
|
||||
assert!(core.move_space_up(&work_space_id)?);
|
||||
assert_eq!(
|
||||
ordered_space_ids(&core)?,
|
||||
vec![work_space_id.clone(), research_space_id.clone(), personal_space_id.clone()]
|
||||
);
|
||||
|
||||
assert!(core.move_space_down(&work_space_id)?);
|
||||
assert_eq!(
|
||||
ordered_space_ids(&core)?,
|
||||
vec![research_space_id, work_space_id, personal_space_id]
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn moving_boundary_or_missing_space_is_safe() -> Result<(), Box<dyn Error>> {
|
||||
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
|
||||
let work_space_id = core.snapshot()?.active_space_id;
|
||||
|
||||
assert!(!core.move_space_up(&work_space_id)?);
|
||||
assert!(!core.move_space_down(&work_space_id)?);
|
||||
|
||||
let missing_space_id = SpaceId::new();
|
||||
let error = match core.move_space_up(&missing_space_id) {
|
||||
Err(error) => error,
|
||||
Ok(_) => return Err("moving a missing space should fail".into()),
|
||||
};
|
||||
|
||||
assert_eq!(error, CoreError::SpaceNotFound { id: missing_space_id });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn space_default_profile_updates_with_profile_validation() -> Result<(), Box<dyn Error>> {
|
||||
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
|
||||
@@ -186,3 +229,7 @@ fn active_space_updated_at(
|
||||
|
||||
Ok(space.updated_at())
|
||||
}
|
||||
|
||||
fn ordered_space_ids(core: &BrowserCore) -> Result<Vec<SpaceId>, Box<dyn Error>> {
|
||||
Ok(core.snapshot()?.spaces.iter().map(|space| space.id().clone()).collect())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user