changeset 2053:b7a3dff5514d

rough and untested port of asco from jquery to vanilla
author drewp@bigasterisk.com
date Fri, 13 May 2022 01:09:14 -0700
parents cba85338def9
children 960a22eed99c
files light9/ascoltami/index.html light9/ascoltami/main.py light9/ascoltami/main.ts
diffstat 3 files changed, 168 insertions(+), 170 deletions(-) [+]
line wrap: on
line diff
--- a/light9/ascoltami/index.html	Fri May 13 01:07:36 2022 -0700
+++ b/light9/ascoltami/index.html	Fri May 13 01:09:14 2022 -0700
@@ -3,10 +3,7 @@
   <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; }
@@ -55,7 +52,5 @@
     <p><a href="">reload</a></p>
     
     <script type="module" src="main.ts"></script>
-
-
   </body>
 </html>
--- a/light9/ascoltami/main.py	Fri May 13 01:07:36 2022 -0700
+++ b/light9/ascoltami/main.py	Fri May 13 01:09:14 2022 -0700
@@ -1,18 +1,25 @@
 #!bin/python
+import logging
+import optparse
+import sys
+from typing import cast
+
+import gi
 from light9.run_local import log
+from rdflib import URIRef
 from twisted.internet import reactor
-import sys, optparse, logging
-from rdflib import URIRef
-import gi
+from twisted.internet.interfaces import IReactorCore
+
 gi.require_version('Gst', '1.0')
 gi.require_version('Gtk', '3.0')
 
+from gi.repository import GObject, Gst
+from light9 import networking, showconfig
 from light9.ascoltami.player import Player
-from light9.ascoltami.playlist import Playlist, NoSuchSong
-from light9.ascoltami.webapp import makeWebApp, songUri, songLocation
-from light9 import networking, showconfig
+from light9.ascoltami.playlist import NoSuchSong, Playlist
+from light9.ascoltami.webapp import makeWebApp, songLocation, songUri
 
-from gi.repository import GObject, Gst
+reactor = cast(IReactorCore, reactor)
 
 
 class App(object):
@@ -41,17 +48,9 @@
     Gst.init(None)
 
     parser = optparse.OptionParser()
-    parser.add_option(
-        '--show',
-        help='show URI, like http://light9.bigasterisk.com/show/dance2008',
-        default=showconfig.showUri())
-    parser.add_option("-v",
-                      "--verbose",
-                      action="store_true",
-                      help="logging.DEBUG")
-    parser.add_option("--twistedlog",
-                      action="store_true",
-                      help="twisted logging")
+    parser.add_option('--show', help='show URI, like http://light9.bigasterisk.com/show/dance2008', default=showconfig.showUri())
+    parser.add_option("-v", "--verbose", action="store_true", help="logging.DEBUG")
+    parser.add_option("--twistedlog", action="store_true", help="twisted logging")
     (options, args) = parser.parse_args()
 
     log.setLevel(logging.DEBUG if options.verbose else logging.INFO)
--- a/light9/ascoltami/main.ts	Fri May 13 01:07:36 2022 -0700
+++ b/light9/ascoltami/main.ts	Fri May 13 01:09:14 2022 -0700
@@ -1,158 +1,162 @@
+function byId(id: string): HTMLElement {
+  return document.getElementById(id)!;
+}
+
 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);
