More ESLint options

This commit is contained in:
uwap 2017-11-07 01:32:22 +01:00
parent a60e800cee
commit 19b91cfd0a
8 changed files with 200 additions and 59 deletions

View file

@ -14,23 +14,36 @@ import {
ListItemIcon,
ListItemSecondaryAction,
ListItemText,
ListSubheader,
ListSubheader
} from "material-ui/List";
import Button from "material-ui/Button";
const enabled = (props: ControlUI, state: State) => {
if (props.enableCondition == null) return true;
else {
if (props.enableCondition == null) {
return true;
} else {
const val = state.values[props.topic];
return props.enableCondition(
val.internal == null ? val.actual : val.internal, val.actual, R.map(x => x.internal == null ?
x.actual : x.internal, state.values == null ? {} : state.values));
val.internal == null ? val.actual : val.internal, val.actual,
R.map(x => x.internal == null ? x.actual
: x.internal, state.values == null ? {} : state.values));
}
};
const getValue = (topic: string, val: string) =>
Config.topics[topic].values[val];
const renderIcon = (icon: string) => {
if (icon != null) {
return (
<ListItemIcon>
<i className={`mdi mdi-${icon} mdi-24px`}></i>
</ListItemIcon>
);
}
return null;
};
export const onSwitch = (topic: string, props: ControlUI, state: State) =>
(x, toggled: boolean) => {
if (state.mqtt != null) {
@ -53,11 +66,11 @@ export const isToggled = (state: State, props: ControlUI) => {
export const toggle = (state: State, props: ControlUI) => {
return (
<ListItem>
{props.icon && <ListItemIcon><i className={`mdi mdi-${props.icon} mdi-24px`}></i></ListItemIcon>}
{renderIcon(props.icon)}
<ListItemText primary={props.text} />
<ListItemSecondaryAction>
<Switch label={props.text}
checked={isToggled(state,props)}
checked={isToggled(state, props)}
onChange={onSwitch(props.topic, props, state)}
disabled={!(enabled(props, state))} />
</ListItemSecondaryAction>
@ -77,10 +90,11 @@ const dropDownItem = (topic: string) => (text: string, key: string) => (
);
export const dropDown = (state: State, props: ControlUI) => {
const id = `${props.topic}.${Object.keys(props.options).reduce((v,r) => v + "." + r)}`;
const id = `${props.topic}.${Object.keys(props.options)
.reduce((v, r) => v + "." + r)}`;
return (
<ListItem>
{props.icon && <ListItemIcon><i className={`mdi mdi-${props.icon} mdi-24px`}></i></ListItemIcon>}
{renderIcon(props.icon)}
<FormControl>
<InputLabel htmlFor={id}>{props.text}</InputLabel>
<Select value={state.values[props.topic].actual}
@ -104,7 +118,7 @@ const onSliderChange = (state: State, props: ControlUI) =>
export const slider = (state: State, props: ControlUI) => (
<ListItem>
{props.icon && <ListItemIcon><i className={`mdi mdi-${props.icon} mdi-24px`}></i></ListItemIcon>}
{renderIcon(props.icon)}
<ListItemText primary={props.text} />
<ListItemSecondaryAction>
<MuiThemeProvider>
@ -125,7 +139,10 @@ export const section = (state: State, props: ControlUI) => (
export const link = (state: State, props: ControlUI) => (
<ListItem>
<Button raised onClick={() => window.open(props.link, "_blank")} color="primary">
<Button raised
onClick={() => window.open(props.link, "_blank")}
color="primary"
>
{props.text}
</Button>
</ListItem>

View file

@ -8,7 +8,7 @@ import Typography from "material-ui/Typography";
const TopBarLayerSelector = (_props: Object) => (
<IconButton>
<Icon>layers</Icon>
<i className="mdi mdi-layers"></i>
</IconButton>
);
@ -19,11 +19,12 @@ const TopBarIndicatorMenu = (props: Object) => (
(<i style={{fontSize: 48}} className="mdi mdi-lan-disconnect"></i>)}
</IconButton>
);
const TopBarIndicator = (props: Object) => {
if (props.mqtt == null || props.mqtt.reconnecting) {
return (<CircularProgress size={48} style={{color: "rgba(0, 0, 0, 0.54)"}} />);
return (<CircularProgress size={48}
style={{color: "rgba(0, 0, 0, 0.54)"}} />);
} else {
return (<TopBarIndicatorMenu {...props} />);
}

View file

@ -23,22 +23,32 @@ const iconHtml = (el, state: State) =>
+ "color:" + color(el.iconColor, state) + ";\">"
+ "</i>";
const Markers = (props) => R.values(R.mapObjIndexed((el,key) => (
const Markers = (props) => R.values(R.mapObjIndexed((el, key) => (
<Marker position={c(el.position)} key={el.name}
icon={Leaflet.divIcon(
{
html: iconHtml(el, props.state),
iconSize: Leaflet.point(36,36),
iconAnchor: Leaflet.point(18,18)
iconSize: Leaflet.point(36, 36),
iconAnchor: Leaflet.point(18, 18)
})}
onClick={(e) => store.dispatch({type: Actions.CHANGE_UI, payload: key, toggle: e.originalEvent.ctrlKey})}>
onClick={(e) => store.dispatch({
type: Actions.CHANGE_UI,
payload: key,
toggle: e.originalEvent.ctrlKey})}>
</Marker>
), R.propOr({}, "controls", Config)));
class SpaceMap extends React.Component<{state: State, width: number, height: number,
zoom: number, image: string}> {
type SpaceMapProps = {
state: State,
width: number,
height: number,
zoom: number,
image: string
};
constructor(props) {
class SpaceMap extends React.Component<SpaceMapProps> {
constructor(props: SpaceMapProps) {
super(props);
}
@ -46,21 +56,25 @@ class SpaceMap extends React.Component<{state: State, width: number, height: num
const props = this.props;
return (
<Map center={c([props.width / 2, props.height / 2])} zoom={props.zoom}
crs={Leaflet.CRS.Simple}>
crs={Leaflet.CRS.Simple}>
{Markers(props)}
<LayersControl position='topright'>
{Config.layers.map(x => this.renderLayer(x, [c([0,0]), c([props.width, props.height])]))}
<LayersControl position="topright">
{Config.layers.map(x =>
this.renderLayer(x, [c([0, 0]), c([props.width, props.height])]))}
</LayersControl>
</Map>
);
}
renderLayer(layer, bounds) {
const LayersControlType = layer.baseLayer ? LayersControl.BaseLayer : LayersControl.Overlay;
const LayersControlType =
layer.baseLayer ? LayersControl.BaseLayer : LayersControl.Overlay;
return (
<LayersControlType name={layer.name}
checked={layer.defaultVisibility == "visible"}>
<ImageOverlay url={layer.image} bounds={bounds} opacity={layer.opacity} />
checked={layer.defaultVisibility === "visible"}>
<ImageOverlay url={layer.image}
bounds={bounds}
opacity={layer.opacity} />
</LayersControlType>
);
}

View file

@ -5,7 +5,7 @@ import { Store } from "redux";
import Config from "./config";
import R from "ramda";
export default function connectMqtt(url: string, store: Store<*,*>) {
export default function connectMqtt(url: string, store: Store<*, *>) {
const client = mqtt.connect(url);
client.on("connect", () => {
store.dispatch({

View file

@ -15,22 +15,29 @@ const initState : State = {
mqtt: null,
uiOpened: null,
values: R.map(
topic => { return {
internal: keyOf(topic.values, topic.defaultValue),
actual: topic.defaultValue
};}, Config.topics),
topic => {
return {
internal: keyOf(topic.values, topic.defaultValue),
actual: topic.defaultValue
};
}, Config.topics),
visibleLayers: []
};
const onMessage = (state: State, action: StateAction) => {
if (action.payload == undefined) return state;
// action.payload.topic is the mqtt topic
// topics is the list of all internal topic references
// that have their state topic set to action.payload.topic
const payload = action.payload == undefined ? { topic: "", message: {} }
if (action.payload == null) {
return state;
}
/*
* action.payload.topic is the mqtt topic
* topics is the list of all internal topic references
* that have their state topic set to action.payload.topic
*/
const payload = action.payload == null ? { topic: "", message: {} }
: action.payload; // thx flow </3
const topics = R.keys(R.pickBy(
val => val.state == payload.topic, Config.topics));
val => val.state === payload.topic, Config.topics));
const message = payload.message;
const parsedMessage = (topic: string) => {
let parseFunction = Config.topics[topic].parseState;
@ -43,7 +50,7 @@ const onMessage = (state: State, action: StateAction) => {
const newValue = (topic: string) => {
return {
actual: parsedMessage(topic),
internal: keyOf(Config.topics[topic].values,parsedMessage(topic))
internal: keyOf(Config.topics[topic].values, parsedMessage(topic))
};
};
return R.mergeDeepRight(state, R.objOf("values", R.mergeAll(
@ -51,14 +58,15 @@ const onMessage = (state: State, action: StateAction) => {
)));
};
const match = (value: any, array: Map<any,any>) => array[value];
const match = (value: any, array: Map<any, any>) => array[value];
const handleEvent = (state: State = initState, action: StateAction) => {
return match(action.type, {
[Actions.MQTT_CONNECT ]: R.merge(state, { mqtt: action.payload }),
[Actions.MQTT_MESSAGE ]: onMessage(state, action),
[Actions.CHANGE_UI ]: (() => {
[Actions.MQTT_CONNECT]: R.merge(state, { mqtt: action.payload }),
[Actions.MQTT_MESSAGE]: onMessage(state, action),
[Actions.CHANGE_UI]: (() => {
const control = Config.controls[action.payload];
if (action.toggle && control.ui.length > 0 && control.ui[0].type == "toggle") {
if (action.toggle && control.ui.length > 0
&& control.ui[0].type === "toggle") {
const props = control.ui[0];
onSwitch(props.topic, props, state)(null, !isToggled(state, props));
return state;

View file

@ -1,5 +1,5 @@
// @flow
import R from "ramda";
export const keyOf = <a,b> (map: Map<b,a>, value: a) : ?b =>
((keys) => keys[R.findIndex(k => map[k] == value, keys)])(R.keys(map));
export const keyOf = <a, b> (map: Map<b, a>, value: a): ?b =>
((keys) => keys[R.findIndex(k => map[k] === value, keys)])(R.keys(map));