diff --git a/client/src/components/breaking-news-widget.tsx b/client/src/components/breaking-news-widget.tsx index 0e19e04..5bb3ae5 100644 --- a/client/src/components/breaking-news-widget.tsx +++ b/client/src/components/breaking-news-widget.tsx @@ -1,5 +1,5 @@ import { useQuery } from "@tanstack/react-query"; -import { artistKey } from "@/lib/artists"; +import { artistGroup } from "@/lib/artists"; import { useState, useEffect, useCallback } from "react"; import { Globe, ExternalLink } from "lucide-react"; @@ -27,13 +27,13 @@ export function BreakingNewsWidget() { const recent: string[] = []; while (rest.length) { let idx = rest.findIndex((n: any) => { - const k = artistKey(n?.title || ""); + const k = artistGroup(n?.title || ""); return !k || !recent.includes(k); }); if (idx < 0) idx = 0; const n = rest.splice(idx, 1)[0]; out.push(n); - recent.push(artistKey((n as any)?.title || "")); + recent.push(artistGroup((n as any)?.title || "")); if (recent.length >= 5) recent.shift(); } return out; diff --git a/client/src/components/news-widget.tsx b/client/src/components/news-widget.tsx index 3bf8c27..05362d3 100644 --- a/client/src/components/news-widget.tsx +++ b/client/src/components/news-widget.tsx @@ -1,5 +1,5 @@ import { useQuery } from "@tanstack/react-query"; -import { artistKey } from "@/lib/artists"; +import { artistGroup } from "@/lib/artists"; import { useState, useEffect, useCallback } from "react"; import { Newspaper, ExternalLink } from "lucide-react"; @@ -27,13 +27,13 @@ export function NewsWidget() { const recent: string[] = []; while (rest.length) { let idx = rest.findIndex((n: any) => { - const k = artistKey(n?.title || ""); + const k = artistGroup(n?.title || ""); return !k || !recent.includes(k); }); if (idx < 0) idx = 0; const n = rest.splice(idx, 1)[0]; out.push(n); - recent.push(artistKey((n as any)?.title || "")); + recent.push(artistGroup((n as any)?.title || "")); if (recent.length >= 5) recent.shift(); } return out; diff --git a/client/src/lib/artists.ts b/client/src/lib/artists.ts index 7007992..b761672 100644 --- a/client/src/lib/artists.ts +++ b/client/src/lib/artists.ts @@ -159,3 +159,33 @@ export function artistKey(title: string): string { } return best ? norm(best) : ""; } + +/** Rocne povezave: druzine in zasedbe, ki spadajo skupaj. */ +const SKUPINE: Record = { + "alexander rier": "kastelruther spatzen", + "norbert rier": "kastelruther spatzen", + "kastelruther spatzen": "kastelruther spatzen", +}; + +/** Druga beseda, ki ni priimek in zato ne sme delati skupine. */ +const NI_PRIIMEK = new Set([ + "schlager", "music", "band", "express", "quintett", "brothers", + "oberkrainer", "buam", "boys", "girls", "sisters", +]); + +/** + * Skupina izvajalca za razmik na naslovnici. Alexander in Norbert Rier sta ista + * skupina (Kastelruther Spatzen), prav tako Costa in Lucas Cordalis ali sestri + * Hofmann - dva taka clanka drug ob drugem bralcu izgledata kot podvojitev. + */ +export function artistGroup(title: string): string { + const k = artistKey(title); + if (!k) return ""; + if (SKUPINE[k]) return SKUPINE[k]; + if (k.includes('"')) return k; + const d = k.split(" "); + if (d.length === 2 && !/^(die|das|der|dj)$/.test(d[0]) && d[1].length >= 4 && !NI_PRIIMEK.has(d[1])) { + return d[1]; + } + return k; +} diff --git a/client/src/pages/home.tsx b/client/src/pages/home.tsx index e4c5b0c..568fcc5 100644 --- a/client/src/pages/home.tsx +++ b/client/src/pages/home.tsx @@ -1,5 +1,5 @@ import { useQuery } from "@tanstack/react-query"; -import { artistKey } from "@/lib/artists"; +import { artistGroup } from "@/lib/artists"; import { Link } from "wouter"; import { type Article } from "@shared/schema"; import { format } from "date-fns"; @@ -190,13 +190,13 @@ function razmakniPoIzvajalcu(list: Article[], razmik = 5, seed: string[] = []): const recent: string[] = seed.filter(Boolean).slice(-(razmik - 1)); while (rest.length) { let idx = rest.findIndex((a) => { - const k = artistKey(a?.title || ""); + const k = artistGroup(a?.title || ""); return !k || !recent.includes(k); }); if (idx < 0) idx = 0; const a = rest.splice(idx, 1)[0]; out.push(a); - recent.push(artistKey(a?.title || "")); + recent.push(artistGroup(a?.title || "")); if (recent.length >= razmik) recent.shift(); } return out; @@ -261,11 +261,14 @@ function MobileMosaic({ latest, popular, focalPoints }: { latest: Article[]; pop if (l.length === 0) return null; const usedIds = new Set(pool.map((a) => a.id)); - const seenNow = l.map((a) => artistKey(a?.title || "")).filter(Boolean); + const poolGroups = new Set(pool.map((a) => artistGroup(a?.title || "")).filter(Boolean)); + const kandidati = (popular || []).filter((a) => !usedIds.has(a.id)); + const brezPodvojitve = kandidati.filter((a) => { + const g = artistGroup(a?.title || ""); + return !g || !poolGroups.has(g); + }); const p = razmakniPoIzvajalcu( - (popular || []).filter((a) => !usedIds.has(a.id)), - 5, - seenNow, + brezPodvojitve.length >= 3 ? brezPodvojitve : kandidati, ).slice(0, 3); const nextStart = ((displayPage + 1) % totalPages) * pageSize; @@ -806,13 +809,13 @@ export default function Home() { const recent: string[] = []; while (rest.length) { let idx = rest.findIndex((a) => { - const k = artistKey(a.title || ""); + const k = artistGroup(a.title || ""); return !k || !recent.includes(k); }); if (idx < 0) idx = 0; const a = rest.splice(idx, 1)[0]; out.push(a); - recent.push(artistKey(a.title || "")); + recent.push(artistGroup(a.title || "")); if (recent.length >= RAZMIK) recent.shift(); } return out;