From 332a74ea768287c3e6aa0c28cbc8b72194438720 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Sat, 25 Jun 2022 02:17:32 +0200 Subject: [PATCH] [MIRROR] Adds Prettierx - or how I broke TGUI for the nth time [MDB IGNORE] (#14475) * Adds Prettierx - or how I broke TGUI for the nth time * fuck Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com> Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com> --- .editorconfig | 5 +- .vscode/extensions.json | 3 +- .vscode/settings.json | 27 +- tgui/.eslintrc.yml | 54 +- tgui/.prettierignore | 15 + tgui/.prettierrc.yml | 5 +- tgui/.yarn/sdks/eslint/lib/api.js | 6 +- tgui/.yarn/sdks/prettier/index.js | 20 + tgui/.yarn/sdks/prettier/package.json | 6 + tgui/.yarn/sdks/typescript/lib/tsserver.js | 90 +- .../sdks/typescript/lib/tsserverlibrary.js | 90 +- tgui/babel.config.js | 5 +- tgui/jest.config.js | 4 +- tgui/package.json | 9 +- tgui/packages/common/collections.spec.ts | 18 +- tgui/packages/common/collections.ts | 104 +- tgui/packages/common/color.js | 12 +- tgui/packages/common/events.js | 7 +- tgui/packages/common/fp.js | 4 +- tgui/packages/common/math.ts | 8 +- tgui/packages/common/perf.js | 3 +- tgui/packages/common/random.ts | 5 +- tgui/packages/common/react.ts | 3 +- tgui/packages/common/redux.js | 16 +- tgui/packages/common/storage.js | 16 +- tgui/packages/common/string.babel-plugin.cjs | 8 +- tgui/packages/common/string.js | 34 +- tgui/packages/common/types.ts | 1 + tgui/packages/common/uuid.js | 3 +- tgui/packages/common/vector.js | 10 +- tgui/packages/tgfont/mkdist.cjs | 3 +- tgui/packages/tgui-bench/entrypoint.tsx | 3 +- tgui/packages/tgui-bench/index.js | 6 +- tgui/packages/tgui-bench/lib/benchmark.js | 1 + .../packages/tgui-bench/tests/Button.test.tsx | 22 +- .../tgui-bench/tests/DisposalUnit.test.tsx | 8 +- tgui/packages/tgui-bench/tests/Flex.test.tsx | 4 +- tgui/packages/tgui-bench/tests/Stack.test.tsx | 4 +- .../tgui-bench/tests/Tooltip.test.tsx | 4 +- tgui/packages/tgui-dev-server/dreamseeker.js | 14 +- tgui/packages/tgui-dev-server/link/client.cjs | 30 +- tgui/packages/tgui-dev-server/link/retrace.js | 16 +- tgui/packages/tgui-dev-server/link/server.js | 9 +- tgui/packages/tgui-dev-server/logging.js | 10 +- tgui/packages/tgui-dev-server/reloader.js | 26 +- tgui/packages/tgui-dev-server/util.js | 3 +- tgui/packages/tgui-dev-server/webpack.js | 6 +- tgui/packages/tgui-dev-server/winreg.js | 7 +- tgui/packages/tgui-panel/Notifications.js | 27 +- tgui/packages/tgui-panel/Panel.js | 31 +- .../tgui-panel/audio/NowPlayingWidget.js | 29 +- tgui/packages/tgui-panel/audio/hooks.js | 2 +- tgui/packages/tgui-panel/audio/middleware.js | 4 +- tgui/packages/tgui-panel/audio/player.js | 6 +- tgui/packages/tgui-panel/audio/selectors.js | 2 +- .../tgui-panel/chat/ChatPageSettings.js | 76 +- tgui/packages/tgui-panel/chat/ChatPanel.js | 28 +- tgui/packages/tgui-panel/chat/ChatTabs.js | 23 +- tgui/packages/tgui-panel/chat/constants.js | 9 +- tgui/packages/tgui-panel/chat/middleware.js | 44 +- tgui/packages/tgui-panel/chat/model.js | 18 +- tgui/packages/tgui-panel/chat/reducer.js | 8 +- tgui/packages/tgui-panel/chat/renderer.js | 96 +- .../tgui-panel/chat/replaceInTextNode.js | 34 +- tgui/packages/tgui-panel/chat/selectors.js | 16 +- tgui/packages/tgui-panel/game/hooks.js | 2 +- tgui/packages/tgui-panel/game/middleware.js | 10 +- tgui/packages/tgui-panel/game/selectors.js | 2 +- tgui/packages/tgui-panel/index.js | 3 +- tgui/packages/tgui-panel/panelFocus.js | 8 +- .../packages/tgui-panel/ping/PingIndicator.js | 8 +- tgui/packages/tgui-panel/ping/middleware.js | 4 +- tgui/packages/tgui-panel/ping/reducer.js | 9 +- tgui/packages/tgui-panel/ping/selectors.js | 2 +- tgui/packages/tgui-panel/reconnect.tsx | 28 +- .../tgui-panel/settings/SettingsPanel.js | 142 +- .../packages/tgui-panel/settings/constants.js | 3 +- tgui/packages/tgui-panel/settings/hooks.js | 4 +- .../tgui-panel/settings/middleware.js | 22 +- .../packages/tgui-panel/settings/selectors.js | 4 +- .../tgui-panel/styles/goon/chat-dark.scss | 95 +- .../tgui-panel/styles/goon/chat-light.scss | 104 +- .../tgui-panel/styles/themes/light.scss | 65 +- tgui/packages/tgui-panel/telemetry.js | 8 +- tgui/packages/tgui-panel/themes.js | 2 +- tgui/packages/tgui-polyfill/00-html5shiv.js | 1 + tgui/packages/tgui-polyfill/01-ie8.js | 1 + tgui/packages/tgui-polyfill/02-dom4.js | 3 + tgui/packages/tgui-polyfill/03-css-om.js | 1 + tgui/packages/tgui-polyfill/10-misc.js | 1 + .../packages/tgui-say/components/dragzone.tsx | 10 +- tgui/packages/tgui-say/handlers/index.tsx | 2 +- tgui/packages/tgui-say/handlers/setSize.tsx | 6 +- tgui/packages/tgui-say/helpers/index.tsx | 6 +- tgui/packages/tgui-say/styles/button.scss | 3 +- tgui/packages/tgui-say/styles/colors.scss | 18 +- tgui/packages/tgui-say/styles/dragzone.scss | 3 +- tgui/packages/tgui-say/styles/modal.scss | 17 +- tgui/packages/tgui-say/styles/textarea.scss | 5 +- tgui/packages/tgui/assets.js | 8 +- tgui/packages/tgui/backend.ts | 103 +- .../tgui/components/AnimatedNumber.js | 3 +- tgui/packages/tgui/components/Autofocus.tsx | 2 +- tgui/packages/tgui/components/Blink.js | 13 +- tgui/packages/tgui/components/BlockQuote.js | 11 +- .../tgui/components/BodyZoneSelector.tsx | 168 +-- tgui/packages/tgui/components/Box.tsx | 62 +- tgui/packages/tgui/components/Button.js | 66 +- tgui/packages/tgui/components/ByondUi.js | 31 +- tgui/packages/tgui/components/Chart.js | 13 +- tgui/packages/tgui/components/Collapsible.js | 18 +- tgui/packages/tgui/components/ColorBox.js | 9 +- tgui/packages/tgui/components/Dimmer.js | 13 +- tgui/packages/tgui/components/Divider.js | 14 +- .../tgui/components/DraggableControl.js | 87 +- tgui/packages/tgui/components/Dropdown.js | 36 +- tgui/packages/tgui/components/FitText.tsx | 42 +- tgui/packages/tgui/components/Flex.tsx | 26 +- tgui/packages/tgui/components/Grid.js | 11 +- tgui/packages/tgui/components/Icon.js | 40 +- .../packages/tgui/components/InfinitePlane.js | 94 +- tgui/packages/tgui/components/Input.js | 25 +- tgui/packages/tgui/components/KeyListener.tsx | 14 +- tgui/packages/tgui/components/Knob.js | 42 +- .../tgui/components/LabeledControls.js | 25 +- tgui/packages/tgui/components/LabeledList.tsx | 38 +- tgui/packages/tgui/components/Modal.js | 14 +- tgui/packages/tgui/components/NoticeBox.js | 15 +- tgui/packages/tgui/components/NumberInput.js | 85 +- tgui/packages/tgui/components/ProgressBar.js | 16 +- tgui/packages/tgui/components/RoundGauge.js | 54 +- tgui/packages/tgui/components/Section.tsx | 12 +- tgui/packages/tgui/components/Slider.js | 43 +- tgui/packages/tgui/components/Stack.tsx | 6 +- tgui/packages/tgui/components/Table.js | 36 +- tgui/packages/tgui/components/Tabs.js | 42 +- tgui/packages/tgui/components/TextArea.js | 42 +- tgui/packages/tgui/components/TimeDisplay.js | 10 +- tgui/packages/tgui/components/Tooltip.tsx | 32 +- .../tgui/components/TrackOutsideClicks.tsx | 21 +- tgui/packages/tgui/constants.js | 184 +-- tgui/packages/tgui/debug/KitchenSink.js | 16 +- tgui/packages/tgui/debug/hooks.js | 2 +- tgui/packages/tgui/debug/middleware.js | 19 +- tgui/packages/tgui/debug/selectors.js | 2 +- tgui/packages/tgui/drag.js | 67 +- tgui/packages/tgui/events.js | 36 +- tgui/packages/tgui/format.js | 41 +- tgui/packages/tgui/hotkeys.ts | 16 +- tgui/packages/tgui/http.ts | 25 +- tgui/packages/tgui/index.js | 1 + .../tgui/interfaces/AbductorConsole.js | 78 +- .../tgui/interfaces/AccountingConsole.js | 52 +- tgui/packages/tgui/interfaces/Achievements.js | 98 +- tgui/packages/tgui/interfaces/Adminhelp.tsx | 83 +- .../tgui/interfaces/AdventureBrowser.tsx | 104 +- tgui/packages/tgui/interfaces/AiAirlock.js | 119 +- tgui/packages/tgui/interfaces/AiRestorer.js | 43 +- .../tgui/interfaces/AiVoiceChanger.js | 35 +- tgui/packages/tgui/interfaces/AirAlarm.js | 131 +- .../tgui/interfaces/AirlockElectronics.js | 111 +- tgui/packages/tgui/interfaces/AlertModal.tsx | 8 +- .../tgui/interfaces/AnomalyRefinery.js | 70 +- .../tgui/interfaces/AntagInfoBrainwashed.tsx | 39 +- .../tgui/interfaces/AntagInfoBrother.tsx | 31 +- .../tgui/interfaces/AntagInfoChangeling.tsx | 133 +- .../tgui/interfaces/AntagInfoDemon.tsx | 56 +- .../tgui/interfaces/AntagInfoGangmember.tsx | 53 +- .../tgui/interfaces/AntagInfoGeneric.tsx | 30 +- .../tgui/interfaces/AntagInfoHeretic.tsx | 168 +-- .../tgui/interfaces/AntagInfoMalf.tsx | 117 +- .../tgui/interfaces/AntagInfoMorph.tsx | 37 +- .../tgui/interfaces/AntagInfoNightmare.tsx | 69 +- .../tgui/interfaces/AntagInfoSeparatist.tsx | 61 +- .../tgui/interfaces/AntagInfoThief.tsx | 37 +- .../tgui/interfaces/AntagInfoTraitor.tsx | 120 +- .../tgui/interfaces/AntagInfoWizard.tsx | 63 +- tgui/packages/tgui/interfaces/Apc.js | 124 +- tgui/packages/tgui/interfaces/ApcControl.js | 136 +- .../tgui/interfaces/ApprenticeContract.tsx | 44 +- tgui/packages/tgui/interfaces/Aquarium.js | 28 +- .../tgui/interfaces/AtmosAlertConsole.js | 22 +- .../tgui/interfaces/AtmosControlConsole.tsx | 40 +- .../tgui/interfaces/AtmosControlPanel.js | 93 +- tgui/packages/tgui/interfaces/AtmosFilter.js | 36 +- tgui/packages/tgui/interfaces/AtmosMixer.js | 43 +- tgui/packages/tgui/interfaces/AtmosPump.js | 43 +- .../packages/tgui/interfaces/AtmosTempGate.js | 25 +- .../packages/tgui/interfaces/AtmosTempPump.js | 25 +- tgui/packages/tgui/interfaces/Autolathe.js | 147 +- .../tgui/interfaces/AutomatedAnnouncement.js | 58 +- .../tgui/interfaces/AuxBaseConsole.js | 58 +- tgui/packages/tgui/interfaces/BankMachine.js | 24 +- tgui/packages/tgui/interfaces/Bepis.js | 54 +- tgui/packages/tgui/interfaces/Biogenerator.js | 130 +- .../tgui/interfaces/BlackMarketUplink.js | 95 +- tgui/packages/tgui/interfaces/BloodFilter.js | 11 +- .../tgui/interfaces/BluespaceArtillery.js | 38 +- .../tgui/interfaces/BluespaceLocator.js | 73 +- .../tgui/interfaces/BluespaceSender.js | 61 +- .../tgui/interfaces/BluespaceVendor.js | 87 +- tgui/packages/tgui/interfaces/BorgHypo.tsx | 40 +- tgui/packages/tgui/interfaces/BorgPanel.js | 102 +- tgui/packages/tgui/interfaces/BorgShaker.tsx | 52 +- tgui/packages/tgui/interfaces/BountyBoard.js | 147 +- tgui/packages/tgui/interfaces/BrigTimer.js | 40 +- tgui/packages/tgui/interfaces/CTFPanel.js | 34 +- .../packages/tgui/interfaces/CameraConsole.js | 93 +- tgui/packages/tgui/interfaces/Canister.js | 136 +- tgui/packages/tgui/interfaces/Canvas.tsx | 141 +- tgui/packages/tgui/interfaces/Cargo.js | 337 +++-- tgui/packages/tgui/interfaces/CargoExpress.js | 28 +- .../tgui/interfaces/CargoHoldTerminal.js | 33 +- .../tgui/interfaces/CellularEmporium.tsx | 80 +- .../tgui/interfaces/CentcomPodLauncher.js | 493 ++++--- .../packages/tgui/interfaces/ChameleonCard.js | 19 +- tgui/packages/tgui/interfaces/Changelog.js | 226 +-- .../tgui/interfaces/ChemAcclimator.js | 34 +- .../tgui/interfaces/ChemDebugSynthesizer.js | 99 +- .../packages/tgui/interfaces/ChemDispenser.js | 216 +-- tgui/packages/tgui/interfaces/ChemFilter.js | 46 +- tgui/packages/tgui/interfaces/ChemHeater.js | 228 ++-- tgui/packages/tgui/interfaces/ChemMaster.js | 271 ++-- tgui/packages/tgui/interfaces/ChemPress.js | 80 +- .../tgui/interfaces/ChemReactionChamber.js | 145 +- .../tgui/interfaces/ChemRecipeDebug.js | 273 ++-- tgui/packages/tgui/interfaces/ChemSplitter.js | 36 +- .../tgui/interfaces/ChemSynthesizer.js | 26 +- .../tgui/interfaces/CircuitAccessChecker.js | 47 +- .../tgui/interfaces/CircuitAdminPanel.tsx | 61 +- .../packages/tgui/interfaces/CircuitModule.js | 95 +- .../tgui/interfaces/CircuitSignalHandler.tsx | 83 +- .../tgui/interfaces/CivCargoHoldTerminal.js | 99 +- tgui/packages/tgui/interfaces/Clipboard.js | 58 +- tgui/packages/tgui/interfaces/CodexGigas.js | 95 +- .../tgui/interfaces/ColorBlindTester.js | 32 +- .../tgui/interfaces/ColorMatrixEditor.js | 30 +- .../tgui/interfaces/CommandReport.tsx | 9 +- .../tgui/interfaces/CommunicationsConsole.js | 505 +++---- .../tgui/interfaces/ComponentPrinter.tsx | 142 +- .../tgui/interfaces/ComputerFabricator.js | 251 ++-- tgui/packages/tgui/interfaces/Crayon.js | 31 +- tgui/packages/tgui/interfaces/CrewConsole.js | 50 +- tgui/packages/tgui/interfaces/CrewManifest.js | 44 +- tgui/packages/tgui/interfaces/Cryo.js | 68 +- tgui/packages/tgui/interfaces/Crystallizer.js | 38 +- .../tgui/interfaces/CyborgBootDebug.js | 105 +- .../packages/tgui/interfaces/DecalPainter.tsx | 12 +- .../tgui/interfaces/DepartmentOrders.tsx | 134 +- .../tgui/interfaces/DestinationTagger.tsx | 4 +- tgui/packages/tgui/interfaces/DisposalUnit.js | 46 +- .../DnaConsole/DnaConsoleEnzymes.js | 249 ++-- .../DnaConsole/DnaConsoleSequencer.js | 166 ++- .../DnaConsole/DnaConsoleStorage.js | 98 +- .../tgui/interfaces/DnaConsole/DnaScanner.js | 59 +- .../interfaces/DnaConsole/MutationInfo.js | 225 +-- .../tgui/interfaces/DnaConsole/index.js | 88 +- tgui/packages/tgui/interfaces/DnaVault.js | 36 +- tgui/packages/tgui/interfaces/DopplerArray.js | 37 +- .../packages/tgui/interfaces/EightBallVote.js | 45 +- tgui/packages/tgui/interfaces/Electrolyzer.js | 26 +- tgui/packages/tgui/interfaces/Electropack.js | 61 +- .../interfaces/EmergencyShuttleConsole.js | 54 +- .../tgui/interfaces/EngravedMessage.js | 34 +- .../tgui/interfaces/ExodroneConsole.tsx | 658 ++++----- .../tgui/interfaces/ExoscannerConsole.tsx | 180 ++- .../tgui/interfaces/ExosuitControlConsole.js | 99 +- .../tgui/interfaces/ExosuitFabricator.js | 298 ++-- .../tgui/interfaces/ExperimentConfigure.js | 157 ++- .../packages/tgui/interfaces/FilingCabinet.js | 28 +- tgui/packages/tgui/interfaces/Filteriffic.js | 249 ++-- tgui/packages/tgui/interfaces/FishCatalog.tsx | 86 +- tgui/packages/tgui/interfaces/Fishing.tsx | 181 +-- .../tgui/interfaces/FishingCalculator.tsx | 99 +- .../interfaces/FishingPortalGenerator.tsx | 24 +- tgui/packages/tgui/interfaces/FishingRod.tsx | 79 +- tgui/packages/tgui/interfaces/Folder.js | 22 +- .../packages/tgui/interfaces/ForbiddenLore.js | 45 +- tgui/packages/tgui/interfaces/GasAnalyzer.tsx | 10 +- tgui/packages/tgui/interfaces/Gateway.js | 50 +- .../tgui/interfaces/GhostPoolProtection.js | 39 +- .../tgui/interfaces/GlandDispenser.js | 22 +- tgui/packages/tgui/interfaces/Gps.js | 81 +- .../tgui/interfaces/GravityGenerator.js | 52 +- .../tgui/interfaces/GreyscaleModifyMenu.tsx | 280 ++-- .../tgui/interfaces/GulagItemReclaimer.js | 29 +- .../tgui/interfaces/GulagTeleporterConsole.js | 50 +- tgui/packages/tgui/interfaces/HoloPay.tsx | 7 +- tgui/packages/tgui/interfaces/Holodeck.js | 41 +- tgui/packages/tgui/interfaces/Holopad.js | 100 +- tgui/packages/tgui/interfaces/HotkeysHelp.tsx | 84 +- .../tgui/interfaces/Hypertorus/Controls.js | 86 +- .../tgui/interfaces/Hypertorus/Gases.js | 121 +- .../tgui/interfaces/Hypertorus/Parameters.js | 58 +- .../tgui/interfaces/Hypertorus/Recipes.js | 166 +-- .../interfaces/Hypertorus/Temperatures.js | 190 ++- .../tgui/interfaces/Hypertorus/helpers.js | 6 +- .../tgui/interfaces/Hypertorus/index.js | 21 +- tgui/packages/tgui/interfaces/HypnoChair.js | 65 +- tgui/packages/tgui/interfaces/IVDrip.js | 32 +- tgui/packages/tgui/interfaces/ImplantChair.js | 50 +- .../tgui/interfaces/InfraredEmitter.js | 15 +- .../IntegratedCircuit/CircuitInfo.js | 11 +- .../IntegratedCircuit/ComponentMenu.js | 101 +- .../IntegratedCircuit/DisplayName.js | 27 +- .../IntegratedCircuit/FundamentalTypes.js | 15 +- .../IntegratedCircuit/ObjectComponent.js | 69 +- .../tgui/interfaces/IntegratedCircuit/Port.js | 64 +- .../IntegratedCircuit/VariableMenu.js | 96 +- .../interfaces/IntegratedCircuit/index.js | 174 ++- tgui/packages/tgui/interfaces/Intellicard.js | 39 +- tgui/packages/tgui/interfaces/Interview.js | 19 +- .../tgui/interfaces/InterviewManager.js | 36 +- tgui/packages/tgui/interfaces/Jukebox.js | 79 +- tgui/packages/tgui/interfaces/KeycardAuth.js | 9 +- .../tgui/interfaces/LaborClaimConsole.js | 40 +- tgui/packages/tgui/interfaces/LanguageMenu.js | 95 +- .../tgui/interfaces/LaunchpadConsole.js | 188 +-- .../tgui/interfaces/LaunchpadRemote.js | 20 +- .../tgui/interfaces/LibraryConsole.js | 529 ++++---- .../tgui/interfaces/LibraryScanner.js | 36 +- .../tgui/interfaces/LibraryVisitor.js | 100 +- tgui/packages/tgui/interfaces/Limbgrower.js | 51 +- .../tgui/interfaces/ListInputModal.tsx | 10 +- tgui/packages/tgui/interfaces/MODpaint.js | 91 +- tgui/packages/tgui/interfaces/MODsuit.js | 497 ++++--- tgui/packages/tgui/interfaces/MafiaPanel.js | 213 ++- .../interfaces/MalfunctionModulePicker.js | 14 +- .../tgui/interfaces/MassDriverControl.js | 66 +- tgui/packages/tgui/interfaces/MassSpec.js | 362 +++-- .../tgui/interfaces/MechBayPowerConsole.js | 81 +- .../tgui/interfaces/Mecha/AlertPane.tsx | 29 +- .../tgui/interfaces/Mecha/ArmPane.tsx | 215 ++- .../tgui/interfaces/Mecha/ArmorPane.tsx | 35 +- .../tgui/interfaces/Mecha/MaintMode.tsx | 152 ++- .../tgui/interfaces/Mecha/MechStatPane.tsx | 87 +- .../tgui/interfaces/Mecha/OperatorMode.tsx | 8 +- .../interfaces/Mecha/PowerModulesPane.tsx | 44 +- .../tgui/interfaces/Mecha/RadioPane.tsx | 38 +- .../interfaces/Mecha/UtilityModulesPane.tsx | 136 +- tgui/packages/tgui/interfaces/Mecha/data.ts | 26 +- tgui/packages/tgui/interfaces/Mecha/index.tsx | 4 +- .../tgui/interfaces/MechpadConsole.js | 68 +- tgui/packages/tgui/interfaces/MedicalKiosk.js | 191 +-- tgui/packages/tgui/interfaces/MemoryPanel.js | 53 +- tgui/packages/tgui/interfaces/Microscope.js | 43 +- .../packages/tgui/interfaces/MinigamesMenu.js | 9 +- tgui/packages/tgui/interfaces/MiningVendor.js | 41 +- tgui/packages/tgui/interfaces/Mule.js | 65 +- tgui/packages/tgui/interfaces/Newscaster.js | 413 +++--- tgui/packages/tgui/interfaces/NoticeBoard.js | 28 +- .../interfaces/NotificationPreferences.js | 10 +- tgui/packages/tgui/interfaces/NtnetRelay.js | 39 +- .../tgui/interfaces/NtosAiRestorer.js | 4 +- tgui/packages/tgui/interfaces/NtosArcade.js | 36 +- .../tgui/interfaces/NtosBountyBoard.js | 4 +- tgui/packages/tgui/interfaces/NtosCard.js | 168 ++- tgui/packages/tgui/interfaces/NtosCargo.js | 4 +- .../tgui/interfaces/NtosConfiguration.js | 38 +- .../tgui/interfaces/NtosCrewManifest.js | 17 +- .../interfaces/NtosCyborgRemoteMonitor.js | 118 +- .../NtosCyborgRemoteMonitorSyndicate.js | 5 +- .../tgui/interfaces/NtosFileManager.js | 89 +- .../tgui/interfaces/NtosJobManager.js | 60 +- tgui/packages/tgui/interfaces/NtosMain.js | 107 +- .../packages/tgui/interfaces/NtosMessenger.js | 84 +- tgui/packages/tgui/interfaces/NtosNetChat.js | 207 +-- tgui/packages/tgui/interfaces/NtosNetDos.js | 59 +- .../tgui/interfaces/NtosNetDownloader.js | 152 ++- .../tgui/interfaces/NtosNetMonitor.js | 121 +- tgui/packages/tgui/interfaces/NtosNotepad.js | 16 +- .../tgui/interfaces/NtosPhysScanner.js | 31 +- .../tgui/interfaces/NtosPortraitPrinter.js | 66 +- .../tgui/interfaces/NtosPowerMonitor.js | 4 +- tgui/packages/tgui/interfaces/NtosRadar.js | 92 +- .../tgui/interfaces/NtosRadarSyndicate.js | 7 +- tgui/packages/tgui/interfaces/NtosRecords.js | 139 +- .../tgui/interfaces/NtosRevelation.js | 27 +- .../tgui/interfaces/NtosRoboControl.js | 234 ++-- tgui/packages/tgui/interfaces/NtosRobotact.js | 184 ++- tgui/packages/tgui/interfaces/NtosScipaper.js | 58 +- tgui/packages/tgui/interfaces/NtosSecurEye.js | 38 +- tgui/packages/tgui/interfaces/NtosShipping.js | 29 +- tgui/packages/tgui/interfaces/NtosSignaler.js | 4 +- .../tgui/interfaces/NtosSkillTracker.js | 48 +- .../interfaces/NtosStationAlertConsole.js | 4 +- tgui/packages/tgui/interfaces/NtosStatus.js | 29 +- .../tgui/interfaces/NtosSupermatterMonitor.js | 4 +- tgui/packages/tgui/interfaces/NtosTechweb.js | 4 +- tgui/packages/tgui/interfaces/NuclearBomb.js | 45 +- .../tgui/interfaces/NumberInputModal.tsx | 11 +- .../tgui/interfaces/OperatingComputer.js | 74 +- tgui/packages/tgui/interfaces/Orbit.js | 132 +- tgui/packages/tgui/interfaces/OreBox.js | 20 +- .../tgui/interfaces/OreRedemptionMachine.js | 86 +- tgui/packages/tgui/interfaces/OrionGame.js | 385 +++--- tgui/packages/tgui/interfaces/OutfitEditor.js | 69 +- .../packages/tgui/interfaces/OutfitManager.js | 31 +- .../packages/tgui/interfaces/PaiInterface.tsx | 3 +- tgui/packages/tgui/interfaces/PaiSubmit.tsx | 3 +- .../tgui/interfaces/PaintingAdminPanel.tsx | 163 ++- .../tgui/interfaces/PaintingMachine.js | 112 +- tgui/packages/tgui/interfaces/Pandemic.tsx | 12 +- tgui/packages/tgui/interfaces/PaperSheet.js | 450 +++--- .../tgui/interfaces/PersonalCrafting.tsx | 77 +- tgui/packages/tgui/interfaces/Photocopier.js | 121 +- .../tgui/interfaces/PhysicalNewscaster.js | 8 +- .../packages/tgui/interfaces/PipeDispenser.js | 41 +- .../tgui/interfaces/PortableChemMixer.js | 140 +- .../tgui/interfaces/PortableGenerator.js | 54 +- tgui/packages/tgui/interfaces/PortablePump.js | 51 +- .../tgui/interfaces/PortableScrubber.js | 15 +- .../tgui/interfaces/PortableTurret.js | 60 +- .../tgui/interfaces/PortraitPicker.js | 71 +- tgui/packages/tgui/interfaces/PowerMonitor.js | 124 +- .../interfaces/PreferencesMenu/AntagsPage.tsx | 170 +-- .../CharacterPreferenceWindow.tsx | 43 +- .../PreferencesMenu/CharacterPreview.tsx | 2 +- .../PreferencesMenu/GamePreferenceWindow.tsx | 49 +- .../PreferencesMenu/GamePreferencesPage.tsx | 59 +- .../interfaces/PreferencesMenu/JobsPage.tsx | 216 ++- .../PreferencesMenu/KeybindingsPage.tsx | 208 ++- .../interfaces/PreferencesMenu/MainPage.tsx | 765 ++++++----- .../interfaces/PreferencesMenu/PageButton.tsx | 26 +- .../interfaces/PreferencesMenu/QuirksPage.tsx | 198 ++- .../PreferencesMenu/RandomizationButton.tsx | 37 +- .../ServerPreferencesFetcher.tsx | 26 +- .../PreferencesMenu/SpeciesPage.tsx | 226 ++- .../interfaces/PreferencesMenu/TabbedMenu.tsx | 48 +- .../antagonists/antagonists/abductor.ts | 8 +- .../antagonists/antagonists/blob.ts | 12 +- .../antagonists/antagonists/blobinfection.ts | 10 +- .../antagonists/antagonists/bloodbrother.ts | 8 +- .../antagonists/antagonists/changeling.ts | 8 +- .../antagonists/antagonists/clownoperative.ts | 10 +- .../antagonists/antagonists/cultist.ts | 8 +- .../antagonists/familyheadaspirant.ts | 10 +- .../antagonists/antagonists/fugitive.ts | 8 +- .../antagonists/antagonists/gangster.ts | 15 +- .../antagonists/headrevolutionary.ts | 16 +- .../antagonists/antagonists/heretic.ts | 11 +- .../antagonists/hereticsmuggler.ts | 10 +- .../antagonists/antagonists/loneoperative.ts | 10 +- .../antagonists/antagonists/malfai.ts | 15 +- .../antagonists/antagonists/malfaimidround.ts | 10 +- .../antagonists/antagonists/nightmare.ts | 8 +- .../antagonists/antagonists/obsessed.ts | 8 +- .../antagonists/antagonists/operative.ts | 8 +- .../antagonists/operativemidround.ts | 10 +- .../antagonists/antagonists/opportunist.ts | 10 +- .../antagonists/antagonists/provocateur.ts | 10 +- .../antagonists/antagonists/revenant.ts | 8 +- .../antagonists/sentientdisease.ts | 8 +- .../antagonists/antagonists/spacedragon.ts | 8 +- .../antagonists/antagonists/spaceninja.ts | 8 +- .../antagonists/syndicateinfiltrator.ts | 10 +- .../antagonists/syndicatesleeperagent.ts | 10 +- .../antagonists/antagonists/thief.ts | 11 +- .../antagonists/antagonists/traitor.ts | 11 +- .../antagonists/antagonists/wizard.ts | 11 +- .../antagonists/antagonists/wizardmidround.ts | 10 +- .../antagonists/antagonists/xenomorph.ts | 8 +- .../tgui/interfaces/PreferencesMenu/data.ts | 76 +- .../tgui/interfaces/PreferencesMenu/index.tsx | 18 +- .../tgui/interfaces/PreferencesMenu/names.tsx | 376 ++--- .../preferences/features/base.tsx | 327 ++--- .../features/character_preferences/age.tsx | 4 +- .../character_preferences/ai_core_display.tsx | 4 +- .../character_preferences/body_type.tsx | 4 +- .../character_preferences/glasses.tsx | 4 +- .../features/character_preferences/pda.tsx | 14 +- .../persistent_scars.tsx | 4 +- .../features/character_preferences/phobia.tsx | 4 +- .../playtime_reward_cloak.tsx | 5 +- .../security_department.tsx | 4 +- .../character_preferences/skin_tone.tsx | 68 +- .../character_preferences/uplink_loc.tsx | 4 +- .../features/game_preferences/admin.tsx | 28 +- .../game_preferences/ambient_occlusion.tsx | 8 +- .../game_preferences/auto_fit_viewport.tsx | 6 +- .../broadcast_login_logout.tsx | 8 +- .../game_preferences/buttons_locked.tsx | 8 +- .../game_preferences/darkened_flash.tsx | 8 +- .../game_preferences/fov_darkness.tsx | 9 +- .../features/game_preferences/fps.tsx | 39 +- .../features/game_preferences/ghost.tsx | 109 +- .../game_preferences/ghost_lighting.tsx | 8 +- .../features/game_preferences/hotkeys.tsx | 9 +- .../game_preferences/item_outlines.tsx | 8 +- .../game_preferences/legacy_chat_toggles.tsx | 66 +- .../game_preferences/legacy_toggles.tsx | 124 +- .../features/game_preferences/mod_select.tsx | 8 +- .../features/game_preferences/ooc.tsx | 8 +- .../features/game_preferences/parallax.tsx | 6 +- .../features/game_preferences/pixel_size.tsx | 16 +- .../game_preferences/preferred_map.tsx | 8 +- .../features/game_preferences/runechat.tsx | 26 +- .../game_preferences/scaling_method.tsx | 12 +- .../features/game_preferences/screentips.tsx | 12 +- .../features/game_preferences/tooltips.tsx | 12 +- .../features/game_preferences/ui_style.tsx | 53 +- .../features/game_preferences/widescreen.tsx | 6 +- .../game_preferences/window_flashing.tsx | 8 +- .../preferences/features/index.ts | 6 +- .../preferences/features/randomization.tsx | 85 +- .../preferences/features/species_features.tsx | 35 +- .../PreferencesMenu/preferences/gender.ts | 14 +- .../PreferencesMenu/useRandomToggleState.ts | 6 +- .../tgui/interfaces/ProbingConsole.js | 71 +- .../packages/tgui/interfaces/ProcCallMenu.tsx | 84 +- .../tgui/interfaces/ProduceConsole.js | 124 +- .../tgui/interfaces/ProximitySensor.js | 51 +- tgui/packages/tgui/interfaces/Puzzgrid.tsx | 115 +- tgui/packages/tgui/interfaces/Radio.js | 50 +- .../tgui/interfaces/RadioactiveMicrolaser.js | 47 +- .../tgui/interfaces/RapidPipeDispenser.js | 215 ++- tgui/packages/tgui/interfaces/Reagents.js | 261 ++-- .../packages/tgui/interfaces/ReligiousTool.js | 129 +- .../tgui/interfaces/RemoteRobotControl.js | 65 +- .../tgui/interfaces/RequestManager.js | 4 +- .../tgui/interfaces/RoboticsControlConsole.js | 122 +- tgui/packages/tgui/interfaces/Roulette.js | 145 +- .../tgui/interfaces/SDQLSpellAdminPanel.tsx | 63 +- .../packages/tgui/interfaces/SDQLSpellMenu.js | 150 +- tgui/packages/tgui/interfaces/Safe.js | 94 +- .../tgui/interfaces/SatelliteControl.js | 36 +- tgui/packages/tgui/interfaces/ScannerGate.js | 117 +- tgui/packages/tgui/interfaces/Secrets.js | 200 +-- .../packages/tgui/interfaces/SeedExtractor.js | 25 +- .../tgui/interfaces/SelectEquipment.js | 107 +- .../tgui/interfaces/SentienceFunBalloon.js | 31 +- .../packages/tgui/interfaces/ServerMonitor.js | 117 +- .../tgui/interfaces/ShuttleConsole.js | 156 +-- .../tgui/interfaces/ShuttleManipulator.js | 171 ++- tgui/packages/tgui/interfaces/Signaler.js | 52 +- tgui/packages/tgui/interfaces/SimpleBot.tsx | 16 +- tgui/packages/tgui/interfaces/SkillPanel.js | 66 +- tgui/packages/tgui/interfaces/SkillStation.js | 236 ++-- tgui/packages/tgui/interfaces/Sleeper.js | 55 +- .../tgui/interfaces/SlimeBodySwapper.js | 48 +- tgui/packages/tgui/interfaces/SmartVend.js | 56 +- tgui/packages/tgui/interfaces/Smes.js | 121 +- tgui/packages/tgui/interfaces/SmokeMachine.js | 44 +- tgui/packages/tgui/interfaces/SolarControl.js | 32 +- tgui/packages/tgui/interfaces/SpaceHeater.js | 83 +- .../tgui/interfaces/SparringContract.tsx | 186 ++- .../packages/tgui/interfaces/SpawnersMenu.tsx | 6 +- tgui/packages/tgui/interfaces/Spellbook.js | 355 ++--- tgui/packages/tgui/interfaces/Stack.js | 159 +-- .../tgui/interfaces/StackingConsole.js | 40 +- .../tgui/interfaces/StationAlertConsole.js | 78 +- .../tgui/interfaces/StationTraitsPanel.tsx | 227 ++-- tgui/packages/tgui/interfaces/StripMenu.tsx | 185 ++- .../tgui/interfaces/SupermatterMonitor.js | 19 +- .../tgui/interfaces/SurgeryInitiator.tsx | 71 +- tgui/packages/tgui/interfaces/Tank.js | 51 +- .../tgui/interfaces/TankCompressor.js | 33 +- .../packages/tgui/interfaces/TankDispenser.js | 18 +- tgui/packages/tgui/interfaces/Techweb.js | 451 +++--- tgui/packages/tgui/interfaces/Telecomms.js | 191 +-- tgui/packages/tgui/interfaces/Teleporter.js | 80 +- tgui/packages/tgui/interfaces/Terminal.js | 12 +- .../tgui/interfaces/TextInputModal.tsx | 12 +- .../packages/tgui/interfaces/ThermoMachine.js | 53 +- tgui/packages/tgui/interfaces/Thermometer.js | 18 +- tgui/packages/tgui/interfaces/Timer.js | 40 +- .../tgui/interfaces/TrackedPlaytime.js | 81 +- .../tgui/interfaces/TrainingMachine.js | 22 +- .../tgui/interfaces/TraitorObjectiveDebug.tsx | 291 ++-- tgui/packages/tgui/interfaces/TramControl.js | 121 +- .../packages/tgui/interfaces/TransferValve.js | 54 +- .../tgui/interfaces/TurbineComputer.js | 30 +- .../packages/tgui/interfaces/TurretControl.js | 21 +- .../tgui/interfaces/Uplink/GenericUplink.tsx | 86 +- .../tgui/interfaces/Uplink/ObjectiveMenu.tsx | 413 +++--- .../Uplink/calculateReputationLevel.tsx | 58 +- .../packages/tgui/interfaces/Uplink/index.tsx | 298 ++-- .../tgui/interfaces/VaultController.js | 21 +- tgui/packages/tgui/interfaces/Vendatray.js | 69 +- tgui/packages/tgui/interfaces/Vending.tsx | 42 +- tgui/packages/tgui/interfaces/VotePanel.tsx | 46 +- tgui/packages/tgui/interfaces/Wires.js | 53 +- .../tgui/interfaces/common/AccessConfig.js | 54 +- .../tgui/interfaces/common/AccessList.js | 201 +-- .../tgui/interfaces/common/AtmosControls.js | 158 ++- .../tgui/interfaces/common/AtmosHandbook.tsx | 23 +- .../tgui/interfaces/common/BeakerContents.js | 23 +- .../tgui/interfaces/common/GasmixParser.tsx | 38 +- .../common/InterfaceLockNoticeBox.js | 10 +- .../tgui/interfaces/common/Loader.tsx | 5 +- .../tgui/interfaces/common/Materials.tsx | 105 +- .../tgui/interfaces/common/PortableAtmos.js | 36 +- .../tgui/interfaces/common/ReagentLookup.js | 85 +- .../tgui/interfaces/common/RecipeLookup.js | 170 +-- tgui/packages/tgui/layouts/Layout.js | 28 +- tgui/packages/tgui/layouts/NtosWindow.js | 43 +- tgui/packages/tgui/layouts/Pane.js | 39 +- tgui/packages/tgui/layouts/Window.js | 107 +- tgui/packages/tgui/links.js | 3 +- tgui/packages/tgui/logging.js | 3 +- tgui/packages/tgui/renderer.ts | 3 +- tgui/packages/tgui/routes.js | 26 +- tgui/packages/tgui/sanitize.js | 5 +- tgui/packages/tgui/store.js | 17 +- tgui/packages/tgui/stories/Blink.stories.js | 4 +- tgui/packages/tgui/stories/Box.stories.js | 32 +- tgui/packages/tgui/stories/Button.stories.js | 32 +- tgui/packages/tgui/stories/ByondUi.stories.js | 43 +- .../tgui/stories/Collapsible.stories.js | 6 +- tgui/packages/tgui/stories/Flex.stories.js | 44 +- tgui/packages/tgui/stories/Input.stories.js | 38 +- tgui/packages/tgui/stories/Popper.stories.js | 70 +- .../tgui/stories/ProgressBar.stories.js | 38 +- tgui/packages/tgui/stories/Storage.stories.js | 10 +- tgui/packages/tgui/stories/Tabs.stories.js | 97 +- tgui/packages/tgui/stories/Themes.stories.js | 3 +- tgui/packages/tgui/stories/Tooltip.stories.js | 9 +- tgui/packages/tgui/stories/common.js | 11 +- .../tgui/styles/atomic/debug-layout.scss | 8 +- .../packages/tgui/styles/atomic/fit-text.scss | 6 +- tgui/packages/tgui/styles/atomic/links.scss | 6 +- tgui/packages/tgui/styles/base.scss | 8 +- tgui/packages/tgui/styles/colors.scss | 2 + .../tgui/styles/components/Button.scss | 20 +- .../tgui/styles/components/Dropdown.scss | 2 +- .../packages/tgui/styles/components/Icon.scss | 1 - .../packages/tgui/styles/components/Knob.scss | 6 +- .../tgui/styles/components/NoticeBox.scss | 18 +- .../tgui/styles/components/RoundGauge.scss | 21 +- .../packages/tgui/styles/components/Tabs.scss | 5 +- tgui/packages/tgui/styles/functions.scss | 20 +- .../tgui/styles/interfaces/Fishing.scss | 4 +- .../tgui/styles/interfaces/HellishRunes.scss | 2 +- .../tgui/styles/interfaces/Hypertorus.scss | 50 +- .../styles/interfaces/LibraryComputer.scss | 4 +- .../tgui/styles/interfaces/ListInput.scss | 29 +- .../tgui/styles/interfaces/Mecha.scss | 4 +- .../tgui/styles/interfaces/NuclearBomb.scss | 8 +- .../styles/interfaces/PersonalCrafting.scss | 15 +- .../styles/interfaces/PreferencesMenu.scss | 13 +- .../styles/interfaces/RequestManager.scss | 2 +- .../packages/tgui/styles/interfaces/Safe.scss | 12 +- .../tgui/styles/interfaces/Uplink.scss | 5 +- tgui/packages/tgui/styles/layouts/Layout.scss | 21 +- .../tgui/styles/layouts/TitleBar.scss | 2 +- tgui/packages/tgui/styles/layouts/Window.scss | 6 +- tgui/packages/tgui/styles/reset.scss | 11 +- .../packages/tgui/styles/themes/abductor.scss | 59 +- tgui/packages/tgui/styles/themes/admin.scss | 28 +- .../tgui/styles/themes/cardtable.scss | 38 +- .../tgui/styles/themes/hackerman.scss | 44 +- .../tgui/styles/themes/malfunction.scss | 59 +- tgui/packages/tgui/styles/themes/neutral.scss | 59 +- tgui/packages/tgui/styles/themes/ntos.scss | 29 +- tgui/packages/tgui/styles/themes/paper.scss | 49 +- tgui/packages/tgui/styles/themes/retro.scss | 33 +- .../tgui/styles/themes/spookyconsole.scss | 61 +- .../tgui/styles/themes/syndicate.scss | 59 +- tgui/packages/tgui/styles/themes/wizard.scss | 91 +- tgui/webpack.config.js | 3 +- tgui/yarn.lock | 1209 ++++++++++++++++- tools/build/build.js | 11 +- 662 files changed, 21462 insertions(+), 21085 deletions(-) create mode 100644 tgui/.prettierignore create mode 100644 tgui/.yarn/sdks/prettier/index.js create mode 100644 tgui/.yarn/sdks/prettier/package.json diff --git a/.editorconfig b/.editorconfig index 471170c449e..76242b39e59 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,10 +1,13 @@ +# http://editorconfig.org +root = true + [*] indent_style = tab indent_size = 4 +end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true -end_of_line = lf [*.yml] indent_style = space diff --git a/.vscode/extensions.json b/.vscode/extensions.json index fa017edecf4..79a1a64683a 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -6,6 +6,7 @@ "dbaeumer.vscode-eslint", "stylemistake.auto-comment-blocks", "Donkie.vscode-tgstation-test-adapter", - "anturk.dmi-editor" + "anturk.dmi-editor", + "esbenp.prettier-vscode" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 4fa80598987..ef34e7edea3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,7 @@ { "eslint.nodePath": "./tgui/.yarn/sdks", - "eslint.workingDirectories": [ - "./tgui" - ], + "eslint.workingDirectories": ["./tgui"], + "prettier.prettierPath": "./tgui/.yarn/sdks/prettier/index.js", "typescript.tsdk": "./tgui/.yarn/sdks/typescript/lib", "typescript.enablePromptUseWorkspaceTsdk": true, "search.exclude": { @@ -17,12 +16,28 @@ "gitlens.advanced.blame.customArguments": ["-w"], "tgstationTestExplorer.project.resultsType": "json", "[javascript]": { - "editor.rulers": [80] + "editor.rulers": [80], + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + "[javascriptreact]": { + "editor.rulers": [80], + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true }, "[typescript]": { - "editor.rulers": [80] + "editor.rulers": [80], + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + "[typescriptreact]": { + "editor.rulers": [80], + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true }, "[scss]": { - "editor.rulers": [80] + "editor.rulers": [80], + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true } } diff --git a/tgui/.eslintrc.yml b/tgui/.eslintrc.yml index daf5f9936e9..fc7385b68b3 100644 --- a/tgui/.eslintrc.yml +++ b/tgui/.eslintrc.yml @@ -1,4 +1,5 @@ root: true +extends: prettier parser: '@typescript-eslint/parser' parserOptions: ecmaVersion: 2020 @@ -17,7 +18,6 @@ settings: react: version: '16.10' rules: - ## Possible Errors ## ---------------------------------------- ## Enforce “for” loop update clause moving the counter in the right @@ -349,15 +349,15 @@ rules: ## Enforce the location of arrow function bodies # implicit-arrow-linebreak: error ## Enforce consistent indentation - indent: [error, 2, { SwitchCase: 1 }] + # indent: [error, 2, { SwitchCase: 1 }] ## Enforce the consistent use of either double or single quotes in JSX ## attributes - jsx-quotes: [error, prefer-double] + # jsx-quotes: [error, prefer-double] ## Enforce consistent spacing between keys and values in object literal ## properties - key-spacing: [error, { beforeColon: false, afterColon: true }] + # key-spacing: [error, { beforeColon: false, afterColon: true }] ## Enforce consistent spacing before and after keywords - keyword-spacing: [error, { before: true, after: true }] + # keyword-spacing: [error, { before: true, after: true }] ## Enforce position of line comments # line-comment-position: error ## Enforce consistent linebreak style @@ -369,15 +369,15 @@ rules: ## Enforce a maximum depth that blocks can be nested # max-depth: error ## Enforce a maximum line length - max-len: [error, { - code: 80, - ## Ignore imports - ignorePattern: '^(import\s.+\sfrom\s|.*require\()', - ignoreUrls: true, - ignoreRegExpLiterals: true, - ignoreStrings: true, - ignoreTemplateLiterals: true, - }] + # max-len: [error, { + # code: 80, + # ## Ignore imports + # ignorePattern: '^(import\s.+\sfrom\s|.*require\()', + # ignoreUrls: true, + # ignoreRegExpLiterals: true, + # ignoreStrings: true, + # ignoreTemplateLiterals: true, + # }] ## Enforce a maximum number of lines per file # max-lines: error ## Enforce a maximum number of line of code in a function @@ -414,7 +414,7 @@ rules: ## Disallow mixed binary operators # no-mixed-operators: error ## Disallow mixed spaces and tabs for indentation - no-mixed-spaces-and-tabs: error + # no-mixed-spaces-and-tabs: error ## Disallow use of chained assignment expressions # no-multi-assign: error ## Disallow multiple empty lines @@ -440,7 +440,7 @@ rules: ## Disallow ternary operators when simpler alternatives exist # no-unneeded-ternary: error ## Disallow whitespace before properties - no-whitespace-before-property: error + # no-whitespace-before-property: error ## Enforce the location of single-line statements # nonblock-statement-body-position: error ## Enforce consistent line breaks inside braces @@ -457,7 +457,7 @@ rules: ## Require or disallow assignment operator shorthand where possible # operator-assignment: error ## Enforce consistent linebreak style for operators - operator-linebreak: [error, before] + # operator-linebreak: [error, before] ## Require or disallow padding within blocks # padded-blocks: error ## Require or disallow padding lines between statements @@ -482,11 +482,11 @@ rules: ## Enforce consistent spacing before blocks space-before-blocks: [error, always] ## Enforce consistent spacing before function definition opening parenthesis - space-before-function-paren: [error, { - anonymous: always, - named: never, - asyncArrow: always, - }] + # space-before-function-paren: [error, { + # anonymous: always, + # named: never, + # asyncArrow: always, + # }] ## Enforce consistent spacing inside parentheses space-in-parens: [error, never] ## Require spacing around infix operators @@ -695,7 +695,7 @@ rules: react/jsx-closing-tag-location: error ## Enforce or disallow newlines inside of curly braces in JSX attributes and ## expressions (fixable) - react/jsx-curly-newline: error + # react/jsx-curly-newline: error ## Enforce or disallow spaces inside of curly braces in JSX attributes and ## expressions (fixable) react/jsx-curly-spacing: error @@ -708,11 +708,11 @@ rules: ## Enforce event handler naming conventions in JSX react/jsx-handler-names: error ## Validate JSX indentation (fixable) - react/jsx-indent: [error, 2, { - checkAttributes: true, - }] + # react/jsx-indent: [error, 2, { + # checkAttributes: true, + # }] ## Validate props indentation in JSX (fixable) - react/jsx-indent-props: [error, 2] + # react/jsx-indent-props: [error, 2] ## Validate JSX has key prop when in array or iterator react/jsx-key: error ## Validate JSX maximum depth diff --git a/tgui/.prettierignore b/tgui/.prettierignore new file mode 100644 index 00000000000..79e703c9544 --- /dev/null +++ b/tgui/.prettierignore @@ -0,0 +1,15 @@ +## NPM +/**/node_modules + +## Yarn +/.yarn +/yarn.lock +/.pnp.* + +/docs +/public +/packages/tgui-polyfill +/packages/tgfont/static +**/*.json +**/*.yml +**/*.md diff --git a/tgui/.prettierrc.yml b/tgui/.prettierrc.yml index fe51f01cc4d..1eebe6098b1 100644 --- a/tgui/.prettierrc.yml +++ b/tgui/.prettierrc.yml @@ -1,8 +1,10 @@ arrowParens: always -bracketSpacing: true +breakLongMethodChains: true endOfLine: lf +importFormatting: oneline jsxBracketSameLine: true jsxSingleQuote: false +offsetTernaryExpressions: true printWidth: 80 proseWrap: preserve quoteProps: preserve @@ -10,3 +12,4 @@ semi: true singleQuote: true tabWidth: 2 trailingComma: es5 +useTabs: false diff --git a/tgui/.yarn/sdks/eslint/lib/api.js b/tgui/.yarn/sdks/eslint/lib/api.js index 97a052442a8..fc728d952bb 100644 --- a/tgui/.yarn/sdks/eslint/lib/api.js +++ b/tgui/.yarn/sdks/eslint/lib/api.js @@ -11,10 +11,10 @@ const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); if (existsSync(absPnpApiPath)) { if (!process.versions.pnp) { - // Setup the environment to be able to require eslint/lib/api.js + // Setup the environment to be able to require eslint require(absPnpApiPath).setup(); } } -// Defer to the real eslint/lib/api.js your application uses -module.exports = absRequire(`eslint/lib/api.js`); +// Defer to the real eslint your application uses +module.exports = absRequire(`eslint`); diff --git a/tgui/.yarn/sdks/prettier/index.js b/tgui/.yarn/sdks/prettier/index.js new file mode 100644 index 00000000000..f6882d80972 --- /dev/null +++ b/tgui/.yarn/sdks/prettier/index.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, createRequireFromPath} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require prettier/index.js + require(absPnpApiPath).setup(); + } +} + +// Defer to the real prettier/index.js your application uses +module.exports = absRequire(`prettier/index.js`); diff --git a/tgui/.yarn/sdks/prettier/package.json b/tgui/.yarn/sdks/prettier/package.json new file mode 100644 index 00000000000..0cbd71ff32d --- /dev/null +++ b/tgui/.yarn/sdks/prettier/package.json @@ -0,0 +1,6 @@ +{ + "name": "prettier", + "version": "0.19.0-sdk", + "main": "./index.js", + "type": "commonjs" +} diff --git a/tgui/.yarn/sdks/typescript/lib/tsserver.js b/tgui/.yarn/sdks/typescript/lib/tsserver.js index 4d90f3879d0..9f9f4d6f469 100644 --- a/tgui/.yarn/sdks/typescript/lib/tsserver.js +++ b/tgui/.yarn/sdks/typescript/lib/tsserver.js @@ -18,6 +18,7 @@ const moduleWrapper = tsserver => { const pnpApi = require(`pnpapi`); const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); + const isPortal = str => str.startsWith("portal:/"); const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { @@ -30,7 +31,7 @@ const moduleWrapper = tsserver => { function toEditorPath(str) { // We add the `zip:` prefix to both `.zip/` paths and virtual paths - if (isAbsolute(str) && !str.match(/^\^zip:/) && (str.match(/\.zip\//) || isVirtual(str))) { + if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { // We also take the opportunity to turn virtual paths into physical ones; // this makes it much easier to work with workspaces that list peer // dependencies, since otherwise Ctrl+Click would bring us to the virtual @@ -44,7 +45,7 @@ const moduleWrapper = tsserver => { const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; if (resolved) { const locator = pnpApi.findPackageLocator(resolved); - if (locator && dependencyTreeRoots.has(`${locator.name}@${locator.reference}`)) { + if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { str = resolved; } } @@ -60,10 +61,34 @@ const moduleWrapper = tsserver => { // // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910 // - case `vscode`: { + // 2021-10-08: VSCode changed the format in 1.61. + // Before | ^zip:/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + // 2022-04-06: VSCode changed the format in 1.66. + // Before | ^/zip//c:/foo/bar.zip/package.json + // After | ^/zip/c:/foo/bar.zip/package.json + // + // 2022-05-06: VSCode changed the format in 1.68 + // Before | ^/zip/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + case `vscode <1.61`: { str = `^zip:${str}`; } break; + case `vscode <1.66`: { + str = `^/zip/${str}`; + } break; + + case `vscode <1.68`: { + str = `^/zip${str}`; + } break; + + case `vscode`: { + str = `^/zip/${str}`; + } break; + // To make "go to definition" work, // We have to resolve the actual file system path from virtual path // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) @@ -77,7 +102,7 @@ const moduleWrapper = tsserver => { // everything else is up to neovim case `neovim`: { str = normalize(resolved).replace(/\.zip\//, `.zip::`); - str = `zipfile:${str}`; + str = `zipfile://${str}`; } break; default: { @@ -91,9 +116,28 @@ const moduleWrapper = tsserver => { } function fromEditorPath(str) { - return process.platform === `win32` - ? str.replace(/^\^?zip:\//, ``) - : str.replace(/^\^?zip:/, ``); + switch (hostInfo) { + case `coc-nvim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for coc-nvim is in format of //zipfile://.yarn/... + // So in order to convert it back, we use .* to match all the thing + // before `zipfile:` + return process.platform === `win32` + ? str.replace(/^.*zipfile:\//, ``) + : str.replace(/^.*zipfile:/, ``); + } break; + + case `neovim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for neovim is in format of zipfile:////.yarn/... + return str.replace(/^zipfile:\/\//, ``); + } break; + + case `vscode`: + default: { + return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) + } break; + } } // Force enable 'allowLocalPluginLoads' @@ -119,8 +163,9 @@ const moduleWrapper = tsserver => { let hostInfo = `unknown`; Object.assign(Session.prototype, { - onMessage(/** @type {string} */ message) { - const parsedMessage = JSON.parse(message) + onMessage(/** @type {string | object} */ message) { + const isStringMessage = typeof message === 'string'; + const parsedMessage = isStringMessage ? JSON.parse(message) : message; if ( parsedMessage != null && @@ -129,11 +174,32 @@ const moduleWrapper = tsserver => { typeof parsedMessage.arguments.hostInfo === `string` ) { hostInfo = parsedMessage.arguments.hostInfo; + if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { + const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( + // The RegExp from https://semver.org/ but without the caret at the start + /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ + ) ?? []).map(Number) + + if (major === 1) { + if (minor < 61) { + hostInfo += ` <1.61`; + } else if (minor < 66) { + hostInfo += ` <1.66`; + } else if (minor < 68) { + hostInfo += ` <1.68`; + } + } + } } - return originalOnMessage.call(this, JSON.stringify(parsedMessage, (key, value) => { - return typeof value === `string` ? fromEditorPath(value) : value; - })); + const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { + return typeof value === 'string' ? fromEditorPath(value) : value; + }); + + return originalOnMessage.call( + this, + isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) + ); }, send(/** @type {any} */ msg) { diff --git a/tgui/.yarn/sdks/typescript/lib/tsserverlibrary.js b/tgui/.yarn/sdks/typescript/lib/tsserverlibrary.js index c3de4ff5d70..878b11946a4 100644 --- a/tgui/.yarn/sdks/typescript/lib/tsserverlibrary.js +++ b/tgui/.yarn/sdks/typescript/lib/tsserverlibrary.js @@ -18,6 +18,7 @@ const moduleWrapper = tsserver => { const pnpApi = require(`pnpapi`); const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); + const isPortal = str => str.startsWith("portal:/"); const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { @@ -30,7 +31,7 @@ const moduleWrapper = tsserver => { function toEditorPath(str) { // We add the `zip:` prefix to both `.zip/` paths and virtual paths - if (isAbsolute(str) && !str.match(/^\^zip:/) && (str.match(/\.zip\//) || isVirtual(str))) { + if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { // We also take the opportunity to turn virtual paths into physical ones; // this makes it much easier to work with workspaces that list peer // dependencies, since otherwise Ctrl+Click would bring us to the virtual @@ -44,7 +45,7 @@ const moduleWrapper = tsserver => { const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; if (resolved) { const locator = pnpApi.findPackageLocator(resolved); - if (locator && dependencyTreeRoots.has(`${locator.name}@${locator.reference}`)) { + if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { str = resolved; } } @@ -60,10 +61,34 @@ const moduleWrapper = tsserver => { // // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910 // - case `vscode`: { + // 2021-10-08: VSCode changed the format in 1.61. + // Before | ^zip:/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + // 2022-04-06: VSCode changed the format in 1.66. + // Before | ^/zip//c:/foo/bar.zip/package.json + // After | ^/zip/c:/foo/bar.zip/package.json + // + // 2022-05-06: VSCode changed the format in 1.68 + // Before | ^/zip/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + case `vscode <1.61`: { str = `^zip:${str}`; } break; + case `vscode <1.66`: { + str = `^/zip/${str}`; + } break; + + case `vscode <1.68`: { + str = `^/zip${str}`; + } break; + + case `vscode`: { + str = `^/zip/${str}`; + } break; + // To make "go to definition" work, // We have to resolve the actual file system path from virtual path // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) @@ -77,7 +102,7 @@ const moduleWrapper = tsserver => { // everything else is up to neovim case `neovim`: { str = normalize(resolved).replace(/\.zip\//, `.zip::`); - str = `zipfile:${str}`; + str = `zipfile://${str}`; } break; default: { @@ -91,9 +116,28 @@ const moduleWrapper = tsserver => { } function fromEditorPath(str) { - return process.platform === `win32` - ? str.replace(/^\^?zip:\//, ``) - : str.replace(/^\^?zip:/, ``); + switch (hostInfo) { + case `coc-nvim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for coc-nvim is in format of //zipfile://.yarn/... + // So in order to convert it back, we use .* to match all the thing + // before `zipfile:` + return process.platform === `win32` + ? str.replace(/^.*zipfile:\//, ``) + : str.replace(/^.*zipfile:/, ``); + } break; + + case `neovim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for neovim is in format of zipfile:////.yarn/... + return str.replace(/^zipfile:\/\//, ``); + } break; + + case `vscode`: + default: { + return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) + } break; + } } // Force enable 'allowLocalPluginLoads' @@ -119,8 +163,9 @@ const moduleWrapper = tsserver => { let hostInfo = `unknown`; Object.assign(Session.prototype, { - onMessage(/** @type {string} */ message) { - const parsedMessage = JSON.parse(message) + onMessage(/** @type {string | object} */ message) { + const isStringMessage = typeof message === 'string'; + const parsedMessage = isStringMessage ? JSON.parse(message) : message; if ( parsedMessage != null && @@ -129,11 +174,32 @@ const moduleWrapper = tsserver => { typeof parsedMessage.arguments.hostInfo === `string` ) { hostInfo = parsedMessage.arguments.hostInfo; + if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { + const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( + // The RegExp from https://semver.org/ but without the caret at the start + /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ + ) ?? []).map(Number) + + if (major === 1) { + if (minor < 61) { + hostInfo += ` <1.61`; + } else if (minor < 66) { + hostInfo += ` <1.66`; + } else if (minor < 68) { + hostInfo += ` <1.68`; + } + } + } } - return originalOnMessage.call(this, JSON.stringify(parsedMessage, (key, value) => { - return typeof value === `string` ? fromEditorPath(value) : value; - })); + const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { + return typeof value === 'string' ? fromEditorPath(value) : value; + }); + + return originalOnMessage.call( + this, + isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) + ); }, send(/** @type {any} */ msg) { diff --git a/tgui/babel.config.js b/tgui/babel.config.js index d8ddb75721d..e702c9a7119 100644 --- a/tgui/babel.config.js +++ b/tgui/babel.config.js @@ -4,8 +4,9 @@ * @license MIT */ -const createBabelConfig = options => { +const createBabelConfig = (options) => { const { presets = [], plugins = [], removeConsole } = options; + // prettier-ignore return { presets: [ [require.resolve('@babel/preset-typescript'), { @@ -34,7 +35,7 @@ const createBabelConfig = options => { }; }; -module.exports = api => { +module.exports = (api) => { api.cache(true); const mode = process.env.NODE_ENV; return createBabelConfig({ mode }); diff --git a/tgui/jest.config.js b/tgui/jest.config.js index e654f0089b8..8b78818004b 100644 --- a/tgui/jest.config.js +++ b/tgui/jest.config.js @@ -4,9 +4,7 @@ module.exports = { '/packages/**/__tests__/*.{js,ts,tsx}', '/packages/**/*.{spec,test}.{js,ts,tsx}', ], - testPathIgnorePatterns: [ - '/packages/tgui-bench', - ], + testPathIgnorePatterns: ['/packages/tgui-bench'], testEnvironment: 'jsdom', testRunner: require.resolve('jest-circus/runner'), transform: { diff --git a/tgui/package.json b/tgui/package.json index 6c2035a5ec4..16a0489973e 100644 --- a/tgui/package.json +++ b/tgui/package.json @@ -7,16 +7,17 @@ "packages/*" ], "scripts": { - "tgui:build": "webpack", "tgui:analyze": "webpack --analyze", + "tgui:bench": "webpack --env TGUI_BENCH=1 && node packages/tgui-bench/index.js", + "tgui:build": "webpack", "tgui:dev": "node --experimental-modules packages/tgui-dev-server/index.js", "tgui:lint": "eslint packages --ext .js,.cjs,.ts,.tsx", + "tgui:prettier": "prettierx --check .", "tgui:sonar": "eslint packages --ext .js,.cjs,.ts,.tsx -c .eslintrc-sonar.yml", - "tgui:tsc": "tsc", "tgui:test": "jest --watch", "tgui:test-simple": "CI=true jest --color", "tgui:test-ci": "CI=true jest --color --collect-coverage", - "tgui:bench": "webpack --env TGUI_BENCH=1 && node packages/tgui-bench/index.js" + "tgui:tsc": "tsc" }, "dependencies": { "@babel/core": "^7.15.0", @@ -38,6 +39,7 @@ "common": "workspace:*", "css-loader": "^5.2.7", "eslint": "^7.32.0", + "eslint-config-prettier": "^8.5.0", "eslint-plugin-radar": "^0.2.1", "eslint-plugin-react": "^7.24.0", "eslint-plugin-unused-imports": "^1.1.4", @@ -47,6 +49,7 @@ "jest-circus": "^27.0.6", "jsdom": "^16.7.0", "mini-css-extract-plugin": "^1.6.2", + "prettier": "npm:prettierx@0.19.0", "sass": "^1.37.5", "sass-loader": "^11.1.1", "style-loader": "^2.0.0", diff --git a/tgui/packages/common/collections.spec.ts b/tgui/packages/common/collections.spec.ts index 58eff7f354c..ef35a95cb3e 100644 --- a/tgui/packages/common/collections.spec.ts +++ b/tgui/packages/common/collections.spec.ts @@ -1,20 +1,20 @@ -import { range, zip } from "./collections"; +import { range, zip } from './collections'; // Type assertions, these will lint if the types are wrong. -const _zip1: [string, number] = zip(["a"], [1])[0]; +const _zip1: [string, number] = zip(['a'], [1])[0]; -describe("range", () => { - test("range(0, 5)", () => { +describe('range', () => { + test('range(0, 5)', () => { expect(range(0, 5)).toEqual([0, 1, 2, 3, 4]); }); }); -describe("zip", () => { +describe('zip', () => { test("zip(['a', 'b', 'c'], [1, 2, 3, 4])", () => { - expect(zip(["a", "b", "c"], [1, 2, 3, 4])).toEqual([ - ["a", 1], - ["b", 2], - ["c", 3], + expect(zip(['a', 'b', 'c'], [1, 2, 3, 4])).toEqual([ + ['a', 1], + ['b', 2], + ['c', 3], ]); }); }); diff --git a/tgui/packages/common/collections.ts b/tgui/packages/common/collections.ts index 5ab378070f0..49f500ebd29 100644 --- a/tgui/packages/common/collections.ts +++ b/tgui/packages/common/collections.ts @@ -11,43 +11,34 @@ * * If collection is 'null' or 'undefined', it will be returned "as is" * without emitting any errors (which can be useful in some cases). - * - * @returns {any[]} */ -export const filter = (iterateeFn: ( - input: T, - index: number, - collection: T[], -) => boolean) => - (collection: T[]): T[] => { - if (collection === null || collection === undefined) { - return collection; - } - if (Array.isArray(collection)) { - const result: T[] = []; - for (let i = 0; i < collection.length; i++) { - const item = collection[i]; - if (iterateeFn(item, i, collection)) { - result.push(item); - } +export const filter = + (iterateeFn: (input: T, index: number, collection: T[]) => boolean) => + (collection: T[]): T[] => { + if (collection === null || collection === undefined) { + return collection; + } + if (Array.isArray(collection)) { + const result: T[] = []; + for (let i = 0; i < collection.length; i++) { + const item = collection[i]; + if (iterateeFn(item, i, collection)) { + result.push(item); } - return result; } - throw new Error(`filter() can't iterate on type ${typeof collection}`); - }; + return result; + } + throw new Error(`filter() can't iterate on type ${typeof collection}`); + }; type MapFunction = { - (iterateeFn: ( - value: T, - index: number, - collection: T[], - ) => U): (collection: T[]) => U[]; + (iterateeFn: (value: T, index: number, collection: T[]) => U): ( + collection: T[] + ) => U[]; - (iterateeFn: ( - value: T, - index: K, - collection: Record, - ) => U): (collection: Record) => U[]; + ( + iterateeFn: (value: T, index: K, collection: Record) => U + ): (collection: Record) => U[]; }; /** @@ -58,7 +49,8 @@ type MapFunction = { * If collection is 'null' or 'undefined', it will be returned "as is" * without emitting any errors (which can be useful in some cases). */ -export const map: MapFunction = (iterateeFn) => +export const map: MapFunction = + (iterateeFn) => (collection: T[]): U[] => { if (collection === null || collection === undefined) { return collection; @@ -81,9 +73,10 @@ export const map: MapFunction = (iterateeFn) => * Given a collection, will run each element through an iteratee function. * Will then filter out undefined values. */ -export const filterMap = (collection: T[], iterateeFn: ( - value: T -) => U | undefined): U[] => { +export const filterMap = ( + collection: T[], + iterateeFn: (value: T) => U | undefined +): U[] => { const finalCollection: U[] = []; for (const value of collection) { @@ -119,22 +112,22 @@ const COMPARATOR = (objA, objB) => { * * Iteratees are called with one argument (value). */ -export const sortBy = ( - ...iterateeFns: ((input: T) => unknown)[] -) => (array: T[]): T[] => { +export const sortBy = + (...iterateeFns: ((input: T) => unknown)[]) => + (array: T[]): T[] => { if (!Array.isArray(array)) { return array; } let length = array.length; // Iterate over the array to collect criteria to sort it by let mappedArray: { - criteria: unknown[], - value: T, + criteria: unknown[]; + value: T; }[] = []; for (let i = 0; i < length; i++) { const value = array[i]; mappedArray.push({ - criteria: iterateeFns.map(fn => fn(value)), + criteria: iterateeFns.map((fn) => fn(value)), value, }); } @@ -163,15 +156,14 @@ export const range = (start: number, end: number): number[] => /** * A fast implementation of reduce. */ -export const reduce = (reducerFn, initialValue) => array => { +export const reduce = (reducerFn, initialValue) => (array) => { const length = array.length; let i; let result; if (initialValue === undefined) { i = 1; result = array[0]; - } - else { + } else { i = 0; result = initialValue; } @@ -192,13 +184,14 @@ export const reduce = (reducerFn, initialValue) => array => { * is determined by the order they occur in the array. The iteratee is * invoked with one argument: value. */ -export const uniqBy = ( - iterateeFn?: (value: T) => unknown -) => (array: T[]): T[] => { +export const uniqBy = + (iterateeFn?: (value: T) => unknown) => + (array: T[]): T[] => { const { length } = array; const result: T[] = []; const seen: unknown[] = iterateeFn ? [] : result; let index = -1; + // prettier-ignore outer: while (++index < length) { let value: T | 0 = array[index]; @@ -214,8 +207,7 @@ export const uniqBy = ( seen.push(computed); } result.push(value); - } - else if (!seen.includes(computed)) { + } else if (!seen.includes(computed)) { if (seen !== result) { seen.push(computed); } @@ -224,7 +216,6 @@ export const uniqBy = ( } return result; }; -/* eslint-enable indent */ export const uniq = uniqBy(); @@ -261,7 +252,8 @@ export const zip = (...arrays: T): Zip => { * specify how grouped values should be combined. The iteratee is * invoked with the elements of each group. */ -export const zipWith = (iterateeFn: (...values: T[]) => U) => +export const zipWith = + (iterateeFn: (...values: T[]) => U) => (...arrays: T[][]): U[] => { return map((values: T[]) => iterateeFn(...values))(zip(...arrays)); }; @@ -269,7 +261,7 @@ export const zipWith = (iterateeFn: (...values: T[]) => U) => const binarySearch = ( getKey: (value: T) => U, collection: readonly T[], - inserting: T, + inserting: T ): number => { if (collection.length === 0) { return 0; @@ -301,12 +293,10 @@ const binarySearch = ( return compare > insertingKey ? middle : middle + 1; }; -export const binaryInsertWith = (getKey: (value: T) => U): - ((collection: readonly T[], value: T) => T[]) => -{ - return (collection, value) => { +export const binaryInsertWith = + (getKey: (value: T) => U) => + (collection: readonly T[], value: T) => { const copy = [...collection]; copy.splice(binarySearch(getKey, collection, value), 0, value); return copy; }; -}; diff --git a/tgui/packages/common/color.js b/tgui/packages/common/color.js index 2aadae8d6bd..672fce529b6 100644 --- a/tgui/packages/common/color.js +++ b/tgui/packages/common/color.js @@ -27,23 +27,23 @@ export class Color { /** * Creates a color from the CSS hex color notation. */ -Color.fromHex = hex => ( +Color.fromHex = (hex) => new Color( parseInt(hex.substr(1, 2), 16), parseInt(hex.substr(3, 2), 16), - parseInt(hex.substr(5, 2), 16)) -); + parseInt(hex.substr(5, 2), 16) + ); /** * Linear interpolation of two colors. */ -Color.lerp = (c1, c2, n) => ( +Color.lerp = (c1, c2, n) => new Color( (c2.r - c1.r) * n + c1.r, (c2.g - c1.g) * n + c1.g, (c2.b - c1.b) * n + c1.b, - (c2.a - c1.a) * n + c1.a) -); + (c2.a - c1.a) * n + c1.a + ); /** * Loops up the color in the provided list of colors diff --git a/tgui/packages/common/events.js b/tgui/packages/common/events.js index 6d590a34453..7eeff511aa5 100644 --- a/tgui/packages/common/events.js +++ b/tgui/packages/common/events.js @@ -19,10 +19,9 @@ export class EventEmitter { if (!listeners) { throw new Error(`There is no listeners for "${name}"`); } - this.listeners[name] = listeners - .filter(existingListener => { - return existingListener !== listener; - }); + this.listeners[name] = listeners.filter((existingListener) => { + return existingListener !== listener; + }); } emit(name, ...params) { diff --git a/tgui/packages/common/fp.js b/tgui/packages/common/fp.js index 7aa00a00f3e..ba7df09d407 100644 --- a/tgui/packages/common/fp.js +++ b/tgui/packages/common/fp.js @@ -9,6 +9,7 @@ * functions, where each successive invocation is supplied the return * value of the previous. */ +// prettier-ignore export const flow = (...funcs) => (input, ...rest) => { let output = input; for (let func of funcs) { @@ -37,11 +38,12 @@ export const flow = (...funcs) => (input, ...rest) => { */ export const compose = (...funcs) => { if (funcs.length === 0) { - return arg => arg; + return (arg) => arg; } if (funcs.length === 1) { return funcs[0]; } + // prettier-ignore return funcs.reduce((a, b) => (value, ...rest) => a(b(value, ...rest), ...rest)); }; diff --git a/tgui/packages/common/math.ts b/tgui/packages/common/math.ts index 97e6b60b2ed..9dc1d655693 100644 --- a/tgui/packages/common/math.ts +++ b/tgui/packages/common/math.ts @@ -14,7 +14,7 @@ export const clamp = (value, min, max) => { /** * Limits a number between 0 and 1. */ -export const clamp01 = value => { +export const clamp01 = (value) => { return value < 0 ? 0 : value > 1 ? 1 : value; }; @@ -69,9 +69,7 @@ export const toFixed = (value, fractionDigits = 0) => { * Range is an array of two numbers, for example: [0, 15]. */ export const inRange = (value, range) => { - return range - && value >= range[0] - && value <= range[1]; + return range && value >= range[0] && value <= range[1]; }; /** @@ -92,7 +90,7 @@ export const keyOfMatchingRange = (value, ranges) => { /** * Get number of digits following the decimal point in a number */ -export const numberOfDecimalDigits = value => { +export const numberOfDecimalDigits = (value) => { if (Math.floor(value) !== value) { return value.toString().split('.')[1].length || 0; } diff --git a/tgui/packages/common/perf.js b/tgui/packages/common/perf.js index 8414971f93b..591aa3537de 100644 --- a/tgui/packages/common/perf.js +++ b/tgui/packages/common/perf.js @@ -48,8 +48,9 @@ const measure = (markerNameA, markerNameB) => { } }; -const formatDuration = duration => { +const formatDuration = (duration) => { const durationInFrames = duration / FRAME_DURATION; + // prettier-ignore return duration.toFixed(duration < 10 ? 1 : 0) + 'ms ' + '(' + durationInFrames.toFixed(2) + ' frames)'; }; diff --git a/tgui/packages/common/random.ts b/tgui/packages/common/random.ts index 7f99cda39f3..fbf9030b1ba 100644 --- a/tgui/packages/common/random.ts +++ b/tgui/packages/common/random.ts @@ -1,4 +1,4 @@ -import { clamp } from "./math"; +import { clamp } from './math'; /** * Returns random number between lowerBound exclusive and upperBound inclusive @@ -27,7 +27,6 @@ export const randomPick = (array: T[]) => { * Return 1 with probability P percent; otherwise 0 */ export const randomProb = (probability: number) => { - const normalized = clamp(probability, 0, 100)/100; + const normalized = clamp(probability, 0, 100) / 100; return Math.random() <= normalized; }; - diff --git a/tgui/packages/common/react.ts b/tgui/packages/common/react.ts index c8a08f04934..8e42d0971ab 100644 --- a/tgui/packages/common/react.ts +++ b/tgui/packages/common/react.ts @@ -24,7 +24,7 @@ export const classes = (classNames: (string | BooleanLike)[]) => { */ export const normalizeChildren = (children: T | T[]) => { if (Array.isArray(children)) { - return children.flat().filter(value => value) as T[]; + return children.flat().filter((value) => value) as T[]; } if (typeof children === 'object') { return [children]; @@ -64,6 +64,7 @@ export const pureComponentHooks = { * A helper to determine whether the object is renderable by React. */ export const canRender = (value: unknown) => { + // prettier-ignore return value !== undefined && value !== null && typeof value !== 'boolean'; diff --git a/tgui/packages/common/redux.js b/tgui/packages/common/redux.js index ebed11f166b..3997134cd74 100644 --- a/tgui/packages/common/redux.js +++ b/tgui/packages/common/redux.js @@ -20,11 +20,11 @@ export const createStore = (reducer, enhancer) => { const getState = () => currentState; - const subscribe = listener => { + const subscribe = (listener) => { listeners.push(listener); }; - const dispatch = action => { + const dispatch = (action) => { currentState = reducer(currentState, action); for (let i = 0; i < listeners.length; i++) { listeners[i](); @@ -49,6 +49,7 @@ export const createStore = (reducer, enhancer) => { * actions. */ export const applyMiddleware = (...middlewares) => { + // prettier-ignore return createStore => (reducer, ...args) => { const store = createStore(reducer, ...args); @@ -80,7 +81,7 @@ export const applyMiddleware = (...middlewares) => { * in the state that are not present in the reducers object. This function * is also more flexible than the redux counterpart. */ -export const combineReducers = reducersObj => { +export const combineReducers = (reducersObj) => { const keys = Object.keys(reducersObj); let hasChanged = false; return (prevState = {}, action) => { @@ -94,9 +95,7 @@ export const combineReducers = reducersObj => { nextState[key] = nextDomainState; } } - return hasChanged - ? nextState - : prevState; + return hasChanged ? nextState : prevState; }; }; @@ -136,15 +135,14 @@ export const createAction = (type, prepare = null) => { }; actionCreator.toString = () => '' + type; actionCreator.type = type; - actionCreator.match = action => action.type === type; + actionCreator.match = (action) => action.type === type; return actionCreator; }; - // Implementation specific // -------------------------------------------------------- -export const useDispatch = context => { +export const useDispatch = (context) => { return context.store.dispatch; }; diff --git a/tgui/packages/common/storage.js b/tgui/packages/common/storage.js index 83dc6d99c1c..acf842f6408 100644 --- a/tgui/packages/common/storage.js +++ b/tgui/packages/common/storage.js @@ -17,11 +17,10 @@ const INDEXED_DB_STORE_NAME = 'storage-v1'; const READ_ONLY = 'readonly'; const READ_WRITE = 'readwrite'; -const testGeneric = testFn => () => { +const testGeneric = (testFn) => () => { try { return Boolean(testFn()); - } - catch { + } catch { return false; } }; @@ -29,10 +28,12 @@ const testGeneric = testFn => () => { // Localstorage can sometimes throw an error, even if DOM storage is not // disabled in IE11 settings. // See: https://superuser.com/questions/1080011 +// prettier-ignore const testLocalStorage = testGeneric(() => ( window.localStorage && window.localStorage.getItem )); +// prettier-ignore const testIndexedDb = testGeneric(() => ( (window.indexedDB || window.msIndexedDB) && (window.IDBTransaction || window.msIDBTransaction) @@ -96,8 +97,7 @@ class IndexedDbBackend { req.onupgradeneeded = () => { try { req.result.createObjectStore(INDEXED_DB_STORE_NAME); - } - catch (err) { + } catch (err) { reject(new Error('Failed to upgrade IDB: ' + req.error)); } }; @@ -109,7 +109,8 @@ class IndexedDbBackend { } getStore(mode) { - return this.dbPromise.then(db => db + // prettier-ignore + return this.dbPromise.then((db) => db .transaction(INDEXED_DB_STORE_NAME, mode) .objectStore(INDEXED_DB_STORE_NAME)); } @@ -161,8 +162,7 @@ class StorageProxy { const backend = new IndexedDbBackend(); await backend.dbPromise; return backend; - } - catch {} + } catch {} } if (testLocalStorage()) { return new LocalStorageBackend(); diff --git a/tgui/packages/common/string.babel-plugin.cjs b/tgui/packages/common/string.babel-plugin.cjs index 68295aefcf8..97ca67c6ea4 100644 --- a/tgui/packages/common/string.babel-plugin.cjs +++ b/tgui/packages/common/string.babel-plugin.cjs @@ -19,7 +19,7 @@ /** * Removes excess whitespace and indentation from the string. */ -const multiline = str => { +const multiline = (str) => { const lines = str.split('\n'); // Determine base indentation let minIndent; @@ -40,15 +40,15 @@ const multiline = str => { // Remove this base indentation and trim the resulting string // from both ends. return lines - .map(line => line.substr(minIndent).trimRight()) + .map((line) => line.substr(minIndent).trimRight()) .join('\n') .trim(); }; -const StringPlugin = ref => { +const StringPlugin = (ref) => { return { visitor: { - TaggedTemplateExpression: path => { + TaggedTemplateExpression: (path) => { if (path.node.tag.name === 'multiline') { const { quasi } = path.node; if (quasi.expressions.length > 0) { diff --git a/tgui/packages/common/string.js b/tgui/packages/common/string.js index 16a0921a255..0d8eef431ed 100644 --- a/tgui/packages/common/string.js +++ b/tgui/packages/common/string.js @@ -7,7 +7,7 @@ /** * Removes excess whitespace and indentation from the string. */ -export const multiline = str => { +export const multiline = (str) => { if (Array.isArray(str)) { // Small stub to allow usage as a template tag return multiline(str.join('')); @@ -32,7 +32,7 @@ export const multiline = str => { // Remove this base indentation and trim the resulting string // from both ends. return lines - .map(line => line.substr(minIndent).trimRight()) + .map((line) => line.substr(minIndent).trimRight()) .join('\n') .trim(); }; @@ -44,12 +44,13 @@ export const multiline = str => { * * Example: createGlobPattern('*@domain')('user@domain') === true */ -export const createGlobPattern = pattern => { - const escapeString = str => str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'); +export const createGlobPattern = (pattern) => { + const escapeString = (str) => str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'); + // prettier-ignore const regex = new RegExp('^' + pattern.split(/\*+/).map(escapeString).join('.*') + '$'); - return str => regex.test(str); + return (str) => regex.test(str); }; /** @@ -64,7 +65,7 @@ export const createGlobPattern = pattern => { */ export const createSearch = (searchText, stringifier) => { const preparedSearchText = searchText.toLowerCase().trim(); - return obj => { + return (obj) => { if (!preparedSearchText) { return true; } @@ -72,13 +73,11 @@ export const createSearch = (searchText, stringifier) => { if (!str) { return false; } - return str - .toLowerCase() - .includes(preparedSearchText); + return str.toLowerCase().includes(preparedSearchText); }; }; -export const capitalize = str => { +export const capitalize = (str) => { // Handle array if (Array.isArray(str)) { return str.map(capitalize); @@ -87,7 +86,7 @@ export const capitalize = str => { return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); }; -export const toTitleCase = str => { +export const toTitleCase = (str) => { // Handle array if (Array.isArray(str)) { return str.map(toTitleCase); @@ -98,20 +97,21 @@ export const toTitleCase = str => { } // Handle string const WORDS_UPPER = ['Id', 'Tv']; + // prettier-ignore const WORDS_LOWER = [ 'A', 'An', 'And', 'As', 'At', 'But', 'By', 'For', 'For', 'From', 'In', 'Into', 'Near', 'Nor', 'Of', 'On', 'Onto', 'Or', 'The', 'To', 'With', ]; - let currentStr = str.replace(/([^\W_]+[^\s-]*) */g, str => { + let currentStr = str.replace(/([^\W_]+[^\s-]*) */g, (str) => { return str.charAt(0).toUpperCase() + str.substr(1).toLowerCase(); }); for (let word of WORDS_LOWER) { const regex = new RegExp('\\s' + word + '\\s', 'g'); - currentStr = currentStr.replace(regex, str => str.toLowerCase()); + currentStr = currentStr.replace(regex, (str) => str.toLowerCase()); } for (let word of WORDS_UPPER) { const regex = new RegExp('\\b' + word + '\\b', 'g'); - currentStr = currentStr.replace(regex, str => str.toLowerCase()); + currentStr = currentStr.replace(regex, (str) => str.toLowerCase()); } return currentStr; }; @@ -122,7 +122,7 @@ export const toTitleCase = str => { * @param {String} str Encoded HTML string * @return {String} Decoded HTML string */ -export const decodeHtmlEntities = str => { +export const decodeHtmlEntities = (str) => { if (!str) { return str; } @@ -133,8 +133,9 @@ export const decodeHtmlEntities = str => { quot: '"', lt: '<', gt: '>', - apos: '\'', + apos: "'", }; + // prettier-ignore return str // Newline tags .replace(/
/gi, '\n') @@ -156,6 +157,7 @@ export const decodeHtmlEntities = str => { /** * Converts an object into a query string, */ +// prettier-ignore export const buildQueryString = obj => Object.keys(obj) .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(obj[key])) diff --git a/tgui/packages/common/types.ts b/tgui/packages/common/types.ts index a92ac122d9f..e219bd3b7e1 100644 --- a/tgui/packages/common/types.ts +++ b/tgui/packages/common/types.ts @@ -1,5 +1,6 @@ /** * Returns the arguments of a function F as an array. */ +// prettier-ignore export type ArgumentsOf = F extends (...args: infer A) => unknown ? A : never; diff --git a/tgui/packages/common/uuid.js b/tgui/packages/common/uuid.js index 7721af64949..6e156d8649b 100644 --- a/tgui/packages/common/uuid.js +++ b/tgui/packages/common/uuid.js @@ -11,9 +11,10 @@ */ export const createUuid = () => { let d = new Date().getTime(); - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { const r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); + // prettier-ignore return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); }); }; diff --git a/tgui/packages/common/vector.js b/tgui/packages/common/vector.js index c3ac350a4e8..b1f85f7429d 100644 --- a/tgui/packages/common/vector.js +++ b/tgui/packages/common/vector.js @@ -32,17 +32,17 @@ export const vecDivide = (...vecs) => { }; export const vecScale = (vec, n) => { - return map(x => x * n)(vec); + return map((x) => x * n)(vec); }; -export const vecInverse = vec => { - return map(x => -x)(vec); +export const vecInverse = (vec) => { + return map((x) => -x)(vec); }; -export const vecLength = vec => { +export const vecLength = (vec) => { return Math.sqrt(reduce(ADD)(zipWith(MUL)(vec, vec))); }; -export const vecNormalize = vec => { +export const vecNormalize = (vec) => { return vecDivide(vec, vecLength(vec)); }; diff --git a/tgui/packages/tgfont/mkdist.cjs b/tgui/packages/tgfont/mkdist.cjs index 5c628becf99..85634bd265d 100644 --- a/tgui/packages/tgfont/mkdist.cjs +++ b/tgui/packages/tgfont/mkdist.cjs @@ -10,5 +10,4 @@ process.chdir(__dirname); // Silently make a dist folder try { require('fs').mkdirSync('dist'); -} -catch (err) {} +} catch (err) {} diff --git a/tgui/packages/tgui-bench/entrypoint.tsx b/tgui/packages/tgui-bench/entrypoint.tsx index d72aa60a667..377848fe3ae 100644 --- a/tgui/packages/tgui-bench/entrypoint.tsx +++ b/tgui/packages/tgui-bench/entrypoint.tsx @@ -62,8 +62,7 @@ const setupApp = async () => { } suite.run(); }); - } - catch (error) { + } catch (error) { sendMessage({ type: 'error', error }); } } diff --git a/tgui/packages/tgui-bench/index.js b/tgui/packages/tgui-bench/index.js index ac3d8c9cce0..9f6aee20996 100644 --- a/tgui/packages/tgui-bench/index.js +++ b/tgui/packages/tgui-bench/index.js @@ -27,7 +27,8 @@ const setup = async () => { assets += `\n`; const publicDir = path.resolve(__dirname, '../../public'); - const page = fs.readFileSync(path.join(publicDir, 'tgui.html'), 'utf-8') + const page = fs + .readFileSync(path.join(publicDir, 'tgui.html'), 'utf-8') .replace('\n', assets); server.register(require('fastify-static'), { @@ -67,8 +68,7 @@ const setup = async () => { try { await server.listen(3002, '0.0.0.0'); - } - catch (err) { + } catch (err) { console.error(err); process.exit(1); } diff --git a/tgui/packages/tgui-bench/lib/benchmark.js b/tgui/packages/tgui-bench/lib/benchmark.js index 1e76cec7087..0837678decf 100644 --- a/tgui/packages/tgui-bench/lib/benchmark.js +++ b/tgui/packages/tgui-bench/lib/benchmark.js @@ -7,6 +7,7 @@ * Manually stripped from useless junk by /tg/station13 maintainers. * Available under MIT license */ +// prettier-ignore module.exports = (function() { 'use strict'; diff --git a/tgui/packages/tgui-bench/tests/Button.test.tsx b/tgui/packages/tgui-bench/tests/Button.test.tsx index e3472cbbbfa..6b806d720ab 100644 --- a/tgui/packages/tgui-bench/tests/Button.test.tsx +++ b/tgui/packages/tgui-bench/tests/Button.test.tsx @@ -7,28 +7,18 @@ const render = createRenderer(); const handleClick = () => undefined; export const SingleButton = () => { - const node = ( - - ); + const node = ; render(node); }; export const SingleButtonWithCallback = () => { - const node = ( - - ); + const node = ; render(node); }; export const SingleButtonWithLinkEvent = () => { const node = ( - + ); render(node); }; @@ -36,11 +26,7 @@ export const SingleButtonWithLinkEvent = () => { export const ListOfButtons = () => { const nodes: JSX.Element[] = []; for (let i = 0; i < 100; i++) { - const node = ( - - ); + const node = ; nodes.push(node); } render(
{nodes}
); diff --git a/tgui/packages/tgui-bench/tests/DisposalUnit.test.tsx b/tgui/packages/tgui-bench/tests/DisposalUnit.test.tsx index b588f306f76..843bd70367a 100644 --- a/tgui/packages/tgui-bench/tests/DisposalUnit.test.tsx +++ b/tgui/packages/tgui-bench/tests/DisposalUnit.test.tsx @@ -6,9 +6,11 @@ import { configureStore, StoreProvider } from 'tgui/store'; const store = configureStore({ sideEffets: false }); const renderUi = createRenderer((dataJson: string) => { - store.dispatch(backendUpdate({ - data: Byond.parseJson(dataJson), - })); + store.dispatch( + backendUpdate({ + data: Byond.parseJson(dataJson), + }) + ); return ( diff --git a/tgui/packages/tgui-bench/tests/Flex.test.tsx b/tgui/packages/tgui-bench/tests/Flex.test.tsx index e81ebc6f611..66c039a1908 100644 --- a/tgui/packages/tgui-bench/tests/Flex.test.tsx +++ b/tgui/packages/tgui-bench/tests/Flex.test.tsx @@ -6,9 +6,7 @@ const render = createRenderer(); export const Default = () => { const node = ( - - Text {Math.random()} - + Text {Math.random()} Text {Math.random()} diff --git a/tgui/packages/tgui-bench/tests/Stack.test.tsx b/tgui/packages/tgui-bench/tests/Stack.test.tsx index 952dba20294..ce7f5599e72 100644 --- a/tgui/packages/tgui-bench/tests/Stack.test.tsx +++ b/tgui/packages/tgui-bench/tests/Stack.test.tsx @@ -6,9 +6,7 @@ const render = createRenderer(); export const Default = () => { const node = ( - - Text {Math.random()} - + Text {Math.random()} Text {Math.random()} diff --git a/tgui/packages/tgui-bench/tests/Tooltip.test.tsx b/tgui/packages/tgui-bench/tests/Tooltip.test.tsx index b953fc911d2..ea43a61f0b4 100644 --- a/tgui/packages/tgui-bench/tests/Tooltip.test.tsx +++ b/tgui/packages/tgui-bench/tests/Tooltip.test.tsx @@ -1,5 +1,5 @@ -import { Box, Tooltip } from "tgui/components"; -import { createRenderer } from "tgui/renderer"; +import { Box, Tooltip } from 'tgui/components'; +import { createRenderer } from 'tgui/renderer'; const render = createRenderer(); diff --git a/tgui/packages/tgui-dev-server/dreamseeker.js b/tgui/packages/tgui-dev-server/dreamseeker.js index 3d4149cf256..eb90b1dc3cf 100644 --- a/tgui/packages/tgui-dev-server/dreamseeker.js +++ b/tgui/packages/tgui-dev-server/dreamseeker.js @@ -24,6 +24,7 @@ export class DreamSeeker { } topic(params = {}) { + // prettier-ignore const query = Object.keys(params) .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(params[key])) @@ -36,7 +37,7 @@ export class DreamSeeker { * @param {number[]} pids * @returns {DreamSeeker[]} */ -DreamSeeker.getInstancesByPids = async pids => { +DreamSeeker.getInstancesByPids = async (pids) => { if (process.platform !== 'win32') { return []; } @@ -46,8 +47,7 @@ DreamSeeker.getInstancesByPids = async pids => { const instance = instanceByPid.get(pid); if (instance) { instances.push(instance); - } - else { + } else { pidsToResolve.push(pid); } } @@ -83,12 +83,10 @@ DreamSeeker.getInstancesByPids = async pids => { instances.push(instance); instanceByPid.set(pid, instance); } - } - catch (err) { + } catch (err) { if (err.code === 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER') { logger.error(err.message, err.code); - } - else { + } else { logger.error(err); } return []; @@ -97,4 +95,4 @@ DreamSeeker.getInstancesByPids = async pids => { return instances; }; -const plural = (word, n) => n !== 1 ? word + 's' : word; +const plural = (word, n) => (n !== 1 ? word + 's' : word); diff --git a/tgui/packages/tgui-dev-server/link/client.cjs b/tgui/packages/tgui-dev-server/link/client.cjs index fe75314acd3..1e21d42ce86 100644 --- a/tgui/packages/tgui-dev-server/link/client.cjs +++ b/tgui/packages/tgui-dev-server/link/client.cjs @@ -23,7 +23,7 @@ const ensureConnection = () => { socket.send(msg); } }; - socket.onmessage = event => { + socket.onmessage = (event) => { const msg = JSON.parse(event.data); for (let subscriber of subscribers) { subscriber(msg); @@ -37,14 +37,14 @@ if (process.env.NODE_ENV !== 'production') { window.onunload = () => socket && socket.close(); } -const subscribe = fn => subscribers.push(fn); +const subscribe = (fn) => subscribers.push(fn); /** * A json serializer which handles circular references and other junk. */ -const serializeObject = obj => { +const serializeObject = (obj) => { let refs = []; - const primitiveReviver = value => { + const primitiveReviver = (value) => { if (typeof value === 'number' && !Number.isFinite(value)) { return { __number__: String(value), @@ -68,6 +68,7 @@ const serializeObject = obj => { } refs.push(value); // Error object + // prettier-ignore const isError = value instanceof Error || ( value.code && value.message && value.message.includes('Error') ); @@ -91,7 +92,7 @@ const serializeObject = obj => { return json; }; -const sendMessage = msg => { +const sendMessage = (msg) => { if (process.env.NODE_ENV !== 'production') { const json = serializeObject(msg); // Send message using WebSocket @@ -99,8 +100,7 @@ const sendMessage = msg => { ensureConnection(); if (socket.readyState === WebSocket.OPEN) { socket.send(json); - } - else { + } else { // Keep only 100 latest messages in the queue if (queue.length > 100) { queue.shift(); @@ -130,19 +130,21 @@ const sendLogEntry = (level, ns, ...args) => { args, }, }); - } - catch (err) {} + } catch (err) {} } }; const setupHotReloading = () => { - if (process.env.NODE_ENV !== 'production' + if ( + // prettier-ignore + process.env.NODE_ENV !== 'production' && process.env.WEBPACK_HMR_ENABLED - && window.WebSocket) { + && window.WebSocket + ) { if (module.hot) { ensureConnection(); sendLogEntry(0, null, 'setting up hot reloading'); - subscribe(msg => { + subscribe((msg) => { const { type } = msg; sendLogEntry(0, null, 'received', type); if (type === 'hotUpdate') { @@ -157,10 +159,10 @@ const setupHotReloading = () => { ignoreDeclined: true, ignoreErrored: true, }) - .then(modules => { + .then((modules) => { sendLogEntry(0, null, 'outdated modules', modules); }) - .catch(err => { + .catch((err) => { sendLogEntry(0, null, 'reload error', err); }); } diff --git a/tgui/packages/tgui-dev-server/link/retrace.js b/tgui/packages/tgui-dev-server/link/retrace.js index c10ba9cb173..842de228fdf 100644 --- a/tgui/packages/tgui-dev-server/link/retrace.js +++ b/tgui/packages/tgui-dev-server/link/retrace.js @@ -18,7 +18,7 @@ const logger = createLogger('retrace'); const { SourceMapConsumer } = SourceMap; const sourceMaps = []; -export const loadSourceMaps = async bundleDir => { +export const loadSourceMaps = async (bundleDir) => { // Destroy and garbage collect consumers while (sourceMaps.length !== 0) { const { consumer } = sourceMaps.shift(); @@ -30,29 +30,29 @@ export const loadSourceMaps = async bundleDir => { try { const file = basename(path).replace('.map', ''); const consumer = await new SourceMapConsumer( - JSON.parse(fs.readFileSync(path, 'utf8'))); + JSON.parse(fs.readFileSync(path, 'utf8')) + ); sourceMaps.push({ file, consumer }); - } - catch (err) { + } catch (err) { logger.error(err); } } logger.log(`loaded ${sourceMaps.length} source maps`); }; -export const retrace = stack => { +export const retrace = (stack) => { if (typeof stack !== 'string') { logger.log('ERROR: Stack is not a string!', stack); return stack; } const header = stack.split(/\n\s.*at/)[0]; const mappedStack = parseStackTrace(stack) - .map(frame => { + .map((frame) => { if (!frame.file) { return frame; } // Find the correct source map - const sourceMap = sourceMaps.find(sourceMap => { + const sourceMap = sourceMaps.find((sourceMap) => { return frame.file.includes(sourceMap.file); }); if (!sourceMap) { @@ -72,7 +72,7 @@ export const retrace = stack => { column: mappedFrame.column, }; }) - .map(frame => { + .map((frame) => { // Stringify the frame const { file, methodName, lineNumber } = frame; if (!file) { diff --git a/tgui/packages/tgui-dev-server/link/server.js b/tgui/packages/tgui-dev-server/link/server.js index 87a8a5911bc..60cc78c1bd9 100644 --- a/tgui/packages/tgui-dev-server/link/server.js +++ b/tgui/packages/tgui-dev-server/link/server.js @@ -32,9 +32,9 @@ class LinkServer { setupWebSocketLink() { const port = 3000; this.wss = new WebSocket.Server({ port }); - this.wss.on('connection', ws => { + this.wss.on('connection', (ws) => { logger.log('client connected'); - ws.on('message', json => { + ws.on('message', (json) => { const msg = deserializeObject(json); this.handleLinkMessage(ws, msg); }); @@ -51,7 +51,7 @@ class LinkServer { this.httpServer = http.createServer((req, res) => { if (req.method === 'POST') { let body = ''; - req.on('data', chunk => { + req.on('data', (chunk) => { body += chunk.toString(); }); req.on('end', () => { @@ -76,6 +76,7 @@ class LinkServer { if (level <= 0 && !DEBUG) { return; } + // prettier-ignore directLog(ns, ...args.map(arg => { if (typeof arg === 'object') { return inspect(arg, { @@ -117,7 +118,7 @@ class LinkServer { } } -const deserializeObject = str => { +const deserializeObject = (str) => { return JSON.parse(str, (key, value) => { if (typeof value === 'object' && value !== null) { if (value.__undefined__) { diff --git a/tgui/packages/tgui-dev-server/logging.js b/tgui/packages/tgui-dev-server/logging.js index 0dc222ae3d7..4ec09008ff5 100644 --- a/tgui/packages/tgui-dev-server/logging.js +++ b/tgui/packages/tgui-dev-server/logging.js @@ -11,8 +11,7 @@ const isNode = process && process.release && process.release.name === 'node'; let isChrome = false; try { isChrome = window.navigator.userAgent.toLowerCase().includes('chrome'); -} -catch {} +} catch {} // Timestamping function const getTimestamp = () => { @@ -32,7 +31,7 @@ const getPrefix = (() => { bright: '\x1b[37;1m', reset: '\x1b[0m', }; - return ns => [ + return (ns) => [ `${ESC.dimmed}${getTimestamp()} ${ESC.bright}${ns}${ESC.reset}`, ]; } @@ -42,12 +41,13 @@ const getPrefix = (() => { dimmed: 'color: #888', bright: 'font-weight: bold', }; - return ns => [ + return (ns) => [ `%c${getTimestamp()}%c ${ns}`, styles.dimmed, styles.bright, ]; } + // prettier-ignore return ns => [ `${getTimestamp()} ${ns}`, ]; @@ -56,7 +56,7 @@ const getPrefix = (() => { /** * Creates a logger object. */ -export const createLogger = ns => ({ +export const createLogger = (ns) => ({ log: (...args) => console.log(...getPrefix(ns), ...args), trace: (...args) => console.trace(...getPrefix(ns), ...args), debug: (...args) => console.debug(...getPrefix(ns), ...args), diff --git a/tgui/packages/tgui-dev-server/reloader.js b/tgui/packages/tgui-dev-server/reloader.js index 5722cee644b..444d9e40cd5 100644 --- a/tgui/packages/tgui-dev-server/reloader.js +++ b/tgui/packages/tgui-dev-server/reloader.js @@ -50,10 +50,9 @@ export const findCacheRoot = async () => { // Query the Windows Registry if (process.platform === 'win32') { logger.log('querying windows registry'); - let userpath = await regQuery( - 'HKCU\\Software\\Dantom\\BYOND', - 'userpath'); + let userpath = await regQuery('HKCU\\Software\\Dantom\\BYOND', 'userpath'); if (userpath) { + // prettier-ignore cacheRoot = userpath .replace(/\\$/, '') .replace(/\\/g, '/') @@ -65,13 +64,13 @@ export const findCacheRoot = async () => { logger.log('found no cache directories'); }; -const onCacheRootFound = cacheRoot => { +const onCacheRootFound = (cacheRoot) => { logger.log(`found cache at '${cacheRoot}'`); // Plant a dummy fs.closeSync(fs.openSync(cacheRoot + '/dummy', 'w')); }; -export const reloadByondCache = async bundleDir => { +export const reloadByondCache = async (bundleDir) => { const cacheRoot = await findCacheRoot(); if (!cacheRoot) { return; @@ -83,15 +82,21 @@ export const reloadByondCache = async bundleDir => { return; } // Get dreamseeker instances - const pids = cacheDirs.map(cacheDir => ( + const pids = cacheDirs.map((cacheDir) => parseInt(cacheDir.split('/cache/tmp').pop(), 10) - )); + ); const dssPromise = DreamSeeker.getInstancesByPids(pids); // Copy assets - const assets = await resolveGlob(bundleDir, './*.+(bundle|chunk|hot-update).*'); + const assets = await resolveGlob( + bundleDir, + './*.+(bundle|chunk|hot-update).*' + ); for (let cacheDir of cacheDirs) { // Clear garbage - const garbage = await resolveGlob(cacheDir, './*.+(bundle|chunk|hot-update).*'); + const garbage = await resolveGlob( + cacheDir, + './*.+(bundle|chunk|hot-update).*' + ); try { for (let file of garbage) { fs.unlinkSync(file); @@ -102,8 +107,7 @@ export const reloadByondCache = async bundleDir => { fs.writeFileSync(destination, fs.readFileSync(asset)); } logger.log(`copied ${assets.length} files to '${cacheDir}'`); - } - catch (err) { + } catch (err) { logger.error(`failed copying to '${cacheDir}'`); logger.error(err); } diff --git a/tgui/packages/tgui-dev-server/util.js b/tgui/packages/tgui-dev-server/util.js index 0fc255ed674..9d07b96c71a 100644 --- a/tgui/packages/tgui-dev-server/util.js +++ b/tgui/packages/tgui-dev-server/util.js @@ -25,8 +25,7 @@ export const resolveGlob = (...sections) => { try { fs.statSync(path); safePaths.push(path); - } - catch {} + } catch {} } return safePaths; }; diff --git a/tgui/packages/tgui-dev-server/webpack.js b/tgui/packages/tgui-dev-server/webpack.js index 8cba68afcba..139610b79ce 100644 --- a/tgui/packages/tgui-dev-server/webpack.js +++ b/tgui/packages/tgui-dev-server/webpack.js @@ -18,7 +18,7 @@ const logger = createLogger('webpack'); * @param {any} config * @return {WebpackCompiler} */ -export const createCompiler = async options => { +export const createCompiler = async (options) => { const compiler = new WebpackCompiler(); await compiler.setup(options); return compiler; @@ -57,7 +57,7 @@ class WebpackCompiler { logger.log('compiling'); }); // Start reloading when it's finished - compiler.hooks.done.tap('tgui-dev-server', async stats => { + compiler.hooks.done.tap('tgui-dev-server', async (stats) => { // Load source maps await loadSourceMaps(this.bundleDir); // Reload cache @@ -77,7 +77,7 @@ class WebpackCompiler { stats .toString(this.config.devServer.stats) .split('\n') - .forEach(line => logger.log(line)); + .forEach((line) => logger.log(line)); }); } } diff --git a/tgui/packages/tgui-dev-server/winreg.js b/tgui/packages/tgui-dev-server/winreg.js index 669e2aad55d..b61fddc1a25 100644 --- a/tgui/packages/tgui-dev-server/winreg.js +++ b/tgui/packages/tgui-dev-server/winreg.js @@ -30,17 +30,14 @@ export const regQuery = async (path, key) => { logger.error('could not find the end of the line'); return null; } - const indexOfValue = stdout.indexOf( - ' ', - indexOfKey + keyPattern.length); + const indexOfValue = stdout.indexOf(' ', indexOfKey + keyPattern.length); if (indexOfValue === -1) { logger.error('could not find the start of the key value'); return null; } const value = stdout.substring(indexOfValue + 4, indexOfEol); return value; - } - catch (err) { + } catch (err) { logger.error(err); return null; } diff --git a/tgui/packages/tgui-panel/Notifications.js b/tgui/packages/tgui-panel/Notifications.js index a64ddd8e306..2b92995287f 100644 --- a/tgui/packages/tgui-panel/Notifications.js +++ b/tgui/packages/tgui-panel/Notifications.js @@ -6,33 +6,20 @@ import { Flex } from 'tgui/components'; -export const Notifications = props => { +export const Notifications = (props) => { const { children } = props; - return ( -
- {children} -
- ); + return
{children}
; }; -const NotificationsItem = props => { - const { - rightSlot, - children, - } = props; +const NotificationsItem = (props) => { + const { rightSlot, children } = props; return ( - - + + {children} {rightSlot && ( - - {rightSlot} - + {rightSlot} )} ); diff --git a/tgui/packages/tgui-panel/Panel.js b/tgui/packages/tgui-panel/Panel.js index a09875e9b2f..83150ab6ef1 100644 --- a/tgui/packages/tgui-panel/Panel.js +++ b/tgui/packages/tgui-panel/Panel.js @@ -17,9 +17,7 @@ import { SettingsPanel, useSettings } from './settings'; export const Panel = (props, context) => { // IE8-10: Needs special treatment due to missing Flex support if (Byond.IS_LTE_IE10) { - return ( - - ); + return ; } const audio = useAudio(context); const settings = useSettings(context); @@ -28,9 +26,7 @@ export const Panel = (props, context) => { const { useDebug, KitchenSink } = require('tgui/debug'); const debug = useDebug(context); if (debug.kitchenSink) { - return ( - - ); + return ; } } return ( @@ -52,17 +48,19 @@ export const Panel = (props, context) => { icon="music" tooltip="Music player" tooltipPosition="bottom-start" - onClick={() => audio.toggle()} /> + onClick={() => audio.toggle()} + /> - {settings.visible && ( - - ) || ( + {(settings.visible && ) || ( )} diff --git a/tgui/packages/tgui-panel/audio/NowPlayingWidget.js b/tgui/packages/tgui-panel/audio/NowPlayingWidget.js index b7a30363d50..b994cb6a01b 100644 --- a/tgui/packages/tgui-panel/audio/NowPlayingWidget.js +++ b/tgui/packages/tgui-panel/audio/NowPlayingWidget.js @@ -17,12 +17,9 @@ export const NowPlayingWidget = (props, context) => { const title = audio.meta?.title; return ( - {audio.playing && ( + {(audio.playing && ( <> - + Now playing: { {'An admin-played soundtrack.'} - ) || ( + )) || ( Nothing to play. @@ -46,9 +43,12 @@ export const NowPlayingWidget = (props, context) => {
- {MESSAGE_TYPES - .filter(typeDef => !typeDef.important && !typeDef.admin) - .map(typeDef => ( + {MESSAGE_TYPES.filter( + (typeDef) => !typeDef.important && !typeDef.admin + ).map((typeDef) => ( + + dispatch( + toggleAcceptedType({ + pageId: page.id, + type: typeDef.type, + }) + ) + }> + {typeDef.name} + + ))} + + {MESSAGE_TYPES.filter( + (typeDef) => !typeDef.important && typeDef.admin + ).map((typeDef) => ( dispatch(toggleAcceptedType({ - pageId: page.id, - type: typeDef.type, - }))}> + onClick={() => + dispatch( + toggleAcceptedType({ + pageId: page.id, + type: typeDef.type, + }) + ) + }> {typeDef.name} ))} - - {MESSAGE_TYPES - .filter(typeDef => !typeDef.important && typeDef.admin) - .map(typeDef => ( - dispatch(toggleAcceptedType({ - pageId: page.id, - type: typeDef.type, - }))}> - {typeDef.name} - - ))}
diff --git a/tgui/packages/tgui-panel/chat/ChatPanel.js b/tgui/packages/tgui-panel/chat/ChatPanel.js index 0a5deaf9feb..3132a66ce7f 100644 --- a/tgui/packages/tgui-panel/chat/ChatPanel.js +++ b/tgui/packages/tgui-panel/chat/ChatPanel.js @@ -16,30 +16,34 @@ export class ChatPanel extends Component { this.state = { scrollTracking: true, }; - this.handleScrollTrackingChange = value => this.setState({ - scrollTracking: value, - }); + this.handleScrollTrackingChange = (value) => + this.setState({ + scrollTracking: value, + }); } componentDidMount() { chatRenderer.mount(this.ref.current); - chatRenderer.events.on('scrollTrackingChanged', - this.handleScrollTrackingChange); + chatRenderer.events.on( + 'scrollTrackingChanged', + this.handleScrollTrackingChange + ); this.componentDidUpdate(); } componentWillUnmount() { - chatRenderer.events.off('scrollTrackingChanged', - this.handleScrollTrackingChange); + chatRenderer.events.off( + 'scrollTrackingChanged', + this.handleScrollTrackingChange + ); } componentDidUpdate(prevProps) { requestAnimationFrame(() => { chatRenderer.ensureScrollTracking(); }); - const shouldUpdateStyle = ( - !prevProps || shallowDiffers(this.props, prevProps) - ); + const shouldUpdateStyle = + !prevProps || shallowDiffers(this.props, prevProps); if (shouldUpdateStyle) { chatRenderer.assignStyle({ 'width': '100%', @@ -51,9 +55,7 @@ export class ChatPanel extends Component { } render() { - const { - scrollTracking, - } = this.state; + const { scrollTracking } = this.state; return ( <>
diff --git a/tgui/packages/tgui-panel/chat/ChatTabs.js b/tgui/packages/tgui-panel/chat/ChatTabs.js index a0e6cc59e52..1d4f6f65edf 100644 --- a/tgui/packages/tgui-panel/chat/ChatTabs.js +++ b/tgui/packages/tgui-panel/chat/ChatTabs.js @@ -32,16 +32,22 @@ export const ChatTabs = (props, context) => { - {pages.map(page => ( + {pages.map((page) => ( 0 && ( - - )} - onClick={() => dispatch(changeChatPage({ - pageId: page.id, - }))}> + rightSlot={ + page.unreadCount > 0 && ( + + ) + } + onClick={() => + dispatch( + changeChatPage({ + pageId: page.id, + }) + ) + }> {page.name} ))} @@ -54,7 +60,8 @@ export const ChatTabs = (props, context) => { onClick={() => { dispatch(addChatPage()); dispatch(openChatSettings()); - }} /> + }} + /> ); diff --git a/tgui/packages/tgui-panel/chat/constants.js b/tgui/packages/tgui-panel/chat/constants.js index c0a5dbaee0d..bf7e8e1d439 100644 --- a/tgui/packages/tgui-panel/chat/constants.js +++ b/tgui/packages/tgui-panel/chat/constants.js @@ -59,19 +59,22 @@ export const MESSAGE_TYPES = [ type: MESSAGE_TYPE_RADIO, name: 'Radio', description: 'All departments of radio messages', - selector: '.alert, .minorannounce, .syndradio, .centcomradio, .aiprivradio, .comradio, .secradio, .gangradio, .engradio, .medradio, .sciradio, .suppradio, .servradio, .radio, .deptradio, .binarysay, .newscaster, .resonate', + selector: + '.alert, .minorannounce, .syndradio, .centcomradio, .aiprivradio, .comradio, .secradio, .gangradio, .engradio, .medradio, .sciradio, .suppradio, .servradio, .radio, .deptradio, .binarysay, .newscaster, .resonate', }, { type: MESSAGE_TYPE_INFO, name: 'Info', description: 'Non-urgent messages from the game and items', - selector: '.notice:not(.pm), .adminnotice, .info, .sinister, .cult, .infoplain, .announce, .hear, .smallnotice, .holoparasite, .boldnotice', + selector: + '.notice:not(.pm), .adminnotice, .info, .sinister, .cult, .infoplain, .announce, .hear, .smallnotice, .holoparasite, .boldnotice', }, { type: MESSAGE_TYPE_WARNING, name: 'Warnings', description: 'Urgent messages from the game and items', - selector: '.warning:not(.pm), .critical, .userdanger, .italics, .alertsyndie, .warningplain', + selector: + '.warning:not(.pm), .critical, .userdanger, .italics, .alertsyndie, .warningplain', }, { type: MESSAGE_TYPE_DEADCHAT, diff --git a/tgui/packages/tgui-panel/chat/middleware.js b/tgui/packages/tgui-panel/chat/middleware.js index 6cfc72bd299..334c438ac0d 100644 --- a/tgui/packages/tgui-panel/chat/middleware.js +++ b/tgui/packages/tgui-panel/chat/middleware.js @@ -15,25 +15,22 @@ import { chatRenderer } from './renderer'; import { selectChat, selectCurrentChatPage } from './selectors'; // List of blacklisted tags -const FORBID_TAGS = [ - 'a', - 'iframe', - 'link', - 'video', -]; +const FORBID_TAGS = ['a', 'iframe', 'link', 'video']; -const saveChatToStorage = async store => { +const saveChatToStorage = async (store) => { const state = selectChat(store.getState()); - const fromIndex = Math.max(0, - chatRenderer.messages.length - MAX_PERSISTED_MESSAGES); + const fromIndex = Math.max( + 0, + chatRenderer.messages.length - MAX_PERSISTED_MESSAGES + ); const messages = chatRenderer.messages .slice(fromIndex) - .map(message => serializeMessage(message)); + .map((message) => serializeMessage(message)); storage.set('chat-state', state); storage.set('chat-messages', messages); }; -const loadChatFromStorage = async store => { +const loadChatFromStorage = async (store) => { const [state, messages] = await Promise.all([ storage.get('chat-state'), storage.get('chat-messages'), @@ -64,10 +61,10 @@ const loadChatFromStorage = async store => { store.dispatch(loadChat(state)); }; -export const chatMiddleware = store => { +export const chatMiddleware = (store) => { let initialized = false; let loaded = false; - chatRenderer.events.on('batchProcessed', countByType => { + chatRenderer.events.on('batchProcessed', (countByType) => { // Use this flag to workaround unread messages caused by // loading them from storage. Side effect of that, is that // message count can not be trusted, only unread count. @@ -75,11 +72,13 @@ export const chatMiddleware = store => { store.dispatch(updateMessageCount(countByType)); } }); - chatRenderer.events.on('scrollTrackingChanged', scrollTracking => { + chatRenderer.events.on('scrollTrackingChanged', (scrollTracking) => { store.dispatch(changeScrollTracking(scrollTracking)); }); - setInterval(() => saveChatToStorage(store), MESSAGE_SAVE_INTERVAL); - return next => action => { + setInterval(() => { + saveChatToStorage(store); + }, MESSAGE_SAVE_INTERVAL); + return (next) => (action) => { const { type, payload } = action; if (!initialized) { initialized = true; @@ -99,10 +98,12 @@ export const chatMiddleware = store => { loaded = true; return; } - if (type === changeChatPage.type - || type === addChatPage.type - || type === removeChatPage.type - || type === toggleAcceptedType.type) { + if ( + type === changeChatPage.type || + type === addChatPage.type || + type === removeChatPage.type || + type === toggleAcceptedType.type + ) { next(action); const page = selectCurrentChatPage(store.getState()); chatRenderer.changePage(page); @@ -119,7 +120,8 @@ export const chatMiddleware = store => { settings.highlightText, settings.highlightColor, settings.matchWord, - settings.matchCase); + settings.matchCase + ); return; } if (type === 'roundrestart') { diff --git a/tgui/packages/tgui-panel/chat/model.js b/tgui/packages/tgui-panel/chat/model.js index 7400d5e13cd..fa12153890d 100644 --- a/tgui/packages/tgui-panel/chat/model.js +++ b/tgui/packages/tgui-panel/chat/model.js @@ -7,11 +7,10 @@ import { createUuid } from 'common/uuid'; import { MESSAGE_TYPES, MESSAGE_TYPE_INTERNAL } from './constants'; -export const canPageAcceptType = (page, type) => ( - type.startsWith(MESSAGE_TYPE_INTERNAL) || page.acceptedTypes[type] -); +export const canPageAcceptType = (page, type) => + type.startsWith(MESSAGE_TYPE_INTERNAL) || page.acceptedTypes[type]; -export const createPage = obj => { +export const createPage = (obj) => { let acceptedTypes = {}; for (let typeDef of MESSAGE_TYPES) { @@ -39,12 +38,12 @@ export const createMainPage = () => { }); }; -export const createMessage = payload => ({ +export const createMessage = (payload) => ({ createdAt: Date.now(), ...payload, }); -export const serializeMessage = message => ({ +export const serializeMessage = (message) => ({ type: message.type, text: message.text, html: message.html, @@ -52,7 +51,6 @@ export const serializeMessage = message => ({ createdAt: message.createdAt, }); -export const isSameMessage = (a, b) => ( - typeof a.text === 'string' && a.text === b.text - || typeof a.html === 'string' && a.html === b.html -); +export const isSameMessage = (a, b) => + (typeof a.text === 'string' && a.text === b.text) || + (typeof a.html === 'string' && a.html === b.html); diff --git a/tgui/packages/tgui-panel/chat/reducer.js b/tgui/packages/tgui-panel/chat/reducer.js index 0188b1fabe8..b727a7c1bab 100644 --- a/tgui/packages/tgui-panel/chat/reducer.js +++ b/tgui/packages/tgui-panel/chat/reducer.js @@ -13,9 +13,7 @@ export const initialState = { version: 5, currentPageId: mainPage.id, scrollTracking: true, - pages: [ - mainPage.id, - ], + pages: [mainPage.id], pageById: { [mainPage.id]: mainPage, }, @@ -74,7 +72,7 @@ export const chatReducer = (state = initialState, action) => { } if (type === updateMessageCount.type) { const countByType = payload; - const pages = state.pages.map(id => state.pageById[id]); + const pages = state.pages.map((id) => state.pageById[id]); const currentPage = state.pageById[state.currentPageId]; const nextPageById = { ...state.pageById }; for (let page of pages) { @@ -170,7 +168,7 @@ export const chatReducer = (state = initialState, action) => { }, }; delete nextState.pageById[pageId]; - nextState.pages = nextState.pages.filter(id => id !== pageId); + nextState.pages = nextState.pages.filter((id) => id !== pageId); if (nextState.pages.length === 0) { nextState.pages.push(mainPage.id); nextState.pageById[mainPage.id] = mainPage; diff --git a/tgui/packages/tgui-panel/chat/renderer.js b/tgui/packages/tgui-panel/chat/renderer.js index b9506611605..869394a78d8 100644 --- a/tgui/packages/tgui-panel/chat/renderer.js +++ b/tgui/packages/tgui-panel/chat/renderer.js @@ -11,7 +11,7 @@ import { COMBINE_MAX_MESSAGES, COMBINE_MAX_TIME_WINDOW, IMAGE_RETRY_DELAY, IMAGE import { render } from 'inferno'; import { canPageAcceptType, createMessage, isSameMessage } from './model'; import { highlightNode, linkifyNode } from './replaceInTextNode'; -import { Tooltip } from "../../tgui/components"; +import { Tooltip } from '../../tgui/components'; const logger = createLogger('chatRenderer'); @@ -27,11 +27,11 @@ export const TGUI_CHAT_COMPONENTS = { // List of injectable attibute names mapped to their proper prop // We need this because attibutes don't support lowercase names export const TGUI_CHAT_ATTRIBUTES_TO_PROPS = { - "position": "position", - "content": "content", + 'position': 'position', + 'content': 'content', }; -const findNearestScrollableParent = startingNode => { +const findNearestScrollableParent = (startingNode) => { const body = document.body; let node = startingNode; while (node && node !== body) { @@ -66,7 +66,7 @@ const createReconnectedNode = () => { return node; }; -const handleImageError = e => { +const handleImageError = (e) => { setTimeout(() => { /** @type {HTMLImageElement} */ const node = e.target; @@ -85,7 +85,7 @@ const handleImageError = e => { /** * Assigns a "times-repeated" badge to the message. */ -const updateMessageBadge = message => { +const updateMessageBadge = (message) => { const { node, times } = message; if (!node || !times) { // Nothing to update @@ -94,10 +94,7 @@ const updateMessageBadge = message => { const foundBadge = node.querySelector('.Chat__badge'); const badge = foundBadge || document.createElement('div'); badge.textContent = times; - badge.className = classes([ - 'Chat__badge', - 'Chat__badge--animate', - ]); + badge.className = classes(['Chat__badge', 'Chat__badge--animate']); requestAnimationFrame(() => { badge.className = 'Chat__badge'; }); @@ -121,13 +118,12 @@ class ChatRenderer { /** @type {HTMLElement} */ this.scrollNode = null; this.scrollTracking = true; - this.handleScroll = type => { + this.handleScroll = (type) => { const node = this.scrollNode; const height = node.scrollHeight; const bottom = node.scrollTop + node.offsetHeight; - const scrollTracking = ( - Math.abs(height - bottom) < SCROLL_TRACKING_TOLERANCE - ); + const scrollTracking = + Math.abs(height - bottom) < SCROLL_TRACKING_TOLERANCE; if (scrollTracking !== this.scrollTracking) { this.scrollTracking = scrollTracking; this.events.emit('scrollTrackingChanged', scrollTracking); @@ -193,18 +189,18 @@ class ChatRenderer { const lines = String(text) .split(',') // eslint-disable-next-line no-useless-escape - .map(str => str.trim().replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')) - .filter(str => ( - // Must be longer than one character - str && str.length > 1 - )); + .map((str) => str.trim().replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')) + // Must be longer than one character + .filter((str) => str && str.length > 1); // Nothing to match, reset highlighting if (lines.length === 0) { this.highlightRegex = null; this.highlightColor = null; return; } - const pattern = `${(matchWord ? '\\b' : '')}(${lines.join('|')})${(matchWord ? '\\b' : '')}`; + const pattern = `${matchWord ? '\\b' : ''}(${lines.join('|')})${ + matchWord ? '\\b' : '' + }`; const flags = 'g' + (matchCase ? '' : 'i'); this.highlightRegex = new RegExp(pattern, flags); this.highlightColor = color; @@ -249,6 +245,7 @@ class ChatRenderer { const to = Math.max(0, len - COMBINE_MAX_MESSAGES); for (let i = from; i >= to; i--) { const message = this.visibleMessages[i]; + // prettier-ignore const matches = ( // Is not an internal message !message.type.startsWith(MESSAGE_TYPE_INTERNAL) @@ -265,17 +262,13 @@ class ChatRenderer { } processBatch(batch, options = {}) { - const { - prepend, - notifyListeners = true, - } = options; + const { prepend, notifyListeners = true } = options; const now = Date.now(); // Queue up messages until chat is ready if (!this.isReady()) { if (prepend) { this.queue = [...batch, ...this.queue]; - } - else { + } else { this.queue = [...this.queue, ...batch]; } return; @@ -311,15 +304,14 @@ class ChatRenderer { // Payload is HTML else if (message.html) { node.innerHTML = message.html; - } - else { + } else { logger.error('Error: message is missing text payload', message); } // Get all nodes in this message that want to be rendered like jsx - const nodes = node.querySelectorAll("[data-component]"); + const nodes = node.querySelectorAll('[data-component]'); for (let i = 0; i < nodes.length; i++) { const childNode = nodes[i]; - const targetName = childNode.getAttribute("data-component"); + const targetName = childNode.getAttribute('data-component'); // Let's pull out the attibute info we need let outputProps = {}; for (let j = 0; j < childNode.attributes.length; j++) { @@ -328,20 +320,18 @@ class ChatRenderer { let working_value = attribute.nodeValue; // We can't do the "if it has no value it's truthy" trick // Because getAttribute returns "", not null. Hate IE - if (working_value === "$true") { + if (working_value === '$true') { working_value = true; - } - else if (working_value === "$false") { + } else if (working_value === '$false') { working_value = false; - } - else if (!isNaN(working_value)) { + } else if (!isNaN(working_value)) { const parsed_float = parseFloat(working_value); if (!isNaN(parsed_float)) { working_value = parsed_float; } } - let canon_name = attribute.nodeName.replace("data-", ""); + let canon_name = attribute.nodeName.replace('data-', ''); // html attributes don't support upper case chars, so we need to map canon_name = TGUI_CHAT_ATTRIBUTES_TO_PROPS[canon_name]; outputProps[canon_name] = working_value; @@ -355,18 +345,17 @@ class ChatRenderer { render( - , childNode); + , + childNode + ); /* eslint-enable react/no-danger */ - } // Highlight text if (!message.avoidHighlighting && this.highlightRegex) { - const highlighted = highlightNode(node, - this.highlightRegex, - text => ( - createHighlightNode(text, this.highlightColor) - )); + const highlighted = highlightNode(node, this.highlightRegex, (text) => + createHighlightNode(text, this.highlightColor) + ); if (highlighted) { node.className += ' ChatMessage--highlighted'; } @@ -391,6 +380,7 @@ class ChatRenderer { if (!message.type) { // IE8: Does not support querySelector on elements that // are not yet in the document. + // prettier-ignore const typeDef = !Byond.IS_LTE_IE8 && MESSAGE_TYPES .find(typeDef => ( typeDef.selector && node.querySelector(typeDef.selector) @@ -413,8 +403,7 @@ class ChatRenderer { const firstChild = this.rootNode.childNodes[0]; if (prepend && firstChild) { this.rootNode.insertBefore(fragment, firstChild); - } - else { + } else { this.rootNode.appendChild(fragment); } if (this.scrollTracking) { @@ -440,8 +429,7 @@ class ChatRenderer { // Visible messages { const messages = this.visibleMessages; - const fromIndex = Math.max(0, - messages.length - MAX_VISIBLE_MESSAGES); + const fromIndex = Math.max(0, messages.length - MAX_VISIBLE_MESSAGES); if (fromIndex > 0) { this.visibleMessages = messages.slice(fromIndex); for (let i = 0; i < fromIndex; i++) { @@ -451,6 +439,7 @@ class ChatRenderer { message.node = 'pruned'; } // Remove pruned messages from the message array + // prettier-ignore this.messages = this.messages.filter(message => ( message.node !== 'pruned' )); @@ -459,8 +448,10 @@ class ChatRenderer { } // All messages { - const fromIndex = Math.max(0, - this.messages.length - MAX_PERSISTED_MESSAGES); + const fromIndex = Math.max( + 0, + this.messages.length - MAX_PERSISTED_MESSAGES + ); if (fromIndex > 0) { this.messages = this.messages.slice(fromIndex); logger.log(`pruned ${fromIndex} stored messages`); @@ -473,8 +464,10 @@ class ChatRenderer { return; } // Make a copy of messages - const fromIndex = Math.max(0, - this.messages.length - MAX_PERSISTED_MESSAGES); + const fromIndex = Math.max( + 0, + this.messages.length - MAX_PERSISTED_MESSAGES + ); const messages = this.messages.slice(fromIndex); // Remove existing nodes for (let message of messages) { @@ -514,6 +507,7 @@ class ChatRenderer { } } // Create a page + // prettier-ignore const pageHtml = '\n' + '\n' + '\n' diff --git a/tgui/packages/tgui-panel/chat/replaceInTextNode.js b/tgui/packages/tgui-panel/chat/replaceInTextNode.js index 0db2b2193e8..fc10772622d 100644 --- a/tgui/packages/tgui-panel/chat/replaceInTextNode.js +++ b/tgui/packages/tgui-panel/chat/replaceInTextNode.js @@ -7,7 +7,7 @@ /** * Replaces text matching a regular expression with a custom node. */ -export const replaceInTextNode = (regex, createNode) => node => { +export const replaceInTextNode = (regex, createNode) => (node) => { const text = node.textContent; const textLength = text.length; let match; @@ -15,7 +15,7 @@ export const replaceInTextNode = (regex, createNode) => node => { let fragment; let n = 0; // eslint-disable-next-line no-cond-assign - while (match = regex.exec(text)) { + while ((match = regex.exec(text))) { n += 1; // Lazy init fragment if (!fragment) { @@ -26,8 +26,9 @@ export const replaceInTextNode = (regex, createNode) => node => { const matchIndex = match.index; // Insert previous unmatched chunk if (lastIndex < matchIndex) { - fragment.appendChild(document.createTextNode( - text.substring(lastIndex, matchIndex))); + fragment.appendChild( + document.createTextNode(text.substring(lastIndex, matchIndex)) + ); } lastIndex = matchIndex + matchLength; // Create a wrapper node @@ -36,8 +37,9 @@ export const replaceInTextNode = (regex, createNode) => node => { if (fragment) { // Insert the remaining unmatched chunk if (lastIndex < textLength) { - fragment.appendChild(document.createTextNode( - text.substring(lastIndex, textLength))); + fragment.appendChild( + document.createTextNode(text.substring(lastIndex, textLength)) + ); } // Commit the fragment node.parentNode.replaceChild(fragment, node); @@ -45,17 +47,15 @@ export const replaceInTextNode = (regex, createNode) => node => { return n; }; - // Highlight // -------------------------------------------------------- /** * Default highlight node. */ -const createHighlightNode = text => { +const createHighlightNode = (text) => { const node = document.createElement('span'); - node.setAttribute('style', - 'background-color:#fd4;color:#000'); + node.setAttribute('style', 'background-color:#fd4;color:#000'); node.textContent = text; return node; }; @@ -71,7 +71,7 @@ const createHighlightNode = text => { export const highlightNode = ( node, regex, - createNode = createHighlightNode, + createNode = createHighlightNode ) => { if (!createNode) { createNode = createHighlightNode; @@ -83,18 +83,17 @@ export const highlightNode = ( // Is a text node if (node.nodeType === 3) { n += replaceInTextNode(regex, createNode)(node); - } - else { + } else { n += highlightNode(node, regex, createNode); } } return n; }; - // Linkify // -------------------------------------------------------- +// prettier-ignore const URL_REGEX = /(?:(?:https?:\/\/)|(?:www\.))(?:[^ ]*?\.[^ ]*?)+[-A-Za-z0-9+&@#/%?=~_|$!:,.;()]+/ig; /** @@ -103,7 +102,7 @@ const URL_REGEX = /(?:(?:https?:\/\/)|(?:www\.))(?:[^ ]*?\.[^ ]*?)+[-A-Za-z0-9+& * @param {Node} node Node which you want to process * @returns {number} Number of matches */ -export const linkifyNode = node => { +export const linkifyNode = (node) => { let n = 0; const childNodes = node.childNodes; for (let i = 0; i < childNodes.length; i++) { @@ -112,15 +111,14 @@ export const linkifyNode = node => { // Is a text node if (node.nodeType === 3) { n += linkifyTextNode(node); - } - else if (tag !== 'a') { + } else if (tag !== 'a') { n += linkifyNode(node); } } return n; }; -const linkifyTextNode = replaceInTextNode(URL_REGEX, text => { +const linkifyTextNode = replaceInTextNode(URL_REGEX, (text) => { const node = document.createElement('a'); node.href = text; node.textContent = text; diff --git a/tgui/packages/tgui-panel/chat/selectors.js b/tgui/packages/tgui-panel/chat/selectors.js index 2bcc6531840..6352b7cddf0 100644 --- a/tgui/packages/tgui-panel/chat/selectors.js +++ b/tgui/packages/tgui-panel/chat/selectors.js @@ -6,16 +6,12 @@ import { map } from 'common/collections'; -export const selectChat = state => state.chat; +export const selectChat = (state) => state.chat; -export const selectChatPages = state => ( - map(id => state.chat.pageById[id])(state.chat.pages) -); +export const selectChatPages = (state) => + map((id) => state.chat.pageById[id])(state.chat.pages); -export const selectCurrentChatPage = state => ( - state.chat.pageById[state.chat.currentPageId] -); +export const selectCurrentChatPage = (state) => + state.chat.pageById[state.chat.currentPageId]; -export const selectChatPageById = id => state => ( - state.chat.pageById[id] -); +export const selectChatPageById = (id) => (state) => state.chat.pageById[id]; diff --git a/tgui/packages/tgui-panel/game/hooks.js b/tgui/packages/tgui-panel/game/hooks.js index e9567b916b4..859aaa09a40 100644 --- a/tgui/packages/tgui-panel/game/hooks.js +++ b/tgui/packages/tgui-panel/game/hooks.js @@ -7,6 +7,6 @@ import { useSelector } from 'common/redux'; import { selectGame } from './selectors'; -export const useGame = context => { +export const useGame = (context) => { return useSelector(context, selectGame); }; diff --git a/tgui/packages/tgui-panel/game/middleware.js b/tgui/packages/tgui-panel/game/middleware.js index ba1ec63f9ec..53dd45bb46e 100644 --- a/tgui/packages/tgui-panel/game/middleware.js +++ b/tgui/packages/tgui-panel/game/middleware.js @@ -9,7 +9,7 @@ import { connectionLost, connectionRestored, roundRestarted } from './actions'; import { selectGame } from './selectors'; import { CONNECTION_LOST_AFTER } from './constants'; -const withTimestamp = action => ({ +const withTimestamp = (action) => ({ ...action, meta: { ...action.meta, @@ -17,7 +17,7 @@ const withTimestamp = action => ({ }, }); -export const gameMiddleware = store => { +export const gameMiddleware = (store) => { let lastPingedAt; setInterval(() => { @@ -26,8 +26,8 @@ export const gameMiddleware = store => { return; } const game = selectGame(state); - const pingsAreFailing = lastPingedAt - && Date.now() >= lastPingedAt + CONNECTION_LOST_AFTER; + const pingsAreFailing = + lastPingedAt && Date.now() >= lastPingedAt + CONNECTION_LOST_AFTER; if (!game.connectionLostAt && pingsAreFailing) { store.dispatch(withTimestamp(connectionLost())); } @@ -36,7 +36,7 @@ export const gameMiddleware = store => { } }, 1000); - return next => action => { + return (next) => (action) => { const { type } = action; if (type === pingSuccess.type || type === pingSoft.type) { diff --git a/tgui/packages/tgui-panel/game/selectors.js b/tgui/packages/tgui-panel/game/selectors.js index dc2d7040f9c..a3b93b327d9 100644 --- a/tgui/packages/tgui-panel/game/selectors.js +++ b/tgui/packages/tgui-panel/game/selectors.js @@ -4,4 +4,4 @@ * @license MIT */ -export const selectGame = state => state.game; +export const selectGame = (state) => state.game; diff --git a/tgui/packages/tgui-panel/index.js b/tgui/packages/tgui-panel/index.js index 721fa97fb50..6bc6b32c462 100644 --- a/tgui/packages/tgui-panel/index.js +++ b/tgui/packages/tgui-panel/index.js @@ -86,7 +86,7 @@ const setupApp = () => { }); // Resize the panel to match the non-browser output - Byond.winget('output').then(output => { + Byond.winget('output').then((output) => { Byond.winset('browseroutput', { 'size': output.size, }); @@ -95,6 +95,7 @@ const setupApp = () => { // Enable hot module reloading if (module.hot) { setupHotReloading(); + // prettier-ignore module.hot.accept([ './audio', './chat', diff --git a/tgui/packages/tgui-panel/panelFocus.js b/tgui/packages/tgui-panel/panelFocus.js index 6922418c899..b7cea229314 100644 --- a/tgui/packages/tgui-panel/panelFocus.js +++ b/tgui/packages/tgui-panel/panelFocus.js @@ -20,13 +20,13 @@ const deferredFocusMap = () => setImmediate(() => focusMap()); export const setupPanelFocusHacks = () => { let focusStolen = false; let clickStartPos = null; - window.addEventListener('focusin', e => { + window.addEventListener('focusin', (e) => { focusStolen = canStealFocus(e.target); }); - window.addEventListener('mousedown', e => { + window.addEventListener('mousedown', (e) => { clickStartPos = [e.screenX, e.screenY]; }); - window.addEventListener('mouseup', e => { + window.addEventListener('mouseup', (e) => { if (clickStartPos) { const clickEndPos = [e.screenX, e.screenY]; const dist = vecLength(vecSubtract(clickEndPos, clickStartPos)); @@ -38,7 +38,7 @@ export const setupPanelFocusHacks = () => { deferredFocusMap(); } }); - globalEvents.on('keydown', key => { + globalEvents.on('keydown', (key) => { if (key.isModifierKey()) { return; } diff --git a/tgui/packages/tgui-panel/ping/PingIndicator.js b/tgui/packages/tgui-panel/ping/PingIndicator.js index b663cd3a180..aadbd1c134b 100644 --- a/tgui/packages/tgui-panel/ping/PingIndicator.js +++ b/tgui/packages/tgui-panel/ping/PingIndicator.js @@ -17,14 +17,10 @@ export const PingIndicator = (props, context) => { new Color(220, 200, 40), new Color(60, 220, 40), ]); - const roundtrip = ping.roundtrip - ? toFixed(ping.roundtrip) - : '--'; + const roundtrip = ping.roundtrip ? toFixed(ping.roundtrip) : '--'; return (
- + {roundtrip}
); diff --git a/tgui/packages/tgui-panel/ping/middleware.js b/tgui/packages/tgui-panel/ping/middleware.js index fb86de9cc48..e5b593d822f 100644 --- a/tgui/packages/tgui-panel/ping/middleware.js +++ b/tgui/packages/tgui-panel/ping/middleware.js @@ -7,7 +7,7 @@ import { pingFail, pingReply, pingSoft, pingSuccess } from './actions'; import { PING_QUEUE_SIZE, PING_TIMEOUT } from './constants'; -export const pingMiddleware = store => { +export const pingMiddleware = (store) => { let initialized = false; let index = 0; const pings = []; @@ -26,7 +26,7 @@ export const pingMiddleware = store => { index = (index + 1) % PING_QUEUE_SIZE; }; - return next => action => { + return (next) => (action) => { const { type, payload } = action; if (!initialized) { diff --git a/tgui/packages/tgui-panel/ping/reducer.js b/tgui/packages/tgui-panel/ping/reducer.js index 874cb75a9b8..b1e3d679cbc 100644 --- a/tgui/packages/tgui-panel/ping/reducer.js +++ b/tgui/packages/tgui-panel/ping/reducer.js @@ -15,8 +15,8 @@ export const pingReducer = (state = {}, action) => { const { roundtrip } = payload; const prevRoundtrip = state.roundtripAvg || roundtrip; const roundtripAvg = Math.round(prevRoundtrip * 0.4 + roundtrip * 0.6); - const networkQuality = 1 - scale(roundtripAvg, - PING_ROUNDTRIP_BEST, PING_ROUNDTRIP_WORST); + const networkQuality = + 1 - scale(roundtripAvg, PING_ROUNDTRIP_BEST, PING_ROUNDTRIP_WORST); return { roundtrip, roundtripAvg, @@ -27,8 +27,9 @@ export const pingReducer = (state = {}, action) => { if (type === pingFail.type) { const { failCount = 0 } = state; - const networkQuality = clamp01(state.networkQuality - - failCount / PING_MAX_FAILS); + const networkQuality = clamp01( + state.networkQuality - failCount / PING_MAX_FAILS + ); const nextState = { ...state, failCount: failCount + 1, diff --git a/tgui/packages/tgui-panel/ping/selectors.js b/tgui/packages/tgui-panel/ping/selectors.js index cfbe95c2f32..1b8bfb4ee40 100644 --- a/tgui/packages/tgui-panel/ping/selectors.js +++ b/tgui/packages/tgui-panel/ping/selectors.js @@ -4,4 +4,4 @@ * @license MIT */ -export const selectPing = state => state.ping; +export const selectPing = (state) => state.ping; diff --git a/tgui/packages/tgui-panel/reconnect.tsx b/tgui/packages/tgui-panel/reconnect.tsx index 25391c0a681..ecfd7671692 100644 --- a/tgui/packages/tgui-panel/reconnect.tsx +++ b/tgui/packages/tgui-panel/reconnect.tsx @@ -3,7 +3,7 @@ import { Button } from 'tgui/components'; let url: string | null = null; setInterval(() => { - Byond.winget('', 'url').then(currentUrl => { + Byond.winget('', 'url').then((currentUrl) => { // Sometimes, for whatever reason, BYOND will give an IP with a :0 port. if (currentUrl && !currentUrl.match(/:0$/)) { url = currentUrl; @@ -11,19 +11,25 @@ setInterval(() => { }); }, 5000); -export const ReconnectButton = (props, context) => { - return url && ( +export const ReconnectButton = () => { + if (!url) { + return null; + } + return ( <> - - - diff --git a/tgui/packages/tgui-panel/settings/SettingsPanel.js b/tgui/packages/tgui-panel/settings/SettingsPanel.js index 01df419ce21..d449fd3e7a6 100644 --- a/tgui/packages/tgui-panel/settings/SettingsPanel.js +++ b/tgui/packages/tgui-panel/settings/SettingsPanel.js @@ -23,13 +23,17 @@ export const SettingsPanel = (props, context) => {
- {SETTINGS_TABS.map(tab => ( + {SETTINGS_TABS.map((tab) => ( dispatch(changeSettingsTab({ - tabId: tab.id, - }))}> + onClick={() => + dispatch( + changeSettingsTab({ + tabId: tab.id, + }) + ) + }> {tab.name} ))} @@ -37,12 +41,8 @@ export const SettingsPanel = (props, context) => {
- {activeTab === 'general' && ( - - )} - {activeTab === 'chatPage' && ( - - )} + {activeTab === 'general' && } + {activeTab === 'chatPage' && } ); @@ -60,7 +60,7 @@ export const SettingsGeneral = (props, context) => { matchCase, } = useSelector(context, selectSettings); const dispatch = useDispatch(context); - const [freeFont, setFreeFont] = useLocalState(context, "freeFont", false); + const [freeFont, setFreeFont] = useLocalState(context, 'freeFont', false); return (
@@ -68,34 +68,48 @@ export const SettingsGeneral = (props, context) => { dispatch(updateSettings({ - theme: value, - }))} /> + onSelected={(value) => + dispatch( + updateSettings({ + theme: value, + }) + ) + } + /> - {!freeFont && ( + {(!freeFont && ( dispatch(updateSettings({ - fontFamily: value, - }))} /> - ) || ( + onSelected={(value) => + dispatch( + updateSettings({ + fontFamily: value, + }) + ) + } + /> + )) || ( dispatch(updateSettings({ - fontFamily: value, - }))} + onChange={(e, value) => + dispatch( + updateSettings({ + fontFamily: value, + }) + ) + } /> )}
@@ -134,9 +134,12 @@ const NewscasterChannelCreation = (props, context) => { @@ -122,13 +143,15 @@ const OutfitSlot = (props, context) => { title={currItem?.desc} style={{ '-ms-interpolation-mode': 'nearest-neighbor', - }} /> + }} + /> act("clear", { slot })} /> + onClick={() => act('clear', { slot })} + /> )} @@ -140,7 +163,7 @@ const OutfitSlot = (props, context) => { 'text-overflow': 'ellipsis', }} title={currItem?.path}> - {currItem?.name || "Empty"} + {currItem?.name || 'Empty'} ); diff --git a/tgui/packages/tgui/interfaces/OutfitManager.js b/tgui/packages/tgui/interfaces/OutfitManager.js index ed7b835897f..5552fc2f2c4 100644 --- a/tgui/packages/tgui/interfaces/OutfitManager.js +++ b/tgui/packages/tgui/interfaces/OutfitManager.js @@ -6,11 +6,7 @@ export const OutfitManager = (props, context) => { const { act, data } = useBackend(context); const { outfits } = data; return ( - +
{ icon="file-upload" tooltip="Load an outfit from a file" tooltipPosition="left" - onClick={() => act("load")} /> + onClick={() => act('load')} + /> diff --git a/tgui/packages/tgui/interfaces/PaintingAdminPanel.tsx b/tgui/packages/tgui/interfaces/PaintingAdminPanel.tsx index d2d6e42ef3d..dbe3c1dfee1 100644 --- a/tgui/packages/tgui/interfaces/PaintingAdminPanel.tsx +++ b/tgui/packages/tgui/interfaces/PaintingAdminPanel.tsx @@ -9,37 +9,38 @@ type PaintingAdminPanelData = { }; type PaintingData = { - md5: string, - title: string, - creator_ckey: string, - creator_name: string | null, - creation_date: Date | null, - creation_round_id: number | null, - patron_ckey: string | null, - patron_name: string | null, - credit_value: number, - width: number, - height: number, - ref: string, - tags: string[] | null, - medium: string | null -} + md5: string; + title: string; + creator_ckey: string; + creator_name: string | null; + creation_date: Date | null; + creation_round_id: number | null; + patron_ckey: string | null; + patron_name: string | null; + credit_value: number; + width: number; + height: number; + ref: string; + tags: string[] | null; + medium: string | null; +}; export const PaintingAdminPanel = (props, context) => { const { act, data } = useBackend(context); - const [chosenPaintingRef, setChosenPaintingRef] = useLocalState(context, 'chosenPainting', null); - const { - paintings, - } = data; - const chosenPainting = paintings.find(p => p.ref === chosenPaintingRef); + const [chosenPaintingRef, setChosenPaintingRef] = useLocalState< + string | null + >(context, 'chosenPainting', null); + const { paintings } = data; + const chosenPainting = paintings.find((p) => p.ref === chosenPaintingRef); return ( - + {chosenPainting && ( -
setChosenPaintingRef(null)}>Close}> +
setChosenPaintingRef(null)}>Close + }> { style={{ 'vertical-align': 'middle', '-ms-interpolation-mode': 'nearest-neighbor', - }} /> + }} + /> - {decodeHtmlEntities(chosenPainting.title)} - + { + setChosenPaintingRef(null); + act('delete', { ref: chosenPainting.ref }); + }}> + Delete + +
)} @@ -96,23 +146,22 @@ export const PaintingAdminPanel = (props, context) => { Preview Actions - {paintings.map(painting => ( - - + {paintings.map((painting) => ( + + {decodeHtmlEntities(painting.title)} {painting.creator_ckey} - + +
@@ -95,10 +96,7 @@ export const PaintingMachine = (props, context) => { }; export const EjectButton = (props, context) => { - const { - name, - onClickEject, - } = props; + const { name, onClickEject } = props; return ( ); @@ -271,7 +272,8 @@ const SpecimenDisplay = (_, context) => { onClick={() => act('create_culture_bottle', { index: virus.index, - })} + }) + } /> @@ -281,8 +283,7 @@ const SpecimenDisplay = (_, context) => { - {virus?.symptoms - && } + {virus?.symptoms && } @@ -352,7 +353,8 @@ const VirusTextInfo = (props: VirusInfoProps, context) => { act('rename_disease', { index: virus.index, name: value, - })} + }) + } /> ) : ( {virus.name} diff --git a/tgui/packages/tgui/interfaces/PaperSheet.js b/tgui/packages/tgui/interfaces/PaperSheet.js index 7994a992995..fb641e33d56 100644 --- a/tgui/packages/tgui/interfaces/PaperSheet.js +++ b/tgui/packages/tgui/interfaces/PaperSheet.js @@ -22,55 +22,85 @@ const MAX_PAPER_LENGTH = 5000; // Question, should we send this with ui_data? // Hacky, yes, works?...yes const textWidth = (text, font, fontsize) => { // default font height is 12 in tgui - font = fontsize + "x " + font; + font = fontsize + 'x ' + font; const c = document.createElement('canvas'); - const ctx = c.getContext("2d"); + const ctx = c.getContext('2d'); ctx.font = font; const width = ctx.measureText(text).width; return width; }; -const setFontinText = (text, font, color, bold=false) => { - return "" + text + ""; +const setFontinText = (text, font, color, bold = false) => { + return ( + '' + + text + + '' + ); }; -const createIDHeader = index => { - return "paperfield_" + index; +const createIDHeader = (index) => { + return 'paperfield_' + index; }; // To make a field you do a [_______] or however long the field is // we will then output a TEXT input for it that hopefully covers // the exact amount of spaces const field_regex = /\[(_+)\]/g; -const field_tag_regex = /\[paperfield_\d+)"(.*?)\/>\]/gm; -const sign_regex = /%s(?:ign)?(?=\\s|$)?/igm; +const field_tag_regex = + /\[paperfield_\d+)"(.*?)\/>\]/gm; +const sign_regex = /%s(?:ign)?(?=\\s|$)?/gim; -const createInputField = (length, width, font, - fontsize, color, id) => { - return "[]"; +const createInputField = (length, width, font, fontsize, color, id) => { + return ( + '[]' + ); }; const createFields = (txt, font, fontsize, color, counter) => { const ret_text = txt.replace(field_regex, (match, p1, offset, string) => { - const width = textWidth(match, font, fontsize) + "px"; - return createInputField(p1.length, - width, font, fontsize, color, createIDHeader(counter++)); + const width = textWidth(match, font, fontsize) + 'px'; + return createInputField( + p1.length, + width, + font, + fontsize, + color, + createIDHeader(counter++) + ); }); return { counter, @@ -80,14 +110,14 @@ const createFields = (txt, font, fontsize, color, counter) => { const signDocument = (txt, color, user) => { return txt.replace(sign_regex, () => { - return setFontinText(user, "Times New Roman", color, true); + return setFontinText(user, 'Times New Roman', color, true); }); }; -const run_marked_default = value => { +const run_marked_default = (value) => { // Override function, any links and images should // kill any other marked tokens we don't want here - const walkTokens = token => { + const walkTokens = (token) => { switch (token.type) { case 'url': case 'autolink': @@ -97,7 +127,7 @@ const run_marked_default = value => { token.type = 'text'; // Once asset system is up change to some default image // or rewrite for icon images - token.href = ""; + token.href = ''; break; } }; @@ -112,17 +142,17 @@ const run_marked_default = value => { }; /* -** This gets the field, and finds the dom object and sees if -** the user has typed something in. If so, it replaces, -** the dom object, in txt with the value, spaces so it -** fits the [] format and saves the value into a object -** There may be ways to optimize this in javascript but -** doing this in byond is nightmarish. -** -** It returns any values that were saved and a corrected -** html code or null if nothing was updated -*/ -const checkAllFields = (txt, font, color, user_name, bold=false) => { + ** This gets the field, and finds the dom object and sees if + ** the user has typed something in. If so, it replaces, + ** the dom object, in txt with the value, spaces so it + ** fits the [] format and saves the value into a object + ** There may be ways to optimize this in javascript but + ** doing this in byond is nightmarish. + ** + ** It returns any values that were saved and a corrected + ** html code or null if nothing was updated + */ +const checkAllFields = (txt, font, color, user_name, bold = false) => { let matches; let values = {}; let replace = []; @@ -137,7 +167,7 @@ const checkAllFields = (txt, font, color, user_name, bold=false) => { const dom = document.getElementById(id); // make sure we got data, and kill any html that might // be in it - const dom_text = dom && dom.value ? dom.value : ""; + const dom_text = dom && dom.value ? dom.value : ''; if (dom_text.length === 0) { continue; } @@ -149,47 +179,46 @@ const checkAllFields = (txt, font, color, user_name, bold=false) => { const target = dom.cloneNode(true); // in case they sign in a field if (sanitized_text.match(sign_regex)) { - target.style.fontFamily = "Times New Roman"; + target.style.fontFamily = 'Times New Roman'; bold = true; target.defaultValue = user_name; - } - else { + } else { target.style.fontFamily = font; target.defaultValue = sanitized_text; } if (bold) { - target.style.fontWeight = "bold"; + target.style.fontWeight = 'bold'; } target.style.color = color; target.disabled = true; const wrap = document.createElement('div'); wrap.appendChild(target); values[id] = sanitized_text; // save the data - replace.push({ value: "[" + wrap.innerHTML + "]", raw_text: full_match }); + replace.push({ value: '[' + wrap.innerHTML + ']', raw_text: full_match }); } } if (replace.length > 0) { for (const o of replace) { - txt = txt.replace(o.raw_text, o.value); } } return { text: txt, fields: values }; }; -const pauseEvent = e => { - if (e.stopPropagation) { e.stopPropagation(); } - if (e.preventDefault) { e.preventDefault(); } - e.cancelBubble=true; - e.returnValue=false; +const pauseEvent = (e) => { + if (e.stopPropagation) { + e.stopPropagation(); + } + if (e.preventDefault) { + e.preventDefault(); + } + e.cancelBubble = true; + e.returnValue = false; return false; }; const Stamp = (props, context) => { - const { - image, - opacity, - } = props; + const { image, opacity } = props; const stamp_transform = { 'left': image.x + 'px', 'top': image.y + 'px', @@ -199,15 +228,12 @@ const Stamp = (props, context) => { return (
+ className={classes(['Paper__Stamp', image.sprite])} + style={stamp_transform} + /> ); }; - const setInputReadonly = (text, readonly) => { return readonly ? text.replace(/ { // got to make this a full component if we // want to control updates const PaperSheetView = (props, context) => { - const { - value = "", - stamps = [], - backgroundColor, - readOnly, - } = props; + const { value = '', stamps = [], backgroundColor, readOnly } = props; const stamp_list = stamps; const text_html = { - __html: '' - + setInputReadonly(value, readOnly) - + '', + __html: + '' + + setInputReadonly(value, readOnly) + + '', }; return ( + height="100%"> + p="10px" + /> {stamp_list.map((o, i) => ( - + ))} ); @@ -260,22 +285,28 @@ class PaperSheetStamper extends Component { rotate: 0, }; this.style = null; - this.handleMouseMove = e => { + this.handleMouseMove = (e) => { const pos = this.findStampPosition(e); - if (!pos) { return; } + if (!pos) { + return; + } // center offset of stamp & rotate pauseEvent(e); this.setState({ x: pos[0], y: pos[1], rotate: pos[2] }); }; - this.handleMouseClick = e => { - if (e.pageY <= 30) { return; } + this.handleMouseClick = (e) => { + if (e.pageY <= 30) { + return; + } const { act, data } = useBackend(this.context); const stamp_obj = { - x: this.state.x, y: this.state.y, r: this.state.rotate, + x: this.state.x, + y: this.state.y, + r: this.state.rotate, stamp_class: this.props.stamp_class, stamp_icon_state: data.stamp_icon_state, }; - act("stamp", stamp_obj); + act('stamp', stamp_obj); }; } @@ -286,30 +317,30 @@ class PaperSheetStamper extends Component { rotating = true; } - if (document.getElementById("stamp")) - { - const stamp = document.getElementById("stamp"); + if (document.getElementById('stamp')) { + const stamp = document.getElementById('stamp'); const stampHeight = stamp.clientHeight; const stampWidth = stamp.clientWidth; - const currentHeight = rotating ? this.state.y : e.pageY - - windowRef.scrollTop - stampHeight; - const currentWidth = rotating ? this.state.x : e.pageX - (stampWidth / 2); + const currentHeight = rotating + ? this.state.y + : e.pageY - windowRef.scrollTop - stampHeight; + const currentWidth = rotating ? this.state.x : e.pageX - stampWidth / 2; const widthMin = 0; const heightMin = 0; - const widthMax = (windowRef.clientWidth) - ( - stampWidth); - const heightMax = (windowRef.clientHeight - windowRef.scrollTop) - ( - stampHeight); + const widthMax = windowRef.clientWidth - stampWidth; + const heightMax = + windowRef.clientHeight - windowRef.scrollTop - stampHeight; const radians = Math.atan2( e.pageX - currentWidth, e.pageY - currentHeight ); - const rotate = rotating ? (radians * (180 / Math.PI) * -1) + const rotate = rotating + ? radians * (180 / Math.PI) * -1 : this.state.rotate; const pos = [ @@ -322,21 +353,17 @@ class PaperSheetStamper extends Component { } componentDidMount() { - document.addEventListener("mousemove", this.handleMouseMove); - document.addEventListener("click", this.handleMouseClick); + document.addEventListener('mousemove', this.handleMouseMove); + document.addEventListener('click', this.handleMouseClick); } componentWillUnmount() { - document.removeEventListener("mousemove", this.handleMouseMove); - document.removeEventListener("click", this.handleMouseClick); + document.removeEventListener('mousemove', this.handleMouseMove); + document.removeEventListener('click', this.handleMouseClick); } render() { - const { - value, - stamp_class, - stamps, - } = this.props; + const { value, stamp_class, stamps } = this.props; const stamp_list = stamps || []; const current_pos = { sprite: stamp_class, @@ -346,13 +373,8 @@ class PaperSheetStamper extends Component { }; return ( <> - - + + ); } @@ -367,7 +389,7 @@ const createPreview = ( color, font, user_name, - is_crayon = false, + is_crayon = false ) => { const out = { text: text }; // check if we are adding to paper, if not @@ -376,19 +398,23 @@ const createPreview = ( value = value.trim(); if (value.length > 0) { // First lets make sure it ends in a new line - value += value[value.length] === "\n" ? " \n" : "\n \n"; + value += value[value.length] === '\n' ? ' \n' : '\n \n'; // Second, we sanitize the text of html const sanitized_text = sanitizeText(value); const signed_text = signDocument(sanitized_text, color, user_name); // Third we replace the [__] with fields as markedjs fucks them up const fielded_text = createFields( - signed_text, font, 12, color, field_counter); + signed_text, + font, + 12, + color, + field_counter + ); // Fourth, parse the text using markup const formatted_text = run_marked_default(fielded_text.text); // Fifth, we wrap the created text in the pin color, and font. // crayon is bold ( tags), maybe make fountain pin italic? - const fonted_text = setFontinText( - formatted_text, font, color, is_crayon); + const fonted_text = setFontinText(formatted_text, font, color, is_crayon); out.text += fonted_text; out.field_counter = fielded_text.counter; } @@ -397,7 +423,12 @@ const createPreview = ( // if any data was entered by the user and // if it was return the data and modify the text const final_processing = checkAllFields( - out.text, font, color, user_name, is_crayon); + out.text, + font, + color, + user_name, + is_crayon + ); out.text = final_processing.text; out.form_fields = final_processing.fields; } @@ -411,37 +442,40 @@ class PaperSheetEdit extends Component { constructor(props, context) { super(props, context); this.state = { - previewSelected: "Preview", - old_text: props.value || "", + previewSelected: 'Preview', + old_text: props.value || '', counter: props.counter || 0, - textarea_text: "", - combined_text: props.value || "", + textarea_text: '', + combined_text: props.value || '', }; } createPreviewFromData(value, do_fields = false) { const { data } = useBackend(this.context); - return createPreview(value, + return createPreview( + value, this.state.old_text, do_fields, this.state.counter, data.pen_color, data.pen_font, data.edit_usr, - data.is_crayon, + data.is_crayon ); } onInputHandler(e, value) { if (value !== this.state.textarea_text) { - const combined_length = this.state.old_text.length - + this.state.textarea_text.length; + const combined_length = + this.state.old_text.length + this.state.textarea_text.length; if (combined_length > MAX_PAPER_LENGTH) { - if ((combined_length - MAX_PAPER_LENGTH) >= value.length) { + if (combined_length - MAX_PAPER_LENGTH >= value.length) { // Basically we cannot add any more text to the paper value = ''; } else { - value = value.substr(0, value.length - - (combined_length - MAX_PAPER_LENGTH)); + value = value.substr( + 0, + value.length - (combined_length - MAX_PAPER_LENGTH) + ); } // we check again to save an update if (value === this.state.textarea_text) { @@ -460,107 +494,108 @@ class PaperSheetEdit extends Component { const { act } = useBackend(this.context); const final_processing = this.createPreviewFromData(new_text, true); act('save', final_processing); - this.setState(() => { return { - textarea_text: "", - previewSelected: "save", - combined_text: final_processing.text, - old_text: final_processing.text, - counter: final_processing.field_counter, - }; }); + this.setState(() => { + return { + textarea_text: '', + previewSelected: 'save', + combined_text: final_processing.text, + old_text: final_processing.text, + counter: final_processing.field_counter, + }; + }); // byond should switch us to readonly mode from here } render() { - const { - textColor, - fontFamily, - stamps, - backgroundColor, - } = this.props; + const { textColor, fontFamily, stamps, backgroundColor } = this.props; return ( - + this.setState({ previewSelected: "Edit" })}> + backgroundColor={ + this.state.previewSelected === 'Edit' ? 'grey' : 'white' + } + selected={this.state.previewSelected === 'Edit'} + onClick={() => this.setState({ previewSelected: 'Edit' })}> Edit this.setState(() => { - const new_state = { - previewSelected: "Preview", - textarea_text: this.state.textarea_text, - combined_text: this.createPreviewFromData( - this.state.textarea_text).text, - }; - return new_state; - })}> + backgroundColor={ + this.state.previewSelected === 'Preview' ? 'grey' : 'white' + } + selected={this.state.previewSelected === 'Preview'} + onClick={() => + this.setState(() => { + const new_state = { + previewSelected: 'Preview', + textarea_text: this.state.textarea_text, + combined_text: this.createPreviewFromData( + this.state.textarea_text + ).text, + }; + return new_state; + }) + }> Preview { - if (this.state.previewSelected === "confirm") { + if (this.state.previewSelected === 'confirm') { this.finalUpdate(this.state.textarea_text); - } - else if (this.state.previewSelected === "Edit") { + } else if (this.state.previewSelected === 'Edit') { this.setState(() => { const new_state = { - previewSelected: "confirm", + previewSelected: 'confirm', textarea_text: this.state.textarea_text, combined_text: this.createPreviewFromData( - this.state.textarea_text).text, + this.state.textarea_text + ).text, }; return new_state; }); - } - else { - this.setState({ previewSelected: "confirm" }); + } else { + this.setState({ previewSelected: 'confirm' }); } }}> - {this.state.previewSelected === "confirm" ? "Confirm" : "Save"} + {this.state.previewSelected === 'confirm' ? 'Confirm' : 'Save'} - - {this.state.previewSelected === "Edit" && ( + + {(this.state.previewSelected === 'Edit' && (