UNPKG

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

Version:
1 lines 12.6 kB
{"version":3,"sources":["../sar-search-runner.tsx"],"sourcesContent":["import React, { useEffect, useState } from \"react\";\n\nimport {\n CreepingLineAheadSearch,\n SectorSearch,\n SearchDisplay,\n SearchConfiguration,\n SearchPattern,\n} from \"@canterbury-air-patrol/sar-search-patterns\";\nimport {\n Distance,\n Speed,\n Time,\n DistanceUI,\n SpeedTimeDistanceUI,\n} from \"@canterbury-air-patrol/speed-time-distance\";\nimport { Button, ButtonGroup } from \"react-bootstrap\";\n\nconst SearchTimer = ({\n runTime,\n run,\n complete,\n}: {\n runTime: number;\n run: boolean;\n complete?: () => void;\n}) => {\n const [remainingTime, setRemainingTime] = useState(runTime);\n const [running, setRunning] = useState(run);\n\n const updateRemainingTime = () => {\n if (running) {\n if (remainingTime <= 1) {\n setRunning(false);\n if (complete !== undefined) {\n complete();\n }\n }\n setRemainingTime(remainingTime - 1);\n }\n };\n\n useEffect(() => {\n const interval = setInterval(() => {\n updateRemainingTime();\n }, 1000);\n\n return () => clearInterval(interval);\n }, [remainingTime]);\n\n return <>Turn in: {remainingTime} seconds</>;\n};\n\ninterface SearchRunnerProps {\n search?: SearchPattern;\n complete?: () => void;\n}\n\ninterface SearchRunnerState {\n search: SearchPattern;\n running: boolean;\n searchLeg: number;\n speed: Speed;\n}\n\nclass SearchRunner extends React.Component<\n SearchRunnerProps,\n SearchRunnerState\n> {\n constructor(props: SearchRunnerProps) {\n super(props);\n this.onChangeSpeed = this.onChangeSpeed.bind(this);\n this.updateState = this.updateState.bind(this);\n this.onCompleteTimer = this.onCompleteTimer.bind(this);\n this.handleReset = this.handleReset.bind(this);\n this.handlePause = this.handlePause.bind(this);\n this.handleRun = this.handleRun.bind(this);\n this.handleBackLeg = this.handleBackLeg.bind(this);\n this.handleSkipLeg = this.handleSkipLeg.bind(this);\n\n this.state = {\n search:\n this.props.search === undefined\n ? new CreepingLineAheadSearch(200, 1000, 5, 0)\n : this.props.search,\n running: false,\n searchLeg: 1,\n speed: new Speed(40, \"knots\"),\n };\n }\n\n onChangeSpeed(newSpeed: Speed) {\n this.setState({\n speed: newSpeed,\n });\n }\n\n updateState() {\n if (this.state.search.complete && this.props.complete) {\n this.props.complete();\n }\n }\n\n onCompleteTimer() {\n this.setState(function (oldState) {\n oldState.search.nextLeg();\n return {\n search: oldState.search,\n searchLeg: oldState.search.currentLeg,\n };\n }, this.updateState);\n }\n\n handleReset() {\n this.setState(function (oldState) {\n oldState.search.currentLeg = 1;\n return {\n search: oldState.search,\n searchLeg: 1,\n running: false,\n };\n });\n }\n\n handlePause() {\n this.setState({\n running: false,\n });\n }\n\n handleRun() {\n this.setState({\n running: true,\n });\n }\n\n handleBackLeg() {\n this.setState(function (oldState) {\n oldState.search.currentLeg--;\n return {\n search: oldState.search,\n searchLeg: oldState.search.currentLeg,\n };\n });\n }\n\n handleSkipLeg() {\n this.setState(function (oldState) {\n oldState.search.currentLeg++;\n return {\n search: oldState.search,\n searchLeg: oldState.search.currentLeg,\n };\n });\n }\n\n humanBearing(bearing: number) {\n if (bearing < 10) {\n return `00${bearing}`;\n }\n if (bearing < 100) {\n return `0${bearing}`;\n }\n return `${bearing}`;\n }\n\n render() {\n const distance = new Distance(\n this.state.search.complete\n ? this.state.search.sweepWidth\n : this.state.search.leg.distance,\n \"m\",\n );\n const time = new Time(\n distance.getDistance(\"m\") / this.state.speed.getSpeed(\"m/s\"),\n \"seconds\",\n );\n const buttons = [];\n if (this.state.search.complete || this.state.searchLeg > 1) {\n buttons.push(\n <Button key=\"reset\" onClick={this.handleReset}>\n Reset\n </Button>,\n );\n }\n if (!this.state.search.complete) {\n if (this.state.running) {\n buttons.push(\n <Button key=\"pause\" onClick={this.handlePause}>\n Pause\n </Button>,\n );\n } else {\n if (this.state.searchLeg > 1) {\n buttons.push(\n <Button key=\"back\" onClick={this.handleBackLeg}>\n Previous\n </Button>,\n );\n buttons.push(\n <Button key=\"resume\" onClick={this.handleRun}>\n Resume\n </Button>,\n );\n } else {\n buttons.push(\n <Button key=\"run\" onClick={this.handleRun}>\n Run\n </Button>,\n );\n }\n if (!this.state.search.complete) {\n buttons.push(\n <Button key=\"skip\" onClick={this.handleSkipLeg}>\n Skip\n </Button>,\n );\n }\n }\n }\n\n let timer = <></>;\n let instructionText = \"Complete\";\n if (!this.state.search.complete) {\n if (this.state.running) {\n timer = (\n <h1>\n <SearchTimer\n key={\"timer\" + this.state.searchLeg}\n runTime={Math.round(time.getTime(\"seconds\"))}\n run={this.state.running}\n complete={this.onCompleteTimer}\n />\n </h1>\n );\n }\n instructionText = `Head ${this.humanBearing(this.state.search.leg.bearing)}`;\n if (\n this.state.search.currentLeg + 1 <=\n this.state.search.searchLegs.length\n ) {\n instructionText += `, Next: ${this.humanBearing(this.state.search.searchLegs[this.state.search.currentLeg].bearing)}`;\n }\n }\n const instruction = <h1>{instructionText}</h1>;\n const totalDistance = (\n <h1>\n Total Length:{\" \"}\n <DistanceUI\n distance={new Distance(this.state.search.length, \"m\")}\n locked\n />\n </h1>\n );\n\n return (\n <>\n <SpeedTimeDistanceUI\n key={\"std\" + this.state.searchLeg}\n calculate=\"time\"\n lockSelector\n lockDistance\n speed={this.state.speed}\n distance={distance}\n time={time}\n updateSpeed={this.onChangeSpeed}\n />\n <ButtonGroup>{buttons}</ButtonGroup>\n {timer}\n {instruction}\n <SearchDisplay\n key={\"display\" + this.state.searchLeg}\n search={this.state.search}\n />\n {totalDistance}\n </>\n );\n }\n}\n\ninterface SearchRunnerConfigurationState {\n search: SearchPattern;\n}\n\nclass SearchRunnerConfiguration extends React.Component<\n object,\n SearchRunnerConfigurationState\n> {\n constructor(props: object) {\n super(props);\n this.onChangeSearch = this.onChangeSearch.bind(this);\n this.state = {\n search: new SectorSearch(200, 1, 1, 0),\n };\n }\n\n onChangeSearch(search: SearchPattern | undefined) {\n if (search !== undefined) {\n this.setState({\n search,\n });\n }\n }\n\n render() {\n return (\n <>\n <SearchConfiguration updateSearch={this.onChangeSearch} />\n <SearchRunner\n key={`${this.state.search.uniqueKey()}`}\n search={this.state.search}\n />\n </>\n );\n }\n}\n\nexport { SearchRunner, SearchRunnerConfiguration };\n"],"mappings":"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","names":[]}