Add tab group sidebar support

This commit is contained in:
2026-05-08 07:16:17 -04:00
parent cbd8d7a091
commit adf5b27207
12 changed files with 572 additions and 31 deletions
@@ -9,7 +9,7 @@ use crate::{
move_tab_space_name, new_private_profile_name, new_profile_name, new_space_name, note_body,
notes_url, plugin_detail_url, plugins_url, reading_list_url, reading_progress_percent,
search_url, settings_page_url, settings_url, shortcut_settings_url, space_icon,
switch_profile_name, sync_status_url, tab_note_body, task_manager_url,
switch_profile_name, sync_status_url, tab_group_name, tab_note_body, task_manager_url,
},
};
@@ -133,6 +133,10 @@ impl BrowserCore {
self.set_active_tab_reading_progress(percent)?;
return Ok(true);
}
if let Some(name) = tab_group_name(command) {
self.group_active_tab(name)?;
return Ok(true);
}
if let Some(body) = tab_note_body(command) {
self.save_active_tab_note(body)?;
return Ok(true);
@@ -0,0 +1,100 @@
use ely_domain::{TabGroup, TabGroupId, TabId};
use crate::CoreError;
use super::BrowserCore;
impl BrowserCore {
pub fn group_active_tab(&mut self, name: impl Into<String>) -> Result<TabGroupId, CoreError> {
let group_id = self.find_or_create_active_space_tab_group(name)?;
let active_tab_id = self.active_tab_id.clone();
self.assign_tab_to_group(&active_tab_id, &group_id)?;
Ok(group_id)
}
pub fn assign_tab_to_group(
&mut self,
tab_id: &TabId,
group_id: &TabGroupId,
) -> Result<(), CoreError> {
let group_space_id = self
.tab_groups
.iter()
.find(|group| group.id() == group_id)
.map(|group| group.space_id().clone())
.ok_or_else(|| CoreError::TabGroupNotFound { id: group_id.clone() })?;
let tab = self
.tabs
.iter_mut()
.find(|tab| tab.id() == tab_id)
.ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?;
if tab.space_id() != &group_space_id {
return Err(CoreError::TabGroupNotFound { id: group_id.clone() });
}
tab.set_group_id(group_id.clone());
Ok(())
}
pub fn clear_tab_group(&mut self, tab_id: &TabId) -> Result<(), CoreError> {
let tab = self
.tabs
.iter_mut()
.find(|tab| tab.id() == tab_id)
.ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?;
tab.clear_group_id();
Ok(())
}
pub(super) fn visible_tab_groups(&self) -> Vec<TabGroup> {
let mut groups = self
.tab_groups
.iter()
.filter(|group| group.space_id() == &self.active_space_id)
.cloned()
.collect::<Vec<_>>();
groups.sort_by(|left, right| {
left.sort_key().cmp(&right.sort_key()).then_with(|| left.id().cmp(right.id()))
});
groups
}
fn find_or_create_active_space_tab_group(
&mut self,
name: impl Into<String>,
) -> Result<TabGroupId, CoreError> {
let name = name.into();
if let Some(group_id) = self.find_active_space_group_id(&name) {
return Ok(group_id);
}
let active_space_id = self.active_space_id.clone();
let color_hex = self.active_space()?.accent_hex();
let sort_key = self.next_tab_group_sort_key();
let group = TabGroup::new(active_space_id, name, color_hex, sort_key)?;
let group_id = group.id().clone();
self.tab_groups.push(group);
Ok(group_id)
}
fn find_active_space_group_id(&self, name: &str) -> Option<TabGroupId> {
let normalized_name = name.trim().to_lowercase();
self.tab_groups
.iter()
.find(|group| {
group.space_id() == &self.active_space_id
&& group.name().to_lowercase() == normalized_name
})
.map(|group| group.id().clone())
}
fn next_tab_group_sort_key(&self) -> u64 {
self.tab_groups
.iter()
.filter(|group| group.space_id() == &self.active_space_id)
.map(TabGroup::sort_key)
.max()
.map_or(0, |sort_key| sort_key.saturating_add(1))
}
}
+2 -2
View File
@@ -4,13 +4,12 @@ use ely_domain::{
ArchivePolicy, ArchiveSource, ArchivedTab, BrowserTab, ProfileId, SpaceId, TabId, UrlText,
};
use super::BrowserCore;
use crate::{
CoreError,
navigation::{tab_matches_query, tab_title},
};
use super::BrowserCore;
impl BrowserCore {
pub fn open_new_tab(&mut self) -> Result<TabId, CoreError> {
let url = self.new_tab_url()?;
@@ -53,6 +52,7 @@ impl BrowserCore {
let tab_index = self.active_tab_index()?;
let target_sort_key = self.next_tab_sort_key(space_id);
self.tabs[tab_index].move_to_space(space_id.clone());
self.tabs[tab_index].clear_group_id();
self.tabs[tab_index].set_sort_key(target_sort_key);
self.sort_tabs_within_space(space_id);
self.active_tabs_by_space.insert(space_id.clone(), tab_id.clone());