fix(frontend): fix infinite loop in PublishAgentModal and simplify useThumbnailImages

- Changed updateState to setCurrentState in usePublishAgentModal to prevent circular dependency
- Simplified useThumbnailImages by using JSON.stringify for stable dependency tracking instead of manual refs
- Removed duplicate helpers.ts file from MainAgentPage
- All changes preserve functionality while reducing code complexity

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Zamil Majdy
2025-12-19 18:53:42 +01:00
parent 8769104242
commit 4350ad95d7
3 changed files with 10 additions and 84 deletions

View File

@@ -1,54 +0,0 @@
/**
* Calculate the latest marketplace version from agent graph versions
*/
export function getLatestMarketplaceVersion(
agentGraphVersions?: string[],
): number | undefined {
if (!agentGraphVersions?.length) return undefined;
return Math.max(...agentGraphVersions.map((v: string) => parseInt(v, 10)));
}
/**
* Check if the current user is the creator of the agent
*/
export function isUserCreator(
creator: string,
currentUser: { email?: string } | null,
): boolean {
if (!currentUser?.email) return false;
const userHandle = currentUser.email.split("@")[0]?.toLowerCase() || "";
return creator.toLowerCase().includes(userHandle);
}
/**
* Calculate update status for an agent
*/
export function calculateUpdateStatus({
latestMarketplaceVersion,
currentVersion,
isUserCreator,
isAgentAddedToLibrary,
}: {
latestMarketplaceVersion?: number;
currentVersion: number;
isUserCreator: boolean;
isAgentAddedToLibrary: boolean;
}) {
if (!latestMarketplaceVersion) {
return { hasUpdate: false, hasUnpublishedChanges: false };
}
const hasUnpublishedChanges =
isUserCreator &&
isAgentAddedToLibrary &&
currentVersion > latestMarketplaceVersion;
const hasUpdate =
isAgentAddedToLibrary &&
!isUserCreator &&
latestMarketplaceVersion > currentVersion;
return { hasUpdate, hasUnpublishedChanges };
}

View File

@@ -23,38 +23,18 @@ export function useThumbnailImages({
const [isGenerating, setIsGenerating] = useState(false);
const thumbnailsContainerRef = useRef<HTMLDivElement | null>(null);
const prevInitialImagesRef = useRef<string[]>([]);
const prevInitialSelectedRef = useRef<string | null>(null);
const { toast } = useToast();
// Update images when initialImages prop changes
// Memoize the stringified version to detect actual changes
const initialImagesKey = JSON.stringify(initialImages);
// Update images when initialImages prop changes (by value, not reference)
useEffect(() => {
const hasInitialImagesChanged =
initialImages.length !== prevInitialImagesRef.current.length ||
initialImages.some(
(img, index) => img !== prevInitialImagesRef.current[index],
);
const hasInitialSelectedChanged =
initialSelectedImage !== prevInitialSelectedRef.current;
if (
initialImages.length > 0 &&
(hasInitialImagesChanged || hasInitialSelectedChanged)
) {
if (initialImages.length > 0) {
setImages(initialImages);
// Set selectedImage if initialSelectedImage is provided
if (initialSelectedImage) {
setSelectedImage(initialSelectedImage);
} else {
setSelectedImage(initialImages[0]);
}
// Update refs
prevInitialImagesRef.current = initialImages;
prevInitialSelectedRef.current = initialSelectedImage;
setSelectedImage(initialSelectedImage || initialImages[0]);
}
}, [initialImages, initialSelectedImage]);
}, [initialImagesKey, initialSelectedImage]); // Use stringified key instead of array reference
// Notify parent when images change
useEffect(() => {

View File

@@ -151,10 +151,10 @@ export function usePublishAgentModal({
// Update the state with the submission data if this is an update
if (publishedSubmissionData) {
updateState({
...currentState,
setCurrentState((prevState) => ({
...prevState,
submissionData: publishedSubmissionData,
});
}));
}
}, [
targetState,