diff --git a/fbw-a32nx/src/systems/instruments/src/EWD/FormattedFwcText.tsx b/fbw-a32nx/src/systems/instruments/src/EWD/FormattedFwcText.tsx index 59f08b95c6d..1d1507ee88a 100644 --- a/fbw-a32nx/src/systems/instruments/src/EWD/FormattedFwcText.tsx +++ b/fbw-a32nx/src/systems/instruments/src/EWD/FormattedFwcText.tsx @@ -20,7 +20,7 @@ export class FormattedFwcText extends DisplayComponent { this.linesRef.instance.innerHTML = ''; this.decorationRef.instance.innerHTML = ''; - let spans: Node[] = []; + let spans: VNode[] = []; let yOffset = 0; let color = 'White'; @@ -36,11 +36,7 @@ export class FormattedFwcText extends DisplayComponent { if (char === '\x1b' || char === '\r') { if (buffer !== '') { // close current part - const s = document.createElementNS('http://www.w3.org/2000/svg', 'tspan'); - s.setAttribute('key', buffer); - s.setAttribute('class', `${color} EWDWarn`); - s.textContent = buffer; - spans.push(s); + spans.push({buffer}); buffer = ''; if (underlined) { @@ -135,7 +131,7 @@ export class FormattedFwcText extends DisplayComponent { e.setAttribute('x', this.props.x.toString()); e.setAttribute('y', (this.props.y + yOffset).toString()); spans.forEach((s) => { - e.appendChild(s); + FSComponent.render(s, e); }); this.linesRef.instance.appendChild(e); yOffset += LINE_SPACING; @@ -152,11 +148,7 @@ export class FormattedFwcText extends DisplayComponent { } if (buffer !== '') { - const s = document.createElementNS('http://www.w3.org/2000/svg', 'tspan'); - s.setAttribute('key', buffer); - s.setAttribute('class', `${color} EWDWarn`); - s.textContent = buffer; - spans.push(s); + spans.push({buffer}); } if (spans.length) { @@ -164,7 +156,7 @@ export class FormattedFwcText extends DisplayComponent { e.setAttribute('x', this.props.x.toString()); e.setAttribute('y', (this.props.y + yOffset).toString()); spans.forEach((s) => { - e.appendChild(s); + FSComponent.render(s, e); }); this.linesRef.instance.appendChild(e); yOffset += LINE_SPACING; diff --git a/fbw-a32nx/src/systems/instruments/src/ND/instrument.tsx b/fbw-a32nx/src/systems/instruments/src/ND/instrument.tsx index 29eb2c2487f..067fac6e786 100644 --- a/fbw-a32nx/src/systems/instruments/src/ND/instrument.tsx +++ b/fbw-a32nx/src/systems/instruments/src/ND/instrument.tsx @@ -174,17 +174,4 @@ class A32NX_ND extends FsBaseInstrument { } } -// Hack to support tspan SVG elements, which FSComponent does not recognise as SVG - -const original = document.createElement.bind(document); - -const extraSvgTags = ['tspan']; - -document.createElement = ((tagName, options) => { - if (extraSvgTags.includes(tagName)) { - return document.createElementNS('http://www.w3.org/2000/svg', tagName, options); - } - return original(tagName, options); -}) as any; - registerInstrument('a32nx-nd', A32NX_ND); diff --git a/fbw-a32nx/src/systems/instruments/src/PFD/FMA.tsx b/fbw-a32nx/src/systems/instruments/src/PFD/FMA.tsx index 40d3290d183..2c9ddb0f0a1 100644 --- a/fbw-a32nx/src/systems/instruments/src/PFD/FMA.tsx +++ b/fbw-a32nx/src/systems/instruments/src/PFD/FMA.tsx @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-3.0 -import { ComponentProps, DisplayComponent, FSComponent, MappedSubject, Subject, Subscribable, VNode } from '@microsoft/msfs-sdk'; +import { ComponentProps, ConsumerSubject, DisplayComponent, FSComponent, MappedSubject, Subject, Subscribable, SubscribableMapFunctions, VNode } from '@microsoft/msfs-sdk'; import { ArincEventBus, Arinc429Word, Arinc429RegisterSubject } from '@flybywiresim/fbw-sdk'; import { ArmedLateralMode, ArmedVerticalMode, isArmed, LateralMode, VerticalMode } from '@shared/autopilot'; @@ -705,9 +705,19 @@ class B1Cell extends ShowForSecondsComponent { private fmaTextRef = FSComponent.createRef(); + private readonly verticalText = Subject.create(''); + + private readonly additionalText = Subject.create(''); + private selectedVS = 0; - private inSpeedProtection = false; + private readonly apSpeedProtection = ConsumerSubject.create(null, false); + + private readonly inSpeedProtection = MappedSubject.create( + ([apSpeedProtection, activeVerticalMode]) => apSpeedProtection && (activeVerticalMode === 14 || activeVerticalMode === 15), + this.apSpeedProtection, + this.activeVerticalModeSub, + ); private fmaModeReversion = false; @@ -815,7 +825,7 @@ class B1Cell extends ShowForSecondsComponent { this.displayModeChangedPath(true); } - const inSpeedProtection = this.inSpeedProtection && (this.activeVerticalModeSub.get() === 14 || this.activeVerticalModeSub.get() === 15); + const inSpeedProtection = this.inSpeedProtection.get(); if (inSpeedProtection || this.fmaModeReversion) { this.boxClassSub.set('NormalStroke None'); @@ -838,7 +848,8 @@ class B1Cell extends ShowForSecondsComponent { this.activeVerticalModeClassSub.set(smallFont ? 'FontMediumSmaller MiddleAlign Green' : 'FontMedium MiddleAlign Green'); - this.fmaTextRef.instance.innerHTML = `${text}${additionalText}`; + this.verticalText.set(text); + this.additionalText.set(additionalText); return text.length > 0; } @@ -874,10 +885,8 @@ class B1Cell extends ShowForSecondsComponent { this.getText(); }); - sub.on('fmaSpeedProtection').whenChanged().handle((protection) => { - this.inSpeedProtection = protection; - this.getText(); - }); + this.apSpeedProtection.setConsumer(sub.on('fmaSpeedProtection')); + this.apSpeedProtection.sub(this.getText.bind(this)); sub.on('expediteMode').whenChanged().handle((e) => { this.expediteMode = e; @@ -905,9 +914,17 @@ class B1Cell extends ShowForSecondsComponent { - - {/* set directly via innerhtml as tspan was invisble for some reason when set here */} - + {this.verticalText} + + {this.additionalText} + + ` ); @@ -1476,6 +1493,13 @@ class D1D2Cell extends ShowForSecondsComponent { } } +enum MdaMode { + None = '', + NoDh = 'NO DH', + Radio = 'RADIO', + Baro = 'BARO', +} + class D3Cell extends DisplayComponent<{bus: ArincEventBus}> { private readonly textRef = FSComponent.createRef(); @@ -1488,38 +1512,46 @@ class D3Cell extends DisplayComponent<{bus: ArincEventBus}> { private readonly noDhSelected = this.fmEisDiscrete2.map((r) => r.bitValueOr(29, false)); - private mdaMdhHtml = MappedSubject.create( - ([mda, dh, noDhSelected]) => { - if (noDhSelected) { - return 'NO DH'; + private readonly mdaDhMode = MappedSubject.create( + ([noDh, dh, mda]) => { + if (noDh) { + return MdaMode.NoDh; } if (!dh.isNoComputedData() && !dh.isFailureWarning()) { - const DHText = Math.round(dh.value).toString().padStart(4, ' '); - return `RADIO${DHText}`; + return MdaMode.Radio; } if (!mda.isNoComputedData() && !mda.isFailureWarning()) { - const MDAText = Math.round(mda.value).toString().padStart(6, ' '); - return `BARO${MDAText}`; + return MdaMode.Baro; } - return ''; + return MdaMode.None; }, + this.noDhSelected, + this.dh, this.mda, + ); + + private readonly mdaDhValueText = MappedSubject.create( + ([mdaMode, dh, mda]) => { + switch (mdaMode) { + case MdaMode.Baro: + return Math.round(mda.value).toString().padStart(6, ' '); + case MdaMode.Radio: + return Math.round(dh.value).toString().padStart(4, ' '); + default: + return ''; + } + }, + this.mdaDhMode, this.dh, - this.noDhSelected, + this.mda, ); onAfterRender(node: VNode): void { super.onAfterRender(node); - this.mdaMdhHtml.sub((html) => this.textRef.instance.innerHTML = html); - this.noDhSelected.sub((noDh) => { - this.textRef.instance.classList.toggle('FontSmallest', !noDh); - this.textRef.instance.classList.toggle('FontMedium', noDh); - }); - const sub = this.props.bus.getArincSubscriber(); sub.on('fmEisDiscreteWord2Raw').handle(this.fmEisDiscrete2.setWord.bind(this.fmEisDiscrete2)); @@ -1529,7 +1561,20 @@ class D3Cell extends DisplayComponent<{bus: ArincEventBus}> { render(): VNode { return ( - + + {this.mdaDhMode} + v.length <= 0) }} style="white-space: pre">{this.mdaDhValueText} + ); } } diff --git a/fbw-a32nx/src/systems/instruments/src/PFD/instrument.tsx b/fbw-a32nx/src/systems/instruments/src/PFD/instrument.tsx index a991c458f61..eb12af1beb9 100644 --- a/fbw-a32nx/src/systems/instruments/src/PFD/instrument.tsx +++ b/fbw-a32nx/src/systems/instruments/src/PFD/instrument.tsx @@ -109,17 +109,4 @@ class A32NX_PFD extends BaseInstrument { } } -// Hack to support tspan SVG elements, which FSComponent does not recognise as SVG - -const original = document.createElement.bind(document); - -const extraSvgTags = ['tspan']; - -document.createElement = ((tagName, options) => { - if (extraSvgTags.includes(tagName)) { - return document.createElementNS('http://www.w3.org/2000/svg', tagName, options); - } - return original(tagName, options); -}) as any; - registerInstrument('a32nx-pfd', A32NX_PFD); diff --git a/package.json b/package.json index 5348ce6c609..fcaac3613aa 100644 --- a/package.json +++ b/package.json @@ -169,7 +169,7 @@ "lodash": "^4.17.20", "msfs-geo": "^0.1.0-alpha3", "msfs-navdata": "^1.1.0", - "@microsoft/msfs-sdk": "^0.6.0", + "@microsoft/msfs-sdk": "^0.7.0", "nanoid": "^3.3.1", "network": "^0.6.1", "qrcode.react": "^1.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c9a4461af72..3bfeee2c909 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,8 @@ dependencies: specifier: ^1.6.0 version: 1.7.5 '@microsoft/msfs-sdk': - specifier: ^0.6.0 - version: 0.6.0 + specifier: ^0.7.0 + version: 0.7.0 '@react-hook/mouse-position': specifier: ~4.1.0 version: 4.1.3(react@17.0.2) @@ -2505,8 +2505,8 @@ packages: - utf-8-validate dev: false - /@microsoft/msfs-sdk@0.6.0: - resolution: {integrity: sha512-fEOg+IynDit88HDKAZkgEoRIrbrTfIQioNO1Ka42PJ+HdjyYC+4neVvs8ohfJyCi7rLzIwlCe3VcsSnNIGUNig==} + /@microsoft/msfs-sdk@0.7.0: + resolution: {integrity: sha512-IWPuI0cKrybcB1xScZx+hTekXyAMFb3wQLjcS6sLXyDygsitH4M0VvpuIfL3KCKRfUUaQRgFhZCXymJ28qWnqA==} dev: false /@navigraph/pkce@1.0.3: