UNPKG

@canterbury-air-patrol/sar-search-runner

Version:
244 lines 7.32 kB
// sar-search-runner.tsx import React, { useEffect, useState } from "react"; import { CreepingLineAheadSearch, SectorSearch, SearchDisplay, SearchConfiguration } from "@canterbury-air-patrol/sar-search-patterns"; import { Distance, Speed, Time, DistanceUI, SpeedTimeDistanceUI } from "@canterbury-air-patrol/speed-time-distance"; import { Button, ButtonGroup } from "react-bootstrap"; var SearchTimer = ({ runTime, run, complete }) => { const [remainingTime, setRemainingTime] = useState(runTime); const [running, setRunning] = useState(run); const updateRemainingTime = () => { if (running) { if (remainingTime <= 1) { setRunning(false); if (complete !== void 0) { complete(); } } setRemainingTime(remainingTime - 1); } }; useEffect(() => { const interval = setInterval(() => { updateRemainingTime(); }, 1e3); return () => clearInterval(interval); }, [remainingTime]); return /* @__PURE__ */ React.createElement(React.Fragment, null, "Turn in: ", remainingTime, " seconds"); }; var SearchRunner = class extends React.Component { constructor(props) { super(props); this.onChangeSpeed = this.onChangeSpeed.bind(this); this.updateState = this.updateState.bind(this); this.onCompleteTimer = this.onCompleteTimer.bind(this); this.handleReset = this.handleReset.bind(this); this.handlePause = this.handlePause.bind(this); this.handleRun = this.handleRun.bind(this); this.handleBackLeg = this.handleBackLeg.bind(this); this.handleSkipLeg = this.handleSkipLeg.bind(this); this.state = { search: this.props.search === void 0 ? new CreepingLineAheadSearch(200, 1e3, 5, 0) : this.props.search, running: false, searchLeg: 1, speed: new Speed(40, "knots") }; } onChangeSpeed(newSpeed) { this.setState({ speed: newSpeed }); } updateState() { if (this.state.search.complete && this.props.complete) { this.props.complete(); } } onCompleteTimer() { this.setState(function(oldState) { oldState.search.nextLeg(); return { search: oldState.search, searchLeg: oldState.search.currentLeg }; }, this.updateState); } handleReset() { this.setState(function(oldState) { oldState.search.currentLeg = 1; return { search: oldState.search, searchLeg: 1, running: false }; }); } handlePause() { this.setState({ running: false }); } handleRun() { this.setState({ running: true }); } handleBackLeg() { this.setState(function(oldState) { oldState.search.currentLeg--; return { search: oldState.search, searchLeg: oldState.search.currentLeg }; }); } handleSkipLeg() { this.setState(function(oldState) { oldState.search.currentLeg++; return { search: oldState.search, searchLeg: oldState.search.currentLeg }; }); } humanBearing(bearing) { if (bearing < 10) { return `00${bearing}`; } if (bearing < 100) { return `0${bearing}`; } return `${bearing}`; } render() { const distance = new Distance( this.state.search.complete ? this.state.search.sweepWidth : this.state.search.leg.distance, "m" ); const time = new Time( distance.getDistance("m") / this.state.speed.getSpeed("m/s"), "seconds" ); const buttons = []; if (this.state.search.complete || this.state.searchLeg > 1) { buttons.push( /* @__PURE__ */ React.createElement(Button, { key: "reset", onClick: this.handleReset }, "Reset") ); } if (!this.state.search.complete) { if (this.state.running) { buttons.push( /* @__PURE__ */ React.createElement(Button, { key: "pause", onClick: this.handlePause }, "Pause") ); } else { if (this.state.searchLeg > 1) { buttons.push( /* @__PURE__ */ React.createElement(Button, { key: "back", onClick: this.handleBackLeg }, "Previous") ); buttons.push( /* @__PURE__ */ React.createElement(Button, { key: "resume", onClick: this.handleRun }, "Resume") ); } else { buttons.push( /* @__PURE__ */ React.createElement(Button, { key: "run", onClick: this.handleRun }, "Run") ); } if (!this.state.search.complete) { buttons.push( /* @__PURE__ */ React.createElement(Button, { key: "skip", onClick: this.handleSkipLeg }, "Skip") ); } } } let timer = /* @__PURE__ */ React.createElement(React.Fragment, null); let instructionText = "Complete"; if (!this.state.search.complete) { if (this.state.running) { timer = /* @__PURE__ */ React.createElement("h1", null, /* @__PURE__ */ React.createElement( SearchTimer, { key: "timer" + this.state.searchLeg, runTime: Math.round(time.getTime("seconds")), run: this.state.running, complete: this.onCompleteTimer } )); } instructionText = `Head ${this.humanBearing(this.state.search.leg.bearing)}`; if (this.state.search.currentLeg + 1 <= this.state.search.searchLegs.length) { instructionText += `, Next: ${this.humanBearing(this.state.search.searchLegs[this.state.search.currentLeg].bearing)}`; } } const instruction = /* @__PURE__ */ React.createElement("h1", null, instructionText); const totalDistance = /* @__PURE__ */ React.createElement("h1", null, "Total Length:", " ", /* @__PURE__ */ React.createElement( DistanceUI, { distance: new Distance(this.state.search.length, "m"), locked: true } )); return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement( SpeedTimeDistanceUI, { key: "std" + this.state.searchLeg, calculate: "time", lockSelector: true, lockDistance: true, speed: this.state.speed, distance, time, updateSpeed: this.onChangeSpeed } ), /* @__PURE__ */ React.createElement(ButtonGroup, null, buttons), timer, instruction, /* @__PURE__ */ React.createElement( SearchDisplay, { key: "display" + this.state.searchLeg, search: this.state.search } ), totalDistance); } }; var SearchRunnerConfiguration = class extends React.Component { constructor(props) { super(props); this.onChangeSearch = this.onChangeSearch.bind(this); this.state = { search: new SectorSearch(200, 1, 1, 0) }; } onChangeSearch(search) { if (search !== void 0) { this.setState({ search }); } } render() { return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(SearchConfiguration, { updateSearch: this.onChangeSearch }), /* @__PURE__ */ React.createElement( SearchRunner, { key: `${this.state.search.uniqueKey()}`, search: this.state.search } )); } }; export { SearchRunner, SearchRunnerConfiguration }; //# sourceMappingURL=sar-search-runner.mjs.map