Vending - Tank Dispenser

vending

vault controller

turbine computer

uplink

fix for turbine computer

transfer valve

timer

thermomachine

teleporter

Tank

Tank Dispenser
This commit is contained in:
actioninja
2020-04-19 19:36:41 +03:00
committed by Aleksej Komarov
parent 8b63e1acf7
commit 775c318d92
10 changed files with 630 additions and 567 deletions
+53 -48
View File
@@ -1,54 +1,59 @@
import { useBackend } from '../backend';
import { Button, LabeledList, NumberInput, ProgressBar, Section } from '../components';
import { Window } from '../layouts';
export const Tank = props => {
const { act, data } = useBackend(props);
export const Tank = (props, context) => {
const { act, data } = useBackend(context);
return (
<Section>
<LabeledList>
<LabeledList.Item label="Pressure">
<ProgressBar
value={data.tankPressure / 1013}
ranges={{
good: [0.35, Infinity],
average: [0.15, 0.35],
bad: [-Infinity, 0.15],
}}>
{data.tankPressure + ' kPa'}
</ProgressBar>
</LabeledList.Item>
<LabeledList.Item label="Pressure Regulator">
<Button
icon="fast-backward"
disabled={data.ReleasePressure === data.minReleasePressure}
onClick={() => act('pressure', {
pressure: 'min',
})} />
<NumberInput
animated
value={parseFloat(data.releasePressure)}
width="65px"
unit="kPa"
minValue={data.minReleasePressure}
maxValue={data.maxReleasePressure}
onChange={(e, value) => act('pressure', {
pressure: value,
})} />
<Button
icon="fast-forward"
disabled={data.ReleasePressure === data.maxReleasePressure}
onClick={() => act('pressure', {
pressure: 'max',
})} />
<Button
icon="undo"
content=""
disabled={data.ReleasePressure === data.defaultReleasePressure}
onClick={() => act('pressure', {
pressure: 'reset',
})} />
</LabeledList.Item>
</LabeledList>
</Section>
<Window>
<Window.Content>
<Section>
<LabeledList>
<LabeledList.Item label="Pressure">
<ProgressBar
value={data.tankPressure / 1013}
ranges={{
good: [0.35, Infinity],
average: [0.15, 0.35],
bad: [-Infinity, 0.15],
}}>
{data.tankPressure + ' kPa'}
</ProgressBar>
</LabeledList.Item>
<LabeledList.Item label="Pressure Regulator">
<Button
icon="fast-backward"
disabled={data.ReleasePressure === data.minReleasePressure}
onClick={() => act('pressure', {
pressure: 'min',
})} />
<NumberInput
animated
value={parseFloat(data.releasePressure)}
width="65px"
unit="kPa"
minValue={data.minReleasePressure}
maxValue={data.maxReleasePressure}
onChange={(e, value) => act('pressure', {
pressure: value,
})} />
<Button
icon="fast-forward"
disabled={data.ReleasePressure === data.maxReleasePressure}
onClick={() => act('pressure', {
pressure: 'max',
})} />
<Button
icon="undo"
content=""
disabled={data.ReleasePressure === data.defaultReleasePressure}
onClick={() => act('pressure', {
pressure: 'reset',
})} />
</LabeledList.Item>
</LabeledList>
</Section>
</Window.Content>
</Window>
);
};
+33 -28
View File
@@ -1,34 +1,39 @@
import { useBackend } from '../backend';
import { Button, LabeledList, Section } from '../components';
import { Window } from '../layouts';
export const TankDispenser = props => {
const { act, data } = useBackend(props);
export const TankDispenser = (props, context) => {
const { act, data } = useBackend(context);
return (
<Section>
<LabeledList>
<LabeledList.Item
label="Plasma"
buttons={(
<Button
icon={data.plasma ? 'square' : 'square-o'}
content="Dispense"
disabled={!data.plasma}
onClick={() => act('plasma')} />
)}>
{data.plasma}
</LabeledList.Item>
<LabeledList.Item
label="Oxygen"
buttons={(
<Button
icon={data.oxygen ? 'square' : 'square-o'}
content="Dispense"
disabled={!data.oxygen}
onClick={() => act('oxygen')} />
)}>
{data.oxygen}
</LabeledList.Item>
</LabeledList>
</Section>
<Window>
<Window.Content>
<Section>
<LabeledList>
<LabeledList.Item
label="Plasma"
buttons={(
<Button
icon={data.plasma ? 'square' : 'square-o'}
content="Dispense"
disabled={!data.plasma}
onClick={() => act('plasma')} />
)}>
{data.plasma}
</LabeledList.Item>
<LabeledList.Item
label="Oxygen"
buttons={(
<Button
icon={data.oxygen ? 'square' : 'square-o'}
content="Dispense"
disabled={!data.oxygen}
onClick={() => act('oxygen')} />
)}>
{data.oxygen}
</LabeledList.Item>
</LabeledList>
</Section>
</Window.Content>
</Window>
);
};
+60 -55
View File
@@ -1,8 +1,9 @@
import { useBackend } from '../backend';
import { Box, Button, LabeledList, Section } from '../components';
import { Window } from '../layouts';
export const Teleporter = props => {
const { act, data } = useBackend(props);
export const Teleporter = (props, context) => {
const { act, data } = useBackend(context);
const {
calibrated,
calibrating,
@@ -12,58 +13,62 @@ export const Teleporter = props => {
target,
} = data;
return (
<Section>
{!power_station && (
<Box color="bad" textAlign="center">
No power station linked.
</Box>
) || (!teleporter_hub && (
<Box color="bad" textAlign="center">
No hub linked.
</Box>
)) || (
<LabeledList>
<LabeledList.Item label="Current Regime"
buttons={(
<Button
icon="tools"
content="Change Regime"
onClick={() => act('regimeset')} />
)}>
{regime_set}
</LabeledList.Item>
<LabeledList.Item label="Current Target"
buttons={(
<Button
icon="tools"
content="Set Target"
onClick={() => act('settarget')} />
)}>
{target}
</LabeledList.Item>
<LabeledList.Item label="Calibration"
buttons={(
<Button
icon="tools"
content="Calibrate Hub"
onClick={() => act('calibrate')} />
)}>
{calibrating && (
<Box color="average">
In Progress
</Box>
) || (calibrated && (
<Box color="good">
Optimal
</Box>
) || (
<Box color="bad">
Sub-Optimal
</Box>
))}
</LabeledList.Item>
</LabeledList>
)}
</Section>
<Window>
<Window.Content>
<Section>
{!power_station && (
<Box color="bad" textAlign="center">
No power station linked.
</Box>
) || (!teleporter_hub && (
<Box color="bad" textAlign="center">
No hub linked.
</Box>
)) || (
<LabeledList>
<LabeledList.Item label="Current Regime"
buttons={(
<Button
icon="tools"
content="Change Regime"
onClick={() => act('regimeset')} />
)}>
{regime_set}
</LabeledList.Item>
<LabeledList.Item label="Current Target"
buttons={(
<Button
icon="tools"
content="Set Target"
onClick={() => act('settarget')} />
)}>
{target}
</LabeledList.Item>
<LabeledList.Item label="Calibration"
buttons={(
<Button
icon="tools"
content="Calibrate Hub"
onClick={() => act('calibrate')} />
)}>
{calibrating && (
<Box color="average">
In Progress
</Box>
) || (calibrated && (
<Box color="good">
Optimal
</Box>
) || (
<Box color="bad">
Sub-Optimal
</Box>
))}
</LabeledList.Item>
</LabeledList>
)}
</Section>
</Window.Content>
</Window>
);
};
+71 -68
View File
@@ -2,76 +2,79 @@ import { toFixed } from 'common/math';
import { Fragment } from 'inferno';
import { useBackend } from '../backend';
import { AnimatedNumber, Button, LabeledList, NumberInput, Section } from '../components';
import { Window } from '../layouts';
export const ThermoMachine = props => {
const { act, data } = useBackend(props);
export const ThermoMachine = (props, context) => {
const { act, data } = useBackend(context);
return (
<Fragment>
<Section title="Status">
<LabeledList>
<LabeledList.Item label="Temperature">
<AnimatedNumber
value={data.temperature}
format={value => toFixed(value, 2)} />
{' K'}
</LabeledList.Item>
<LabeledList.Item label="Pressure">
<AnimatedNumber
value={data.pressure}
format={value => toFixed(value, 2)} />
{' kPa'}
</LabeledList.Item>
</LabeledList>
</Section>
<Section
title="Controls"
buttons={(
<Button
icon={data.on ? 'power-off' : 'times'}
content={data.on ? 'On' : 'Off'}
selected={data.on}
onClick={() => act('power')} />
)}>
<LabeledList>
<LabeledList.Item label="Target Temperature">
<NumberInput
animated
value={Math.round(data.target)}
unit="K"
width="62px"
minValue={Math.round(data.min)}
maxValue={Math.round(data.max)}
step={5}
stepPixelSize={3}
onDrag={(e, value) => act('target', {
target: value,
})} />
</LabeledList.Item>
<LabeledList.Item label="Presets">
<Window>
<Window.Content>
<Section title="Status">
<LabeledList>
<LabeledList.Item label="Temperature">
<AnimatedNumber
value={data.temperature}
format={value => toFixed(value, 2)} />
{' K'}
</LabeledList.Item>
<LabeledList.Item label="Pressure">
<AnimatedNumber
value={data.pressure}
format={value => toFixed(value, 2)} />
{' kPa'}
</LabeledList.Item>
</LabeledList>
</Section>
<Section
title="Controls"
buttons={(
<Button
icon="fast-backward"
disabled={data.target === data.min}
title="Minimum temperature"
onClick={() => act('target', {
target: data.min,
})} />
<Button
icon="sync"
disabled={data.target === data.initial}
title="Room Temperature"
onClick={() => act('target', {
target: data.initial,
})} />
<Button
icon="fast-forward"
disabled={data.target === data.max}
title="Maximum Temperature"
onClick={() => act('target', {
target: data.max,
})} />
</LabeledList.Item>
</LabeledList>
</Section>
</Fragment>
icon={data.on ? 'power-off' : 'times'}
content={data.on ? 'On' : 'Off'}
selected={data.on}
onClick={() => act('power')} />
)}>
<LabeledList>
<LabeledList.Item label="Target Temperature">
<NumberInput
animated
value={Math.round(data.target)}
unit="K"
width="62px"
minValue={Math.round(data.min)}
maxValue={Math.round(data.max)}
step={5}
stepPixelSize={3}
onDrag={(e, value) => act('target', {
target: value,
})} />
</LabeledList.Item>
<LabeledList.Item label="Presets">
<Button
icon="fast-backward"
disabled={data.target === data.min}
title="Minimum temperature"
onClick={() => act('target', {
target: data.min,
})} />
<Button
icon="sync"
disabled={data.target === data.initial}
title="Room Temperature"
onClick={() => act('target', {
target: data.initial,
})} />
<Button
icon="fast-forward"
disabled={data.target === data.max}
title="Maximum Temperature"
onClick={() => act('target', {
target: data.max,
})} />
</LabeledList.Item>
</LabeledList>
</Section>
</Window.Content>
</Window>
);
};
+42 -37
View File
@@ -1,9 +1,10 @@
import { Fragment } from 'inferno';
import { useBackend } from '../backend';
import { Button, Section } from '../components';
import { Window } from '../layouts';
export const Timer = props => {
const { act, data } = useBackend(props);
export const Timer = (props, context) => {
const { act, data } = useBackend(context);
const {
minutes,
seconds,
@@ -11,42 +12,46 @@ export const Timer = props => {
loop,
} = data;
return (
<Section
title="Timing Unit"
buttons={(
<Fragment>
<Window>
<Window.Content>
<Section
title="Timing Unit"
buttons={(
<Fragment>
<Button
icon={'sync'}
content={loop ? 'Repeating' : 'Repeat'}
selected={loop}
onClick={() => act('repeat')} />
<Button
icon={"clock-o"}
content={timing ? 'Stop' : 'Start'}
selected={timing}
onClick={() => act('time')} />
</Fragment>
)}>
<Button
icon={'sync'}
content={loop ? 'Repeating' : 'Repeat'}
selected={loop}
onClick={() => act('repeat')} />
icon="fast-backward"
disabled={timing}
onClick={() => act('input', { adjust: -30 })} />
<Button
icon={"clock-o"}
content={timing ? 'Stop' : 'Start'}
selected={timing}
onClick={() => act('time')} />
</Fragment>
)}>
<Button
icon="fast-backward"
disabled={timing}
onClick={() => act('input', { adjust: -30 })} />
<Button
icon="backward"
disabled={timing}
onClick={() => act('input', { adjust: -1 })} />
{' '}
{String(minutes).padStart(2, '0')}:
{String(seconds).padStart(2, '0')}
{' '}
<Button
icon="forward"
disabled={timing}
onClick={() => act('input', { adjust: 1 })} />
<Button
icon="fast-forward"
disabled={timing}
onClick={() => act('input', { adjust: 30 })} />
</Section>
icon="backward"
disabled={timing}
onClick={() => act('input', { adjust: -1 })} />
{' '}
{String(minutes).padStart(2, '0')}:
{String(seconds).padStart(2, '0')}
{' '}
<Button
icon="forward"
disabled={timing}
onClick={() => act('input', { adjust: 1 })} />
<Button
icon="fast-forward"
disabled={timing}
onClick={() => act('input', { adjust: 30 })} />
</Section>
</Window.Content>
</Window>
);
};
+77 -74
View File
@@ -1,9 +1,10 @@
import { Fragment } from 'inferno';
import { useBackend } from '../backend';
import { Button, LabeledList, NoticeBox, Section } from '../components';
import { Window } from '../layouts';
export const TransferValve = props => {
const { act, data } = useBackend(props);
export const TransferValve = (props, context) => {
const { act, data } = useBackend(context);
const {
tank_one,
tank_two,
@@ -11,78 +12,80 @@ export const TransferValve = props => {
valve,
} = data;
return (
<Fragment>
<Section>
<LabeledList>
<LabeledList.Item label="Valve Status">
<Window>
<Window.Content>
<Section>
<LabeledList>
<LabeledList.Item label="Valve Status">
<Button
icon={valve ? "unlock" : "lock"}
content={valve ? "Open" : "Closed"}
disabled={!tank_one || !tank_two}
onClick={() => act('toggle')} />
</LabeledList.Item>
</LabeledList>
</Section>
<Section
title="Valve Attachment"
buttons={(
<Button
icon={valve ? "unlock" : "lock"}
content={valve ? "Open" : "Closed"}
disabled={!tank_one || !tank_two}
onClick={() => act('toggle')} />
</LabeledList.Item>
</LabeledList>
</Section>
<Section
title="Valve Attachment"
buttons={(
<Button
textAlign="center"
width="30px"
icon={"cog"}
disabled={(!attached_device)}
onClick={() => act('device')} />
)}>
<LabeledList>
{attached_device ? (
<LabeledList.Item label="Attachment">
<Button
icon={"wrench"}
content={attached_device}
disabled={!attached_device}
onClick={() => act('remove_device')} />
</LabeledList.Item>
) : (
<NoticeBox textAlign="center">
Insert Assembly
</NoticeBox>
)}
</LabeledList>
</Section>
<Section title="Attachment One">
<LabeledList>
{tank_one ? (
<LabeledList.Item label="Attachment">
<Button
icon={"wrench"}
content={tank_one}
disabled={!tank_one}
onClick={() => act('tankone')} />
</LabeledList.Item>
) : (
<NoticeBox textAlign="center">
Insert Tank
</NoticeBox>
)}
</LabeledList>
</Section>
<Section title="Attachment Two">
<LabeledList>
{tank_two ? (
<LabeledList.Item label="Attachment">
<Button
icon={"wrench"}
content={tank_two}
disabled={!tank_two}
onClick={() => act('tanktwo')} />
</LabeledList.Item>
) : (
<NoticeBox textAlign="center">
Insert Tank
</NoticeBox>
)}
</LabeledList>
</Section>
</Fragment>
textAlign="center"
width="30px"
icon={"cog"}
disabled={(!attached_device)}
onClick={() => act('device')} />
)}>
<LabeledList>
{attached_device ? (
<LabeledList.Item label="Attachment">
<Button
icon={"wrench"}
content={attached_device}
disabled={!attached_device}
onClick={() => act('remove_device')} />
</LabeledList.Item>
) : (
<NoticeBox textAlign="center">
Insert Assembly
</NoticeBox>
)}
</LabeledList>
</Section>
<Section title="Attachment One">
<LabeledList>
{tank_one ? (
<LabeledList.Item label="Attachment">
<Button
icon={"wrench"}
content={tank_one}
disabled={!tank_one}
onClick={() => act('tankone')} />
</LabeledList.Item>
) : (
<NoticeBox textAlign="center">
Insert Tank
</NoticeBox>
)}
</LabeledList>
</Section>
<Section title="Attachment Two">
<LabeledList>
{tank_two ? (
<LabeledList.Item label="Attachment">
<Button
icon={"wrench"}
content={tank_two}
disabled={!tank_two}
onClick={() => act('tanktwo')} />
</LabeledList.Item>
) : (
<NoticeBox textAlign="center">
Insert Tank
</NoticeBox>
)}
</LabeledList>
</Section>
</Window.Content>
</Window>
);
};
@@ -1,64 +1,69 @@
import { Fragment } from 'inferno';
import { useBackend } from '../backend';
import { Button, LabeledList, Section } from '../components';
import { Window } from '../layouts';
export const TurbineComputer = props => {
const { act, data } = useBackend(props);
export const TurbineComputer = (props, context) => {
const { act, data } = useBackend(context);
const operational = Boolean(data.compressor
&& !data.compressor_broke
&& data.turbine
&& !data.turbine_broke);
return (
<Section
title="Status"
buttons={(
<Fragment>
<Button
icon={data.online ? 'power-off' : 'times'}
content={data.online ? 'Online' : 'Offline'}
selected={data.online}
disabled={!operational}
onClick={() => act('toggle_power')} />
<Button
icon="sync"
content="Reconnect"
onClick={() => act('reconnect')} />
</Fragment>
)}>
{!operational && (
<LabeledList>
<LabeledList.Item
label="Compressor Status"
color={(!data.compressor || data.compressor_broke)
? 'bad'
: 'good'}>
{data.compressor_broke
? data.compressor ? 'Offline' : 'Missing'
: 'Online'}
</LabeledList.Item>
<LabeledList.Item
label="Turbine Status"
color={(!data.turbine || data.turbine_broke)
? 'bad'
: 'good'}>
{data.turbine_broke
? data.turbine ? 'Offline' : 'Missing'
: 'Online'}
</LabeledList.Item>
</LabeledList>
) || (
<LabeledList>
<LabeledList.Item label="Turbine Speed">
{data.rpm} RPM
</LabeledList.Item>
<LabeledList.Item label="Internal Temp">
{data.temp} K
</LabeledList.Item>
<LabeledList.Item label="Generated Power">
{data.power}
</LabeledList.Item>
</LabeledList>
)}
</Section>
<Window>
<Window.Content>
<Section
title="Status"
buttons={(
<Fragment>
<Button
icon={data.online ? 'power-off' : 'times'}
content={data.online ? 'Online' : 'Offline'}
selected={data.online}
disabled={!operational}
onClick={() => act('toggle_power')} />
<Button
icon="sync"
content="Reconnect"
onClick={() => act('reconnect')} />
</Fragment>
)}>
{!operational && (
<LabeledList>
<LabeledList.Item
label="Compressor Status"
color={(!data.compressor || data.compressor_broke)
? 'bad'
: 'good'}>
{data.compressor_broke
? data.compressor ? 'Offline' : 'Missing'
: 'Online'}
</LabeledList.Item>
<LabeledList.Item
label="Turbine Status"
color={(!data.turbine || data.turbine_broke)
? 'bad'
: 'good'}>
{data.turbine_broke
? data.turbine ? 'Offline' : 'Missing'
: 'Online'}
</LabeledList.Item>
</LabeledList>
) || (
<LabeledList>
<LabeledList.Item label="Turbine Speed">
{data.rpm} RPM
</LabeledList.Item>
<LabeledList.Item label="Internal Temp">
{data.temp} K
</LabeledList.Item>
<LabeledList.Item label="Generated Power">
{data.power}
</LabeledList.Item>
</LabeledList>
)}
</Section>
</Window.Content>
</Window>
);
};
+85 -79
View File
@@ -2,6 +2,8 @@ import { decodeHtmlEntities } from 'common/string';
import { Component, Fragment } from 'inferno';
import { act } from '../byond';
import { Box, Button, Input, Section, Table, Tabs } from '../components';
import { useBackend } from '../backend';
import { Window } from '../layouts';
// It's a class because we need to store state in the form of the current
// hovered item, and current search terms
@@ -27,9 +29,7 @@ export class Uplink extends Component {
}
render() {
const { state } = this.props;
const { config, data } = state;
const { ref } = config;
const { act, data } = useBackend(this.context);
const {
compact_mode,
lockable,
@@ -38,84 +38,90 @@ export class Uplink extends Component {
} = data;
const { hoveredItem, currentSearch } = this.state;
return (
<Section
title={(
<Box
inline
color={telecrystals > 0 ? 'good' : 'bad'}>
{telecrystals} TC
</Box>
)}
buttons={(
<Fragment>
Search
<Input
value={currentSearch}
onInput={(e, value) => this.setSearchText(value)}
ml={1}
mr={1} />
<Button
icon={compact_mode ? 'list' : 'info'}
content={compact_mode ? 'Compact' : 'Detailed'}
onClick={() => act(ref, 'compact_toggle')} />
{!!lockable && (
<Button
icon="lock"
content="Lock"
onClick={() => act(ref, 'lock')} />
<Window
theme="syndicate"
resizable>
<Window.Content scrollable>
<Section
title={(
<Box
inline
color={telecrystals > 0 ? 'good' : 'bad'}>
{telecrystals} TC
</Box>
)}
</Fragment>
)}>
{currentSearch.length > 0 ? (
<table className="Table">
<ItemList
compact
items={categories
.flatMap(category => {
return category.items || [];
})
.filter(item => {
const searchTerm = currentSearch.toLowerCase();
const searchableString = String(item.name + item.desc)
.toLowerCase();
return searchableString.includes(searchTerm);
buttons={(
<Fragment>
Search
<Input
value={currentSearch}
onInput={(e, value) => this.setSearchText(value)}
ml={1}
mr={1} />
<Button
icon={compact_mode ? 'list' : 'info'}
content={compact_mode ? 'Compact' : 'Detailed'}
onClick={() => act('compact_toggle')} />
{!!lockable && (
<Button
icon="lock"
content="Lock"
onClick={() => act('lock')} />
)}
</Fragment>
)}>
{currentSearch.length > 0 ? (
<table className="Table">
<ItemList
compact
items={categories
.flatMap(category => {
return category.items || [];
})
.filter(item => {
const searchTerm = currentSearch.toLowerCase();
const searchableString = String(item.name + item.desc)
.toLowerCase();
return searchableString.includes(searchTerm);
})}
hoveredItem={hoveredItem}
onBuyMouseOver={item => this.setHoveredItem(item)}
onBuyMouseOut={item => this.setHoveredItem({})}
onBuy={item => act('buy', {
item: item.name,
})} />
</table>
) : (
<Tabs vertical>
{categories.map(category => {
const { name, items } = category;
if (items === null) {
return;
}
return (
<Tabs.Tab
key={name}
label={`${name} (${items.length})`}>
{() => (
<ItemList
compact={compact_mode}
items={items}
hoveredItem={hoveredItem}
telecrystals={telecrystals}
onBuyMouseOver={item => this.setHoveredItem(item)}
onBuyMouseOut={item => this.setHoveredItem({})}
onBuy={item => act('buy', {
item: item.name,
})} />
)}
</Tabs.Tab>
);
})}
hoveredItem={hoveredItem}
onBuyMouseOver={item => this.setHoveredItem(item)}
onBuyMouseOut={item => this.setHoveredItem({})}
onBuy={item => act(ref, 'buy', {
item: item.name,
})} />
</table>
) : (
<Tabs vertical>
{categories.map(category => {
const { name, items } = category;
if (items === null) {
return;
}
return (
<Tabs.Tab
key={name}
label={`${name} (${items.length})`}>
{() => (
<ItemList
compact={compact_mode}
items={items}
hoveredItem={hoveredItem}
telecrystals={telecrystals}
onBuyMouseOver={item => this.setHoveredItem(item)}
onBuyMouseOut={item => this.setHoveredItem({})}
onBuy={item => act(ref, 'buy', {
item: item.name,
})} />
)}
</Tabs.Tab>
);
})}
</Tabs>
)}
</Section>
</Tabs>
)}
</Section>
</Window.Content>
</Window>
);
}
}
@@ -1,33 +1,38 @@
import { toFixed } from 'common/math';
import { useBackend } from '../backend';
import { Button, LabeledList, ProgressBar, Section } from '../components';
import { Window } from '../layouts';
export const VaultController = props => {
const { act, data } = useBackend(props);
export const VaultController = (props, context) => {
const { act, data } = useBackend(context);
return (
<Section
title="Lock Status: "
buttons={(
<Button
content={data.doorstatus ? 'Locked' : 'Unlocked'}
icon={data.doorstatus ? 'lock' : 'unlock'}
disabled={data.stored < data.max}
onClick={() => act('togglelock')} />
)}>
<LabeledList>
<LabeledList.Item label="Charge">
<ProgressBar
value={data.stored / data.max}
ranges={{
good: [1, Infinity],
average: [0.30, 1],
bad: [-Infinity, 0.30],
}}>
{toFixed(data.stored / 1000) + ' / '
<Window>
<Window.Content>
<Section
title="Lock Status: "
buttons={(
<Button
content={data.doorstatus ? 'Locked' : 'Unlocked'}
icon={data.doorstatus ? 'lock' : 'unlock'}
disabled={data.stored < data.max}
onClick={() => act('togglelock')} />
)}>
<LabeledList>
<LabeledList.Item label="Charge">
<ProgressBar
value={data.stored / data.max}
ranges={{
good: [1, Infinity],
average: [0.30, 1],
bad: [-Infinity, 0.30],
}}>
{toFixed(data.stored / 1000) + ' / '
+ toFixed(data.max / 1000) + ' kW'}
</ProgressBar>
</LabeledList.Item>
</LabeledList>
</Section>
</ProgressBar>
</LabeledList.Item>
</LabeledList>
</Section>
</Window.Content>
</Window>
);
};
+121 -100
View File
@@ -2,9 +2,95 @@ import { classes } from 'common/react';
import { Fragment } from 'inferno';
import { useBackend } from '../backend';
import { Box, Button, Section, Table } from '../components';
import { Window } from '../layouts';
export const Vending = props => {
const { act, data } = useBackend(props);
export const VendingRow = (props, context) => {
const { act, data } = useBackend(context);
const {
product,
productStock,
custom,
} = props;
const free = (
!data.onstation
|| product.price === 0
|| (
!product.premium
&& data.department
&& data.user
&& data.department === data.user.department
)
);
return (
<Table.Row>
<Table.Cell collapsing>
{product.base64 ? (
<img
src={`data:image/jpeg;base64,${product.img}`}
style={{
'vertical-align': 'middle',
'horizontal-align': 'middle',
}} />
) : (
<span
className={classes([
'vending32x32',
product.path,
])}
style={{
'vertical-align': 'middle',
'horizontal-align': 'middle',
}} />
)}
</Table.Cell>
<Table.Cell bold>
{product.name}
</Table.Cell>
<Table.Cell collapsing textAlign="center">
<Box
color={custom
? 'good'
: productStock <= 0
? 'bad'
: productStock <= (product.max_amount / 2)
? 'average'
: 'good'}>
{productStock} in stock
</Box>
</Table.Cell>
<Table.Cell collapsing textAlign="center">
{custom && (
<Button
content={data.access ? 'FREE' : product.price + ' cr'}
onClick={() => act('dispense', {
'item': product.name,
})} />
) || (
<Button
disabled={(
productStock === 0
|| (
!free && (
!data.user
|| product.price > data.user.cash
)
)
)}
content={free ? 'FREE' : product.price + ' cr'}
onClick={() => act('vend', {
'ref': product.ref,
})} />
)}
</Table.Cell>
</Table.Row>
);
};
export const Vending = (props, context) => {
const { act, data } = useBackend(context);
let inventory;
let custom = false;
if (data.vending_machine_input) {
@@ -23,104 +109,39 @@ export const Vending = props => {
];
}
return (
<Fragment>
{!!data.onstation && (
<Section title="User">
{data.user && (
<Box>
Welcome, <b>{data.user.name}</b>,
{' '}
<b>{data.user.job || "Unemployed"}</b>!
<br />
Your balance is <b>{data.user.cash} credits</b>.
</Box>
) || (
<Box color="light-gray">
No registered ID card!<br />
Please contact your local HoP!
</Box>
)}
<Window resizable>
<Window.Content scrollable>
{!!data.onstation && (
<Section title="User">
{data.user && (
<Box>
Welcome, <b>{data.user.name}</b>,
{' '}
<b>{data.user.job || "Unemployed"}</b>!
<br />
Your balance is <b>{data.user.cash} credits</b>.
</Box>
) || (
<Box color="light-gray">
No registered ID card!<br />
Please contact your local HoP!
</Box>
)}
</Section>
)}
<Section title="Products" >
<Table>
{inventory.map(product => (
<VendingRow
key={product.name}
custom={custom}
product={product}
productStock={data.stock[product.name]}
/>
))}
</Table>
</Section>
)}
<Section title="Products" >
<Table>
{inventory.map((product => {
const free = (
!data.onstation
|| product.price === 0
|| (
!product.premium
&& data.department
&& data.user
&& data.department === data.user.department
)
);
return (
<Table.Row key={product.name}>
<Table.Cell collapsing>
{product.base64 ? (
<img
src={`data:image/jpeg;base64,${product.img}`}
style={{
'vertical-align': 'middle',
'horizontal-align': 'middle',
}} />
) : (
<span
className={classes([
'vending32x32',
product.path,
])}
style={{
'vertical-align': 'middle',
'horizontal-align': 'middle',
}} />
)}
</Table.Cell>
<Table.Cell bold>
{product.name}
</Table.Cell>
<Table.Cell collapsing textAlign="center">
<Box
color={custom
? 'good'
: data.stock[product.name] <= 0
? 'bad'
: data.stock[product.name] <= (product.max_amount / 2)
? 'average'
: 'good'}>
{data.stock[product.name]} in stock
</Box>
</Table.Cell>
<Table.Cell collapsing textAlign="center">
{custom && (
<Button
content={data.access ? 'FREE' : product.price + ' cr'}
onClick={() => act('dispense', {
'item': product.name,
})} />
) || (
<Button
disabled={(
data.stock[product.namename] === 0
|| (
!free && (
!data.user
|| product.price > data.user.cash
)
)
)}
content={free ? 'FREE' : product.price + ' cr'}
onClick={() => act('vend', {
'ref': product.ref,
})} />
)}
</Table.Cell>
</Table.Row>
);
}))}
</Table>
</Section>
</Fragment>
</Window.Content>
</Window>
);
};