Skip to content

Conversation

@blazoncek
Copy link
Collaborator

@blazoncek blazoncek commented Oct 13, 2025

Ability to reorder LED outputs.
May allow users to update/modify otherwise unmodifiable output.

Summary by CodeRabbit

  • New Features

    • Drag-and-drop reordering of LED outputs in Settings with automatic reindexing of blocks, labels and IDs.
    • Dynamic bus-type availability: LED/bus type options update across selectors based on current configuration.
  • Refactor

    • Internal per-LED selector and initialization logic reorganized for consistent behavior and reliable reindexing.
  • Bug Fixes

    • UI text/spacing tweaks and updated min/max constraints for per‑LED settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 13, 2025

Walkthrough

Split digital-type detection into 1‑pin/2‑pin helpers, added drag‑and‑drop reordering for LED output blocks with reindexing, changed per‑LED limiter signature to enLA(s), migrated per‑LED current selectors to LL, and updated IDs/names and UI bindings in settings_leds.htm.

Changes

Cohort / File(s) Summary of Changes
LED outputs drag-and-drop, type checks, and reindexing
wled00/data/settings_leds.htm
Split digital-type checks into isD1P/isD2P and updated isDig; added drag/drop handlers hDS, hDO, hDrop and recalcIds for block reordering; introduced updateTypeDropdowns(change, sel) to constrain LT options; changed enLA(s,n)enLA(s) and updated callers to derive index from the element; renamed per-LED current selectors to LL and replaced many getElementsByName uses with wrapper accessors (gN/gId/gEBCN); extensive ID/name remapping across LT/LL/LA/MA/CO and related UI text/limits/memory/validation updates.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify recalcIds() updates every ID/name and that no old LT/LA/LAsel references remain.
  • Confirm callers to enLA pass elements (or that code derives the bus index reliably from s).
  • Test drag/drop edge cases, ordering persistence, and updateTypeDropdowns behavior when adding/removing LEDs.

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Drag and drop LED output reordering' directly and accurately describes the main feature addition in this pull request—enabling users to reorder LED outputs through drag-and-drop functionality.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dnd-output-reorder

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f8977f and df79845.

