diff --git a/src/app/home-page/components/ArticleFeed.tsx b/src/app/home-page/components/ArticleFeed.tsx index 4bda80a..577a409 100644 --- a/src/app/home-page/components/ArticleFeed.tsx +++ b/src/app/home-page/components/ArticleFeed.tsx @@ -1,10 +1,14 @@ "use client"; -import React, { useState, useRef, useId, useEffect, useCallback } from "react"; +import React, { Fragment, useState, useRef, useId, useEffect, useCallback, useMemo } from "react"; import AppImage from "@/components/ui/AppImage"; import SidebarAdStack from "@/components/SidebarAdStack"; +import AdImage from "@/components/AdImage"; +import { rotateAll, type Ad } from "@/lib/ads"; import { PersonIcon, ChevronLeftIcon, ChevronRightIcon, SearchIcon, CloseIcon } from "@/components/ui/Icons"; import Link from "next/link"; +const MOBILE_AD_EVERY_N = 4; + interface ArticleItem { title: string; @@ -86,6 +90,10 @@ export default function ArticleFeed() { const sentinelRef = useRef(null); const feedId = useId(); + // Shuffled 300x250 pool for mobile in-feed inserts (md:hidden). + // Tablet/desktop already get the SidebarAdStack to the right of the feed. + const mobileInfeedAds = useMemo(() => rotateAll("300x250"), []); + // Load preference from localStorage useEffect(() => { try { @@ -550,8 +558,18 @@ export default function ArticleFeed() { : `/articles/${article?.slug}`; const linkProps = isImported ? { target: "_blank", rel: "noopener noreferrer" } : {}; + // Mobile in-feed ad after every Nth article (skip if last item). + const isAdSlot = + (i + 1) % MOBILE_AD_EVERY_N === 0 && + i + 1 < displayedArticles.length && + mobileInfeedAds.length > 0; + const inFeedAd = isAdSlot + ? mobileInfeedAds[Math.floor((i + 1) / MOBILE_AD_EVERY_N - 1) % mobileInfeedAds.length] + : null; + return ( -
+ +
+ {inFeedAd && ( +
+ + Sponsored + + +
+ )} +
); })}