diff options
Diffstat (limited to 'desk/web/tv/tv.hoon')
-rw-r--r-- | desk/web/tv/tv.hoon | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/desk/web/tv/tv.hoon b/desk/web/tv/tv.hoon new file mode 100644 index 0000000..5a3360a --- /dev/null +++ b/desk/web/tv/tv.hoon @@ -0,0 +1,285 @@ +/- *boke +/+ kaji, sr=sortug, lib=boke +/= post-text /web/components/post-text +|_ [s=state =bowl:gall] +++ css ^~ %- trip +''' +#tv{ + padding: 1rem; + + & main{ + margin-top: 0.5rem; + height: 50vw; + & #screen{ + } + & #chat{ + border: 1px solid var(--text-color); + h3{ + height: 1.5rem; + margin: 0; + } + + & #chat-container{ + overflow-y: scroll; + max-height: calc(100% - 3.5rem); + height: calc(100% - 3.5rem); + .chat-msg{ + padding: 0.5rem; + & .author{ + opacity: 0.8; + font-family: Inter; + } + & .chat-content{ + padding: 0.3rem 1rem; + & p{ + margin: 0; + } + } + } + } + & form{ + display: flex; + margin-bottom: 0; + border-top: 1px solid black; + + & input{ + border: none; + border-radius: 0; + } + + & input[type=text]{ + width: 100%; + height: 2rem; + } + & input[type=submit]{ + padding: 0.2rem; + } + } + } + } + & #radio-list{ + overflow-y: scroll; + max-height: 70vh; + & .entry{ + cursor: pointer; + } + } +} +#video{ + width: 100%; + background-color: black; +} +.tabs{ + display: flex; + gap: 1rem; + & .tab{ + cursor: pointer; + } +} +@media (min-width: 1200px){ +#tv main{ + display: flex; + align-items: stretch; + gap: 1rem; + +} +#screen{ + width: 75%; +} +#chat{ + width: 25%; +} +@media (max-width: 1200px){ +#screen{ + width: 100%; +} +#chat{ + width: 25%; +} + +} +.movie-name{ + font-size: 1.2rem; + font-weight: 500; +} +''' +++ script +|= sub-path=tape +^~ %+ weld %- trip +''' +function initVideo(videoSrc){ + const video = document.getElementById('video'); + video.autoplay = true; + console.log(videoSrc, "starting video") + + if (Hls.isSupported()) { + var hls = new Hls(); + hls.loadSource(videoSrc); + hls.attachMedia(video); + hls.on(Hls.Events.MANIFEST_LOADED, function (event, data) { + console.log("manifest loaded", [event, data]) + }); + hls.on(Hls.Events.MANIFEST_LOADED, function (event, data) { + console.log("manifest loaded", [event, data]) + }); + hls.on(Hls.Events.FRAG_LOADED, function (event, data) { + console.log("frag loaded", [event, data]) + }); + hls.on(Hls.Events.LEVEL_LOADED, function (event, data) { + console.log("level loaded", [event, data]) + }); + hls.on(Hls.Events.SUBTITLE_TRACK_SWITCH, function (event, data) { + console.log("sub switch", [event, data]) + }); + hls.on(Hls.Events.SUBTITLE_TRACK_LOADED, function (event, data) { + console.log("sub loaded", [event, data]) + }); + hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) { + console.log("manifest parsed", [event, data]) + video.play(); + }); + } + // HLS.js is not supported on platforms that natively support HLS + else if (video.canPlayType('application/vnd.apple.mpegurl')) { + video.src = videoSrc; + video.addEventListener('loadedmetadata', function () { + video.play(); + }); + } + +} +document.addEventListener('DOMContentLoaded', () => { + const src = 'https://hydrogen.finnem.net/hls/live.m3u8'; + //const src = 'https://hls.urbit.cam/output.m3u8'; + initVideo(src); + const room = document.getElementById("chat-container"); + if (room) room.scrollTop = room.scrollHeight +}); + +document.addEventListener('kaji-fact', (event) => { + console.log(event.detail, "kaji fact") + if (event.detail.event === "scroll"){ + const room = document.getElementById("chat-container"); + if (room) setTimeout(() => room.scrollTop = room.scrollHeight, 50) + } + else if ("change-radio" in event.detail) + initVideo(event.detail["change-radio"]); +}); + +''' +""" +subscribe('{sub-path}'); + +""" +++ main +|= [symbol=@tas =twr] ^- manx + =/ author (scow %p owner.twr) + =/ name (trip symbol) + =/ sub-path "/tv/{(trip -.twr)}/{name}" + ~& sub-path=sub-path +;div#tv + ;style: {css} + ;main + ;div#screen + ;video#video + =controls "" + ; + == + ;+ (broadcast-metadata twr) + == + ;+ (chat-box symbol twr) + == + :: ;+ rl + ;script: {(script sub-path)} + ;script@"https://cdn.jsdelivr.net/npm/hls.js@latest"; +== +++ broadcast-metadata +|= =twr ^- manx + =/ author (scow %p owner.twr) + =/ stat-name (trip name.twr) + ?: ?=(%our -.twr) + =/ desc (trip description.tv.twr) + ;div.meta + ;div.movie-name:"{desc}" + ;div.movie-from:"from {stat-name} by {author}" + == + :: + =/ desc (trip description.p.twr) + ;div.meta + ;div:"{desc}" + ;div:"by {author}" + == + +++ rl ^- manx + ;div#radio-list + ;div.tabs + =kaji "scry" + =swap "swap" + =targ "#rlist" + ;div.tab + =path "/tv/f/s" + ; Spandrell TV + == + ;div.tab + =path "/tv/f/u" + ; Urbit Radio + == + == + ;div#rlist + ;* tv-list + == + == +++ radio-list ^- marl + %+ turn ~(tap by urbit.tv.s) |= [p=@p q=urbit-radio] + ;div.entry + =kaji "poke" + =action "change-radio" + =payload (enc:kaji p) + ;p:"{(trip description.q)}" + ;p:"by {(scow %p p)}" + == +++ tv-list ^- marl + %+ turn ~(tap by here.tv.s) |= [p=@t q=bstv] + ;div.entry + =kaji "poke" + =action "change-nradio" + =payload (trip p) + ;p:"{(trip playing.current.q)}" + ;p:"by {(scow %p owner.q)}" + == + +++ chat-box +|= [symbol=@tas =twr] +?: ?=(%urb -.twr) ;div; +;div#chat + ;h3.tc.bb:"Chat" + ;div#chat-container + ;* %+ turn (flop chat.tv.twr) chat-msg + == + ;form + =id "chat-composer" + =kaji "poke" + =action "add-radio-chat" + =wipe "yes" + ;input#text-input(type "text", name "input", placeholder "Nice", autocomplete "off"); + ;input(type "hidden", name "type", value (trip -.twr)); + ;input(type "hidden", name "owner", value (scow %p owner.twr)); + ;input(type "hidden", name "name", value (trip symbol)); + ;input(type "submit", value "⇛"); + == + +== +++ chat-msg +|= p=post:tp +:: =/ usr (user author.p whoms 32) + =/ author ?: (is-anon:lib author.p) "anon" (scow %p author.p) +;div.chat-msg + ;div.f1 + ;div.author:"{author}:" + ;div.time:"{(time-to-tape:string:sr id.p)}" + == + ;div.chat-content + ;* (content:post-text contents.p) + == +== +-- |