📒 Files selected for processing (1)
  • wled00/data/settings_leds.htm (23 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
wled00/data/**/*.{htm,html,css,js}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use tabs for indentation in web files (.htm/.html/.css/.js) under wled00/data

Files:

  • wled00/data/settings_leds.htm
wled00/data/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

wled00/data/**: When modifying web UI files, run npm run build to regenerate embedded headers before any firmware build
For web UI changes, edit files only under wled00/data (not firmware or generated files)

Files:

  • wled00/data/settings_leds.htm
wled00/data/settings*.htm

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Name settings pages as settings*.htm within the web UI

Files:

  • wled00/data/settings_leds.htm
🧠 Learnings (24)
📓 Common learnings
Learnt from: DedeHai
Repo: wled/WLED PR: 4923
File: wled00/FX.cpp:4883-4901
Timestamp: 2025-09-12T17:29:43.826Z
Learning: In WLED’s web UI, only one slider value (e.g., SEGMENT.intensity or SEGMENT.custom1) changes at a time; code relying on this may use simplified change guards, though presets/JSON can still update multiple fields atomically.
📚 Learning: 2025-09-12T17:29:43.826Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4923
File: wled00/FX.cpp:4883-4901
Timestamp: 2025-09-12T17:29:43.826Z
Learning: In WLED’s web UI, only one slider value (e.g., SEGMENT.intensity or SEGMENT.custom1) changes at a time; code relying on this may use simplified change guards, though presets/JSON can still update multiple fields atomically.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-16T18:08:42.848Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1176-1187
Timestamp: 2025-09-16T18:08:42.848Z
Learning: In WLED finalizeInit() bus creation (wled00/FX_fcn.cpp), intentionally allowing memory overruns when bus configurations exceed MAX_LED_MEMORY is a deliberate design choice. The trade-off prioritizes creating buses with reduced LED counts over completely failing to create buses, which would cause no LED output and UI failures. This approach forces users to update configurations after migrating to version 0.16 while maintaining basic functionality.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-01T10:26:17.959Z
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/wled_eeprom.cpp:0-0
Timestamp: 2025-09-01T10:26:17.959Z
Learning: In WLED PR #4876, the DMXStartLED EEPROM backward compatibility issue was partially addressed by keeping it at address 2550 and reading it as a 16-bit value, with DMXChannelsValue array moved to addresses 2552-2566. This maintains compatibility with pre-0.11 EEPROM layouts for DMXStartLED, though legacy "Set to 255" (code 6) configurations may still need migration logic.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/data/** : For web UI changes, edit files only under wled00/data (not firmware or generated files)

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-08-26T11:51:21.817Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/html_*.h : DO NOT edit generated embedded web header files (wled00/html_*.h)

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-10T18:34:06.550Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4997
File: wled00/e131.cpp:33-44
Timestamp: 2025-10-10T18:34:06.550Z
Learning: In WLED's DDP packet handling (ws.cpp and e131.cpp), only prevent out-of-bounds memory access rather than enforcing DDP spec compliance. Don't check the 1440-byte spec limit—accept out-of-spec packets assuming correct encoding. The bounds check `maxDataIndex = c + numLeds * ddpChannelsPerLed; if (maxDataIndex > dataLen) reject` is sufficient and already covers the timecode flag case (when c=4) without needing separate validation.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-08-28T08:09:20.630Z
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/xml.cpp:0-0
Timestamp: 2025-08-28T08:09:20.630Z
Learning: The WLED codebase has opportunities for refactoring hardcoded array bounds (like the "15" used for DMX channels) to use sizeof(array)/sizeof(array[0]) for more maintainable code, but such changes should be done consistently across the entire codebase in a dedicated refactoring effort.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/data/**/*.{htm,html,css,js} : Use tabs for indentation in web files (.htm/.html/.css/.js) under wled00/data

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/html_*.h : Always commit generated html_*.h files along with related source changes

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/data/index.htm : Main web interface entry file is index.htm; ensure it remains present and functional

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-11T10:49:13.498Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4956
File: wled00/data/edit.htm:295-295
Timestamp: 2025-10-11T10:49:13.498Z
Learning: In the WLED codebase (wled00/data/), the variable `d` is defined in common.js as `var d=document;` and serves as a shorthand alias for `document`. This is a valid convention used throughout WLED's JavaScript files, so references to `d.getElementById()`, `d.body`, `d.onclick`, etc. should not be flagged as undefined variable errors.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-18T03:17:30.107Z
Learnt from: willmmiles
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1183-1194
Timestamp: 2025-09-18T03:17:30.107Z
Learning: In WLED bus management code, dead code branches in error handling (like unreachable else breaks) are intentionally preserved to accommodate potential future API changes, even when currently unreachable.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-04-24T09:31:06.879Z
Learnt from: blazoncek
Repo: wled/WLED PR: 4658
File: wled00/led.cpp:90-91
Timestamp: 2025-04-24T09:31:06.879Z
Learning: In the WLED codebase, the `getSegment()` function guards against out-of-bounds segment IDs by falling back to the main segment ID, and `getFirstSelectedSegId()` falls back to `getMainSegmentId()` if no segments are selected, ensuring no crashes when used through the `setValuesFromFirstSelectedSeg()` macro.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-04-24T09:31:06.879Z
Learnt from: blazoncek
Repo: wled/WLED PR: 4658
File: wled00/led.cpp:90-91
Timestamp: 2025-04-24T09:31:06.879Z
Learning: In the WLED codebase, the `getSegment()` function guards against out-of-bounds segment IDs, and `getFirstSelectedSegId()` falls back to `getMainSegmentId()` if no segments are selected, ensuring no crashes when used through the `setValuesFromFirstSelectedSeg()` macro.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-07-31T18:21:49.868Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4793
File: wled00/file.cpp:481-513
Timestamp: 2025-07-31T18:21:49.868Z
Learning: In WLED, essential configuration files that require backup have short, controlled names (like "/cfg.json", "/presets.json") that are well within a 32-character buffer limit. The file naming is controlled by developers, making buffer overflow in backup filename construction highly unlikely.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-08-31T03:38:14.114Z
Learnt from: BobLoeffler68
Repo: wled/WLED PR: 4891
File: wled00/FX.cpp:3333-3349
Timestamp: 2025-08-31T03:38:14.114Z
Learning: WLED PacMan effect (wled00/FX.cpp): Keep pacmancharacters_t position fields as signed int (not int16_t). Maintainer preference (blazoncek) prioritizes avoiding potential overhead/regressions over minor RAM savings. Avoid type shrinking here unless memory pressure is demonstrated.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-08-21T00:00:17.196Z
Learnt from: willmmiles
Repo: wled/WLED PR: 4859
File: usermods/udp_name_sync/udp_name_sync.cpp:62-70
Timestamp: 2025-08-21T00:00:17.196Z
Learning: In WLED codebase, UDP packet processing code must never rely on null termination being present on the wire and must always validate packet size first. The codebase already has some vulnerabilities where malformed data can crash the software, so avoiding introduction of new ones is a priority.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-28T09:53:42.670Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4939
File: wled00/data/index.js:2406-2413
Timestamp: 2025-09-28T09:53:42.670Z
Learning: In WLED, code paths that appear unreachable may actually be safety fallbacks for low-heap conditions. These fallbacks are intentional defensive programming measures to ensure UI functionality is preserved when system resources are constrained.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-04-30T05:41:03.633Z
Learnt from: blazoncek
Repo: wled/WLED PR: 4667
File: usermods/user_fx/user_fx.cpp:27-30
Timestamp: 2025-04-30T05:41:03.633Z
Learning: In WLED, the Segment::allocateData() method already includes optimization to check if data is allocated and sufficiently sized, handling buffer reuse to reduce memory fragmentation. Adding an external check like `if (SEGENV.data == nullptr && !SEGENV.allocateData(dataSize))` is unnecessary and could be problematic, as it bypasses proper size verification.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-21T20:44:09.502Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4928
File: wled00/bus_wrapper.h:1248-1275
Timestamp: 2025-09-21T20:44:09.502Z
Learning: In WLED bus_wrapper.h, the _useParallelI2S flag is used for selecting the correct function pointer (between parallel I2S and non-parallel I2S bus types) rather than for changing memory calculations. Both parallel and non-parallel I2S configurations have the same memory requirements, so memUsage() correctly doesn't differentiate based on this flag.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-20T09:41:50.374Z
Learnt from: blazoncek
Repo: wled/WLED PR: 4995
File: wled00/FX.cpp:5209-5212
Timestamp: 2025-10-20T09:41:50.374Z
Learning: In WLED 2D effects, SEGMENT.length() returns the physical pixel count (upper bound), while SEG_W * SEG_H can be smaller depending on mapping (mirroring/grouping). For per-cell state buffers (e.g., mode_2Dgameoflife in wled00/FX.cpp), allocate using SEGMENT.length() to ensure sufficient capacity and avoid reallocations, while bounding indexing by cols*rows.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-18T03:17:30.107Z
Learnt from: willmmiles
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1183-1194
Timestamp: 2025-09-18T03:17:30.107Z
Learning: In WLED finalizeInit() bus creation (wled00/FX_fcn.cpp), digitalCount is intentionally incremented even for placeholder buses to maintain consistent resource mapping across all bus configurations.

Applied to files:

  • wled00/data/settings_leds.htm
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
  • GitHub Check: wled_build / Build Environments (esp32s3_4M_qspi)
  • GitHub Check: wled_build / Build Environments (esp32_eth)
  • GitHub Check: wled_build / Build Environments (esp32dev)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full_160)
  • GitHub Check: wled_build / Build Environments (lolin_s2_mini)
  • GitHub Check: wled_build / Build Environments (nodemcuv2_160)
  • GitHub Check: wled_build / Build Environments (nodemcuv2)
  • GitHub Check: wled_build / Build Environments (esp8266_2m_160)
  • GitHub Check: wled_build / Build Environments (usermods)
  • GitHub Check: wled_build / Build Environments (lolin_s2_mini)
  • GitHub Check: wled_build / Build Environments (esp32c3dev)
  • GitHub Check: wled_build / Build Environments (nodemcuv2_compat)
  • GitHub Check: wled_build / Build Environments (esp32s3_4M_qspi)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_8MB_opi)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_16MB_opi)
  • GitHub Check: wled_build / Build Environments (esp32_wrover)
  • GitHub Check: wled_build / Build Environments (nodemcuv2_160)
  • GitHub Check: wled_build / Build Environments (esp32dev)
  • GitHub Check: Analyze (c-cpp)
🔇 Additional comments (6)
wled00/data/settings_leds.htm (6)

16-18: LGTM: Clean refactoring of digital type detection.

Separating 1-pin and 2-pin digital type checks into dedicated helpers improves clarity and makes the type categorization logic more maintainable.


218-220: Note: DMA buffer calculation remains approximate.

The TODO comment correctly identifies that DMA buffer allocation should be based on the bus with the largest LED count rather than per-bus. As noted in previous review discussion, this requires a proper fix beyond this PR's scope.

Based on past review comments.


232-244: LGTM: updateTypeDropdowns integration enables dynamic type enforcement.

The call to updateTypeDropdowns(change) at line 232 ensures LED type options are dynamically updated based on current bus usage. The use of isD1P(t) for counting digital buses correctly tracks 1-pin digital types for parallel I2S calculations.


381-387: LGTM: Refactored to use gN helper.

The changes replace getElementsByName calls with the gN helper while preserving existing indexing logic. As clarified in previous review discussion, the indexing semantics are correct and unchanged by this PR.


400-467: LGTM: Drag-and-drop support and LL naming integrated correctly.

The addition of draggable="true" and drag event handlers enables the core reordering feature. The dynamic type selection logic (lines 456-460) correctly initializes new outputs by selecting the first available valid type after updating type availability. The LL naming convention is consistently applied for LED current selectors.


163-171: All enLA call sites have been correctly updated to the new single-argument signature.

The verification confirms:

  • Line 194: enLA(sel)
  • Line 405: enLA(this) in event handler ✓
  • Line 454: enLA(gN("LL"+s))

No legacy two-argument calls remain. The function properly derives the bus number internally from the element's name attribute.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
wled00/data/settings_leds.htm (1)

134-136: Consider removing commented-out code.

The commented-out lines appear to be dead code. If this logic is no longer needed, remove it to improve maintainability. If it's kept for reference, rely on version control history instead.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3bc728e and 00fab2e.

📒 Files selected for processing (1)
  • wled00/data/settings_leds.htm (9 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
wled00/data/**/*.{htm,html,css,js}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use tabs for indentation in web files (.htm/.html/.css/.js) under wled00/data

Files:

  • wled00/data/settings_leds.htm
wled00/data/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

wled00/data/**: When modifying web UI files, run npm run build to regenerate embedded headers before any firmware build
For web UI changes, edit files only under wled00/data (not firmware or generated files)

Files:

  • wled00/data/settings_leds.htm
wled00/data/settings*.htm

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Name settings pages as settings*.htm within the web UI

Files:

  • wled00/data/settings_leds.htm
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: wled_build / Build Environments (usermods)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_8MB_opi)
  • GitHub Check: wled_build / Build Environments (lolin_s2_mini)
  • GitHub Check: wled_build / Build Environments (esp32dev)
🔇 Additional comments (3)
wled00/data/settings_leds.htm (3)

163-171: LGTM: Function signature refactored correctly.

The signature change from enLA(s,n) to enLA(s) is well-implemented. The bus number is now correctly derived from the select element's name using s.name.substring(2), making the function more self-contained and reducing the chance of passing incorrect parameters.


468-525: LGTM: Draggable HTML structure is well-implemented.

The updated HTML structure correctly implements draggable LED blocks with:

  • Proper drag attributes (draggable="true", ondragstart)
  • Unique IDs for tracking (id="l${s}")
  • Good UX feedback (cursor:grab)
  • Consistent naming convention (LL${s} instead of LAsel${s})

638-657: LGTM: Comprehensive ID recalculation.

The recalcIds() function thoroughly handles all necessary updates after reordering:

  • Display numbers (line 644)
  • All name attributes for form elements (lines 646-649)
  • All ID attributes for DOM elements (lines 651-655)

The implementation correctly maintains consistency across the entire LED output block structure.

if (n==1) {
// npm run build has trouble minimizing spaces inside string
var cn = `<div class="iST">
var cn = `<div class="iST" draggable="true" ondragstart="hDS(event)" id="l${s}" style="cursor:grab;">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add keyboard navigation and ARIA attributes for accessibility.

The drag-and-drop implementation lacks keyboard navigation support and ARIA attributes, preventing users who rely on keyboards or screen readers from reordering LED outputs. This violates WCAG 2.1 accessibility guidelines.

Consider adding:

  1. Keyboard shortcuts (e.g., Ctrl+Up/Down arrows to reorder)
  2. Visible reorder buttons (↑/↓) as an alternative
  3. ARIA attributes: role="list", role="listitem", aria-label="Drag to reorder", aria-grabbed, aria-dropeffect
  4. Focus management after reordering

Example ARIA enhancement:

-<div class="iST" draggable="true" ondragstart="hDS(event)" id="l${s}" style="cursor:grab;">
+<div class="iST" draggable="true" ondragstart="hDS(event)" id="l${s}" style="cursor:grab;" role="listitem" aria-label="LED output ${i+1}, drag to reorder" tabindex="0">

Also applies to: 621-637

🤖 Prompt for AI Agents
In wled00/data/settings_leds.htm around line 468 (and similarly 621-637), the
draggable LED item lacks keyboard navigation and ARIA attributes; add
accessibility by marking the container as role="list" and each item as
role="listitem" with aria-label="Drag to reorder", aria-grabbed (true/false) and
aria-dropeffect where appropriate, add tabindex="0" to make items focusable,
implement keyboard handlers (e.g., Ctrl+ArrowUp/Ctrl+ArrowDown or Home/End) to
move items programmatically and update aria-grabbed/dropeffect states, provide
visible ↑/↓ reorder buttons as alternatives that also update the underlying
order and focus, and ensure focus is moved to the item (or its button) after
reordering so screen reader users remain oriented.

Comment on lines +621 to +637
function hDS(e) {
e.dataTransfer.setData('text', e.currentTarget.id);
}
function hDO(e) {
e.preventDefault();
}
function hDrop(e) {
e.preventDefault();
let t = e.target;
if (t.id === "mLC") t = t.children[0]; // dropped on a container, not on an element
else while (t && !t.classList.contains("iST")) t = t.parentNode; // find target element
if (!t || t.id === "") return false; // not dropping on a valid target
const id = e.dataTransfer.getData("text");
t.parentNode.insertBefore(gId(id), t);
recalcIds();
UI();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Minor: Handle edge case when dropping on empty container.

Line 630 assumes t.children[0] exists when dropping on the container. While unlikely in practice (there's always at least one LED output), this could cause a runtime error if the container is empty.

Consider adding a guard:

 	let t = e.target;
-	if (t.id === "mLC") t = t.children[0]; // dropped on a container, not on an element
+	if (t.id === "mLC") {
+		if (!t.children[0]) return; // empty container
+		t = t.children[0];
+	}
 	else while (t && !t.classList.contains("iST")) t = t.parentNode; // find target element
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function hDS(e) {
e.dataTransfer.setData('text', e.currentTarget.id);
}
function hDO(e) {
e.preventDefault();
}
function hDrop(e) {
e.preventDefault();
let t = e.target;
if (t.id === "mLC") t = t.children[0]; // dropped on a container, not on an element
else while (t && !t.classList.contains("iST")) t = t.parentNode; // find target element
if (!t || t.id === "") return false; // not dropping on a valid target
const id = e.dataTransfer.getData("text");
t.parentNode.insertBefore(gId(id), t);
recalcIds();
UI();
}
function hDrop(e) {
e.preventDefault();
let t = e.target;
if (t.id === "mLC") {
if (!t.children[0]) return; // empty container
t = t.children[0];
}
else while (t && !t.classList.contains("iST")) t = t.parentNode; // find target element
if (!t || t.id === "") return false; // not dropping on a valid target
const id = e.dataTransfer.getData("text");
t.parentNode.insertBefore(gId(id), t);
recalcIds();
UI();
}
🤖 Prompt for AI Agents
In wled00/data/settings_leds.htm around lines 621 to 637, the drop handler
assumes t.children[0] exists when the drop target is the container ("mLC"); add
a guard so you don't access children[0] on an empty container: if the container
has no children, treat the container itself as the insertion point (or append
the dragged element to the container) instead of dereferencing children[0]; keep
the rest of the logic (recalcIds and UI) unchanged.

@DedeHai
Copy link
Collaborator

DedeHai commented Oct 20, 2025

I tried this but what is the purpose?

  • if I move outputs around, it does not allow me to change the LED type
  • does not work on mobile

can you elaborate?

@blazoncek
Copy link
Collaborator Author

You can change only the last one, however now you can choose which is the last.
Doing it on mobile would require a hell-of-a-good-dexterity. Not intended for mobile.

@DedeHai
Copy link
Collaborator

DedeHai commented Oct 20, 2025

On a C3 I can not change the last one:
image

@blazoncek
Copy link
Collaborator Author

You found a bug. 🤦‍♂️

Reordering did not enable editing last bus' type.
@netmindz
Copy link
Member

Do we need reordering as a feature or is this a workaround for the inability to edit all values of all outputs?

@blazoncek
Copy link
Collaborator Author

Do we need reordering as a feature or is this a workaround for the inability to edit all values of all outputs?

You are welcome to find a solution how to dynamically enable certain LED types to prevent questions like "I've added 3 WS2812 outputs to my C3 but only 2 work. How come?"

You can, however, just remove the line I changed in last commit if you don't want such protection. It is responsible for disabling select box.

Disregarding above, there was a request long time ago to allow simpler reordering outputs.

- some string optimisations
- imports from/replaces #5014
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
wled00/data/settings_leds.htm (2)

219-221: Address TODO: DMA buffer calculation for parallel I2S.

The comment indicates that only the bus with the largest LED count should contribute to the DMA buffer calculation, but the current implementation calculates it per-bus. This may lead to memory over-allocation.

Do you want me to generate code to track the maximum LED count across parallel I2S buses and use only that for DMA buffer calculation, or open an issue to track this optimization?


623-642: LGTM: Comprehensive ID recalculation after reordering.

The recalcIds function systematically updates all element IDs and form names after drag-and-drop reordering. The use of "?" as a placeholder to handle both old and new suffixes is elegant.

Consider adding defensive checks for missing elements to make the code more robust:

 ["LT","LL","LA","MA","CO","WO","SP","LS","LC","L0","L1","L2","L3","L4","HS","CV","SL","RF","AW"].forEach((n)=>{
 	let el = e.querySelector("[name^="+n+"]");
-	if (el) el.name = n + sNew;
+	if (!el) {
+		console.warn(`Missing element with name starting with ${n}`);
+		return;
+	}
+	el.name = n + sNew;
 });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a18b133 and a03f758.

📒 Files selected for processing (1)
  • wled00/data/settings_leds.htm (26 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
wled00/data/**/*.{htm,html,css,js}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use tabs for indentation in web files (.htm/.html/.css/.js) under wled00/data

Files:

  • wled00/data/settings_leds.htm
wled00/data/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

wled00/data/**: When modifying web UI files, run npm run build to regenerate embedded headers before any firmware build
For web UI changes, edit files only under wled00/data (not firmware or generated files)

Files:

  • wled00/data/settings_leds.htm
wled00/data/settings*.htm

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Name settings pages as settings*.htm within the web UI

Files:

  • wled00/data/settings_leds.htm
🧠 Learnings (15)
📓 Common learnings
Learnt from: DedeHai
Repo: wled/WLED PR: 4923
File: wled00/FX.cpp:4883-4901
Timestamp: 2025-09-12T17:29:43.826Z
Learning: In WLED’s web UI, only one slider value (e.g., SEGMENT.intensity or SEGMENT.custom1) changes at a time; code relying on this may use simplified change guards, though presets/JSON can still update multiple fields atomically.
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/wled_eeprom.cpp:0-0
Timestamp: 2025-09-01T10:26:17.959Z
Learning: In WLED PR #4876, the DMXStartLED EEPROM backward compatibility issue was partially addressed by keeping it at address 2550 and reading it as a 16-bit value, with DMXChannelsValue array moved to addresses 2552-2566. This maintains compatibility with pre-0.11 EEPROM layouts for DMXStartLED, though legacy "Set to 255" (code 6) configurations may still need migration logic.
Learnt from: DedeHai
Repo: wled/WLED PR: 4997
File: wled00/e131.cpp:33-44
Timestamp: 2025-10-10T18:34:06.550Z
Learning: In WLED's DDP packet handling (ws.cpp and e131.cpp), only prevent out-of-bounds memory access rather than enforcing DDP spec compliance. Don't check the 1440-byte spec limit—accept out-of-spec packets assuming correct encoding. The bounds check `maxDataIndex = c + numLeds * ddpChannelsPerLed; if (maxDataIndex > dataLen) reject` is sufficient and already covers the timecode flag case (when c=4) without needing separate validation.
📚 Learning: 2025-09-12T17:29:43.826Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4923
File: wled00/FX.cpp:4883-4901
Timestamp: 2025-09-12T17:29:43.826Z
Learning: In WLED’s web UI, only one slider value (e.g., SEGMENT.intensity or SEGMENT.custom1) changes at a time; code relying on this may use simplified change guards, though presets/JSON can still update multiple fields atomically.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-16T18:08:42.848Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1176-1187
Timestamp: 2025-09-16T18:08:42.848Z
Learning: In WLED finalizeInit() bus creation (wled00/FX_fcn.cpp), intentionally allowing memory overruns when bus configurations exceed MAX_LED_MEMORY is a deliberate design choice. The trade-off prioritizes creating buses with reduced LED counts over completely failing to create buses, which would cause no LED output and UI failures. This approach forces users to update configurations after migrating to version 0.16 while maintaining basic functionality.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-08-26T11:51:21.817Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/data/** : For web UI changes, edit files only under wled00/data (not firmware or generated files)

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-01T10:26:17.959Z
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/wled_eeprom.cpp:0-0
Timestamp: 2025-09-01T10:26:17.959Z
Learning: In WLED PR #4876, the DMXStartLED EEPROM backward compatibility issue was partially addressed by keeping it at address 2550 and reading it as a 16-bit value, with DMXChannelsValue array moved to addresses 2552-2566. This maintains compatibility with pre-0.11 EEPROM layouts for DMXStartLED, though legacy "Set to 255" (code 6) configurations may still need migration logic.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-08-28T08:09:20.630Z
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/xml.cpp:0-0
Timestamp: 2025-08-28T08:09:20.630Z
Learning: The WLED codebase has opportunities for refactoring hardcoded array bounds (like the "15" used for DMX channels) to use sizeof(array)/sizeof(array[0]) for more maintainable code, but such changes should be done consistently across the entire codebase in a dedicated refactoring effort.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/html_*.h : DO NOT edit generated embedded web header files (wled00/html_*.h)

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-10T18:34:06.550Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4997
File: wled00/e131.cpp:33-44
Timestamp: 2025-10-10T18:34:06.550Z
Learning: In WLED's DDP packet handling (ws.cpp and e131.cpp), only prevent out-of-bounds memory access rather than enforcing DDP spec compliance. Don't check the 1440-byte spec limit—accept out-of-spec packets assuming correct encoding. The bounds check `maxDataIndex = c + numLeds * ddpChannelsPerLed; if (maxDataIndex > dataLen) reject` is sufficient and already covers the timecode flag case (when c=4) without needing separate validation.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-11T10:49:13.498Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4956
File: wled00/data/edit.htm:295-295
Timestamp: 2025-10-11T10:49:13.498Z
Learning: In the WLED codebase (wled00/data/), the variable `d` is defined in common.js as `var d=document;` and serves as a shorthand alias for `document`. This is a valid convention used throughout WLED's JavaScript files, so references to `d.getElementById()`, `d.body`, `d.onclick`, etc. should not be flagged as undefined variable errors.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/data/**/*.{htm,html,css,js} : Use tabs for indentation in web files (.htm/.html/.css/.js) under wled00/data

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/data/index.htm : Main web interface entry file is index.htm; ensure it remains present and functional

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/**/!(html_*)*.h : Use 2-space indentation for non-generated C++ header files (.h)

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-21T20:44:09.502Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4928
File: wled00/bus_wrapper.h:1248-1275
Timestamp: 2025-09-21T20:44:09.502Z
Learning: In WLED bus_wrapper.h, the _useParallelI2S flag is used for selecting the correct function pointer (between parallel I2S and non-parallel I2S bus types) rather than for changing memory calculations. Both parallel and non-parallel I2S configurations have the same memory requirements, so memUsage() correctly doesn't differentiate based on this flag.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-18T03:17:30.107Z
Learnt from: willmmiles
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1183-1194
Timestamp: 2025-09-18T03:17:30.107Z
Learning: In WLED finalizeInit() bus creation (wled00/FX_fcn.cpp), digitalCount is intentionally incremented even for placeholder buses to maintain consistent resource mapping across all bus configurations.

Applied to files:

  • wled00/data/settings_leds.htm
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: wled_build / Build Environments (esp8266_2m_160)
  • GitHub Check: wled_build / Build Environments (nodemcuv2_160)
  • GitHub Check: wled_build / Build Environments (nodemcuv2)
  • GitHub Check: wled_build / Build Environments (esp32s3_4M_qspi)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_8MB_opi)
  • GitHub Check: wled_build / Build Environments (esp32c3dev)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full)
  • GitHub Check: wled_build / Build Environments (esp32_eth)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full_160)
  • GitHub Check: wled_build / Build Environments (nodemcuv2_compat)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full_compat)
  • GitHub Check: wled_build / Build Environments (usermods)
  • GitHub Check: wled_build / Build Environments (lolin_s2_mini)
  • GitHub Check: wled_build / Build Environments (esp32_wrover)
  • GitHub Check: wled_build / Build Environments (esp32dev)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_16MB_opi)
  • GitHub Check: wled_build / Build Environments (esp8266_2m_160)
  • GitHub Check: wled_build / Build Environments (esp8266_2m_compat)
  • GitHub Check: wled_build / Build Environments (esp8266_2m)
  • GitHub Check: Analyze (c-cpp)
🔇 Additional comments (8)
wled00/data/settings_leds.htm (8)

16-18: LGTM: Clean type detection refactor.

The split between 1-pin digital (isD1P) and 2-pin digital (isD2P) improves code clarity and makes the type hierarchy more explicit.


233-252: LGTM: Consistent label spacing.

The trailing spaces after labels improve visual consistency across different pin configuration types.


460-522: LGTM: addLEDs updated for drag-and-drop and refactored indexing.

The changes correctly implement:

  • Draggable LED output blocks with ondragstart handler
  • 1-based display numbering with ${++i}
  • Renamed LAselLL for clarity
  • Updated max PSU current from 65000 to 65500 mA

One minor note: Ensure the max value increase to 65500 is intentional and matches backend validation limits.


606-622: LGTM: Drag-and-drop handlers correctly implement reordering.

The implementation properly:

  • Stores dragged element ID in dataTransfer
  • Prevents default drop behavior
  • Finds the correct drop target (container or element)
  • Reorders DOM elements with insertBefore
  • Triggers ID recalculation and UI update

Note: The empty container edge case on line 615 was already flagged in previous reviews.


903-903: LGTM: Container properly configured for drag-and-drop.

The ondragover and ondrop handlers correctly enable the container to accept dropped LED output blocks.


