Skip to content

Conversation

@sensei-hacker
Copy link
Member

@sensei-hacker sensei-hacker commented Dec 8, 2025

User description

Summary

Makes OSD tab load significantly faster by allowing the page to render immediately while settings load in the background.

Previously the OSD tab waited for all 67+ settings to load sequentially before displaying anything. Now the UI appears instantly and settings populate as they arrive.

Changes

  • Settings.processHtml now calls callback immediately instead of waiting for configureInputs() to complete
  • Added guards in OSD tab functions to handle being called before data is fully loaded
  • Ensures updatePilotAndCraftNames() runs after OSD data is available via updateAll()

Testing

  • OSD tab renders immediately on navigation
  • All OSD settings populate correctly
  • OSD preview displays properly after data loads
  • No console errors during normal operation

Description

  • Optimize logic conditions loading with configured mask

    • Reduces MSP requests from 64 to 1+N (mask + configured only)
    • Supports firmware 9.0.0+ with fallback to legacy path
  • Enable progressive settings loading for faster tab rendering

    • Settings load asynchronously in background while UI renders immediately
    • Callback fires before configureInputs() completes
  • Add safety guards in OSD tab functions

    • Prevent errors when functions called before data loads
    • Check for OSD.data, OSD.constants, and array items existence
  • Minor code cleanup and formatting improvements


Diagram Walkthrough

flowchart LR
  A["Settings.processHtml"] -->|calls immediately| B["Callback fires"]
  B -->|page renders| C["UI visible"]
  A -->|background| D["configureInputs async"]
  D -->|completes| E["Settings populate"]
  F["Logic Conditions Load"] -->|firmware 9.0.0+| G["Get configured mask"]
  G -->|fetch only configured| H["Reduce MSP requests"]
  F -->|firmware 5.0.0-8.x| I["Legacy: fetch all 64"]
Loading

File Walkthrough

Relevant files
Enhancement
MSPHelper.js
Optimize logic conditions loading with mask                           

js/msp/MSPHelper.js

  • Added handler for MSP2_INAV_LOGIC_CONDITIONS_CONFIGURED message to
    store 64-bit bitmask
  • Refactored loadLogicConditions() to use optimized path for firmware
    9.0.0+
  • Optimized path fetches configured mask first, then only requests
    configured conditions
  • Legacy path preserved for firmware 5.0.0-8.x to fetch all 64
    conditions sequentially
+63/-8   
settings.js
Enable progressive settings loading                                           

js/settings.js

  • Modified processHtml() to call callback immediately instead of waiting
    for configureInputs() to complete
  • configureInputs() now runs asynchronously in background without
    blocking page rendering
  • Removed unnecessary blank line for code cleanup
  • Fixed trailing whitespace in comment
+5/-3     
Error handling
osd.js
Add safety guards for progressive loading                               

tabs/osd.js

  • Added guard in updatePreviews() to check if OSD.data exists before
    processing
  • Added guard in fillCustomElementsValues() to verify array items exist
    before access
  • Added guard in updatePilotAndCraftNames() to check OSD.constants and
    generalGroup initialization
  • Moved updatePilotAndCraftNames() call into updateAll() to ensure it
    runs after data loads
+21/-0   
Configuration changes
MSPCodes.js
Add logic conditions configured mask code                               

js/msp/MSPCodes.js

  • Added new MSP code MSP2_INAV_LOGIC_CONDITIONS_CONFIGURED (0x203C) for
    fetching configured conditions mask
  • Aligned formatting of existing MSP2_INAV_LOGIC_CONDITIONS_SINGLE code
    definition
+2/-1     
Miscellaneous
settingsCache.js
Refactor settings cache retrieval                                               

js/settingsCache.js

  • Refactored get() function to extract key into variable before use
  • Changed let to const for immutable key variable
  • Removed unnecessary blank line for consistency
+2/-2     

Changes Settings.processHtml to call its callback immediately
instead of waiting for all settings to load. This allows tabs
to start rendering while settings populate in the background.

Key changes:
- js/settings.js: configureInputs() now runs async, callback
  fires immediately for progressive rendering
- tabs/osd.js: Added guards in updatePreviews(), updatePilotAndCraftNames(),
  and fillCustomElementsValues() to handle being called before data loads
