Bedienoberfläche für Webradio
ulrich
2018-02-22 9af04242b4fb3bcbc52cad2992222ace5b4ea6cf
commit | author | age
623a61 1 var TPL_HOME = 'home';
U 2 var TPL_PREFS = 'prefs';
47a970 3 var TPL_SENDER = 'sender';
9e336a 4 var TPL_DLG_MSG = 'dlg-msg';
36646e 5 var TPL_DLG_INFO = 'dlg-info';
ffc872 6 var TPL_DLG_SENDER_NEU = 'dlg-sender-neu';
U 7 var TPL_DLG_SENDER_EDIT = 'dlg-sender-edit';
bdbb07 8 var TPL_DLG_SENDER_DEL = 'dlg-sender-del';
56852d 9 var TPL_SENDER_EDIT_FORM = 'sender-edit-form';
f9c6e2 10 var TPL_SENDER_KACHEL = 'sender-kachel';
576085 11 var TPL_ABSPIELER = 'abspieler';
f1e273 12 var TPL_DLG_ABSPIELER_NEU = 'dlg-abspieler-neu';
8d5292 13 var TPL_DLG_ABSPIELER_EDIT_FORM = 'dlg-abspieler-edit-form';
e1c80a 14 var TPL_DLG_ABSPIELER_DEL = 'dlg-abspieler-del';
089f14 15 var TPL_ABSPIELER_EINTRAG = 'abspieler-eintrag';
df379b 16 var templateCache = {}; // mustache templates
623a61 17 var prefsRendered = false;
abef80 18 var senderKlickModus = "1"; // 1=abspielen, 2=bearbeiten, 3=loeschen
f9c6e2 19 var ID_UNDEFINED = -1;
e73f1b 20 var A_ID_UNDEFINED = -1;
599f2f 21 var suchTimeout;
623a61 22
U 23 function app_init() {
abef80 24   $('.sued').text('Initialisieren..');
9f0d54 25   $('.dialog').hide();
623a61 26   $('.ost').hide();
abef80 27
U 28   // Menü initialisieren
136220 29   app_menu_init(
U 30     "data/menu/",
31     "hauptmenue.json",
32     "../jslib/app-menu/app-menu.tpl",
33     ".west",
34     "8em");
abef80 35
U 36   // Templates laden
8881ca 37   app_get_template('data/tpl/dlg-msg.tpl', TPL_DLG_MSG);
U 38   app_get_template('data/tpl/dlg-info.tpl', TPL_DLG_INFO);
39   app_get_template('data/tpl/sender.tpl', TPL_SENDER);
ffc872 40   app_get_template('data/tpl/dlg-sender-neu.tpl', TPL_DLG_SENDER_NEU);
U 41   app_get_template('data/tpl/dlg-sender-edit.tpl', TPL_DLG_SENDER_EDIT);
bdbb07 42   app_get_template('data/tpl/dlg-sender-loeschen.tpl', TPL_DLG_SENDER_DEL);
56852d 43   app_get_template('data/tpl/dlg-sender-edit-form.tpl', TPL_SENDER_EDIT_FORM);
f9c6e2 44   app_get_template('data/tpl/kachel.tpl', TPL_SENDER_KACHEL);
576085 45   app_get_template('data/tpl/abspieler.tpl', TPL_ABSPIELER);
f1e273 46   app_get_template('data/tpl/dlg-abspieler-neu.tpl', TPL_DLG_ABSPIELER_NEU);
089f14 47   app_get_template('data/tpl/abspieler-eintrag.tpl', TPL_ABSPIELER_EINTRAG);
e1c80a 48   app_get_template('data/tpl/dlg-abspieler-loeschen.tpl', TPL_DLG_ABSPIELER_DEL);
8d5292 49   app_get_template('data/tpl/dlg-abspieler-edit-form.tpl', TPL_DLG_ABSPIELER_EDIT_FORM);
03f9a7 50
abef80 51   // Klicks auf das Hamburger-Menü-Icon an eine Funktion leiten
U 52   $(".hamburger").on("click", function(e) {
03f9a7 53     app_menue_umschalten();
U 54   });
55
abef80 56   // Eingaben ins Suchfeld an eine Funktion leiten
599f2f 57   $(".sendersuche-eingabe").on('keyup', function() {
U 58     clearTimeout(suchTimeout);
59     suchTimeout = setTimeout('app_sendersuche()', 500);
60   });
abef80 61
U 62   // Abspieler und Sender laden
623a61 63   setTimeout(function() {
576085 64     app_get_abspieler();
a480d0 65     app_get_sender();
abef80 66     $('.sued').text('Bereit.');
623a61 67   }, 200);
47a970 68 }
U 69
599f2f 70 function app_sendersuche() {
U 71   var suchbegriff = $(".sendersuche-eingabe").val();
54eba2 72
599f2f 73   app_meldung_mit_timeout(
U 74     'Suchbegriff: ' + suchbegriff,
75     1500
76   );
54eba2 77
U 78   /*
79     nachfolgend wird ueber alle divs der Klasse sender-kachel
80     iteriert und diejenigen mit .hide() ausgeblendet, die nicht
81     den Suchbegiff im Namen tragen
82
83     evtl. findet sich spaeter noch eine elegantere Suchfunktion..
84   */
85
86   var divs = $(".sender-kachel");
87   if(suchbegriff.length > 0) {
88     divs.each(function(index, element) {
d5964d 89       if ($(element).html().indexOf(suchbegriff) < 0) {
54eba2 90         $(element).hide();
U 91       } else {
92         $(element).show();
93       }
94     });
95   } else {
96     $(divs).show();
97   }
03f9a7 98 }
U 99
100 function app_menue_umschalten() {
abef80 101   $(".hamburger").toggleClass("is-active"); // hamburger-icon umschalten
03f9a7 102   app_menu_toggle(); // menue oeffnen/schliessen
abef80 103 }
08bce7 104
abef80 105 /* Abspieler und abspielen */
U 106
107 function app_get_abspiel_ziel() {
108   var opt = $(".abspieler-auswahl :selected");
109   var atyp = opt.attr("atyp");
110   var aname = opt.text();
111   var aurl = opt.attr("aurl");
24a135 112   var zustand = opt.attr("standardzustand");
U 113   return new Abspieler(-1, aname, aurl, atyp, "", zustand);
abef80 114 }
U 115
116 /*
117   Abspiel-URL für Raspi:
118   http://raspi:8080/pirc/sys/rpc?c=de.uhilger.pirc.App&m=abspielen&p=http://bob.hoerradar.de/radiobob-live-mp3-hq&p=
c70430 119
U 120   der folgende Aufruf übergibt zusätzlich einen Parameter zum Abspielen über
121   das Audiokabel (nicht das HDMI-Kabel) des Raspi (sofern angeschlossen)
122   http://raspi-wz:8080/pirc/sys/rpc?c=de.uhilger.pirc.App
123   &m=abspielenMitParametern&p=http://bob.hoerradar.de/radiobob-live-mp3-hq
124   &p=-o%20local&p=
abef80 125 */
U 126 function app_abspielen(sender, abspieler) {
c70430 127   var url;
abef80 128   if(abspieler.typ === 'pirc') {
c70430 129     url =
abef80 130       abspieler.url +
c70430 131       '/sys/rpc?c=de.uhilger.pirc.App&m=abspielenMitParametern&p=' +
abef80 132       sender.url +
c70430 133       '&p=-o%20local&p=';
abef80 134     app_radio_kommando_senden(url);
U 135   } else {
c70430 136     url = sender.url;
U 137     var win = window.open(url, '_blank');
138     win.focus();
abef80 139   }
U 140 }
141
142 function app_abspielen_stoppen() {
143   var abspieler = app_get_abspiel_ziel();
144   if(abspieler.typ === 'pirc') {
145     var url =
146       abspieler.url +
147       '/sys/rpc?c=de.uhilger.pirc.App&m=kommando&p=q';
148     app_radio_kommando_senden(url);
149   } else {
150     // 'hier abspielen' stoppen muss noch gebaut werden
151   }
089f14 152 }
U 153
154 function app_abspieler_neu(abspieler) {
155   var html = Mustache.render(templateCache[TPL_ABSPIELER_EINTRAG], abspieler);
156   if(abspieler.zustand === 'selected') {
157     $.each($(".abspieler-auswahl option:selected"), function() {
158        $(this).prop('selected', false);
159     });
160   }
161   $(".abspieler-auswahl").append(html);
e1c80a 162 }
U 163
164 function app_abspieler_entfernen(abspieler) {
165   $(".abspieler-auswahl :selected").remove();
599f2f 166 }
U 167
3cecdc 168 /* Senderliste */
U 169
170 function app_kachel_anpassen(sender) {
171   var kachel = $( "div[sid='" + sender.id + "']" );
abef80 172   kachel.find(".sender-name").text(sender.name);
U 173   kachel.attr("data-verweis", sender.url);
174   kachel.find("img").attr("src", sender.logo);
f9c6e2 175 }
U 176
177 function app_kachel_neu(sender) {
178   var html = Mustache.render(templateCache[TPL_SENDER_KACHEL], sender);
179   $("#sender").append(html);
180   var kachel = $( "div[sid='" + sender.id + "']" );
abef80 181   kachel.on('click', app_kachel_klick);
f9c6e2 182 }
U 183
bdbb07 184 function app_kachel_entfernen(sender) {
U 185   $( "div[sid='" + sender.id + "']" ).remove();
186 }
187
f9c6e2 188 function app_kachel_klick() {
U 189   var kachel = $( this );
abef80 190   var senderId = kachel.attr("sid");
U 191   var senderName = kachel.find(".sender-name").text();
192   var senderUrl = kachel.attr("data-verweis");
193   var senderLogo = kachel.find("img").attr("src");
f9c6e2 194   var s = new Sender(senderId, senderName, senderUrl, senderLogo);
U 195   switch (senderKlickModus) {
196       case "1":
abef80 197         app_abspielen(s, app_get_abspiel_ziel());
f9c6e2 198         break;
U 199       case "2":
200         $(".dlg-behaelter").html(
201           Mustache.render(templateCache[TPL_SENDER_EDIT_FORM], s)
202         );
203         $('#sender-speichern').on('click', function() {
204           $('#sender-speichern').off('click');
205           app_kachel_anpassen(app_sender_dialog_lesen(senderId));
206           app_dialog_schliessen();
207           app_meldung_mit_timeout('Speichern gewaehlt', 1500);
208         });
209         break;
210       case "3":
babc24 211         app_dialog_zeigen(templateCache[TPL_DLG_SENDER_DEL], s);
U 212         /*
bdbb07 213         $(".dlg-behaelter").html(
U 214           Mustache.render(templateCache[TPL_DLG_SENDER_DEL], s)
215         );
babc24 216         */
bdbb07 217         $('#sender-loeschen').on('click', function() {
U 218           $('#sender-loeschen').off('click');
219           app_kachel_entfernen(s);
220           app_dialog_schliessen();
221           app_meldung_mit_timeout('Loeschen gewaehlt ' + s.name, 1500);
222         });
babc24 223         //app_menue_umschalten();
f9c6e2 224         break;
U 225       default:
226         app_meldung_mit_timeout(
227           'Sender ' + s.name + ', ID ' + s.id,
228           1500
229         );
230         break;
231   }
3cecdc 232 }
U 233
8881ca 234 /* --- Menüfunktionen --- */
U 235
9f0d54 236 function app_nachricht_test() {
e6c850 237   app_dialog_laden_und_zeigen(
U 238     templateCache[TPL_DLG_MSG], 'data/msg-test.json');
03f9a7 239   app_menue_umschalten();
36646e 240 }
U 241
242 function app_info_dialog_zeigen() {
b520d1 243   app_dialog_laden_und_zeigen(templateCache[TPL_DLG_INFO], '');
03f9a7 244   app_menue_umschalten();
8881ca 245 }
U 246
5226a2 247 function app_neuer_sender() {
ffc872 248   app_dialog_laden_und_zeigen(templateCache[TPL_DLG_SENDER_NEU], '');
b520d1 249   $('#sender-speichern').on('click', function() {
136220 250     $('#sender-speichern').off('click');
f9c6e2 251     app_kachel_neu(app_sender_dialog_lesen(--ID_UNDEFINED));
b520d1 252     app_dialog_schliessen();
742e75 253     app_meldung_mit_timeout('Speichern gewaehlt', 1500);
b520d1 254   });
03f9a7 255   app_menue_umschalten();
5226a2 256 }
U 257
742e75 258 function app_sender_bearbeiten() {
56852d 259   senderKlickModus = "2"; // bearbeiten
ffc872 260   app_dialog_laden_und_zeigen(templateCache[TPL_DLG_SENDER_EDIT], '');
03f9a7 261   app_menue_umschalten();
742e75 262 }
5226a2 263
742e75 264 function app_sender_loeschen() {
bdbb07 265   senderKlickModus = "3"; // loeschen
U 266   app_dialog_laden_und_zeigen(templateCache[TPL_DLG_SENDER_EDIT], '');
03f9a7 267   app_menue_umschalten();
742e75 268 }
U 269
69ffa5 270 function app_abspieler_loeschen() {
e1c80a 271   var abspieler = app_get_abspiel_ziel();
U 272   app_dialog_zeigen(templateCache[TPL_DLG_ABSPIELER_DEL], abspieler);
273   $('#abspieler-loeschen').on('click', function() {
274     $('#abspieler-loeschen').off('click');
275     app_abspieler_entfernen(abspieler);
276     app_dialog_schliessen();
277     app_meldung_mit_timeout('Loeschen gewaehlt ' + abspieler.name, 1500);
278   });
03f9a7 279   app_menue_umschalten();
69ffa5 280 }
U 281 function app_neuer_abspieler() {
f1e273 282   app_dialog_laden_und_zeigen(templateCache[TPL_DLG_ABSPIELER_NEU], '');
U 283   $('#abspieler-speichern').on('click', function() {
284     $('#abspieler-speichern').off('click');
089f14 285     app_abspieler_neu(app_abspieler_dialog_lesen(--A_ID_UNDEFINED));
f1e273 286     app_dialog_schliessen();
U 287     app_meldung_mit_timeout('Speichern gewaehlt', 1500);
288   });
03f9a7 289   app_menue_umschalten();
69ffa5 290 }
U 291 function app_abspieler_bearbeiten() {
cb2424 292   var abspieler = app_get_abspiel_ziel();
d52d2a 293   app_dialog_zeigen(templateCache[TPL_DLG_ABSPIELER_EDIT_FORM], abspieler);
24a135 294   $("#abspieler-typ").val(abspieler.typ);
U 295   $("#abspieler-zustand").val(abspieler.zustand);
8d5292 296   $('#abspieler-speichern').on('click', function() {
U 297     $('#abspieler-speichern').off('click');
298
24a135 299     // Aenderungen auf die Bedienoberflaeche uebernehmen
U 300     var abspieler = app_abspieler_dialog_lesen();
301     if(abspieler.zustand === 'selected') {
302       $(".abspieler-auswahl").children().attr("standardzustand", "");
303     }
304     var opt = $(".abspieler-auswahl :selected");
305     opt.attr("atyp", abspieler.typ);
306     opt.attr("aurl", abspieler.url);
307     opt.attr("standardzustand", abspieler.zustand);
308     opt.text(abspieler.name);
309
8d5292 310     /*
24a135 311       hier fehlt noch eine Funktion zum Speichern
U 312       der Aenderungen
8d5292 313     */
24a135 314
8d5292 315     app_dialog_schliessen();
U 316     app_meldung_mit_timeout('Speichern gewaehlt', 1500);
317   });
03f9a7 318   app_menue_umschalten();
69ffa5 319 }
U 320
742e75 321 /* --- Dialogfunktionen --- */
8881ca 322
U 323 function app_dialog_zeigen(vorlage, inhalt) {
abef80 324   var dlg = $(".dialog");
U 325   dlg.html(Mustache.render(vorlage, inhalt));
8881ca 326   $(".close-btn").on('click', function() {
b520d1 327     app_dialog_schliessen();
8881ca 328   });
abef80 329   dlg.slideDown(300);
f9c6e2 330 }
U 331
332 function app_sender_dialog_lesen(senderId) {
333   var nameNeu = $("#sender-name").val();
334   var logoNeu = $("#sender-logo").val();
335   var urlNeu = $("#sender-url").val();
336   return new Sender(senderId, nameNeu, urlNeu, logoNeu);
b520d1 337 }
U 338
e73f1b 339 function app_abspieler_dialog_lesen(abspielerId) {
U 340   var aName = $("#abspieler-name").val();
341   var aUrl = $("#abspieler-url").val();
342   var aTyp = $("#abspieler-typ").val();
343   var aBild = $("#abspieler-bild").val();
344   var aZustand = $("#abspieler-zustand").val();
345   return new Abspieler(abspielerId, aName, aUrl, aTyp, aBild, aZustand);
346 }
347
b520d1 348 function app_dialog_schliessen() {
abef80 349   senderKlickModus = "1";
136220 350   $('.close-btn').off('click');
b520d1 351   $('.dialog').slideUp(300);
9f0d54 352 }
U 353
742e75 354 /* --- Meldungen in der Fusszeile --- */
U 355
356 /*
357   Eine Meldung eine Zeitlang in der Fusszeile anzeigen
358
359   meldung - Text der Meldung
360   timeout - die Anzahl Millisekunden, die eine Meldung zu sehen sein soll
361 */
362 function app_meldung_mit_timeout(meldung, timeout) {
abef80 363   var s = $('.sued');
U 364   s.text(meldung);
742e75 365   setTimeout(function() {
abef80 366     s.text('Bereit.');
742e75 367   }, timeout);
U 368 }
369
47a970 370 /* --- Ajax-Aufrufe --- */
U 371
a480d0 372 function app_get_sender() {
U 373   $.ajax({
0c85a2 374     url: "data/sender.json",
a480d0 375     type: "GET",
U 376     dataType : "json"
377   }).done(function( senderliste ) {
56852d 378     $(".sender-kachel").off("click");
U 379     $(".sender-behaelter").html(
380       Mustache.render(templateCache[TPL_SENDER], senderliste));
f9c6e2 381     $('.sender-kachel').on('click', app_kachel_klick);
a480d0 382   });
U 383 }
384
576085 385 function app_get_abspieler() {
U 386   $.ajax({
387     url: "data/abspieler.json",
388     type: "GET",
389     dataType : "json"
390   }).done(function( abspielerliste ) {
391     $(".abspieler-behaelter").html(
392       Mustache.render(templateCache[TPL_ABSPIELER], abspielerliste));
abef80 393     $("#abspielen-stoppen").on('click', app_abspielen_stoppen);
576085 394   });
U 395 }
396
8d5292 397 /*
U 398   vorlage - die Dialogvorlage
399   msgTpl - eine Vorlage mit einem Mitteilungstext (optional)
400 */
401 function app_dialog_laden_und_zeigen(vorlage, msgTpl) {
98c715 402   if(msgTpl !== '') {
36646e 403     $.ajax({
8d5292 404       url: msgTpl,
36646e 405       type: "GET",
U 406       dataType : "json"
407     }).done(function( msg ) {
8881ca 408       app_dialog_zeigen(vorlage, msg);
36646e 409     });
U 410   } else {
8881ca 411     app_dialog_zeigen(vorlage, '');
36646e 412   }
abef80 413 }
U 414
415 function app_radio_kommando_senden(kommando) {
416   $.ajax({
417     url: kommando,
418     type: "GET",
419     dataType : "text",
420     crossDomain: true
421   }).done(function( antwort ) {
422     /*
423       der folgende Schritt wird nicht erreicht, weil beim Aufruf
424       aus dem Browser heraus keine Adresse aufgerufen werden darf,
425       die nicht von der Domain kommt, von der aus das radio-ui
426       ausgeliefert wird.
427
428       Kommt das radio-ui z.B. von der Domain uhilger.de, wird ein Aufruf
429       zur Domain raspi-az blockiert.
430
431       Das laesst sich vermeiden, wenn der Server den Aufruf zum Raspi
432       uebernimmt.
433
434       Interessanterweise kommt der Aufruf zum Raspi durch und löst auch
435       das Abspielen des Radiosenders aus. Nur die Antwort vom Raspi wird
436       blockiert und hier nicht ausgegeben.
437     */
438     app_meldung_mit_timeout(antwort, 2000);
439   }).fail(function(xhr, status, errorThrown ) {
440     app_meldung_mit_timeout(errorThrown + " " + status, 2000);
441   });
9e336a 442 }
U 443
47a970 444 /*
U 445   Ein Template vom Server in den Cache laden
446   template_url - home.tpl, prefs.tpl, sender.tpl
447   tname - 'home', 'prefs', 'sender'
448 */
449 function app_get_template(template_url, tname) {
450   $.ajax({
451     url: template_url,
452     type: "GET",
453     dataType : "text"
454   }).done(function( template ) {
455     templateCache[tname] = template;
456   });
623a61 457 }
e6c850 458
U 459 /* Objekte */
460
461 function Sender(i, n, u, l) {
462   this.id = i;
463   this.name = n;
464   this.url = u;
465   this.logo = l;
466 }
abef80 467
U 468 function Abspieler(i, n, u, t, b, z) {
469   this.id = i;
470   this.name = n;
471   this.url = u;
472   this.typ = t;
473   this.bild = b;
474   this.zustand = z;
475 }