feat: add icon and color support to project persistence (#439)

This commit is contained in:
Bohdan Triapitsyn
2026-02-17 19:14:04 +02:00
committed by GitHub
parent 4d71bb27eb
commit 4915e5f1fb
4 changed files with 21 additions and 4 deletions
@@ -44,6 +44,7 @@ import {
RiGitBranchLine, RiGitBranchLine,
RiGitPullRequestLine, RiGitPullRequestLine,
RiGitRepositoryLine, RiGitRepositoryLine,
RiNodeTree,
RiStickyNoteLine, RiStickyNoteLine,
RiLinkUnlinkM, RiLinkUnlinkM,
@@ -1758,7 +1759,7 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
}, [activeProjectForHeader, projectRenameDraft, renameProject]); }, [activeProjectForHeader, projectRenameDraft, renameProject]);
const headerActionButtonClass = const headerActionButtonClass =
'inline-flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground hover:text-foreground hover:bg-interactive-hover/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50'; 'inline-flex h-6 w-6 items-center justify-center rounded-md leading-none text-muted-foreground hover:text-foreground hover:bg-interactive-hover/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50';
// Track when project sticky headers become "stuck" // Track when project sticky headers become "stuck"
React.useEffect(() => { React.useEffect(() => {
@@ -2535,9 +2536,9 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
</div> </div>
)} )}
{reserveHeaderActionsSpace ? ( {reserveHeaderActionsSpace ? (
<div className="mt-1 -ml-1 flex h-8 items-center"> <div className="-ml-1 flex h-8 items-center">
{activeProjectForHeader ? ( {activeProjectForHeader ? (
<div className="flex h-full items-center gap-1.5 rounded-md pl-0 pr-1"> <div className="flex h-8 -translate-y-px items-center gap-1.5 rounded-md pl-0 pr-1">
{stableActiveProjectIsRepo ? ( {stableActiveProjectIsRepo ? (
<> <>
<Tooltip> <Tooltip>
@@ -2564,7 +2565,7 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
className={headerActionButtonClass} className={headerActionButtonClass}
aria-label="New worktree" aria-label="New worktree"
> >
<RiGitBranchLine className="h-4.5 w-4.5" /> <RiNodeTree className="h-4.5 w-4.5" />
</button> </button>
</TooltipTrigger> </TooltipTrigger>
<TooltipContent side="bottom" sideOffset={4}><p>New worktree</p></TooltipContent> <TooltipContent side="bottom" sideOffset={4}><p>New worktree</p></TooltipContent>
+6
View File
@@ -147,6 +147,12 @@ const sanitizeProjects = (value: unknown): DesktopSettings['projects'] | undefin
if (typeof candidate.label === 'string' && candidate.label.trim().length > 0) { if (typeof candidate.label === 'string' && candidate.label.trim().length > 0) {
project.label = candidate.label.trim(); project.label = candidate.label.trim();
} }
if (typeof candidate.icon === 'string' && candidate.icon.trim().length > 0) {
project.icon = candidate.icon.trim();
}
if (typeof candidate.color === 'string' && candidate.color.trim().length > 0) {
project.color = candidate.color.trim();
}
if (typeof candidate.addedAt === 'number' && Number.isFinite(candidate.addedAt) && candidate.addedAt >= 0) { if (typeof candidate.addedAt === 'number' && Number.isFinite(candidate.addedAt) && candidate.addedAt >= 0) {
project.addedAt = candidate.addedAt; project.addedAt = candidate.addedAt;
} }
@@ -116,6 +116,12 @@ const sanitizeProjects = (value: unknown): ProjectEntry[] => {
if (typeof candidate.label === 'string' && candidate.label.trim().length > 0) { if (typeof candidate.label === 'string' && candidate.label.trim().length > 0) {
project.label = candidate.label.trim(); project.label = candidate.label.trim();
} }
if (typeof candidate.icon === 'string' && candidate.icon.trim().length > 0) {
project.icon = candidate.icon.trim();
}
if (typeof candidate.color === 'string' && candidate.color.trim().length > 0) {
project.color = candidate.color.trim();
}
if (typeof candidate.addedAt === 'number' && Number.isFinite(candidate.addedAt) && candidate.addedAt >= 0) { if (typeof candidate.addedAt === 'number' && Number.isFinite(candidate.addedAt) && candidate.addedAt >= 0) {
project.addedAt = candidate.addedAt; project.addedAt = candidate.addedAt;
} }
+4
View File
@@ -1325,6 +1325,8 @@ const sanitizeProjects = (input) => {
const rawPath = typeof candidate.path === 'string' ? candidate.path.trim() : ''; const rawPath = typeof candidate.path === 'string' ? candidate.path.trim() : '';
const normalizedPath = rawPath ? path.resolve(normalizeDirectoryPath(rawPath)) : ''; const normalizedPath = rawPath ? path.resolve(normalizeDirectoryPath(rawPath)) : '';
const label = typeof candidate.label === 'string' ? candidate.label.trim() : ''; const label = typeof candidate.label === 'string' ? candidate.label.trim() : '';
const icon = typeof candidate.icon === 'string' ? candidate.icon.trim() : '';
const color = typeof candidate.color === 'string' ? candidate.color.trim() : '';
const addedAt = Number.isFinite(candidate.addedAt) ? Number(candidate.addedAt) : null; const addedAt = Number.isFinite(candidate.addedAt) ? Number(candidate.addedAt) : null;
const lastOpenedAt = Number.isFinite(candidate.lastOpenedAt) const lastOpenedAt = Number.isFinite(candidate.lastOpenedAt)
? Number(candidate.lastOpenedAt) ? Number(candidate.lastOpenedAt)
@@ -1341,6 +1343,8 @@ const sanitizeProjects = (input) => {
id, id,
path: normalizedPath, path: normalizedPath,
...(label ? { label } : {}), ...(label ? { label } : {}),
...(icon ? { icon } : {}),
...(color ? { color } : {}),
...(Number.isFinite(addedAt) && addedAt >= 0 ? { addedAt } : {}), ...(Number.isFinite(addedAt) && addedAt >= 0 ? { addedAt } : {}),
...(Number.isFinite(lastOpenedAt) && lastOpenedAt >= 0 ? { lastOpenedAt } : {}), ...(Number.isFinite(lastOpenedAt) && lastOpenedAt >= 0 ? { lastOpenedAt } : {}),
}; };