Compare commits

...

3 Commits

Author SHA1 Message Date
a62bf7ea4c simpler init, added fllback (classic) 2022-04-27 16:37:53 -04:00
eb5a1c189f css changes 2022-04-27 12:23:06 -04:00
21e0e0dd9c responsive 2022-04-27 08:25:22 -04:00
3 changed files with 156 additions and 55 deletions

27
app.classic.js Normal file
View File

@ -0,0 +1,27 @@
import 'https://js.boxcast.com/v3.min.js';
const Channels = {
Basics: "sfz7ja3rlpoous6usu8a",
Sunday: "gzahmhugrzogttfdtbjj",
Dev: "r3os2zfdnhlquhuypgtp"
};
const Player = boxcast("#boxcast");
Player.loadChannel(Channels.Basics,
{
showTitle: true,
showDescription: true,
showRelated: true,
showDocuments: true,
showIndex :true,
showDonations: false,
showCountdown: true,
relatedBroadcastsQuery:
{
s: "starts_at",
l: 100,
q: "timeframe:next starts_at:[2022-04-01T00:00:00 TO 2022-06-01T00:00:00]"
},
autoplay: true,
defaultVideo: "next",
});

180
app.js
View File

@ -6,10 +6,24 @@ import { html } from "https://esm.sh/htm/react";
import styled from 'https://esm.sh/styled-components?deps=react@18';
import { createElement as h, useState, useEffect, useRef } from 'https://esm.sh/react@18';
import { createRoot } from "https://esm.sh/react-dom/client";
/*
import State01 from "./testdata-01.json" assert { type: "json" };
import State02 from "./testdata-02.json" assert { type: "json" };
import State03 from "./testdata-03.json" assert { type: "json" };
*/
const StyledRoot = styled.div`
.Boxcast-Upper
{
background: white;
box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.1);
}
.Boxcast-Player
{
.boxcast-well-container
{
display: none;
}
.boxcast-well
{
display:flex;
@ -30,6 +44,13 @@ const StyledRoot = styled.div`
}
}
}
.Boxcast-Active
{
text-align: center;
padding:20px;
background: white;
& > * { margin: 0; }
}
.Boxcast-Playlist
{
max-width: 550px;
@ -37,7 +58,10 @@ const StyledRoot = styled.div`
}
.Partition
{
margin: 10px 0 0 0;
margin: 15px 0 0 0;
padding: 0 0 8px 0;
border-bottom: 1px solid #dddddd;
text-align: center;
}
.Broadcast
{
@ -45,9 +69,16 @@ const StyledRoot = styled.div`
display: flex;
padding: 5px 0 5px 0;
& > *
{
box-sizing: border-box;
padding: 5px;
}
.Pointer
{
width: 75px;
text-align: right;
.Badge
{
display: inline-block;
@ -58,6 +89,7 @@ const StyledRoot = styled.div`
font-family: sans-serif;
letter-spacing: 0.1em;
text-transform: uppercase;
text-align: center;
&.Next
{
@ -78,33 +110,71 @@ const StyledRoot = styled.div`
}
.Time
{
width: 75px;
margin-right: 5px;
width: 80px;
font-size: 16px;
text-align: right;
}
.Title
{
flex: 1;
font-weight: 900;
}
.Control
{
button
width: 80px;
}
button
{
appearance: none;
display: inline-block;
padding: 5px 10px 5px 10px;
background: black;
cursor: pointer;
border: none;
color: white;
font-size: 10px;
font-weight: 900;
transition: all 0.4s;
}
button[disabled]
{
background: red !important;
border-radius: 20px;
}
button:hover
{
border-radius: 20px;
}
&.future button
{
background: #aaa;
}
@media(max-width:500px)
{
flex-wrap: wrap;
.Time
{
appearance: none;
display: block;
width: 80px;
padding: 5px 10px 5px 10px;
background: black;
cursor: pointer;
border: none;
color: white;
font-size: 10px;
font-weight: 900;
order: 0;
width: 30%;
}
button[disabled]
.Title
{
background: red;
order: 1;
flex: none;
width: 60%;
}
.Pointer
{
order: 2;
width: 30%;
}
.Control
{
order: 3;
width: 60%;
}
}
}
@ -114,7 +184,7 @@ const StyledRoot = styled.div`
right: 20px;
bottom: -300px;
width: 300px;
height: 200px;
padding: 20px 0 40px 0;
background: #333;
border-radius: 5px;
transition: bottom 0.4s;
@ -126,13 +196,23 @@ const StyledRoot = styled.div`
bottom: 20px;
}
button
{
padding: 5px 15px;
border: none;
background: white;
cursor: pointer;
font-weight: 900;
}
.Close
{
display: inline-block;
position: absolute;
padding: 5px 10px 5px 10px;
border-radius: 20px;
top: -15px;
border: 3px solid white;
top: -20px;
right: 10px;
background: #000000;
cursor: pointer;
@ -163,7 +243,7 @@ const App = props =>
inList.sort((a, b) => a.starts_at > b.starts_at ? 1 : -1);
inList.forEach( item => item.start = DateParse(item.starts_at));
return inList;
}
};
const Player = useRef(null);
@ -239,12 +319,27 @@ const App = props =>
};
Player.current.loadChannel(props.channel, settings);
document.documentElement.style.scrollBehavior = "smooth";
window.location = (`#${PlayerID}`);
}
, [SelectedGet]);
return html`
<${StyledRoot}>
<div class="Boxcast-Player" id=${PlayerID}></div>
<div class="Boxcast-Upper">
<div class="Boxcast-Player" id=${PlayerID}></div>
<!--
<div>
<button onClick=${()=>ListSet(SortStart(State01))}>testdata-01</button>
<button onClick=${()=>ListSet(SortStart(State02))}>testdata-02</button>
<button onClick=${()=>ListSet(SortStart(State03))}>testdata-03</button>
</div>
-->
<div class="Boxcast-Active">
<h2>${ ListGet.filter( item=>item.id == SelectedGet )[0]?.name }</h2>
</div>
</div>
<div class="Boxcast-Playlist">
${
ListGet.map( (item, index) =>
@ -275,18 +370,9 @@ const BroadcastItem = ({item, previous, priority, selected, select}) =>
{
// pointer
let pointerText;
if (priority)
{
pointerText = html`<div class="Badge Next">Next</div>`;
}
if(item.timeframe == "current")
{
pointerText = html`<div class="Badge Live">Live</div>`;
}
if(item.timeframe == "preroll")
{
pointerText = html`<div class="Badge Soon">Soon</div>`;
}
if (priority){ pointerText = html`<div class="Badge Next">Next</div>`; }
if(item.timeframe == "preroll"){ pointerText = html`<div class="Badge Soon">Soon</div>`; }
if(item.timeframe == "current"){ pointerText = html`<div class="Badge Live">Live</div>`; }
// (date) partition
let partition;
@ -299,32 +385,19 @@ const BroadcastItem = ({item, previous, priority, selected, select}) =>
// button
let buttonText;
if(item.timeframe == "past")
{
buttonText = "Re-watch";
}
if(item.timeframe == "current" || item.timeframe == "preroll")
{
buttonText = "Watch";
}
if(item.timeframe == "future")
{
buttonText = "Preview";
}
if(selected)
{
buttonText = "(Viewing)";
}
if(item.timeframe == "past"){ buttonText = "Rewatch"; }
if(item.timeframe == "current" || item.timeframe == "preroll"){ buttonText = "Watch"; }
if(item.timeframe == "future"){ buttonText = "Preview"; }
return html`
${ partition }
<div class="Broadcast" key=${item.id} onClick=${select}>
<div class="Pointer">${ pointerText }</div>
<div class=${`Broadcast ${item.timeframe}`} key=${item.id}>
<div class="Time">${item.start.Hours}:${item.start.Minutes} ${item.start.M}</div>
<div class="Title">${item.name}</strong>
<div class="Control">
<button onClick=${select} disabled=${selected}>${buttonText}</button>
</div>
<div class="Pointer">${ pointerText }</div>
</div>`;
};
@ -351,5 +424,8 @@ const DateParse = (inDateString) =>
return obj;
};
/** @type {(inChannel:string, inSelector:string)=>void} */
export default (inChannel, inSelector) => createRoot(document.querySelector(inSelector)).render(h(App, {channel:inChannel, interval:5000}));
/** @type {(inChannel:string, inSelector:string, inInterval:number)=>void} */
const Init = (inChannel, inSelector, inInterval) => createRoot(document.querySelector(inSelector)).render(h(App, {channel:inChannel, interval:inInterval}));
const Channel = { Basics: "sfz7ja3rlpoous6usu8a", Sunday: "gzahmhugrzogttfdtbjj", Dev: "r3os2zfdnhlquhuypgtp" };
Init(Channel.Basics, "#boxcast", 5000);

View File

@ -8,9 +8,7 @@
<div style="max-width:1100px; margin: 0 auto;">
<div id="boxcast"></div>
<script type="module">
import Init from "./app.js";
const Channel = { Basics: "sfz7ja3rlpoous6usu8a", Sunday: "gzahmhugrzogttfdtbjj", Dev: "r3os2zfdnhlquhuypgtp" };
Init(Channel.Basics, "#boxcast");
import "./app.js";
</script>
</div>