@canterbury-air-patrol/sar-search-runner
Version:
244 lines • 7.32 kB
JavaScript
// 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