react + styled-components

This commit is contained in:
TreetopFlyer 2022-04-26 13:49:43 -04:00
parent ec2c8916e0
commit c54e398eb1

145
app.js
View File

@ -2,50 +2,76 @@
/// <reference path="./types.d.ts"/> /// <reference path="./types.d.ts"/>
import 'https://js.boxcast.com/v3.min.js'; import 'https://js.boxcast.com/v3.min.js';
import { h, html, render } from "https://esm.sh/htm/preact"; import { html } from "https://esm.sh/htm/react";
import { useReducer, useState, useEffect, useLayoutEffect, useMemo, useRef } from 'https://esm.sh/preact/hooks'; import styled, { css, keyframes } from 'https://esm.sh/styled-components';
import { createElement as h, useState, useEffect, useRef } from 'https://esm.sh/react';
import { createRoot } from "https://esm.sh/react-dom/client";
import State01 from "./testdata-01.json" assert { type: "json" }; import State01 from "./testdata-01.json" assert { type: "json" };
import State02 from "./testdata-02.json" assert { type: "json" }; import State02 from "./testdata-02.json" assert { type: "json" };
import State03 from "./testdata-03.json" assert { type: "json" }; import State03 from "./testdata-03.json" assert { type: "json" };
const Styles = const Styles =
{ {
Broadcast:
{
position: "relative",
display: "flex",
padding: "5px 0 5px 0",
},
Time:
{
width: "75px",
marginRight: "5px",
fontSize: "16px",
textAlign: "right",
},
Partition:
{
margin: "10px 0 0 0",
},
Pointer:
{
width: "75px",
},
Alert:
{
position: "fixed",
right: "20px",
bottom: "20px",
width: "300px",
height: "200px",
background: "#333",
borderRadius: "5px",
transition: "all 0.4s",
color: "#fff",
textAlign: "center",
}
}; };
const PlayerID = "boxcast-player"
const StyledRoot = styled.div`
.Partition
{
margin: 10px 0 0 0;
}
.Broadcast
{
position: relative;
display: flex;
padding: 5px 0 5px 0;
.Time
{
width: 75px;
margin-right: 5px;
font-size: 16px;
text-align: right;
}
.Pointer
{
width: 75px;
}
}
.Alert
{
position: fixed;
right: 20px;
bottom: -300px;
width: 300px;
height: 200px;
background: #333;
border-radius: 5px;
transition: bottom 0.4s;
color: #fff;
text-align: center;
&.Show
{
bottom: 20px;
}
.Close
{
display: inline-block;
position: absolute;
padding: 5px 10px 5px 10px;
border-radius: 20px;
top: -15px;
right: 10px;
background: #000000;
cursor: pointer;
color: #fff;
}
}
`;
const PlayerID = "boxcast-player";
/** @type {(props:{channel:string, interval:number})=>any} */ /** @type {(props:{channel:string, interval:number})=>any} */
const App = props => const App = props =>
@ -144,7 +170,7 @@ const App = props =>
, [SelectedGet]) , [SelectedGet])
return html` return html`
<div> <${StyledRoot}>
<div id=${PlayerID}></div> <div id=${PlayerID}></div>
<div> <div>
<button onClick=${()=>ListSet(SortStart(State01))}>testdata-01</button> <button onClick=${()=>ListSet(SortStart(State01))}>testdata-01</button>
@ -165,13 +191,13 @@ const App = props =>
)) ))
} }
</div> </div>
${ AlertGet ? h(BroadcastAlert, <div class=${`Alert ${ AlertGet ? " Show" : null }`}>
{ <span class="Close" onClick=${()=>{ AlertSet(false); }}>Dismiss </span>
broadcast: LeadingGet, <h4>A new session is starting:</h4>
clickWatch: ()=>{ SelectedSet(LeadingGet); AlertSet(false); }, <p>${LeadingGet?.name}</p>
clickDismiss: ()=>{ AlertSet(false) } <button onClick=${()=>{ SelectedSet(LeadingGet); AlertSet(false); }}>Watch Now</button>
}) : null } </div>
</div> <//>
`; `;
} }
@ -191,7 +217,7 @@ const BroadcastItem = ({item, previous, priority, selected, select}) =>
let partition; let partition;
if(!previous || (previous.start.Date !== item.start.Date)) if(!previous || (previous.start.Date !== item.start.Date))
{ {
partition = html`<h3 key=${item.start.Day} style=${Styles.Partition} >${item.start.Day}, ${item.start.Month} ${item.start.Date}</h3>` partition = html`<h3 key=${item.start.Day} class="Partition" >${item.start.Day}, ${item.start.Month} ${item.start.Date}</h3>`
} }
let buttonText; let buttonText;
@ -214,27 +240,16 @@ const BroadcastItem = ({item, previous, priority, selected, select}) =>
return html` return html`
${ partition } ${ partition }
<div key=${item.id} onClick=${select} style=${Styles.Broadcast}> <div key=${item.id} onClick=${select} class="Broadcast">
<div style=${Styles.Pointer}>${ pointerText }</div> <div class="Pointer">${ pointerText }</div>
<div style=${Styles.Time}>${item.start.Hours}:${item.start.Minutes} ${item.start.M}</div> <div class="Time">${item.start.Hours}:${item.start.Minutes} ${item.start.M}</div>
<strong>${item.name}</strong> <div class="Title">${item.name}</strong>
<button onClick=${select} disabled=${selected}>${buttonText}</button> <div class="Control">
<button onClick=${select} disabled=${selected}>${buttonText}</button>
</div>
</div>`; </div>`;
}; };
/** @type { (props:{broadcast:Boxcast.Broadcast, clickWatch:()=>void, clickDismiss:()=>void})=>any } */
const BroadcastAlert = ({broadcast, clickWatch, clickDismiss}) =>
{
return html`
<div style=${Styles.Alert}>
<span onClick=${clickDismiss}>X</span>
<h4>A new session is starting:</h4>
<p>${broadcast.name}</p>
<button onClick=${clickWatch}>Watch Now</button>
</div>
`;
}
/** @type {(inDate:string)=>Boxcast.Date} */ /** @type {(inDate:string)=>Boxcast.Date} */
const DateParse = (inDateString) => const DateParse = (inDateString) =>
{ {
@ -259,4 +274,4 @@ const DateParse = (inDateString) =>
}; };
/** @type {(inChannel:string, inSelector:string)=>void} */ /** @type {(inChannel:string, inSelector:string)=>void} */
export default (inChannel, inSelector) => render(h(App, {channel:inChannel, interval:50000}), document.querySelector(inSelector)); export default (inChannel, inSelector) => createRoot(document.querySelector(inSelector)).render(h(App, {channel:inChannel, interval:50000}));