324-324: LGTM: Minor logic improvements.

The changes correctly:

  • Enforce analog LED count max of 1 (line 324)
  • Track maximum LED count per output (line 333)
  • Include segment buffer calculation based on MS checkbox (line 413)

Also applies to: 952-952, 954-954, 915-915, 923-923

Also applies to: 333-333, 413-413


164-172: All enLA() call sites correctly use the new single-parameter signature.

Verification confirms three call sites (lines 195, 465, 517) all pass the select element as the sole parameter. The function correctly derives the bus number from the element's name attribute, and all elements follow the naming convention required for substring(2) extraction.


474-474: No backend issues found—65500 mA is within uint16_t range and backend accepts it.

The values 65000 and 65500 both fit safely within the uint16_t data type (max 65535). Backend code uses setMilliampsMax(uint16_t max) without enforcing a specific maximum limit, so 65500 is accepted without overflow or validation issues. The change is consistent between per-output (line 474) and global PSU settings (line 889).

Copy link
Collaborator

@DedeHai DedeHai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested this and its now working properly in general. I have a fix for the drag selection which is now broken (and very annoying). should I push it directly to this PR for review?

sel.selectedIndex = sel.querySelector('option:not(:disabled)').index;
enLA(gN("LL"+s)); // update LED mA
let sel = gN("LT"+s);
sel.selectedIndex = sel.querySelector('option:not([data-type])').index; // select On/Off by default
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you add

updateTypeDropdowns(); // update valid bus options including this new one
sel.selectedIndex = sel.querySelector('option:not(:disabled)').index; // select first valid option

like in my original implementation, the current behaviour of selecting the first available is preserved

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
wled00/data/settings_leds.htm (1)

302-302: Fix typo in comment.

Apply this diff:

-				if (!isNet(t) || is8266()) d.Sf["HS"+n].value = "";                         // cleart host field if not network type or ESP8266
+				if (!isNet(t) || is8266()) d.Sf["HS"+n].value = "";                         // clear host field if not network type or ESP8266
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a03f758 and 7f8977f.

