From 768b74fa4ae63523d1b8bb50acd8e7e632343c0f Mon Sep 17 00:00:00 2001 From: Saschl Date: Wed, 4 Jan 2023 21:01:25 +0100 Subject: [PATCH] refactor: port SD to full react-based instrument #7345 @2c1fd8e --- .../ModelBehaviorDefs/A32NX/Airbus.xml | 10 +- .../AirPlanes/FlyByWire_A320_NEO/apron.FLT | 1 + .../FlyByWire_A320_NEO/panel/panel.cfg | 6 +- .../FlyByWire_A320_Neo/A32NX_BaseAirliners.js | 2 +- .../EICAS/A320_Neo_EICAS.js | 4 +- .../FlyByWire_A320_Neo/EICAS/EICAS_Common.js | 4 +- src/behavior/src/A32NX_Interior_Misc.xml | 4 +- src/instruments/buildSrc/igniter/tasks.mjs | 77 +----- src/instruments/buildSrc/simulatorBuild.mjs | 3 +- src/instruments/buildSrc/templatePlugins.mjs | 19 +- src/instruments/ecam-page-template/rollup.js | 41 --- .../ecam-page-template/template.html | 21 -- .../ecam-page-template/template.js | 48 ---- src/instruments/src/Common/NXUnits.ts | 51 ++++ src/instruments/src/Common/defaults.ts | 8 +- src/instruments/src/EWD/index.tsx | 31 +-- .../src/SD/Common/definitions.scss | 2 +- .../src/SD}/DoorVideoResources/empty.png | Bin src/instruments/src/SD/Pages/Apu/Apu.tsx | 6 - src/instruments/src/SD/Pages/Apu/config.json | 4 - src/instruments/src/SD/Pages/Bleed/Bleed.tsx | 6 - .../src/SD/Pages/Bleed/config.json | 4 - src/instruments/src/SD/Pages/Cond/Cond.tsx | 6 - src/instruments/src/SD/Pages/Cond/config.json | 4 - src/instruments/src/SD/Pages/Crz/Crz.tsx | 6 - src/instruments/src/SD/Pages/Crz/config.json | 4 - src/instruments/src/SD/Pages/Door/Door.tsx | 7 +- src/instruments/src/SD/Pages/Door/config.json | 4 - src/instruments/src/SD/Pages/Elec/Elec.scss | 2 +- src/instruments/src/SD/Pages/Elec/Elec.tsx | 8 +- src/instruments/src/SD/Pages/Elec/config.json | 4 - src/instruments/src/SD/Pages/Eng/Eng.tsx | 6 - src/instruments/src/SD/Pages/Eng/config.json | 4 - src/instruments/src/SD/Pages/Fctl/Fctl.tsx | 7 +- src/instruments/src/SD/Pages/Fctl/config.json | 4 - src/instruments/src/SD/Pages/Fuel/Fuel.tsx | 6 - src/instruments/src/SD/Pages/Fuel/config.json | 4 - src/instruments/src/SD/Pages/Hyd/Hyd.tsx | 6 - src/instruments/src/SD/Pages/Hyd/config.json | 4 - src/instruments/src/SD/Pages/Press/Press.tsx | 6 - .../src/SD/Pages/Press/config.json | 4 - .../src/SD/Pages/Status/Status.tsx | 6 - .../src/SD/Pages/Status/config.json | 4 - src/instruments/src/SD/Pages/Wheel/Wheel.tsx | 6 - .../src/SD/Pages/Wheel/config.json | 4 - src/instruments/src/SD/PagesContainer.jsx | 39 --- src/instruments/src/SD/PagesContainer.tsx | 204 ++++++++++++++ .../src/SD/StatusArea/StatusArea.jsx | 102 ------- .../src/SD/StatusArea/StatusArea.scss | 11 + .../src/SD/StatusArea/StatusArea.tsx | 248 ++++++++++++++++++ src/instruments/src/SD/Text/Text.scss | 4 +- .../src/SD/Text/{Text.jsx => Text.tsx} | 1 + src/instruments/src/SD/config.json | 2 +- src/instruments/src/SD/index.jsx | 85 ------ src/instruments/src/SD/index.tsx | 55 ++++ src/instruments/src/SD/style.scss | 34 ++- 56 files changed, 647 insertions(+), 606 deletions(-) delete mode 100644 src/instruments/ecam-page-template/rollup.js delete mode 100644 src/instruments/ecam-page-template/template.html delete mode 100644 src/instruments/ecam-page-template/template.js create mode 100644 src/instruments/src/Common/NXUnits.ts rename {flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/EICAS => src/instruments/src/SD}/DoorVideoResources/empty.png (100%) delete mode 100644 src/instruments/src/SD/Pages/Apu/config.json delete mode 100644 src/instruments/src/SD/Pages/Bleed/config.json delete mode 100644 src/instruments/src/SD/Pages/Cond/config.json delete mode 100644 src/instruments/src/SD/Pages/Crz/config.json delete mode 100644 src/instruments/src/SD/Pages/Door/config.json delete mode 100644 src/instruments/src/SD/Pages/Elec/config.json delete mode 100644 src/instruments/src/SD/Pages/Eng/config.json delete mode 100644 src/instruments/src/SD/Pages/Fctl/config.json delete mode 100644 src/instruments/src/SD/Pages/Fuel/config.json delete mode 100644 src/instruments/src/SD/Pages/Hyd/config.json delete mode 100644 src/instruments/src/SD/Pages/Press/config.json delete mode 100644 src/instruments/src/SD/Pages/Status/config.json delete mode 100644 src/instruments/src/SD/Pages/Wheel/config.json delete mode 100644 src/instruments/src/SD/PagesContainer.jsx create mode 100644 src/instruments/src/SD/PagesContainer.tsx delete mode 100644 src/instruments/src/SD/StatusArea/StatusArea.jsx create mode 100644 src/instruments/src/SD/StatusArea/StatusArea.tsx rename src/instruments/src/SD/Text/{Text.jsx => Text.tsx} (97%) delete mode 100644 src/instruments/src/SD/index.jsx create mode 100644 src/instruments/src/SD/index.tsx diff --git a/flybywire-aircraft-a320-neo/ModelBehaviorDefs/A32NX/Airbus.xml b/flybywire-aircraft-a320-neo/ModelBehaviorDefs/A32NX/Airbus.xml index c4d27bc1df4..07bd4258c73 100644 --- a/flybywire-aircraft-a320-neo/ModelBehaviorDefs/A32NX/Airbus.xml +++ b/flybywire-aircraft-a320-neo/ModelBehaviorDefs/A32NX/Airbus.xml @@ -145,7 +145,8 @@ PUSH_ECAM_#BASE_NAME# PUSH_ECAM_#BASE_NAME#_SEQ2 PUSH_ECAM_#BASE_NAME#_SEQ1 - A320_Neo_EICAS_2_ECAM_CHANGE_PAGE_#BASE_NAME# + + A32NX_SD_PAGE_CHANGED A32NX_ECAM_SD_CURRENT_PAGE_INDEX mcdubuttons 0.1 @@ -160,9 +161,12 @@ #ANIM_NAME_BUTTON# - #GROUP_INDEX# -1 > if{ - (>H:#EVENT_NAME#) #GROUP_INDEX# + (L:A32NX_ECAM_SD_CURRENT_PAGE_INDEX) #GROUP_INDEX# != if{ + #GROUP_INDEX# (>L:A32NX_ECAM_SD_CURRENT_PAGE_INDEX) + } els{ + -1 (>L:A32NX_ECAM_SD_CURRENT_PAGE_INDEX) } + (>H:A32NX_SD_PAGE_CHANGED) diff --git a/flybywire-aircraft-a320-neo/SimObjects/AirPlanes/FlyByWire_A320_NEO/apron.FLT b/flybywire-aircraft-a320-neo/SimObjects/AirPlanes/FlyByWire_A320_NEO/apron.FLT index d19ef1cb9e1..c348abcf22d 100644 --- a/flybywire-aircraft-a320-neo/SimObjects/AirPlanes/FlyByWire_A320_NEO/apron.FLT +++ b/flybywire-aircraft-a320-neo/SimObjects/AirPlanes/FlyByWire_A320_NEO/apron.FLT @@ -273,6 +273,7 @@ A32NX_GEAR_CENTER_POSITION = 100 A32NX_GEAR_LEFT_POSITION = 100 A32NX_GEAR_RIGHT_POSITION = 100 A32NX_GEAR_LEVER_POSITION_REQUEST = 1 +A32NX_ECAM_SD_CURRENT_PAGE_INDEX = -1 [Gauges.0] KollsmanSetting=29.921342849731445313 diff --git a/flybywire-aircraft-a320-neo/SimObjects/AirPlanes/FlyByWire_A320_NEO/panel/panel.cfg b/flybywire-aircraft-a320-neo/SimObjects/AirPlanes/FlyByWire_A320_NEO/panel/panel.cfg index 27e150ef271..cb3b57230b2 100644 --- a/flybywire-aircraft-a320-neo/SimObjects/AirPlanes/FlyByWire_A320_NEO/panel/panel.cfg +++ b/flybywire-aircraft-a320-neo/SimObjects/AirPlanes/FlyByWire_A320_NEO/panel/panel.cfg @@ -35,11 +35,11 @@ texture = $EWD htmlgauge00 = A32NX/EWD/template.html?Index=1, 0,0,768,768 [VCockpit04] -size_mm = 1280,1280 #TODO FIXME - Should be 768,768 -pixel_size = 1280,1280 #TODO FIXME - Should be 768,768 +size_mm = 768,768 #TODO FIXME - Should be 768,768 +pixel_size = 768,768 #TODO FIXME - Should be 768,768 texture = $EICAS2 -htmlgauge00 = Airliners/FlyByWire_A320_Neo/EICAS/A320_Neo_EICAS.html?Index=2, 0,0,1280,1280 #TODO FIXME - Should be 768,768 +htmlgauge00 = A32NX/SD/template.html, 0,0,768,768 [VCockpit05] size_mm = 512,512 diff --git a/flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/A32NX_BaseAirliners.js b/flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/A32NX_BaseAirliners.js index 0c772e3826e..ec60ccdce40 100644 --- a/flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/A32NX_BaseAirliners.js +++ b/flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/A32NX_BaseAirliners.js @@ -69,7 +69,7 @@ var Airliners; this.SwitchToPageName(BaseEICAS.LOWER_SCREEN_GROUP_NAME, pageName); for (let i = 0; i < this.lowerScreenPages.length; i++) { if (this.lowerScreenPages[i].name == pageName) { - SimVar.SetSimVarValue("L:A32NX_ECAM_SD_CURRENT_PAGE_INDEX", "number", i); + // SimVar.SetSimVarValue("L:A32NX_ECAM_SD_CURRENT_PAGE_INDEX", "number", i); break; } } diff --git a/flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/EICAS/A320_Neo_EICAS.js b/flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/EICAS/A320_Neo_EICAS.js index f8ce30a1a76..7555c287747 100644 --- a/flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/EICAS/A320_Neo_EICAS.js +++ b/flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/EICAS/A320_Neo_EICAS.js @@ -51,7 +51,7 @@ class A320_Neo_EICAS extends Airliners.BaseEICAS { } } this.SwitchToPageName(this.LOWER_SCREEN_GROUP_NAME, pageName); - SimVar.SetSimVarValue("L:A32NX_ECAM_SD_CURRENT_PAGE_INDEX", "number", this.currentPage); + //SimVar.SetSimVarValue("L:A32NX_ECAM_SD_CURRENT_PAGE_INDEX", "number", this.currentPage); } createLowerScreenPages() { @@ -234,7 +234,7 @@ class A320_Neo_EICAS extends Airliners.BaseEICAS { // Disable user selected page when new failure detected if (this.PrevFailPage !== sFailPage) { this.currentPage = -1; - SimVar.SetSimVarValue("L:A32NX_ECAM_SD_CURRENT_PAGE_INDEX", "number", -1); + //SimVar.SetSimVarValue("L:A32NX_ECAM_SD_CURRENT_PAGE_INDEX", "number", -1); } } diff --git a/flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/EICAS/EICAS_Common.js b/flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/EICAS/EICAS_Common.js index 58456e873ab..2166484c134 100644 --- a/flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/EICAS/EICAS_Common.js +++ b/flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/EICAS/EICAS_Common.js @@ -47,9 +47,9 @@ class EICASCommonDisplay extends Airliners.EICASTemplateElement { const airDataReferenceSource = this.getStatusAirDataReferenceSource(); const inertialReferenceSource = this.getStatusInertialReferenceSource(); const sat = Arinc429Word.fromSimVarValue(`L:A32NX_ADIRS_ADR_${airDataReferenceSource}_STATIC_AIR_TEMPERATURE`); - this.refreshTAT(Arinc429Word.fromSimVarValue(`L:A32NX_ADIRS_ADR_${airDataReferenceSource}_TOTAL_AIR_TEMPERATURE`)); + /* this.refreshTAT(Arinc429Word.fromSimVarValue(`L:A32NX_ADIRS_ADR_${airDataReferenceSource}_TOTAL_AIR_TEMPERATURE`)); this.refreshSAT(sat); - this.refreshISA(Arinc429Word.fromSimVarValue(`L:A32NX_ADIRS_ADR_${airDataReferenceSource}_INTERNATIONAL_STANDARD_ATMOSPHERE_DELTA`), sat); + this.refreshISA(Arinc429Word.fromSimVarValue(`L:A32NX_ADIRS_ADR_${airDataReferenceSource}_INTERNATIONAL_STANDARD_ATMOSPHERE_DELTA`), sat); */ this.refreshClock(); this.refreshLoadFactor(_deltaTime, Arinc429Word.fromSimVarValue(`L:A32NX_ADIRS_IR_${inertialReferenceSource}_BODY_NORMAL_ACC`)); diff --git a/src/behavior/src/A32NX_Interior_Misc.xml b/src/behavior/src/A32NX_Interior_Misc.xml index 7dc7fa2bdc6..b237de343b1 100644 --- a/src/behavior/src/A32NX_Interior_Misc.xml +++ b/src/behavior/src/A32NX_Interior_Misc.xml @@ -466,12 +466,12 @@ #ANIM_NAME_BUTTON# - + diff --git a/src/instruments/buildSrc/igniter/tasks.mjs b/src/instruments/buildSrc/igniter/tasks.mjs index 301cc87a856..2a688045160 100644 --- a/src/instruments/buildSrc/igniter/tasks.mjs +++ b/src/instruments/buildSrc/igniter/tasks.mjs @@ -3,85 +3,20 @@ import { join } from 'path'; import { ExecTask } from '@flybywiresim/igniter'; import { Directories } from '../directories.mjs'; -const ecamPages = [ - { - name: 'eng-page', - path: 'SD/Pages/Eng', - }, - { - name: 'door-page', - path: 'SD/Pages/Door', - }, - { - name: 'cond-page', - path: 'SD/Pages/Cond', - }, - { - name: 'fctl-page', - path: 'SD/Pages/Fctl', - }, - { - name: 'elec-page', - path: 'SD/Pages/Elec', - }, - { - name: 'hyd-page', - path: 'SD/Pages/Hyd', - }, - { - name: 'wheel-page', - path: 'SD/Pages/Wheel', - }, - { - name: 'crz-page', - path: 'SD/Pages/Crz', - }, - { - name: 'fuel-page', - path: 'SD/Pages/Fuel', - }, - { - name: 'apu-page', - path: 'SD/Pages/Apu', - }, - { - name: 'press-page', - path: 'SD/Pages/Press', - }, - { - name: 'bleed-page', - path: 'SD/Pages/Bleed', - }, - { - name: 'status-page', - path: 'SD/Pages/Status', - }, -]; - export function getInputs() { const baseInstruments = fs.readdirSync(join(Directories.instruments, 'src'), { withFileTypes: true }) .filter((d) => d.isDirectory() && fs.existsSync(join(Directories.instruments, 'src', d.name, 'config.json'))); - return [ - ...baseInstruments.map(({ name }) => ({ path: name, name, isInstrument: true })), - ...ecamPages.map((def) => ({ ...def, isInstrument: false })), - ]; + return baseInstruments.map(({ name }) => ({ path: name, name })); } export function getInstrumentsIgniterTasks() { const baseInstruments = fs.readdirSync(join(Directories.instruments, 'src'), { withFileTypes: true }) .filter((d) => d.isDirectory() && fs.existsSync(join(Directories.instruments, 'src', d.name, 'config.json'))); - return [ - ...baseInstruments.map(({ name }) => new ExecTask( - name, - `node src/instruments/buildSrc/igniter/worker.mjs ${name}`, - [join('src/instruments/src', name), join('flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/A32NX', name)], - )), - ...ecamPages.map(({ name, path }) => new ExecTask( - name, - `node src/instruments/buildSrc/igniter/worker.mjs ${name}`, - [join('src/instruments/src', path), join('flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/A32NX/EcamPages', name)], - )), - ]; + return baseInstruments.map(({ name }) => new ExecTask( + name, + `node src/instruments/buildSrc/igniter/worker.mjs ${name}`, + [join('src/instruments/src', name), join('flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/A32NX', name)], + )); } diff --git a/src/instruments/buildSrc/simulatorBuild.mjs b/src/instruments/buildSrc/simulatorBuild.mjs index 0c88292bdb1..da1b6f82fdb 100644 --- a/src/instruments/buildSrc/simulatorBuild.mjs +++ b/src/instruments/buildSrc/simulatorBuild.mjs @@ -8,7 +8,7 @@ import { getInputs } from './igniter/tasks.mjs'; process.chdir(Directories.src); export default getInputs() - .map(({ path, name, isInstrument }) => { + .map(({ path, name }) => { const config = JSON.parse(fs.readFileSync(join(Directories.instruments, 'src', path, 'config.json'))); const additionalImports = config.additionalImports ? config.additionalImports : []; @@ -36,7 +36,6 @@ export default getInputs() ...additionalImports, ], config, - isInstrument, }), ], }; diff --git a/src/instruments/buildSrc/templatePlugins.mjs b/src/instruments/buildSrc/templatePlugins.mjs index 0ad21914b1e..c8b7a8c5208 100644 --- a/src/instruments/buildSrc/templatePlugins.mjs +++ b/src/instruments/buildSrc/templatePlugins.mjs @@ -1,20 +1,13 @@ import { join } from 'path'; import instrumentTemplate from '@flybywiresim/rollup-plugin-msfs'; -import ecamPageTemplate from '../ecam-page-template/rollup.js'; import { Directories } from './directories.mjs'; -export function getTemplatePlugin({ name, config, imports = [], isInstrument }) { - if (isInstrument) { - return instrumentTemplate({ - name, - elementName: `a32nx-${name.toLowerCase()}`, - config, - imports, - outputDir: join(Directories.root, 'flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/A32NX'), - }); - } - return ecamPageTemplate({ +export function getTemplatePlugin({ name, config, imports = [] }) { + return instrumentTemplate({ name, - outputDir: join(Directories.root, 'flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/A32NX/EcamPages'), + elementName: `a32nx-${name.toLowerCase()}`, + config, + imports, + outputDir: join(Directories.root, 'flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/A32NX'), }); } diff --git a/src/instruments/ecam-page-template/rollup.js b/src/instruments/ecam-page-template/rollup.js deleted file mode 100644 index b0b601cf990..00000000000 --- a/src/instruments/ecam-page-template/rollup.js +++ /dev/null @@ -1,41 +0,0 @@ -'use strict'; - -const path = require('path'); -const fs = require('fs'); - -// The bundle code contains `$`, which is a special character -// in JS replace and replaceAll, so we can't use those. -function replaceButSad(s, search, replace) { - return s.split(search).join(replace); -} - -const TEMPLATE_HTML = fs.readFileSync(path.join(__dirname, 'template.html'), 'utf8'); -const TEMPLATE_JS = fs.readFileSync(path.join(__dirname, 'template.js'), 'utf8'); - -module.exports = ({ name, outputDir }) => ({ - name: 'template', - writeBundle(_config, bundle) { - const { code: jsCode } = bundle['bundle.js']; - const { source: cssCode } = bundle['bundle.css']; - - const snakeCaseName = name.replace('-', '_'); - - const process = (s) => { - let tmp = s; - tmp = replaceButSad(tmp, 'PAGE_NAME_LOWER_SKEWER', name); - tmp = replaceButSad(tmp, 'PAGE_NAME_SKEWER', name); - tmp = replaceButSad(tmp, 'PAGE_NAME_LOWER', snakeCaseName.toLowerCase()); - tmp = replaceButSad(tmp, 'PAGE_NAME', snakeCaseName); - tmp = replaceButSad(tmp, 'PAGE_BUNDLE', jsCode); - tmp = replaceButSad(tmp, 'PAGE_STYLE', cssCode); - return tmp; - }; - - const templateHtml = process(TEMPLATE_HTML); - const templateJs = process(TEMPLATE_JS); - - fs.mkdirSync(path.join(outputDir, name), { recursive: true }); - fs.writeFileSync(path.join(outputDir, name, 'template.html'), templateHtml); - fs.writeFileSync(path.join(outputDir, name, 'template.js'), templateJs); - }, -}); diff --git a/src/instruments/ecam-page-template/template.html b/src/instruments/ecam-page-template/template.html deleted file mode 100644 index 3b70fbd3877..00000000000 --- a/src/instruments/ecam-page-template/template.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - diff --git a/src/instruments/ecam-page-template/template.js b/src/instruments/ecam-page-template/template.js deleted file mode 100644 index 46b381f5c38..00000000000 --- a/src/instruments/ecam-page-template/template.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict'; - -/* global Airliners */ - -class A32NX_PAGE_NAME_Logic extends Airliners.EICASTemplateElement { - constructor() { - super(); - let lastTime = this._lastTime; - this.getDeltaTime = () => { - const nowTime = Date.now(); - const deltaTime = nowTime - lastTime; - lastTime = nowTime; - - return deltaTime; - }; - } - - get templateID() { - return 'A32NX_PAGE_NAME_TEMPLATE'; - } - - connectedCallback() { - super.connectedCallback(); - - // This is big hack, see `template.html`. - { - const code = document.getElementById('A32NX_PAGE_NAME_BUNDLED_STYLE').innerHTML; - const style = document.createElement('style'); - style.innerHTML = code; - document.head.appendChild(style); - } - { - const code = document.getElementById('A32NX_PAGE_NAME_BUNDLED_LOGIC').innerHTML; - const script = document.createElement('script'); - script.innerHTML = code; - document.body.appendChild(script); - } - } - - onEvent(_event) { - } - - update(_deltaTime) { - this.dispatchEvent(new CustomEvent('update', { detail: this.getDeltaTime() })); - } -} - -customElements.define('a32nx-PAGE_NAME_LOWER_SKEWER-element', A32NX_PAGE_NAME_Logic); diff --git a/src/instruments/src/Common/NXUnits.ts b/src/instruments/src/Common/NXUnits.ts new file mode 100644 index 00000000000..325bfd52a6e --- /dev/null +++ b/src/instruments/src/Common/NXUnits.ts @@ -0,0 +1,51 @@ +/** + * Unit conversion utilities + */ + +import { NXDataStore } from '@shared/persistence'; + +export class NXUnits { + private static metricWeightVal: boolean; + + static get metricWeight() { + if (NXUnits.metricWeightVal === undefined) { + NXDataStore.getAndSubscribe('CONFIG_USING_METRIC_UNIT', (key, value) => { + NXUnits.metricWeightVal = value === '1'; + }, '1'); + } + return NXUnits.metricWeightVal; + } + + static userToKg(value) { + return NXUnits.metricWeight ? value : value / 2.204625; + } + + static kgToUser(value) { + return NXUnits.metricWeight ? value : value * 2.204625; + } + + static poundsToUser(value) { + return NXUnits.metricWeight ? value / 2.204625 : value; + } + + static userWeightUnit() { + return NXUnits.metricWeight ? 'KG' : 'LBS'; // EIS uses S suffix on LB + } + + /** + * Converts meter into ft if imperial units are selected + * @param value {number} in unit Meters + * @returns {number} in metric or ft + */ + static mToUser(value) { + return NXUnits.metricWeight ? value : value * 3.28084; + } + + /** + * Returns 'M' for meters and 'FT' for feet depending on the unit system selected + * @returns {string} 'M' (meter) OR 'FT' (feet) + */ + static userDistanceUnit() { + return NXUnits.metricWeight ? 'M' : 'FT'; + } +} diff --git a/src/instruments/src/Common/defaults.ts b/src/instruments/src/Common/defaults.ts index 4d9f3629023..be65440c26c 100644 --- a/src/instruments/src/Common/defaults.ts +++ b/src/instruments/src/Common/defaults.ts @@ -1,16 +1,16 @@ // We currently assume that these two elements will be found. // Might be worth implementing checking in the future. -let reactMount = document.getElementById('MSFS_REACT_MOUNT') as HTMLElement; +const reactMount = document.getElementById('MSFS_REACT_MOUNT') as HTMLElement; -const getEcamPageRenderTarget = (pageName: string): HTMLElement => (document.getElementById(`A32NX_${pageName}_PAGE_REACT_MOUNT`) as HTMLElement); +// const getEcamPageRenderTarget = (pageName: string): HTMLElement => (document.getElementById(`A32NX_${pageName}_PAGE_REACT_MOUNT`) as HTMLElement); /** * Configures the framework to render inside the ECAM. Temporary solution for moving individual SD pages to React. */ -export const setIsEcamPage = (pageName: string) => { +/* export const setIsEcamPage = (pageName: string) => { reactMount = getEcamPageRenderTarget(pageName); -}; +}; */ /** * Returns the render target which React mounts onto diff --git a/src/instruments/src/EWD/index.tsx b/src/instruments/src/EWD/index.tsx index 4a51628dc09..fda3f5667bc 100644 --- a/src/instruments/src/EWD/index.tsx +++ b/src/instruments/src/EWD/index.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React from 'react'; import { DisplayUnit } from '@instruments/common/displayUnit'; import { render } from '../Common'; import UpperDisplay from './elements/UpperDisplay'; @@ -6,23 +6,16 @@ import LowerDisplay from './elements/LowerDisplay'; import './style.scss'; -export const EWD: React.FC = () => { - const [displayIndex] = useState(() => { - const url = document.getElementsByTagName('a32nx-ewd')[0].getAttribute('url'); - return url ? parseInt(url.substring(url.length - 1), 10) : 0; - }); - - return ( - - - - - - - ); -}; +export const EWD: React.FC = () => ( + + + + + + +); render(); diff --git a/src/instruments/src/SD/Common/definitions.scss b/src/instruments/src/SD/Common/definitions.scss index 8fd432adf9f..28fd152886c 100644 --- a/src/instruments/src/SD/Common/definitions.scss +++ b/src/instruments/src/SD/Common/definitions.scss @@ -1,4 +1,4 @@ -$font-size-small: 14px; +$font-size-small: 15px; $font-size-medium: 16px; $font-size-large: 17px; $font-size-larger: 18px; diff --git a/flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/EICAS/DoorVideoResources/empty.png b/src/instruments/src/SD/DoorVideoResources/empty.png similarity index 100% rename from flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/Airliners/FlyByWire_A320_Neo/EICAS/DoorVideoResources/empty.png rename to src/instruments/src/SD/DoorVideoResources/empty.png diff --git a/src/instruments/src/SD/Pages/Apu/Apu.tsx b/src/instruments/src/SD/Pages/Apu/Apu.tsx index 21b52cc3769..b6f1111e455 100644 --- a/src/instruments/src/SD/Pages/Apu/Apu.tsx +++ b/src/instruments/src/SD/Pages/Apu/Apu.tsx @@ -1,7 +1,5 @@ import React, { useEffect, useState } from 'react'; import { useArinc429Var } from '@instruments/common/arinc429'; -import { render } from '@instruments/common/index'; -import { setIsEcamPage } from '@instruments/common/defaults'; import { useSimVar } from '@instruments/common/simVars'; import { GaugeComponent, GaugeMarkerComponent } from '@instruments/common/gauges'; import { PageTitle } from '../../Common/PageTitle'; @@ -10,8 +8,6 @@ import { SvgGroup } from '../../Common/SvgGroup'; import './Apu.scss'; -setIsEcamPage('apu_page'); - export const ApuPage = () => { const [apuAvail] = useSimVar('L:A32NX_OVHD_APU_START_PB_IS_AVAILABLE', 'Bool', 1000); @@ -499,5 +495,3 @@ const ApuMemos = ({ x, y } : ComponentPositionProps) => { ); }; - -render(); diff --git a/src/instruments/src/SD/Pages/Apu/config.json b/src/instruments/src/SD/Pages/Apu/config.json deleted file mode 100644 index 3ea0390ce9c..00000000000 --- a/src/instruments/src/SD/Pages/Apu/config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "index": "./Apu.tsx", - "isInteractive": false -} diff --git a/src/instruments/src/SD/Pages/Bleed/Bleed.tsx b/src/instruments/src/SD/Pages/Bleed/Bleed.tsx index 94db340e7f7..5eabcfbcdbc 100644 --- a/src/instruments/src/SD/Pages/Bleed/Bleed.tsx +++ b/src/instruments/src/SD/Pages/Bleed/Bleed.tsx @@ -1,7 +1,5 @@ import React, { FC } from 'react'; -import { render } from '@instruments/common/index'; import { useSimVar } from '@instruments/common/simVars'; -import { setIsEcamPage } from '@instruments/common/defaults'; import { PageTitle } from '../../Common/PageTitle'; import { EcamPage } from '../../Common/EcamPage'; import EngineBleed from './elements/EngineBleed'; @@ -11,8 +9,6 @@ import { Triangle } from '../../Common/Shapes'; import './Bleed.scss'; -setIsEcamPage('bleed_page'); - export const BleedPage: FC = () => { const sdacDatum = true; const [xbleedAirValveOpen] = useSimVar('L:A32NX_PNEU_XBLEED_VALVE_OPEN', 'bool', 500); @@ -102,5 +98,3 @@ export const BleedPage: FC = () => { ); }; - -render(); diff --git a/src/instruments/src/SD/Pages/Bleed/config.json b/src/instruments/src/SD/Pages/Bleed/config.json deleted file mode 100644 index 279acb91304..00000000000 --- a/src/instruments/src/SD/Pages/Bleed/config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "index": "./Bleed.tsx", - "isInteractive": false -} diff --git a/src/instruments/src/SD/Pages/Cond/Cond.tsx b/src/instruments/src/SD/Pages/Cond/Cond.tsx index 5b898c966bb..fc6081635ba 100644 --- a/src/instruments/src/SD/Pages/Cond/Cond.tsx +++ b/src/instruments/src/SD/Pages/Cond/Cond.tsx @@ -1,14 +1,10 @@ import React from 'react'; import { SvgGroup } from '../../Common/SvgGroup'; -import { render } from '../../../Common'; -import { setIsEcamPage } from '../../../Common/defaults'; import { useSimVar } from '../../../Common/simVars'; import Valve from './Valve'; import '../../Common/CommonStyles.scss'; -setIsEcamPage('cond_page'); - export const CondPage = () => { // Disaply trim valve position for each zone const gaugeOffset = -43; // Gauges range is from -43 degree to +43 degree @@ -105,5 +101,3 @@ const CondUnit = ({ title, selectedTemp, cabinTemp, trimTemp, x, y, offset, hotA ); }; - -render(); diff --git a/src/instruments/src/SD/Pages/Cond/config.json b/src/instruments/src/SD/Pages/Cond/config.json deleted file mode 100644 index befff9b98ad..00000000000 --- a/src/instruments/src/SD/Pages/Cond/config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "index": "./Cond.tsx", - "isInteractive": false -} diff --git a/src/instruments/src/SD/Pages/Crz/Crz.tsx b/src/instruments/src/SD/Pages/Crz/Crz.tsx index 398ac1c7a19..c66eb60e7af 100644 --- a/src/instruments/src/SD/Pages/Crz/Crz.tsx +++ b/src/instruments/src/SD/Pages/Crz/Crz.tsx @@ -1,15 +1,11 @@ import React, { useEffect, useState } from 'react'; import { GaugeComponent, GaugeMarkerComponent, splitDecimals } from '@instruments/common/gauges'; -import { render } from '../../../Common'; -import { setIsEcamPage } from '../../../Common/defaults'; import { useSimVar } from '../../../Common/simVars'; import { usePersistentProperty } from '../../../Common/persistence'; import { fuelForDisplay } from '../../Common/FuelFunctions'; import './Crz.scss'; -setIsEcamPage('crz_page'); - export const CrzPage = () => ( <> @@ -232,5 +228,3 @@ export const CondComponent = () => { ); }; - -render(); diff --git a/src/instruments/src/SD/Pages/Crz/config.json b/src/instruments/src/SD/Pages/Crz/config.json deleted file mode 100644 index 560f590c6a6..00000000000 --- a/src/instruments/src/SD/Pages/Crz/config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "index": "./Crz.tsx", - "isInteractive": false -} diff --git a/src/instruments/src/SD/Pages/Door/Door.tsx b/src/instruments/src/SD/Pages/Door/Door.tsx index 697b93c68a6..27ca066a941 100644 --- a/src/instruments/src/SD/Pages/Door/Door.tsx +++ b/src/instruments/src/SD/Pages/Door/Door.tsx @@ -1,10 +1,7 @@ -import './Door.scss'; import React from 'react'; -import { render } from '@instruments/common/index'; -import { setIsEcamPage } from '../../../Common/defaults'; import { useSimVar } from '../../../Common/simVars'; -setIsEcamPage('door_page'); +import './Door.scss'; export const DoorPage = () => { const [cabin] = useSimVar('INTERACTIVE POINT OPEN:0', 'percent', 1000); @@ -87,5 +84,3 @@ export const DoorPage = () => { ); }; - -render(); diff --git a/src/instruments/src/SD/Pages/Door/config.json b/src/instruments/src/SD/Pages/Door/config.json deleted file mode 100644 index e3e5e64860a..00000000000 --- a/src/instruments/src/SD/Pages/Door/config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "index": "./Door.tsx", - "isInteractive": false -} diff --git a/src/instruments/src/SD/Pages/Elec/Elec.scss b/src/instruments/src/SD/Pages/Elec/Elec.scss index b45c2512170..28056f94abb 100644 --- a/src/instruments/src/SD/Pages/Elec/Elec.scss +++ b/src/instruments/src/SD/Pages/Elec/Elec.scss @@ -29,7 +29,7 @@ text { fill: #EEEEEE; - font-family: 'Roboto Mono', monospace; + //font-family: 'Roboto Mono', monospace !important; font-size: 19px; &.ExtraLarge { diff --git a/src/instruments/src/SD/Pages/Elec/Elec.tsx b/src/instruments/src/SD/Pages/Elec/Elec.tsx index a2307f7f309..fc0e0ee9b73 100644 --- a/src/instruments/src/SD/Pages/Elec/Elec.tsx +++ b/src/instruments/src/SD/Pages/Elec/Elec.tsx @@ -1,16 +1,12 @@ -import classNames from 'classnames'; import React from 'react'; -import { render } from '@instruments/common/index'; +import classNames from 'classnames'; import { PageTitle } from '../../Common/PageTitle'; -import { setIsEcamPage } from '../../../Common/defaults'; import { useSimVar } from '../../../Common/simVars'; import { EcamPage } from '../../Common/EcamPage'; import { SvgGroup } from '../../Common/SvgGroup'; import './Elec.scss'; -setIsEcamPage('elec_page'); - const maxStaleness = 300; export const ElecPage = () => { @@ -517,5 +513,3 @@ const Wire = ({ d, amber }: WireProps) => { const classes = classNames({ Green: !amber }, { Amber: amber }); return ; }; - -render(); diff --git a/src/instruments/src/SD/Pages/Elec/config.json b/src/instruments/src/SD/Pages/Elec/config.json deleted file mode 100644 index 8b188b36870..00000000000 --- a/src/instruments/src/SD/Pages/Elec/config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "index": "./Elec.tsx", - "isInteractive": false -} diff --git a/src/instruments/src/SD/Pages/Eng/Eng.tsx b/src/instruments/src/SD/Pages/Eng/Eng.tsx index b1cdabb4332..1a80ccfbc2b 100644 --- a/src/instruments/src/SD/Pages/Eng/Eng.tsx +++ b/src/instruments/src/SD/Pages/Eng/Eng.tsx @@ -1,6 +1,4 @@ import React, { FC, useState, useEffect } from 'react'; -import { render } from '@instruments/common/index'; -import { setIsEcamPage } from '@instruments/common/defaults'; import { Arc, Needle } from '@instruments/common/gauges'; import { usePersistentProperty } from '@instruments/common/persistence'; import { useSimVar } from '@instruments/common/simVars'; @@ -10,8 +8,6 @@ import { SvgGroup } from '../../Common/SvgGroup'; import './Eng.scss'; -setIsEcamPage('eng_page'); - export const EngPage: FC = () => { const [weightUnit] = usePersistentProperty('CONFIG_USING_METRIC_UNIT', '1'); const [engSelectorPosition] = useSimVar('L:XMLVAR_ENG_MODE_SEL', 'Enum', 1000); @@ -351,5 +347,3 @@ const EngineColumn = ({ x, y, engineNumber }: ComponentPositionProps) => { ); }; - -render(); diff --git a/src/instruments/src/SD/Pages/Eng/config.json b/src/instruments/src/SD/Pages/Eng/config.json deleted file mode 100644 index 020be6050c2..00000000000 --- a/src/instruments/src/SD/Pages/Eng/config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "index": "./Eng.tsx", - "isInteractive": false -} diff --git a/src/instruments/src/SD/Pages/Fctl/Fctl.tsx b/src/instruments/src/SD/Pages/Fctl/Fctl.tsx index c56a2f480c2..f2cca546e96 100644 --- a/src/instruments/src/SD/Pages/Fctl/Fctl.tsx +++ b/src/instruments/src/SD/Pages/Fctl/Fctl.tsx @@ -1,8 +1,6 @@ import React from 'react'; -import { render } from '@instruments/common/index'; import { useArinc429Var } from '@instruments/common/arinc429'; import { Arinc429Word } from '@shared/arinc429'; -import { setIsEcamPage } from '../../../Common/defaults'; import { useSimVar } from '../../../Common/simVars'; import { SvgGroup } from '../../Common/SvgGroup'; import { HydraulicsProvider, useHydraulics } from '../../Common/HydraulicsProvider'; @@ -14,8 +12,6 @@ import { Spoilers } from '../../Common/Spoilers'; import '../../Common/CommonStyles.scss'; -setIsEcamPage('fctl_page'); - interface HydraulicSystemPairProps { leftHydraulicSystem: HydraulicSystem, rightHydraulicSystem: HydraulicSystem, @@ -432,10 +428,9 @@ const ElevatorAxis = ({ x, y, side }: ComponentPositionProps & ComponentSidePosi interface ServoControlIndicatorProps extends ComponentPositionProps { servoFailed: boolean, } + const ServoControlIndicator = ({ x, y, servoFailed }: ServoControlIndicatorProps) => ( ); - -render(); diff --git a/src/instruments/src/SD/Pages/Fctl/config.json b/src/instruments/src/SD/Pages/Fctl/config.json deleted file mode 100644 index 2aaf052180d..00000000000 --- a/src/instruments/src/SD/Pages/Fctl/config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "index": "./Fctl.tsx", - "isInteractive": false -} diff --git a/src/instruments/src/SD/Pages/Fuel/Fuel.tsx b/src/instruments/src/SD/Pages/Fuel/Fuel.tsx index e796c8c6b39..835875eaa96 100644 --- a/src/instruments/src/SD/Pages/Fuel/Fuel.tsx +++ b/src/instruments/src/SD/Pages/Fuel/Fuel.tsx @@ -1,7 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { render } from '@instruments/common/index'; import { useSimVar } from '@instruments/common/simVars'; -import { setIsEcamPage } from '@instruments/common/defaults'; import { useArinc429Var } from '@instruments/common/arinc429'; import { usePersistentProperty } from '../../../Common/persistence'; import { fuelForDisplay, fuelInTanksForDisplay } from '../../Common/FuelFunctions'; @@ -11,8 +9,6 @@ import { EcamPage } from '../../Common/EcamPage'; import './Fuel.scss'; -setIsEcamPage('fuel_page'); - export const FuelPage = () => { const [crossFeedPosition] = useSimVar('FUELSYSTEM VALVE OPEN:3', 'number', 500); @@ -358,5 +354,3 @@ const Pump = ({ x, y, onBus = 'DC_ESS', pumpNumber, centreTank, tankQuantity }: ); }; - -render(); diff --git a/src/instruments/src/SD/Pages/Fuel/config.json b/src/instruments/src/SD/Pages/Fuel/config.json deleted file mode 100644 index 140e76bdea6..00000000000 --- a/src/instruments/src/SD/Pages/Fuel/config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "index": "./Fuel.tsx", - "isInteractive": false -} diff --git a/src/instruments/src/SD/Pages/Hyd/Hyd.tsx b/src/instruments/src/SD/Pages/Hyd/Hyd.tsx index 7050243bd55..37772df6b9c 100644 --- a/src/instruments/src/SD/Pages/Hyd/Hyd.tsx +++ b/src/instruments/src/SD/Pages/Hyd/Hyd.tsx @@ -1,14 +1,10 @@ import React, { useEffect, useState } from 'react'; -import { render } from '@instruments/common/index'; import { useSimVar } from '@instruments/common/simVars'; -import { setIsEcamPage } from '@instruments/common/defaults'; import { SvgGroup } from '../../Common/SvgGroup'; import { Triangle } from '../../Common/Shapes'; import '../../Common/CommonStyles.scss'; -setIsEcamPage('hyd_page'); - const litersPerGallon = 3.79; enum HydSystem { @@ -478,5 +474,3 @@ const PTU = ({ x, y, yellowPressure, greenPressure, yellowPumpLowPressure, green ); }; - -render(); diff --git a/src/instruments/src/SD/Pages/Hyd/config.json b/src/instruments/src/SD/Pages/Hyd/config.json deleted file mode 100644 index d8479691e3f..00000000000 --- a/src/instruments/src/SD/Pages/Hyd/config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "index": "./Hyd.tsx", - "isInteractive": false -} diff --git a/src/instruments/src/SD/Pages/Press/Press.tsx b/src/instruments/src/SD/Pages/Press/Press.tsx index ea97da275f4..cf1370e91ea 100644 --- a/src/instruments/src/SD/Pages/Press/Press.tsx +++ b/src/instruments/src/SD/Pages/Press/Press.tsx @@ -1,7 +1,5 @@ import React, { FC, useState, useEffect, memo } from 'react'; -import { render } from '@instruments/common/index'; import { GaugeComponent, GaugeMarkerComponent, splitDecimals } from '@instruments/common/gauges'; -import { setIsEcamPage } from '@instruments/common/defaults'; import { Triangle } from '../../Common/Shapes'; import { PageTitle } from '../../Common/PageTitle'; import { EcamPage } from '../../Common/EcamPage'; @@ -10,8 +8,6 @@ import { SvgGroup } from '../../Common/SvgGroup'; import './Press.scss'; -setIsEcamPage('press_page'); - export const PressPage: FC = () => { const [cabinAlt] = useSimVar('L:A32NX_PRESS_CABIN_ALTITUDE', 'feet', 500); const [deltaPsi] = useSimVar('L:A32NX_PRESS_CABIN_DELTA_PRESSURE', 'psi', 500); @@ -561,5 +557,3 @@ const OverboardOutletComponent: FC = ({ validSDAC, ); }; - -render(); diff --git a/src/instruments/src/SD/Pages/Press/config.json b/src/instruments/src/SD/Pages/Press/config.json deleted file mode 100644 index 8b34840c485..00000000000 --- a/src/instruments/src/SD/Pages/Press/config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "index": "./Press.tsx", - "isInteractive": false -} diff --git a/src/instruments/src/SD/Pages/Status/Status.tsx b/src/instruments/src/SD/Pages/Status/Status.tsx index 9f747dce19b..844f46c9c6e 100644 --- a/src/instruments/src/SD/Pages/Status/Status.tsx +++ b/src/instruments/src/SD/Pages/Status/Status.tsx @@ -1,6 +1,4 @@ import React, { FC } from 'react'; -import { render } from '@instruments/common/index'; -import { setIsEcamPage } from '@instruments/common/defaults'; import { PageTitle } from '../../Common/PageTitle'; import { EcamPage } from '../../Common/EcamPage'; import StatusDisplay from './elements/StatusDisplay'; @@ -8,8 +6,6 @@ import DownArrow from './elements/DownArrow'; import './Status.scss'; -setIsEcamPage('status_page'); - export const StatusPage: FC = () => ( @@ -22,5 +18,3 @@ export const StatusPage: FC = () => ( ); - -render(); diff --git a/src/instruments/src/SD/Pages/Status/config.json b/src/instruments/src/SD/Pages/Status/config.json deleted file mode 100644 index 6129deb79fe..00000000000 --- a/src/instruments/src/SD/Pages/Status/config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "index": "./Status.tsx", - "isInteractive": false -} diff --git a/src/instruments/src/SD/Pages/Wheel/Wheel.tsx b/src/instruments/src/SD/Pages/Wheel/Wheel.tsx index 44222406348..8e410a0fcea 100644 --- a/src/instruments/src/SD/Pages/Wheel/Wheel.tsx +++ b/src/instruments/src/SD/Pages/Wheel/Wheel.tsx @@ -1,7 +1,5 @@ import React from 'react'; -import { render } from '@instruments/common/index'; import { useSimVar } from '@instruments/common/simVars'; -import { setIsEcamPage } from '@instruments/common/defaults'; import { useArinc429Var } from '@instruments/common/arinc429'; import { Arinc429Word } from '@shared/arinc429'; import { HydraulicsProvider, useHydraulics } from '../../Common/HydraulicsProvider'; @@ -12,8 +10,6 @@ import { Spoilers } from '../../Common/Spoilers'; import '../../Common/CommonStyles.scss'; -setIsEcamPage('wheel_page'); - const maxStaleness = 300; export const WheelPage = () => { @@ -498,5 +494,3 @@ const Wheels = ({ x, y, left, right }: WheelsProps) => { ); }; - -render(); diff --git a/src/instruments/src/SD/Pages/Wheel/config.json b/src/instruments/src/SD/Pages/Wheel/config.json deleted file mode 100644 index bd64d7ef8e9..00000000000 --- a/src/instruments/src/SD/Pages/Wheel/config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "index": "./Wheel.tsx", - "isInteractive": false -} diff --git a/src/instruments/src/SD/PagesContainer.jsx b/src/instruments/src/SD/PagesContainer.jsx deleted file mode 100644 index 6f99c16fa21..00000000000 --- a/src/instruments/src/SD/PagesContainer.jsx +++ /dev/null @@ -1,39 +0,0 @@ -import { useState } from 'react'; -import { getSimVar, useInteractionEvent } from '../util.js'; -import { EngPage } from './Pages/Eng/Eng.tsx'; -import { BleedPage } from './Pages/Bleed/Bleed.tsx'; -import { PressPage } from './Pages/Press/Press.tsx'; -import { ElecPage } from './Pages/Elec/Elec.tsx'; -import { HydPage } from './Pages/Hyd/Hyd.tsx'; -import { FuelPage } from './Pages/Fuel/Fuel.tsx'; -import { ApuPage } from './Pages/Apu/Apu.tsx'; -import { CondPage } from './Pages/Cond/Cond.tsx'; -import { DoorPage } from './Pages/Door/Door.tsx'; -import { WheelPage } from './Pages/Wheel/Wheel.tsx'; -import { FctlPage } from './Pages/Fctl/Fctl.tsx'; -import { StatusPage } from './Pages/Status/Status.tsx'; -import { CrzPage } from './Pages/Crz/Crz.tsx'; - -export const PagesContainer = () => { - const [currentPage, setCurrentPage] = useState(0); - - useInteractionEvent('A32NX_SD_PAGE_CHANGED', () => setCurrentPage(getSimVar('L:A32NX_ECAM_SD_CURRENT_PAGE_INDEX', 'number'))); - - const pages = { - 0: , - 1: , - 2: , - 3: , - 4: , - 5: , - 6: , - 7: , - 8: , - 9: , - 10: , - 11: , - 12: , - }; - - return pages[currentPage] || invalid page; -}; diff --git a/src/instruments/src/SD/PagesContainer.tsx b/src/instruments/src/SD/PagesContainer.tsx new file mode 100644 index 00000000000..1d222447791 --- /dev/null +++ b/src/instruments/src/SD/PagesContainer.tsx @@ -0,0 +1,204 @@ +import React, { useState } from 'react'; +import { useUpdate } from '@instruments/common/hooks'; +import { useSimVar } from '@instruments/common/simVars'; +import { useArinc429Var } from '@instruments/common/arinc429'; +import { EngPage } from './Pages/Eng/Eng'; +import { BleedPage } from './Pages/Bleed/Bleed'; +import { PressPage } from './Pages/Press/Press'; +import { ElecPage } from './Pages/Elec/Elec'; +import { HydPage } from './Pages/Hyd/Hyd'; +import { FuelPage } from './Pages/Fuel/Fuel'; +import { ApuPage } from './Pages/Apu/Apu'; +import { CondPage } from './Pages/Cond/Cond'; +import { DoorPage } from './Pages/Door/Door'; +import { WheelPage } from './Pages/Wheel/Wheel'; +import { FctlPage } from './Pages/Fctl/Fctl'; +import { StatusPage } from './Pages/Status/Status'; +import { CrzPage } from './Pages/Crz/Crz'; + +export const PagesContainer = () => { + const [currentPage, setCurrentPage] = useState(8); + const [prevFailPage, setPrevFailPage] = useState(0); + const [ecamCycleInterval, setEcamCycleInterval] = useState(-1); + const [failPage] = useSimVar('L:A32NX_ECAM_SFAIL', 'Enum', 300); + + const [prevEcamAllButtonState, setPrevEcamAllButtonState] = useState(false); + + const [pageWhenUnselected, setPageWhenUnselected] = useState(8); + + const [ecamAllButtonPushed] = useSimVar('L:A32NX_ECAM_ALL_Push_IsDown', 'Bool', 100); + const [fwcFlightPhase] = useSimVar('L:A32NX_FWC_FLIGHT_PHASE', 'Enum', 500); + const [crzCondTimer, setCrzCondTimer] = useState(60); + const [ecamFCTLTimer, setEcamFCTLTimer] = useState(20); + const [mainEngineStarterOffTimer, setMainEngineStarterOffTimer] = useState(-1); + const [apuAboveThresholdTimer, setApuAboveThresholdTimer] = useState(-1); + const apuRpm = useArinc429Var('L:A32NX_APU_N', 100); + + const altitude = useArinc429Var('L:A32NX_ADIRS_ADR_1_ALTITUDE', 300); + + const [page, setPage] = useSimVar('L:A32NX_ECAM_SD_CURRENT_PAGE_INDEX', 'number', 50); + + const checkEnginePage = (deltaTime: number) => { + const engModeSel = SimVar.GetSimVarValue('L:XMLVAR_ENG_MODE_SEL', 'number'); + const eng1State = SimVar.GetSimVarValue('L:A32NX_ENGINE_STATE:1', 'number'); + const eng2State = SimVar.GetSimVarValue('L:A32NX_ENGINE_STATE:2', 'number'); + const oneEngOff = eng1State !== 1 || eng2State !== 1; + + if (engModeSel === 0 || (oneEngOff && engModeSel === 2) || mainEngineStarterOffTimer >= 0) { + // Show ENG until >10 seconds after both engines are fully started + if (engModeSel === 0 || (oneEngOff && engModeSel === 2)) { + setMainEngineStarterOffTimer(10); + } else if (mainEngineStarterOffTimer >= 0) { + setMainEngineStarterOffTimer((prev) => prev - deltaTime / 1000); + } + setPageWhenUnselected(0); + } + }; + + const checkApuPage = (deltaTime) => { + const currentAPUMasterState = SimVar.GetSimVarValue('L:A32NX_OVHD_APU_MASTER_SW_PB_IS_ON', 'Bool'); + + if (currentAPUMasterState && apuRpm.isNormalOperation() && (apuRpm.value <= 95 || apuAboveThresholdTimer >= 0)) { + // Show APU on Lower ECAM until 15s after RPM > 95% + if (apuAboveThresholdTimer <= 0 && apuRpm.value <= 95) { + setApuAboveThresholdTimer(15); + } else if (apuRpm.value > 95) { + setApuAboveThresholdTimer((prev) => prev - deltaTime / 1000); + } + setPageWhenUnselected(6); + } + }; + + const updateCallback = (deltaTime) => { + if (ecamAllButtonPushed && !prevEcamAllButtonState) { // button press + setPage((prev) => (prev + 1) % 12); + setCurrentPage((prev) => (prev + 1) % 12); + setEcamCycleInterval(setInterval(() => { + setCurrentPage((prev) => { + setPage((prev + 1) % 12); + return (prev + 1) % 12; + }); + }, 1000) as unknown as number); + } else if (!ecamAllButtonPushed && prevEcamAllButtonState) { // button release + clearInterval(ecamCycleInterval); + } else if (!ecamAllButtonPushed) { + const newPage = page; + if (newPage !== -1) { + setCurrentPage(newPage); + } else { + setCurrentPage(pageWhenUnselected); + } + + switch (fwcFlightPhase) { + case 10: + case 1: + setCrzCondTimer(60); + setPageWhenUnselected(8); + // TODO: Emergency Generator Test displays ELEC + // Needs system implementation (see A320_NEO_INTERIOR Component ID EMER_ELEC_PWR [LVar: L:A32NX_EMERELECPWR_GEN_TEST]) + checkApuPage(deltaTime); + checkEnginePage(deltaTime); + break; + case 2: + const sidestickPosX = SimVar.GetSimVarValue('L:A32NX_SIDESTICK_POSITION_X', 'Number'); + const sidestickPosY = SimVar.GetSimVarValue('L:A32NX_SIDESTICK_POSITION_Y', 'Number'); + const rudderPos = SimVar.GetSimVarValue('RUDDER PEDAL POSITION', 'Position'); + const controlsMoved = Math.abs(sidestickPosX) > 0.05 || Math.abs(sidestickPosY) > 0.05 || Math.abs(rudderPos) > 0.2; + + setPageWhenUnselected(9); + // When controls are moved > threshold, show FCTL page for 20s + if (controlsMoved) { + setPageWhenUnselected(10); + setEcamFCTLTimer(20); + } else if (ecamFCTLTimer >= 0) { + setPageWhenUnselected(10); + setEcamFCTLTimer((prev) => prev - deltaTime / 1000); + } + checkApuPage(deltaTime); + checkEnginePage(deltaTime); + break; + case 3: + case 4: + case 5: + setPageWhenUnselected(0); + break; + case 6: + case 7: + case 8: + case 9: + const isGearExtended = SimVar.GetSimVarValue('GEAR TOTAL PCT EXTENDED', 'percent') > 0.95; + const ToPowerSet = Math.max(SimVar.GetSimVarValue('L:A32NX_AUTOTHRUST_TLA:1', 'number'), + SimVar.GetSimVarValue('L:A32NX_AUTOTHRUST_TLA:2', 'number')) >= 35 && SimVar.GetSimVarValue('ENG N1 RPM:1', 'Percent') > 15 + && SimVar.GetSimVarValue('ENG N1 RPM:2', 'Percent') > 15; + const spoilerOrFlapsDeployed = SimVar.GetSimVarValue('L:A32NX_FLAPS_HANDLE_INDEX', 'number') !== 0 + || SimVar.GetSimVarValue('L:A32NX_SPOILERS_HANDLE_POSITION', 'percent') !== 0; + + if (isGearExtended && (altitude.value < 16000)) { + setPageWhenUnselected(9); + checkApuPage(deltaTime); + checkEnginePage(deltaTime); + break; + // Else check for CRZ + } + + if ((spoilerOrFlapsDeployed || ToPowerSet)) { + if (crzCondTimer <= 0) { + setPageWhenUnselected(12); + checkApuPage(deltaTime); + checkEnginePage(deltaTime); + } else { + setCrzCondTimer((prev) => prev - deltaTime / 1000); + } + } else if (!spoilerOrFlapsDeployed && !ToPowerSet) { + setPageWhenUnselected(12); + checkApuPage(deltaTime); + checkEnginePage(deltaTime); + } + break; + default: + // Sometimes happens when loading in, in which case we have to initialise pageNameWhenUnselected here. + setPageWhenUnselected(8); + break; + } + + if (failPage !== -1) { + setPageWhenUnselected(failPage); + + // Disable user selected page when new failure detected + if (prevFailPage !== failPage) { + setCurrentPage(-1); + setPage(-1); + } + } + + // switch page when desired page was changed, or new Failure detected + if ((pageWhenUnselected !== newPage && page === -1) || (prevFailPage !== failPage)) { + setCurrentPage(pageWhenUnselected); + } + + setPrevFailPage(failPage); + } + + setPrevEcamAllButtonState(ecamAllButtonPushed); + }; + + useUpdate(updateCallback); + + const pages = { + 0: , + 1: , + 2: , + 3: , + 4: , + 5: , + 6: , + 7: , + 8: , + 9: , + 10: , + 11: , + 12: , + }; + + return pages[currentPage] || invalid page; +}; diff --git a/src/instruments/src/SD/StatusArea/StatusArea.jsx b/src/instruments/src/SD/StatusArea/StatusArea.jsx deleted file mode 100644 index 6444f1f9637..00000000000 --- a/src/instruments/src/SD/StatusArea/StatusArea.jsx +++ /dev/null @@ -1,102 +0,0 @@ -/** - * WARNING - * - * CODE IN THIS FILE IS OLD. THIS STATUS AREA WAS UNUSED AND THE ORIGINAL ASOBO - * STATUS AREA WAS EXTENDED FURTHER. WHEN STARTING TO USE THIS COMPONENT. PLEASE - * PORT ANY FUNCTIONALITY FOUND ON THE ORIGINAL STATUS AREA. - */ - -import './StatusArea.scss'; -import { Text } from '../Text/Text.jsx'; -import { useGlobalVar, getSimVar } from '../../util.js'; - -export const StatusArea = () => { - const gw = getSimVar('TOTAL WEIGHT', 'kg'); - const zulu = useGlobalVar('ZULU TIME', 'seconds'); - let tat = Math.round(getSimVar('TOTAL AIR TEMPERATURE', 'celsius')); - if (tat > 99 || tat < -99) { - tat = tat > 99 ? 99 : -99; - } - let sat = Math.round(getSimVar('AMBIENT TEMPERATURE', 'celsius')); - if (sat > 99 || sat < -99) { - sat = sat > 99 ? 99 : -99; - } - - // TODO FIXME improve this - // const adirsAlign = !ADIRS.mapNotAvailable(1) || !ADIRS.mapNotAvailable(2); - const adirsAlign = true; - - const satPrefix = sat > 0 ? '+' : ''; - const tatPrefix = tat > 0 ? '+' : ''; - const seconds = Math.floor(zulu); - const hours = Math.floor(seconds / 3600); - const minutes = Math.floor((seconds - (hours * 3600)) / 60); - const padMinutes = String(minutes).padStart(2, '0'); - const padHours = String(hours).padStart(2, '0'); - - return ( - <> - - - - - {/* Temperatures */} - - - TAT - - { adirsAlign - ? ( - - XX - - ) - : ( - - {tatPrefix} - {tat} - - )} - - °C - - - - SAT - - { adirsAlign - ? ( - - XX - - ) - : ( - - {satPrefix} - {sat} - - )} - - °C - - - {/* Time */} - - {padHours} - H - {padMinutes} - - {/* Gross weight */} - - - GW - - - {Math.round(gw)} - - - KG - - - ); -}; diff --git a/src/instruments/src/SD/StatusArea/StatusArea.scss b/src/instruments/src/SD/StatusArea/StatusArea.scss index eb4c81658b7..646ede1c464 100644 --- a/src/instruments/src/SD/StatusArea/StatusArea.scss +++ b/src/instruments/src/SD/StatusArea/StatusArea.scss @@ -2,3 +2,14 @@ stroke: white; stroke-width: 3; } + +#StatusArea { + display: block; + position: absolute; + bottom: 0%; + left: 0%; + width: 100%; + height: 20%; + + font-family: "Ecam", monospace !important; +} diff --git a/src/instruments/src/SD/StatusArea/StatusArea.tsx b/src/instruments/src/SD/StatusArea/StatusArea.tsx new file mode 100644 index 00000000000..b5abf1503ab --- /dev/null +++ b/src/instruments/src/SD/StatusArea/StatusArea.tsx @@ -0,0 +1,248 @@ +/** + * WARNING + * + * CODE IN THIS FILE IS OLD. THIS STATUS AREA WAS UNUSED AND THE ORIGINAL ASOBO + * STATUS AREA WAS EXTENDED FURTHER. WHEN STARTING TO USE THIS COMPONENT. PLEASE + * PORT ANY FUNCTIONALITY FOUND ON THE ORIGINAL STATUS AREA. + */ + +import './StatusArea.scss'; +import React, { useEffect, useState } from 'react'; +import { useGlobalVar, useSimVar } from '@instruments/common/simVars'; +import { getSupplier } from '@instruments/common/utils'; +import { useArinc429Var } from '@instruments/common/arinc429'; +import { NXLogicConfirmNode, NXLogicMemoryNode } from '@instruments/common/NXLogic'; +import { useUpdate } from '@instruments/common/hooks'; +import { NXUnits } from '@instruments/common/NXUnits'; +import { Text } from '../Text/Text'; + +export const StatusArea = () => { + const [gwDisplayedValue, setGwDisplayedValue] = useState('0'); + + const [gwDisplayedUnit, setGwDisplayedUnit] = useState('kg'); + + const zulu = useGlobalVar('ZULU TIME', 'seconds', 60000); + + const [airDataSwitch] = useSimVar('L:A32NX_AIR_DATA_SWITCHING_KNOB', 'enum', 200); + const [attHdgSwitch] = useSimVar('L:A32NX_ATT_HDG_SWITCHING_KNOB', 'enum', 200); + + const [eng1Running] = useSimVar('ENG COMBUSTION:1', 'bool', 1000); + const [eng2Running] = useSimVar('ENG COMBUSTION:2', 'bool', 1000); + + const [isaVisible, setIsaVisible] = useState(false); + + const [airDataReferenceSource, setAirDataSource] = useState(0); + const [inertialReferenceSource, setInertialSource] = useState(0); + const [loadFactorVisibleElement, setLoadFactorVisibleElement] = useState(false); + const [loadFactorText, setLoadFactorText] = useState(''); + + const sat = useArinc429Var(`L:A32NX_ADIRS_ADR_${airDataReferenceSource}_STATIC_AIR_TEMPERATURE`, 6000); + const tat = useArinc429Var(`L:A32NX_ADIRS_ADR_${airDataReferenceSource}_TOTAL_AIR_TEMPERATURE`, 6000); + const isa = useArinc429Var(`L:A32NX_ADIRS_ADR_${airDataReferenceSource}_INTERNATIONAL_STANDARD_ATMOSPHERE_DELTA`, 6000); + const loadFactor = useArinc429Var(`L:A32NX_ADIRS_IR_${inertialReferenceSource}_BODY_NORMAL_ACC`, 300); + + const [loadFactorSet] = useState(new NXLogicConfirmNode(2)); + const [loadFactorReset] = useState(new NXLogicConfirmNode(5)); + const [loadFactorVisible] = useState(new NXLogicMemoryNode()); + + useEffect(() => { + setAirDataSource(getSupplier(undefined, airDataSwitch)); + }, [airDataSwitch]); + + useEffect(() => { + setInertialSource(getSupplier(undefined, attHdgSwitch)); + }, [attHdgSwitch]); + + useUpdate((deltaTime) => { + const conditionsMet = loadFactor.value > 1.4 || loadFactor.value < 0.7; + const loadFactorSetValue = loadFactorSet.write(conditionsMet && loadFactor.isNormalOperation(), deltaTime); + const loadFactorResetValue = loadFactorReset.write(!conditionsMet || !loadFactor.isNormalOperation(), deltaTime); + const flightPhase = SimVar.GetSimVarValue('L:A32NX_FWC_FLIGHT_PHASE', 'Enum'); + + setLoadFactorVisibleElement( + flightPhase >= 4 + && flightPhase <= 8 + && loadFactorVisible.write(loadFactorSetValue, loadFactorResetValue), + ); + + let loadFactorText = 'XX'; + if (loadFactor.isNormalOperation()) { + const clamped = Math.min(Math.max(loadFactor.value, -3), 5); + loadFactorText = (clamped >= 0 ? '+' : '') + clamped.toFixed(1); + } + setLoadFactorText(loadFactorText); + }); + + useEffect(() => { + const baroMode = SimVar.GetSimVarValue('L:XMLVAR_Baro1_Mode', 'number'); + const isInStdMode = baroMode !== 0 && baroMode !== 1; + // As ISA relates to SAT, we cannot present ISA when SAT is unavailable. We might want to move this into + // Rust ADIRS code itself. + const isaShouldBeVisible = isInStdMode && isa.isNormalOperation() && sat.isNormalOperation(); + setIsaVisible(isaShouldBeVisible); + // this.isaContainer.setAttribute('visibility', isaShouldBeVisible ? 'visible' : 'hidden'); + + // this.setValueOnTemperatureElement(Math.round(isa.value), this.isaText); + }, [isa, sat]); + + /* let tat = Math.round(useSimVar('TOTAL AIR TEMPERATURE', 'celsius', 6000)[0]); + if (tat > 99 || tat < -99) { + tat = tat > 99 ? 99 : -99; + } + let sat = Math.round(useSimVar('AMBIENT TEMPERATURE', 'celsius', 6000)[0]); + if (sat > 99 || sat < -99) { + sat = sat > 99 ? 99 : -99; + } */ + + const satPrefix = sat.value > 0 ? '+' : ''; + const tatPrefix = tat.value > 0 ? '+' : ''; + const seconds = Math.floor(zulu); + const hours = Math.floor(seconds / 3600); + const minutes = Math.floor((seconds - (hours * 3600)) / 60); + const padMinutes = String(minutes).padStart(2, '0'); + const padHours = String(hours).padStart(2, '0'); + + const getPayloadWeight = (unit: string, payloadCount: number) => { + let payloadWeight = 0; + for (let i = 1; i <= payloadCount; i++) { + payloadWeight += SimVar.GetSimVarValue(`PAYLOAD STATION WEIGHT:${i}`, unit); + } + return payloadWeight; + }; + + useUpdate((_deltaTime) => { + const fuelWeight = SimVar.GetSimVarValue('FUEL TOTAL QUANTITY WEIGHT', 'kg'); + const emptyWeight = SimVar.GetSimVarValue('EMPTY WEIGHT', 'kg'); + const payloadCount = SimVar.GetSimVarValue('PAYLOAD STATION COUNT', 'number'); + + const gwUnit = NXUnits.userWeightUnit(); + const payloadWeight = getPayloadWeight(gwUnit, payloadCount); + const gw = Math.round(NXUnits.kgToUser(emptyWeight + fuelWeight + payloadWeight)); + + // if ((gw != this.currentGW) || (this.isOneEngineRunning != isOneEngineRunning) || _force) { + // this.currentGW = gw; + // this.isOneEngineRunning = isOneEngineRunning; + + if (eng1Running || eng2Running && gw != null) { + // Lower EICAS displays GW in increments of 100 + setGwDisplayedValue((Math.floor(gw / 100) * 100).toString()); + /* this.gwValue.classList.add('Value'); + this.gwValue.classList.remove('Cyan'); + this.gwValue.textContent = (Math.floor(gw / 100) * 100).toString(); */ + } else { + setGwDisplayedValue('--'); + } + setGwDisplayedUnit(gwUnit); + + /* if (gwUnit != this.currentGwUnit) { + this.currentGwUnit = gwUnit; + if (this.gwUnit != null) { + this.gwUnit.textContent = gwUnit; + } + } */ + }); + + return ( +
+ + + + + + + {/* Temperatures */} + + + TAT + + { !tat.isNormalOperation() + ? ( + + XX + + ) + : ( + + {tatPrefix} + {Math.round(tat.value)} + + )} + + °C + + + + SAT + + { !sat.isNormalOperation() + ? ( + + XX + + ) + : ( + + {satPrefix} + {Math.round(sat.value)} + + )} + + °C + + + {/* Time */} + + {padHours} + H + {padMinutes} + + {/* Gross weight */} + {(eng1Running || eng2Running) && ( + <> + + GW + + + {gwDisplayedValue} + + + {gwDisplayedUnit} + + + )} + + {!eng1Running && !eng2Running && ( + <> + + GW + + + {gwDisplayedValue} + + + {gwDisplayedUnit} + + + )} + + {/* ISA */} + {isaVisible && ( + <> + ISA + {Math.round(isa.value)} + °C + + + )} + + {loadFactorVisibleElement && ( + + G LOAD + {loadFactorText} + + )} + + +
+ ); +}; diff --git a/src/instruments/src/SD/Text/Text.scss b/src/instruments/src/SD/Text/Text.scss index 4976a92ed7b..c0f5b2d7b93 100644 --- a/src/instruments/src/SD/Text/Text.scss +++ b/src/instruments/src/SD/Text/Text.scss @@ -1,4 +1,4 @@ -@import "../../Common/definitions"; +@import "../Common/definitions.scss"; text.text-unit { fill: $display-cyan; @@ -24,4 +24,4 @@ text.text-big-value { text.text-title { fill: $display-white; font-size: $font-size-xlarge; -} \ No newline at end of file +} diff --git a/src/instruments/src/SD/Text/Text.jsx b/src/instruments/src/SD/Text/Text.tsx similarity index 97% rename from src/instruments/src/SD/Text/Text.jsx rename to src/instruments/src/SD/Text/Text.tsx index c80575c8077..94752c9ae4f 100644 --- a/src/instruments/src/SD/Text/Text.jsx +++ b/src/instruments/src/SD/Text/Text.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import './Text.scss'; export const Text = (props) => { diff --git a/src/instruments/src/SD/config.json b/src/instruments/src/SD/config.json index 899622d8f02..b6d30d46d50 100644 --- a/src/instruments/src/SD/config.json +++ b/src/instruments/src/SD/config.json @@ -1,4 +1,4 @@ { - "index": "./index.jsx", + "index": "./index.tsx", "isInteractive": false } diff --git a/src/instruments/src/SD/index.jsx b/src/instruments/src/SD/index.jsx deleted file mode 100644 index 1a44310b260..00000000000 --- a/src/instruments/src/SD/index.jsx +++ /dev/null @@ -1,85 +0,0 @@ -import ReactDOM from 'react-dom'; -import { useState } from 'react'; -import { - renderTarget, - useInteractionEvent, - useUpdate, - getSimVar, -} from '../util.js'; -import './style.scss'; -import { PagesContainer } from './PagesContainer.jsx'; -import { StatusArea } from './StatusArea/StatusArea.jsx'; - -function powerAvailable() { - return getSimVar('L:A32NX_ELEC_AC_2_BUS_IS_POWERED', 'Bool'); -} - -function SelfTest() { - return ( - - SELF TEST IN PROGRESS - (MAX 10 SECONDS) - - ); -} - -function Idle() { - const [inop, setInop] = useState(false); - - useInteractionEvent('A32NX_DCDU_BTN_INOP', () => { - if (!inop) { - setInop(true); - setTimeout(() => { - setInop(false); - }, 3000); - } - }); - - return ( - <> - - - - - - ); -} - -function SD() { - const [state, setState] = useState('DEFAULT'); - - useUpdate((_deltaTime) => { - if (state === 'OFF') { - if (powerAvailable()) { - setState('ON'); - } - } else if (!powerAvailable()) { - setState('OFF'); - } - }); - - switch (state) { - case 'DEFAULT': - if (getSimVar('L:A32NX_COLD_AND_DARK_SPAWN')) { - setState('OFF'); - } else { - setState('IDLE'); - } - return <>; - case 'OFF': - return <>; - case 'ON': - setTimeout(() => { - if (powerAvailable()) { - setState('IDLE'); - } - }, 8000); - return ; - case 'IDLE': - return ; - default: - throw new RangeError(); - } -} - -ReactDOM.render(, renderTarget); diff --git a/src/instruments/src/SD/index.tsx b/src/instruments/src/SD/index.tsx new file mode 100644 index 00000000000..12b6afa1bd7 --- /dev/null +++ b/src/instruments/src/SD/index.tsx @@ -0,0 +1,55 @@ +import { DisplayUnit } from '@instruments/common/displayUnit'; +import React, { useEffect, useState } from 'react'; +import { render } from '@instruments/common/index'; +import { useInteractionEvent } from '@instruments/common/hooks'; +import './style.scss'; + +import { useSimVar } from '@instruments/common/simVars'; +import { PagesContainer } from './PagesContainer'; +import { StatusArea } from './StatusArea/StatusArea'; + +const Idle = () => { + const [inop, setInop] = useState(false); + + const [doorVideoEnabledNow] = useSimVar('L:A32NX_OVHD_COCKPITDOORVIDEO_TOGGLE', 'Bool'); + const [doorVideoPressedNow] = useSimVar('L:PUSH_DOORPANEL_VIDEO', 'Bool'); + const [doorVideoVisible, setDoorVideoVisible] = useState(false); + + useEffect(() => { + if (doorVideoEnabledNow && doorVideoPressedNow) { + setDoorVideoVisible(true); + } else { + setDoorVideoVisible(false); + } + }, [doorVideoEnabledNow, doorVideoPressedNow]); + + useInteractionEvent('A32NX_DCDU_BTN_INOP', () => { + if (!inop) { + setInop(true); + setTimeout(() => { + setInop(false); + }, 3000); + } + }); + + return ( +
+ + + + + {doorVideoVisible && (
)} + + +
+ ); +}; + +render( + + + , +); diff --git a/src/instruments/src/SD/style.scss b/src/instruments/src/SD/style.scss index 0428b9fbec7..5aa3e4b4459 100644 --- a/src/instruments/src/SD/style.scss +++ b/src/instruments/src/SD/style.scss @@ -7,21 +7,31 @@ } .sd-svg { - position: absolute; - width: 768px; - height: 768px; - - background: radial-gradient( - ellipse at center, - rgba(13, 20, 35, 1) 0%, - rgb(13, 20, 35) 100% - ); - visibility: visible !important; font-family: "Ecam", monospace !important; } -text { - stroke-width: 0; +:root { + --bodyHeightScale: 1; +} + + +#Mainframe { + top: 0; + left: 0; + width: 100%; + height: 100%; + display: block; + position: relative; +} + +#door-video-wrapper { + position: absolute; + top: -5%; + width: 100%; + height: 82%; + z-index: 100; + background-image: url(/Pages/VCockpit/Instruments/A32NX/SD/DoorVideoResources/empty.png); + background-size: cover; }