Added features

Language selection
Dimming feature
Improvements to the code
This commit is contained in:
mfactory-osaka
2025-07-07 13:22:06 +09:00
parent 91d9b222a8
commit 2c3092bd0d
5 changed files with 777 additions and 236 deletions

View File

@@ -14,5 +14,6 @@
"ntpServer2": "time.nist.gov",
"twelveHourToggle": false,
"showDayOfWeek": true,
"showHumidity": false
"showHumidity": false,
"language": "en"
}

View File

@@ -72,6 +72,7 @@
margin-top: 0.75rem;
}
input[type="text"],
input[type="time"],
input[type="password"],
input[type="number"], select {
width: 100%; padding: 0.75rem;
@@ -81,6 +82,12 @@
color: #ffffff;
font-size: 1rem; appearance: none;
}
input[type="time"]:disabled ,
input[type="number"]:disabled {
color: rgba(255, 255, 255, 0.250);
}
input[type="submit"] {
background-color: #007aff; color: white;
padding: 0.9rem; font-size: 1rem;
@@ -91,6 +98,10 @@
background-color: #005ecb;
}
input[type="time"]::-webkit-calendar-picker-indicator{
filter: invert(100%);
}
input:-webkit-autofill,
input:-webkit-autofill:focus,
input:-webkit-autofill:hover {
@@ -389,6 +400,38 @@ textarea::placeholder {
<option value="Etc/UTC">Etc/UTC</option>
</select>
<label for="language">Day of Week Language</label>
<select id="language" name="language" onchange="setLanguage(this.value)">
<option value="" disabled selected>Select language</option>
<option value="af">Afrikaans</option>
<option value="hr">Croatian</option>
<option value="cs">Czech</option>
<option value="da">Danish</option>
<option value="nl">Dutch</option>
<option value="en">English</option>
<option value="eo">Esperanto</option>
<option value="et">Estonian</option>
<option value="fi">Finnish</option>
<option value="fr">French</option>
<option value="de">German</option>
<option value="hu">Hungarian</option>
<option value="it">Italian</option>
<option value="ja">Japanese</option>
<option value="lv">Latvian</option>
<option value="lt">Lithuanian</option>
<option value="no">Norwegian</option>
<option value="pl">Polish</option>
<option value="pt">Portuguese</option>
<option value="ro">Romanian</option>
<option value="sk">Slovak</option>
<option value="sl">Slovenian</option>
<option value="es">Spanish</option>
<option value="sv">Swedish</option>
<option value="sw">Swahili</option>
<option value="tr">Turkish</option>
</select>
<div class="form-row two-col">
<div>
<label for="clockDuration">Clock Duration</label>
@@ -422,7 +465,7 @@ textarea::placeholder {
<label style="display: flex; align-items: center; margin-top: 1.75rem; justify-content: space-between;">
<span style="margin-right: 0.5em;">Show Day of Week:</span>
<span class="toggle-switch">
<input type="checkbox" name="showDayOfWeek" id="showDayOfWeek" checked>
<input type="checkbox" id="showDayOfWeek" name="showDayOfWeek" onchange="setShowDayOfWeek(this.checked)">
<span class="toggle-slider"></span>
</span>
</label>
@@ -431,7 +474,7 @@ textarea::placeholder {
<label style="display: flex; align-items: center; margin-top: 1.75rem; justify-content: space-between;">
<span style="margin-right: 0.5em;">Display 12-hour Clock:</span>
<span class="toggle-switch">
<input type="checkbox" name="twelveHourToggle" id="twelveHourToggle">
<input type="checkbox" id="twelveHourToggle" name="twelveHourToggle" onchange="setTwelveHour(this.checked)">
<span class="toggle-slider"></span>
</span>
</label>
@@ -440,7 +483,7 @@ textarea::placeholder {
<label style="display: flex; align-items: center; margin-top: 1.75rem; justify-content: space-between;">
<span style="margin-right: 0.5em;">Show Humidity:</span>
<span class="toggle-switch">
<input type="checkbox" name="showHumidity" id="showHumidity">
<input type="checkbox" id="showHumidity" name="showHumidity" onchange="setShowHumidity(this.checked)">
<span class="toggle-slider"></span>
</span>
</label>
@@ -449,17 +492,45 @@ textarea::placeholder {
<label style="display: flex; align-items: center; margin-top: 1.75rem; justify-content: space-between;">
<span style="margin-right: 0.5em;">Flip Display (180°):</span>
<span class="toggle-switch">
<input type="checkbox" name="flipDisplay" id="flipDisplay">
<input type="checkbox" id="flipDisplay" name="flipDisplay" onchange="setFlipDisplay(this.checked)">
<span class="toggle-slider"></span>
</span>
</label>
<!-- Brightness Slider with Value -->
<label style="margin-top: 1.75rem;">Brightness: <span id="brightnessValue">10</span></label>
<input style="width: 100%;" type="range" min="0" max="15" name="brightness" id="brightnessSlider" value="10" oninput="brightnessValue.textContent = brightnessSlider.value">
<input style="width: 100%;" type="range" min="0" max="15" name="brightness" id="brightnessSlider" value="10"
oninput="brightnessValue.textContent = brightnessSlider.value; setBrightnessLive(this.value);">
<br><br>
<!-- Dimming Controls -->
<label style="display: flex; align-items: center; justify-content: space-between;">
<span style="margin-right: 0.5em;">Enable Dimming:</span>
<span class="toggle-switch">
<input type="checkbox" id="dimmingEnabled" name="dimmingEnabled">
<span class="toggle-slider"></span>
</span>
</label>
<div class="form-row two-col">
<div>
<label for="dimStartTime">Dimming Start Time:</label>
<input type="time" id="dimStartTime" value="18:00">
</div>
<div>
<label for="dimEndTime">Dimming End Time:</label>
<input type="time" id="dimEndTime" value="08:00">
</div>
</div>
<div style="margin-top: 1rem;">
<label for="dimBrightness">Dimming Brightness (0-15):</label>
<input type="number" id="dimBrightness" min="0" max="15" value="2" style="width:80px;">
</div>
</div>
</div>
<input type="submit" class="primary-button" value="Save Settings">
</form>
@@ -511,6 +582,7 @@ window.onload = function () {
document.getElementById('weatherUnits').value = data.weatherUnits || 'metric';
document.getElementById('clockDuration').value = (data.clockDuration || 10000) / 1000;
document.getElementById('weatherDuration').value = (data.weatherDuration || 5000) / 1000;
document.getElementById('language').value = data.language || '';
// Advanced:
document.getElementById('brightnessSlider').value = typeof data.brightness !== "undefined" ? data.brightness : 10;
document.getElementById('brightnessValue').textContent = document.getElementById('brightnessSlider').value;
@@ -520,6 +592,33 @@ window.onload = function () {
document.getElementById('twelveHourToggle').checked = !!data.twelveHourToggle;
document.getElementById('showDayOfWeek').checked = !!data.showDayOfWeek;
document.getElementById('showHumidity').checked = !!data.showHumidity;
// Dimming controls
const dimmingEnabledEl = document.getElementById('dimmingEnabled');
const isDimming = (data.dimmingEnabled === true || data.dimmingEnabled === "true" || data.dimmingEnabled === 1);
dimmingEnabledEl.checked = isDimming;
// Defer field enabling until checkbox state is rendered
setTimeout(() => {
setDimmingFieldsEnabled(dimmingEnabledEl.checked);
}, 0);
dimmingEnabledEl.addEventListener('change', function () {
setDimmingFieldsEnabled(this.checked);
});
document.getElementById('dimStartTime').value =
(data.dimStartHour !== undefined ? String(data.dimStartHour).padStart(2, '0') : "18") + ":" +
(data.dimStartMinute !== undefined ? String(data.dimStartMinute).padStart(2, '0') : "00");
document.getElementById('dimEndTime').value =
(data.dimEndHour !== undefined ? String(data.dimEndHour).padStart(2, '0') : "08") + ":" +
(data.dimEndMinute !== undefined ? String(data.dimEndMinute).padStart(2, '0') : "00");
document.getElementById('dimBrightness').value = (data.dimBrightness !== undefined ? data.dimBrightness : 2);
setDimmingFieldsEnabled(!!data.dimmingEnabled);
// Auto-detect browser's timezone if not set in config
if (!data.timeZone) {
try {
@@ -581,6 +680,24 @@ async function submitConfig(event) {
formData.set('showDayOfWeek', document.getElementById('showDayOfWeek').checked ? 'on' : '');
formData.set('showHumidity', document.getElementById('showHumidity').checked ? 'on' : '');
//dimming
formData.set('dimmingEnabled', document.getElementById('dimmingEnabled').checked ? 'true' : 'false');
const dimStart = document.getElementById('dimStartTime').value; // "18:45"
const dimEnd = document.getElementById('dimEndTime').value; // "08:30"
// Parse hour and minute
if (dimStart) {
const [startHour, startMin] = dimStart.split(":").map(x => parseInt(x, 10));
formData.set('dimStartHour', startHour);
formData.set('dimStartMinute', startMin);
}
if (dimEnd) {
const [endHour, endMin] = dimEnd.split(":").map(x => parseInt(x, 10));
formData.set('dimEndHour', endHour);
formData.set('dimEndMinute', endMin);
}
formData.set('dimBrightness', document.getElementById('dimBrightness').value);
const params = new URLSearchParams();
for (const pair of formData.entries()) {
params.append(pair[0], pair[1]);
@@ -806,6 +923,72 @@ const toggle = document.querySelector('.collapsible-toggle');
content.style.height = 'auto';
}
let brightnessDebounceTimeout = null;
function setBrightnessLive(val) {
// Cancel the previous timeout if it exists
if (brightnessDebounceTimeout) {
clearTimeout(brightnessDebounceTimeout);
}
// Set a new timeout
brightnessDebounceTimeout = setTimeout(() => {
fetch('/set_brightness', {
method: 'POST',
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: "value=" + encodeURIComponent(val)
})
.then(res => res.json())
.catch(e => {}); // Optionally handle errors
}, 150); // 150ms debounce, adjust as needed
}
function setFlipDisplay(val) {
fetch('/set_flip', {
method: 'POST',
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: "value=" + (val ? 1 : 0)
});
}
function setTwelveHour(val) {
fetch('/set_twelvehour', {
method: 'POST',
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: "value=" + (val ? 1 : 0)
});
}
function setShowDayOfWeek(val) {
fetch('/set_dayofweek', {
method: 'POST',
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: "value=" + (val ? 1 : 0)
});
}
function setShowHumidity(val) {
fetch('/set_humidity', {
method: 'POST',
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: "value=" + (val ? 1 : 0)
});
}
function setLanguage(val) {
fetch('/set_language', {
method: 'POST',
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: "value=" + encodeURIComponent(val)
});
}
// --- Dimming Controls Logic ---
function setDimmingFieldsEnabled(enabled) {
document.getElementById('dimStartTime').disabled = !enabled;
document.getElementById('dimEndTime').disabled = !enabled;
document.getElementById('dimBrightness').disabled = !enabled;
}
</script>
</body>
</html>