📒 Files selected for processing (1)
  • wled00/data/settings_leds.htm (26 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
wled00/data/**/*.{htm,html,css,js}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use tabs for indentation in web files (.htm/.html/.css/.js) under wled00/data

Files:

  • wled00/data/settings_leds.htm
wled00/data/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

wled00/data/**: When modifying web UI files, run npm run build to regenerate embedded headers before any firmware build
For web UI changes, edit files only under wled00/data (not firmware or generated files)

Files:

  • wled00/data/settings_leds.htm
wled00/data/settings*.htm

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Name settings pages as settings*.htm within the web UI

Files:

  • wled00/data/settings_leds.htm
🧠 Learnings (24)
📓 Common learnings
Learnt from: DedeHai
Repo: wled/WLED PR: 4923
File: wled00/FX.cpp:4883-4901
Timestamp: 2025-09-12T17:29:43.826Z
Learning: In WLED’s web UI, only one slider value (e.g., SEGMENT.intensity or SEGMENT.custom1) changes at a time; code relying on this may use simplified change guards, though presets/JSON can still update multiple fields atomically.
📚 Learning: 2025-09-16T18:08:42.848Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1176-1187
Timestamp: 2025-09-16T18:08:42.848Z
Learning: In WLED finalizeInit() bus creation (wled00/FX_fcn.cpp), intentionally allowing memory overruns when bus configurations exceed MAX_LED_MEMORY is a deliberate design choice. The trade-off prioritizes creating buses with reduced LED counts over completely failing to create buses, which would cause no LED output and UI failures. This approach forces users to update configurations after migrating to version 0.16 while maintaining basic functionality.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-12T17:29:43.826Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4923
File: wled00/FX.cpp:4883-4901
Timestamp: 2025-09-12T17:29:43.826Z
Learning: In WLED’s web UI, only one slider value (e.g., SEGMENT.intensity or SEGMENT.custom1) changes at a time; code relying on this may use simplified change guards, though presets/JSON can still update multiple fields atomically.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/data/** : For web UI changes, edit files only under wled00/data (not firmware or generated files)

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-01T10:26:17.959Z
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/wled_eeprom.cpp:0-0
Timestamp: 2025-09-01T10:26:17.959Z
Learning: In WLED PR #4876, the DMXStartLED EEPROM backward compatibility issue was partially addressed by keeping it at address 2550 and reading it as a 16-bit value, with DMXChannelsValue array moved to addresses 2552-2566. This maintains compatibility with pre-0.11 EEPROM layouts for DMXStartLED, though legacy "Set to 255" (code 6) configurations may still need migration logic.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/html_*.h : DO NOT edit generated embedded web header files (wled00/html_*.h)

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-08-26T11:51:21.817Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-08-28T08:09:20.630Z
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/xml.cpp:0-0
Timestamp: 2025-08-28T08:09:20.630Z
Learning: The WLED codebase has opportunities for refactoring hardcoded array bounds (like the "15" used for DMX channels) to use sizeof(array)/sizeof(array[0]) for more maintainable code, but such changes should be done consistently across the entire codebase in a dedicated refactoring effort.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-10T18:34:06.550Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4997
File: wled00/e131.cpp:33-44
Timestamp: 2025-10-10T18:34:06.550Z
Learning: In WLED's DDP packet handling (ws.cpp and e131.cpp), only prevent out-of-bounds memory access rather than enforcing DDP spec compliance. Don't check the 1440-byte spec limit—accept out-of-spec packets assuming correct encoding. The bounds check `maxDataIndex = c + numLeds * ddpChannelsPerLed; if (maxDataIndex > dataLen) reject` is sufficient and already covers the timecode flag case (when c=4) without needing separate validation.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/data/**/*.{htm,html,css,js} : Use tabs for indentation in web files (.htm/.html/.css/.js) under wled00/data

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/html_*.h : Always commit generated html_*.h files along with related source changes

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/data/index.htm : Main web interface entry file is index.htm; ensure it remains present and functional

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-11T10:49:13.498Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4956
File: wled00/data/edit.htm:295-295
Timestamp: 2025-10-11T10:49:13.498Z
Learning: In the WLED codebase (wled00/data/), the variable `d` is defined in common.js as `var d=document;` and serves as a shorthand alias for `document`. This is a valid convention used throughout WLED's JavaScript files, so references to `d.getElementById()`, `d.body`, `d.onclick`, etc. should not be flagged as undefined variable errors.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-18T03:17:30.107Z
Learnt from: willmmiles
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1183-1194
Timestamp: 2025-09-18T03:17:30.107Z
Learning: In WLED bus management code, dead code branches in error handling (like unreachable else breaks) are intentionally preserved to accommodate potential future API changes, even when currently unreachable.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-04-24T09:31:06.879Z
Learnt from: blazoncek
Repo: wled/WLED PR: 4658
File: wled00/led.cpp:90-91
Timestamp: 2025-04-24T09:31:06.879Z
Learning: In the WLED codebase, the `getSegment()` function guards against out-of-bounds segment IDs by falling back to the main segment ID, and `getFirstSelectedSegId()` falls back to `getMainSegmentId()` if no segments are selected, ensuring no crashes when used through the `setValuesFromFirstSelectedSeg()` macro.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-04-24T09:31:06.879Z
Learnt from: blazoncek
Repo: wled/WLED PR: 4658
File: wled00/led.cpp:90-91
Timestamp: 2025-04-24T09:31:06.879Z
Learning: In the WLED codebase, the `getSegment()` function guards against out-of-bounds segment IDs, and `getFirstSelectedSegId()` falls back to `getMainSegmentId()` if no segments are selected, ensuring no crashes when used through the `setValuesFromFirstSelectedSeg()` macro.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-07-31T18:21:49.868Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4793
File: wled00/file.cpp:481-513
Timestamp: 2025-07-31T18:21:49.868Z
Learning: In WLED, essential configuration files that require backup have short, controlled names (like "/cfg.json", "/presets.json") that are well within a 32-character buffer limit. The file naming is controlled by developers, making buffer overflow in backup filename construction highly unlikely.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-08-31T03:38:14.114Z
Learnt from: BobLoeffler68
Repo: wled/WLED PR: 4891
File: wled00/FX.cpp:3333-3349
Timestamp: 2025-08-31T03:38:14.114Z
Learning: WLED PacMan effect (wled00/FX.cpp): Keep pacmancharacters_t position fields as signed int (not int16_t). Maintainer preference (blazoncek) prioritizes avoiding potential overhead/regressions over minor RAM savings. Avoid type shrinking here unless memory pressure is demonstrated.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-08-21T00:00:17.196Z
Learnt from: willmmiles
Repo: wled/WLED PR: 4859
File: usermods/udp_name_sync/udp_name_sync.cpp:62-70
Timestamp: 2025-08-21T00:00:17.196Z
Learning: In WLED codebase, UDP packet processing code must never rely on null termination being present on the wire and must always validate packet size first. The codebase already has some vulnerabilities where malformed data can crash the software, so avoiding introduction of new ones is a priority.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-28T09:53:42.670Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4939
File: wled00/data/index.js:2406-2413
Timestamp: 2025-09-28T09:53:42.670Z
Learning: In WLED, code paths that appear unreachable may actually be safety fallbacks for low-heap conditions. These fallbacks are intentional defensive programming measures to ensure UI functionality is preserved when system resources are constrained.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-04-30T05:41:03.633Z
Learnt from: blazoncek
Repo: wled/WLED PR: 4667
File: usermods/user_fx/user_fx.cpp:27-30
Timestamp: 2025-04-30T05:41:03.633Z
Learning: In WLED, the Segment::allocateData() method already includes optimization to check if data is allocated and sufficiently sized, handling buffer reuse to reduce memory fragmentation. Adding an external check like `if (SEGENV.data == nullptr && !SEGENV.allocateData(dataSize))` is unnecessary and could be problematic, as it bypasses proper size verification.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-21T20:44:09.502Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4928
File: wled00/bus_wrapper.h:1248-1275
Timestamp: 2025-09-21T20:44:09.502Z
Learning: In WLED bus_wrapper.h, the _useParallelI2S flag is used for selecting the correct function pointer (between parallel I2S and non-parallel I2S bus types) rather than for changing memory calculations. Both parallel and non-parallel I2S configurations have the same memory requirements, so memUsage() correctly doesn't differentiate based on this flag.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-10-20T09:41:50.374Z
Learnt from: blazoncek
Repo: wled/WLED PR: 4995
File: wled00/FX.cpp:5209-5212
Timestamp: 2025-10-20T09:41:50.374Z
Learning: In WLED 2D effects, SEGMENT.length() returns the physical pixel count (upper bound), while SEG_W * SEG_H can be smaller depending on mapping (mirroring/grouping). For per-cell state buffers (e.g., mode_2Dgameoflife in wled00/FX.cpp), allocate using SEGMENT.length() to ensure sufficient capacity and avoid reallocations, while bounding indexing by cols*rows.

Applied to files:

  • wled00/data/settings_leds.htm
📚 Learning: 2025-09-18T03:17:30.107Z
Learnt from: willmmiles
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1183-1194
Timestamp: 2025-09-18T03:17:30.107Z
Learning: In WLED finalizeInit() bus creation (wled00/FX_fcn.cpp), digitalCount is intentionally incremented even for placeholder buses to maintain consistent resource mapping across all bus configurations.

Applied to files:

  • wled00/data/settings_leds.htm
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_16MB_opi)
  • GitHub Check: wled_build / Build Environments (esp32c3dev)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_8MB_opi)
  • GitHub Check: wled_build / Build Environments (esp32_wrover)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_16MB_opi)
  • GitHub Check: wled_build / Build Environments (lolin_s2_mini)
  • GitHub Check: wled_build / Build Environments (esp32_eth)
  • GitHub Check: wled_build / Build Environments (usermods)
  • GitHub Check: wled_build / Build Environments (esp32s3_4M_qspi)
  • GitHub Check: wled_build / Build Environments (esp8266_2m_compat)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full_160)
  • GitHub Check: wled_build / Build Environments (nodemcuv2_160)
  • GitHub Check: wled_build / Build Environments (esp32dev)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full_compat)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full)
  • GitHub Check: wled_build / Build Environments (nodemcuv2_compat)
  • GitHub Check: wled_build / Build Environments (esp8266_2m_160)
  • GitHub Check: wled_build / Build Environments (nodemcuv2)
  • GitHub Check: wled_build / Build Environments (esp8266_2m)
  • GitHub Check: Analyze (c-cpp)
