Persoenliche Mediazentrale
undisclosed
2023-01-09 1bf4f6d3cdcf1445c2a40959f286a73485eb31c8
Drag and drop fuer Abspiellisten eingebaut
6 files modified
197 ■■■■ changed files
src/de/uhilger/tango/api/AbstractHandler.java 2 ●●● patch | view | raw | blame | history
src/de/uhilger/tango/api/ListHandler.java 81 ●●●● patch | view | raw | blame | history
src/de/uhilger/tango/entity/Abspielliste.java 8 ●●●●● patch | view | raw | blame | history
www/app.css 10 ●●●●● patch | view | raw | blame | history
www/data/tpl/titel_liste.txt 2 ●●● patch | view | raw | blame | history
www/js/app.js 94 ●●●● patch | view | raw | blame | history
src/de/uhilger/tango/api/AbstractHandler.java
@@ -130,7 +130,7 @@
    return "nicht unterstuetzt";
  }
  protected String post(HttpExchange e) {
  protected String post(HttpExchange e) throws IOException {
    setReturnCode(RTC_NOT_FOUND);
    return "nicht unterstuetzt";
  }
src/de/uhilger/tango/api/ListHandler.java
@@ -19,13 +19,13 @@
import com.google.gson.Gson;
import com.sun.net.httpserver.HttpExchange;
import de.uhilger.tango.App;
import de.uhilger.tango.Server;
import de.uhilger.tango.entity.Abspielliste;
import de.uhilger.tango.entity.Entity;
import de.uhilger.tango.entity.Titel;
import de.uhilger.tango.store.FileStorage;
import java.io.IOException;
import java.util.List;
import java.util.logging.Logger;
/**
@@ -34,13 +34,12 @@
 * GET /mz/api/alist/[pl-name]          die Titel-Objekte der Liste [pl-name] liefern
 * PUT /mz/api/alist/[pl-name]          den Titel im Body anfuegen an die Liste [pl-name]
 * PUT /mz/api/alist/[pl-name]/[nr]     an der Position nr der Liste [pl-name] den Titel im Body einfuegen
 * Neu: PUT /mz/api/alist/[pl-name]/[nr]/up  den Titel an der Position nr der Liste [pl-name] eins nach oben
 * Neu: PUT /mz/api/alist/[pl-name]/[nr]/dn  den Titel an der Position nr der Liste [pl-name] eins nach unten
 * PUT /mz/api/alist/[pl-name]/[nrVon]/[nrNach]   den Titel von seiner aktuellen Position an eine
 *                                                 andere Position der Liste [pl-name] verschieben
 * DELETE /mz/api/alist/[pl-name]/[nr]  den Titel an der Position [nr] aus der Liste [pl-name] entfernen  
 * DELETE /mz/api/alist/[pl-name]/alle  alle Titel aus der Liste [pl-name] entfernen  
 * 
 * TODO (2.1.2023):
 * - Titel eins nach oben/unten
 * - Liste ab Titel spielen
 * - Ganzes Album der Liste hinzufuegen
 *
@@ -80,8 +79,75 @@
        break;
        
      case 6:
        response = "Einfuegen noch nicht fertig.";
        response = insertTitel(e, elems[4], Integer.parseInt(elems[5]));
        break;
      case 7:
        response = moveTitel(e, elems[4], Integer.parseInt(elems[5]), Integer.parseInt(elems[6]));
        break;
    }
    return response;
  }
  /**
   * Den Titel im Body von seiner aktuellen Position an die angegebene
   * Position setzen. Der Titel an der angegebenen Position rueckt nach
   * unten.
   *
   * Annahme: Die Abspielliste enthaelt keine Titel mehrfach.
   *
   * @param e
   * @param plname
   * @param zielPos
   * @return
   * @throws IOException
   */
  private String moveTitel(HttpExchange e, String plname, int pos, int zielPos) throws IOException {
    FileStorage fs = new FileStorage(conf);
    Entity entity = fs.read(FileStorage.ST_ABSPIELLISTE, plname);
    String response = "Titel konnte nicht verschoben werden.";
    if(entity instanceof Abspielliste) {
      if(pos < zielPos) {
        --zielPos;
      }
      Abspielliste aliste = (Abspielliste) entity;
      List<Titel> liste = aliste.getTitel();
      Titel t = liste.get(pos);
      liste.remove(pos);
      liste.add(zielPos, t);
      fs.write(aliste, true);
      response = "Titel " + t.getName() + " der Liste " + aliste.getName() +
              " an Position " + zielPos + " verschoben.";
    }
    return response;
  }
  /**
   * Den Titel im Body an Position anPos einfuegen. Der Titel an anPos
   * rueckt nach unten.
   *
   * @param e
   * @param plname
   * @param anPos
   * @return
   * @throws IOException
   */
  private String insertTitel(HttpExchange e, String plname, int anPos) throws IOException {
    FileStorage fs = new FileStorage(conf);
    Entity entity = fs.read(FileStorage.ST_ABSPIELLISTE, plname);
    String response = "Titel konnte nicht hinzugefuegt werden.";
    if(entity instanceof Abspielliste) {
      Abspielliste aliste = (Abspielliste) entity;
      String titelJson = bodyLesen(e);
      Gson gson = new Gson();
      Object o = gson.fromJson(titelJson, fs.typeFromName(Titel.class.getSimpleName()).getType());
      if(o instanceof Titel) {
        Titel titel = (Titel) o;
        aliste.putTitel(titel, anPos);
        fs.write(aliste, true);
        response = "Titel " + titel.getName() + " der Liste " + aliste.getName() +
                " an Position " + anPos + " hinzugefuegt.";
      }
    }
    return response;
  }
@@ -103,11 +169,6 @@
      }
    }
    return response;
  }
  @Override
  protected String post(HttpExchange e) {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
  }
  // DELETE /mz/api/alist/[pl-name]/[nr]  den Titel an der Position [nr] aus der Liste [pl-name] entfernen  
