From 9ab7ea49f2cbeb0a0adfb517bcd3c0b2fac5dff2 Mon Sep 17 00:00:00 2001 From: Simo Date: Tue, 3 Mar 2026 11:25:34 -0400 Subject: [PATCH 1/3] wip Signed-off-by: Simo --- components/waves/drops/WaveDropAuthorPfp.tsx | 56 +++++++++---- package-lock.json | 83 +++++--------------- 2 files changed, 61 insertions(+), 78 deletions(-) diff --git a/components/waves/drops/WaveDropAuthorPfp.tsx b/components/waves/drops/WaveDropAuthorPfp.tsx index 66d6762c6a..1c61cf3543 100644 --- a/components/waves/drops/WaveDropAuthorPfp.tsx +++ b/components/waves/drops/WaveDropAuthorPfp.tsx @@ -1,12 +1,12 @@ "use client"; -import React from "react"; -import Image from "next/image"; -import Link from "next/link"; -import type { ApiDrop } from "@/generated/models/ApiDrop"; import { resolveIpfsUrlSync } from "@/components/ipfs/IPFSContext"; import UserProfileTooltipWrapper from "@/components/utils/tooltip/UserProfileTooltipWrapper"; import { useCompactMode } from "@/contexts/CompactModeContext"; +import type { ApiDrop } from "@/generated/models/ApiDrop"; +import Image from "next/image"; +import Link from "next/link"; +import React, { useState } from "react"; interface WaveDropAuthorPfpProps { readonly drop: ApiDrop; @@ -17,6 +17,18 @@ const WaveDropAuthorPfp: React.FC = ({ drop }) => { const resolvedPfp = drop.author.pfp ? resolveIpfsUrlSync(drop.author.pfp) : null; + const [loadState, setLoadState] = useState<{ + src: string | null; + mode: "optimized" | "unoptimized" | "placeholder"; + }>({ + src: null, + mode: "optimized", + }); + const loadMode: "optimized" | "unoptimized" | "placeholder" = + loadState.src === resolvedPfp ? loadState.mode : "optimized"; + const setLoadMode = (mode: "optimized" | "unoptimized" | "placeholder") => { + setLoadState({ src: resolvedPfp, mode }); + }; const authorHandle = drop.author.handle; const profileHref = authorHandle ? `/${authorHandle}` : null; @@ -25,17 +37,31 @@ const WaveDropAuthorPfp: React.FC = ({ drop }) => { const sizeClasses = compact ? "tw-h-8 tw-w-8" : "tw-h-10 tw-w-10"; const containerClasses = `tw-relative tw-flex-shrink-0 ${sizeClasses} tw-rounded-lg tw-bg-iron-900 tw-overflow-hidden`; - const avatarContent = resolvedPfp ? ( - {authorHandle - ) : ( -
- ); + const handleImageError = () => { + if (loadMode === "optimized") { + setLoadMode("unoptimized"); + return; + } + setLoadMode("placeholder"); + }; + + const avatarContent = + resolvedPfp === null || loadMode === "placeholder" ? ( +
+ ) : ( + { + ); const handleClick = (event: React.MouseEvent) => { event.stopPropagation(); diff --git a/package-lock.json b/package-lock.json index bae46c49e0..2e2199d22a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1486,29 +1486,27 @@ "license": "MIT" }, "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.2" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "*" } }, "node_modules/@eslint/config-helpers": { @@ -1563,29 +1561,27 @@ "license": "MIT" }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.2" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "*" } }, "node_modules/@eslint/js": { @@ -6505,9 +6501,6 @@ "cpu": [ "arm" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6521,9 +6514,6 @@ "cpu": [ "arm" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -6537,9 +6527,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6553,9 +6540,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -6569,9 +6553,6 @@ "cpu": [ "loong64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6585,9 +6566,6 @@ "cpu": [ "loong64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -6601,9 +6579,6 @@ "cpu": [ "ppc64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6617,9 +6592,6 @@ "cpu": [ "ppc64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -6633,9 +6605,6 @@ "cpu": [ "riscv64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6649,9 +6618,6 @@ "cpu": [ "riscv64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -6665,9 +6631,6 @@ "cpu": [ "s390x" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6681,9 +6644,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6697,9 +6657,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ From 9a7af0c955e1fdc49b6802627a0558de9320364c Mon Sep 17 00:00:00 2001 From: Simo Date: Tue, 3 Mar 2026 11:34:00 -0400 Subject: [PATCH 2/3] wip Signed-off-by: Simo --- components/waves/drops/WaveDropAuthorPfp.tsx | 3 ++- helpers/image.helpers.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/components/waves/drops/WaveDropAuthorPfp.tsx b/components/waves/drops/WaveDropAuthorPfp.tsx index 1c61cf3543..a6ebbc5746 100644 --- a/components/waves/drops/WaveDropAuthorPfp.tsx +++ b/components/waves/drops/WaveDropAuthorPfp.tsx @@ -4,6 +4,7 @@ import { resolveIpfsUrlSync } from "@/components/ipfs/IPFSContext"; import UserProfileTooltipWrapper from "@/components/utils/tooltip/UserProfileTooltipWrapper"; import { useCompactMode } from "@/contexts/CompactModeContext"; import type { ApiDrop } from "@/generated/models/ApiDrop"; +import { getScaledImageUri, ImageScale } from "@/helpers/image.helpers"; import Image from "next/image"; import Link from "next/link"; import React, { useState } from "react"; @@ -51,7 +52,7 @@ const WaveDropAuthorPfp: React.FC = ({ drop }) => { ) : ( { Date: Tue, 3 Mar 2026 11:54:15 -0400 Subject: [PATCH 3/3] wip Signed-off-by: Simo --- components/waves/drops/WaveDropAuthorPfp.tsx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/components/waves/drops/WaveDropAuthorPfp.tsx b/components/waves/drops/WaveDropAuthorPfp.tsx index a6ebbc5746..55dfd08a52 100644 --- a/components/waves/drops/WaveDropAuthorPfp.tsx +++ b/components/waves/drops/WaveDropAuthorPfp.tsx @@ -13,21 +13,25 @@ interface WaveDropAuthorPfpProps { readonly drop: ApiDrop; } +type PfpLoadMode = "optimized" | "unoptimized" | "placeholder"; + +type PfpLoadState = { + src: string | null; + mode: PfpLoadMode; +}; + const WaveDropAuthorPfp: React.FC = ({ drop }) => { const compact = useCompactMode(); const resolvedPfp = drop.author.pfp ? resolveIpfsUrlSync(drop.author.pfp) : null; - const [loadState, setLoadState] = useState<{ - src: string | null; - mode: "optimized" | "unoptimized" | "placeholder"; - }>({ + const [loadState, setLoadState] = useState({ src: null, mode: "optimized", }); - const loadMode: "optimized" | "unoptimized" | "placeholder" = + const loadMode: PfpLoadMode = loadState.src === resolvedPfp ? loadState.mode : "optimized"; - const setLoadMode = (mode: "optimized" | "unoptimized" | "placeholder") => { + const setLoadMode = (mode: PfpLoadMode) => { setLoadState({ src: resolvedPfp, mode }); };