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