src/de/uhilger/tango/entity/Abspielliste.java
@@ -40,6 +40,14 @@
  public List<Titel> getTitel() {
    return titel;
  }
  public void putTitel(Titel t, int anPos) {
    this.titel.set(anPos, t);
  }
  public int getIndex(Titel t) {
    return this.titel.indexOf(t);
  }
  public void setTitel(List titel) {
    this.titel = titel;
www/app.css
@@ -296,6 +296,16 @@
  cursor: pointer;
}
.drag-over {
  color: blueviolet;
  border-style: dashed;
  border-width: 1px;
}
.hide {
  display: none;
}
.entity-eintrag:hover {
  /* background-color: #ececec; */
  color: red;
www/data/tpl/titel_liste.txt
@@ -2,7 +2,7 @@
<div class='entity-formular'>
  <ul class='entity-liste'>
    {{#titel}}
    <li class='entity-eintrag'>{{interpret}}: {{titelAnzName}}</li>
    <li class='entity-eintrag' draggable='true'>{{interpret}}: {{titelAnzName}}</li>
    {{/titel}}
  </ul>
</div>
www/js/app.js
@@ -402,6 +402,47 @@
          self.removeClassMulti('selected');
          t.classList.add('selected');
        });
        self.addEvtListener('.entity-eintrag', 'dragstart', function (e) {
          //console.log("drag started");
          e.dataTransfer.setData('text/plain', e.target.textContent);
          setTimeout(() => {
                  e.target.classList.add('hide');
                  e.target.classList.add('drag-elem');
          }, 0);
        });
        self.addEvtListener('.entity-eintrag', 'dragenter', function (e) {
          e.preventDefault();
          //console.log("drag enter");
          e.target.classList.add('drag-over');
        });
        self.addEvtListener('.entity-eintrag', 'dragover', function (e) {
          e.preventDefault();
          //console.log("drag over");
          e.target.classList.add('drag-over');
        });
        self.addEvtListener('.entity-eintrag', 'dragleave', function (e) {
          //console.log("drag leave");
          e.target.classList.remove('drag-over');
        });
        self.addEvtListener('.entity-eintrag', 'drop', function (e) {
          e.preventDefault();
          //console.log("drop");
          //console.log("index: " + self.getIndexBySelector('drag-over'));
          const pos = self.getIndexBySelector('drag-elem');
          const zielPos = self.getIndexBySelector('drag-over');
          const titeltext = e.dataTransfer.getData('text/plain');
          const draggable = document.querySelector(".drag-elem");
          draggable.classList.remove("drag-elem");
          e.target.classList.remove('drag-over');
          var plname = document.querySelector('#playlist').value;
          self.http_put('api/alist/' + plname + "/" + pos + "/" + zielPos, '', function(responseText) {
            //self.meldung_mit_timeout(responseText, 1500);
          });
          ulElem = draggable.parentElement;
          ulElem.removeChild(draggable);
          e.target.insertAdjacentElement('beforebegin', draggable);
          draggable.classList.remove('hide');
        });
      });
    });
  };  
