From cc9afe9e28dc17fb78d8cf06fa54ee5cbb58818f Mon Sep 17 00:00:00 2001 From: sebastjan Date: Mon, 31 Aug 2026 13:31:11 +0200 Subject: [PATCH] video kartice v mrezi, oglas le v vsako drugo vrstico in v visini kartice, vremenski pripomocek z naslovnice (prosil je za lokacijo) --- client/src/components/adsense.tsx | 8 ++-- client/src/pages/home.tsx | 80 +++++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 12 deletions(-) diff --git a/client/src/components/adsense.tsx b/client/src/components/adsense.tsx index 51e32fc..d91a441 100644 --- a/client/src/components/adsense.tsx +++ b/client/src/components/adsense.tsx @@ -153,12 +153,14 @@ export function ArticleCardAd() { if (filled === false) return null; return ( + {/* Meritev 31. 8. 2026: kartica clanka je visoka 399 px, fluid in-feed + enota pa se je ustavila pri 248 in pod njo je ostala luknja. Navaden + auto display z minimalno visino zapolni celo celico. */} diff --git a/client/src/pages/home.tsx b/client/src/pages/home.tsx index d7c8b72..ebcf2c0 100644 --- a/client/src/pages/home.tsx +++ b/client/src/pages/home.tsx @@ -12,7 +12,6 @@ import Header from "@/components/header"; import Footer from "@/components/footer"; import AdSense, { ArticleCardAd, SidebarAd, PageSideAds, MultiplexAd, TopBannerAd } from "@/components/adsense"; import { NewsWidget } from "@/components/news-widget"; -import { SidebarWeatherWidget } from "@/components/weather-widget"; import { BreakingNewsWidget } from "@/components/breaking-news-widget"; import PushPromptBanner from "@/components/push-prompt-banner"; import { useState, useEffect, useCallback, useRef, useMemo, lazy, Suspense } from "react"; @@ -332,6 +331,53 @@ function MobileMosaic({ latest, popular, focalPoints }: { latest: Article[]; pop ); } +interface YtVideo { ytId: string; slug: string; shortTitle?: string; title: string; rubrik?: string; publishedAt?: string; durationS?: number } + +// Video kartica v mrezi: enaka velikost kot kartica clanka, da v vrstici ni +// luknje. Pelje na /video/, kjer je oglasni prostor, ne na YouTube. +function VideoCard({ video }: { video: YtVideo }) { + const mm = Math.floor((video.durationS || 0) / 60); + const ss = String((video.durationS || 0) % 60).padStart(2, "0"); + return ( + +
+
+ {video.shortTitle +
+
+ +
+
+ {video.durationS ? ( + + {mm}:{ss} + + ) : null} +
+
+
+ VIDEO + {video.publishedAt && ( + {timeAgo(new Date(video.publishedAt))} + )} +
+

+ {video.shortTitle || video.title} +

+

+ Jetzt ansehen auf FOLX TV +

+
+
+ + ); +} + function MediumCard({ article, focalPoints }: { article: Article; focalPoints?: Record }) { const isVideo = article.category === "Video"; const objPos = getObjectPosition(article.coverImage, focalPoints); @@ -785,6 +831,12 @@ export default function Home() { queryKey: ["/api/articles/popular"], }); + // Videi v mrezi: gledalca zadrzijo pri nas in odprejo se eno stran z oglasi. + const { data: ytData } = useQuery<{ items: YtVideo[] }>({ + queryKey: ["/api/yt-videos?limit=12"], + }); + const videos = ytData?.items || []; + const { data: galleryImages } = useQuery({ queryKey: ["/api/gallery", "home"], queryFn: () => fetch("/api/gallery?limit=20").then((r) => r.json()), @@ -864,20 +916,29 @@ export default function Home() { } } + // Oglas gre le v vsako drugo vrstico. Meritev 31. 8. 2026: od 13 enot na + // naslovnici jih je 9 vrnilo unfilled, torej je mest vec, kot jih Google + // za to stran zapolni. Manj mest z visjo zapolnjenostjo prinese vec. let adCount = 0; + let vidCount = 0; const totalRows = items.length / 4; for (let r = 0; r < totalRows; r++) { const rowStart = r * 4; const hasWidget = items.slice(rowStart, rowStart + 4).some((it) => it.type === "widget"); - if (!hasWidget) { - // Enako kot na straneh rubrik: v prvi vrstici oglas ni prva celica. - const pos = r === 0 ? 3 : adCount % 2 === 0 ? 0 : 3; + if (hasWidget) continue; + if (r % 2 === 1) { + const pos = r === 1 ? 3 : adCount % 2 === 0 ? 0 : 3; items[rowStart + pos] = { type: "ad", key: `ad-row-${adCount++}` }; + } else if (r > 0 && videos.length) { + // video namesto zadnjega clanka v vrstici brez oglasa + const v = videos[vidCount % videos.length]; + vidCount += 1; + items[rowStart + 2] = { type: "video", key: `v-${v.ytId}`, video: v }; } } return items; - }, [spaced, widgets]); + }, [spaced, widgets, videos]); const NA_NASLOVNICI = 48; const gridRows: (typeof gridItems)[] = useMemo(() => { @@ -977,7 +1038,6 @@ export default function Home() { />
- {articles && articles.length > 0 && new Date(b.publishedAt).getTime() - new Date(a.publishedAt).getTime())).slice(0, 8)} className="lg:flex-1 lg:min-h-0 overflow-hidden" />}
@@ -992,9 +1052,11 @@ export default function Home() { ?
{item.widget!.el}
: item.type === "ad" ?
- : item.article - ? - : null + : item.type === "video" && item.video + ? + : item.article + ? + : null )} {ri === gridRows.length - 1 && widePickedArticles.length > 0 && (