+  const config = await (await fetch("api/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);
 
-    var times = {% raw times %};
+  byId("nav").innerText = navigator.userAgent;
+  var updateFreq = navigator.userAgent.indexOf("Linux") != -1 ? 10 : 2;
+  if (navigator.userAgent.match(/Windows NT/)) {
+    // helper laptop
+    updateFreq = 10;
+  }
+  byId("updateReq").innerText = "" + updateFreq;
+
+  let currentDuration = 0;
+  let currentHighlightedSong = "";
+  let lastPlaying = false;
 
-    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();
-	});
+  async function updateCurrent() {
+    const data = await (await fetch("api/time")).json();
+    byId("currentSong").innerText = data.song;
+    if (data.song != currentHighlightedSong) {
+      showCurrentSong(data.song);
+    }
+    byId("currentTime").innerText = data.t.toFixed(1);
+    byId("leftTime").innerText = (data.duration - data.t).toFixed(1);
+    byId("leftAutoStopTime").innerText = Math.max(0, data.duration - times.post - data.t).toFixed(1);
+    byId("states").innerText = JSON.stringify(data.state);
+    currentDuration = data.duration;
+    //   document.querySelector("#timeSlider").slider({ value: data.t, max: data.duration });
+    if (data.playing != lastPlaying) {
+      document.querySelectorAll(".playMode").forEach((e: Element) => e.classList.remove("active"));
+      byId(data.playing ? "cmd-play" : "cmd-stop").classList.add("active");
+      lastPlaying = data.playing;
     }
-    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));
-	});
+    byId("next").innerText = data.next;
+  }
+
+  function showCurrentSong(uri: string) {
+    document.querySelectorAll(".songs div").forEach((row: Element, i: number) => {
+      if (row.querySelector("button")!.dataset.uri == uri) {
+        row.classList.add("currentSong");
+      } else {
+        row.classList.remove("currentSong");
+      }
+    });
+    currentHighlightedSong = uri;
+  }
+
+  	const data = await (await fetch('api/songs')).json()
+      data.songs.forEach((song)=> {
+        const button = document.createElement("button");
+        // link is just for dragging, not clicking
+        const link = document.createElement("a");
+        link.appendChild($("<span>").addClass("num").text(song.label.slice(0, 2)));
+        link.appendChild($("<span>").addClass("song-name").text(song.label.slice(2).trim()));
+        link.setAttribute("href", song.uri);
+        link.addEventListener("click", (ev) => {
+			ev.stopPropagation()
+          button.click();
+        });
+        button.appendChild(link);
+        button.dataset.uri=(song);
+        button.click(function () {
+          fetch('api/song', {method: 'POST', body: song$.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();
+  document.addEventListener("keypress", (ev) => {
+    if (ev.which == 115) {
+      byId("cmd-stop").click();
+      return false;
+    }
+    if (ev.which == 112) {
+      byId("cmd-play").click();
+      return false;
+    }
+    if (ev.which == 105) {
+      byId("cmd-intro").click();
+      return false;
+    }
+    if (ev.which == 116) {
+      byId("cmd-post").click();
+      return false;
     }
 
-    function refreshUpdateFreqs() {
-        if (recentUpdates.length > 1) {
-          if (+new Date() - recentUpdates[recentUpdates.length - 1] > 1000) {
-            $("#updateActual").text("(stalled)");
-            $(".dimStalled").addClass("stalled");
-            return;
-          }
+    if (ev.key == "g") {
+      byId("cmd-go").click();
+      return false;
+    }
+    return true;
+  });
+
+  async function postJson(url: string, jsBody: Object) {
+    return fetch(url, { method: "POST", headers: { "Content-Type": "applcation/json" }, body: JSON.stringify(jsBody) });
+  }
 
-          var avgMs = (recentUpdates[recentUpdates.length - 1] - recentUpdates[0]) / (recentUpdates.length - 1);
-          $("#updateActual").text(Math.round(1000 / avgMs));
-        }
-    }
-    setInterval(refreshUpdateFreqs, 2000);
+  byId("cmd-stop").addEventListener("click", (ev: Event) => postJson("time", { pause: true }));
+  byId("cmd-play").addEventListener("click", (ev: Event) => postJson("time", { resume: true }));
+  byId("cmd-intro").addEventListener("click", (ev: Event) => postJson("time", { t: times.intro, resume: true }));
+  byId("cmd-post").addEventListener("click", (ev: Event) => postJson("time", { t: currentDuration - times.post, resume: true }));
+  byId("cmd-go").addEventListener("click", (ev: Event) => postJson("go", {}));
+  byId("cmd-out0").addEventListener("click", (ev: Event) => postJson("output", { sink: "0" }));
+  byId("cmd-out1").addEventListener("click", (ev: Event) => postJson("output", { sink: "1" }));
+
+  //   var pendingSlide = false;
+  //   $("#timeSlider").slider({
+  //     step: 0.01,
+  //     slide: function (event, ui) {
+  //       if (pendingSlide) {
+  //         return;
+  //       }
+  //       pendingSlide = true;
+  //       $.post("time", '{"t" : ' + ui.value + "}", function (data, status, xhr) {
+  //         pendingSlide = false;
+  //       });
+  //     },
+  //   });
 
-    function updateLoop() {
-	var whenDone = function () {
-	    setTimeout(function () { 
-		raf(updateLoop);
-	    }, 1000 / updateFreq);
-	};
-        onUpdate();
-	updateCurrent(whenDone);
+  let recentUpdates: Array<number> = [];
+  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) {
+        byId("updateActual").innerText = "(stalled)";
+        document.querySelectorAll(".dimStalled").forEach((el) => el.classList.add("stalled"));
+        return;
+      }
+
+      var avgMs = (recentUpdates[recentUpdates.length - 1] - recentUpdates[0]) / (recentUpdates.length - 1);
+      byId("updateActual").innerText = "" + Math.round(1000 / avgMs);
     }
-    updateLoop();
-*/
+  }
+  setInterval(refreshUpdateFreqs, 2000);
+
+  async function updateLoop() {
+    var whenDone = function () {
+      setTimeout(function () {
+        requestAnimationFrame(updateLoop);
+      }, 1000 / updateFreq);
+    };
+    onUpdate();
+    await updateCurrent();
+	whenDone();
+  }
+  updateLoop();
 }
-onLoad()
\ No newline at end of file
+onLoad();