implemented minimizable configuration sections
authorCalin Crisan <ccrisan@gmail.com>
Sat, 28 Feb 2015 15:56:03 +0000 (17:56 +0200)
committerCalin Crisan <ccrisan@gmail.com>
Sat, 28 Feb 2015 16:42:04 +0000 (18:42 +0200)
src/wifictl.py
static/css/main.css
static/css/ui.css
static/js/main.js
templates/main.html

index 0890b432f422265e3bb6cf28c586c64930c060ca..e2e066effaf9516983994b368099b725c7d65401 100644 (file)
@@ -93,8 +93,9 @@ def _set_wifi_settings(s):
     s.setdefault('wifiNetworkName', '')
     s.setdefault('wifiNetworkKey', '')
     
-    logging.debug('writing wifi settings to %s' % WPA_SUPPLICANT_CONF)
-    
+    logging.debug('writing wifi settings to %s: enabled=%s, psk="%s"' % (
+            WPA_SUPPLICANT_CONF, s['wifiEnabled'], s['wifiNetworkName']))
+
     enabled = s['wifiEnabled']
     ssid = s['wifiNetworkName']
     psk = s['wifiNetworkKey']
index 9b3d87d9f11cdabb57fe59d5b2ab9463b0a0997b..fd938d893424cb17db278efe0bb0694a777651f8 100644 (file)
@@ -283,6 +283,9 @@ div.settings-section-title {
     padding: 5px 0.5em 5px 5px;
 }
 
+a.settings-section-title {
+}
+
 table.settings {
     width: 100%;
     padding: 0.5em 0.5em 1em 0.5em;
@@ -439,6 +442,58 @@ tr.hidden {
     display: none !important;
 }
 
+span.help-mark {
+    display: inline-block;
+    visibility: hidden;
+    text-align: center;
+    background-color: #414141;
+    color: #3498db;
+    font-size: 0.75em;
+    font-family: monospace;
+    width: 1.2em;
+    height: 1.2em;
+    border-radius: 100em;
+    cursor: pointer;
+    vertical-align: middle;
+    position: relative;
+    top: -0.1em;
+}
+
+div.settings-section-title > span.help-mark {
+    background-color: #515151;
+}
+
+div.settings-section-title:HOVER > span.help-mark,
+tr:HOVER span.help-mark {
+    visibility: visible;
+}
+
+span.minimize {
+    display: inline-block;
+    background-image: url(../img/combo-box-arrow.svg);
+    background-size: cover;
+    width: 0.8em;
+    height: 0.8em;
+    cursor: pointer;
+    vertical-align: middle;
+    position: relative;
+    top: -0.1em;
+    transition: transform 0.1s linear;
+    -webkit-transform: rotate(90deg);
+    -moz-transform: rotate(90deg);
+    -ms-transform: rotate(90deg);
+    -o-transform: rotate(90deg);
+    transform: rotate(90deg);
+}
+
+span.minimize.open {
+    -webkit-transform: rotate(0deg);
+    -moz-transform: rotate(0deg);
+    -ms-transform: rotate(0deg);
+    -o-transform: rotate(0deg);
+    transform: rotate(0deg);
+}
+
 
     /* dialogs */
     
index bb155a8d91018826ddcacea78a88cd3ee532d09e..1da69b9d544da543e56dffaae569248c087db574 100644 (file)
@@ -18,13 +18,13 @@ input[type=checkbox].styled {
 }
 
 a {
-    color: #317CAD;
+    color: #3498db;
     text-decoration: inherit;
     transition: color 0.1s ease;
+    cursor: pointer;
 }
 
 a:HOVER {
-    color: #3498db;
 }
 
 a:ACTIVE {
@@ -433,35 +433,6 @@ span.popup-message.error {
 }
 
 
-    /* misc */
-
-span.help-mark {
-    display: inline-block;
-    visibility: hidden;
-    text-align: center;
-    background-color: #414141;
-    color: #3498db;
-    font-size: 0.75em;
-    font-family: monospace;
-    width: 1.2em;
-    height: 1.2em;
-    border-radius: 100em;
-    cursor: pointer;
-    vertical-align: middle;
-    position: relative;
-    top: -0.1em;
-}
-
-div.settings-section-title > span.help-mark {
-    background-color: #515151;
-}
-
-div.settings-section-title:HOVER > span.help-mark,
-tr:HOVER span.help-mark {
-    visibility: visible;
-}
-
-
     /* media queries */
 
 @media all and (max-width: 400px) {
index 83ec100d7b5fad985c2e12572a978d3970ec403f..7f99441e1675a134cd0ed5689ec3708958665708 100644 (file)
@@ -544,6 +544,14 @@ function initUI() {
     /* input value processors */
     makeStrippedInput($('tr[strip=true] input[type=text]'));
     makeStrippedInput($('tr[strip=true] input[type=password]'));
+    
+    function unMinimizeSection() {
+        var $switch = $(this);
+        var $minimizeSpan = $switch.parent().find('span.minimize');
+        if ($switch.is(':checked') && !$minimizeSpan.hasClass('open')) {
+            $minimizeSpan.addClass('open');
+        }
+    }
 
     /* ui elements that enable/disable other ui elements */
     $('#motionEyeSwitch').change(updateConfigUi);
@@ -554,19 +562,19 @@ function initUI() {
     $('#rightTextSelect').change(updateConfigUi);
     $('#captureModeSelect').change(updateConfigUi);
     $('#autoNoiseDetectSwitch').change(updateConfigUi);
-    $('#videoDeviceSwitch').change(updateConfigUi);
-    $('#textOverlaySwitch').change(updateConfigUi);
-    $('#videoStreamingSwitch').change(updateConfigUi);
+    $('#videoDeviceSwitch').change(unMinimizeSection).change(updateConfigUi);
+    $('#textOverlaySwitch').change(unMinimizeSection).change(updateConfigUi);
+    $('#videoStreamingSwitch').change(unMinimizeSection).change(updateConfigUi);
     $('#streamingServerResizeSwitch').change(updateConfigUi);
-    $('#stillImagesSwitch').change(updateConfigUi);
+    $('#stillImagesSwitch').change(unMinimizeSection).change(updateConfigUi);
     $('#preservePicturesSelect').change(updateConfigUi);
-    $('#motionDetectionSwitch').change(updateConfigUi);
-    $('#motionMoviesSwitch').change(updateConfigUi);
+    $('#motionDetectionSwitch').change(unMinimizeSection).change(updateConfigUi);
+    $('#motionMoviesSwitch').change(unMinimizeSection).change(updateConfigUi);
     $('#preserveMoviesSelect').change(updateConfigUi);
     $('#emailNotificationsSwitch').change(updateConfigUi);
     $('#webHookNotificationsSwitch').change(updateConfigUi);
     $('#commandNotificationsSwitch').change(updateConfigUi);
-    $('#workingScheduleSwitch').change(updateConfigUi);
+    $('#workingScheduleSwitch').change(unMinimizeSection).change(updateConfigUi);
     
     $('#mondayEnabledSwitch').change(updateConfigUi);
     $('#tuesdayEnabledSwitch').change(updateConfigUi);
@@ -575,6 +583,16 @@ function initUI() {
     $('#fridayEnabledSwitch').change(updateConfigUi);
     $('#saturdayEnabledSwitch').change(updateConfigUi);
     $('#sundayEnabledSwitch').change(updateConfigUi);
+    
+    /* minimizable sections */
+    $('span.minimize').click(function () {
+        $(this).toggleClass('open');
+        updateConfigUi();
+    });
+
+    $('a.settings-section-title').click(function () {
+        $(this).parent().find('span.minimize').click();
+    });
 
     /* additional configs */
     var seenDependNames = {};
@@ -717,7 +735,15 @@ function updateConfigUi() {
             $(this).parents('tr:eq(0)').each(markHide);
         }
     });
-    
+
+    /* minimizable sections */
+    $('span.minimize').each(function () {
+        var $this = $(this);
+        if (!$this.hasClass('open')) {
+            $this.parent().next('table.settings').find('tr').each(markHide);
+        }
+    });
+
     /* general enable switch */
     var motionEyeEnabled = $('#motionEyeSwitch').get(0).checked;
     if (!motionEyeEnabled) {
@@ -1002,6 +1028,9 @@ function mainUi2Dict() {
         if (id.endsWith('Entry')) {
             name = id.substring(0, id.length - 5);
             value = control.val();
+            if (control.hasClass('number')) {
+                value = Number(value);
+            }
         }
         else if (id.endsWith('Select')) {
             name = id.substring(0, id.length - 6);
@@ -1009,7 +1038,7 @@ function mainUi2Dict() {
         }
         else if (id.endsWith('Slider')) {
             name = id.substring(0, id.length - 6);
-            value = control.val();
+            value = Number(control.val());
         }
         else if (id.endsWith('Switch')) {
             name = id.substring(0, id.length - 6);
@@ -1212,6 +1241,9 @@ function cameraUi2Dict() {
         if (id.endsWith('Entry')) {
             name = id.substring(0, id.length - 5);
             value = control.val();
+            if (control.hasClass('number')) {
+                value = Number(value);
+            }
         }
         else if (id.endsWith('Select')) {
             name = id.substring(0, id.length - 6);
@@ -1219,7 +1251,7 @@ function cameraUi2Dict() {
         }
         else if (id.endsWith('Slider')) {
             name = id.substring(0, id.length - 6);
-            value = control.val();
+            value = Number(control.val());
         }
         else if (id.endsWith('Switch')) {
             name = id.substring(0, id.length - 6);
index 2962911de9fd59c468add7169967ccbb7e0bcc8d..a18e4a4eefc28880538681b7ca144ffd2dbbadd6 100644 (file)
     <div class="page">
         <div class="settings closed">
             <div class="settings-container">
-                <div class="settings-section-title"><input type="checkbox" class="styled section general main-config" id="motionEyeSwitch">General Settings
-                        <span class="help-mark" title="general settings, not related to any camera">?</span></div>
+                <div class="settings-section-title">
+                    <input type="checkbox" class="styled section general main-config" id="motionEyeSwitch">
+                    <span class="help-mark" title="general settings, not related to any camera">?</span>
+                    <a class="settings-section-title">General Settings</a>
+                    <span class="minimize open"></span>
+                </div>
                 <table class="settings">
                     <tr class="settings-item">
                         <td class="settings-item-label"><span class="settings-item-label">Show Advanced Settings</span></td>
                 
                 {% for section in main_sections.values() %}
                 {% if section.get('label') and section.get('configs') %}
-                <div class="settings-section-title {% if section['advanced'] %}advanced-setting{% endif %}">{% if section.get('onoff') %}
-                        <input type="checkbox" class="styled section additional-section {{section['name']}} main-config" id="{{section['name']}}Switch">{% endif %}{{section['label']}}
-                        {% if section.get('description') %}<span class="help-mark" title="{{section['description']}}">?</span>{% endif %}</div>
-                <table class="settings">
+                <div class="settings-section-title {% if section['advanced'] %}advanced-setting{% endif %}">
+                    {% if section.get('onoff') %}<input type="checkbox" class="styled section additional-section {{section['name']}} main-config" id="{{section['name']}}Switch">{% endif %}
+                    {% if section.get('description') %}<span class="help-mark" title="{{section['description']}}">?</span>{% endif %}
+                    <a class="settings-section-title">{{section['label']}}</a>
+                    <span class="minimize {% if section.get('open') %}open{% endif %}"></span>
+                </div>
+                <table class="settings {% if section.get('advanced') %}advanced-setting{% endif %}">
                     {% for config in section['configs'] %}
                         {{config_item(config)}}
                     {% endfor %}
                 {% endif %}                    
                 {% endfor %}
 
-                <div class="settings-section-title"><input type="checkbox" class="styled section device camera-config" id="videoDeviceSwitch">Video Device
-                        <span class="help-mark" title="enable this if you want to use this camera device">?</span></div>
+                <div class="settings-section-title">
+                    <input type="checkbox" class="styled section device camera-config" id="videoDeviceSwitch">
+                    <span class="help-mark" title="enable this if you want to use this camera device">?</span>
+                    <a class="settings-section-title">Video Device</a>
+                    <span class="minimize open"></span>
+                </div>
                 <table class="settings">
                     <tr class="settings-item" required="true" strip="true">
                         <td class="settings-item-label"><span class="settings-item-label">Camera Name</span></td>
                     {% endfor %}
                 </table>
                 
-                <div class="settings-section-title advanced-setting">File Storage
-                        <span class="help-mark" title="choose where and how your media files are saved">?</span></div>
+                <div class="settings-section-title advanced-setting">
+                    <span class="help-mark" title="choose where and how your media files are saved">?</span>
+                    <a class="settings-section-title">File Storage</a>
+                    <span class="minimize"></span>
+                </div>
                 <table class="settings advanced-setting">
                     <tr class="settings-item advanced-setting">
                         <td class="settings-item-label"><span class="settings-item-label">Storage Device</span></td>
                     {% endfor %}
                 </table>
                 
-                <div class="settings-section-title advanced-setting"><input type="checkbox" class="styled section text-overlay camera-config" id="textOverlaySwitch">Text Overlay
-                        <span class="help-mark" title="choose what information is displayed on the captured frames">?</span></div>
+                <div class="settings-section-title advanced-setting">
+                    <input type="checkbox" class="styled section text-overlay camera-config" id="textOverlaySwitch">
+                    <span class="help-mark" title="choose what information is displayed on the captured frames">?</span>
+                    <a class="settings-section-title">Text Overlay</a>
+                    <span class="minimize"></span>
+                </div>
                 <table class="settings advanced-setting">
                     <tr class="settings-item advanced-setting">
                         <td class="settings-item-label"><span class="settings-item-label">Left Text</span></td>
                     {% endfor %}
                 </table>
 
-                <div class="settings-section-title"><input type="checkbox" class="styled section streaming camera-config" id="videoStreamingSwitch">Video Streaming
-                        <span class="help-mark" title="enable this if you want video streaming for this camera">?</span></div>
+                <div class="settings-section-title">
+                    <input type="checkbox" class="styled section streaming camera-config" id="videoStreamingSwitch">
+                    <span class="help-mark" title="enable this if you want video streaming for this camera">?</span>
+                    <a class="settings-section-title">Video Streaming</a>
+                    <span class="minimize"></span>
+                </div>
                 <table class="settings">
                     <tr class="settings-item advanced-setting local-streaming" min="1" max="30" snap="0" ticks="1|5|10|15|20|25|30" decimals="0">
                         <td class="settings-item-label"><span class="settings-item-label">Streaming Frame Rate</span></td>
                     {% endfor %}
                 </table>
                 
-                <div class="settings-section-title"><input type="checkbox" class="styled section still-images camera-config" id="stillImagesSwitch">Still Images
-                        <span class="help-mark" title="enable this if you want to capture still images (pictures)">?</span></div>
+                <div class="settings-section-title">
+                    <input type="checkbox" class="styled section still-images camera-config" id="stillImagesSwitch">
+                    <span class="help-mark" title="enable this if you want to capture still images (pictures)">?</span>
+                    <a class="settings-section-title">Still Images</a>
+                    <span class="minimize"></span>
+                </div>
                 <table class="settings">
                     <tr class="settings-item advanced-setting" required="true" strip="true">
                         <td class="settings-item-label"><span class="settings-item-label">Image File Name</span></td>
                     {% endfor %}
                 </table>
                 
-                <div class="settings-section-title advanced-setting"><input type="checkbox" class="styled section motion-detection camera-config" id="motionDetectionSwitch">Motion Detection
-                        <span class="help-mark" title="enable this to use and configure the motion detection mechanism">?</span></div>
+                <div class="settings-section-title advanced-setting">
+                    <input type="checkbox" class="styled section motion-detection camera-config" id="motionDetectionSwitch">
+                    <span class="help-mark" title="enable this to use and configure the motion detection mechanism">?</span>
+                    <a class="settings-section-title">Motion Detection</a>
+                    <span class="minimize"></span>
+                </div>
                 <table class="settings advanced-setting">
                     <tr class="settings-item advanced-setting">
                         <td class="settings-item-label"><span class="settings-item-label">Show Frame Changes</span></td>
                     {% endfor %}
                 </table>
                 
-                <div class="settings-section-title"><input type="checkbox" class="styled section motion-movies camera-config" id="motionMoviesSwitch">Motion Movies
-                        <span class="help-mark" title="enable this if you want to record motion movies">?</span></div>
+                <div class="settings-section-title">
+                    <input type="checkbox" class="styled section motion-movies camera-config" id="motionMoviesSwitch">
+                    <span class="help-mark" title="enable this if you want to record motion movies">?</span>
+                    <a class="settings-section-title">Motion Movies</a>
+                    <span class="minimize"></span>
+                </div>
                 <table class="settings">
                     <tr class="settings-item advanced-setting" required="true" strip="true">
                         <td class="settings-item-label"><span class="settings-item-label">Movie File Name</span></td>
                         {{config_item(config)}}
                     {% endfor %}
                 </table>
-                <div class="settings-section-title advanced-setting">Motion Notifications
-                        <span class="help-mark" title="enable this if you want to be notified when motion is detected">?</span></div>
+                <div class="settings-section-title advanced-setting">
+                    <span class="help-mark" title="enable this if you want to be notified when motion is detected">?</span>
+                    <a class="settings-section-title">Motion Notifications</a>
+                    <span class="minimize"></span>
+                </div>
                 <table class="settings">
                     <tr class="settings-item advanced-setting">
                         <td class="settings-item-label"><span class="settings-item-label">Email Notifications</span></td>
                     {% endfor %}
                 </table>
 
-                <div class="settings-section-title"><input type="checkbox" class="styled section working-schedule camera-config" id="workingScheduleSwitch">Working Schedule
-                        <span class="help-mark" title="enable this if you want to define a weekly working schedule for motion detection">?</span></div>
+                <div class="settings-section-title">
+                    <input type="checkbox" class="styled section working-schedule camera-config" id="workingScheduleSwitch">
+                    <span class="help-mark" title="enable this if you want to define a weekly working schedule for motion detection">?</span>
+                    <a class="settings-section-title">Working Schedule</a>
+                    <span class="minimize"></span>
+                </div>
                 <table class="settings">
                     <tr class="settings-item">
                         <td class="settings-item-label"><span class="settings-item-label">Monday</span></td>
 
                 {% for section in camera_sections.values() %}
                 {% if section.get('label') and section.get('configs') %}
-                <div class="settings-section-title {% if section['advanced'] %}advanced-setting{% endif %}">{% if section.get('onoff') %}
-                        <input type="checkbox" class="styled section additional-section {{section['name']}} camera-config" id="{{section['name']}}Switch">{% endif %}{{section['label']}}
-                        {% if section.get('description') %}<span class="help-mark" title="{{section['description']}}">?</span>{% endif %}</div>
+                <div class="settings-section-title {% if section['advanced'] %}advanced-setting{% endif %}">
+                    {% if section.get('onoff') %}<input type="checkbox" class="styled section additional-section {{section['name']}} camera-config" id="{{section['name']}}Switch">{% endif %}
+                    {% if section.get('description') %}<span class="help-mark" title="{{section['description']}}">?</span>{% endif %}
+                    <a class="settings-section-title">{{section['label']}}</a>
+                    <span class="minimize {% if section.get('open') %}open{% endif %}"></span>
+                </div>
                 <table class="settings">
                     {% for config in section['configs'] %}
                         {{config_item(config)}}