New Design
This commit is contained in:
		
							
								
								
									
										365
									
								
								html/index.html
									
									
									
									
									
								
							
							
						
						
									
										365
									
								
								html/index.html
									
									
									
									
									
								
							@@ -4,133 +4,300 @@
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <title>Pixelserver Interface</title>
 | 
			
		||||
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=1, viewport-fit=auto"/>
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, viewport-fit=cover"/>
 | 
			
		||||
    <link rel="apple-touch-icon" sizes="180x180" href="/icons/apple-touch-icon.png">
 | 
			
		||||
    <link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32x32.png">
 | 
			
		||||
    <link rel="icon" type="image/png" sizes="16x16" href="/icons/favicon-16x16.png">
 | 
			
		||||
    <link rel="manifest" href="/site.webmanifest">
 | 
			
		||||
 | 
			
		||||
    <style>
 | 
			
		||||
        .main {
 | 
			
		||||
            display: grid;
 | 
			
		||||
            grid-gap: 1rem;
 | 
			
		||||
            align-items: stretch;
 | 
			
		||||
        /* --- Base Styles & CSS Variables --- */
 | 
			
		||||
        :root {
 | 
			
		||||
            --bg-color: #f7fafc;
 | 
			
		||||
            --card-bg-color: #ffffff;
 | 
			
		||||
            --text-color: #2d3748;
 | 
			
		||||
            --header-color: #1a202c;
 | 
			
		||||
            --muted-text-color: #718096;
 | 
			
		||||
            --border-color: #e2e8f0;
 | 
			
		||||
            --input-bg-color: #f7fafc;
 | 
			
		||||
            --button-primary-bg: #3b82f6;
 | 
			
		||||
            --button-primary-hover-bg: #2563eb;
 | 
			
		||||
            --button-secondary-bg: #6b7280;
 | 
			
		||||
            --button-secondary-hover-bg: #4b5563;
 | 
			
		||||
            --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @media only screen {
 | 
			
		||||
            .main {
 | 
			
		||||
                grid-template-columns: repeat(1, 1fr);
 | 
			
		||||
        @media (prefers-color-scheme: dark) {
 | 
			
		||||
            :root {
 | 
			
		||||
                --bg-color: #111827;
 | 
			
		||||
                --card-bg-color: #1f2937;
 | 
			
		||||
                --text-color: #d1d5db;
 | 
			
		||||
                --header-color: #ffffff;
 | 
			
		||||
                --muted-text-color: #9ca3af;
 | 
			
		||||
                --border-color: #374151;
 | 
			
		||||
                --input-bg-color: #374151;
 | 
			
		||||
                --button-secondary-bg: #4b5563;
 | 
			
		||||
                --button-secondary-hover-bg: #374151;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @media only screen and (min-width: 800px) {
 | 
			
		||||
            .main {
 | 
			
		||||
                grid-template-columns: repeat(2, 1fr);
 | 
			
		||||
            }
 | 
			
		||||
        body {
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
 | 
			
		||||
            background-color: var(--bg-color);
 | 
			
		||||
            color: var(--text-color);
 | 
			
		||||
            padding: 1rem;
 | 
			
		||||
            box-sizing: border-box;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @media only screen and (min-width: 1111px) {
 | 
			
		||||
            .main {
 | 
			
		||||
                grid-template-columns: repeat(3, 1fr);
 | 
			
		||||
            }
 | 
			
		||||
        /* --- Layout --- */
 | 
			
		||||
        .main-container {
 | 
			
		||||
            max-width: 1400px;
 | 
			
		||||
            margin: 0 auto;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .main {
 | 
			
		||||
            display: flex;
 | 
			
		||||
            flex-wrap: wrap;
 | 
			
		||||
            gap: 1.5rem;
 | 
			
		||||
            justify-content: center;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .col {
 | 
			
		||||
            background-color: var(--card-bg-color);
 | 
			
		||||
            border-radius: 0.75rem;
 | 
			
		||||
            padding: 1.5rem;
 | 
			
		||||
            box-shadow: var(--shadow-md);
 | 
			
		||||
            border: 1px solid var(--border-color);
 | 
			
		||||
            flex: 1 1 320px; /* Flex-grow, flex-shrink, basis */
 | 
			
		||||
            min-width: 300px;
 | 
			
		||||
            /*max-width: 350px;*/
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .just, .just-col {
 | 
			
		||||
            display: flex;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .just > * {
 | 
			
		||||
            flex: 1;
 | 
			
		||||
            margin: 0 1rem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .just-col {
 | 
			
		||||
            flex-direction: column;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .just-col > * {
 | 
			
		||||
            flex: 1;
 | 
			
		||||
            margin: 2px 1rem;
 | 
			
		||||
        /* --- Typography --- */
 | 
			
		||||
        h1 {
 | 
			
		||||
            text-align: center;
 | 
			
		||||
            color: var(--header-color);
 | 
			
		||||
            margin-bottom: 2rem;
 | 
			
		||||
            font-size: 2.25rem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        h1 i {
 | 
			
		||||
            font-style: normal;
 | 
			
		||||
            color: var(--button-primary-bg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        h2 {
 | 
			
		||||
            font-size: 1.25rem;
 | 
			
		||||
            color: var(--header-color);
 | 
			
		||||
            border-bottom: 1px solid var(--border-color);
 | 
			
		||||
            padding-bottom: 0.5rem;
 | 
			
		||||
            margin-top: 0;
 | 
			
		||||
            margin-bottom: 1rem;
 | 
			
		||||
            display: flex;
 | 
			
		||||
            justify-content: space-between;
 | 
			
		||||
            align-items: center;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        h3 {
 | 
			
		||||
            color: var(--header-color);
 | 
			
		||||
            margin-top: 0.5rem;
 | 
			
		||||
            margin-bottom: 0;
 | 
			
		||||
            font-size: 1rem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        label {
 | 
			
		||||
            display: block;
 | 
			
		||||
            /*margin-top: 0.5rem;*/
 | 
			
		||||
            font-weight: 500;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* --- Forms & Inputs --- */
 | 
			
		||||
        form {
 | 
			
		||||
            display: flex;
 | 
			
		||||
            flex-direction: column;
 | 
			
		||||
            gap: 1rem;
 | 
			
		||||
            flex-grow: 1; /* Allow form to grow */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        input[type="text"],
 | 
			
		||||
        input[type="number"],
 | 
			
		||||
        select {
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            padding: 0.75rem;
 | 
			
		||||
            border-radius: 0.375rem;
 | 
			
		||||
            border: 1px solid var(--border-color);
 | 
			
		||||
            background-color: var(--input-bg-color);
 | 
			
		||||
            color: var(--text-color);
 | 
			
		||||
            box-sizing: border-box;
 | 
			
		||||
            font-size: 1rem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        input[type="checkbox"] {
 | 
			
		||||
            /* Hide original checkbox */
 | 
			
		||||
            display: none;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        button {
 | 
			
		||||
            padding: 0.75rem 1.5rem;
 | 
			
		||||
            border: none;
 | 
			
		||||
            border-radius: 0.375rem;
 | 
			
		||||
            background-color: var(--button-primary-bg);
 | 
			
		||||
            color: white;
 | 
			
		||||
            font-weight: 600;
 | 
			
		||||
            font-size: 1rem;
 | 
			
		||||
            cursor: pointer;
 | 
			
		||||
            transition: background-color 0.2s ease;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        button:hover {
 | 
			
		||||
            background-color: var(--button-primary-hover-bg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        button.startstop {
 | 
			
		||||
            padding: 0.25rem 0.75rem;
 | 
			
		||||
            font-size: 0.875rem;
 | 
			
		||||
            font-weight: 500;
 | 
			
		||||
            background-color: var(--button-secondary-bg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        button.startstop:hover {
 | 
			
		||||
            background-color: var(--button-secondary-hover-bg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        textarea {
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            box-sizing: border-box;
 | 
			
		||||
            height: 300px;
 | 
			
		||||
            background-color: var(--input-bg-color);
 | 
			
		||||
            color: var(--text-color);
 | 
			
		||||
            border: 1px solid var(--border-color);
 | 
			
		||||
            border-radius: 0.375rem;
 | 
			
		||||
            padding: 0.5rem;
 | 
			
		||||
            font-family: monospace;
 | 
			
		||||
            flex-grow: 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* --- Helper classes --- */
 | 
			
		||||
        .just-col {
 | 
			
		||||
            display: flex;
 | 
			
		||||
            flex-direction: column;
 | 
			
		||||
            gap: 1rem;
 | 
			
		||||
            align-items: stretch;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .just-col label {
 | 
			
		||||
            display: flex;
 | 
			
		||||
            align-items: center;
 | 
			
		||||
            justify-content: space-between;
 | 
			
		||||
            gap: 1rem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #gammaform span {
 | 
			
		||||
            display: inline-block;
 | 
			
		||||
            width: 4rem;
 | 
			
		||||
            flex-basis: 4rem;
 | 
			
		||||
            flex-shrink: 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .logging {
 | 
			
		||||
            max-width: 500px;
 | 
			
		||||
        /* --- Button Checkbox Styles --- */
 | 
			
		||||
        .checkbox-button {
 | 
			
		||||
            display: block;
 | 
			
		||||
            padding: 0.75rem 1rem;
 | 
			
		||||
            border: 5px solid var(--border-color);
 | 
			
		||||
            border-radius: 0.375rem;
 | 
			
		||||
            text-align: center;
 | 
			
		||||
            cursor: pointer;
 | 
			
		||||
            background-color: var(--card-bg-color);
 | 
			
		||||
            color: var(--text-color);
 | 
			
		||||
            transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
 | 
			
		||||
            font-weight: 500;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .options {
 | 
			
		||||
            max-width: 350px;
 | 
			
		||||
        #flipform input[type="checkbox"]:checked + .checkbox-button {
 | 
			
		||||
            /*background-color: var(--button-primary-bg);*/
 | 
			
		||||
            /*color: white;*/
 | 
			
		||||
            border-color: var(--button-primary-bg);
 | 
			
		||||
            border-width: 5px;
 | 
			
		||||
        }
 | 
			
		||||
    </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<h1 style="text-align: center;">Andreas <i>production-ready</i> Interface</h1>
 | 
			
		||||
<div class="main">
 | 
			
		||||
<div class="main-container">
 | 
			
		||||
    <h1>Andreas <i>production-ready</i> Interface</h1>
 | 
			
		||||
    <div class="main">
 | 
			
		||||
        <div class="col">
 | 
			
		||||
        <h2><label for="list">Kommando:</label></h2>
 | 
			
		||||
        <form id="in" class="" onSubmit="return request()">
 | 
			
		||||
            <h2>Kommando</h2>
 | 
			
		||||
            <form id="in" onSubmit="return request()">
 | 
			
		||||
                <select id="list"></select>
 | 
			
		||||
            <input id="args"/>
 | 
			
		||||
            <button id="execute">Ausführen</button>
 | 
			
		||||
        </form>
 | 
			
		||||
 | 
			
		||||
        <h2><label for="brightness">Intensität:</label></h2>
 | 
			
		||||
        <form id="brightnessform" class="just" onSubmit="return setbrightness()">
 | 
			
		||||
            <input id="brightness" value="1.0"><br/>
 | 
			
		||||
            <button id="sendbrightness">Setzen</button>
 | 
			
		||||
                <input id="args" type="text" placeholder="Argumente..."/>
 | 
			
		||||
                <button>Ausführen</button>
 | 
			
		||||
            </form>
 | 
			
		||||
        </div>
 | 
			
		||||
    <div class="options col">
 | 
			
		||||
        <h2>Gamma:</h2>
 | 
			
		||||
        <form id="gammaform" class="just-col" onSubmit="return setgamma()">
 | 
			
		||||
            <label><span>Rot: </span><input id="gammar" value="2.8"/></label><br/>
 | 
			
		||||
            <label><span>Grün: </span><input id="gammag" value="2.65"/></label><br/>
 | 
			
		||||
            <label><span>Blau: </span><input id="gammab" value="2.65"/></label><br/>
 | 
			
		||||
            <label><span>Weiß: </span><input id="gammaw" value="2.65"/></label><br/>
 | 
			
		||||
            <button id="sendgamma">Setzen</button>
 | 
			
		||||
        </form>
 | 
			
		||||
 | 
			
		||||
        <h2>Flip:</h2>
 | 
			
		||||
        <form id="flipform" class="just" onSubmit="return setFlip()">
 | 
			
		||||
            <label><input id="flipx" type="checkbox"/> Flip X</label>
 | 
			
		||||
            <label><input id="flipy" type="checkbox"/> Flip Y</label>
 | 
			
		||||
            <button id="sendflip">Setzen</button>
 | 
			
		||||
        </form>
 | 
			
		||||
 | 
			
		||||
        <h2><label for="filtername">Filterimage:</label></h2>
 | 
			
		||||
        <form id="filterform" class="just" onSubmit="return setFilter()">
 | 
			
		||||
            <input id="filtername" value="test">
 | 
			
		||||
            <button id="filterflip">Setzen</button>
 | 
			
		||||
        </form>
 | 
			
		||||
 | 
			
		||||
        <h2><label for="filterexpr">Filter expression:</label></h2>
 | 
			
		||||
        <form id="filterexprform" class="just" onSubmit="return setFilterExpr()">
 | 
			
		||||
            <input id="filterexpr" value="0.5+0.25*sin(x/3+t)">
 | 
			
		||||
        <div class="col">
 | 
			
		||||
            <h2>Intensität</h2>
 | 
			
		||||
            <form onSubmit="return setbrightness()">
 | 
			
		||||
                <input id="brightness" value="1.0" type="number" step="0.1"><br/>
 | 
			
		||||
                <button>Setzen</button>
 | 
			
		||||
            </form>
 | 
			
		||||
        </div>
 | 
			
		||||
    <div class="logging col">
 | 
			
		||||
        <h2>Crash Log:
 | 
			
		||||
            <button id="crashlogbtn" type="button" onclick="return enableCrashLog()">start</button>
 | 
			
		||||
        </h2>
 | 
			
		||||
        <textarea readonly id="crashlogs" style="width: 500px; height: 300px; display: none;"></textarea>
 | 
			
		||||
 | 
			
		||||
        <h2>Log:
 | 
			
		||||
            <button id="logbtn" type="button" onclick="return enableLog()">start</button>
 | 
			
		||||
        </h2>
 | 
			
		||||
        <textarea readonly id="logs" style="width: 500px; height: 300px; display: none;"></textarea>
 | 
			
		||||
        <div class="col">
 | 
			
		||||
            <h2>Gamma</h2>
 | 
			
		||||
            <form id="gammaform" class="just-col" onSubmit="return setgamma()">
 | 
			
		||||
                <label><span>Rot: </span><input id="gammar" value="2.8" type="number" step="0.05"/></label>
 | 
			
		||||
                <label><span>Grün: </span><input id="gammag" value="2.65" type="number" step="0.05"/></label>
 | 
			
		||||
                <label><span>Blau: </span><input id="gammab" value="2.65" type="number" step="0.05"/></label>
 | 
			
		||||
                <label><span>Weiß: </span><input id="gammaw" value="2.65" type="number" step="0.05"/></label>
 | 
			
		||||
                <button>Setzen</button>
 | 
			
		||||
            </form>
 | 
			
		||||
        </div>
 | 
			
		||||
    <script>
 | 
			
		||||
 | 
			
		||||
        <div class="col">
 | 
			
		||||
            <h2>Flip</h2>
 | 
			
		||||
            <form id="flipform" onSubmit="return setFlip()">
 | 
			
		||||
                <label>
 | 
			
		||||
                    <input id="flipx" type="checkbox"/>
 | 
			
		||||
                    <span class="checkbox-button">Flip X</span>
 | 
			
		||||
                </label>
 | 
			
		||||
                <label>
 | 
			
		||||
                    <input id="flipy" type="checkbox"/>
 | 
			
		||||
                    <span class="checkbox-button">Flip Y</span>
 | 
			
		||||
                </label>
 | 
			
		||||
                <button>Setzen</button>
 | 
			
		||||
            </form>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="col">
 | 
			
		||||
            <h2>Filter</h2>
 | 
			
		||||
            <form onSubmit="return setFilter()">
 | 
			
		||||
                <h3><label for="filtername">Filterimage:</label></h3>
 | 
			
		||||
                <input id="filtername" value="test" type="text">
 | 
			
		||||
                <button>Setzen</button>
 | 
			
		||||
            </form>
 | 
			
		||||
            <form onSubmit="return setFilterExpr()">
 | 
			
		||||
                <h3><label for="filterexpr">Filter expression:</label></h3>
 | 
			
		||||
                <input id="filterexpr" value="0.5+0.25*sin(x/3+t)" type="text">
 | 
			
		||||
                <button>Setzen</button>
 | 
			
		||||
            </form>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="col">
 | 
			
		||||
            <h2>Crash Log
 | 
			
		||||
                <button id="crashlogbtn" class="startstop" type="button" onclick="return enableCrashLog()">start</button>
 | 
			
		||||
            </h2>
 | 
			
		||||
            <textarea readonly id="crashlogs" style="display: none;"></textarea>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="col">
 | 
			
		||||
            <h2>Log
 | 
			
		||||
                <button id="logbtn" class="startstop" type="button" onclick="return enableLog()">start</button>
 | 
			
		||||
            </h2>
 | 
			
		||||
            <textarea readonly id="logs" style="display: none;"></textarea>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
<script>
 | 
			
		||||
    function getRaw(url, callback) {
 | 
			
		||||
        const xhttp = new XMLHttpRequest();
 | 
			
		||||
        xhttp.onreadystatechange = function () {
 | 
			
		||||
@@ -185,7 +352,6 @@
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        list.onchange();
 | 
			
		||||
            document.getElementById("container").style.display = "block";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function request() {
 | 
			
		||||
@@ -244,23 +410,36 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function enableCrashLog() {
 | 
			
		||||
            document.getElementById("crashlogbtn").remove();
 | 
			
		||||
            document.getElementById("crashlogs").style.display = "block";
 | 
			
		||||
        const logArea = document.getElementById('crashlogs');
 | 
			
		||||
        const btn = document.getElementById('crashlogbtn');
 | 
			
		||||
        const isHidden = logArea.style.display === 'none';
 | 
			
		||||
        logArea.style.display = isHidden ? 'block' : 'none';
 | 
			
		||||
        btn.textContent = isHidden ? 'stop' : 'start';
 | 
			
		||||
 | 
			
		||||
        clearInterval(window.crash_interval);
 | 
			
		||||
        if (isHidden) {
 | 
			
		||||
            updateCrashLog();
 | 
			
		||||
            setInterval(updateCrashLog, 1000);
 | 
			
		||||
            window.crash_interval = setInterval(updateCrashLog, 1000);
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function enableLog() {
 | 
			
		||||
            document.getElementById("logbtn").remove();
 | 
			
		||||
            document.getElementById("logs").style.display = "block";
 | 
			
		||||
        const logArea = document.getElementById('logs');
 | 
			
		||||
        const btn = document.getElementById('logbtn');
 | 
			
		||||
        const isHidden = logArea.style.display === 'none';
 | 
			
		||||
        logArea.style.display = isHidden ? 'block' : 'none';
 | 
			
		||||
        btn.textContent = isHidden ? 'stop' : 'start';
 | 
			
		||||
 | 
			
		||||
        clearInterval(window.log_interval);
 | 
			
		||||
        if (isHidden) {
 | 
			
		||||
            updateLog();
 | 
			
		||||
            setInterval(updateLog, 1000);
 | 
			
		||||
            window.log_interval = setInterval(updateLog, 1000);
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getJSON("/apps/list", populateForm);
 | 
			
		||||
    </script>
 | 
			
		||||
</div>
 | 
			
		||||
</script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user