feat(spaces): make the Space accent real end to end

This commit is contained in:
2026-07-10 11:45:08 -04:00
parent e95177b3e6
commit dd0f84600d
7 changed files with 103 additions and 10 deletions
@@ -97,6 +97,7 @@ fn render_picker_pill(
) -> AnyElement {
let space_name = active_space.map(|space| space.name().to_string()).unwrap_or_default();
let space_glyph = active_space.map(|space| space.icon().to_string()).unwrap_or_default();
let space_accent = active_space.map(ely_domain::Space::accent_hex);
let chevron = if picker_open { IconName::ChevronUp } else { IconName::ChevronDown };
let bg = if picker_open { picker_bg_hover() } else { picker_bg() };
@@ -118,7 +119,7 @@ fn render_picker_pill(
.on_click(cx.listener(|shell, _, _, cx| {
shell.toggle_workspace_picker(cx);
}))
.child(render_workspace_glyph(space_glyph))
.child(render_workspace_glyph(space_glyph, space_accent))
.child(
div()
.flex_1()
@@ -260,7 +261,7 @@ fn render_disclosure_row(
.on_click(cx.listener(move |shell, _, window, cx| {
shell.select_space_from_picker(&space_id, window, cx);
}))
.child(render_workspace_glyph(space.icon().to_string()))
.child(render_workspace_glyph(space.icon().to_string(), Some(space.accent_hex())))
.child(
div()
.flex_1()
@@ -301,15 +302,17 @@ fn render_disclosure_footer(cx: &mut Context<ElyShell>) -> AnyElement {
.into_any_element()
}
fn render_workspace_glyph(emoji: String) -> AnyElement {
div()
.size(px(18.0))
.rounded(px(5.0))
.bg(linear_gradient(
fn render_workspace_glyph(emoji: String, accent_hex: Option<u32>) -> AnyElement {
let glyph = div().size(px(18.0)).rounded(px(5.0));
let glyph = match accent_hex {
Some(accent) => glyph.bg(rgb(accent)),
None => glyph.bg(linear_gradient(
135.0,
linear_color_stop(hsla(341.0 / 360.0, 0.78, 0.67, 1.0), 0.0),
linear_color_stop(hsla(15.0 / 360.0, 0.55, 0.53, 1.0), 1.0),
))
)),
};
glyph
.flex()
.items_center()
.justify_center()
@@ -123,6 +123,14 @@ pub(crate) fn tab_group_color_hex(command: &str) -> Option<u32> {
parse_color_hex(value)
}
pub(crate) fn space_accent_hex(command: &str) -> Option<u32> {
let value = command_argument(
command,
&["set-space-accent ", "set space accent ", "space-accent ", "space accent "],
)?;
parse_color_hex(value)
}
pub(crate) fn split_group_name(command: &str) -> Option<&str> {
command_argument(
command,
+11
View File
@@ -262,6 +262,17 @@ impl BrowserCore {
self.set_space_archive_policy(&active_space_id, archive_policy)
}
pub fn set_active_space_accent(&mut self, accent_hex: u32) -> Result<(), CoreError> {
let active_space_id = self.active_space_id.clone();
let space = self
.spaces
.iter_mut()
.find(|space| space.id() == &active_space_id)
.ok_or_else(|| CoreError::SpaceNotFound { id: active_space_id.clone() })?;
space.set_accent_hex(accent_hex);
Ok(())
}
pub fn set_space_archive_policy(
&mut self,
space_id: &SpaceId,
@@ -11,7 +11,7 @@ use crate::{
move_tab_space_name, new_private_profile_name, new_profile_name, new_space_name, note_body,
notes_url, plugin_detail_url, plugin_settings_url, plugins_url, reading_list_url,
reading_progress_percent, rename_tab_group_name, search_url, settings_page_url,
settings_url, shortcut_settings_url, site_compatibility_url, space_icon,
settings_url, shortcut_settings_url, site_compatibility_url, space_accent_hex, space_icon,
space_settings_url, split_group_name, switch_profile_name, sync_status_url,
tab_group_color_hex, tab_group_name, tab_note_body, task_manager_url,
},
@@ -111,7 +111,11 @@ impl BrowserCore {
fn submit_named_command(&mut self, command: &str) -> Result<bool, CoreError> {
let command = command.trim();
if let Some(name) = new_space_name(command) {
self.create_space(name.to_string(), space_icon(name), 0xf54e00)?;
self.create_space(name.to_string(), space_icon(name), self.next_space_accent())?;
return Ok(true);
}
if let Some(accent_hex) = space_accent_hex(command) {
self.set_active_space_accent(accent_hex)?;
return Ok(true);
}
if let Some(name) = new_profile_name(command) {
@@ -59,6 +59,15 @@ impl TrashedSpace {
}
impl BrowserCore {
/// Rotate new spaces through distinct accents so workspace identity
/// reads at a glance; `>space-accent` overrides per space.
#[must_use]
pub fn next_space_accent(&self) -> u32 {
const SPACE_ACCENT_PALETTE: &[u32] =
&[0xf54e00, 0x0f7b6c, 0x2f5fe0, 0x8a4bd8, 0xb26b00, 0xc23a63];
SPACE_ACCENT_PALETTE[self.spaces.len() % SPACE_ACCENT_PALETTE.len()]
}
pub fn create_space(
&mut self,
name: impl Into<String>,
@@ -0,0 +1,53 @@
use std::error::Error;
use ely_browser_core::{BrowserCore, InitialBrowserConfig};
use ely_domain::CommandIntent;
#[test]
fn space_accent_command_updates_the_active_space() -> Result<(), Box<dyn Error>> {
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
core.set_command_query(">space-accent #123ABC");
let intent = core.submit_command()?;
let snapshot = core.snapshot()?;
let active_space = snapshot
.spaces
.iter()
.find(|space| space.id() == &snapshot.active_space_id)
.ok_or("missing active space")?;
assert_eq!(intent, Some(CommandIntent::Command("space-accent #123ABC".to_string())));
assert_eq!(snapshot.command_query, "");
assert_eq!(active_space.accent_hex(), 0x123abc);
Ok(())
}
#[test]
fn space_accent_command_preserves_query_for_invalid_hex() -> Result<(), Box<dyn Error>> {
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
let original_accent = core.snapshot()?.spaces[0].accent_hex();
core.set_command_query(">space-accent #12");
core.submit_command()?;
let snapshot = core.snapshot()?;
assert_eq!(snapshot.command_query, ">space-accent #12");
assert_eq!(snapshot.spaces[0].accent_hex(), original_accent);
Ok(())
}
#[test]
fn new_spaces_rotate_through_the_accent_palette() -> Result<(), Box<dyn Error>> {
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
core.set_command_query(">new-space Research");
core.submit_command()?;
core.set_command_query(">new-space Notes");
core.submit_command()?;
let snapshot = core.snapshot()?;
let accents: Vec<u32> = snapshot.spaces.iter().map(ely_domain::Space::accent_hex).collect();
assert_eq!(accents.len(), 3);
assert_ne!(accents[1], accents[2], "consecutive spaces must not share one accent");
Ok(())
}
+5
View File
@@ -80,6 +80,11 @@ impl Space {
self.record_update();
}
pub fn set_accent_hex(&mut self, accent_hex: u32) {
self.accent_hex = accent_hex;
self.record_update();
}
pub fn set_presentation(
&mut self,
name: impl Into<String>,