Mercurial > code > home > repos > light9
changeset 2050:7ed414bdaab9
wip porting asco to TS and not-jquery
author | drewp@bigasterisk.com |
---|---|
date | Wed, 11 May 2022 00:07:13 -0700 |
parents | 1aa9a1293611 |
children | bfee787d7b5c |
files | light9/ascoltami/index.html light9/ascoltami/main.ts light9/ascoltami/webapp.py |
diffstat | 3 files changed, 183 insertions(+), 177 deletions(-) [+] |
line wrap: on
line diff
--- a/light9/ascoltami/index.html Wed May 11 00:06:19 2022 -0700 +++ b/light9/ascoltami/index.html Wed May 11 00:07:13 2022 -0700 @@ -1,14 +1,12 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" -"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:py="http://genshi.edgewall.org/"> +<!DOCTYPE html> +<html> <head> <title>ascoltami on {{host}}</title> + <script type="text/javascript" src="/lib/jquery/dist/jquery.min.js"></script> <script type="text/javascript" src="/lib/jquery-ui/jquery-ui.min.js"></script> <link rel="Stylesheet" type="text/css" href="/lib/jquery-ui/themes/smoothness/jquery-ui.min.css"/> - <link rel="Stylesheet" type="text/css" href="/style.css"/> + <link rel="Stylesheet" type="text/css" href="style.css"/> <style> #cmd-go { min-width: 5em; } .song-name { padding-left: 0.4em; } @@ -16,28 +14,28 @@ </head> <body> <h1>ascoltami on {{host}}</h1> - <div class="songs"/> + <div class="songs"></div> <div class="dimStalled"> <table> - <tr><td colspan="3"><strong>Song:</strong> <span id="currentSong"/></td></tr> + <tr><td colspan="3"><strong>Song:</strong> <span id="currentSong"></span></td></tr> <tr> - <td><strong>Time:</strong> <span id="currentTime"/></td> - <td><strong>Left:</strong> <span id="leftTime"/></td> - <td><strong>Until autostop:</strong> <span id="leftAutoStopTime"/></td> + <td><strong>Time:</strong> <span id="currentTime"></span></td> + <td><strong>Left:</strong> <span id="leftTime"></span></td> + <td><strong>Until autostop:</strong> <span id="leftAutoStopTime"></span></td> </tr> <tr> <td colspan="3"> - <strong>Update freq:</strong> requested <span id="updateReq"/>, actual <span id="updateActual"/> - <strong>States:</strong> <span id="states"/> + <strong>Update freq:</strong> requested <span id="updateReq"></span>, actual <span id="updateActual"></span> + <strong>States:</strong> <span id="states"></span> </td> </tr> </table> <div class="timeRow"> - <div id="timeSlider"/> + <div id="timeSlider"></div> </div> </div> <div class="commands"> @@ -53,165 +51,10 @@ --> </div> - <p>Running on <span id="nav"/></p> + <p>Running on <span id="nav"></span></p> <p><a href="">reload</a></p> - -<script type="text/javascript"> -// <![CDATA[ -$(function () { - - $("#nav").text(navigator.userAgent); - var updateFreq = (navigator.userAgent.indexOf("Linux") != -1) ? 10 : 2; - if (navigator.userAgent.match(/Windows NT/)) { - // helper laptop - updateFreq = 10; - } - $("#updateReq").text(updateFreq); - - var times = {% raw times %}; - - var currentDuration = 0; - var currentHighlightedSong = ""; - var lastPlaying; - function updateCurrent(doneCallback) { - $.getJSON("time", {}, function (data, status) { - $("#currentSong").text(data.song); - if (data.song != currentHighlightedSong) { - showCurrentSong(data.song); - } - $("#currentTime").text(data.t.toFixed(1)); - $("#leftTime").text((data.duration - data.t).toFixed(1)); - $("#leftAutoStopTime").text( - Math.max(0, data.duration - times.post - data.t).toFixed(1)); - $("#states").text(JSON.stringify(data.state)); - currentDuration = data.duration; - $("#timeSlider").slider({value: data.t, - max: data.duration}); - if (data.playing != lastPlaying) { - $(".playMode").removeClass("active"); - $(data.playing ? "#cmd-play" : "#cmd-stop").addClass("active"); - lastPlaying = data.playing; - } - $("#next").text(data.next); - doneCallback(); - }); - } - function showCurrentSong(uri) { - $(".songs div").each(function (i, row) { - row = $(row); - if (row.find("button").data("uri") == uri) { - row.addClass("currentSong"); - } else { - row.removeClass("currentSong"); - } - }); - currentHighlightedSong = uri; - } - $.getJSON("songs", {}, function (data, status) { - $.each(data.songs, function (i, song) { - var button = $("<button>"); - // link is just for dragging, not clicking - var link = $("<a>"); - link.append($("<span>").addClass("num").text(song.label.slice(0,2))); - link.append($("<span>").addClass("song-name").text(song.label.slice(2).trim())); - link.attr("href", song.uri); - link.click(function () { button.click(); return false; }); - button.append(link); - button.data(song); - button.click(function () { - $.post("song", button.data("uri"), - function (data, textStatus, xhr) { - showCurrentSong(song.uri); - }); - }); - $(".songs").append($("<div>").append(button)); - }); - }); - - var tojs = JSON.stringify; - - $(document).keypress(function (ev) { - - if (ev.which == 115) { $("#cmd-stop").click(); return false; } - if (ev.which == 112) { $("#cmd-play").click(); return false; } - if (ev.which == 105) { $("#cmd-intro").click(); return false; } - if (ev.which == 116) { $("#cmd-post").click(); return false; } - - if (ev.key == 'g') { - $("#cmd-go").click(); - return false; - } - return true; - }); - - $("#cmd-stop").click(function () { $.post("time", tojs({pause: true})); }); - $("#cmd-play").click(function () { $.post("time", tojs({resume: true})); }); - $("#cmd-intro").click(function () { - $.post("time", tojs({t: times.intro, resume: true})) - }); - $("#cmd-post").click(function () { - $.post("time", tojs({t: currentDuration - times.post, resume: true})) - }); - $("#cmd-go").click(function () { - $.post("go"); - }); - $("#cmd-out0").click(function () { $.post("output", tojs({sink: "0"})); }) - $("#cmd-out1").click(function () { $.post("output", tojs({sink: "1"})); }) - - var pendingSlide = false; - $("#timeSlider").slider({ - step: .01, - slide: function (event, ui) { - if (pendingSlide) { - return; - } - pendingSlide = true; - $.post("time", '{"t" : '+ui.value+'}', - function (data, status, xhr) { - pendingSlide = false; - }); - }, - }); - var raf = window.requestAnimationFrame || - window.mozRequestAnimationFrame || - window.webkitRequestAnimationFrame; - - var recentUpdates = []; - function onUpdate() { - recentUpdates.push(+new Date()); - recentUpdates = recentUpdates.slice(Math.max(recentUpdates.length - 5, 0)); - refreshUpdateFreqs(); - } - - function refreshUpdateFreqs() { - if (recentUpdates.length > 1) { - if (+new Date() - recentUpdates[recentUpdates.length - 1] > 1000) { - $("#updateActual").text("(stalled)"); - $(".dimStalled").addClass("stalled"); - return; - } - - var avgMs = (recentUpdates[recentUpdates.length - 1] - recentUpdates[0]) / (recentUpdates.length - 1); - $("#updateActual").text(Math.round(1000 / avgMs)); - } - } - setInterval(refreshUpdateFreqs, 2000); - - function updateLoop() { - var whenDone = function () { - setTimeout(function () { - raf(updateLoop); - }, 1000 / updateFreq); - }; - onUpdate(); - updateCurrent(whenDone); - } - updateLoop(); - -}); -// ]]> -</script> + <script type="module" src="main.ts"></script> </body>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/light9/ascoltami/main.ts Wed May 11 00:07:13 2022 -0700 @@ -0,0 +1,158 @@ +async function onLoad() { +const config = await (await fetch('config')).json(); +const times = config.times; +document.title = document.title.replace('{{host}}', config.host); +const h1 =document.querySelector('h1')! +h1.innerText = h1?.innerText.replace('{{host}}', config.host) +/* + $("#nav").text(navigator.userAgent); + var updateFreq = (navigator.userAgent.indexOf("Linux") != -1) ? 10 : 2; + if (navigator.userAgent.match(/Windows NT/)) { + // helper laptop + updateFreq = 10; + } + $("#updateReq").text(updateFreq); + + var times = {% raw times %}; + + var currentDuration = 0; + var currentHighlightedSong = ""; + var lastPlaying; + function updateCurrent(doneCallback) { + $.getJSON("time", {}, function (data, status) { + $("#currentSong").text(data.song); + if (data.song != currentHighlightedSong) { + showCurrentSong(data.song); + } + $("#currentTime").text(data.t.toFixed(1)); + $("#leftTime").text((data.duration - data.t).toFixed(1)); + $("#leftAutoStopTime").text( + Math.max(0, data.duration - times.post - data.t).toFixed(1)); + $("#states").text(JSON.stringify(data.state)); + currentDuration = data.duration; + $("#timeSlider").slider({value: data.t, + max: data.duration}); + if (data.playing != lastPlaying) { + $(".playMode").removeClass("active"); + $(data.playing ? "#cmd-play" : "#cmd-stop").addClass("active"); + lastPlaying = data.playing; + } + $("#next").text(data.next); + doneCallback(); + }); + } + function showCurrentSong(uri) { + $(".songs div").each(function (i, row) { + row = $(row); + if (row.find("button").data("uri") == uri) { + row.addClass("currentSong"); + } else { + row.removeClass("currentSong"); + } + }); + currentHighlightedSong = uri; + } + $.getJSON("songs", {}, function (data, status) { + $.each(data.songs, function (i, song) { + var button = $("<button>"); + // link is just for dragging, not clicking + var link = $("<a>"); + link.append($("<span>").addClass("num").text(song.label.slice(0,2))); + link.append($("<span>").addClass("song-name").text(song.label.slice(2).trim())); + link.attr("href", song.uri); + link.click(function () { button.click(); return false; }); + button.append(link); + button.data(song); + button.click(function () { + $.post("song", button.data("uri"), + function (data, textStatus, xhr) { + showCurrentSong(song.uri); + }); + }); + $(".songs").append($("<div>").append(button)); + }); + }); + + var tojs = JSON.stringify; + + $(document).keypress(function (ev) { + + if (ev.which == 115) { $("#cmd-stop").click(); return false; } + if (ev.which == 112) { $("#cmd-play").click(); return false; } + if (ev.which == 105) { $("#cmd-intro").click(); return false; } + if (ev.which == 116) { $("#cmd-post").click(); return false; } + + if (ev.key == 'g') { + $("#cmd-go").click(); + return false; + } + return true; + }); + + $("#cmd-stop").click(function () { $.post("time", tojs({pause: true})); }); + $("#cmd-play").click(function () { $.post("time", tojs({resume: true})); }); + $("#cmd-intro").click(function () { + $.post("time", tojs({t: times.intro, resume: true})) + }); + $("#cmd-post").click(function () { + $.post("time", tojs({t: currentDuration - times.post, resume: true})) + }); + $("#cmd-go").click(function () { + $.post("go"); + }); + $("#cmd-out0").click(function () { $.post("output", tojs({sink: "0"})); }) + $("#cmd-out1").click(function () { $.post("output", tojs({sink: "1"})); }) + + var pendingSlide = false; + $("#timeSlider").slider({ + step: .01, + slide: function (event, ui) { + if (pendingSlide) { + return; + } + pendingSlide = true; + $.post("time", '{"t" : '+ui.value+'}', + function (data, status, xhr) { + pendingSlide = false; + }); + }, + }); + + var raf = window.requestAnimationFrame || + window.mozRequestAnimationFrame || + window.webkitRequestAnimationFrame; + + var recentUpdates = []; + function onUpdate() { + recentUpdates.push(+new Date()); + recentUpdates = recentUpdates.slice(Math.max(recentUpdates.length - 5, 0)); + refreshUpdateFreqs(); + } + + function refreshUpdateFreqs() { + if (recentUpdates.length > 1) { + if (+new Date() - recentUpdates[recentUpdates.length - 1] > 1000) { + $("#updateActual").text("(stalled)"); + $(".dimStalled").addClass("stalled"); + return; + } + + var avgMs = (recentUpdates[recentUpdates.length - 1] - recentUpdates[0]) / (recentUpdates.length - 1); + $("#updateActual").text(Math.round(1000 / avgMs)); + } + } + setInterval(refreshUpdateFreqs, 2000); + + function updateLoop() { + var whenDone = function () { + setTimeout(function () { + raf(updateLoop); + }, 1000 / updateFreq); + }; + onUpdate(); + updateCurrent(whenDone); + } + updateLoop(); +*/ +} +onLoad() \ No newline at end of file
--- a/light9/ascoltami/webapp.py Wed May 11 00:06:19 2022 -0700 +++ b/light9/ascoltami/webapp.py Wed May 11 00:07:13 2022 -0700 @@ -27,14 +27,18 @@ class root(PrettyErrorHandler, cyclone.web.RequestHandler): def get(self): - self.set_header("Content-Type", "application/xhtml+xml") + self.set_header("Content-Type", "text/html") self.write( - loader.load('index.html').generate(host=socket.gethostname(), - times=json.dumps({ - 'intro': 4, - 'post': 4 - }))) + loader.load('index.html').generate()) +class config(cyclone.web.RequestHandler): + def get(self): + self.set_header("Content-Type", "application/json") + self.write(json.dumps(dict(host=socket.gethostname(), + times={ + 'intro': 4, + 'post': 4 + }))) def playerSongUri(graph, player): """or None""" @@ -198,6 +202,7 @@ def makeWebApp(app): return cyclone.web.Application(handlers=[ (r"/", root), + (r"/config", config), (r"/time", timeResource), (r"/time/stream", timeStreamResource), (r"/song", songResource),