Apply the saved review-card fill before paint so reload does not flash the teal placeholder.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
b12de611f7
commit
782b1e1d64
2 files changed
+23
-15
No files matched your search
@@ -1,19 +1,21 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { dominantColorFromImageUrl } from "../../../../lib/create/previewSurfaceColor";
|
||||
import { useEffect, useLayoutEffect, useState } from "react";
|
||||
import {
|
||||
dominantColorFromImageUrl,
|
||||
isPreviewSurfaceColor,
|
||||
} from "../../../../lib/create/previewSurfaceColor";
|
||||
import { resolvePreviewSurfaceFallback } from "../utils/resolvePreviewSurfaceFallback";
|
||||
|
||||
/**
|
||||
* Fill for the review preview card. An uploaded logo contributes its most
|
||||
* common color; no image uses a random light color stored on the draft so
|
||||
* reload keeps the same fill. Unset until mount so the server and client
|
||||
* share the fallback class.
|
||||
* reload keeps the same fill.
|
||||
*
|
||||
* @param imageUrl Uploaded logo URL, or `null` when the user skipped the photo.
|
||||
* @param storedFallback Draft `previewSurfaceColor`, if already picked.
|
||||
* @param persistFallback Writes the fallback onto React state once.
|
||||
* @returns A CSS color, or `undefined` before the client picks one.
|
||||
* @returns A CSS color, or `undefined` before the client resolves one.
|
||||
*
|
||||
* @example
|
||||
* const color = usePreviewSurfaceColor(avatarUrl, state.previewSurfaceColor, persist);
|
||||
@@ -23,16 +25,22 @@ export function usePreviewSurfaceColor(
|
||||
storedFallback: string | undefined,
|
||||
persistFallback: (_color: string) => void,
|
||||
): string | undefined {
|
||||
const [color, setColor] = useState<string | undefined>(undefined);
|
||||
const [color, setColor] = useState<string | undefined>(() =>
|
||||
storedFallback && isPreviewSurfaceColor(storedFallback)
|
||||
? storedFallback
|
||||
: undefined,
|
||||
);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (imageUrl) return;
|
||||
const next = resolvePreviewSurfaceFallback(storedFallback);
|
||||
persistFallback(next);
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect -- apply before paint so reload does not flash the teal token
|
||||
setColor((prev) => (prev === next ? prev : next));
|
||||
}, [imageUrl, persistFallback, storedFallback]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!imageUrl) {
|
||||
const next = resolvePreviewSurfaceFallback(storedFallback);
|
||||
persistFallback(next);
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect -- random fill is client-only; first paint stays on the fallback class
|
||||
setColor(next);
|
||||
return;
|
||||
}
|
||||
if (!imageUrl) return;
|
||||
|
||||
let cancelled = false;
|
||||
void dominantColorFromImageUrl(imageUrl).then((extracted) => {
|
||||
|
||||
Reference in new issue
Block a user