Persoenliche Mediazentrale
ulrich
2021-04-09 245ac197112b653193be4672ed9940bfd0c83d0e
commit | author | age
b379f5 1 function Mediazentrale() {
cfa858 2   var self = this;
U 3   var appMenu;
4   var cache; // mustache templates
86bbf7 5   var ortPfad;
U 6   var mediaPfad;
e60cff 7   var katUrl;
U 8   var selTitel;
f45e20 9
U 10   this.init = function () {
11     self.mediaPfad = '/';
12     self.ortPfad = '/';
13     self.cache = new Array();
14     self.appMenu = new AppMenu();
15     self.appMenu.init(
16             "data/menu/",
17             "hauptmenue.json",
18             "data/tpl/app-menu.tpl",
19             ".west",
20             "8em");
21
22     document.querySelector('.hamburger').addEventListener('click', function (e) {
23       self.menue_umschalten();
24     });
25     
26     self.addEvtListener('#mi-katalog', 'click', self.media_liste);
27     self.addEvtListener('#mi-orte', 'click', self.ablageort_liste);
28     self.addEvtListener('#mi-prefs', 'click', self.prefs_liste);
29     self.addEvtListener('#mi-player', 'click', self.abspieler_liste);
8d7d35 30     self.addEvtListener('#mi-listen', 'click', self.abspielliste_liste);
U 31     self.addEvtListener('#mi-list', 'click', self.titel_liste);
f45e20 32     
U 33     self.fusszeile_umschalten();
34     self.seitenleiste_umschalten();
35     self.dialog_unten_zeigen();
36   };
37   
38   this.abspieler_auswahl_fuellen = function() {
39     self.http_get('../api/store/Abspieler/', function (responseText) {
40       /*
41        {"ArrayList": [{"name":"Wohnz","url":"http://rpi4-wz:9090/"},{"name":"Arbz","url":"http://rpi4-az:9090/"}]}
42        */
43       self.vorlage_laden_und_fuellen("data/tpl/abs_sel.tpl", JSON.parse(responseText), function (html) {
44         document.querySelector(".abs-sel").innerHTML = html;
45       });    
46     });
47   };
48
8d7d35 49   this.abspielliste_auswahl_fuellen = function() {
U 50     self.http_get('../api/store/Abspielliste/', function (responseText) {
51       /*
52           ?
53        */
54       self.vorlage_laden_und_fuellen("data/tpl/pl_sel.tpl", JSON.parse(responseText), function (html) {
55         document.querySelector(".pl-sel").innerHTML = html;
56       });    
57     });
58   };
59   
f45e20 60   /* Unterer Einblendbereich */
U 61   
62   this.dialog_unten_zeigen = function() {
63     self.vorlage_laden_und_fuellen("data/tpl/ctrl.tpl", "", function (html) {
64       var dlg = document.querySelector(".dialog-unten");
65       dlg.style.height = '4.5em';
66       dlg.innerHTML = html;
67       self.abspieler_auswahl_fuellen();
8d7d35 68       self.abspielliste_auswahl_fuellen();
e60cff 69       self.addEvtListener('#dazu-btn', 'click', self.addSelectedTitel);
8d7d35 70       self.media_liste();
f45e20 71     });
U 72   };
73
8d7d35 74   /* ---------------- Titel einer Abspielliste ----------------- */
U 75   
76   this.titel_liste = function() {
fcc734 77     self.reset_top_buttons();
U 78     var plname = document.querySelector('#playlist').value;
79     self.http_get('../api/alist/' + plname, function (responseText) {
80       self.vorlage_laden_und_fuellen("data/tpl/titel_liste.tpl", JSON.parse(responseText), function (html) {
8d7d35 81         document.querySelector(".zentraler-inhalt").innerHTML = html;
U 82         self.addEvtListener('.entity-eintrag', 'click', function (event) {
83           var t = event.target;
fcc734 84           self.removeClassMulti('selected');
U 85           t.classList.add('selected');
86
87           /*
8d7d35 88           self.http_get('../api/store/Ablageort/' + t.textContent, function(responseText){
U 89             var ablageort = JSON.parse(responseText);
90             self.ablageort_form(ablageort);
91           });
fcc734 92           */
8d7d35 93         });
fcc734 94         /*
8d7d35 95         self.addEvtListener('#neu-btn', 'click', function (event) {
U 96           eval("self.ablageort_form" + "(this)");
fcc734 97         });
U 98         */
8d7d35 99       });
U 100     });
101   };
102     
103   /* ---------------- Entitaets-Listen ----------------- */
104
105   self.reset_top_buttons = function() {
106     self.vorlage_laden_und_fuellen("data/tpl/top_btns.tpl", '', function (html) {
107       document.querySelector(".top-btns").innerHTML = html;
108     });
109   };
86bbf7 110   
U 111   // auf der obersten Ebene werden die Kataloge angezeigt,
112   // darunter der Inhalt des aktuellen Pfades
113   this.media_liste = function() {
8d7d35 114     self.reset_top_buttons();
86bbf7 115     if(self.ortPfad === '/') {
U 116       // Kataloge listen
f45e20 117       self.http_get('../api/store/Ablageort/liste/', function (responseText) {
8d7d35 118         //document.querySelector('#top-up-btn').removeEventListener('click', self.media_liste_herauf);
86bbf7 119         self.vorlage_laden_und_fuellen("data/tpl/katalog_root_liste.tpl", JSON.parse(responseText), function (html) {
U 120           document.querySelector(".zentraler-inhalt").innerHTML = html;
121           self.addEvtListener('.entity-eintrag', 'click', function (event) {
122             var t = event.target;
123             self.http_get('../api/store/Ablageort/' + t.textContent, function(responseText) {
124               var ablageort = JSON.parse(responseText);
125               self.ortPfad = ablageort.url;
126               self.media_liste();
127             });
128           });
129         });
130       });
131     } else {
3271f1 132       var url = '..' + self.ortPfad + self.mediaPfad;
U 133       if(!url.endsWith('/')) {
134         url = url + '/';
135       }
136       self.http_get(url, function(responseText) {
86bbf7 137         self.vorlage_laden_und_fuellen("data/tpl/katalog_inhalt_liste.tpl", JSON.parse(responseText), function (html) {
U 138           document.querySelector(".zentraler-inhalt").innerHTML = html;
139           self.addEvtListener('.entity-eintrag', 'click', function (event) {
140             var t = event.target;
3271f1 141             var tx = t.textContent;
86bbf7 142             if(t.classList.contains("entity-typ-folder")) {
3271f1 143               if(self.mediaPfad.endsWith('/')) {
U 144                 self.mediaPfad = self.mediaPfad + tx;                
145               } else {
146                 self.mediaPfad = self.mediaPfad + '/' + tx;
147               }
86bbf7 148               self.media_liste();
U 149             } else {
37eadf 150               if(t.classList.contains('selected')) {
U 151                 self.addSelectedTitel();
152               } else {
153                 self.removeClassMulti('selected');
154                 t.classList.add('selected');
155               }
e60cff 156               //self.selTitel = new Titel(t.textContent, self.ortPfad);       
86bbf7 157             }
U 158           });
8d7d35 159           self.addEvtListener('#top-up-btn', 'click', function(event) {
86bbf7 160             if(self.mediaPfad === '/') {
U 161               self.ortPfad = '/';              
162             } else {
163               var pos = self.mediaPfad.lastIndexOf('/');
3271f1 164               var parent;
U 165               if(pos > 1) {
166                 parent = self.mediaPfad.substring(0, pos);
167               } else {
168                 parent = '/';
169               }
86bbf7 170               self.mediaPfad = parent;
U 171             }
172             self.media_liste();
8d7d35 173           });
86bbf7 174         });
U 175       });
176     }
e60cff 177   };
U 178   
245ac1 179   /*
U 180
181         {"Medialiste": [{"name":"sound_city.m4v","typ":"video","interpret":"","titelAnzName":"","album":""},{"name":"sub","typ":"folder","interpret":"","titelAnzName":"","album":""},{"name":"Aufnahmen.ods","typ":"file","interpret":"","titelAnzName":"","album":""},{"name":"index.html","typ":"file","interpret":"","titelAnzName":"","album":""},{"name":"A","typ":"folder","interpret":"","titelAnzName":"","album":""},{"name":"sleepers.m4v","typ":"video","interpret":"","titelAnzName":"","album":""}]}
182
183
184         function Titel(n, p, u, i, t, a) {
185           this.katalogUrl = u;
186           this.pfad = p;
187           this.name = n;
188           this.interpret = i;
189           this.titelAnzName = t;
190           this.album  = a;
191         }
192
193    */
194   
e60cff 195   this.addSelectedTitel = function() {
245ac1 196     var elem = document.querySelector(".selected");
U 197     var titelName = elem.textContent;
198     var album = elem.attributes.album.nodeValue;
199     var interpret = elem.attributes.interpret.nodeValue;
200     var anzName = elem.attributes.titelAnzName.nodeValue;
fcc734 201     var titel;
U 202     if(self.mediaPfad.endsWith('/')) {
245ac1 203       titel = new Titel(titelName, self.mediaPfad, self.ortPfad, interpret, anzName, album);
fcc734 204     } else {
245ac1 205       titel = new Titel(titelName, self.mediaPfad + '/', self.ortPfad, interpret, anzName, album);
fcc734 206     }
e60cff 207     var plname = document.querySelector('#playlist').value;
U 208     self.http_put('../api/alist/' + plname, JSON.stringify(titel), function(responseText) {
8e2578 209       self.meldung_mit_timeout(responseText, 1500);
e60cff 210     });
86bbf7 211   };
cfa858 212
a43e1a 213   this.ablageort_liste = function() {
8d7d35 214     self.reset_top_buttons();
f45e20 215     self.http_get('../api/store/Ablageort/liste/', function (responseText) {
a43e1a 216       self.vorlage_laden_und_fuellen("data/tpl/ablageort_liste.tpl", JSON.parse(responseText), function (html) {
U 217         document.querySelector(".zentraler-inhalt").innerHTML = html;
218         self.addEvtListener('.entity-eintrag', 'click', function (event) {
219           var t = event.target;
90f5d4 220           self.http_get('../api/store/Ablageort/' + t.textContent, function(responseText){
86bbf7 221             var ablageort = JSON.parse(responseText);
90f5d4 222             self.ablageort_form(ablageort);
U 223           });
a43e1a 224         });
8d7d35 225         //self.addEvtListener('#neu-btn', 'click', function (event) {
U 226         self.addEvtListener('#top-neu-btn', 'click', function(event) {
faab2d 227           eval("self.ablageort_form" + "(this)");
U 228         });        
cf6509 229       });
U 230     });
231   };
232
233   this.prefs_liste = function() {
8d7d35 234     self.reset_top_buttons();
f45e20 235     self.http_get('../api/store/Einstellung/liste/', function (responseText) {
cf6509 236       self.vorlage_laden_und_fuellen("data/tpl/einstellung_liste.tpl", JSON.parse(responseText), function (html) {
U 237         document.querySelector(".zentraler-inhalt").innerHTML = html;
238         self.addEvtListener('.entity-eintrag', 'click', function (event) {
239           var t = event.target;
240           self.http_get('../api/store/Einstellung/' + t.textContent, function(responseText){
241             var einstellung = JSON.parse(responseText);
242             self.prefs_form(einstellung);
243           });
244         });
8d7d35 245         self.addEvtListener('#top-neu-btn', 'click', function(event) {
cf6509 246           eval("self.prefs_form" + "(this)");
U 247         });        
248       });
249     });
250   };
251
3d4bca 252   this.abspieler_liste = function() {
f45e20 253     self.http_get('../api/store/Abspieler/liste/', function (responseText) {
3d4bca 254       self.vorlage_laden_und_fuellen("data/tpl/abspieler_liste.tpl", JSON.parse(responseText), function (html) {
U 255         document.querySelector(".zentraler-inhalt").innerHTML = html;
256         self.addEvtListener('.entity-eintrag', 'click', function (event) {
257           var t = event.target;
258           self.http_get('../api/store/Abspieler/' + t.textContent, function(responseText){
259             var abspieler = JSON.parse(responseText);
260             self.abspieler_form(abspieler);
261           });
262         });
8d7d35 263         self.addEvtListener('#neu-btn', 'click', function(event) {
3d4bca 264           eval("self.abspieler_form" + "(this)");
8d7d35 265         });           
U 266       });
267     });
268   };
269   
270   this.abspielliste_liste = function() {
271     self.http_get('../api/store/Abspielliste/liste/', function (responseText) {
272       self.vorlage_laden_und_fuellen("data/tpl/abspielliste_liste.tpl", JSON.parse(responseText), function (html) {
273         document.querySelector(".zentraler-inhalt").innerHTML = html;
274         self.addEvtListener('.entity-eintrag', 'click', function (event) {
275           var t = event.target;
276           self.http_get('../api/store/Abspielliste/' + t.textContent, function(responseText){
277             var abspielliste = JSON.parse(responseText);
278             self.abspielliste_form(abspielliste);
279           });
280         });
281         self.addEvtListener('#top-neu-btn', 'click', function(event) {
282           eval("self.abspielliste_form" + "(this)");
283         });            
284       });
285     });
286   };
287   
288   /* -------------------- Entitaets-Formulare ------------------ */
289   
290   this.abspielliste_form = function(al) {
291     self.vorlage_laden_und_fuellen("data/tpl/form_abspielliste.tpl", al, function (html) {
292       document.querySelector(".zentraler-inhalt").innerHTML = html;
293       self.addEvtListener('#ok-btn', 'click', function () {
294         var alname = document.querySelector('#abspielliste-name').value;
295         alname = alname.replace(' ', '').replace(/[\W]+/g, '');
296         var abspielliste = new Abspielliste(
297           alname
298         );
299         var daten = JSON.stringify(abspielliste);        
300         //if(typeof pl === "undefined" || pl.key !== plname) {
301         if(typeof al.name === "undefined" || al.name.length < 1) {
302           // neu
303           self.http_put('../api/store/Abspielliste/' + alname, daten, function (responseText) {
304             // hier die Antwort verarbeiten
305             self.abspielliste_auswahl_fuellen();
306             self.abspielliste_liste();
307           });
308         } else {
309           // aendern
310           self.http_put('../api/store/Abspielliste/' + al.name, daten, function (responseText) {
311             // hier die Antwort verarbeiten
312             self.abspielliste_auswahl_fuellen();
313             self.abspielliste_liste();
314           });
315         }
316       });
317       self.addEvtListener('#cancel-btn', 'click', function () {
318         //document.querySelector(".zentraler-inhalt").innerHTML = '';
319         self.abspielliste_liste();
320       });
321       self.addEvtListener('#loeschen-btn', 'click', function() {
322         var alname = document.querySelector('#abspielliste-name').value;
323         var dlgdata = {"del-elem": alname};
324         self.dialog_laden_und_zeigen('data/tpl/dlg-loeschen.tpl', dlgdata, function() {
325           self.addEvtListener('#nein-btn', 'click', self.dialog_schliessen);
326           self.addEvtListener('#ja-btn', 'click', function() {
327             self.http_delete('../api/store/Abspielliste/' + alname, '', function (responseText) {
328               // hier die Antwort verarbeiten
329               self.dialog_schliessen();
330               //document.querySelector(".zentraler-inhalt").innerHTML = '';
331               self.abspielliste_auswahl_fuellen();
332               self.abspielliste_liste();
333             });
334           });
335         });
3d4bca 336       });
U 337     });
338   };
339
340   this.abspieler_form = function(pl) {
341     self.vorlage_laden_und_fuellen("data/tpl/form_abspieler.tpl", pl, function (html) {
342       document.querySelector(".zentraler-inhalt").innerHTML = html;
343       self.addEvtListener('#ok-btn', 'click', function () {
344         var plname = document.querySelector('#abspieler-name').value;
345         plname = plname.replace(' ', '').replace(/[\W]+/g, '');
346         var abspieler = new Abspieler(
347           plname,
348           document.querySelector('#abspieler-url').value
349         );
350         var daten = JSON.stringify(abspieler);        
dfb7d3 351         //if(typeof pl === "undefined" || pl.key !== plname) {
U 352         if(typeof pl.name === "undefined" || pl.name.length < 1) {
3d4bca 353           // neu
dfb7d3 354           self.http_put('../api/store/Abspieler/' + plname, daten, function (responseText) {
3d4bca 355             // hier die Antwort verarbeiten
dfb7d3 356             self.abspieler_auswahl_fuellen();
U 357             self.abspieler_liste();
3d4bca 358           });
U 359         } else {
360           // aendern
dfb7d3 361           self.http_put('../api/store/Abspieler/' + pl.name, daten, function (responseText) {
3d4bca 362             // hier die Antwort verarbeiten
dfb7d3 363             self.abspieler_auswahl_fuellen();
U 364             self.abspieler_liste();
3d4bca 365           });
U 366         }
367       });
368       self.addEvtListener('#cancel-btn', 'click', function () {
369         //document.querySelector(".zentraler-inhalt").innerHTML = '';
370         self.abspieler_liste();
371       });
372       self.addEvtListener('#loeschen-btn', 'click', function() {
373         var plname = document.querySelector('#abspieler-name').value;
374         var dlgdata = {"del-elem": plname};
375         self.dialog_laden_und_zeigen('data/tpl/dlg-loeschen.tpl', dlgdata, function() {
376           self.addEvtListener('#nein-btn', 'click', self.dialog_schliessen);
377           self.addEvtListener('#ja-btn', 'click', function() {
378             self.http_delete('../api/store/Abspieler/' + plname, '', function (responseText) {
379               // hier die Antwort verarbeiten
380               self.dialog_schliessen();
381               //document.querySelector(".zentraler-inhalt").innerHTML = '';
dfb7d3 382               self.abspieler_auswahl_fuellen();
3d4bca 383               self.abspieler_liste();
U 384             });
385           });
386         });
387       });
388     });
389   };
cf6509 390
U 391   this.prefs_form = function(k) {
392     self.vorlage_laden_und_fuellen("data/tpl/form_einstellung.tpl", k, function (html) {
393       document.querySelector(".zentraler-inhalt").innerHTML = html;
394       self.addEvtListener('#ok-btn', 'click', function () {
395         var pkey = document.querySelector('#einstellung-key').value;
396         pkey = pkey.replace(' ', '').replace(/[\W]+/g, '');
397         var pref = new Einstellung(
398           pkey,
399           document.querySelector('#einstellung-value').value
400         );
401         var daten = JSON.stringify(pref);        
dfb7d3 402         //if(typeof k === "undefined" || k.key !== pkey) {
U 403         if(typeof k.key === "undefined" ||  k.key.length < 1) {
cf6509 404           // neu
dfb7d3 405           self.http_put('../api/store/Einstellung/' + pkey, daten, function (responseText) {
cf6509 406             // hier die Antwort verarbeiten
dfb7d3 407             self.prefs_liste();
cf6509 408           });
U 409         } else {
410           // aendern
dfb7d3 411           self.http_put('../api/store/Einstellung/' + k.key, daten, function (responseText) {
cf6509 412             // hier die Antwort verarbeiten
dfb7d3 413             self.prefs_liste();
cf6509 414           });
U 415         }
416       });
417       self.addEvtListener('#cancel-btn', 'click', function () {
418         //document.querySelector(".zentraler-inhalt").innerHTML = '';
419         self.prefs_liste();
420       });
421       self.addEvtListener('#loeschen-btn', 'click', function() {
422         var pkey = document.querySelector('#einstellung-key').value;
423         var dlgdata = {"del-elem": pkey};
424         self.dialog_laden_und_zeigen('data/tpl/dlg-loeschen.tpl', dlgdata, function() {
425           self.addEvtListener('#nein-btn', 'click', self.dialog_schliessen);
426           self.addEvtListener('#ja-btn', 'click', function() {
427             self.http_delete('../api/store/Einstellung/' + pkey, '', function (responseText) {
428               // hier die Antwort verarbeiten
429               self.dialog_schliessen();
430               //document.querySelector(".zentraler-inhalt").innerHTML = '';
431               self.prefs_liste();
432             });
433           });
434         });
a43e1a 435       });
U 436     });
437   };
cfa858 438
90f5d4 439   /* 
U 440    * Ablageort-Formular anzeigen
441    * 
442    * {"name":"Katalog 2","ort":"/home/ulrich/Videos","url":"/media/kat2"}: 
443    * 
444    * @param {type} ablageort  der Ablageort, der bearbeitet werden soll, leer fuer neuen Ort
445    * @returns {undefined} kein Rueckgabewert
446    */
447   this.ablageort_form = function(ort) {
448     self.vorlage_laden_und_fuellen("data/tpl/form_ablageort.tpl", ort, function (html) {
b379f5 449       document.querySelector(".zentraler-inhalt").innerHTML = html;
f074f6 450       self.addEvtListener('#ok-btn', 'click', function () {
2597cd 451         var aName = document.querySelector('#ablageort-name').value;
U 452         aName = aName.replace(' ', '').replace(/[\W]+/g, '');
b379f5 453         var a = new Ablageort(
2597cd 454           aName,
b379f5 455           document.querySelector('#ablageort-ort').value,
U 456           document.querySelector('#ablageort-url').value
457         );
90f5d4 458         var daten = JSON.stringify(a);        
dfb7d3 459         //if(typeof ort === "undefined" || ort.name !== aName) {
U 460         if(typeof ort.name === "undefined"  || ort.name.length < 1) {
2597cd 461           // neu
dfb7d3 462           self.http_put('../api/store/Ablageort/' + aName, daten, function (responseText) {
90f5d4 463             // hier die Antwort verarbeiten
dfb7d3 464             self.ablageort_liste();
90f5d4 465           });
U 466         } else {
2597cd 467           // aendern
dfb7d3 468           self.http_put('../api/store/Ablageort/' + ort.name, daten, function (responseText) {
90f5d4 469             // hier die Antwort verarbeiten
dfb7d3 470             self.ablageort_liste();
90f5d4 471           });
U 472         }
b379f5 473       });
f074f6 474       self.addEvtListener('#cancel-btn', 'click', function () {
b29119 475         //document.querySelector(".zentraler-inhalt").innerHTML = '';
faab2d 476         self.ablageort_liste();
5b7356 477       });
U 478       self.addEvtListener('#loeschen-btn', 'click', function() {
479         var aoname = document.querySelector('#ablageort-name').value;
480         var dlgdata = {"del-elem": aoname};
481         self.dialog_laden_und_zeigen('data/tpl/dlg-loeschen.tpl', dlgdata, function() {
482           self.addEvtListener('#nein-btn', 'click', self.dialog_schliessen);
483           self.addEvtListener('#ja-btn', 'click', function() {
90f5d4 484             self.http_delete('../api/store/Ablageort/' + aoname, '', function (responseText) {
U 485               // hier die Antwort verarbeiten
2597cd 486               self.dialog_schliessen();
b29119 487               //document.querySelector(".zentraler-inhalt").innerHTML = '';
faab2d 488               self.ablageort_liste();
90f5d4 489             });
5b7356 490           });
U 491         });
b379f5 492       });
U 493     });
494   };
495
7c22a2 496   this.addEvtListener = function(selector, eventName, func) {
U 497     document.querySelectorAll(selector).forEach(elem => { elem.addEventListener(eventName, func); });
498   };
499   
500   this.removeClassMulti = function(selector) {
501     document.querySelectorAll('.' + selector).forEach(elem => { elem.classList.remove(selector); });
502   };
503
f45e20 504   /* --------------------- asynchroner HTTP Client ----------------- */
faab2d 505   
f074f6 506   this.http_get = function (u, cb) {
b379f5 507     self.http_call('GET', u, null, cb);
U 508   };
f074f6 509
U 510   this.http_post = function (u, data, cb) {
b379f5 511     self.http_call('POST', u, data, cb);
U 512   };
513
90f5d4 514   this.http_put = function (u, data, cb) {
U 515     self.http_call('PUT', u, data, cb);
516   };
517   
5b7356 518   this.http_delete = function (u, data, cb) {
2597cd 519     console.log("delete " + u);
5b7356 520     self.http_call('DELETE', u, data, cb);
U 521   };
522   
f074f6 523   this.http_call = function (method, u, data, scallback) {
b379f5 524     var xhr = new XMLHttpRequest();
U 525     var url = u;
f074f6 526     xhr.onreadystatechange = function () {
b379f5 527       if (this.readyState === 4 && this.status === 200) {
U 528         scallback(this.responseText);
529       }
530     };
531     xhr.open(method, url);
f074f6 532     if (method === 'GET') {
b379f5 533       xhr.send();
2597cd 534     } else if (method === 'POST' || method === 'PUT' || method === 'DELETE') {
b379f5 535       xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
U 536       xhr.send(data);
537     }
538   };
8239d1 539   
f45e20 540   /* ------------------------ aus App-Vorlage -------------------  */
cfa858 541
f074f6 542   this.menue_umschalten = function () {
cfa858 543     var ham = document.querySelector(".hamburger");
U 544     ham.classList.toggle("is-active"); // hamburger-icon umschalten
545     self.appMenu.toggle(); // menue oeffnen/schliessen
546   };
547
f074f6 548   this.info_dialog_zeigen = function () {
cfa858 549     self.dialog_laden_und_zeigen('data/tpl/dlg-info.tpl', '');
U 550     self.menue_umschalten();
551   };
552
f074f6 553   this.seitenleiste_umschalten = function () {
cfa858 554     var ostDiv = document.querySelector('.ost');
f074f6 555     if (ostDiv.classList.contains('ost-open')) {
cfa858 556       ostDiv.classList.remove('ost-open');
f074f6 557       ostDiv.style.flexBasis = '0em';
cfa858 558     } else {
f074f6 559       ostDiv.classList.add('ost-open');
U 560       ostDiv.style.flexBasis = '6em';
cfa858 561     }
U 562     self.menue_umschalten();
563   };
564
f074f6 565   this.fusszeile_umschalten = function () {
cfa858 566     var suedDiv = document.querySelector('.sued');
f074f6 567     if (suedDiv.classList.contains('sued-open')) {
cfa858 568       suedDiv.classList.remove('sued-open');
f074f6 569       suedDiv.style.height = '0';
cfa858 570     } else {
U 571       suedDiv.classList.add('sued-open');
f074f6 572       suedDiv.style.height = '1.5em';
cfa858 573     }
U 574     self.menue_umschalten();
575   };
576
f074f6 577   this.menu_message = function (msg) {
cfa858 578     self.meldung_mit_timeout(msg, 1500);
U 579     var suedDiv = document.querySelector('.sued');
f074f6 580     if (suedDiv.classList.contains('sued-open')) {
cfa858 581     } else {
U 582       suedDiv.classList.add('sued-open');
f074f6 583       suedDiv.style.height = '1.5em';
cfa858 584     }
U 585     self.menue_umschalten();
586   };
587
f074f6 588   this.message_1 = function () {
cfa858 589     self.menu_message('Eine Mitteilung.');
U 590   };
591
f074f6 592   this.message_2 = function () {
cfa858 593     self.menu_message('Was wir schon immer sagen wollten.');
U 594   };
595
f074f6 596   this.message_3 = function (text) {
cfa858 597     self.menu_message(text);
U 598   };
599
f074f6 600   this.meldung_mit_timeout = function (meldung, timeout) {
cfa858 601     var s = document.querySelector('.sued');
a43e1a 602     s.classList.add('sued-open');
U 603     s.style.height = '1.5em';
cfa858 604     s.textContent = meldung;
f074f6 605     setTimeout(function () {
cfa858 606       s.textContent = 'Bereit.';
f074f6 607       setTimeout(function () {
cfa858 608         var suedDiv = document.querySelector('.sued');
f074f6 609         if (suedDiv.classList.contains('sued-open')) {
U 610           suedDiv.classList.remove('sued-open');
611           suedDiv.style.height = '0';
cfa858 612         }
U 613       }, 500);
614     }, timeout);
615   };
8239d1 616   
f45e20 617   /* --------------------- Dialog-Funktionen ------------------------ */
cfa858 618
U 619   /*
f074f6 620    Einen Dialog aus Vorlagen erzeugen
U 621    
622    vurl - URL zur Dialogvorlage
623    msgTpl - URL mit einer Vorlage eines Mitteilungstextes (optional)
624    */
5b7356 625   this.dialog_laden_und_zeigen = function (vurl, msgTpl, cb) {
U 626     var vorlage = self.cache[vurl];
627     if(vorlage === undefined) {
628       self.http_get(vurl, function(antwort) {
629         self.cache[vurl] = antwort;
630         self.dialog_zeigen(vurl, msgTpl, cb);
f074f6 631       });
cfa858 632     } else {
5b7356 633       self.dialog_zeigen(vurl, msgTpl, cb);
cfa858 634     }
U 635   };
636
5b7356 637   this.dialog_zeigen = function (vurl, inhalt, cb) {
U 638     var dlg = document.querySelector(".dialog");
2597cd 639     self.html_erzeugen(vurl, inhalt, function (html) {
U 640       dlg.style.height = '7em';
641       dlg.innerHTML = html;
642       document.querySelector('.close-btn').addEventListener('click', self.dialog_schliessen);
643       if(typeof(cb) !== 'function') {
644         // ..
645       } else {
646         cb();
647       }
648     });
5b7356 649   };
2597cd 650   
f45e20 651   this.dialog_schliessen = function () {
cfa858 652     document.querySelector('.close-btn').removeEventListener('click', self.dialog_schliessen);
U 653     var dlg = document.querySelector('.dialog');
654     dlg.style.height = '0';
655     dlg.innerHTML = '';
656   };
657
f45e20 658   /* ---------------------   Vorlagen   ---------------------- */
cfa858 659
U 660   /*
f074f6 661    Das HTML erzeugen, das entsteht, wenn eine Vorlage mit Inhalt
U 662    gefüllt wird
663    
664    Das Füllen erfolgt asynchron, d.h. der Programmlauf geht nach dem
665    Aufruf weiter ohne auf das Laden und Füllen der Vorlage zu warten.
666    Das fertige HTML wird der Callback-Funktion übergeben
667    sobald die Vorlage geladen und gefüllt ist, unabhängig davon, wo der
668    Programmlauf zu diesem Zeitpunkt mittlerweile ist.
669    
670    vurl - URL zur Vorlagendatei
671    inhalt - die JSON-Struktur, deren Inhalt in die
672    Vorlage gefüllt werden soll
673    cb - Callback-Funktion, die gerufen wird, wenn die Vorlage gefüllt ist.
674    Dieser Callback-Funktion wird das fertige HTML übergeben
675    */
676   this.html_erzeugen = function (vurl, inhalt, cb) {
cfa858 677     var vorlage = self.cache[vurl];
f074f6 678     if (vorlage === undefined) {
cfa858 679       self.vorlage_laden_und_fuellen(vurl, inhalt, cb);
U 680     } else {
681       self.vorlage_fuellen(vurl, inhalt, cb);
682     }
683   };
684
f074f6 685   this.vorlage_fuellen = function (vurl, inhalt, cb) {
cfa858 686     cb(Mustache.render(self.cache[vurl], inhalt));
U 687   };
688
689   /*
f074f6 690    Eine Vorlage vom Server in den lokalen Speicher laden
U 691    vurl - der URL unter dem die Vorlage zu finden ist
692    inhalt - die JSON-Struktur, deren Inhalt in die
693    Vorlage gefüllt werden soll
694    cb - callback: Diese Funktion wird gerufen, wenn die Vorlage mit dem
695    Inhalt gefüllt ist
696    */
697   this.vorlage_laden_und_fuellen = function (vurl, inhalt, cb) {
cfa858 698     var xmlhttp = new XMLHttpRequest();
f074f6 699     xmlhttp.onreadystatechange = function () {
cfa858 700       if (this.readyState == 4 && this.status == 200) {
U 701         self.cache[vurl] = this.responseText;
702         self.vorlage_fuellen(vurl, inhalt, cb);
703       }
704     };
705     xmlhttp.open("GET", vurl, true);
706     xmlhttp.send();
707   };
708
709
710 }
711
f45e20 712 /* ----------- Objekte ---------------- */
U 713
714 function Ablageort(n, o, u) {
715   this.name = n;
716   this.ort = o;
717   this.url = u;
718 }
719
720 function Einstellung(k, v) {
721   this.key = k;
722   this.value = v;
723 }
724
725 function Abspieler(n, u) {
726   this.name = n;
727   this.url = u;
8d7d35 728 }
U 729
730 function Abspielliste(n) {
731   this.name = n;
e60cff 732 }
U 733
245ac1 734 function Titel(n, p, u, i, t, a) {
e60cff 735   this.katalogUrl = u;
2bdd78 736   this.pfad = p;
e60cff 737   this.name = n;
245ac1 738   this.interpret = i;
U 739   this.titelAnzName = t;
740   this.album  = a;
d6b78c 741 }