Refactored

master
David Volovskiy 2025-04-23 20:29:03 -04:00
parent fd8785fe5b
commit 3022a9acf6
1 changed files with 85 additions and 71 deletions

View File

@ -4,14 +4,23 @@ const storage = require('Storage');
const widget_utils = require('widget_utils');
const global_settings = storage.readJSON("setting.json", true) || {};
const LOCATION_FILE = "mylocation.json";
const h = g.getHeight();
const w = g.getWidth();
let location;
let cachedSunTimes = null;
let lastSunCalcDate = null;
var prevVals = {};
var valsArrs = {};
let drawTimeout;
const h = g.getHeight();
const w = g.getWidth();
const fontSize = 13;
const lineHeight = 16;
const buttonHeight = 12;
const buttonX = 78;
const buttonY = 3;
const headerHeight = 16;
const usableHeight = h - headerHeight;
const maxLines = Math.floor(usableHeight / lineHeight);
var settings = {
hr_12: global_settings["12hour"] !== undefined ? global_settings["12hour"] : false,
dark_mode: g.theme.dark
@ -26,22 +35,6 @@ let clrs = {
brackets: g.theme.fg,
};
let jsonText;
let lines = [];
let fontSize = 13;
const lineHeight = 16;
const buttonHeight = 12;
const buttonX = 78;
const buttonY = 3;
let keysDrawn = false;
const headerHeight = 16;
const usableHeight = h - headerHeight;
const maxLines = Math.floor(usableHeight / lineHeight);
var numWidth = 0;
// requires the myLocation app
let loadLocation = function() {
location = require("Storage").readJSON(LOCATION_FILE, 1) || {};
@ -110,7 +103,17 @@ let getVal = function(now, loc) {
return vals;
};
let loadJson = function() {
let getKeyValRegex = function(line) {
return line.trim().match(/^"([^"]+)":\s*(.+)$/);
};
let getIndentRegex = function(line) {
const indentMatch = line.match(/^(\s*)/);
return indentMatch ? indentMatch[1] : "";
};
let getJsonLine = function() {
const now = new Date();
const vals = getVal(now, location);
//vals.steps = null; // For testing; uncomment to see the steps not appear
@ -135,9 +138,9 @@ let loadJson = function() {
set: vals.set,
};
}
jsonText = JSON.stringify(raw, null, 2);
lines = jsonText.split("\n");
};
let jsonText = JSON.stringify(raw, null, 2);
return jsonText.split("\n");
};
let draw = function() {
g.clear();
@ -153,91 +156,101 @@ let draw = function() {
g.setFont("Vector", buttonHeight);
g.drawString("X", buttonX, buttonY);
g.setFont("Vector", fontSize);
var lines = getJsonLine();
var numWidth = 0;
// Draw numbers first to find out their max width
for (let i = 0; i < maxLines; i++) {
const y = headerHeight + i * lineHeight;
const lineNumberStr = (i + 1).toString().padStart(2, " ") + " ";
g.drawString(lineNumberStr, 0, y);
numWidth = Math.max(numWidth, g.stringWidth(lineNumberStr));
}
redrawValues();
};
let redraw = function() {
g.setFont("Vector", fontSize);
for (let i = 0; i < maxLines; i++) {
const lineIndex = i;
const line = lines[lineIndex];
if (!line) continue;
const y = headerHeight + i * lineHeight;
const line = lines[i];
if (!line) continue;
const indentMatch = line.match(/^(\s*)/);
const indent = indentMatch ? indentMatch[1] : "";
const kvMatch = line.trim().match(/^"([^"]+)":\s*(.+)$/);
let kvMatch = getKeyValRegex(line);
if (kvMatch) {
const key = kvMatch[1];
let value = kvMatch[2];
let valPrev = (prevVals[key] && prevVals[key].text) || null;
if (valPrev === value) continue;
if (!keysDrawn) {
prevVals[key] = {};
// Key
g.setColor(clrs.keys);
const keyText = indent + `"${key}"`;
g.drawString(keyText, numWidth, y);
const keyWidth = g.stringWidth(keyText);
let valueX = numWidth + keyWidth;
g.setColor(clrs.brackets);
const colonText = ": ";
g.drawString(colonText, valueX, y);
valueX += g.stringWidth(colonText);
prevVals[key].x = valueX;
prevVals[key].y = y;
}
prevVals[key].text = value;
let pos = prevVals[key];
// Key
g.setColor(clrs.keys);
const indent = getIndentRegex(line);
const keyText = indent + `"${key}"`;
g.drawString(keyText, numWidth, y);
const keyWidth = g.stringWidth(keyText);
let x = numWidth + keyWidth;
// Clear prev values
g.setColor(clrs.bg);
g.fillRect(pos.x, pos.y, w, pos.y + lineHeight);
g.setColor(clrs.brackets);
const colonText = ": ";
g.drawString(colonText, x, y);
x += g.stringWidth(colonText);
// Value color
const endComma = value.endsWith(',');
valsArrs[key] = {text:value, x:x, y:y, endComma:endComma};
if (endComma) value = value.slice(0, -1);
if (value.startsWith('"')) {
g.setColor(clrs.strings);
valsArrs[key].color = clrs.strings;
} else if (value.startsWith('{') || value.startsWith('}')) {
g.setColor(clrs.brackets);
valsArrs[key].color = clrs.brackets;
} else {
g.setColor(clrs.ints);
valsArrs[key].color = clrs.ints;
}
g.drawString(value, pos.x, pos.y);
g.setColor(valsArrs[key].color);
g.drawString(value, x, y);
if (endComma){
g.setColor(clrs.brackets);
g.drawString(',', pos.x + g.stringWidth(value), pos.y);
g.drawString(',', x + g.stringWidth(value), y);
}
}
else if (!keysDrawn) {
else {
g.setColor(clrs.brackets);
g.drawString(line, numWidth, y);
}
}
};
// Redraws only values that changed
let redraw = function() {
g.setFontAlign(-1, -1);
g.setFont("Vector", fontSize);
var lines = getJsonLine();
for (let i = 0; i < lines.length; i++) {
let kvMatch = getKeyValRegex(lines[i]);
if (!kvMatch) continue;
const key = kvMatch[1];
let value = kvMatch[2];
if (!(key in valsArrs)) continue;
let valsArr = valsArrs[key];
if (value === valsArr.text) continue; // No need to update
valsArrs[key].text = value;
// Clear prev values
g.setColor(clrs.bg);
g.fillRect(valsArr.x, valsArr.y, w, valsArr.y + lineHeight);
g.setColor(valsArr.color);
g.drawString(value, valsArr.x, valsArr.y);
if (valsArr.endComma){
g.setColor(clrs.brackets);
g.drawString(',', valsArr.Banglex + g.stringWidth(value), valsArr.y);
}
}
}
keysDrawn = true;
};
let redrawValues = function() {
loadJson();
redraw();
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() {
drawTimeout = undefined;
redrawValues();
}, 60000 - (Date.now() % 60000));
}, 600 - (Date.now() % 600));
};
Bangle.on('touch', (zone, e) => {
@ -258,4 +271,5 @@ loadLocation();
Bangle.loadWidgets();
widget_utils.hide();
draw();
redrawValues(); // To set the timeout
}