Skip to content

Commit 942c2b1

Browse files
committed
fix(webapp): address light theme review feedback
- re-resolve theme colors when data-theme changes - narrow jsonb_set write for theme preference - opaque amber for reasoning text in light mode
1 parent 140073d commit 942c2b1

4 files changed

Lines changed: 28 additions & 15 deletions

File tree

apps/webapp/app/components/runs/v3/agent/AgentMessageView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ export function renderPart(part: UIMessage["parts"][number], i: number) {
136136
return (
137137
<div key={i} className="border-l-2 border-amber-500/40 pl-2">
138138
<ChatBubble>
139-
<div className="whitespace-pre-wrap text-xs italic text-amber-600/70 dark:text-amber-200/70">
139+
<div className="whitespace-pre-wrap text-xs italic text-amber-700 dark:text-amber-200/70">
140140
{p.text ?? ""}
141141
</div>
142142
</ChatBubble>

apps/webapp/app/components/runs/v3/ai/AIChatMessages.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ function SubAgentContent({ parts }: { parts: any[] }) {
483483
if (partType === "reasoning" && part.text) {
484484
return (
485485
<div key={j} className="border-l-2 border-amber-500/40 pl-2">
486-
<div className="whitespace-pre-wrap text-xs italic text-amber-600/70 dark:text-amber-200/70">
486+
<div className="whitespace-pre-wrap text-xs italic text-amber-700 dark:text-amber-200/70">
487487
{part.text}
488488
</div>
489489
</div>

apps/webapp/app/hooks/useThemeColor.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,28 @@ function toRgb(color: string): string {
1717
}
1818

1919
/**
20-
* Resolve a theme CSS variable to a concrete, animatable color on mount.
20+
* Resolve a theme CSS variable to a concrete, animatable color.
2121
* framer-motion can't interpolate `var()` strings or oklch values, so animated
2222
* colors must be resolved and normalized first. Resolution happens in an
2323
* effect so server and hydration renders both use the fallback — resolving
24-
* during render caused hydration style mismatches.
24+
* during render caused hydration style mismatches. Long-lived components
25+
* (e.g. the side menu) outlive theme switches, so re-resolve whenever
26+
* `data-theme` flips on <html>.
2527
*/
2628
export function useThemeColor(variable: `--${string}`, fallback: string): string {
2729
const [color, setColor] = useState(fallback);
2830
useEffect(() => {
29-
const value = getComputedStyle(document.documentElement).getPropertyValue(variable).trim();
30-
if (value) setColor(toRgb(value));
31+
const resolve = () => {
32+
const value = getComputedStyle(document.documentElement).getPropertyValue(variable).trim();
33+
if (value) setColor(toRgb(value));
34+
};
35+
resolve();
36+
const observer = new MutationObserver(resolve);
37+
observer.observe(document.documentElement, {
38+
attributes: true,
39+
attributeFilter: ["data-theme"],
40+
});
41+
return () => observer.disconnect();
3142
}, [variable]);
3243
return color;
3344
}

apps/webapp/app/services/dashboardPreferences.server.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,17 @@ export async function updateThemePreference({
117117
return;
118118
}
119119

120-
const updatedPreferences: DashboardPreferences = {
121-
...user.dashboardPreferences,
122-
theme,
123-
};
124-
125-
return prisma.user.update({
126-
where: { id: user.id },
127-
data: { dashboardPreferences: updatedPreferences },
128-
});
120+
// Narrow jsonb_set write: a full-blob update from the session snapshot can
121+
// race with other preference writes and drop unrelated fields.
122+
return prisma.$executeRaw`
123+
UPDATE "User"
124+
SET "dashboardPreferences" = jsonb_set(
125+
COALESCE("dashboardPreferences", '{}'::jsonb),
126+
'{theme}',
127+
to_jsonb(${theme}::text)
128+
)
129+
WHERE id = ${user.id}
130+
`;
129131
}
130132

131133
export async function clearCurrentProject({ user }: { user: UserFromSession }) {

0 commit comments

Comments
 (0)