Track tab sort keys

This commit is contained in:
2026-05-08 05:47:50 -04:00
parent bce489c119
commit 668557773b
5 changed files with 130 additions and 9 deletions
+12 -8
View File
@@ -20,6 +20,7 @@ mod reading_list;
mod site_permissions;
mod splits;
mod sync;
mod tab_order;
mod tabs;
pub use plugins::{InstalledPlugin, PluginAuditAction, PluginAuditEvent};
@@ -125,7 +126,8 @@ impl BrowserCore {
active_profile_id.clone(),
new_tab_title,
new_tab_url.clone(),
);
)
.with_sort_key(0);
let active_tab_id = tab.id().clone();
let mut active_tabs_by_space = BTreeMap::new();
let mut active_tabs_by_space_profile = BTreeMap::new();
@@ -406,16 +408,18 @@ impl BrowserCore {
}
fn pinned_tabs(&self) -> Vec<BrowserTab> {
self.tabs
.iter()
.filter(|tab| tab.space_id() == &self.active_space_id)
.filter(|tab| tab.flags().pinned && !tab.flags().favorite)
.cloned()
.collect()
tab_order::sorted_tabs(
self.tabs
.iter()
.filter(|tab| tab.space_id() == &self.active_space_id)
.filter(|tab| tab.flags().pinned && !tab.flags().favorite),
)
}
fn visible_tabs(&self) -> Vec<BrowserTab> {
self.tabs.iter().filter(|tab| tab.space_id() == &self.active_space_id).cloned().collect()
tab_order::sorted_tabs(
self.tabs.iter().filter(|tab| tab.space_id() == &self.active_space_id),
)
}
fn record_tab_activity(&mut self, tab_id: &TabId, active_at: SystemTime) {
@@ -0,0 +1,47 @@
use ely_domain::{BrowserTab, SpaceId};
use super::BrowserCore;
impl BrowserCore {
pub(super) fn next_tab_sort_key(&self, space_id: &SpaceId) -> u64 {
self.tabs
.iter()
.filter(|tab| tab.space_id() == space_id)
.map(BrowserTab::sort_key)
.max()
.map_or(0, |sort_key| sort_key.saturating_add(1))
}
pub(super) fn normalize_tab_sort_keys(&mut self, space_id: &SpaceId) {
let mut sort_key = 0;
for tab in self.tabs.iter_mut().filter(|tab| tab.space_id() == space_id) {
tab.set_sort_key(sort_key);
sort_key = sort_key.saturating_add(1);
}
}
pub(super) fn sort_tabs_within_space(&mut self, space_id: &SpaceId) {
let indices = self
.tabs
.iter()
.enumerate()
.filter_map(|(index, tab)| (tab.space_id() == space_id).then_some(index))
.collect::<Vec<_>>();
let mut tabs = indices.iter().map(|index| self.tabs[*index].clone()).collect::<Vec<_>>();
tabs.sort_by(compare_tabs);
for (index, tab) in indices.into_iter().zip(tabs) {
self.tabs[index] = tab;
}
}
}
pub(super) fn sorted_tabs<'a>(tabs: impl Iterator<Item = &'a BrowserTab>) -> Vec<BrowserTab> {
let mut tabs = tabs.cloned().collect::<Vec<_>>();
tabs.sort_by(compare_tabs);
tabs
}
fn compare_tabs(left: &BrowserTab, right: &BrowserTab) -> std::cmp::Ordering {
left.sort_key().cmp(&right.sort_key()).then_with(|| left.id().cmp(right.id()))
}
+21 -1
View File
@@ -20,6 +20,7 @@ impl BrowserCore {
pub fn open_tab(&mut self, url: UrlText) -> TabId {
let tab = self.build_tab(url);
let tab_id = tab.id().clone();
let space_id = tab.space_id().clone();
let insert_index = self
.tabs
.iter()
@@ -27,6 +28,7 @@ impl BrowserCore {
.map_or(self.tabs.len(), |index| index + 1);
self.record_history_entry(&tab);
self.tabs.insert(insert_index, tab);
self.normalize_tab_sort_keys(&space_id);
self.active_tab_id = tab_id.clone();
self.active_tabs_by_space.insert(self.active_space_id.clone(), tab_id.clone());
self.active_tabs_by_space_profile
@@ -49,7 +51,10 @@ impl BrowserCore {
self.detach_tab_from_split(&tab_id);
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].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());
self.active_tabs_by_space_profile.remove(&(source_space_id.clone(), profile_id.clone()));
@@ -257,6 +262,18 @@ impl BrowserCore {
Ok(())
}
pub fn set_tab_sort_key(&mut self, tab_id: &TabId, sort_key: u64) -> Result<(), CoreError> {
let tab = self
.tabs
.iter_mut()
.find(|tab| tab.id() == tab_id)
.ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?;
let space_id = tab.space_id().clone();
tab.set_sort_key(sort_key);
self.sort_tabs_within_space(&space_id);
Ok(())
}
pub fn active_tab(&self) -> Result<&BrowserTab, CoreError> {
self.tabs
.iter()
@@ -279,7 +296,8 @@ impl BrowserCore {
url: UrlText,
) -> BrowserTab {
let title = tab_title(&url);
BrowserTab::new(TabId::new(), space_id, profile_id, title, url)
let sort_key = self.next_tab_sort_key(&space_id);
BrowserTab::new(TabId::new(), space_id, profile_id, title, url).with_sort_key(sort_key)
}
pub(super) fn tab_belongs_to_space(&self, tab_id: &TabId, space_id: &SpaceId) -> bool {
@@ -294,7 +312,9 @@ impl BrowserCore {
.position(|existing| existing.id() == &self.active_tab_id)
.map_or(self.tabs.len(), |index| index + 1);
let space_id = tab.space_id().clone();
self.tabs.insert(insert_index, tab);
self.normalize_tab_sort_keys(&space_id);
self.select_tab(&tab_id)?;
Ok(tab_id)
}