Integrate WebcamFeed resource with app, remove `webcam_url` from Device interface
parent
66e2b2b643
commit
8254c007ee
|
@ -27,6 +27,10 @@ FarmBot::Application.routes.draw do
|
|||
patch "/device/:id" => "devices#update", as: :patch_device_redirect
|
||||
put "/users/:id" => "users#update", as: :put_users_redirect
|
||||
patch "/users/:id" => "users#update", as: :patch_users_redirect
|
||||
put "/webcam_feed/:id" => "webcam_feeds#update",
|
||||
as: :put_webcam_feed_redirect
|
||||
patch "/webcam_feed/:id" => "webcam_feeds#update",
|
||||
as: :patch_webcam_feed_redirect
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -8,8 +8,7 @@ export let FAKE_RESOURCES: TaggedResource[] = [
|
|||
"specialStatus": undefined,
|
||||
"body": {
|
||||
"id": 415,
|
||||
"name": "wispy-firefly-846",
|
||||
"webcam_url": undefined
|
||||
"name": "wispy-firefly-846"
|
||||
},
|
||||
"uuid": "device.415.0"
|
||||
},
|
||||
|
|
|
@ -141,7 +141,8 @@ export function urlFor(tag: ResourceName) {
|
|||
users: API.current.usersPath,
|
||||
device: API.current.devicePath,
|
||||
images: API.current.imagesPath,
|
||||
logs: API.current.logsPath
|
||||
logs: API.current.logsPath,
|
||||
webcam_feed: API.current.webcamFeedPath
|
||||
};
|
||||
let url = OPTIONS[tag];
|
||||
if (url) {
|
||||
|
|
|
@ -34,7 +34,7 @@ export class Controls extends React.Component<Props, {}> {
|
|||
</Col>
|
||||
<Col xs={12} sm={6}>
|
||||
<WebcamPanel bot={this.props.bot}
|
||||
account={this.props.account}
|
||||
feed={this.props.feed}
|
||||
dispatch={this.props.dispatch} />
|
||||
</Col>
|
||||
</Row>
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
import { BotState, Xyz, BotPosition } from "../devices/interfaces";
|
||||
import { Vector3 } from "farmbot/dist";
|
||||
import { TaggedPeripheral, TaggedDevice } from "../resources/tagged_resources";
|
||||
import { RestResources } from "../resources/interfaces";
|
||||
import { TaggedUser } from "../resources/tagged_resources";
|
||||
import {
|
||||
TaggedUser,
|
||||
TaggedWebcamFeed,
|
||||
TaggedPeripheral
|
||||
} from "../resources/tagged_resources";
|
||||
|
||||
export interface Props {
|
||||
dispatch: Function;
|
||||
bot: BotState;
|
||||
account: TaggedDevice;
|
||||
feed: TaggedWebcamFeed;
|
||||
user: TaggedUser | undefined;
|
||||
peripherals: TaggedPeripheral[];
|
||||
resources: RestResources;
|
||||
|
@ -23,7 +26,7 @@ export interface MoveProps {
|
|||
export interface WebcamPanelProps {
|
||||
dispatch: Function;
|
||||
bot: BotState;
|
||||
account: TaggedDevice;
|
||||
feed: TaggedWebcamFeed;
|
||||
}
|
||||
|
||||
export interface WebcamPanelState {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Everything } from "../interfaces";
|
||||
import {
|
||||
selectAllPeripherals,
|
||||
getDeviceAccountSettings
|
||||
getFeed
|
||||
} from "../resources/selectors";
|
||||
import { Props } from "./interfaces";
|
||||
import { maybeFetchUser } from "../resources/selectors";
|
||||
|
@ -12,7 +12,7 @@ export function mapStateToProps(props: Everything): Props {
|
|||
let resources = props.resources;
|
||||
|
||||
return {
|
||||
account: getDeviceAccountSettings(resources.index),
|
||||
feed: getFeed(resources.index),
|
||||
dispatch: props.dispatch,
|
||||
bot: props.bot,
|
||||
user: maybeFetchUser(props.resources.index),
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import * as React from "react";
|
||||
import { t } from "i18next";
|
||||
import { Widget, WidgetHeader } from "../ui";
|
||||
import { WebcamPanelState, WebcamPanelProps } from "./interfaces";
|
||||
import { WebcamPanelState, WebcamPanelProps, WebcamFeed } from "./interfaces";
|
||||
import { PLACEHOLDER_FARMBOT } from "../farmware/images/image_flipper";
|
||||
import { showUrl } from "./show_url";
|
||||
import { ToolTips } from "../constants";
|
||||
import { overwrite, edit, save } from "../api/crud";
|
||||
import { API } from "../api/api";
|
||||
import { DeviceAccountSettings } from "../devices/interfaces";
|
||||
import { createOK } from "../resources/actions";
|
||||
import axios from "axios";
|
||||
import { HttpData } from "../util";
|
||||
|
@ -20,33 +19,33 @@ export class WebcamPanel extends
|
|||
toggle = () => { this.setState({ isEditing: !this.state.isEditing }); };
|
||||
|
||||
save = () => {
|
||||
this.props.dispatch(save(this.props.account.uuid));
|
||||
this.props.dispatch(save(this.props.feed.uuid));
|
||||
this.toggle();
|
||||
};
|
||||
|
||||
edit = (update: Partial<DeviceAccountSettings>) => {
|
||||
this.props.dispatch(edit(this.props.account, update));
|
||||
edit = (update: Partial<WebcamFeed>) => {
|
||||
this.props.dispatch(edit(this.props.feed, update));
|
||||
};
|
||||
|
||||
resetURL = () => {
|
||||
axios
|
||||
.get(API.current.devicePath)
|
||||
.then((resp: HttpData<DeviceAccountSettings>) => {
|
||||
.then((resp: HttpData<WebcamFeed>) => {
|
||||
// TODO: We're starting to hit use cases where we need edit/undo.
|
||||
// Revisit this one when undo/redo is implemented.
|
||||
this.props.dispatch(overwrite(this.props.account, resp.data));
|
||||
this.props.dispatch(createOK(this.props.account));
|
||||
this.props.dispatch(overwrite(this.props.feed, resp.data));
|
||||
this.props.dispatch(createOK(this.props.feed));
|
||||
});
|
||||
}
|
||||
|
||||
clearURL = () => {
|
||||
// TODO: This should set webcam_url to "", but the input box to "https://"
|
||||
this.props.dispatch(edit(this.props.account, { webcam_url: "https://" }));
|
||||
// TODO: This should set url to "", but the input box to "https://"
|
||||
this.props.dispatch(edit(this.props.feed, { url: "https://" }));
|
||||
(document.querySelector(".webcam-url-input") as HTMLInputElement).focus();
|
||||
}
|
||||
|
||||
render() {
|
||||
let url = this.props.account.body.webcam_url || PLACEHOLDER_FARMBOT;
|
||||
let url = this.props.feed.body.url || PLACEHOLDER_FARMBOT;
|
||||
let dirty = !!this.props.bot.dirty;
|
||||
let { isEditing } = this.state;
|
||||
|
||||
|
@ -58,7 +57,7 @@ export class WebcamPanel extends
|
|||
className="fb-button green"
|
||||
onClick={this.save}
|
||||
>
|
||||
{t("Save")}{this.props.account.specialStatus ? "" : "*"}
|
||||
{t("Save")}{this.props.feed.specialStatus ? "" : "*"}
|
||||
</button>
|
||||
}
|
||||
{isEditing &&
|
||||
|
@ -83,9 +82,9 @@ export class WebcamPanel extends
|
|||
<label>{t("Set Webcam URL:")}</label>
|
||||
<input
|
||||
type="text"
|
||||
onChange={e => this.edit({ webcam_url: e.currentTarget.value })}
|
||||
onChange={e => this.edit({ url: e.currentTarget.value })}
|
||||
placeholder="https://"
|
||||
value={this.props.account.body.webcam_url}
|
||||
value={this.props.feed.body.url}
|
||||
className="webcam-url-input" />
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ export interface Props {
|
|||
export interface DeviceAccountSettings {
|
||||
id: number;
|
||||
name: string;
|
||||
webcam_url?: string;
|
||||
timezone?: string | undefined;
|
||||
last_seen?: string | undefined;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,8 @@ import {
|
|||
TaggedSequence,
|
||||
TaggedTool,
|
||||
TaggedToolSlotPointer,
|
||||
TaggedUser
|
||||
TaggedUser,
|
||||
TaggedWebcamFeed
|
||||
} from "./tagged_resources";
|
||||
import { CowardlyDictionary, betterCompact, sortResourcesById } from "../util";
|
||||
type StringMap = CowardlyDictionary<string>;
|
||||
|
@ -439,6 +440,25 @@ export function getDeviceAccountSettings(index: ResourceIndex) {
|
|||
}
|
||||
}
|
||||
|
||||
export function getFeed(index: ResourceIndex): TaggedWebcamFeed {
|
||||
let list = index.byKind.webcam_feed;
|
||||
let uuid = list[0];
|
||||
let device = index.references[uuid || -1];
|
||||
switch (list.length) {
|
||||
case 0:
|
||||
throw new Error("Missing webcam feed");
|
||||
case 1:
|
||||
if (device && device.kind === "webcam_feed") {
|
||||
sanityCheck(device);
|
||||
return device;
|
||||
} else {
|
||||
throw new Error("Malformed webcam feed");
|
||||
}
|
||||
default:
|
||||
throw new Error("Too many webcam feeds. Expected exactly 1.");
|
||||
}
|
||||
}
|
||||
|
||||
export function maybeFetchUser(index: ResourceIndex):
|
||||
TaggedUser | undefined {
|
||||
let list = index.byKind.users;
|
||||
|
|
Loading…
Reference in New Issue