Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
44 changes: 36 additions & 8 deletions src/app/profile/[address]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import { getFullUserProfile } from "../../../../lib/actions";
import { truncateAddress } from "../../../../lib/utils";
import { formatPrice, formatSupply } from "../../../../lib/format";
import { getTokenPrice, mcv2BondAbi, erc20Abi, type TokenPriceInfo, get24hPriceChange, getTokenTVL } from "../../../../lib/price";

Check warning on line 14 in src/app/profile/[address]/page.tsx

View workflow job for this annotation

GitHub Actions / lint-and-typecheck

'TokenPriceInfo' is defined but never used
import { browserClient } from "../../../../lib/rpc";
import type { FarcasterProfile } from "../../../../lib/farcaster";
import type { AgentMetadata } from "../../../../lib/contracts/erc8004";
Expand Down Expand Up @@ -133,7 +133,7 @@
if (r <= 0) clearInterval(interval);
}, 1000);
return () => clearInterval(interval);
}, [dbUser?.steemhunt_fetched_at]);

Check warning on line 136 in src/app/profile/[address]/page.tsx

View workflow job for this annotation

GitHub Actions / lint-and-typecheck

React Hook useEffect has a missing dependency: 'COOLDOWN_MS'. Either include it or remove the dependency array

const onCooldown = cooldownRemaining > 0;

Expand Down Expand Up @@ -477,6 +477,9 @@
{claimedRoyalties != null && claimedRoyalties > BigInt(0) && (
<div className="text-muted mt-1.5 text-[11px]">
Royalties: <span className="text-green-700 font-medium">{formatPrice(formatUnits(claimedRoyalties, 18))} {RESERVE_LABEL}</span>
{plotUsdPrice != null && (
<span className="text-muted"> (≈ {formatUsdValue(Number(formatUnits(claimedRoyalties, 18)) * plotUsdPrice)})</span>
)}
</div>
)}
</div>
Expand Down Expand Up @@ -704,14 +707,14 @@
<StatCell
label="Donations"
value={totalDonations > BigInt(0)
? `${formatPrice(formatUnits(totalDonations, 18))} ${RESERVE_LABEL}`
? `${formatPrice(formatUnits(totalDonations, 18))} ${RESERVE_LABEL}${plotUsd != null ? ` (≈ ${formatUsdValue(Number(formatUnits(totalDonations, 18)) * plotUsd)})` : ""}`
: "—"}
/>
{isOwnProfile && royaltyInfo && (
<StatCell
label="Claimable"
value={royaltyInfo.unclaimed > BigInt(0)
? `${formatPrice(formatUnits(royaltyInfo.unclaimed, 18))} ${RESERVE_LABEL}`
? `${formatPrice(formatUnits(royaltyInfo.unclaimed, 18))} ${RESERVE_LABEL}${plotUsd != null ? ` (≈ ${formatUsdValue(Number(formatUnits(royaltyInfo.unclaimed, 18)) * plotUsd)})` : ""}`
: "—"}
/>
)}
Expand Down Expand Up @@ -862,7 +865,7 @@
</span>
<span>
{priceInfo
? `${formatPrice(priceInfo.pricePerToken)} ${RESERVE_LABEL}`
? `${formatPrice(priceInfo.pricePerToken)} ${RESERVE_LABEL}${plotUsd != null ? ` (≈ ${formatUsdValue(Number(priceInfo.pricePerToken) * plotUsd)})` : ""}`
: "—"}
</span>
<span>
Expand Down Expand Up @@ -1031,6 +1034,7 @@
const DONATION_PAGE_SIZE = 10;