@@ -532,6 +573,17 @@
    });
  };
  
  /*
   * {
   *  "katalogUrl":"/media",
   *  "pfad":"/Musik/B/Bay-City-Rollers/Original-Album-Classics/3/",
   *  "name":"3-37-Love-Is.mp3",
   *  "interpret":"Bay City Rollers",
   *  "titelAnzName":"Love Is",
   *  "album":"Original Album Classics"
   * }
   * @returns {undefined}
   */
  this.titelDazu = function() {
    var titel = self.titelErmitteln(document.querySelector(".selected"));
    //var titelName = elem.textContent;
@@ -554,20 +606,22 @@
  };  
  
  this.titelWeg = function() {
    var elem = document.querySelector(".selected");
    var parentElem = elem.parentNode;
    //var elem = document.querySelector(".selected");
    //var parentElem = elem.parentNode;
    //console.log("elem: " + elem.nodeName + ", parent: " + parentElem.nodeName + ", len: " + parentElem.childNodes.length);
    var liElems = parentElem.getElementsByTagName(elem.nodeName); // nur die LI Elemente
    //var liElems = parentElem.getElementsByTagName(elem.nodeName); // nur die LI Elemente
    //console.log("liElems.anz: " + liElems.length);
    var gefunden = false;
    for(var i = 0; i < liElems.length && !gefunden; i++) {
    //var gefunden = false;
    //for(var i = 0; i < liElems.length && !gefunden; i++) {
      //console.log(liElems.item(i).textContent);
      if(liElems.item(i).classList.contains("selected")) {
        gefunden = true;
        var index = i;
      //if(liElems.item(i).classList.contains("selected")) {
        //gefunden = true;
        //var index = i;
        //console.log(elem.textContent + ' hat Index ' + i);
      }
    }
      //}
    //}
    const index = self.getIndexBySelector("selected");
    // /mz/api/alist/[pl-name]/[nr] 
    var plname = document.querySelector('#playlist').value;
    self.http_delete('api/alist/' + plname + '/' + index,'', function(responseText) {
@@ -578,6 +632,26 @@
    
  };
  
  this.getIndexBySelector = function(selector) {
    var qSel = '.' + selector;
    var elem = document.querySelector(qSel);
    var parentElem = elem.parentNode;
    //console.log("elem: " + elem.nodeName + ", parent: " + parentElem.nodeName + ", len: " + parentElem.childNodes.length);
    var liElems = parentElem.getElementsByTagName(elem.nodeName); // nur die LI Elemente
    //console.log("liElems.anz: " + liElems.length);
    var gefunden = false;
    var index = -1;
    for(var i = 0; i < liElems.length && !gefunden; i++) {
      //console.log(liElems.item(i).textContent);
      if(liElems.item(i).classList.contains(selector)) {
        gefunden = true;
        index = i;
        //console.log(elem.textContent + ' hat Index ' + i);
      }
    }
    return index;
  };
  /* ------------- Helfer fuer Entitaets-Formulare ----------------------- */
  
  /*