// Roulsen one-screen homepage — app const { useState, useEffect, useRef } = React; const { Eyebrow } = window.RoulsenDesignSystem_aea9bf; const { RL_TRACKS: TRACKS, RL_CITIES: CITIES } = window.RL_DATA; const RL_COLLABS = ['SHINee', 'Monsta X', "Girls' Generation", 'Red Velvet', '時代少年團 TNT', 'MIRROR', 'Timmy Trumpet', '王一博', '张靓颖', '李宇春']; const RL_CREDS_LEAD = ['160+ songs', '“Blackout”', 'Eurovision ’19']; const RL_CREDS_FULL = [...RL_CREDS_LEAD, ...RL_COLLABS].join(' · '); const RL_CREDS_CURATED = [...RL_CREDS_LEAD, 'SHINee', 'Monsta X', "Girls' Generation"].join(' · '); const RL_TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "comp": "Masthead", "mood": "Charcoal", "socials": "Right", "textLayout": "B", "logo": "Left", "wmScale": 1 }/*EDITMODE-END*/; /* ---------- Spotify mini-player ---------- Uses Spotify's IFrame API so selecting a track loads (and plays) it. Falls back to a plain embed iframe if the API doesn't load. */ function SpotifyPlayer({ trackId }) { const hostRef = useRef(null); const controllerRef = useRef(null); const [apiFailed, setApiFailed] = useState(false); const firstId = useRef(trackId); useEffect(() => { let cancelled = false; const timer = setTimeout(() => { if (!controllerRef.current) setApiFailed(true); }, 3500); function init(IFrameAPI) { if (cancelled || !hostRef.current || controllerRef.current) return; IFrameAPI.createController( hostRef.current, { uri: 'spotify:track:' + firstId.current, width: '100%', height: 80 }, (controller) => { controllerRef.current = controller; } ); } if (window.__spotifyIFrameAPI) { init(window.__spotifyIFrameAPI); } else { const prev = window.onSpotifyIframeApiReady; window.onSpotifyIframeApiReady = (IFrameAPI) => { window.__spotifyIFrameAPI = IFrameAPI; if (prev) prev(IFrameAPI); init(IFrameAPI); }; } return () => { cancelled = true; clearTimeout(timer); }; }, []); useEffect(() => { if (controllerRef.current && trackId !== firstId.current) { controllerRef.current.loadUri('spotify:track:' + trackId); controllerRef.current.play(); } }, [trackId]); return (
{RL_CREDS_CURATED}
{RL_CREDS_FULL}
)}