Conversation
…e HTML gateway fallback behavior, and drive next-mint visibility from drop completion Signed-off-by: prxt6529 <prxt@6529.io>
📝 WalkthroughWalkthroughAdds MIME-type inference utilities, integrates a MediaTypeBadge across NFT UIs, gates iframe fallback timeouts by gateway type (Arweave vs IPFS), updates now-minting status usage, normalizes nft-image imports, and expands tests for gateway fallback and MIME behavior. Changes
Sequence Diagram(s)sequenceDiagram
participant UI as MediaDisplay / NFTHTMLRenderer
participant Gateway as gateway-fallback util
participant Iframe as SandboxedIframe
participant Timer as setTimeout
UI->>Gateway: getArweaveGatewayFallbackUrls(activeUrl) / shouldUseIframeFallbackTimeout(activeUrl)
Gateway-->>UI: fallback URLs + boolean decision
alt shouldUseIframeFallbackTimeout == true
UI->>Timer: schedule IFRAME_FALLBACK_TIMEOUT_MS
Timer-->>UI: timeout fires
UI->>Iframe: update data-src to next fallback URL
else shouldUseIframeFallbackTimeout == false
UI-->>Iframe: leave iframe data-src unchanged (no timeout scheduled)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Signed-off-by: prxt6529 <prxt@6529.io>
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (4)
components/nft-image/utils/gateway-fallback.ts (1)
121-132: Consider centralizing URL classification to avoid drift.This helper duplicates the same IPFS-vs-Arweave branching used in
getArweaveGatewayFallbackUrls. A shared classifier would reduce future divergence risk between timeout gating and fallback URL generation.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/nft-image/utils/gateway-fallback.ts` around lines 121 - 132, Centralize the URL classification logic into a single shared helper (e.g., classifyAssetUrl or isArweaveAsset) and replace the branching in both shouldUseIframeFallbackTimeout and getArweaveGatewayFallbackUrls to call that helper; the new helper should encapsulate the current checks that use isIpfsProtocolUrl, getIpfsProtocolUrlFromGatewayUrl, and isArweaveUrl so both functions use the same decision logic and avoid future drift.__tests__/components/nft-image/utils/gateway-fallback.test.ts (1)
51-64: Consider adding edge case tests forshouldUseIframeFallbackTimeout.The current tests cover the happy paths well. Consider adding tests for edge cases like empty strings and
ipfs://protocol URLs to ensure full coverage of the guard conditions inshouldUseIframeFallbackTimeout.📝 Suggested additional test cases
it("does not use timeout fallback for ipfs gateways", () => { expect( shouldUseIframeFallbackTimeout("https://ipfs.6529.io/ipfs/bafy-test") ).toBe(false); expect( shouldUseIframeFallbackTimeout("https://ipfs.io/ipfs/bafy-test") ).toBe(false); }); + + it("does not use timeout fallback for empty or whitespace-only strings", () => { + expect(shouldUseIframeFallbackTimeout("")).toBe(false); + expect(shouldUseIframeFallbackTimeout(" ")).toBe(false); + }); + + it("does not use timeout fallback for ipfs protocol urls", () => { + expect(shouldUseIframeFallbackTimeout("ipfs://bafy-test")).toBe(false); + }); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@__tests__/components/nft-image/utils/gateway-fallback.test.ts` around lines 51 - 64, Add edge-case unit tests for shouldUseIframeFallbackTimeout: include a test asserting that an empty string returns false and a test asserting that an ipfs:// protocol URL (e.g., "ipfs://bafy-test" or similar) returns false; place them alongside the existing cases so the guard conditions in shouldUseIframeFallbackTimeout are fully covered.__tests__/helpers/mint-visibility.helpers.test.ts (1)
7-37: AddnextMintExists: falsecases to complete branch coverage.Current tests only cover
nextMintExists: true. Adding thefalsebranch for both helpers will lock down the guard-path behavior too.✅ Suggested test additions
describe("mint visibility helpers", () => { it("shows latest drop next mint only when the overall mint is complete", () => { @@ expect( shouldShowNextMintInLatestDrop({ isMintEnded: true, nextMintExists: true, }) ).toBe(true); + + expect( + shouldShowNextMintInLatestDrop({ + isMintEnded: true, + nextMintExists: false, + }) + ).toBe(false); }); it("keeps coming-up next mint visible while the overall mint is not complete", () => { @@ expect( shouldShowNextWinnerInComingUp({ isMintEnded: true, nextMintExists: true, }) ).toBe(false); + + expect( + shouldShowNextWinnerInComingUp({ + isMintEnded: false, + nextMintExists: false, + }) + ).toBe(false); }); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@__tests__/helpers/mint-visibility.helpers.test.ts` around lines 7 - 37, Add tests for the missing branch where nextMintExists is false for both helpers: call shouldShowNextMintInLatestDrop and shouldShowNextWinnerInComingUp with isMintEnded true/false and nextMintExists: false and assert the expected boolean outcomes (both should be false when nextMintExists is false regardless of isMintEnded for each helper's guard path). Update the existing test block to include these two cases so both true and false branches for nextMintExists are covered for shouldShowNextMintInLatestDrop and shouldShowNextWinnerInComingUp.components/the-memes/MemePageLive.tsx (1)
224-243: Consider simplifying the nullish coalescing on line 232.The
fileMimeType ?? undefinedis redundant since the enclosing ternaryfileMimeType ? ... : nullalready guaranteesfileMimeTypeis truthy whenMediaTypeBadgerenders. You can passmimeType={fileMimeType}directly.♻️ Optional simplification
<MediaTypeBadge - mimeType={fileMimeType ?? undefined} + mimeType={fileMimeType} size="sm"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/the-memes/MemePageLive.tsx` around lines 224 - 243, The MediaTypeBadge's mimeType prop is being passed redundantly as fileMimeType ?? undefined inside the afterMetadata conditional; since the ternary only renders when fileMimeType is truthy, change the prop to mimeType={fileMimeType} directly. Update the JSX inside NftPageStats -> afterMetadata (the MediaTypeBadge instantiation) to remove the nullish coalescing and pass fileMimeType as-is, leaving other props (size, showTooltip, showLabel, tone, labelClassName) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@components/home/now-minting/LatestDropNextMintSection.tsx`:
- Around line 33-45: The fallback inline element inside the JSX "content" pill
uses a <div> which breaks inline semantics; replace the fallback <div> with an
inline <span aria-hidden="true"> element (keeping the same class names and
sizing) so the pfp conditional (pfp ? <Image ... resolveIpfsUrl(pfp) ... label
/> : <fallback/>) preserves inline layout and avoids DOM reshaping/warnings in
LatestDropNextMintSection.tsx.
In `@components/memelab/MemeLabPage.tsx`:
- Around line 1204-1218: The current guard `fileType && fileMimeType` hides the
entire File Type row when MIME lookup fails even though
`get*FileTypeFromMetadata()` may have returned a usable raw `fileType`; change
the rendering to keep the <tr> whenever `fileType` exists and inside it render
the <MediaTypeBadge> only when `fileMimeType` is present, otherwise render the
textual `fileType` fallback (use the same cell styling as the badge cell).
Update the JSX around `fileType`, `fileMimeType`, and `MediaTypeBadge` so the
row always renders when `fileType` is truthy and falls back to plain text when
`fileMimeType` is null.
In `@helpers/nft.helpers.ts`:
- Around line 187-199: The fallback logic in the MIME detection prefers imageSrc
over animationSrc when getMimeTypeFromFormat(getUrlExtension(imageSrc)) returns
falsy, causing animated NFTs to be misclassified; update the logic in the block
around getResolvedImageSrc, getMimeTypeFromFormat and getUrlExtension to check
animationSrc first (e.g., attempt to derive MIME from animationSrc or, if
animationSrc exists, return "video/mp4" before falling back to imageSrc) so that
animation takes precedence even when image extension is unmapped.
---
Nitpick comments:
In `@__tests__/components/nft-image/utils/gateway-fallback.test.ts`:
- Around line 51-64: Add edge-case unit tests for
shouldUseIframeFallbackTimeout: include a test asserting that an empty string
returns false and a test asserting that an ipfs:// protocol URL (e.g.,
"ipfs://bafy-test" or similar) returns false; place them alongside the existing
cases so the guard conditions in shouldUseIframeFallbackTimeout are fully
covered.
In `@__tests__/helpers/mint-visibility.helpers.test.ts`:
- Around line 7-37: Add tests for the missing branch where nextMintExists is
false for both helpers: call shouldShowNextMintInLatestDrop and
shouldShowNextWinnerInComingUp with isMintEnded true/false and nextMintExists:
false and assert the expected boolean outcomes (both should be false when
nextMintExists is false regardless of isMintEnded for each helper's guard path).
Update the existing test block to include these two cases so both true and false
branches for nextMintExists are covered for shouldShowNextMintInLatestDrop and
shouldShowNextWinnerInComingUp.
In `@components/nft-image/utils/gateway-fallback.ts`:
- Around line 121-132: Centralize the URL classification logic into a single
shared helper (e.g., classifyAssetUrl or isArweaveAsset) and replace the
branching in both shouldUseIframeFallbackTimeout and
getArweaveGatewayFallbackUrls to call that helper; the new helper should
encapsulate the current checks that use isIpfsProtocolUrl,
getIpfsProtocolUrlFromGatewayUrl, and isArweaveUrl so both functions use the
same decision logic and avoid future drift.
In `@components/the-memes/MemePageLive.tsx`:
- Around line 224-243: The MediaTypeBadge's mimeType prop is being passed
redundantly as fileMimeType ?? undefined inside the afterMetadata conditional;
since the ternary only renders when fileMimeType is truthy, change the prop to
mimeType={fileMimeType} directly. Update the JSX inside NftPageStats ->
afterMetadata (the MediaTypeBadge instantiation) to remove the nullish
coalescing and pass fileMimeType as-is, leaving other props (size, showTooltip,
showLabel, tone, labelClassName) unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3b2e49e9-42bc-4de4-a045-8e4ef2105709
📒 Files selected for processing (34)
__tests__/components/drops/view/item/content/media/MediaDisplay.test.tsx__tests__/components/memelab/MemeLabPage.test.tsx__tests__/components/nft-image/utils/gateway-fallback.test.ts__tests__/components/the-memes/MemePageArt.test.tsx__tests__/components/the-memes/MemePageLive.test.tsx__tests__/helpers/mint-visibility.helpers.test.ts__tests__/helpers/nft.helpers.test.tscomponents/drops/media/MediaTypeBadge.tsxcomponents/drops/view/item/content/media/MediaDisplay.tsxcomponents/home/next-mint-leading/NextMintLeadingSection.tsxcomponents/home/now-minting/LatestDropNextMintSection.tsxcomponents/home/now-minting/LatestDropSection.tsxcomponents/home/now-minting/NowMintingDetails.tsxcomponents/home/now-minting/NowMintingHeader.tsxcomponents/memelab/MemeLab.tsxcomponents/memelab/MemeLabPage.tsxcomponents/nft-attributes/ArweaveLinksTable.tsxcomponents/nft-attributes/MetadataLink.tsxcomponents/nft-attributes/NftStats.tsxcomponents/nft-image/NFTImage.tsxcomponents/nft-image/NFTImageBalance.tsxcomponents/nft-image/NFTModel.tsxcomponents/nft-image/RememeImage.tsxcomponents/nft-image/renderers/NFTHTMLRenderer.tsxcomponents/nft-image/renderers/NFTImageRenderer.tsxcomponents/nft-image/renderers/NFTModelRenderer.tsxcomponents/nft-image/renderers/NFTVideoRenderer.tsxcomponents/nft-image/utils/gateway-fallback.tscomponents/nft-image/utils/media-type.tscomponents/the-memes/MemePageArt.tsxcomponents/the-memes/MemePageLive.tsxcomponents/the-memes/TheMemes.tsxhelpers/nft.helpers.tshooks/useNowMintingStatus.ts
Signed-off-by: prxt6529 <prxt@6529.io>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
components/home/now-minting/LatestDropNextMintSection.tsx (1)
44-47: Remove unusedtw-object-containfrom placeholder span.The
object-containCSS property only applies to replaced elements (images, videos, iframes). On a<span>, it has no effect and is vestigial from copying the<Image>styling.Suggested fix
<span aria-hidden="true" - className="tw-size-4 tw-flex-shrink-0 tw-rounded-sm tw-bg-iron-900 tw-object-contain" + className="tw-size-4 tw-flex-shrink-0 tw-rounded-sm tw-bg-iron-900" />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/home/now-minting/LatestDropNextMintSection.tsx` around lines 44 - 47, In LatestDropNextMintSection remove the unused utility "tw-object-contain" from the placeholder <span> (the span with aria-hidden="true" and classes "tw-size-4 tw-flex-shrink-0 tw-rounded-sm tw-bg-iron-900..."); edit the className to drop "tw-object-contain" so the span only keeps relevant utilities (e.g., tw-size-4 tw-flex-shrink-0 tw-rounded-sm tw-bg-iron-900) since object-contain only applies to replaced elements like <Image>.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@components/home/now-minting/LatestDropNextMintSection.tsx`:
- Around line 174-179: The MediaTypeBadge usage sets size="sm" (badge container
is tw-size-6 / 24px) but iconClassName="tw-size-[26px]" makes the icon 26px and
overflows; fix by making the icon match the container or the container match the
icon: either change iconClassName to tw-size-6 (or remove the explicit size so
it defaults to the badge's internal sizing) or bump the badge size prop (e.g.,
size="md") or pass a matching container class via className to accommodate
tw-size-[26px]; update the MediaTypeBadge invocation accordingly (the component
name and props: MediaTypeBadge, mimeType, dropId, size, iconClassName).
In `@components/the-memes/MemePageArt.tsx`:
- Around line 198-217: The File Type row is currently rendered only when
fileType is truthy but the badge uses fileTypeMimeType, causing the row to be
omitted when a MIME is present but fileType is not; update the conditional that
wraps the "file-type" row to check fileTypeMimeType instead of fileType and
ensure the MediaTypeBadge remains passed fileTypeMimeType (keep size="sm",
showTooltip/Label, tone and labelClassName as-is) so MemePageArt's output
matches MemePageLive's behavior.
---
Nitpick comments:
In `@components/home/now-minting/LatestDropNextMintSection.tsx`:
- Around line 44-47: In LatestDropNextMintSection remove the unused utility
"tw-object-contain" from the placeholder <span> (the span with
aria-hidden="true" and classes "tw-size-4 tw-flex-shrink-0 tw-rounded-sm
tw-bg-iron-900..."); edit the className to drop "tw-object-contain" so the span
only keeps relevant utilities (e.g., tw-size-4 tw-flex-shrink-0 tw-rounded-sm
tw-bg-iron-900) since object-contain only applies to replaced elements like
<Image>.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 047df656-caa8-44f2-97bc-e49740399314
📒 Files selected for processing (9)
__tests__/components/nft-image/utils/gateway-fallback.test.ts__tests__/helpers/mint-visibility.helpers.test.ts__tests__/helpers/nft.helpers.test.tscomponents/home/now-minting/LatestDropNextMintSection.tsxcomponents/memelab/MemeLabPage.tsxcomponents/nft-image/utils/gateway-fallback.tscomponents/the-memes/MemePageArt.tsxcomponents/the-memes/MemePageLive.tsxhelpers/nft.helpers.ts
✅ Files skipped from review due to trivial changes (3)
- tests/helpers/mint-visibility.helpers.test.ts
- tests/components/nft-image/utils/gateway-fallback.test.ts
- tests/helpers/nft.helpers.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- helpers/nft.helpers.ts
- components/nft-image/utils/gateway-fallback.ts
- components/memelab/MemeLabPage.tsx
|
There was a problem hiding this comment.
🧹 Nitpick comments (2)
components/the-memes/MemePageLive.tsx (1)
82-191: Optional: reduce repeatedtw-font-mediumliterals.You now repeat the same class string across many
<td>cells; consider a shared utility class/constant for easier future edits and lower churn.Also applies to: 210-222
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/the-memes/MemePageLive.tsx` around lines 82 - 191, Many <td> cells repeat the "tw-font-medium" (and in some cases "text-right tw-font-medium") literal; define a single shared class constant or small helper (e.g., FONT_MEDIUM or TD_RIGHT_CLASS) inside MemePageLive.tsx and replace the repeated class strings used in the rows that render props.nftMeta (including the blocks showing burnt, museum, cleaned, percent_unique, etc.) with that constant to centralize styling and reduce churn when updating the class name.components/memelab/MemeLabPage.tsx (1)
1013-1017: Optional simplification: MIME fallback logic is currently redundant.
getAnimationMimeTypeFromMetadata/getImageMimeTypeFromMetadataalready resolve via format mapping, so the extragetMimeTypeFromFormat(...)fallback likely repeats the same work.♻️ Suggested simplification
- const fileMimeType = isShowingAnimation - ? (getAnimationMimeTypeFromMetadata(nft?.metadata) ?? - getMimeTypeFromFormat(animationFormat)) - : (getImageMimeTypeFromMetadata(nft?.metadata) ?? - getMimeTypeFromFormat(imageFormat)); + const fileMimeType = isShowingAnimation + ? getAnimationMimeTypeFromMetadata(nft?.metadata) + : getImageMimeTypeFromMetadata(nft?.metadata);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/memelab/MemeLabPage.tsx` around lines 1013 - 1017, The MIME-type fallback is redundant: remove the extra getMimeTypeFromFormat(...) calls and rely solely on getAnimationMimeTypeFromMetadata and getImageMimeTypeFromMetadata which already map to formats; update the fileMimeType assignment in MemeLabPage.tsx so it sets fileMimeType = isShowingAnimation ? getAnimationMimeTypeFromMetadata(nft?.metadata) : getImageMimeTypeFromMetadata(nft?.metadata), keeping the existing isShowingAnimation, nft, animationFormat and imageFormat context intact and ensuring any null coalescing behavior remains consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@components/memelab/MemeLabPage.tsx`:
- Around line 1013-1017: The MIME-type fallback is redundant: remove the extra
getMimeTypeFromFormat(...) calls and rely solely on
getAnimationMimeTypeFromMetadata and getImageMimeTypeFromMetadata which already
map to formats; update the fileMimeType assignment in MemeLabPage.tsx so it sets
fileMimeType = isShowingAnimation ?
getAnimationMimeTypeFromMetadata(nft?.metadata) :
getImageMimeTypeFromMetadata(nft?.metadata), keeping the existing
isShowingAnimation, nft, animationFormat and imageFormat context intact and
ensuring any null coalescing behavior remains consistent.
In `@components/the-memes/MemePageLive.tsx`:
- Around line 82-191: Many <td> cells repeat the "tw-font-medium" (and in some
cases "text-right tw-font-medium") literal; define a single shared class
constant or small helper (e.g., FONT_MEDIUM or TD_RIGHT_CLASS) inside
MemePageLive.tsx and replace the repeated class strings used in the rows that
render props.nftMeta (including the blocks showing burnt, museum, cleaned,
percent_unique, etc.) with that constant to centralize styling and reduce churn
when updating the class name.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d4eea4ac-28ae-4a44-b637-5702a66378f9
📒 Files selected for processing (3)
components/home/now-minting/LatestDropNextMintSection.tsxcomponents/memelab/MemeLabPage.tsxcomponents/the-memes/MemePageLive.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- components/home/now-minting/LatestDropNextMintSection.tsx



Summary by CodeRabbit
New Features
Improvements
Tests