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