feat(sidebar): default new folders to neutral foreground color
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
use sea_orm_migration::prelude::*;
|
use sea_orm_migration::prelude::*;
|
||||||
use sea_orm_migration::sea_orm::{ConnectionTrait, DbBackend, Statement};
|
|
||||||
|
|
||||||
#[derive(DeriveMigrationName)]
|
#[derive(DeriveMigrationName)]
|
||||||
pub struct Migration;
|
pub struct Migration;
|
||||||
@@ -15,29 +14,12 @@ impl MigrationTrait for Migration {
|
|||||||
ColumnDef::new(Folder::Color)
|
ColumnDef::new(Folder::Color)
|
||||||
.string()
|
.string()
|
||||||
.not_null()
|
.not_null()
|
||||||
.default("#22c55e"),
|
.default("foreground"),
|
||||||
)
|
)
|
||||||
.to_owned(),
|
.to_owned(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Backfill existing rows with a palette color chosen by (id - 1) mod N,
|
|
||||||
// so existing workspaces get visually distinct swatches after migration.
|
|
||||||
let conn = manager.get_connection();
|
|
||||||
let sql = "UPDATE folder SET color = CASE ((id - 1) % 9) \
|
|
||||||
WHEN 0 THEN '#ef4444' \
|
|
||||||
WHEN 1 THEN '#f97316' \
|
|
||||||
WHEN 2 THEN '#eab308' \
|
|
||||||
WHEN 3 THEN '#84cc16' \
|
|
||||||
WHEN 4 THEN '#22c55e' \
|
|
||||||
WHEN 5 THEN '#06b6d4' \
|
|
||||||
WHEN 6 THEN '#8b5cf6' \
|
|
||||||
WHEN 7 THEN '#d946ef' \
|
|
||||||
WHEN 8 THEN '#ec4899' \
|
|
||||||
END";
|
|
||||||
conn.execute(Statement::from_string(DbBackend::Sqlite, sql.to_string()))
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,34 +10,10 @@ use crate::db::error::DbError;
|
|||||||
use crate::models::agent::AgentType;
|
use crate::models::agent::AgentType;
|
||||||
use crate::models::{FolderDetail, FolderHistoryEntry};
|
use crate::models::{FolderDetail, FolderHistoryEntry};
|
||||||
|
|
||||||
/// Palette kept in sync with the frontend swatch picker. Changes here must be
|
/// Sentinel stored in the DB that the frontend resolves to
|
||||||
/// mirrored in `src/components/conversations/sidebar-conversation-list.tsx`.
|
/// `var(--sidebar-foreground)` — the theme-aware text color. New folders
|
||||||
/// `"foreground"` is a theme-aware sentinel the frontend resolves to
|
/// start with this neutral swatch until the user picks a palette color.
|
||||||
/// `var(--sidebar-foreground)`.
|
pub const DEFAULT_FOLDER_COLOR: &str = "foreground";
|
||||||
pub const FOLDER_COLOR_PALETTE: &[&str] = &[
|
|
||||||
"#ef4444",
|
|
||||||
"#f97316",
|
|
||||||
"#eab308",
|
|
||||||
"#84cc16",
|
|
||||||
"#22c55e",
|
|
||||||
"#06b6d4",
|
|
||||||
"#8b5cf6",
|
|
||||||
"#d946ef",
|
|
||||||
"#ec4899",
|
|
||||||
"foreground",
|
|
||||||
];
|
|
||||||
|
|
||||||
fn pick_folder_color(folder_id: i32, folder_name: &str) -> String {
|
|
||||||
let mut name_hash: u32 = 0;
|
|
||||||
for c in folder_name.chars() {
|
|
||||||
name_hash = name_hash.wrapping_mul(31).wrapping_add(c as u32);
|
|
||||||
}
|
|
||||||
let combined = (folder_id as u32)
|
|
||||||
.wrapping_mul(2654435761)
|
|
||||||
.wrapping_add(name_hash);
|
|
||||||
let idx = (combined as usize) % FOLDER_COLOR_PALETTE.len();
|
|
||||||
FOLDER_COLOR_PALETTE[idx].to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_entry(m: folder::Model) -> FolderHistoryEntry {
|
fn to_entry(m: folder::Model) -> FolderHistoryEntry {
|
||||||
FolderHistoryEntry {
|
FolderHistoryEntry {
|
||||||
@@ -121,16 +97,9 @@ pub async fn add_folder(
|
|||||||
deleted_at: Set(None),
|
deleted_at: Set(None),
|
||||||
is_open: Set(true),
|
is_open: Set(true),
|
||||||
sort_order: Set(max_order + 1),
|
sort_order: Set(max_order + 1),
|
||||||
// Temporary placeholder — we overwrite below with a hash derived
|
color: Set(DEFAULT_FOLDER_COLOR.to_string()),
|
||||||
// from the final auto-assigned id so each new folder gets a
|
|
||||||
// deterministic, well-distributed palette color.
|
|
||||||
color: Set(FOLDER_COLOR_PALETTE[0].to_string()),
|
|
||||||
};
|
};
|
||||||
let inserted = active.insert(conn).await?;
|
active.insert(conn).await?
|
||||||
let assigned = pick_folder_color(inserted.id, &name);
|
|
||||||
let mut active = inserted.into_active_model();
|
|
||||||
active.color = Set(assigned);
|
|
||||||
active.update(conn).await?
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(to_entry(model))
|
Ok(to_entry(model))
|
||||||
|
|||||||
Reference in New Issue
Block a user