Changeset - 7ed414bdaab9
[Not reviewed]
default
0 2 1
drewp@bigasterisk.com - 3 years ago 2022-05-11 07:07:13
drewp@bigasterisk.com
wip porting asco to TS and not-jquery
3 files changed with 183 insertions and 177 deletions:
0 comments (0 inline, 0 general)
light9/ascoltami/index.html
Show inline comments
 
<?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>
light9/ascoltami/main.ts
Show inline comments
 
new file 100644
 
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
light9/ascoltami/webapp.py
Show inline comments
 
@@ -27,14 +27,18 @@ def songUri(graph, locationUri):
 
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 @@ class goButton(PrettyErrorHandler, cyclo
 
def makeWebApp(app):
 
    return cyclone.web.Application(handlers=[
 
        (r"/", root),
 
        (r"/config", config),
 
        (r"/time", timeResource),
 
        (r"/time/stream", timeStreamResource),
 
        (r"/song", songResource),
0 comments (0 inline, 0 general)