1import { e as createSignal, i as getNextElement, t as template, l as insert, b as createComponent, v as createRenderEffect, w as className, F as For, D as createEffect, f as onCleanup, a as createMemo, M as Match, p as getNextMarker, m as memo, J as Switch, S as Show, z as setAttribute, L as ErrorBoundary, A as classList, k as mergeProps } from './web-CqJQ5ziD.js'; 2import { C as ChannelCarousel, a as areChannelListsPopulated, i as isSliderPopulated, b as extractIds, c as extractId, d as BlockErrorFallback, P as PlaylistBlock, f as PodcastEpisodeListBlock, S as StationHostsBlockRenderer, h as StationShowsBlockRenderer, E as EmojiCardBlock, j as CardGridBlockRenderer, k as ChannelBlockRenderer, l as SocialHotlineBlock, F as FormBlock, R as RichTextBlock, A as AudioPlayerBlock } from './BlockRenderer-SYwZdfFN.js'; 3import { n as isHydrated, h as channelListsActions, t as transformCMSChannelToPlayerChannel, j as hasAvailableStream, T as Text, o as AnchorLink, p as ArticleBlockRenderer } from './AnchorLink-xdKcA1QU.js'; 4import { C as ChannelSelectorItem, S as Slider, c as ShareButton } from './AllPodcastsPage-B6iz_uTK.js'; 5import { l as logger, A } from './logger-BHOJRl6t.js'; 6import { H as Heading } from './Button-DlqpH0JT.js'; 7import { r as resolveMediaUrl } from './embedConsentSync-D36RIyVL.js'; 8import { b as audioPlayerActions } from './audioPlayer-CSGXEXsU.js'; 9import { k as createAsync, u as getChannelListsByIdsQuery, v as getSliderByIdQuery } from './podcastEpisodesFetcher-BAa5SFHz.js'; 10import { R as RichTextRenderer } from './RichTextRenderer-D9Zgg_g6.js'; 11import './env-CTimTkDP.js'; 12import { T as TextAndMediaCTABlock } from './TextAndMediaCTABlock-DV1_Wzdo.js'; 13 14const channelSelector = "ChannelSelector-module_channelSelector__hvGFv"; 15const divider = "ChannelSelector-module_divider__4pU2G"; 16const dividerText = "ChannelSelector-module_dividerText__CnIMe"; 17const styles$5 = { 18 channelSelector: channelSelector, 19 divider: divider,
20 dividerText: dividerText 21}; 22 23var _tmpl$$5 = /* @__PURE__ */ template(`<div>`), _tmpl$2$4 = /* @__PURE__ */ template(`<div><span>`); 24const ChannelSelector = (props) => { 25 const [expandedChannelId, setExpandedChannelId] = createSignal(null); 26 const toggleChannel = (categoryIndex, channelIndex) => { 27 const channelId = `${categoryIndex}-${channelIndex}`; 28 setExpandedChannelId(expandedChannelId() === channelId ? null : channelId); 29 }; 30 return (() => { 31 var _el$ = getNextElement(_tmpl$$5); 32 insert(_el$, createComponent(For, { 33 get each() { 34 return props.items; 35 }, 36 children: (item, categoryIndex) => { 37 return [(() => { 38 var _el$2 = getNextElement(_tmpl$2$4), _el$3 = _el$2.firstChild; 39 insert(_el$3, () => item.title); 40 createRenderEffect((_p$) => { 41 var _v$ = styles$5.divider, _v$2 = styles$5.dividerText; 42 _v$ !== _p$.e && className(_el$2, _p$.e = _v$); 43 _v$2 !== _p$.t && className(_el$3, _p$.t = _v$2); 44 return _p$; 45 }, { 46 e: void 0, 47 t: void 0 48 }); 49 return _el$2; 50 })(), createComponent(For, { 51 get each() { 52 return item.channels; 53 }, 54 children: (channel, channelIndex) => { 55 const channelData = typeof channel === "object" && channel !== null ? channel : null; 56 if (!channelData) { 57 logger.warn("[ChannelSelector] Channel data is ID (not populated):", channel); 58 return null; 59 } 60 const channelId = `${categoryIndex()}-${channelIndex()}`; 61 return createComponent(ChannelSelectorItem, { 62 channel: channelData, 63 get isExpanded() { 64 return expandedChannelId() === channelId; 65 }, 66 onToggle: () => toggleChannel(categoryIndex(), channelIndex()) 67 }); 68 } 69 })]; 70 } 71 })); 72 createRenderEffect(() => className(_el$, styles$5.channelSelector)); 73 return _el$; 74 })(); 75}; 76 77function useMediaQuery(query) { 78 const [matches, setMatches] = createSignal(false); 79 createEffect(() => { 80 const mediaQuery = window.matchMedia(query); 81 setMatches(mediaQuery.matches); 82 const handleChange = (e) => { 83 setMatches(e.matches); 84 }; 85 mediaQuery.addEventListener("change", handleChange); 86 onCleanup(() => { 87 mediaQuery.removeEventListener("change", handleChange); 88 }); 89 }); 90 return matches; 91} 92function useIsDesktop() { 93 return useMediaQuery("(min-width: 1024px)"); 94} 95 96const carouselWrapper = "ChannelGallery-module_carouselWrapper__iKm7G"; 97const carouselSection = "ChannelGallery-module_carouselSection__psC6x"; 98const sectionTitle = "ChannelGallery-module_sectionTitle__Blyos"; 99const styles$4 = { 100 carouselWrapper: carouselWrapper, 101 carouselSection: carouselSection, 102 sectionTitle: sectionTitle 103}; 104 105var _tmpl$$4 = /* @__PURE__ */ template(`<div>`), _tmpl$2$3 = /* @__PURE__ */ template(`<div><!$><!/><!$><!/>`); 106const ChannelGallery = (props) => { 107 const isDesktopRaw = useIsDesktop(); 108 const isDesktop = createMemo(() => { 109 if (!isHydrated()) return true; 110 return isDesktopRaw(); 111 }); 112 const getVariantForItem = (item) => { 113 if (!item.channels || item.channels.length === 0) return "sender"; 114 const firstChannel = item.channels[0]; 115 if (typeof firstChannel !== "object" || firstChannel === null) return "sender"; 116 return firstChannel.channelType === "stream" ? "stream" : "sender"; 117 }; 118 return createComponent(Switch, { 119 get children() { 120 return [createComponent(Match, { 121 get when() { 122 return isDesktop(); 123 }, 124 get children() { 125 return createComponent(ChannelSelector, { 126 get items() { 127 return props.items; 128 } 129 }); 130 } 131 }), createComponent(Match, { 132 get when() { 133 return !isDesktop(); 134 }, 135 get children() { 136 var _el$ = getNextElement(_tmpl$$4); 137 insert(_el$, createComponent(For, { 138 get each() { 139 return props.items; 140 }, 141 children: (item) => (() => { 142 var _el$2 = getNextElement(_tmpl$2$3), _el$3 = _el$2.firstChild, [_el$4, _co$] = getNextMarker(_el$3.nextSibling), _el$5 = _el$4.nextSibling, [_el$6, _co$2] = getNextMarker(_el$5.nextSibling); 143 insert(_el$2, (() => { 144 var _c$ = memo(() => !!item.title); 145 return () => _c$() && createComponent(Heading, { 146 variant: "sectionTitle", 147 as: "h2", 148 get ["class"]() { 149 return styles$4.sectionTitle; 150 }, 151 get children() { 152 return item.title; 153 } 154 }); 155 })(), _el$4, _co$); 156 insert(_el$2, createComponent(ChannelCarousel, { 157 get channels() { 158 return item.channels || []; 159 }, 160 get variant() { 161 return getVariantForItem(item); 162 } 163 }), _el$6, _co$2); 164 createRenderEffect(() => className(_el$2, styles$4.carouselSection)); 165 return _el$2; 166 })() 167 })); 168 createRenderEffect(() => className(_el$, styles$4.carouselWrapper)); 169 return _el$; 170 } 171 })]; 172 } 173 }); 174}; 175 176const heroBlock = "HeroHomeBlock-module_heroBlock__HZnPP"; 177const titleSection = "HeroHomeBlock-module_titleSection__ZYHCI"; 178const title = "HeroHomeBlock-module_title__PFzF1"; 179const heroContent$1 = "HeroHomeBlock-module_heroContent__jAbqk"; 180const gallerySection = "HeroHomeBlock-module_gallerySection__BYG-b"; 181const galleryScrollContainer = "HeroHomeBlock-module_galleryScrollContainer__owdQe"; 182const sliderSection = "HeroHomeBlock-module_sliderSection__iKtyT"; 183const galleryErrorMessage = "HeroHomeBlock-module_galleryErrorMessage__ekw5e"; 184const styles$3 = { 185 heroBlock: heroBlock, 186 titleSection: titleSection, 187 title: title, 188 heroContent: heroContent$1, 189 gallerySection: gallerySection, 190 galleryScrollContainer: galleryScrollContainer, 191 sliderSection: sliderSection, 192 galleryErrorMessage: galleryErrorMessage 193}; 194 195var _tmpl$$3 = /* @__PURE__ */ template(`<div>`), _tmpl$2$2 = /* @__PURE__ */ template(`<div><div><p>Sender konnten nicht geladen werden`), _tmpl$3$1 = /* @__PURE__ */ template(`<div><div>`), _tmpl$4$1 = /* @__PURE__ */ template(`<div><!$><!/><div><!$><!/><!$><!/><!$><!/>`); 196function transformSliderData(slider) { 197 if (!slider.slides || slider.slides.length === 0) { 198 logger.warn("No slides found in slider"); 199 return []; 200 } 201 return slider.slides.map((slide) => { 202 const imageUrl = typeof slide.image === "string" ? slide.image : slide.image?.url; 203 const fullImageUrl = resolveMediaUrl(imageUrl); 204 return { 205 image: fullImageUrl || "", 206 headline: slide.headline, 207 subheadline: slide.subheadline, 208 // Link URL is pre-populated by CMS, just pass through with normalized type 209 link: slide.link ? { 210 type: slide.link.type === "none" ? "none" : slide.link.type === "custom" ? "custom" : "reference", 211 url: slide.link.url, 212 label: slide.link.label, 213 newTab: slide.link.newTab 214 } : void 0 215 }; 216 }); 217} 218function initializeAudioPlayer(channelLists) { 219 const mainPlayerLists = channelLists.filter((list) => list.inMainPlayer === true); 220 channelListsActions.setChannelLists(mainPlayerLists); 221 const allChannels = []; 222 for (const list of mainPlayerLists) { 223 if (!list.channels) continue; 224 for (const channel of list.channels) { 225 if (typeof channel !== "object" || channel === null) continue; 226 if (!allChannels.some((c) =>
226 c.id === channel.id)) { 227 allChannels.push(channel); 228 } 229 } 230 } 231 if (allChannels.length === 0) { 232 logger.warn("No channels found in hero block channel lists"); 233 return; 234 } 235 const playerChannels = allChannels.map(transformCMSChannelToPlayerChannel).filter((channel) => { 236 if (!hasAvailableStream(channel.streaming.streamUrls)) { 237 logger.warn(`Channel ${channel.identifier} has no stream URLs`); 238 return false; 239 } 240 return true; 241 }); 242 if (playerChannels.length === 0) { 243 logger.warn("No valid channels with streaming data in hero block"); 244 return; 245 } 246 audioPlayerActions.setCurrentPlaylist(playerChannels); 247 audioPlayerActions.setCurrentStream(playerChannels[0]); 248 audioPlayerActions.setPlayerColour(playerChannels[0]?.branding?.primaryColor || "var(--bg-player)"); 249 logger.info(`[HeroBlock] Set player playlist: ${playerChannels.length} channels`); 250} 251const HeroHomeBlock = (props) => { 252 const needsChannelListFetch = createMemo(() => !areChannelListsPopulated(props.data.channelLists)); 253 const needsSliderFetch = createMemo(() => props.data.slider && !isSliderPopulated(props.data.slider)); 254 const channelListIds = createMemo(() => extractIds(props.data.channelLists)); 255 const sliderId = createMemo(() => extractId(props.data.slider)); 256 const fetchedChannelLists = createAsync(async () => { 257 if (!needsChannelListFetch()) return []; 258 return getChannelListsByIdsQuery(channelListIds()); 259 }, { 260 deferStream: true 261 }); 262 const fetchedSlider = createAsync(async () => { 263 if (!needsSliderFetch()) return null; 264 return getSliderByIdQuery(sliderId()); 265 }, { 266 deferStream: true 267 }); 268 const channelListFetchError = createMemo(() => { 269 if (!needsChannelListFetch()) return false; 270 const ids = channelListIds(); 271 const fetched = fetchedChannelLists(); 272 return ids.length > 0 && fetched !== void 0 && fetched.length === 0; 273 }); 274 const channelLists = createMemo(() => { 275 if (needsChannelListFetch()) { 276 return fetchedChannelLists() ?? []; 277 } 278 if (!props.data.channelLists) return []; 279 return props.data.channelLists.filter((list) => typeof list === "object" && list !== null); 280 }); 281 const mainPlayerChannelLists = createMemo(() => channelLists().filter((list) => list.inMainPlayer === true)); 282 const sliderFetchError = createMemo(() => { 283 if (!needsSliderFetch()) return false; 284 const id = sliderId(); 285 const fetched = fetchedSlider(); 286 return id !== null && fetched !== void 0 && fetched === null; 287 }); 288 const slider = createMemo(() => { 289 if (needsSliderFetch()) { 290 return fetchedSlider() || null; 291 } 292 return isSliderPopulated(props.data.slider) ? props.data.slider : null; 293 }); 294 const galleryItems = createMemo(() => mainPlayerChannelLists().map((list) => ({ 295 id: list.id, 296 title: list.title || list.name, 297 channels: list.channels || [] 298 }))); 299 const sliderData = createMemo(() => { 300 const sliderBlock = slider(); 301 if (!sliderBlock) return []; 302 return transformSliderData(sliderBlock); 303 }); 304 let audioPlayerInitialized = false; 305 createEffect(() => { 306 const lists = channelLists(); 307 if (lists.length > 0 && !audioPlayerInitialized) { 308 audioPlayerInitialized = true; 309 initializeAudioPlayer(lists); 310 } 311 }); 312 createEffect(() => { 313 if (channelListFetchError()) { 314 logger.error("[HeroHomeBlock] Channel lists fetch failed - gallery will be empty"); 315 } 316 if (sliderFetchError()) { 317 logger.error("[HeroHomeBlock] Slider fetch failed - slider will be hidden"); 318 } 319 }); 320 return (() => { 321 var _el$ = getNextElement(_tmpl$4$1), _el$13 = _el$.firstChild, [_el$14, _co$4] = getNextMarker(_el$13.nextSibling), _el$3 = _el$14.nextSibling, _el$9 = _el$3.firstChild, [_el$0, _co$] = getNextMarker(_el$9.nextSibling), _el$1 = _el$0.nextSibling, [_el$10, _co$2] = getNextMarker(_el$1.nextSibling), _el$11 = _el$10.nextSibling, [_el$12, _co$3] = getNextMarker(_el$11.nextSibling); 322 insert(_el$, createComponent(Show, { 323 get when() { 324 return props.data.homeTitle; 325 }, 326 get children() { 327 var _el$2 = getNextElement(_tmpl$$3); 328 insert(_el$2, createComponent(Heading, { 329 variant: "pageTitle", 330 as: "h1", 331 get ["class"]() { 332 return styles$3.title; 333 }, 334 get children() { 335 return props.data.homeTitle; 336 } 337 })); 338 createRenderEffect(() => className(_el$2, styles$3.titleSection)); 339 return _el$2; 340 } 341 }), _el$14, _co$4); 342 insert(_el$3, createComponent(Show, { 343 get when() { 344 return channelListFetchError(); 345 }, 346 get children() { 347 var _el$4 = getNextElement(_tmpl$2$2), _el$5 = _el$4.firstChild; 348 createRenderEffect((_p$) => { 349 var _v$ = styles$3.gallerySection, _v$2 = styles$3.galleryErrorMessage; 350 _v$ !== _p$.e && className(_el$4, _p$.e = _v$); 351 _v$2 !== _p$.t && className(_el$5, _p$.t = _v$2); 352 return _p$; 353 }, { 354 e: void 0, 355 t: void 0 356 }); 357 return _el$4; 358 } 359 }), _el$0, _co$); 360 insert(_el$3, createComponent(Show, { 361 get when() { 362 return memo(() => !!!channelListFetchError())() && galleryItems().length > 0; 363 }, 364 get children() { 365 var _el$6 = getNextElement(_tmpl$3$1), _el$7 = _el$6.firstChild; 366 insert(_el$7, createComponent(ChannelGallery, { 367 get items() { 368 return galleryItems(); 369 } 370 })); 371 createRenderEffect((_p$) => { 372 var _v$3 = styles$3.gallerySection, _v$4 = styles$3.galleryScrollContainer; 373 _v$3 !== _p$.e && className(_el$6, _p$.e = _v$3); 374 _v$4 !== _p$.t && className(_el$7, _p$.t = _v$4); 375 return _p$; 376 }, { 377 e: void 0, 378 t: void 0 379 }); 380 return _el$6; 381 } 382 }), _el$10, _co$2); 383 insert(_el$3, createComponent(Show, { 384 get when() { 385 return sliderData().length > 0; 386 }, 387 get children() { 388 var _el$8 = getNextElement(_tmpl$$3); 389 insert(_el$8, createComponent(Slider, { 390 get slides() { 391 return sliderData(); 392 }, 393 get autoPlay() { 394 return slider()?.autoPlay ?? true; 395 }, 396 get interval() { 397 return slider()?.interval ?? 5e3; 398 }, 399 get showIndicators() { 400 return slider()?.showDots ?? true; 401 }, 402 get showArrows() { 403 return slider()?.showArrows ?? false; 404 } 405 })); 406 createRenderEffect(() => className(_el$8, styles$3.sliderSection)); 407 return _el$8; 408 } 409 }), _el$12, _co$3); 410 createRenderEffect((_p$) => { 411 var _v$5 = styles$3.heroBlock, _v$6 = styles$3.heroContent; 412 _v$5 !== _p$.e && className(_el$, _p$.e = _v$5); 413 _v$6 !== _p$.t && className(_el$3, _p$.t = _v$6); 414 return _p$; 415 }, {
416 e: void 0, 417 t: void 0 418 }); 419 return _el$; 420 })(); 421}; 422 423const heroContent = "HeroContentBlock-module_heroContent__ccb9o"; 424const header = "HeroContentBlock-module_header__s9XR9"; 425const overlineRow = "HeroContentBlock-module_overlineRow__1fWwp"; 426const overlineSeparator = "HeroContentBlock-module_overlineSeparator__zSFWG"; 427const podcastLink = "HeroContentBlock-module_podcastLink__ILNYJ"; 428const subtitle = "HeroContentBlock-module_subtitle__5w5ws"; 429const card = "HeroContentBlock-module_card__J1Lyj"; 430const cardContent = "HeroContentBlock-module_cardContent__iYXiy"; 431const contentColumn = "HeroContentBlock-module_contentColumn__f9r4q"; 432const episodeMeta = "HeroContentBlock-module_episodeMeta__jMuvt"; 433const episodeNumber = "HeroContentBlock-module_episodeNumber__E3Xqc"; 434const metaItem = "HeroContentBlock-module_metaItem__XyyzB"; 435const publishDate = "HeroContentBlock-module_publishDate__hSF8-"; 436const richContent = "HeroContentBlock-module_richContent__Cj7RV"; 437const coverWrapper = "HeroContentBlock-module_coverWrapper__vOjqr"; 438const coverImage = "HeroContentBlock-module_coverImage__1IdGK"; 439const styles$2 = { 440 heroContent: heroContent, 441 header: header, 442 overlineRow: overlineRow, 443 overlineSeparator: overlineSeparator, 444 podcastLink: podcastLink, 445 subtitle: subtitle, 446 card: card, 447 cardContent: cardContent, 448 contentColumn: contentColumn, 449 episodeMeta: episodeMeta, 450 episodeNumber: episodeNumber, 451 metaItem: metaItem, 452 publishDate: publishDate, 453 richContent: richContent, 454 coverWrapper: coverWrapper, 455 coverImage: coverImage 456}; 457 458var _tmpl$$2 = /* @__PURE__ */ template(`<span>|`), _tmpl$2$1 = /* @__PURE__ */ template(`<div><!$><!/><!$><!/>`), _tmpl$3 = /* @__PURE__ */ template(`<span>`), _tmpl$4 = /* @__PURE__ */ template(`<div><!$><!/><!$><!/><!$><!/>`), _tmpl$5 = /* @__PURE__ */ template(`<p>`), _tmpl$6 = /* @__PURE__ */ template(`<div>`), _tmpl$7 = /* @__PURE__ */ template(`<div><div><img loading=eager width=460 height=460></div><!$><!/>`, true, false, false), _tmpl$8 = /* @__PURE__ */ template(`<div><div><!$><!/><!$><!/><!$><!/></div><div><div><div><!$><!/><!$><!/><!$><!/></div><!$><!/>`); 459const HeroContentBlock = (props) => { 460 const episodeLabel = () => { 461 if (props.type !== "podcast-episode") return ""; 462 const parts = []; 463 if (props.seasonNumber) parts.push(`S${props.seasonNumber}`); 464 if (props.episodeNumber) parts.push(`E${props.episodeNumber}`); 465 return parts.join(" "); 466 }; 467 const overlineText = () => { 468 switch (props.type) { 469 case "podcast": 470 return "Podcast"; 471 case "podcast-episode": 472 return "Episode"; 473 default: 474 return null; 475 } 476 }; 477 const shareAriaLabel = () => { 478 switch (props.type) { 479 case "article": 480 return "Artikel teilen"; 481 case "podcast": 482 return "Podcast teilen"; 483 case "podcast-episode": 484 return "Episode teilen"; 485 default: 486 return "Teilen"; 487 } 488 }; 489 return (() => { 490 var _el$ = getNextElement(_tmpl$8), _el$2 = _el$.firstChild, _el$9 = _el$2.firstChild, [_el$0, _co$3] = getNextMarker(_el$9.nextSibling), _el$1 = _el$0.nextSibling, [_el$10, _co$4] = getNextMarker(_el$1.nextSibling), _el$11 = _el$10.nextSibling, [_el$12, _co$5] = getNextMarker(_el$11.nextSibling), _el$13 = _el$2.nextSibling, _el$14 = _el$13.firstChild, _el$15 = _el$14.firstChild, _el$28 = _el$15.firstChild, [_el$29, _co$9] = getNextMarker(_el$28.nextSibling), _el$30 = _el$29.nextSibling, [_el$31, _co$0] = getNextMarker(_el$30.nextSibling), _el$32 = _el$31.nextSibling, [_el$33, _co$1] = getNextMarker(_el$32.nextSibling), _el$39 = _el$15.nextSibling, [_el$40, _co$11] = getNextMarker(_el$39.nextSibling); 491 insert(_el$2, createComponent(Show, { 492 get when() { 493 return overlineText(); 494 }, 495 get children() { 496 var _el$3 = getNextElement(_tmpl$2$1), _el$5 = _el$3.firstChild, [_el$6, _co$] = getNextMarker(_el$5.nextSibling), _el$7 = _el$6.nextSibling, [_el$8, _co$2] = getNextMarker(_el$7.nextSibling); 497 insert(_el$3, createComponent(Text, { 498 variant: "heroOverline", 499 get children() { 500 return overlineText(); 501 } 502 }), _el$6, _co$); 503 insert(_el$3, createComponent(Show, { 504 get when() { 505 return memo(() => !!(props.type === "podcast-episode" && props.podcastTitle))() && props.podcastSlug; 506 }, 507 get children() { 508 return [(() => { 509 var _el$4 = getNextElement(_tmpl$$2); 510 createRenderEffect(() => className(_el$4, styles$2.overlineSeparator)); 511 return _el$4; 512 })(), createComponent(A, { 513 get href() { 514 return `/podcast/${props.podcastSlug}`; 515 }, 516 get ["class"]() { 517 return styles$2.podcastLink; 518 }, 519 get children() { 520 return props.podcastTitle; 521 } 522 })]; 523 } 524 }), _el$8, _co$2); 525 createRenderEffect(() => className(_el$3, styles$2.overlineRow)); 526 return _el$3; 527 } 528 }), _el$0, _co$3); 529 insert(_el$2, createComponent(Heading, { 530 variant: "pageTitle", 531 get children() { 532 return props.title; 533 } 534 }), _el$10, _co$4); 535 insert(_el$2, createComponent(Show, { 536 get when() { 537 return props.subtitle; 538 }, 539 get children() { 540 return createComponent(Heading, { 541 variant: "h2", 542 get ["class"]() { 543 return styles$2.subtitle; 544 }, 545 get children() { 546 return props.subtitle; 547 } 548 }); 549 } 550 }), _el$12, _co$5); 551 insert(_el$15, createComponent(Show, { 552 get when() { 553 return props.type === "podcast-episode"; 554 }, 555 get children() { 556 var _el$16 = getNextElement(_tmpl$4), _el$20 = _el$16.firstChild, [_el$21, _co$6] = getNextMarker(_el$20.nextSibling), _el$22 = _el$21.nextSibling, [_el$23, _co$7] = getNextMarker(_el$22.nextSibling), _el$24 = _el$23.nextSibling, [_el$25, _co$8] = getNextMarker(_el$24.nextSibling); 557 insert(_el$16, createComponent(Show, { 558 get when() { 559 return episodeLabel(); 560 }, 561 get children() { 562 var _el$17 = getNextElement(_tmpl$3); 563 insert(_el$17, episodeLabel); 564 createRenderEffect(() => className(_el$17, styles$2.episodeNumber)); 565 return _el$17; 566 } 567 }), _el$21, _co$6); 568 insert(_el$16, createComponent(Show, { 569 get when() { 570 return props.duration; 571 }, 572 get children() { 573 var _el$18 = getNextElement(_tmpl$3); 574 insert(_el$18, () => props.duration); 575 createRenderEffect(() => className(_el$18, styles$2.metaItem)); 576 return _el$18; 577 } 578 }), _el$23, _co$7); 579 insert(_el$16, createComponent(Show, { 580 get when() { 581 return props.publishDate; 582 }, 583 get children() { 584 var _el$19 = getNextElement(_tmpl$3); 585 insert(_el$19, () => props.publishDate); 586 createRenderEffect(() => className(_el$19, styles$2.metaItem)); 587 return _el$19; 588 } 589 }), _el$25, _co$8); 590 createRenderEffect(() => className(_el$16, styles$2.episodeMeta)); 591 return _el$16; 592 } 593 }), _el$29, _co$9); 594 insert(_el$15, createComponent(Show, { 595 get when() { 596 return memo(() => props.type === "article")() && props.publishDate; 597 }, 598 get children() { 599 var _el$26 = getNextElement(_tmpl$5); 600 insert(_el$26, () => props.publishDate); 601 createRenderEffect(() => className(_el$26, styles$2.publishDate)); 602 return _el$26; 603 } 604 }), _el$31, _co$0); 605 insert(_el$15, createComponent(Show, { 606 get when() { 607 return props.content; 608 }, 609 get children() { 610 var _el$27 = getNextElement(_tmpl$6); 611 insert(_el$27, createComponent(RichTextRenderer, { 612 get content() { 613 return props.content; 614 }, 615 variant: "hero" 616 })); 617 createRenderEffect(() => className(_el$27, styles$2.richContent)); 618 return _el$27; 619 } 620 }), _el$33, _co$1); 621 insert(_el$14, createComponent(Show, { 622 get when() { 623 return props.imageUrl; 624 }, 625 get children() { 626 var _el$34 = getNextElement(_tmpl$7), _el$35 = _el$34.firstChild, _el$36 = _el$35.firstChild, _el$37 = _el$35.nextSibling, [_el$38, _c
626o$10] = getNextMarker(_el$37.nextSibling); 627 insert(_el$34, createComponent(Show, { 628 get when() { 629 return props.showShare !== false; 630 }, 631 get children() { 632 return createComponent(ShareButton, { 633 get onClick() { 634 return props.onShare; 635 }, 636 get ariaLabel() { 637 return shareAriaLabel(); 638 } 639 }); 640 } 641 }), _el$38, _co$10); 642 createRenderEffect((_p$) => { 643 var _v$ = styles$2.coverWrapper, _v$2 = styles$2.coverImage, _v$3 = props.imageUrl, _v$4 = props.imageAlt || props.title; 644 _v$ !== _p$.e && className(_el$34, _p$.e = _v$); 645 _v$2 !== _p$.t && className(_el$35, _p$.t = _v$2); 646 _v$3 !== _p$.a && setAttribute(_el$36, "src", _p$.a = _v$3); 647 _v$4 !== _p$.o && setAttribute(_el$36, "alt", _p$.o = _v$4); 648 return _p$; 649 }, { 650 e: void 0, 651 t: void 0, 652 a: void 0, 653 o: void 0 654 }); 655 return _el$34; 656 } 657 }), _el$40, _co$11); 658 createRenderEffect((_p$) => { 659 var _v$5 = styles$2.heroContent, _v$6 = styles$2.header, _v$7 = styles$2.card, _v$8 = styles$2.cardContent, _v$9 = styles$2.contentColumn; 660 _v$5 !== _p$.e && className(_el$, _p$.e = _v$5); 661 _v$6 !== _p$.t && className(_el$2, _p$.t = _v$6); 662 _v$7 !== _p$.a && className(_el$13, _p$.a = _v$7); 663 _v$8 !== _p$.o && className(_el$14, _p$.o = _v$8); 664 _v$9 !== _p$.i && className(_el$15, _p$.i = _v$9); 665 return _p$; 666 }, { 667 e: void 0, 668 t: void 0, 669 a: void 0, 670 o: void 0, 671 i: void 0 672 }); 673 return _el$; 674 })(); 675}; 676 677const LOG_PREFIX$1 = "[transformSliderSlides]"; 678function getImageUrl(image) { 679 return resolveMediaUrl(image) || ""; 680} 681function normalizeLinkType(linkType) { 682 if (linkType === "none") return "none"; 683 if (linkType === "custom") return "custom"; 684 return "reference"; 685} 686function transformSliderSlides(cmsSlides) { 687 if (!cmsSlides || !Array.isArray(cmsSlides)) { 688 logger.warn(`${LOG_PREFIX$1} no slides provided`); 689 return []; 690 } 691 return cmsSlides.map((slide) => { 692 let linkUrl; 693 let linkLabel = slide.link?.label; 694 const linkType = slide.link?.type; 695 if (linkType === "custom") { 696 linkUrl = slide.link?.url; 697 } else if (linkType === "reference") { 698 if (slide.link?.reference && typeof slide.link.reference === "object") { 699 const ref = slide.link.reference; 700 const refValue = typeof ref.value === "object" ? ref.value : null;
701 if (refValue?.slug || refValue?.identifier) { 702 switch (ref.relationTo) { 703 case "pages": 704 linkUrl = refValue.slug === "home" ? "/" : `/${refValue.slug}`; 705 break; 706 case "articles": 707 linkUrl = `/artikel/${refValue.slug}`; 708 break; 709 case "podcasts": 710 linkUrl = `/podcast/${refValue.slug}`; 711 break; 712 case "channel-pages": 713 const channelPrefix = refValue.pageType === "stream" || refValue.channelType === "stream" ? "stream" : "sender"; 714 linkUrl = `/${channelPrefix}/${refValue.identifier || refValue.slug}`; 715 break; 716 default: 717 logger.warn(`${LOG_PREFIX$1} unknown reference relationTo: ${ref.relationTo}`); 718 } 719 } 720 if (!linkLabel && refValue && "title" in refValue) { 721 linkLabel = refValue.title; 722 } 723 } 724 } else if (linkType && linkType !== "none") { 725 linkUrl = slide.link?.url; 726 } 727 return { 728 image: getImageUrl(slide.image), 729 headline: slide.headline, 730 subheadline: slide.subheadline, 731 link: slide.link ? { 732 type: normalizeLinkType(linkType), 733 url: linkUrl, 734 label: linkLabel, 735 newTab: slide.link.newTab 736 } : void 0 737 }; 738 }); 739} 740 741const sliderBlockWrapper = "SliderBlockRenderer-module_sliderBlockWrapper__DMsaz"; 742const sliderInner = "SliderBlockRenderer-module_sliderInner__xL88P"; 743const styles$1 = { 744 sliderBlockWrapper: sliderBlockWrapper, 745 sliderInner: sliderInner 746}; 747 748var _tmpl$$1 = /* @__PURE__ */ template(`<div><div>`); 749const LOG_PREFIX = "[SliderBlockRenderer]"; 750function isCollectionId(id) { 751 if (id === void 0 || id === null) return false; 752 if (typeof id === "number") return true; 753 return /^\d+$/.test(id); 754} 755const SliderBlockRenderer = (props) => { 756 const needsFetch = createMemo(() => !isSliderPopulated(props.slider)); 757 const fetchedSlider = createAsync(async () => { 758 if (!needsFetch()) return null; 759 const id = props.slider.id; 760 if (!isCollectionId(id)) { 761 logger.warn(`${LOG_PREFIX} slides unpopulated but id ${String(id)} is not a sliders collection id; skipping refetch`); 762 return null; 763 } 764 return getSliderByIdQuery(String(id)); 765 }, { 766 deferStream: true 767 }); 768 const resolved = createMemo(() => { 769 if (!needsFetch()) return props.slider; 770 return fetchedSlider() ?? null; 771 }); 772 return createComponent(Show, { 773 get when() { 774 return resolved(); 775 }, 776 children: (getSlider) => (() => { 777 var _el$ = getNextElement(_tmpl$$1), _el$2 = _el$.firstChild; 778 insert(_el$2, createComponent(Slider, { 779 get slides() { 780 return transformSliderSlides(getSlider().slides); 781 }, 782 get autoPlay() { 783 return getSlider().autoPlay; 784 }, 785 get interval() { 786 return getSlider().interval; 787 }, 788 get showIndicators() { 789 return getSlider().showDots; 790 }, 791 get showArrows() { 792 return getSlider().showArrows; 793 } 794 })); 795 createRenderEffect((_p$) => { 796 var _v$ = styles$1.sliderBlockWrapper, _v$2 = styles$1.sliderInner; 797 _v$ !== _p$.e && className(_el$, _p$.e = _v$); 798 _v$2 !== _p$.t && className(_el$2, _p$.t = _v$2); 799 return _p$; 800 }, { 801 e: void 0, 802 t: void 0 803 }); 804 return _el$; 805 })() 806 }); 807}; 808 809const contentContainer = "ContentRenderer-module_contentContainer__Rj9RJ"; 810const anchorTarget = "ContentRenderer-module_anchorTarget__rzahq"; 811const anchorTargetLead = "ContentRenderer-module_anchorTargetLead__TsL7f"; 812const anchorLink = "ContentRenderer-module_anchorLink__RmLBP"; 813const styles = { 814 contentContainer: contentContainer, 815 anchorTarget: anchorTarget, 816 anchorTargetLead: anchorTargetLead, 817 anchorLink: anchorLink 818}; 819 820var _tmpl$ = /* @__PURE__ */ template(`<div>`), _tmpl$2 = /* @__PURE__ */ template(`<div><!$><!/><!$><!/>`); 821function getItemAnchor(item) { 822 if (item?.type === "block") { 823 const anchor = item.block?.[0]?.anchor; 824 return anchor || void 0; 825 } 826 if (item?.type === "reference") { 827 const value = item.contentReference?.value; 828 const anchor = typeof value === "object" ? value.anchor : void 0; 829 return anchor || void 0; 830 } 831 return void 0; 832} 833function getItemShowAnchorLink(item) { 834 if (item?.type === "block") { 835 return item.block?.[0]?.showAnchorLink !== false; 836 } 837 return true; 838} 839function renderInlineBlock(block, ctx) { 840 const { 841 currentStationId, 842 currentArticleId, 843 stationColor, 844 channelIdentifier, 845 channelId, 846 channelAccentColor, 847 articleContext, 848 podcastContext, 849 episodeContext 850 } = ctx; 851 if (!block || !block.blockType) {
852 logger.warn("[ContentRenderer] Received invalid block:", block); 853 return null; 854 } 855 switch (block.blockType) { 856 case "audioPlayer": 857 return createComponent(AudioPlayerBlock, mergeProps(block, { 858 backgroundColor: stationColor 859 })); 860 case "audioBlock": 861 return createComponent(AudioPlayerBlock, mergeProps(block, { 862 backgroundColor: stationColor, 863 get podcastSlug() { 864 return podcastContext?.slug; 865 } 866 })); 867 case "richtext": 868 return createComponent(RichTextBlock, block); 869 case "formBlock": 870 return createComponent(FormBlock, block); 871 case "socialHotline": 872 return createComponent(SocialHotlineBlock, { 873 block 874 }); 875 case "channelBlock": 876 return createComponent(ChannelBlockRenderer, block); 877 case "cardGridBlock": 878 return createComponent(CardGridBlockRenderer, block); 879 case "emojiCardBlock": 880 return createComponent(EmojiCardBlock, { 881 block 882 }); 883 case "stationShowsBlock": 884 return createComponent(StationShowsBlockRenderer, mergeProps(block, { 885 channelId 886 })); 887 case "stationHostsBlock": 888 return createComponent(StationHostsBlockRenderer, mergeProps(block, { 889 channelId, 890 channelAccentColor 891 })); 892 case "articleBlock": { 893 if (!block.items || !Array.isArray(block.items)) { 894 logger.warn("[ContentRenderer] articleBlock has no items"); 895 return null; 896 } 897 return createComponent(ArticleBlockRenderer, { 898 block, 899 currentStationId, 900 currentArticleId 901 }); 902 } 903 case "slider": 904 return createComponent(SliderBlockRenderer, { 905 slider: block 906 }); 907 case "podcastEpisodeListBlock": { 908 const parentPodcast = typeof block.parentPodcast === "object" ? block.parentPodcast : void 0; 909 return createComponent(PodcastEpisodeListBlock, { 910 get episodes() { 911 return block.episodes || []; 912 }, 913 get headerText() { 914 return block.headerText; 915 }, 916 get initialLimit() { 917 return block.initialLimit; 918 }, 919 get showPlayButton() { 920 return block.showPlayButton; 921 }, 922 get showLoadMore() { 923 return block.showLoadMore; 924 }, 925 get showMoreText() { 926 return block.showMoreText; 927 }, 928 get sortOrder() { 929 return block.sortOrder; 930 }, 931 get maxEpisodes() { 932 return block.maxEpisodes; 933 }, 934 get podcastSlug() { 935 return parentPodcast?.slug; 936 }, 937 parentPodcast, 938 backgroundColor: stationColor 939 }); 940 } 941 case "heroBlock": 942 return renderHeroByType(block, articleContext, podcastContext, episodeContext); 943 case "textAndMediaCTA": 944 return createComponent(TextAndMediaCTABlock, block); 945 case "playlistBlock": 946 return createComponent(PlaylistBlock, { 947 channelIdentifier: channelIdentifier || "", 948 get title() { 949 return block.title; 950 }, 951 get showTitle() { 952 return block.showTitle; 953 }, 954 get maxItems() { 955 return block.maxItems; 956 }, 957 get showSearchLink() { 958 return block.showSearchLink; 959 }, 960 get showMoreButton() { 961 return block.showMoreButton; 962 }, 963 get searchLinkUrl() { 964 return block.searchLinkUrl; 965 }, 966 accentColor: channelAccentColor 967 }); 968 default: 969 logger.warn(`[ContentRenderer] Unknown block type:`, block); 970 return null; 971 } 972} 973function transformHosts(hosts) { 974 if (!hosts || !Array.isArray(hosts)) return []; 975 return hosts.filter((host) => typeof host === "object" && host !== null).map((host) => ({ 976 name: host.name, 977 imageUrl: resolveMediaUrl(host.image) || void 0 978 })); 979} 980function renderHeroByType(hero, articleContext, podcastContext, episodeContext) { 981 switch (hero.type) { 982 case "home": 983 return createComponent(HeroHomeBlock, { 984 data: hero 985 }); 986 case "page": 987 return createComponent(HeroContentBlock, { 988 type: "article", 989 get title() { 990 return hero.title || ""; 991 }, 992 get subtitle() { 993 return hero.subtitle || hero.description; 994 }, 995 get content() { 996 return hero.content; 997 }, 998 get imageUrl() { 999 return resolveMediaUrl(hero.image) || void 0; 1000 }, 1001 get publishDate() { 1002 return articleContext?.publishDate; 1003 }, 1004 get backgroundColor() { 1005 return articleContext?.backgroundColor; 1006 }, 1007 get showShare() { 1008 return articleContext?.showShare; 1009 }, 1010 get onShare() { 1011 return articleContext?.onShare; 1012 } 1013 }); 1014 case "article": 1015 return createComponent(HeroContentBlock, { 1016 type: "article", 1017 get title() { 1018 return hero.title || ""; 1019 }, 1020 get subtitle() { 1021 return hero.subtitle; 1022 }, 1023 get content() { 1024 return hero.content; 1025 }, 1026 get imageUrl() { 1027 return resolveMediaUrl(hero.image) || void 0; 1028 }, 1029 get publishDate() { 1030 return articleContext?.publishDate; 1031 }, 1032 get backgroundColor() { 1033 return articleContext?.backgroundColor; 1034 }, 1035 get showShare() { 1036 return articleContext?.showShare; 1037 }, 1038 get onShare() { 1039 return articleContext?.onShare; 1040 } 1041 }); 1042 case "podcast": 1043 return createComponent(HeroContentBlock, { 1044 type: "podcast", 1045 get title() { 1046 return hero.title || podcastContext?.title || ""; 1047 }, 1048 get subtitle() { 1049 return hero.subtitle; 1050 }, 1051 get content() { 1052 return hero.content; 1053 }, 1054 get imageUrl() { 1055 return resolveMediaUrl(hero.image) || void 0; 1056 }, 1057 get hosts() { 1058 return transformHosts(hero.hosts); 1059 }, 1060 get backgroundColor() { 1061 return podcastContext?.backgroundColor; 1062 }, 1063 get showShare() { 1064 return podcastContext?.showShare; 1065 }, 1066 get onShare() { 1067 return podcastContext?.onShare; 1068 } 1069 }); 1070 case "podcast-episode": 1071 return createComponent(HeroContentBlock, { 1072 type: "podcast-episode", 1073 get title() { 1074 return hero.title || ""; 1075 }, 1076 get subtitle() { 1077 return hero.subtitle; 1078 }, 1079 get content() { 1080 return hero.content; 1081 }, 1082 get imageUrl() { 1083 return resolveMediaUrl(hero.image) || void 0; 1084 }, 1085 get podcastTitle() { 1086 return episodeContext?.podcastTitle; 1087 }, 1088 get podcastSlug() { 1089 return episodeContext?.podcastSlug; 1090 }, 1091 get episodeNumber() { 1092 return episodeContext?.episodeNumber; 1093 }, 1094 get seasonNumber() { 1095 return episodeContext?.seasonNumber; 1096 }, 1097 get duration() { 1098 return episodeContext?.duration; 1099 }, 1100 get publishDate() { 1101 return episodeContext?.publishDate; 1102 }, 1103 get backgroundColor() { 1104 return episodeContext?.backgroundColor; 1105 }, 1106 get showShare() { 1107 return episodeContext?.showShare; 1108 }, 1109 get onShare() { 1110 return episodeContext?.onShare; 1111 } 1112 }); 1113 default: 1114 logger.warn(`[ContentRenderer] Unknown hero type:`, hero); 1115 return null; 1116 } 1117} 1118function renderReference(relationTo, value) { 1119 if (!value) { 1120 logger.warn(`[ContentRenderer] Reference value is null/undefined for: ${relationTo}`); 1121 return null; 1122 } 1123 if (typeof value === "string") { 1124 logger.warn(`[ContentRenderer] Reference not populated: ${relationTo}:${value}`); 1125 return null; 1126 } 1127 switch (relationTo) { 1128 // ======================================== 1129 // SLIDERS 1130 // ======================================== 1131 case "slider-blocks": 1132 case "sliders": 1133 return createComponent(SliderBlockRenderer, { 1134 slider: value 1135 }); 1136 // ======================================== 1137 // CONTENT BLOCKS 1138 // ======================================== 1139 case "content-blocks": { 1140 const contentBlock = value; 1141 return createComponent(TextAndMediaCTABlock, contentBlock); 1142 } 1143 default: 1144 logger.warn(`[ContentRenderer] Unknown reference type: ${relationTo}`, value); 1145 return null; 1146 } 1147} 1148function renderContentItem(item, ctx) { 1149 if (!item) { 1150 logger.warn("[ContentRenderer] Received null/undefined content item"); 1151 return null; 1152 } 1153 if (item.type === "block" && item.block && item.block.length > 0) { 1154 return renderInlineBlock(item.block[0], ctx); 1155 } 1156 if (item.type === "reference" && item.contentReference) { 1157 const { 1158 relationTo, 1159 value 1160 } = item.contentReference; 1161 return renderReference(relationTo, value); 1162 } 1163 logger.warn("[ContentRenderer] Invalid content item:", item); 1164 return null; 1165} 1166const ContentRenderer = (props) => { 1167 const ctx = { 1168 currentStationId: props.currentStationId, 1169 currentArticleId: props.currentArticleId, 1170 stationColor: props.stationColor, 1171 channelIdentifier: props.channelIdentifier, 1172 channelId: props.channelId, 1173 channelAccentColor: props.channelAccentColor, 1174 articleContext: props.articleContext, 1175 podcastContext: props.podcastContext, 1176 episodeContext: props.episodeContext 1177 }; 1178 return createComponent(Show, { 1179 get when() { 1180 return memo(() => !!props.items)() && props.items.length > 0; 1181 }, 1182 get children() { 1183 var _el$ = getNextElement(_tmpl$); 1184 insert(_el$, createComponent(For, { 1185 get each() { 1186 return props.items; 1187 }, 1188 children: (item, index) => { 1189 const anchor = getItemAnchor(item); 1190 const itemType = item?.type === "reference" ? item.contentReference?.relationTo : item?.block?.[0]?.blockType; 1191 const rendered = createComponent(ErrorBoundary, { 1192 fallback: (err) => createComponent(BlockErrorFallback, { 1193 error: err, 1194 blockType: itemType 1195 }), 1196 get children() { 1197 return renderContentItem(item, ctx); 1198 } 1199 }); 1200 if (!anchor) return rendered; 1201 return (() => { 1202 var _el$2 = getNextElement(_tmpl$2), _el$3 = _el$2.firstChild, [_el$4, _co$] = getNextMarker(_el$3.nextSibling), _el$5 = _el$4.nextSibling, [_el$6, _co$2] = getNextMarker(_el$5.nextSibling);
1203 setAttribute(_el$2, "id", anchor); 1204 insert(_el$2, createComponent(Show, { 1205 get when() { 1206 return getItemShowAnchorLink(item); 1207 }, 1208 get children() { 1209 return createComponent(AnchorLink, { 1210 anchor, 1211 get ["class"]() { 1212 return styles.anchorLink; 1213 } 1214 }); 1215 } 1216 }), _el$4, _co$); 1217 insert(_el$2, rendered, _el$6, _co$2); 1218 createRenderEffect((_p$) => { 1219 var _v$ = styles.anchorTarget, _v$2 = { 1220 [styles.anchorTargetLead]: index() === 0 1221 }; 1222 _v$ !== _p$.e && className(_el$2, _p$.e = _v$); 1223 _p$.t = classList(_el$2, _v$2, _p$.t); 1224 return _p$; 1225 }, { 1226 e: void 0, 1227 t: void 0 1228 }); 1229 return _el$2; 1230 })(); 1231 } 1232 })); 1233 createRenderEffect(() => className(_el$, props.class || styles.contentContainer)); 1234 return _el$; 1235 } 1236 }); 1237}; 1238 1239export { ContentRenderer as C }; 1240//# sourceMappingURL=ContentRenderer-CQRyK-so.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.