function ProfileDonationHistory({ storylineId }: { storylineId: number }) {
const { data: plotUsd } = usePlotUsdPrice();
const {
data,
isFetchingNextPage,
Expand Down Expand Up @@ -1094,6 +1098,9 @@
<span className="text-accent font-medium">
{formatPrice(formatUnits(BigInt(d.amount), 18))} {RESERVE_LABEL}
</span>
{plotUsd != null && (
<span className="text-muted">(≈ {formatUsdValue(Number(formatUnits(BigInt(d.amount), 18)) * plotUsd)})</span>
)}
{d.tx_hash && (
<a
href={`${EXPLORER_URL}/tx/${d.tx_hash}`}
Expand Down Expand Up @@ -1127,6 +1134,7 @@
// ---------------------------------------------------------------------------

function StoryDonationCount({ storylineId, tokenAddress }: { storylineId: number; tokenAddress: string }) {
const { data: plotUsd } = usePlotUsdPrice();
const { data } = useQuery({
queryKey: ["story-donation-count", storylineId, tokenAddress],
queryFn: async () => {
Expand All @@ -1149,7 +1157,7 @@

return (
<span>
{formatPrice(formatUnits(data.total, 18))} {RESERVE_LABEL} <span className="text-muted">({data.count})</span>
{formatPrice(formatUnits(data.total, 18))} {RESERVE_LABEL}{plotUsd != null && ` (≈ ${formatUsdValue(Number(formatUnits(data.total, 18)) * plotUsd)})`} <span className="text-muted">({data.count})</span>
</span>
);
}
Expand Down Expand Up @@ -1437,10 +1445,16 @@
</span>
<span>
Price: <span className="text-foreground">{formatPrice(formatUnits(h.price, 18))} {RESERVE_LABEL}</span>
{plotUsd != null && (
<span className="text-muted"> (≈ {formatUsdValue(Number(formatUnits(h.price, 18)) * plotUsd)})</span>
)}
</span>
{h.entryPrice !== null && h.entryPrice > 0 && (
<span>
Entry: <span className="text-foreground">{formatPrice(h.entryPrice)} {RESERVE_LABEL}</span>
{plotUsd != null && (
<span className="text-muted"> (≈ {formatUsdValue(h.entryPrice * plotUsd)})</span>
)}
</span>
)}
{h.lastTraded && (
Expand Down Expand Up @@ -1468,6 +1482,9 @@
<span className="text-accent text-sm font-medium">
{formatPrice(formatUnits(donationsReceived!.total, 18))} {RESERVE_LABEL}
</span>
{plotUsd != null && (
<span className="text-muted ml-1 text-xs">(≈ {formatUsdValue(Number(formatUnits(donationsReceived!.total, 18)) * plotUsd)})</span>
)}
<span className="text-muted ml-2 text-xs">
from {donationsReceived!.count} {donationsReceived!.count === 1 ? "donation" : "donations"}
</span>
Expand All @@ -1483,7 +1500,7 @@
<span className="text-foreground ml-2 normal-case">
{donationTotalCount} {donationTotalCount === 1 ? "donation" : "donations"}
{totalDonated > BigInt(0) && (
<> &middot; {formatPrice(formatUnits(totalDonated, 18))} {RESERVE_LABEL} total loaded</>
<> &middot; {formatPrice(formatUnits(totalDonated, 18))} {RESERVE_LABEL}{plotUsd != null && ` (≈ ${formatUsdValue(Number(formatUnits(totalDonated, 18)) * plotUsd)})`} total loaded</>
)}
</span>
)}
Expand Down Expand Up @@ -1511,6 +1528,9 @@
<span className="text-accent font-medium">
{formatPrice(formatUnits(BigInt(d.amount), 18))} {RESERVE_LABEL}
</span>
{plotUsd != null && (
<span className="text-muted">(≈ {formatUsdValue(Number(formatUnits(BigInt(d.amount), 18)) * plotUsd)})</span>
)}
{d.tx_hash && (
<a
href={`${EXPLORER_URL}/tx/${d.tx_hash}`}
Expand Down Expand Up @@ -1700,11 +1720,14 @@
storyTitle?: string;
txHash?: string;
detail?: string;
/** Numeric PLOT amount for USD conversion */
reserveAmount?: number;
}

const FEED_PAGE_SIZE = 30;

function ActivityTab({ address }: { address: string }) {
const { data: plotUsd } = usePlotUsdPrice();
const [visibleCount, setVisibleCount] = useState(FEED_PAGE_SIZE);

const { data: feed = [], isLoading } = useQuery({
Expand Down Expand Up @@ -1798,6 +1821,7 @@
detail: tokenAmount
? `${tokenAmount} tokens for ${formatPrice(t.reserve_amount)} ${RESERVE_LABEL}`
: `${formatPrice(t.reserve_amount)} ${RESERVE_LABEL}`,
reserveAmount: t.reserve_amount,
txHash: t.tx_hash,
});
}
Expand All @@ -1810,6 +1834,7 @@
timestamp: d.block_timestamp,
storylineId: d.storyline_id,
detail: `${formatPrice(formatUnits(BigInt(d.amount), 18))} ${RESERVE_LABEL}`,
reserveAmount: Number(formatUnits(BigInt(d.amount), 18)),
txHash: d.tx_hash,
});
}
Expand Down Expand Up @@ -1853,7 +1878,7 @@
<div className="mt-6">
<div className="space-y-1.5">
{visible.map((entry, i) => (
<FeedRow key={`${entry.type}-${entry.timestamp}-${i}`} entry={entry} />
<FeedRow key={`${entry.type}-${entry.timestamp}-${i}`} entry={entry} plotUsd={plotUsd} />
))}
</div>
{hasMore && (
Expand Down Expand Up @@ -1888,7 +1913,7 @@
claimed_royalties: "text-green-700",
};

function FeedRow({ entry }: { entry: FeedEntry }) {
function FeedRow({ entry, plotUsd }: { entry: FeedEntry; plotUsd?: number | null }) {
return (
<div className="border-border flex flex-col gap-1 rounded border px-3 py-2 text-xs sm:flex-row sm:items-center sm:justify-between sm:gap-2">
{/* Row 1 (mobile) / Left (desktop): event type + story title */}
Expand All @@ -1910,7 +1935,10 @@
{/* Row 2 (mobile) / Right (desktop): detail + date + tx link */}
<div className="flex flex-wrap items-center gap-x-2 gap-y-0.5 pl-18 sm:shrink-0 sm:pl-0">
{entry.detail && (
<span className="text-muted">{entry.detail}</span>
<span className="text-muted">
{entry.detail}
{entry.reserveAmount != null && plotUsd != null && ` (≈ ${formatUsdValue(entry.reserveAmount * plotUsd)})`}
</span>
)}
<time dateTime={entry.timestamp} className="text-muted whitespace-nowrap text-[10px]">
{new Date(entry.timestamp).toLocaleDateString("en-US", {
Expand Down
8 changes: 4 additions & 4 deletions src/components/ClaimRoyalties.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export function ClaimRoyalties({ tokenAddress, plotCount, beneficiary, plotUsd }
Chain at least 2 plots ({plotCount}/2) {eligible && "\u2713"}
</li>
<li>
Royalties accrue when readers trade your token ({formatTruncated(unclaimed, decimals)} {RESERVE_LABEL} unclaimed)
Royalties accrue when readers trade your token ({formatTruncated(unclaimed, decimals)} {RESERVE_LABEL}{plotUsd != null ? ` ≈ ${formatUsdValue(parseFloat(formatUnits(unclaimed, decimals)) * plotUsd)}` : ""} unclaimed)
</li>
</ul>
</div>
Expand All @@ -148,14 +148,14 @@ export function ClaimRoyalties({ tokenAddress, plotCount, beneficiary, plotUsd }
<span className={`ml-1 font-medium ${unclaimed > BigInt(0) ? "text-accent" : "text-foreground"}`}>
{formatTruncated(unclaimed, decimals)} {RESERVE_LABEL}
</span>
{unclaimed > BigInt(0) && plotUsd && (
{plotUsd != null && (
<span className="text-muted ml-1 text-[10px]">
(≈ {formatUsdValue(parseFloat(formatUnits(unclaimed, decimals)) * plotUsd)})
</span>
)}
{totalClaimed > BigInt(0) && (
<span className="text-muted ml-1 text-[10px]">
(claimed: {formatTruncated(totalClaimed, decimals)} {RESERVE_LABEL} so far)
(claimed: {formatTruncated(totalClaimed, decimals)} {RESERVE_LABEL}{plotUsd != null ? ` ≈ ${formatUsdValue(parseFloat(formatUnits(totalClaimed, decimals)) * plotUsd)}` : ""} so far)
</span>
)}
<button
Expand Down Expand Up @@ -187,7 +187,7 @@ export function ClaimRoyalties({ tokenAddress, plotCount, beneficiary, plotUsd }
)}
{txHash && txState === "done" && (
<p className="text-muted mt-1 text-[10px]">
Claimed {formatTruncated(claimedAmount, decimals)} {RESERVE_LABEL} —{" "}
Claimed {formatTruncated(claimedAmount, decimals)} {RESERVE_LABEL}{plotUsd != null ? ` (≈ ${formatUsdValue(parseFloat(formatUnits(claimedAmount, decimals)) * plotUsd)})` : ""} —{" "}
tx:{" "}
<a
href={`${EXPLORER_URL}/tx/${txHash}`}
Expand Down
Loading