92 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // @ts-check
 | |
| /// <reference path="./types.d.ts"/>
 | |
| 
 | |
| import { h, html, render } from "https://esm.sh/htm/preact";
 | |
| import { createContext, Fragment } from 'https://esm.sh/preact';
 | |
| import { useReducer, useState, useEffect, useLayoutEffect, useMemo, useRef } from 'https://esm.sh/preact/hooks';
 | |
| 
 | |
| /** @type {(props:{channel:string, interval:number})=>any} */
 | |
| const App = props =>
 | |
| {
 | |
|     /** @type {Boxcast.StateBinding<Array<Boxcast.Broadcast>>} */
 | |
|     const [ListGet, ListSet] = useState([]);
 | |
| 
 | |
|     /** @type {Boxcast.StateBinding<string>} */
 | |
|     const Selected = useState("");
 | |
| 
 | |
|     /** @type {Boxcast.StateBinding<string>} */
 | |
|     const [LiveGet, LiveSet] = useState("");
 | |
| 
 | |
|     /** @type {(item:Boxcast.Broadcast)=>boolean} */
 | |
|     const Iterator = (item) => item.timeframe == "current" || item.timeframe == "preroll";
 | |
| 
 | |
|     /** @type {()=>Promise} */
 | |
|     const Ping = async () =>
 | |
|     {
 | |
|         const response = await fetch(`https://rest.boxcast.com/channels/${props.channel}/broadcasts?s=starts_at&l=1000`);
 | |
|         const json = await response.json();
 | |
|         ListSet(json);
 | |
|         LiveSet(json.filter(Iterator)[0] || "");
 | |
|     };
 | |
| 
 | |
|     useEffect(()=>
 | |
|     {
 | |
|         Ping();
 | |
|         const timer = setInterval(Ping, props.interval);
 | |
|         return ()=>clearInterval(timer);
 | |
|     }
 | |
|     , []);
 | |
| 
 | |
|     useEffect(()=>{alert("New session is starting.")}, [LiveGet]);
 | |
| 
 | |
|     return html`
 | |
|     <div class="Playlist">
 | |
|     ${
 | |
|         ListGet.map(item => html`<${BroadcastItem} item=${item} active=${Selected} />`)
 | |
|     }
 | |
|     </div>
 | |
|     `;
 | |
| }
 | |
| 
 | |
| /** @type {(props:{item:Boxcast.Broadcast, active:Boxcast.StateBinding<string>})=>any} */
 | |
| const BroadcastItem = ({item, active}) =>
 | |
| {
 | |
|     const startDate = useMemo(()=>DateParse(item.starts_at), [item.starts_at]);
 | |
| 
 | |
|     return html`
 | |
|     <div key=${item.id} onClick=${()=>active[1](item.id)}>
 | |
|         <span>${startDate.Month} ${startDate.Date}</span>
 | |
|         <strong>${item.name}</strong>
 | |
|         <span>${startDate.Hours}:${startDate.Minutes} ${startDate.M}</span>
 | |
|         ${
 | |
|             active[0] == item.id ? html`<dd>Active</dd>` : null
 | |
|         }
 | |
|         <p>${item.id}</p>
 | |
|     </div>
 | |
|     `;
 | |
| };
 | |
| 
 | |
| 
 | |
| /** @type {(inDate:string)=>Boxcast.Date} */
 | |
| const DateParse = (inDateString) =>
 | |
| {
 | |
|     let date = new Date(inDateString);
 | |
|     /** @type {Boxcast.Date} */
 | |
|     let obj = {
 | |
|         Zone: date.toString().match(/\(([A-Za-z\s].*)\)/),
 | |
|         Day: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][date.getDay()],
 | |
|         Month: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][date.getMonth()],
 | |
|         Date: date.getDate(),
 | |
|         Hours: date.getHours(),
 | |
|         Minutes: date.getMinutes(),
 | |
|     };
 | |
| 
 | |
|     obj.Zone = obj.Zone ? obj.Zone[1] : "local time";
 | |
|     obj.M = obj.Hours >= 12 ? "PM" : "AM";
 | |
|     obj.Hours %= 12;
 | |
|     if(obj.Hours == 0){ obj.Hours = 12; }
 | |
|     if(obj.Minutes < 10){ obj.Minutes = "0"+obj.Minutes; }
 | |
|     return obj;
 | |
| };
 | |
| 
 | |
| export default App; |