oglasi: manj vsiljivo in bolje placano
- vse enote se zahtevajo sele ~200 px pred vstopom v vidno polje (IntersectionObserver); prej so se vse pushale ob nalaganju strani, tudi tiste globoko spodaj, ki jih uporabnik ni nikoli videl. Odlocitev o praznosti (3 s) tece sele od zahteve, ne od mounta. - clanek: zgornji pas odstranjen (potiskal je naslovnico in naslov pod pregib, placan pa je najslabse). Prvi oglas pride sele v besedilu. - clanek: stevilo oglasov vezano na dolzino — 2 osnovna + 1 na vsakih 5 blokov cez 10, strop 5. Mediana (9 blokov) ostane pri 2, dolgi clanki dobijo do 5. Prvi je fluid in-article, vsi nadaljnji nov InContentDisplayAd (odzivni display, visja kreativa). - TopBannerAd na seznamih: odzivni namesto trdih 90 px. - mobilni lepljivi pas: odzivni vodoravni (do 110 px) namesto trdih 320x50, z onAdStatus — prazen se ne izrise. - PageSideAds: en desni 300x600 sticky z onAdStatus namesto dveh 160x600 brez zaznave (prazna je pustila luknjo); prikaze se od 1700 px navzgor. - interstitial odstranjen s horoskopa (prekrivalo cez zaslon, zaklenilo scroll); interstitial-ad.tsx in neuporabljen parallax-ad.tsx izbrisana. CMP ostaja nedotaknjen po dogovoru.
This commit is contained in:
@@ -9,7 +9,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import Header from "@/components/header";
|
||||
import Footer from "@/components/footer";
|
||||
import { InArticleAd, PageSideAds, MultiplexAd, TopBannerAd } from "@/components/adsense";
|
||||
import { InArticleAd, InContentDisplayAd, PageSideAds, MultiplexAd } from "@/components/adsense";
|
||||
import { useIsMobile } from "@/hooks/use-mobile";
|
||||
import DOMPurify from "dompurify";
|
||||
import ShareButtons from "@/components/share-buttons";
|
||||
@@ -304,7 +304,8 @@ export default function ArticlePage() {
|
||||
<Header />
|
||||
<PageSideAds contentHalfWidth={480} />
|
||||
<main className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
|
||||
<TopBannerAd />
|
||||
{/* Zgornjega pasu na clanku namenoma ni: potiskal je naslovnico in naslov
|
||||
pod pregib, placan pa je najslabse. Prvi oglas pride sele v besedilu. */}
|
||||
<Link href="/">
|
||||
<Button variant="ghost" size="sm" className="mb-3 gap-2" data-testid="button-back">
|
||||
<ArrowLeft className="w-4 h-4" />
|
||||
@@ -375,9 +376,18 @@ export default function ArticlePage() {
|
||||
[&_div[style]]:flex [&_div[style]]:justify-center
|
||||
[&_blockquote:not(.instagram-media)]:border-l-primary [&_blockquote:not(.instagram-media)]:bg-accent/50 [&_blockquote:not(.instagram-media)]:rounded-r-md [&_blockquote:not(.instagram-media)]:py-1
|
||||
[&_.instagram-media]:!bg-transparent [&_.instagram-media]:!border-0 [&_.instagram-media]:!shadow-none [&_.instagram-media]:!p-0 [&_.instagram-media]:mx-auto`;
|
||||
// Najvec dva oglasa v besedilu: po prvem odstavku in na sredini.
|
||||
// Stevilo oglasov je vezano na dolzino clanka, ne fiksno na dva:
|
||||
// dva osnovna, plus eden na vsakih pet blokov cez deset, strop pet.
|
||||
// Prvi je fluid in-article (mehak, takoj za uvodom), vsi nadaljnji so
|
||||
// navaden odzivni display - visja kreativa, mimo katere se odskrola.
|
||||
const last = segments.length - 1;
|
||||
const AD_AFTER = last <= 0 ? [] : (last === 1 ? [0] : [0, Math.floor(last / 2)]);
|
||||
const extra = Math.min(3, Math.max(0, Math.floor((blocks.length - 10) / 5)));
|
||||
const adCount = last <= 0 ? 0 : (last === 1 ? 1 : Math.min(2 + extra, last));
|
||||
const AD_AFTER: number[] = [];
|
||||
for (let i = 0; i < adCount; i++) {
|
||||
const pos = i === 0 ? 0 : Math.round((i * last) / adCount);
|
||||
if (pos < last && !AD_AFTER.includes(pos)) AD_AFTER.push(pos);
|
||||
}
|
||||
return (
|
||||
<div ref={(el) => {
|
||||
if (!el) return;
|
||||
@@ -398,7 +408,7 @@ export default function ArticlePage() {
|
||||
dangerouslySetInnerHTML={{ __html: html }}
|
||||
data-testid={idx === 0 ? "article-content" : `article-content-${idx}`}
|
||||
/>
|
||||
{AD_AFTER.includes(idx) && <InArticleAd />}
|
||||
{AD_AFTER.includes(idx) && (idx === AD_AFTER[0] ? <InArticleAd /> : <InContentDisplayAd />)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
} from "lucide-react";
|
||||
import Header from "@/components/header";
|
||||
import Footer from "@/components/footer";
|
||||
import InterstitialAd from "@/components/interstitial-ad";
|
||||
import { InArticleAd, PageSideAds, MultiplexAd } from "@/components/adsense";
|
||||
import {
|
||||
SIGNS,
|
||||
@@ -385,7 +384,6 @@ export default function HoroscopePage() {
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<Header />
|
||||
<InterstitialAd forceShow />
|
||||
<PageSideAds />
|
||||
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
|
||||
<h1 className="sr-only" data-testid="text-horoscope-title">
|
||||
|
||||
Reference in New Issue
Block a user