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