From feceadf432cd5677bd842c807fffd3b03f62f7f7 Mon Sep 17 00:00:00 2001 From: you Date: Mon, 23 Mar 2026 01:29:56 +0000 Subject: [PATCH] Customization: packet type colors (ADVERT, GRP_TXT, etc.) Added global window.TYPE_COLORS in roles.js. Live.js and audio-lab.js now reference the global. Customizer shows packet type colors with emoji + descriptions. Changes sync to TYPE_COLORS in real-time. Saved/restored via localStorage alongside node colors. --- public/audio-lab.js | 2 +- public/customize.js | 72 ++++++++++++++++++++++++++++++++++++++++++++- public/index.html | 8 ++--- public/live.js | 2 +- public/roles.js | 6 ++++ 5 files changed, 83 insertions(+), 7 deletions(-) diff --git a/public/audio-lab.js b/public/audio-lab.js index c2ef6d36..781b9f29 100644 --- a/public/audio-lab.js +++ b/public/audio-lab.js @@ -10,7 +10,7 @@ let speedMult = 1; let highlightTimers = []; - const TYPE_COLORS = { + const TYPE_COLORS = window.TYPE_COLORS || { ADVERT: '#f59e0b', GRP_TXT: '#10b981', TXT_MSG: '#6366f1', TRACE: '#8b5cf6', REQ: '#ef4444', RESPONSE: '#3b82f6', ACK: '#6b7280', PATH: '#ec4899', ANON_REQ: '#f97316', UNKNOWN: '#6b7280' diff --git a/public/customize.js b/public/customize.js index ae0b35dc..16a3b580 100644 --- a/public/customize.js +++ b/public/customize.js @@ -63,6 +63,10 @@ sensor: '#d97706', observer: '#8b5cf6' }, + typeColors: { + ADVERT: '#22c55e', GRP_TXT: '#3b82f6', TXT_MSG: '#f59e0b', ACK: '#6b7280', + REQUEST: '#a855f7', RESPONSE: '#06b6d4', TRACE: '#ec4899', PATH: '#14b8a6' + }, home: { heroTitle: 'MeshCore Analyzer', heroSubtitle: 'Find your nodes to start monitoring them.', @@ -170,6 +174,24 @@ const NODE_EMOJI = { repeater: '◆', companion: '●', room: '■', sensor: '▲', observer: '★' }; + const TYPE_LABELS = { + ADVERT: 'ADVERT', GRP_TXT: 'GRP_TXT', TXT_MSG: 'TXT_MSG', ACK: 'ACK', + REQUEST: 'REQUEST', RESPONSE: 'RESPONSE', TRACE: 'TRACE', PATH: 'PATH' + }; + const TYPE_HINTS = { + ADVERT: 'Node advertisements — map, feed, packet list', + GRP_TXT: 'Group/channel messages — map, feed, channels', + TXT_MSG: 'Direct messages — map, feed', + ACK: 'Acknowledgments — packet list', + REQUEST: 'Requests — packet list, feed', + RESPONSE: 'Responses — packet list', + TRACE: 'Traceroute — map, traces page', + PATH: 'Path packets — packet list' + }; + const TYPE_EMOJI = { + ADVERT: '📡', GRP_TXT: '💬', TXT_MSG: '✉️', ACK: '✓', REQUEST: '❓', RESPONSE: '📨', TRACE: '🔍', PATH: '🛤️' + }; + // Current state let state = {}; @@ -182,6 +204,7 @@ theme: Object.assign({}, DEFAULTS.theme, cfg.theme || {}), themeDark: Object.assign({}, DEFAULTS.themeDark, cfg.themeDark || {}), nodeColors: Object.assign({}, DEFAULTS.nodeColors, cfg.nodeColors || {}), + typeColors: Object.assign({}, DEFAULTS.typeColors, cfg.typeColors || {}), home: { heroTitle: (cfg.home && cfg.home.heroTitle) || DEFAULTS.home.heroTitle, heroSubtitle: (cfg.home && cfg.home.heroSubtitle) || DEFAULTS.home.heroSubtitle, @@ -376,8 +399,24 @@ (val !== def ? '' : '') + ''; } + var typeRows = ''; + for (var tkey in TYPE_LABELS) { + var tval = state.typeColors[tkey]; + var tdef = DEFAULTS.typeColors[tkey]; + typeRows += '
' + + '
' + + '
' + (TYPE_HINTS[tkey] || '') + '
' + + '' + + '' + + '' + tval + '' + + (tval !== tdef ? '' : '') + + '
'; + } return '
' + - '

Node Role Colors

' + rows + '
'; + '

Node Role Colors

' + rows + + '
' + + '

Packet Type Colors

' + typeRows + + ''; } function renderHome() { @@ -451,6 +490,13 @@ } if (Object.keys(nc).length) out.nodeColors = nc; + // Packet type colors + var tc = {}; + for (var tck in DEFAULTS.typeColors) { + if (state.typeColors[tck] !== DEFAULTS.typeColors[tck]) tc[tck] = state.typeColors[tck]; + } + if (Object.keys(tc).length) out.typeColors = tc; + // Home var hm = {}; if (state.home.heroTitle !== DEFAULTS.home.heroTitle) hm.heroTitle = state.home.heroTitle; @@ -599,6 +645,27 @@ }); }); + // Packet type color pickers + container.querySelectorAll('input[data-type-color]').forEach(function (inp) { + inp.addEventListener('input', function () { + var key = inp.dataset.typeColor; + state.typeColors[key] = inp.value; + if (window.TYPE_COLORS) window.TYPE_COLORS[key] = inp.value; + var dot = container.querySelector('[data-tdot="' + key + '"]'); + if (dot) dot.style.background = inp.value; + var hex = container.querySelector('[data-thex="' + key + '"]'); + if (hex) hex.textContent = inp.value; + }); + }); + container.querySelectorAll('[data-reset-type]').forEach(function (btn) { + btn.addEventListener('click', function () { + var key = btn.dataset.resetType; + state.typeColors[key] = DEFAULTS.typeColors[key]; + if (window.TYPE_COLORS) window.TYPE_COLORS[key] = DEFAULTS.typeColors[key]; + render(container); + }); + }); + // Steps container.querySelectorAll('[data-step-field]').forEach(function (inp) { inp.addEventListener('input', function () { @@ -786,6 +853,9 @@ } } } + if (userTheme.typeColors && window.TYPE_COLORS) { + Object.assign(window.TYPE_COLORS, userTheme.typeColors); + } } } catch {} }); diff --git a/public/index.html b/public/index.html index 19b3868e..8fcdbc9b 100644 --- a/public/index.html +++ b/public/index.html @@ -81,7 +81,7 @@
- + @@ -95,12 +95,12 @@ - - + + - + diff --git a/public/live.js b/public/live.js index f9b2a273..010a657b 100644 --- a/public/live.js +++ b/public/live.js @@ -36,7 +36,7 @@ // ROLE_COLORS loaded from shared roles.js (includes 'unknown') - const TYPE_COLORS = { + const TYPE_COLORS = window.TYPE_COLORS || { ADVERT: '#22c55e', GRP_TXT: '#3b82f6', TXT_MSG: '#f59e0b', ACK: '#6b7280', REQUEST: '#a855f7', RESPONSE: '#06b6d4', TRACE: '#ec4899', PATH: '#14b8a6' }; diff --git a/public/roles.js b/public/roles.js index 572af81c..a74e12d2 100644 --- a/public/roles.js +++ b/public/roles.js @@ -14,6 +14,12 @@ sensor: '#d97706', observer: '#8b5cf6', unknown: '#6b7280' }; + window.TYPE_COLORS = { + ADVERT: '#22c55e', GRP_TXT: '#3b82f6', TXT_MSG: '#f59e0b', ACK: '#6b7280', + REQUEST: '#a855f7', RESPONSE: '#06b6d4', TRACE: '#ec4899', PATH: '#14b8a6', + UNKNOWN: '#6b7280' + }; + window.ROLE_LABELS = { repeater: 'Repeaters', companion: 'Companions', room: 'Room Servers', sensor: 'Sensors', observer: 'Observers'