Add tab group color command
This commit is contained in:
@@ -112,6 +112,14 @@ pub(crate) fn rename_tab_group_name(command: &str) -> Option<&str> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn tab_group_color_hex(command: &str) -> Option<u32> {
|
||||||
|
let value = command_argument(
|
||||||
|
command,
|
||||||
|
&["set-tab-group-color ", "set tab group color ", "tab-group-color ", "tab group color "],
|
||||||
|
)?;
|
||||||
|
parse_color_hex(value)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn split_group_name(command: &str) -> Option<&str> {
|
pub(crate) fn split_group_name(command: &str) -> Option<&str> {
|
||||||
command_argument(
|
command_argument(
|
||||||
command,
|
command,
|
||||||
@@ -142,6 +150,15 @@ fn command_argument<'a>(command: &'a str, prefixes: &[&str]) -> Option<&'a str>
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_color_hex(value: &str) -> Option<u32> {
|
||||||
|
let value = value.trim().strip_prefix('#').unwrap_or(value.trim());
|
||||||
|
if value.len() != 6 || !value.as_bytes().iter().all(u8::is_ascii_hexdigit) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32::from_str_radix(value, 16).ok()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn space_icon(name: &str) -> String {
|
pub(crate) fn space_icon(name: &str) -> String {
|
||||||
name.chars().next().map_or_else(String::new, |value| value.to_string())
|
name.chars().next().map_or_else(String::new, |value| value.to_string())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ use crate::{
|
|||||||
move_tab_space_name, new_private_profile_name, new_profile_name, new_space_name, note_body,
|
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,
|
notes_url, plugin_detail_url, plugins_url, reading_list_url, reading_progress_percent,
|
||||||
rename_tab_group_name, search_url, settings_page_url, settings_url, shortcut_settings_url,
|
rename_tab_group_name, search_url, settings_page_url, settings_url, shortcut_settings_url,
|
||||||
space_icon, split_group_name, switch_profile_name, sync_status_url, tab_group_name,
|
space_icon, split_group_name, switch_profile_name, sync_status_url, tab_group_color_hex,
|
||||||
tab_note_body, task_manager_url,
|
tab_group_name, tab_note_body, task_manager_url,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -149,6 +149,9 @@ impl BrowserCore {
|
|||||||
if let Some(name) = rename_tab_group_name(command) {
|
if let Some(name) = rename_tab_group_name(command) {
|
||||||
return Ok(self.rename_active_tab_group(name)?.is_some());
|
return Ok(self.rename_active_tab_group(name)?.is_some());
|
||||||
}
|
}
|
||||||
|
if let Some(color_hex) = tab_group_color_hex(command) {
|
||||||
|
return Ok(self.set_active_tab_group_color(color_hex)?.is_some());
|
||||||
|
}
|
||||||
if let Some(body) = tab_note_body(command) {
|
if let Some(body) = tab_note_body(command) {
|
||||||
self.save_active_tab_note(body)?;
|
self.save_active_tab_note(body)?;
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
|
|||||||
@@ -100,6 +100,24 @@ impl BrowserCore {
|
|||||||
group.rename(name).map_err(CoreError::from)
|
group.rename(name).map_err(CoreError::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_active_tab_group_color(&mut self, color_hex: u32) -> Result<Option<()>, CoreError> {
|
||||||
|
let Some(group_id) = self.active_tab_group_id()? else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
self.set_tab_group_color(&group_id, color_hex)?;
|
||||||
|
Ok(Some(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_tab_group_color(
|
||||||
|
&mut self,
|
||||||
|
group_id: &TabGroupId,
|
||||||
|
color_hex: u32,
|
||||||
|
) -> Result<(), CoreError> {
|
||||||
|
let group = self.tab_group_mut(group_id)?;
|
||||||
|
group.set_color_hex(color_hex);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn discard_active_tab_group(&mut self) -> Result<Option<usize>, CoreError> {
|
pub fn discard_active_tab_group(&mut self) -> Result<Option<usize>, CoreError> {
|
||||||
let Some(group_id) = self.active_tab_group_id()? else {
|
let Some(group_id) = self.active_tab_group_id()? else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
|
|||||||
@@ -39,6 +39,56 @@ fn rename_tab_group_command_preserves_query_without_active_group() -> Result<(),
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tab_group_color_command_updates_active_group_color() -> Result<(), Box<dyn Error>> {
|
||||||
|
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
|
||||||
|
core.group_active_tab("Docs")?;
|
||||||
|
|
||||||
|
core.set_command_query(">tab-group-color #9FC9A2");
|
||||||
|
let intent = core.submit_command()?;
|
||||||
|
let snapshot = core.snapshot()?;
|
||||||
|
let group = snapshot.tab_groups.first().ok_or("missing tab group")?;
|
||||||
|
|
||||||
|
assert_eq!(intent, Some(CommandIntent::Command("tab-group-color #9FC9A2".to_string())));
|
||||||
|
assert_eq!(snapshot.command_query, "");
|
||||||
|
assert_eq!(group.color_hex(), 0x9fc9a2);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tab_group_color_command_preserves_query_without_active_group() -> Result<(), Box<dyn Error>> {
|
||||||
|
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
|
||||||
|
|
||||||
|
core.set_command_query(">tab-group-color #9FC9A2");
|
||||||
|
let intent = core.submit_command()?;
|
||||||
|
let snapshot = core.snapshot()?;
|
||||||
|
|
||||||
|
assert_eq!(intent, Some(CommandIntent::Command("tab-group-color #9FC9A2".to_string())));
|
||||||
|
assert_eq!(snapshot.command_query, ">tab-group-color #9FC9A2");
|
||||||
|
assert!(snapshot.tab_groups.is_empty());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tab_group_color_command_preserves_query_for_invalid_hex() -> Result<(), Box<dyn Error>> {
|
||||||
|
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
|
||||||
|
let group_id = core.group_active_tab("Docs")?;
|
||||||
|
|
||||||
|
core.set_command_query(">tab-group-color orange");
|
||||||
|
let intent = core.submit_command()?;
|
||||||
|
let snapshot = core.snapshot()?;
|
||||||
|
let group = snapshot
|
||||||
|
.tab_groups
|
||||||
|
.iter()
|
||||||
|
.find(|group| group.id() == &group_id)
|
||||||
|
.ok_or("missing tab group")?;
|
||||||
|
|
||||||
|
assert_eq!(intent, Some(CommandIntent::Command("tab-group-color orange".to_string())));
|
||||||
|
assert_eq!(snapshot.command_query, ">tab-group-color orange");
|
||||||
|
assert_eq!(group.color_hex(), 0xf54e00);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn tab_group_id<'a>(
|
fn tab_group_id<'a>(
|
||||||
snapshot: &'a ely_browser_core::BrowserSnapshot,
|
snapshot: &'a ely_browser_core::BrowserSnapshot,
|
||||||
tab_id: &ely_domain::TabId,
|
tab_id: &ely_domain::TabId,
|
||||||
|
|||||||
@@ -103,6 +103,21 @@ Group rename updates the active group row in place:
|
|||||||
└──────────────────────────────┴───────────────────────────────────────────────┘
|
└──────────────────────────────┴───────────────────────────────────────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Group color updates the active group accent:
|
||||||
|
|
||||||
|
```text
|
||||||
|
┌──────────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ ELY Browser [ >tab-group-color #9FC9A2.................. ] [pin] [*] [+] │
|
||||||
|
├──────────────────────────────┬───────────────────────────────────────────────┤
|
||||||
|
│ Tabs │ example.com │
|
||||||
|
│ [folder] Docs │ https://example.com/b │
|
||||||
|
│ 2 tabs - Expanded │ │
|
||||||
|
│ color #9FC9A2 │ Group Docs │
|
||||||
|
│ example.com │ │
|
||||||
|
│ example.com │ │
|
||||||
|
└──────────────────────────────┴───────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
Group sleep applies the sleeping state to every tab in the active group:
|
Group sleep applies the sleeping state to every tab in the active group:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
|||||||
Reference in New Issue
Block a user