- tabs/osd.js: Call updatePilotAndCraftNames() from updateAll() to ensure
  it runs after OSD data is available

This significantly improves perceived load time for tabs with many
settings (e.g., OSD tab with 67+ settings).
@sensei-hacker sensei-hacker added this to the 9.0 milestone Dec 8, 2025
@github-actions
Copy link

github-actions bot commented Dec 8, 2025

Branch Targeting Suggestion

You've targeted the master branch with this PR. Please consider if a version branch might be more appropriate:

  • maintenance-9.x - If your change is backward-compatible and won't create compatibility issues between INAV firmware and Configurator 9.x versions. This will allow your PR to be included in the next 9.x release.

  • maintenance-10.x - If your change introduces compatibility requirements between firmware and configurator that would break 9.x compatibility. This is for PRs which will be included in INAV 10.x

If master is the correct target for this change, no action is needed.


This is an automated suggestion to help route contributions to the appropriate branch.

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Dec 8, 2025

PR Compliance Guide 🔍

All compliance sections have been disabled in the configurations.

@sensei-hacker sensei-hacker changed the base branch from master to maintenance-9.x December 8, 2025 18:17
Apply qodo-merge suggestion: check that customElementItems exists
before entering the inner loop, not just the parent items[i] object.
The settingsPromise is now passed to the processHtml callback, allowing
tabs to optionally await it if they need settings values immediately.
Existing tabs work unchanged - they can simply ignore the parameter.

Also reverts settingsCache.js to match original code structure.
- Remove premature loadOsdCustomElements() call during tab init
  (OSD.reload() already calls it in proper sequence)
- Remove premature updatePilotAndCraftNames() call during tab init
  (already added to updateAll() in previous commit)
- Remove explanatory comments (code is self-documenting)
… or master

Replace semver version checks with runtime capability detection for loading
logic conditions. This will allow a newer configurator to work with 9.0.0-RC1 firmware.
ALso nightly firmware build from between 8 and 9.

Always tries the optimized CONFIGURED mask path first (MSP2_INAV_LOGIC_CONDITIONS_CONFIGURED)
Falls back to legacy path (fetch all 64) if:
   - Firmware returns unsupported/empty response
   - No response within 500ms timeout

This approach removes hardcoded version checks (5.0.0, 9.0.0)
@sensei-hacker
Copy link
Member Author

/review

@qodo-code-review
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
✅ No TODO sections
⚡ Recommended focus areas for review

Timeout Logic

The 500ms fallback for mask retrieval may be too aggressive on slow links, potentially triggering the legacy path even when the mask will arrive; verify typical latency and consider making this configurable or longer.

// Set up timeout fallback - if no response in 500ms, use legacy path
const fallbackTimeout = setTimeout(function() {
    if (!maskResponseReceived) {
        maskResponseReceived = true;
        loadAllConditionsLegacy();
    }
}, 500);
Bounds Check

Legacy loop stops at getMaxLogicConditionCount() - 1 but mask-driven loop iterates to max; confirm both paths fetch the intended count and there is no off-by-one difference.

    idx++;
    if (idx < FC.LOGIC_CONDITIONS.getMaxLogicConditionCount() - 1) {
        MSP.send_message(MSPCodes.MSP2_INAV_LOGIC_CONDITIONS_SINGLE, [idx], false, nextLogicCondition);
    } else {
        MSP.send_message(MSPCodes.MSP2_INAV_LOGIC_CONDITIONS_SINGLE, [idx], false, callback);
    }
}
Deferred Update Risk

getLCoptions returns empty until all conditions load, which may leave dropdowns empty if refresh is missed; ensure the post-load refresh reliably updates all dependent selects.

function getLCoptions(){
    var result = '';
    // Return empty if conditions aren't fully loaded yet - callback will refresh
    if (FC.LOGIC_CONDITIONS.getCount() < FC.LOGIC_CONDITIONS.getMaxLogicConditionCount()) {
        return result;
    }
    for(var i = 0; i < FC.LOGIC_CONDITIONS.getMaxLogicConditionCount(); i++) {
        if (FC.LOGIC_CONDITIONS.isEnabled(i)) {
            result += `<option value="` + i + `">LC ` + i + `</option>`;
        }
    }
    return result;

@sensei-hacker sensei-hacker merged commit a70f2e2 into iNavFlight:maintenance-9.x Dec 12, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant