Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions components/drops/media/InteractiveIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
interface InteractiveIconProps {
readonly className?: string;
}

export default function InteractiveIcon({
className,
}: InteractiveIconProps) {
return (
<svg
viewBox="45 15 170 230"
className={className}
fill="currentColor"
aria-hidden="true"
focusable="false"
>
<path d="M195.4,107.9c-2.6,0-5,0.4-7.4,1.2c-0.2-0.1-0.5-0.2-0.8-0.3c-4.4-7.1-12-11.4-20.4-11.4c-2.9,0-5.7,0.5-8.4,1.4c-4.4-7.4-12.1-11.9-20.8-11.9c-1.6,0-3.1,0.1-4.6,0.4V73.9c0-14-10.7-24.9-24.4-24.9c-13.8,0-25,11.2-25,24.9v65.8l-3.9-3.9c-4.5-4.4-10.7-6.9-17.5-6.9c-6.9,0-13.6,2.6-17.9,6.9c-9.4,9.4-12.5,25.7-1.5,36.7l56.2,55.9c1.3,1.3,2.8,2.4,4.4,3.4c10.5,8.6,23.1,14.2,49.7,14.2c61.8,0,66.9-36.2,66.9-73.3v-40C220.1,118.8,209.4,107.9,195.4,107.9L195.4,107.9z M210.3,172.8c0,36-4.2,63.5-57.1,63.5c-24,0-34.5-4.7-43.7-12.2l-0.6-0.4c-1.1-0.7-2-1.4-2.9-2.2l-56.2-55.8c-7.3-7.3-3.5-17.8,1.5-22.8c2.5-2.5,6.7-4,10.9-4c4.2,0,8,1.4,10.6,4l20.6,20.5V73.8c0-8.3,6.8-15.1,15.2-15.1c8.2,0,14.6,6.6,14.6,15.1v28.5l0.1-0.1v29.3c0,2.7,2.2,4.9,4.9,4.9c2.7,0,4.9-2.2,4.9-4.9V97.4c1.4-0.4,2.9-0.7,4.5-0.7c6.3,0,11.6,3.9,13.8,10.2l0.6,1.8v32.1c0,2.7,2.2,4.9,4.9,4.9c2.7,0,4.9-2.2,4.9-4.9V108c1.6-0.5,3.3-0.9,4.9-0.9c6.3,0,11.6,3.9,13.8,10.2l0.3,1v32.1c0,2.7,2.2,4.9,4.9,4.9c2.7,0,4.9-2.2,4.9-4.9v-31.8c1.6-0.6,3.2-1,5.2-1c8.2,0,14.4,6.5,14.4,15.1V172.8L210.3,172.8z M68.4,120.1c0.9,0.7,1.9,1,2.9,1c1.5,0,3-0.7,4-2c1.6-2.2,1.2-5.3-1-6.9C61.1,102.4,53.5,87.4,53.5,71c0-28.3,23-51.2,51.2-51.2S156,42.8,156,71c0,3.4-0.3,6.9-1,10.2c-0.5,2.6,1.2,5.3,3.9,5.8c2.6,0.5,5.3-1.2,5.8-3.9c0.8-4,1.2-8.1,1.2-12.1c0-33.6-27.4-61-61-61S43.7,37.4,43.7,71.1C43.7,90.3,52.9,108.6,68.4,120.1L68.4,120.1z" />
</svg>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ImageScale } from "@/helpers/image.helpers";
import DropListItemContentMediaImage from "./DropListItemContentMediaImage";
import DropListItemContentMediaVideo from "./DropListItemContentMediaVideo";
import SandboxedExternalIframe from "@/components/common/SandboxedExternalIframe";
import InteractiveIcon from "@/components/drops/media/InteractiveIcon";

enum MediaType {
IMAGE = "IMAGE",
Expand Down Expand Up @@ -103,21 +104,18 @@ export default function DropListItemContentMedia({
case MediaType.HTML:
if (disableAutoPlay && !htmlActivated) {
return (
<div className="tw-flex tw-h-full tw-w-full tw-items-center tw-justify-center tw-bg-iron-950/30">
<div
role="button"
tabIndex={0}
<div className="tw-relative tw-flex tw-h-full tw-w-full tw-items-center tw-justify-center tw-bg-iron-950/30">
<button
type="button"
onClick={() => setHtmlActivated(true)}
onKeyDown={(event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
setHtmlActivated(true);
}
}}
className="tw-inline-flex tw-cursor-pointer tw-items-center tw-justify-center tw-rounded-md tw-border tw-border-iron-700 tw-bg-iron-900/80 tw-px-3 tw-py-1.5 tw-text-xs tw-font-medium tw-text-iron-200 tw-transition hover:tw-bg-iron-800"
className="tw-absolute tw-inset-0 tw-flex tw-items-center tw-justify-center tw-bg-transparent"
aria-label="Load interactive media"
>
Tap to load
</div>
<span className="tw-inline-flex tw-items-center tw-justify-center tw-gap-2 tw-rounded-full tw-border tw-border-white/20 tw-bg-iron-950/90 tw-px-4 tw-py-2 tw-text-xs tw-font-semibold tw-text-white tw-shadow-[0_16px_40px_rgba(0,0,0,0.65)] tw-ring-1 tw-ring-white/10 tw-transition hover:tw-bg-iron-900">
<InteractiveIcon className="tw-size-4 tw-flex-shrink-0" />
Tap to load
</span>
</button>
</div>
);
}
Expand Down
4 changes: 2 additions & 2 deletions components/home/boosted/BoostedDropCardHome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import ContentDisplay from "@/components/waves/drops/ContentDisplay";
import { buildProcessedContent } from "@/components/waves/drops/media-utils";
import type { ApiDrop } from "@/generated/models/ApiDrop";
import { getScaledImageUri, ImageScale } from "@/helpers/image.helpers";
import { LinkIcon, Square2StackIcon } from "@heroicons/react/24/outline";
import { LinkIcon, PhotoIcon } from "@heroicons/react/24/outline";
import Link from "next/link";
import { memo, useCallback, useMemo } from "react";

Expand Down Expand Up @@ -71,7 +71,7 @@ const BoostedDropCardHome = memo(
<div className="tw-relative tw-aspect-[4/5] tw-w-full tw-overflow-hidden tw-rounded-xl sm:tw-aspect-[3/4]">
{media ? (
<div className="tw-relative tw-h-full tw-w-full">
<Square2StackIcon
<PhotoIcon
className="tw-pointer-events-none tw-absolute tw-left-6 tw-top-8 tw-z-10 tw-size-6 tw-text-iron-700 tw-opacity-50"
aria-hidden="true"
/>
Expand Down
76 changes: 52 additions & 24 deletions components/home/next-mint-leading/LeadingCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ import ProfileAvatar, {
ProfileBadgeSize,
} from "@/components/common/profile/ProfileAvatar";
import MediaTypeBadge from "@/components/drops/media/MediaTypeBadge";
import InteractiveIcon from "@/components/drops/media/InteractiveIcon";
import MediaDisplay from "@/components/drops/view/item/content/media/MediaDisplay";
import { formatNumberWithCommas } from "@/helpers/Helpers";
import { ImageScale } from "@/helpers/image.helpers";
import {
getDropPreviewImageUrl,
type ExtendedDrop,
} from "@/helpers/waves/drop.helpers";
import { type ExtendedDrop } from "@/helpers/waves/drop.helpers";
import useDeviceInfo from "@/hooks/useDeviceInfo";
import { useMediaQuery } from "@/hooks/useMediaQuery";
import Link from "next/link";
import { useMemo } from "react";
import { useEffect, useState } from "react";

interface LeadingCardProps {
readonly drop: ExtendedDrop;
Expand All @@ -28,23 +27,66 @@ const getRankLabelClass = (rank: number) => {
};

export const LeadingCard = ({ drop, rank }: LeadingCardProps) => {
const { hasTouchScreen } = useDeviceInfo();
const media = drop.parts[0]?.media[0];
const isTabletOrSmaller = useMediaQuery("(max-width: 1023px)");
const mediaImageScale = isTabletOrSmaller
? ImageScale.AUTOx450
: ImageScale.AUTOx600;
const isHtml = media?.mime_type === "text/html";
const shouldGate = hasTouchScreen && isHtml;
const [interactiveEnabled, setInteractiveEnabled] = useState(!shouldGate);

const previewImageUrl = useMemo(
() => getDropPreviewImageUrl(drop.metadata),
[drop.metadata]
);
useEffect(() => {
if (shouldGate) {
setInteractiveEnabled(false);
return;
}
setInteractiveEnabled(true);
}, [drop.id, shouldGate]);
Comment thread
ragnep marked this conversation as resolved.

const title =
drop.title ??
drop.metadata.find((m) => m.data_key === "title")?.data_value ??
"Untitled";
const author = drop.author;
const rankLabelClass = getRankLabelClass(rank);
const mediaContent = (() => {
if (!media) {
return (
<div className="tw-flex tw-size-full tw-items-center tw-justify-center tw-bg-iron-950">
<span className="tw-text-sm tw-text-white/40">No image</span>
</div>
);
}

if (shouldGate && !interactiveEnabled) {
return (
<div className="tw-relative tw-flex tw-h-full tw-w-full tw-items-center tw-justify-center tw-bg-iron-950/30">
<button
type="button"
onClick={() => setInteractiveEnabled(true)}
className="tw-absolute tw-inset-0 tw-flex tw-items-center tw-justify-center tw-bg-transparent"
aria-label="Load interactive media"
>
<span className="tw-inline-flex tw-items-center tw-justify-center tw-gap-2 tw-rounded-full tw-border tw-border-white/20 tw-bg-iron-950/90 tw-px-4 tw-py-2 tw-text-xs tw-font-semibold tw-text-white tw-shadow-[0_16px_40px_rgba(0,0,0,0.65)] tw-ring-1 tw-ring-white/10 tw-transition hover:tw-bg-iron-900">
<InteractiveIcon className="tw-size-4 tw-flex-shrink-0" />
Tap to load
</span>
</button>
</div>
);
}

return (
<MediaDisplay
media_mime_type={media.mime_type}
media_url={media.url}
disableMediaInteraction={true}
imageScale={mediaImageScale}
/>
);
})();

return (
<div className="tw-group tw-flex tw-flex-col tw-gap-3 tw-text-left tw-transition-all tw-duration-500 desktop-hover:tw-opacity-70 desktop-hover:tw-grayscale desktop-hover:hover:tw-opacity-100 desktop-hover:hover:tw-grayscale-0 sm:tw-gap-4">
Expand All @@ -64,21 +106,7 @@ export const LeadingCard = ({ drop, rank }: LeadingCardProps) => {
</div>
<div className="tw-relative tw-flex tw-aspect-[3/4] tw-max-h-[clamp(320px,70vw,500px)] tw-w-full tw-items-center tw-justify-center tw-overflow-hidden tw-bg-iron-950 tw-p-2 sm:tw-p-3">
<div className="tw-flex tw-h-full tw-w-full tw-items-center tw-justify-center tw-transition-transform tw-duration-700 tw-ease-out group-hover:tw-scale-105">
{media ? (
<MediaDisplay
media_mime_type={
drop.parts[0]?.media[0]!.mime_type ?? "image/jpeg"
}
media_url={drop.parts[0]?.media[0]!.url!}
disableMediaInteraction={true}
imageScale={mediaImageScale}
previewImageUrl={previewImageUrl}
/>
) : (
<div className="tw-flex tw-size-full tw-items-center tw-justify-center tw-bg-iron-950">
<span className="tw-text-sm tw-text-white/40">No image</span>
</div>
)}
{mediaContent}
</div>
</div>
</div>
Expand Down
47 changes: 46 additions & 1 deletion components/home/now-minting/NowMintingArtwork.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,59 @@
"use client";

import { useEffect, useMemo, useState } from "react";
import NFTImage from "@/components/nft-image/NFTImage";
import { getMediaType } from "@/components/nft-image/utils/media-type";
import type { NFTWithMemesExtendedData } from "@/entities/INFT";
import useDeviceInfo from "@/hooks/useDeviceInfo";
import InteractiveIcon from "@/components/drops/media/InteractiveIcon";

interface NowMintingArtworkProps {
readonly nft: NFTWithMemesExtendedData;
}

export default function NowMintingArtwork({ nft }: NowMintingArtworkProps) {
const { hasTouchScreen } = useDeviceInfo();
const isHtml = useMemo(() => getMediaType(nft, true) === "html", [nft]);
const [hasMounted, setHasMounted] = useState(false);
const shouldGate = hasTouchScreen && isHtml;
const [interactiveEnabled, setInteractiveEnabled] = useState(false);

useEffect(() => {
setHasMounted(true);
}, []);

useEffect(() => {
setInteractiveEnabled(false);
}, [nft.id, shouldGate]);

let shouldAnimate = true;
if (isHtml) {
shouldAnimate = hasMounted && (interactiveEnabled || !shouldGate);
}

return (
<div className="tw-flex tw-w-full tw-items-start tw-justify-center">
<NFTImage nft={nft} animation={true} height={650} showBalance={true} />
<div className="tw-relative tw-w-full">
<NFTImage
nft={nft}
animation={shouldAnimate}
height={650}
showBalance={true}
/>
{shouldGate && !interactiveEnabled && (
<button
type="button"
onClick={() => setInteractiveEnabled(true)}
className="tw-absolute tw-inset-0 tw-flex tw-items-center tw-justify-center tw-bg-transparent"
aria-label="Load interactive artwork"
>
<span className="tw-inline-flex tw-items-center tw-justify-center tw-gap-2 tw-rounded-full tw-border tw-border-white/20 tw-bg-iron-950/90 tw-px-4 tw-py-2 tw-text-xs tw-font-semibold tw-text-white tw-shadow-[0_16px_40px_rgba(0,0,0,0.65)] tw-ring-1 tw-ring-white/10 tw-transition hover:tw-bg-iron-900">
<InteractiveIcon className="tw-size-4 tw-flex-shrink-0" />
Tap to load
</span>
</button>
)}
</div>
</div>
);
}
2 changes: 1 addition & 1 deletion components/home/now-minting/NowMintingSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default function NowMintingSection() {

<div className="tw-relative tw-rounded-xl tw-border tw-border-solid tw-border-iron-800/50 tw-bg-iron-950">
<div className="tw-grid tw-h-full tw-grid-cols-1 tw-gap-y-10 tw-divide-x-0 tw-divide-y tw-divide-solid tw-divide-white/5 lg:tw-grid-cols-12 lg:tw-divide-x lg:tw-divide-y-0 xl:tw-grid-cols-9">
<div className="tw-p-6 tw-pb-10 md:tw-p-8 md:tw-pb-12 lg:tw-col-span-6 xl:tw-col-span-5">
<div className="tw-px-6 tw-pt-6 md:tw-p-8 md:tw-pb-12 lg:tw-col-span-6 xl:tw-col-span-5">
<NowMintingArtwork nft={nft} />
</div>

Expand Down
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.