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