Persoenliche Mediazentrale
ulrich
2021-04-07 d6b78c3129943790cfd8ab1891b5d8fe9010894c
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;
f45e20 7
U 8   this.init = function () {
9     self.mediaPfad = '/';
10     self.ortPfad = '/';
11     self.cache = new Array();
12     self.appMenu = new AppMenu();
13     self.appMenu.init(
14             "data/menu/",
15             "hauptmenue.json",
16             "data/tpl/app-menu.tpl",
17             ".west",
18             "8em");
19
20     document.querySelector('.hamburger').addEventListener('click', function (e) {
21       self.menue_umschalten();
22     });
23     
24     self.addEvtListener('#mi-katalog', 'click', self.media_liste);
25     self.addEvtListener('#mi-orte', 'click', self.ablageort_liste);
26     self.addEvtListener('#mi-prefs', 'click', self.prefs_liste);
27     self.addEvtListener('#mi-player', 'click', self.abspieler_liste);
28     
29     self.fusszeile_umschalten();
30     self.seitenleiste_umschalten();
31     self.dialog_unten_zeigen();
32   };
33   
34   this.abspieler_auswahl_fuellen = function() {
35     self.http_get('../api/store/Abspieler/', function (responseText) {
36       /*
37        {"ArrayList": [{"name":"Wohnz","url":"http://rpi4-wz:9090/"},{"name":"Arbz","url":"http://rpi4-az:9090/"}]}
38        */
39       self.vorlage_laden_und_fuellen("data/tpl/abs_sel.tpl", JSON.parse(responseText), function (html) {
40         document.querySelector(".abs-sel").innerHTML = html;
41       });    
42     });
43   };
44
45   /* Unterer Einblendbereich */
46   
47   this.dialog_unten_zeigen = function() {
48     self.vorlage_laden_und_fuellen("data/tpl/ctrl.tpl", "", function (html) {
49       var dlg = document.querySelector(".dialog-unten");
50       dlg.style.height = '4.5em';
51       dlg.innerHTML = html;
52       self.abspieler_auswahl_fuellen();
53     });
54   };
55
86bbf7 56   
U 57   // auf der obersten Ebene werden die Kataloge angezeigt,
58   // darunter der Inhalt des aktuellen Pfades
59   this.media_liste = function() {
60     if(self.ortPfad === '/') {
61       // Kataloge listen
f45e20 62       self.http_get('../api/store/Ablageort/liste/', function (responseText) {
86bbf7 63         self.vorlage_laden_und_fuellen("data/tpl/katalog_root_liste.tpl", JSON.parse(responseText), function (html) {
U 64           document.querySelector(".zentraler-inhalt").innerHTML = html;
65           self.addEvtListener('.entity-eintrag', 'click', function (event) {
66             var t = event.target;
67             self.http_get('../api/store/Ablageort/' + t.textContent, function(responseText) {
68               var ablageort = JSON.parse(responseText);
69               self.ortPfad = ablageort.url;
70               self.media_liste();
71             });
72           });
73         });
74       });
75     } else {
76       // Pfad listen
3271f1 77       console.log("vorher ortPfad: " + self.ortPfad);
U 78       console.log("vorher mediaPfad: " + self.mediaPfad);
79       //self.http_get('..' + self.ortPfad + '/' + self.mediaPfad + '/', function(responseText) {
80       var url = '..' + self.ortPfad + self.mediaPfad;
81       if(!url.endsWith('/')) {
82         url = url + '/';
83       }
84       console.log("url: " + url);      
85       self.http_get(url, function(responseText) {
ca9872 86         //console.log(responseText);
86bbf7 87         self.vorlage_laden_und_fuellen("data/tpl/katalog_inhalt_liste.tpl", JSON.parse(responseText), function (html) {
U 88           document.querySelector(".zentraler-inhalt").innerHTML = html;
3271f1 89           console.log("mediaPfad bei Anzeige: " + self.mediaPfad);
86bbf7 90           self.addEvtListener('.entity-eintrag', 'click', function (event) {
U 91             var t = event.target;
3271f1 92             var tx = t.textContent;
U 93             console.log("tx: " + tx);
94             console.log("mediaPfad nach Auswahl: " + self.mediaPfad);
86bbf7 95             if(t.classList.contains("entity-typ-folder")) {
3271f1 96               if(self.mediaPfad.endsWith('/')) {
U 97                 self.mediaPfad = self.mediaPfad + tx;                
98               } else {
99                 self.mediaPfad = self.mediaPfad + '/' + tx;
100               }
101               //self.mediaPfad = self.mediaPfad + t.textContent;
102               console.log("mediaPfad neu: " + self.mediaPfad);
86bbf7 103               self.media_liste();
U 104             } else {
105               console.log("Media-Inhalt auswaehlen oder abspielen");
7c22a2 106               self.removeClassMulti('selected');
U 107               t.classList.add('selected');
86bbf7 108             }
U 109           });
110           self.addEvtListener('#zurueck-btn', 'click', function (event) {
111             if(self.mediaPfad === '/') {
112               self.ortPfad = '/';              
113             } else {
114               var pos = self.mediaPfad.lastIndexOf('/');
3271f1 115               var parent;
U 116               if(pos > 1) {
117                 parent = self.mediaPfad.substring(0, pos);
118               } else {
119                 parent = '/';
120               }
121               console.log("Parent: " + parent);
86bbf7 122               self.mediaPfad = parent;
U 123             }
124             self.media_liste();
125           });        
126         });
127       });
128     }
129   };
cf6509 130   
U 131   /* Die folgenden '_liste' Funktionen koennen noch vereinheitlicht werden */
cfa858 132
a43e1a 133   this.ablageort_liste = function() {
f45e20 134     self.http_get('../api/store/Ablageort/liste/', function (responseText) {
a43e1a 135       self.vorlage_laden_und_fuellen("data/tpl/ablageort_liste.tpl", JSON.parse(responseText), function (html) {
U 136         document.querySelector(".zentraler-inhalt").innerHTML = html;
137         self.addEvtListener('.entity-eintrag', 'click', function (event) {
138           var t = event.target;
90f5d4 139           self.http_get('../api/store/Ablageort/' + t.textContent, function(responseText){
86bbf7 140             var ablageort = JSON.parse(responseText);
90f5d4 141             self.ablageort_form(ablageort);
U 142           });
a43e1a 143         });
faab2d 144         self.addEvtListener('#neu-btn', 'click', function (event) {
U 145           eval("self.ablageort_form" + "(this)");
146         });        
cf6509 147       });
U 148     });
149   };
150
151   this.prefs_liste = function() {
f45e20 152     self.http_get('../api/store/Einstellung/liste/', function (responseText) {
cf6509 153       self.vorlage_laden_und_fuellen("data/tpl/einstellung_liste.tpl", JSON.parse(responseText), function (html) {
U 154         document.querySelector(".zentraler-inhalt").innerHTML = html;
155         self.addEvtListener('.entity-eintrag', 'click', function (event) {
156           var t = event.target;
157           self.http_get('../api/store/Einstellung/' + t.textContent, function(responseText){
158             var einstellung = JSON.parse(responseText);
159             self.prefs_form(einstellung);
160           });
161         });
162         self.addEvtListener('#neu-btn', 'click', function (event) {
163           eval("self.prefs_form" + "(this)");
164         });        
165       });
166     });
167   };
168
3d4bca 169   this.abspieler_liste = function() {
f45e20 170     self.http_get('../api/store/Abspieler/liste/', function (responseText) {
3d4bca 171       self.vorlage_laden_und_fuellen("data/tpl/abspieler_liste.tpl", JSON.parse(responseText), function (html) {
U 172         document.querySelector(".zentraler-inhalt").innerHTML = html;
173         self.addEvtListener('.entity-eintrag', 'click', function (event) {
174           var t = event.target;
175           self.http_get('../api/store/Abspieler/' + t.textContent, function(responseText){
176             var abspieler = JSON.parse(responseText);
177             self.abspieler_form(abspieler);
178           });
179         });
180         self.addEvtListener('#neu-btn', 'click', function (event) {
181           eval("self.abspieler_form" + "(this)");
182         });        
183       });
184     });
185   };
186
cf6509 187   /* Die folgenden '_form' Funktionen koennen noch vereinheitlicht werden */
3d4bca 188
U 189   this.abspieler_form = function(pl) {
190     self.vorlage_laden_und_fuellen("data/tpl/form_abspieler.tpl", pl, function (html) {
191       document.querySelector(".zentraler-inhalt").innerHTML = html;
192       self.addEvtListener('#ok-btn', 'click', function () {
193         var plname = document.querySelector('#abspieler-name').value;
194         plname = plname.replace(' ', '').replace(/[\W]+/g, '');
195         var abspieler = new Abspieler(
196           plname,
197           document.querySelector('#abspieler-url').value
198         );
199         var daten = JSON.stringify(abspieler);        
200         if(typeof pl === "undefined" || pl.key !== plname) {
201           // neu
202           self.http_post('../api/store/Abspieler', daten, function (responseText) {
203             // hier die Antwort verarbeiten
204           });
205         } else {
206           // aendern
207           self.http_put('../api/store/Abspieler', daten, function (responseText) {
208             // hier die Antwort verarbeiten
209           });
210         }
211         //document.querySelector(".zentraler-inhalt").innerHTML = '';
212         self.abspieler_liste();
213       });
214       self.addEvtListener('#cancel-btn', 'click', function () {
215         //document.querySelector(".zentraler-inhalt").innerHTML = '';
216         self.abspieler_liste();
217       });
218       self.addEvtListener('#loeschen-btn', 'click', function() {
219         var plname = document.querySelector('#abspieler-name').value;
220         var dlgdata = {"del-elem": plname};
221         self.dialog_laden_und_zeigen('data/tpl/dlg-loeschen.tpl', dlgdata, function() {
222           self.addEvtListener('#nein-btn', 'click', self.dialog_schliessen);
223           self.addEvtListener('#ja-btn', 'click', function() {
224             self.http_delete('../api/store/Abspieler/' + plname, '', function (responseText) {
225               // hier die Antwort verarbeiten
226               self.dialog_schliessen();
227               //document.querySelector(".zentraler-inhalt").innerHTML = '';
228               self.abspieler_liste();
229             });
230           });
231         });
232       });
233     });
234   };
cf6509 235
U 236   this.prefs_form = function(k) {
237     self.vorlage_laden_und_fuellen("data/tpl/form_einstellung.tpl", k, function (html) {
238       document.querySelector(".zentraler-inhalt").innerHTML = html;
239       self.addEvtListener('#ok-btn', 'click', function () {
240         var pkey = document.querySelector('#einstellung-key').value;
241         pkey = pkey.replace(' ', '').replace(/[\W]+/g, '');
242         var pref = new Einstellung(
243           pkey,
244           document.querySelector('#einstellung-value').value
245         );
246         var daten = JSON.stringify(pref);        
247         if(typeof k === "undefined" || k.key !== pkey) {
248           // neu
249           self.http_post('../api/store/Einstellung', daten, function (responseText) {
250             // hier die Antwort verarbeiten
251           });
252         } else {
253           // aendern
254           self.http_put('../api/store/Einstellung', daten, function (responseText) {
255             // hier die Antwort verarbeiten
256           });
257         }
258         //document.querySelector(".zentraler-inhalt").innerHTML = '';
259         self.prefs_liste();
260       });
261       self.addEvtListener('#cancel-btn', 'click', function () {
262         //document.querySelector(".zentraler-inhalt").innerHTML = '';
263         self.prefs_liste();
264       });
265       self.addEvtListener('#loeschen-btn', 'click', function() {
266         var pkey = document.querySelector('#einstellung-key').value;
267         var dlgdata = {"del-elem": pkey};
268         self.dialog_laden_und_zeigen('data/tpl/dlg-loeschen.tpl', dlgdata, function() {
269           self.addEvtListener('#nein-btn', 'click', self.dialog_schliessen);
270           self.addEvtListener('#ja-btn', 'click', function() {
271             self.http_delete('../api/store/Einstellung/' + pkey, '', function (responseText) {
272               // hier die Antwort verarbeiten
273               self.dialog_schliessen();
274               //document.querySelector(".zentraler-inhalt").innerHTML = '';
275               self.prefs_liste();
276             });
277           });
278         });
a43e1a 279       });
U 280     });
281   };
cfa858 282
90f5d4 283   /* 
U 284    * Ablageort-Formular anzeigen
285    * 
286    * {"name":"Katalog 2","ort":"/home/ulrich/Videos","url":"/media/kat2"}: 
287    * 
288    * @param {type} ablageort  der Ablageort, der bearbeitet werden soll, leer fuer neuen Ort
289    * @returns {undefined} kein Rueckgabewert
290    */
291   this.ablageort_form = function(ort) {
292     self.vorlage_laden_und_fuellen("data/tpl/form_ablageort.tpl", ort, function (html) {
b379f5 293       document.querySelector(".zentraler-inhalt").innerHTML = html;
f074f6 294       self.addEvtListener('#ok-btn', 'click', function () {
2597cd 295         var aName = document.querySelector('#ablageort-name').value;
U 296         aName = aName.replace(' ', '').replace(/[\W]+/g, '');
b379f5 297         var a = new Ablageort(
2597cd 298           aName,
b379f5 299           document.querySelector('#ablageort-ort').value,
U 300           document.querySelector('#ablageort-url').value
301         );
90f5d4 302         var daten = JSON.stringify(a);        
2597cd 303         if(typeof ort === "undefined" || ort.name !== aName) {
U 304           // neu
90f5d4 305           self.http_post('../api/store/Ablageort', daten, function (responseText) {
U 306             // hier die Antwort verarbeiten
307           });
308         } else {
2597cd 309           // aendern
90f5d4 310           self.http_put('../api/store/Ablageort', daten, function (responseText) {
U 311             // hier die Antwort verarbeiten
312           });
313         }
b29119 314         //document.querySelector(".zentraler-inhalt").innerHTML = '';
faab2d 315         self.ablageort_liste();
b379f5 316       });
f074f6 317       self.addEvtListener('#cancel-btn', 'click', function () {
b29119 318         //document.querySelector(".zentraler-inhalt").innerHTML = '';
faab2d 319         self.ablageort_liste();
5b7356 320       });
U 321       self.addEvtListener('#loeschen-btn', 'click', function() {
322         var aoname = document.querySelector('#ablageort-name').value;
323         var dlgdata = {"del-elem": aoname};
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() {
90f5d4 327             self.http_delete('../api/store/Ablageort/' + aoname, '', function (responseText) {
U 328               // hier die Antwort verarbeiten
2597cd 329               self.dialog_schliessen();
b29119 330               //document.querySelector(".zentraler-inhalt").innerHTML = '';
faab2d 331               self.ablageort_liste();
90f5d4 332             });
5b7356 333           });
U 334         });
b379f5 335       });
U 336     });
337   };
338
7c22a2 339   this.addEvtListener = function(selector, eventName, func) {
U 340     document.querySelectorAll(selector).forEach(elem => { elem.addEventListener(eventName, func); });
341   };
342   
343   this.removeClassMulti = function(selector) {
344     document.querySelectorAll('.' + selector).forEach(elem => { elem.classList.remove(selector); });
345   };
346
f45e20 347   /* --------------------- asynchroner HTTP Client ----------------- */
faab2d 348   
f074f6 349   this.http_get = function (u, cb) {
b379f5 350     self.http_call('GET', u, null, cb);
U 351   };
f074f6 352
U 353   this.http_post = function (u, data, cb) {
b379f5 354     self.http_call('POST', u, data, cb);
U 355   };
356
90f5d4 357   this.http_put = function (u, data, cb) {
U 358     self.http_call('PUT', u, data, cb);
359   };
360   
5b7356 361   this.http_delete = function (u, data, cb) {
2597cd 362     console.log("delete " + u);
5b7356 363     self.http_call('DELETE', u, data, cb);
U 364   };
365   
f074f6 366   this.http_call = function (method, u, data, scallback) {
b379f5 367     var xhr = new XMLHttpRequest();
U 368     var url = u;
f074f6 369     xhr.onreadystatechange = function () {
b379f5 370       if (this.readyState === 4 && this.status === 200) {
U 371         scallback(this.responseText);
372       }
373     };
374     xhr.open(method, url);
f074f6 375     if (method === 'GET') {
b379f5 376       xhr.send();
2597cd 377     } else if (method === 'POST' || method === 'PUT' || method === 'DELETE') {
b379f5 378       xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
U 379       xhr.send(data);
380     }
381   };
8239d1 382   
f45e20 383   /* ------------------------ aus App-Vorlage -------------------  */
cfa858 384
f074f6 385   this.menue_umschalten = function () {
cfa858 386     var ham = document.querySelector(".hamburger");
U 387     ham.classList.toggle("is-active"); // hamburger-icon umschalten
388     self.appMenu.toggle(); // menue oeffnen/schliessen
389   };
390
f074f6 391   this.info_dialog_zeigen = function () {
cfa858 392     self.dialog_laden_und_zeigen('data/tpl/dlg-info.tpl', '');
U 393     self.menue_umschalten();
394   };
395
f074f6 396   this.seitenleiste_umschalten = function () {
cfa858 397     var ostDiv = document.querySelector('.ost');
f074f6 398     if (ostDiv.classList.contains('ost-open')) {
cfa858 399       ostDiv.classList.remove('ost-open');
f074f6 400       ostDiv.style.flexBasis = '0em';
cfa858 401     } else {
f074f6 402       ostDiv.classList.add('ost-open');
U 403       ostDiv.style.flexBasis = '6em';
cfa858 404     }
U 405     self.menue_umschalten();
406   };
407
f074f6 408   this.fusszeile_umschalten = function () {
cfa858 409     var suedDiv = document.querySelector('.sued');
f074f6 410     if (suedDiv.classList.contains('sued-open')) {
cfa858 411       suedDiv.classList.remove('sued-open');
f074f6 412       suedDiv.style.height = '0';
cfa858 413     } else {
U 414       suedDiv.classList.add('sued-open');
f074f6 415       suedDiv.style.height = '1.5em';
cfa858 416     }
U 417     self.menue_umschalten();
418   };
419
f074f6 420   this.menu_message = function (msg) {
cfa858 421     self.meldung_mit_timeout(msg, 1500);
U 422     var suedDiv = document.querySelector('.sued');
f074f6 423     if (suedDiv.classList.contains('sued-open')) {
cfa858 424     } else {
U 425       suedDiv.classList.add('sued-open');
f074f6 426       suedDiv.style.height = '1.5em';
cfa858 427     }
U 428     self.menue_umschalten();
429   };
430
f074f6 431   this.message_1 = function () {
cfa858 432     self.menu_message('Eine Mitteilung.');
U 433   };
434
f074f6 435   this.message_2 = function () {
cfa858 436     self.menu_message('Was wir schon immer sagen wollten.');
U 437   };
438
f074f6 439   this.message_3 = function (text) {
cfa858 440     self.menu_message(text);
U 441   };
442
f074f6 443   this.meldung_mit_timeout = function (meldung, timeout) {
cfa858 444     var s = document.querySelector('.sued');
a43e1a 445     s.classList.add('sued-open');
U 446     s.style.height = '1.5em';
cfa858 447     s.textContent = meldung;
f074f6 448     setTimeout(function () {
cfa858 449       s.textContent = 'Bereit.';
f074f6 450       setTimeout(function () {
cfa858 451         var suedDiv = document.querySelector('.sued');
f074f6 452         if (suedDiv.classList.contains('sued-open')) {
U 453           suedDiv.classList.remove('sued-open');
454           suedDiv.style.height = '0';
cfa858 455         }
U 456       }, 500);
457     }, timeout);
458   };
8239d1 459   
f45e20 460   /* --------------------- Dialog-Funktionen ------------------------ */
cfa858 461
U 462   /*
f074f6 463    Einen Dialog aus Vorlagen erzeugen
U 464    
465    vurl - URL zur Dialogvorlage
466    msgTpl - URL mit einer Vorlage eines Mitteilungstextes (optional)
467    */
5b7356 468   this.dialog_laden_und_zeigen = function (vurl, msgTpl, cb) {
U 469     var vorlage = self.cache[vurl];
470     if(vorlage === undefined) {
471       self.http_get(vurl, function(antwort) {
472         self.cache[vurl] = antwort;
473         self.dialog_zeigen(vurl, msgTpl, cb);
f074f6 474       });
cfa858 475     } else {
5b7356 476       self.dialog_zeigen(vurl, msgTpl, cb);
cfa858 477     }
U 478   };
479
5b7356 480   this.dialog_zeigen = function (vurl, inhalt, cb) {
U 481     var dlg = document.querySelector(".dialog");
2597cd 482     self.html_erzeugen(vurl, inhalt, function (html) {
U 483       dlg.style.height = '7em';
484       dlg.innerHTML = html;
485       document.querySelector('.close-btn').addEventListener('click', self.dialog_schliessen);
486       if(typeof(cb) !== 'function') {
487         // ..
488       } else {
489         cb();
490       }
491     });
5b7356 492   };
2597cd 493   
f45e20 494   this.dialog_schliessen = function () {
cfa858 495     document.querySelector('.close-btn').removeEventListener('click', self.dialog_schliessen);
U 496     var dlg = document.querySelector('.dialog');
497     dlg.style.height = '0';
498     dlg.innerHTML = '';
499   };
500
f45e20 501   /* ---------------------   Vorlagen   ---------------------- */
cfa858 502
U 503   /*
f074f6 504    Das HTML erzeugen, das entsteht, wenn eine Vorlage mit Inhalt
U 505    gefüllt wird
506    
507    Das Füllen erfolgt asynchron, d.h. der Programmlauf geht nach dem
508    Aufruf weiter ohne auf das Laden und Füllen der Vorlage zu warten.
509    Das fertige HTML wird der Callback-Funktion übergeben
510    sobald die Vorlage geladen und gefüllt ist, unabhängig davon, wo der
511    Programmlauf zu diesem Zeitpunkt mittlerweile ist.
512    
513    vurl - URL zur Vorlagendatei
514    inhalt - die JSON-Struktur, deren Inhalt in die
515    Vorlage gefüllt werden soll
516    cb - Callback-Funktion, die gerufen wird, wenn die Vorlage gefüllt ist.
517    Dieser Callback-Funktion wird das fertige HTML übergeben
518    */
519   this.html_erzeugen = function (vurl, inhalt, cb) {
cfa858 520     var vorlage = self.cache[vurl];
f074f6 521     if (vorlage === undefined) {
cfa858 522       self.vorlage_laden_und_fuellen(vurl, inhalt, cb);
U 523     } else {
524       self.vorlage_fuellen(vurl, inhalt, cb);
525     }
526   };
527
f074f6 528   this.vorlage_fuellen = function (vurl, inhalt, cb) {
cfa858 529     cb(Mustache.render(self.cache[vurl], inhalt));
U 530   };
531
532   /*
f074f6 533    Eine Vorlage vom Server in den lokalen Speicher laden
U 534    vurl - der URL unter dem die Vorlage zu finden ist
535    inhalt - die JSON-Struktur, deren Inhalt in die
536    Vorlage gefüllt werden soll
537    cb - callback: Diese Funktion wird gerufen, wenn die Vorlage mit dem
538    Inhalt gefüllt ist
539    */
540   this.vorlage_laden_und_fuellen = function (vurl, inhalt, cb) {
cfa858 541     var xmlhttp = new XMLHttpRequest();
f074f6 542     xmlhttp.onreadystatechange = function () {
cfa858 543       if (this.readyState == 4 && this.status == 200) {
U 544         self.cache[vurl] = this.responseText;
545         self.vorlage_fuellen(vurl, inhalt, cb);
546       }
547     };
548     xmlhttp.open("GET", vurl, true);
549     xmlhttp.send();
550   };
551
552
553 }
554
f45e20 555 /* ----------- Objekte ---------------- */
U 556
557 function Ablageort(n, o, u) {
558   this.name = n;
559   this.ort = o;
560   this.url = u;
561 }
562
563 function Einstellung(k, v) {
564   this.key = k;
565   this.value = v;
566 }
567
568 function Abspieler(n, u) {
569   this.name = n;
570   this.url = u;
d6b78c 571 }