🔇 Additional comments (6)
wled00/data/settings_leds.htm (6)

16-18: LGTM: Type detection refactoring.

The split of isDig into isD1P and isD2P helpers provides clearer semantics for distinguishing single-pin from two-pin digital types, improving code readability and enabling more precise bus-type validation logic downstream.


181-194: LGTM: LED current selector naming migration.

The migration from legacy naming to LL prefix for per-LED current selectors is consistent with the broader naming convention update and correctly extracts bus numbers using substring(2).


472-472: Document rationale for PSU max increase.

The maximum PSU current limit was increased from 65000 to 65500 mA. Consider documenting why 65500 is the new safe upper bound, especially given the warning at line 895 about high current requiring thick cables and fuses.


704-736: LGTM: DOM access helper migration.

The conversion from getElementsByName to the gN helper for non-indexed form fields is consistent and improves code readability.


163-171: All enLA call sites correctly use the new signature.

Verification confirms all three call sites (lines 194, 463, 515) pass only the selector element parameter, matching the refactored function signature enLA(s) that now derives the bus number internally.


515-517: Verify new default LED type selection logic.

Line 517 selects the first option without a data-type attribute (typically "On/Off") as the default. Ensure this logic correctly identifies the intended default type and doesn't inadvertently select a disabled or invalid option.

Run the following script to verify the LED type structure and default selection:

Comment on lines +622 to +641
function recalcIds() {
gId("mLC").querySelectorAll(".iST").forEach((e,i)=>{
let sOld = e.id.substring(1);
let sNew = chrID(i);
// update all element IDs and names
e.id = "l"+sNew;
e.querySelector("#n"+sOld).innerText = (i+1);
// names: LT,LL,LA,MA,CO,WO,SP,LS,LC,L0,L1,L2,L3,L4,HS,CV,SL,RF,AW
["LT","LL","LA","MA","CO","WO","SP","LS","LC","L0","L1","L2","L3","L4","HS","CV","SL","RF","AW"].forEach((n)=>{
let el = e.querySelector("[name^="+n+"]");
if (el) el.name = n + sNew;
});
// IDs: l,n,abl,LAdis,PSU,co,ls,dig?w,dig?l,psd,dig?c,p0d,p1d,p2d,p3d,p4d,net?h,dig?r,dig?s,dig?f,dig?a
["l","n","abl","LAdis","PSU","co","ls","dig?w","dig?l","psd","dig?c","p0d","p1d","p2d","p3d","p4d","net?h","dig?r","dig?s","dig?f","dig?a"].forEach((n)=>{
if (n.indexOf("?") < 0) n += "?";
let el = e.querySelector("#"+n.replace("?", sOld));
if (el) el.id = n.replace("?", sNew);
});
});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Update startsDirty array after reordering.

The recalcIds function renumbers all LED blocks but doesn't update the startsDirty array, which tracks custom start indices by bus index. After drag-and-drop reordering, the array indices no longer match the reordered buses, potentially causing incorrect custom start index behavior.

Apply this fix to update startsDirty when reordering:

 		function recalcIds() {
+			let newStartsDirty = [];
 			gId("mLC").querySelectorAll(".iST").forEach((e,i)=>{
 				let sOld = e.id.substring(1);
 				let sNew = chrID(i);
+				let oldIndex = toNum(sOld);
+				newStartsDirty[i] = startsDirty[oldIndex] || false;
 				// update all element IDs and names
 				e.id = "l"+sNew;
 				e.querySelector("#n"+sOld).innerText = (i+1);
 				// names: LT,LL,LA,MA,CO,WO,SP,LS,LC,L0,L1,L2,L3,L4,HS,CV,SL,RF,AW
 				["LT","LL","LA","MA","CO","WO","SP","LS","LC","L0","L1","L2","L3","L4","HS","CV","SL","RF","AW"].forEach((n)=>{
 					let el = e.querySelector("[name^="+n+"]");
 					if (el) el.name = n + sNew;
 				});
 				// IDs: l,n,abl,LAdis,PSU,co,ls,dig?w,dig?l,psd,dig?c,p0d,p1d,p2d,p3d,p4d,net?h,dig?r,dig?s,dig?f,dig?a
 				["l","n","abl","LAdis","PSU","co","ls","dig?w","dig?l","psd","dig?c","p0d","p1d","p2d","p3d","p4d","net?h","dig?r","dig?s","dig?f","dig?a"].forEach((n)=>{
 					if (n.indexOf("?") < 0) n += "?";
 					let el = e.querySelector("#"+n.replace("?", sOld));
 					if (el) el.id = n.replace("?", sNew);
 				});
 			});
+			startsDirty = newStartsDirty;
 		}

Committable suggestion skipped: line range outside the PR's diff.

@blazoncek blazoncek requested a review from DedeHai November 4, 2025 06:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants