From b379f5d6fa95c9c938c38ce592739ea732847821 Mon Sep 17 00:00:00 2001
From: ulrich
Date: Sun, 04 Apr 2021 18:08:17 +0000
Subject: [PATCH] Durchstich Neuer Ablageort
---
www/ui/data/ablageort.css | 20 +
www/ui/data/formulare.css | 145 +++++++++++
src/de/uhilger/mediaz/App.java | 2
www/ui/data/menu/hauptmenue.json | 5
src/de/uhilger/mediaz/api/StoreTestHandler.java | 1
www/ui/js/app.js | 76 +++++
www/ui/index.html | 37 +-
src/de/uhilger/mediaz/api/StoreHandler.java | 125 +++++++++
www/ui/data/test.html | 28 ++
src/de/uhilger/mediaz/api/AblageTestHandler.java | 11
src/de/uhilger/mediaz/conf/Store.java | 2
www/ui/app.css | 145 +++++++++++
src/mediaz_de_DE.properties | 1
src/de/uhilger/mediaz/Server.java | 76 ++++-
www/ui/data/tpl/form_ablageort.tpl | 13 +
www/ui/data/ablageort.html | 43 +++
16 files changed, 683 insertions(+), 47 deletions(-)
diff --git a/src/de/uhilger/mediaz/App.java b/src/de/uhilger/mediaz/App.java
index 777c985..351bb27 100644
--- a/src/de/uhilger/mediaz/App.java
+++ b/src/de/uhilger/mediaz/App.java
@@ -53,7 +53,7 @@
*
* @param args Kommandozeilenparameter
*/
- public static void main(String[] args) {
+ public static void main(String[] args) throws ClassNotFoundException {
rb = ResourceBundle.getBundle(RB_NAME);
logger.info(new File(".").getAbsolutePath());
diff --git a/src/de/uhilger/mediaz/Server.java b/src/de/uhilger/mediaz/Server.java
index 7fbef25..375d7af 100644
--- a/src/de/uhilger/mediaz/Server.java
+++ b/src/de/uhilger/mediaz/Server.java
@@ -21,7 +21,11 @@
import de.uhilger.mediaz.api.AblageTestHandler;
import de.uhilger.mediaz.api.FileHandler;
import de.uhilger.mediaz.api.StopServerHandler;
+import de.uhilger.mediaz.api.StoreHandler;
import de.uhilger.mediaz.api.StoreTestHandler;
+import de.uhilger.mediaz.conf.Store;
+import de.uhilger.mediaz.entity.Ablageort;
+import de.uhilger.mediaz.entity.ConfigurationElement;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;
@@ -30,76 +34,83 @@
import java.util.logging.Level;
/**
- * Die Klasse Server stellt Methoden zur Ausführung eines
- * HTTP-Servers bereit
- *
+ * Die Klasse Server stellt Methoden zur Ausführung eines HTTP-Servers
+ * bereit
+ *
* @author Ulrich Hilger
* @version 0.1, 25.03.2021
*/
public class Server {
-
+
private static final Logger logger = Logger.getLogger(Server.class.getName());
-
+
public static final String RB_SERVER_START_MSG = "msgServerStart";
public static final String RB_WEBROOT = "webroot";
+ public static final String RB_STORE = "store";
//public static final String RB_UI_ROOT = "uiroot";
public static final String RB_STOP_SERVER = "stopServer";
public static final String RB_ABLAGE_TEST = "testAblage";
public static final String RB_STORE_TEST = "testStore";
public static final String RB_SLASH = "slash";
-
+
private int port;
-
+
private String ctx;
-
+
/**
* Ein neues Objekt der Kalsse Server erzeugen
- * @param port der Port, über den dieser Server erreichbar sein soll
+ *
+ * @param port der Port, über den dieser Server erreichbar sein soll
*/
public Server(int port) {
this.port = port;
}
-
+
/**
* Den Port angeben, unter dem der Server erreichbar sein soll
- *
+ *
* @param port der Port, unter dem der Server erreichbar sein soll
*/
public void setPort(int port) {
this.port = port;
}
-
+
/**
- * Den Namen des Kontexts angeben, über den dieser Server
- * erreichbar sein soll
+ * Den Namen des Kontexts angeben, über den dieser Server erreichbar sein
+ * soll
+ *
* @param ctxName Name des Kontexts, unter dem der Server aufrufbar sein soll
*/
public void setContextName(String ctxName) {
String slash = App.getRs(RB_SLASH);
- if(!ctxName.startsWith(slash)) {
+ if (!ctxName.startsWith(slash)) {
this.ctx = slash + ctxName;
} else {
this.ctx = ctxName;
}
}
-
+
/**
- * Die Endpunkte ('Context'e) einrichten, unter denen die Dienste
- * dieses Servers erreichbar sein sollen und den Server starten
- *
- * @throws IOException wenn etwas schief geht, finden sich Angaben
- * in diesem Objekt
+ * Die Endpunkte ('Context'e) einrichten, unter denen die Dienste dieses
+ * Servers erreichbar sein sollen und den Server starten
+ *
+ * @throws IOException wenn etwas schief geht, finden sich Angaben in diesem
+ * Objekt
+ * @throws java.lang.ClassNotFoundException
*/
- public void start() throws IOException {
+ public void start() throws IOException, ClassNotFoundException {
logger.log(Level.INFO, App.getRs(RB_SERVER_START_MSG), Integer.toString(port));
-
+
String wwwData = App.getInitParameter(App.getRs(App.RB_AP_WWW_DATA));
File wwwDir = new File(wwwData);
//String ui = App.getInitParameter(App.getRs(App.RB_AP_UI));
//File uiDir = new File(ui);
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
- server.createContext(ctx + App.getRs(RB_WEBROOT), new FileHandler(wwwDir.getAbsolutePath()));
+ server.createContext(ctx + App.getRs(RB_WEBROOT),
+ new FileHandler(wwwDir.getAbsolutePath()));
+ ablageorteEinklinken(server);
+ server.createContext(ctx + App.getRs(RB_STORE), new StoreHandler());
//server.createContext(ctx + App.getRs(RB_UI_ROOT), new FileHandler(uiDir.getAbsolutePath()));
server.createContext(ctx + App.getRs(RB_STOP_SERVER), new StopServerHandler());
server.createContext(ctx + App.getRs(RB_ABLAGE_TEST), new AblageTestHandler());
@@ -108,4 +119,21 @@
server.start();
}
+ private void ablageorteEinklinken(HttpServer server) throws ClassNotFoundException, IOException {
+ Store store = new Store();
+ String conf = App.getInitParameter(App.getRs(App.RB_AP_CONF));
+ File ablageortDir = new File(conf, Ablageort.class.getSimpleName());
+ File[] orte = ablageortDir.listFiles();
+ if (orte != null) {
+ for (File ort : orte) {
+ ConfigurationElement elem = store.readFromFile(ort);
+ if (elem instanceof Ablageort) {
+ Ablageort ablageort = (Ablageort) elem;
+ server.createContext(ctx + ablageort.getUrl(),
+ new FileHandler(new File(ablageort.getOrt()).getAbsolutePath()));
+ }
+ }
+ }
+ }
+
}
diff --git a/src/de/uhilger/mediaz/api/AblageTestHandler.java b/src/de/uhilger/mediaz/api/AblageTestHandler.java
index e43f4c4..b22a6f5 100644
--- a/src/de/uhilger/mediaz/api/AblageTestHandler.java
+++ b/src/de/uhilger/mediaz/api/AblageTestHandler.java
@@ -21,19 +21,20 @@
@Override
public void handle(HttpExchange e) throws IOException {
- Ablageort ablage = new Ablageort();
- ablage.setName("Katalog");
- ablage.setOrt("/home/ulrich/Videos");
+ Ablageort ablageort = new Ablageort();
+ ablageort.setName("Katalog");
+ ablageort.setOrt("/home/ulrich/Videos");
+ ablageort.setUrl("/media/test");
Gson gson = new Gson();
- File mediaOrdner = new File(ablage.getOrt());
+ File mediaOrdner = new File(ablageort.getOrt());
File[] files = mediaOrdner.listFiles();
String json = gson.toJson(files);
StringBuilder sb = new StringBuilder();
sb.append(json);
- json = gson.toJson(ablage);
+ json = gson.toJson(ablageort);
sb.append(json);
byte[] b = sb.toString().getBytes();
diff --git a/src/de/uhilger/mediaz/api/StoreHandler.java b/src/de/uhilger/mediaz/api/StoreHandler.java
new file mode 100644
index 0000000..4e317bb
--- /dev/null
+++ b/src/de/uhilger/mediaz/api/StoreHandler.java
@@ -0,0 +1,125 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package de.uhilger.mediaz.api;
+
+import com.google.gson.Gson;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import de.uhilger.mediaz.App;
+import de.uhilger.mediaz.Server;
+import de.uhilger.mediaz.conf.Store;
+import de.uhilger.mediaz.entity.Ablageort;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author ulrich
+ */
+public class StoreHandler extends Store implements HttpHandler {
+
+ private static final Logger logger = Logger.getLogger(StoreHandler.class.getName());
+
+
+ /*
+
+ HTTP GET: lies einen Ablageort und schreibe JSON
+ HTTP PUT: schreibe einen neuen Ablageort auf die Platte
+ HTTP POST: schreibe Aenderungen auf die Platte
+ HTTP DELETE: loesche den Ablageort
+
+ Beispiele:
+
+ HTTP GET an /mz/api/store/Ablageort/Katalog
+ liest den Ablageort namens "Katalog"
+
+ HTTP POST an /mz/api/store/Ablageort
+ schreibt den neuen Ablageort im Body der Anfrage
+
+ HTTP PUT an /mz/api/store/Ablageort
+ sucht den Ablageort mit dem Namen laut Body der Anfrage
+ und schreibt den Inhalt aus der Anfrage in die Datei
+
+ HTTP DELETE an /mz/api/store/Ablageort/Katalog
+ löscht den Ablageort namens "Katalog"
+
+ */
+
+ public static final String HTTP_GET = "GET";
+ public static final String HTTP_PUT = "PUT";
+ public static final String HTTP_POST = "POST";
+ public static final String HTTP_DELETE = "DELETE";
+
+ @Override
+ public void handle(HttpExchange e) throws IOException {
+ String method = e.getRequestMethod();
+ String path = e.getRequestURI().toString();
+ String[] elems = path.split(App.getRs(Server.RB_SLASH));
+ String type = "";
+ String elemName = "";
+ switch(method) {
+ case HTTP_GET:
+ type = elems[elems.length - 2];
+ elemName = elems[elems.length - 1];
+ //this.readFromFile(file);
+ break;
+
+ case HTTP_PUT:
+ type = elems[elems.length - 1];
+ elemName = "noch bauen: lesen aus Body";
+ break;
+
+ case HTTP_POST:
+ type = elems[elems.length - 1];
+ elemName = bodyLesen(e);
+ if(type.equalsIgnoreCase("Ablageort")) {
+ Gson gson = new Gson();
+ Ablageort ort = gson.fromJson(elemName, Ablageort.class);
+ elemName = ort.getName();
+ }
+ break;
+
+ case HTTP_DELETE:
+ type = elems[elems.length - 2];
+ elemName = elems[elems.length - 1];
+ break;
+ }
+
+
+ String response = "Method: " + method + ", Path: " + path +
+ ", Type: " + type + ", elemName: " + elemName;
+ logger.info(response);
+ e.sendResponseHeaders(200, response.length());
+ OutputStream os = e.getResponseBody();
+ os.write(response.getBytes());
+ os.close();
+ }
+
+
+ private String bodyLesen(HttpExchange e) throws IOException {
+ InputStream is = e.getRequestBody();
+ BufferedReader r = new BufferedReader(new InputStreamReader(is));
+ StringBuilder sb = new StringBuilder();
+ String line = r.readLine();
+ while(line != null) {
+ sb.append(line);
+ line = r.readLine();
+ }
+ r.close();
+ // {"Ablageort":{"name":"test1","ort":"test2","url":"test3"}}
+ //String data = sb.toString();
+ //data = data.substring(1, data.length() - 1);
+ //String json = data.substring(data.indexOf("{"));
+ // {"name":"test1","ort":"test2","url":"test3"}
+ String json = sb.toString();
+ logger.info("json: " + json);
+ return json;
+ }
+}
diff --git a/src/de/uhilger/mediaz/api/StoreTestHandler.java b/src/de/uhilger/mediaz/api/StoreTestHandler.java
index 8e040a0..e1da7c3 100644
--- a/src/de/uhilger/mediaz/api/StoreTestHandler.java
+++ b/src/de/uhilger/mediaz/api/StoreTestHandler.java
@@ -30,6 +30,7 @@
Ablageort ort = new Ablageort();
ort.setName("Katalog");
ort.setOrt("/home/ulrich/Videos");
+ ort.setUrl("/media/test");
Store store = new Store();
File file = store.writeToFile(ort);
try {
diff --git a/src/de/uhilger/mediaz/conf/Store.java b/src/de/uhilger/mediaz/conf/Store.java
index 546aeee..fcfe3ae 100644
--- a/src/de/uhilger/mediaz/conf/Store.java
+++ b/src/de/uhilger/mediaz/conf/Store.java
@@ -94,4 +94,6 @@
logger.info(parts[parts.length-2]);
return parts[parts.length-2];
}
+
+
}
diff --git a/src/mediaz_de_DE.properties b/src/mediaz_de_DE.properties
index b8e6f6f..b95252e 100644
--- a/src/mediaz_de_DE.properties
+++ b/src/mediaz_de_DE.properties
@@ -9,6 +9,7 @@
# HTTP-Endpunkte
webroot=/
# uiroot=/ui
+store=/api/store
stopServer=/api/server/stop
testAblage=/api/test/ablage
testStore=/api/test/store
diff --git a/www/ui/app.css b/www/ui/app.css
index 5827ce8..d5bae40 100644
--- a/www/ui/app.css
+++ b/www/ui/app.css
@@ -117,3 +117,148 @@
font-size: 1.3em;
color: #b8b8b8;
}
+
+/* ab hier Mediazentrale */
+
+.entity-formular {
+ display: flex;
+ flex-flow: column;
+}
+
+.entity-element {
+ margin: 0.4rem;
+}
+
+/*
+@media (min-width: 800px) {
+ .zentrum-behaelter {
+ padding: 0 1em 0 1em;
+ }
+ .zentrum-behaelter, .nord {
+ margin: 0 10% 0 10%;
+ }
+}
+
+
+/* von Skeleton */
+
+/* Buttons
+–––––––––––––––––––––––––––––––––––––––––––––––––– */
+.button,
+button,
+input[type="submit"],
+input[type="reset"],
+input[type="button"] {
+ display: inline-block;
+ height: 38px;
+ padding: 0 30px;
+ color: #555;
+ text-align: center;
+ font-size: 11px;
+ font-weight: 600;
+ line-height: 38px;
+ letter-spacing: .1rem;
+ text-transform: uppercase;
+ text-decoration: none;
+ white-space: nowrap;
+ background-color: transparent;
+ border-radius: 4px;
+ border: 1px solid #bbb;
+ cursor: pointer;
+ box-sizing: border-box; }
+.button:hover,
+button:hover,
+input[type="submit"]:hover,
+input[type="reset"]:hover,
+input[type="button"]:hover,
+.button:focus,
+button:focus,
+input[type="submit"]:focus,
+input[type="reset"]:focus,
+input[type="button"]:focus {
+ color: #333;
+ border-color: #888;
+ outline: 0; }
+.button.button-primary,
+button.button-primary,
+input[type="submit"].button-primary,
+input[type="reset"].button-primary,
+input[type="button"].button-primary {
+ color: #FFF;
+ background-color: #33C3F0;
+ border-color: #33C3F0; }
+.button.button-primary:hover,
+button.button-primary:hover,
+input[type="submit"].button-primary:hover,
+input[type="reset"].button-primary:hover,
+input[type="button"].button-primary:hover,
+.button.button-primary:focus,
+button.button-primary:focus,
+input[type="submit"].button-primary:focus,
+input[type="reset"].button-primary:focus,
+input[type="button"].button-primary:focus {
+ color: #FFF;
+ background-color: #1EAEDB;
+ border-color: #1EAEDB; }
+
+
+/* Forms
+–––––––––––––––––––––––––––––––––––––––––––––––––– */
+input[type="email"],
+input[type="number"],
+input[type="search"],
+input[type="text"],
+input[type="tel"],
+input[type="url"],
+input[type="password"],
+textarea,
+select {
+ height: 38px;
+ padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
+ background-color: #fff;
+ border: 1px solid #D1D1D1;
+ border-radius: 4px;
+ box-shadow: none;
+ box-sizing: border-box; }
+/* Removes awkward default styles on some inputs for iOS */
+input[type="email"],
+input[type="number"],
+input[type="search"],
+input[type="text"],
+input[type="tel"],
+input[type="url"],
+input[type="password"],
+textarea {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none; }
+textarea {
+ min-height: 65px;
+ padding-top: 6px;
+ padding-bottom: 6px; }
+input[type="email"]:focus,
+input[type="number"]:focus,
+input[type="search"]:focus,
+input[type="text"]:focus,
+input[type="tel"]:focus,
+input[type="url"]:focus,
+input[type="password"]:focus,
+textarea:focus,
+select:focus {
+ border: 1px solid #33C3F0;
+ outline: 0; }
+label,
+legend {
+ display: block;
+ margin-bottom: .5rem;
+ font-weight: 600; }
+fieldset {
+ padding: 0;
+ border-width: 0; }
+input[type="checkbox"],
+input[type="radio"] {
+ display: inline; }
+label > .label-body {
+ display: inline-block;
+ margin-left: .5rem;
+ font-weight: normal; }
diff --git a/www/ui/data/ablageort.css b/www/ui/data/ablageort.css
new file mode 100644
index 0000000..923d8ab
--- /dev/null
+++ b/www/ui/data/ablageort.css
@@ -0,0 +1,20 @@
+/*
+To change this license header, choose License Headers in Project Properties.
+To change this template file, choose Tools | Templates
+and open the template in the editor.
+*/
+/*
+ Created on : 04.04.2021, 17:02:13
+ Author : ulrich
+*/
+
+
+
+.entity-formular {
+ display: flex;
+ flex-flow: column;
+}
+
+.entity-element {
+ margin: 0.4rem;
+}
\ No newline at end of file
diff --git a/www/ui/data/ablageort.html b/www/ui/data/ablageort.html
new file mode 100644
index 0000000..34ee44d
--- /dev/null
+++ b/www/ui/data/ablageort.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!--
+ Mediazentrale - Personal Media Center
+ Copyright (C) 2021 Ulrich Hilger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+-->
+<html>
+ <head>
+ <title>Ablageort</title>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="../app.css">
+ <link rel="stylesheet" type="text/css" href="formulare.css">
+ <link rel="stylesheet" type="text/css" href="ablageort.css">
+
+ </head>
+ <body>
+ <div class="entity-formular">
+ Ablageort
+
+ <input class="entity-element" type="text" id="ablageort-name" placeholder="Name" >
+ <input class="entity-element" type="text" id="ablageort-ort" placeholder="Pfad" >
+ <input class="entity-element" type="text" id="ablageort-url" placeholder="URL" >
+ <div class="entity-buttons">
+ <button class="button-primary" id="ok-btn">Speichern</button>
+ <button class="button" id="cancel-btn">Abbrechen</button>
+ </div>
+
+ </div>
+ </body>
+</html>
diff --git a/www/ui/data/formulare.css b/www/ui/data/formulare.css
new file mode 100644
index 0000000..a4c677c
--- /dev/null
+++ b/www/ui/data/formulare.css
@@ -0,0 +1,145 @@
+/*
+To change this license header, choose License Headers in Project Properties.
+To change this template file, choose Tools | Templates
+and open the template in the editor.
+*/
+/*
+ Created on : 04.04.2021, 17:05:29
+ Author : ulrich
+*/
+
+
+
+@media (min-width: 800px) {
+ .zentrum-behaelter {
+ padding: 0 1em 0 1em;
+ }
+ .zentrum-behaelter, .nord {
+ margin: 0 10% 0 10%;
+ }
+}
+
+
+
+/* von Skeleton */
+
+/* Buttons
+–––––––––––––––––––––––––––––––––––––––––––––––––– */
+.button,
+button,
+input[type="submit"],
+input[type="reset"],
+input[type="button"] {
+ display: inline-block;
+ height: 38px;
+ padding: 0 30px;
+ color: #555;
+ text-align: center;
+ font-size: 11px;
+ font-weight: 600;
+ line-height: 38px;
+ letter-spacing: .1rem;
+ text-transform: uppercase;
+ text-decoration: none;
+ white-space: nowrap;
+ background-color: transparent;
+ border-radius: 4px;
+ border: 1px solid #bbb;
+ cursor: pointer;
+ box-sizing: border-box; }
+.button:hover,
+button:hover,
+input[type="submit"]:hover,
+input[type="reset"]:hover,
+input[type="button"]:hover,
+.button:focus,
+button:focus,
+input[type="submit"]:focus,
+input[type="reset"]:focus,
+input[type="button"]:focus {
+ color: #333;
+ border-color: #888;
+ outline: 0; }
+.button.button-primary,
+button.button-primary,
+input[type="submit"].button-primary,
+input[type="reset"].button-primary,
+input[type="button"].button-primary {
+ color: #FFF;
+ background-color: #33C3F0;
+ border-color: #33C3F0; }
+.button.button-primary:hover,
+button.button-primary:hover,
+input[type="submit"].button-primary:hover,
+input[type="reset"].button-primary:hover,
+input[type="button"].button-primary:hover,
+.button.button-primary:focus,
+button.button-primary:focus,
+input[type="submit"].button-primary:focus,
+input[type="reset"].button-primary:focus,
+input[type="button"].button-primary:focus {
+ color: #FFF;
+ background-color: #1EAEDB;
+ border-color: #1EAEDB; }
+
+
+/* Forms
+–––––––––––––––––––––––––––––––––––––––––––––––––– */
+input[type="email"],
+input[type="number"],
+input[type="search"],
+input[type="text"],
+input[type="tel"],
+input[type="url"],
+input[type="password"],
+textarea,
+select {
+ height: 38px;
+ padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
+ background-color: #fff;
+ border: 1px solid #D1D1D1;
+ border-radius: 4px;
+ box-shadow: none;
+ box-sizing: border-box; }
+/* Removes awkward default styles on some inputs for iOS */
+input[type="email"],
+input[type="number"],
+input[type="search"],
+input[type="text"],
+input[type="tel"],
+input[type="url"],
+input[type="password"],
+textarea {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none; }
+textarea {
+ min-height: 65px;
+ padding-top: 6px;
+ padding-bottom: 6px; }
+input[type="email"]:focus,
+input[type="number"]:focus,
+input[type="search"]:focus,
+input[type="text"]:focus,
+input[type="tel"]:focus,
+input[type="url"]:focus,
+input[type="password"]:focus,
+textarea:focus,
+select:focus {
+ border: 1px solid #33C3F0;
+ outline: 0; }
+label,
+legend {
+ display: block;
+ margin-bottom: .5rem;
+ font-weight: 600; }
+fieldset {
+ padding: 0;
+ border-width: 0; }
+input[type="checkbox"],
+input[type="radio"] {
+ display: inline; }
+label > .label-body {
+ display: inline-block;
+ margin-left: .5rem;
+ font-weight: normal; }
diff --git a/www/ui/data/menu/hauptmenue.json b/www/ui/data/menu/hauptmenue.json
index b0685f0..44f268a 100644
--- a/www/ui/data/menu/hauptmenue.json
+++ b/www/ui/data/menu/hauptmenue.json
@@ -8,6 +8,11 @@
},
"inhalt": [
{
+ "titel": "Neuer Ablageort",
+ "umenue": false,
+ "funktion": "app.form_ablageort_neu"
+ },
+ {
"titel": "Seite umschalten",
"umenue": false,
"funktion": "app.seitenleiste_umschalten"
diff --git a/www/ui/data/test.html b/www/ui/data/test.html
new file mode 100644
index 0000000..00949d9
--- /dev/null
+++ b/www/ui/data/test.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!--
+ Mediazentrale - Personal Media Center
+ Copyright (C) 2021 Ulrich Hilger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+-->
+<html>
+ <head>
+ <title>TODO supply a title</title>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ </head>
+ <body>
+ <div>TODO write content</div>
+ </body>
+</html>
diff --git a/www/ui/data/tpl/form_ablageort.tpl b/www/ui/data/tpl/form_ablageort.tpl
new file mode 100644
index 0000000..d6132bf
--- /dev/null
+++ b/www/ui/data/tpl/form_ablageort.tpl
@@ -0,0 +1,13 @@
+ <div class="entity-formular">
+ Ablageort
+
+ <input class="entity-element" type="text" id="ablageort-name" placeholder="Name" />
+ <input class="entity-element" type="text" id="ablageort-ort" placeholder="Pfad" />
+ <input class="entity-element" type="text" id="ablageort-url" placeholder="URL" />
+ <div class="entity-buttons">
+ <button class="button-primary" id="ok-btn">Speichern</button>
+ <button class="button" id="cancel-btn">Abbrechen</button>
+ </div>
+
+ </div>
+
diff --git a/www/ui/index.html b/www/ui/index.html
index d206386..2a2f3df 100644
--- a/www/ui/index.html
+++ b/www/ui/index.html
@@ -1,7 +1,24 @@
<!DOCTYPE html>
+<!--
+ Mediazentrale - Personal Media Center
+ Copyright (C) 2021 Ulrich Hilger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+-->
<html>
<head>
- <title>App-Vorlage</title>
+ <title>Mediazentrale</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes" />
@@ -21,7 +38,7 @@
</div>
</div>
<div class="app-titel">
- <span id="app-titel">App-Vorlage</span>
+ <span id="app-titel">Mediazentrale</span>
</div>
</div>
<div class="inhalt">
@@ -36,19 +53,7 @@
<div class="zentrum">
<div class="zentraler-inhalt">
<p>
- Hier kann beliebiger Inhalt erscheinen.
- </p>
- <p>
- Wenn dessen Darstellung mehr
- Platz benötigt als das Anzeigegerät bietet wird ein
- Rollbalken eingeblendet. Beim Rollen zu anfangs nicht sichtbaren
- Teilen des Inhalts bleiben die den Inhaltsbereich
- umschließenden Elemente sichtbar.
- </p>
- <p>
- Ein Klick auf das Hamburger-Piktogramm oben links bzw. dessen
- Antippen blendet ein Menü ein von dem aus weitere Funktionen
- ausgelöst werden können.
+ Hier erschient der Media-Inhalt.
</p>
</div>
</div>
@@ -70,7 +75,7 @@
<script>
var app;
document.addEventListener('DOMContentLoaded', function () {
- app = new AppVorlage();
+ app = new Mediazentrale();
app.init();
});
</script>
diff --git a/www/ui/js/app.js b/www/ui/js/app.js
index 4eaffef..f7cd6be 100644
--- a/www/ui/js/app.js
+++ b/www/ui/js/app.js
@@ -1,10 +1,84 @@
-function AppVorlage() {
+function Ablageort(n, o, u) {
+ this.name = n;
+ this.ort = o;
+ this.url = u;
+}
+
+
+
+function Mediazentrale() {
var self = this;
var appMenu;
// var vorlagen;
var cache; // mustache templates
+
+ this.form_ablageort_neu = function() {
+ self.vorlage_laden_und_fuellen("data/tpl/form_ablageort.tpl", "", function(html) {
+ document.querySelector(".zentraler-inhalt").innerHTML = html;
+ self.addEvtListener('#ok-btn', 'click', function() {
+ // hier neuen Ablageort speichern
+ var a = new Ablageort(
+ document.querySelector('#ablageort-name').value,
+ document.querySelector('#ablageort-ort').value,
+ document.querySelector('#ablageort-url').value
+ );
+ // {"name":"Katalog","ort":"/home/ulrich/Videos","url":"/media/test"}
+ //var daten = self.serialisieren(a);
+ var daten = JSON.stringify(a);
+ self.http_post('../api/store/Ablageort', daten, function(){
+ // hier die Antwort verarbeiten
+ });
+ });
+ self.addEvtListener('#cancel-btn', 'click', function() {
+ // hier die Aktion abbrechen
+ });
+ });
+ };
+
+ this.addEvtListener = function(selector, eventName, func) {
+ var elems = document.querySelectorAll(selector);
+ var index;
+ for (index = 0; index < elems.length; index++) {
+ elems[index].addEventListener(eventName, func);
+ }
+ };
+
+ this.http_get = function(u, cb) {
+ self.http_call('GET', u, null, cb);
+ };
+
+ this.http_post = function(u, data, cb) {
+ self.http_call('POST', u, data, cb);
+ };
+
+ this.http_call = function (method, u, data, scallback) {
+ var xhr = new XMLHttpRequest();
+ var url = u;
+ xhr.onreadystatechange = function() {
+ if (this.readyState === 4 && this.status === 200) {
+ scallback(this.responseText);
+ }
+ };
+ xhr.open(method, url);
+ if(method === 'GET') {
+ xhr.send();
+ } else if(method === 'POST' || method === 'PUT') {
+ xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+ xhr.send(data);
+ }
+ };
+
+ this.serialisieren = function(obj) {
+ return '{"' + obj.constructor.name + '":' + JSON.stringify(obj) + '}';
+ };
+
+
+
+
+ /* ab hier aus App-Vorlage */
+
this.init = function() {
//self.vorlagen = new Vorlagen();
self.cache = new Array();
--
Gitblit v1.9.3