mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 23:27:34 +01:00
Another SmartFridge restyle (#89013)
## About The Pull Request Another SmartFridge restyle aimed at improving the UI/UX. Finally used the new component (ImageButton) as I originally wanted to, but I kept failing. If you need to get a certain amount of fruit, you don't have to type in how much you need and then click on the fruit, just type it in and the fruit will be dispensed immediately, example in the video below. There are a total of 3 options to get what you need with SmartFridge: 1. Just click on the product, you will get 1 unit, nothing new. 2. Enter the required value, this was already there but it became a bit more convenient because you don't have to click on the product after entering it. 3. Press Right Mouse Button to get everything at once. ## Why It's Good For The Game Better UI/UX (No offense to those who made the past variations, they tried their best, but now there is a special component for such purposes, which makes it very much easier) ## Demonstration <details><summary> Comparison screenshots </summary> | Old (Grid) | New (Grid) | | - | - | |  |  | | Old (List) | New (List) | - | - | |  |  | </details> <details><summary> Video </summary> https://github.com/user-attachments/assets/c8788707-5947-4f1e-8a3c-6a56ac983e98 </details> ## Changelog 🆑 qol: SmartFridge got another redesign, and you can dispense all amount of product in one click (RMB on product) /🆑
This commit is contained in:
@@ -12,6 +12,6 @@
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"tgui": "workspace:*",
|
||||
"tgui-core": "^1.7.2"
|
||||
"tgui-core": "^1.7.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"tgui": "workspace:*",
|
||||
"tgui-core": "^1.7.2",
|
||||
"tgui-core": "^1.7.4",
|
||||
"tgui-dev-server": "workspace:*",
|
||||
"tgui-polyfill": "workspace:*"
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"tgui": "workspace:*",
|
||||
"tgui-core": "^1.7.2",
|
||||
"tgui-core": "^1.7.4",
|
||||
"tgui-polyfill": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { useState } from 'react';
|
||||
import { DmIcon, Icon } from 'tgui-core/components';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
ImageButton,
|
||||
Input,
|
||||
NoticeBox,
|
||||
NumberInput,
|
||||
@@ -48,44 +47,57 @@ export const SmartVend = (props) => {
|
||||
? Object.values(data.contents).filter(search)
|
||||
: Object.values(data.contents);
|
||||
return (
|
||||
<Window width={498} height={550}>
|
||||
<Window width={431} height={575}>
|
||||
<Window.Content>
|
||||
<Section
|
||||
fill
|
||||
scrollable
|
||||
title="Storage"
|
||||
buttons={
|
||||
data.isdryer ? (
|
||||
<Button
|
||||
icon={data.drying ? 'stop' : 'tint'}
|
||||
onClick={() => act('Dry')}
|
||||
>
|
||||
{data.drying ? 'Stop drying' : 'Dry'}
|
||||
</Button>
|
||||
) : (
|
||||
<>
|
||||
<Input
|
||||
autoFocus
|
||||
placeholder={'Search...'}
|
||||
value={searchText}
|
||||
onInput={(e, value) => setSearchText(value)}
|
||||
/>
|
||||
<>
|
||||
{data.isdryer ? (
|
||||
<Button
|
||||
icon={displayMode === MODE.tile ? 'list' : 'border-all'}
|
||||
tooltip={
|
||||
displayMode === MODE.tile
|
||||
? 'Display as a list'
|
||||
: 'Display as a grid'
|
||||
}
|
||||
tooltipPosition="bottom"
|
||||
onClick={() =>
|
||||
setDisplayMode(
|
||||
displayMode === MODE.tile ? MODE.list : MODE.tile,
|
||||
)
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
icon={data.drying ? 'stop' : 'tint'}
|
||||
onClick={() => act('Dry')}
|
||||
>
|
||||
{data.drying ? 'Stop drying' : 'Dry'}
|
||||
</Button>
|
||||
) : (
|
||||
<>
|
||||
<Input
|
||||
autoFocus
|
||||
placeholder={'Search...'}
|
||||
value={searchText}
|
||||
onInput={(e, value) => setSearchText(value)}
|
||||
/>
|
||||
<Button
|
||||
icon={displayMode === MODE.tile ? 'list' : 'border-all'}
|
||||
tooltip={
|
||||
displayMode === MODE.tile
|
||||
? 'Display as a list'
|
||||
: 'Display as a grid'
|
||||
}
|
||||
tooltipPosition="bottom"
|
||||
onClick={() =>
|
||||
setDisplayMode(
|
||||
displayMode === MODE.tile ? MODE.list : MODE.tile,
|
||||
)
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<Button
|
||||
icon="question"
|
||||
tooltip={
|
||||
<>
|
||||
LMB - Vend selected amount
|
||||
<br />
|
||||
RMB - Vend all
|
||||
</>
|
||||
}
|
||||
tooltipPosition={'bottom-end'}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
>
|
||||
{!contents.length ? (
|
||||
@@ -107,173 +119,107 @@ export const SmartVend = (props) => {
|
||||
|
||||
const ItemTile = ({ item }) => {
|
||||
const { act } = useBackend<Data>();
|
||||
const [itemCount, setItemCount] = useState(1);
|
||||
const fallback = (
|
||||
<Icon name="spinner" lineHeight="64px" size={3} spin color="gray" />
|
||||
);
|
||||
return (
|
||||
<Box m={1} p={0} inline width="64px">
|
||||
<Button
|
||||
p={0}
|
||||
height="64px"
|
||||
width="64px"
|
||||
tooltip={item.name}
|
||||
tooltipPosition="bottom"
|
||||
textAlign="right"
|
||||
disabled={item.amount < 1}
|
||||
>
|
||||
<Box
|
||||
position="absolute"
|
||||
right="2px"
|
||||
// in case you click on this instead, let it work as a regular click.
|
||||
onClick={() =>
|
||||
act('Release', {
|
||||
path: item.path,
|
||||
amount: itemCount,
|
||||
})
|
||||
}
|
||||
>
|
||||
x{item.amount}
|
||||
</Box>
|
||||
<DmIcon
|
||||
fallback={fallback}
|
||||
icon={item.icon}
|
||||
icon_state={item.icon_state}
|
||||
height="64px"
|
||||
width="64px"
|
||||
onClick={() =>
|
||||
act('Release', {
|
||||
path: item.path,
|
||||
amount: itemCount,
|
||||
})
|
||||
}
|
||||
/>
|
||||
{item.amount > 1 && (
|
||||
<Box
|
||||
color="transparent"
|
||||
minWidth="24px"
|
||||
height="24px"
|
||||
lineHeight="24px"
|
||||
textAlign="center"
|
||||
position="absolute"
|
||||
left="0"
|
||||
bottom="0"
|
||||
fontWeight="bold"
|
||||
fontSize="14px"
|
||||
>
|
||||
<NumberInput
|
||||
width="25px"
|
||||
minValue={1}
|
||||
maxValue={item.amount}
|
||||
step={1}
|
||||
value={itemCount}
|
||||
onChange={(value) => setItemCount(value)}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</Button>
|
||||
<Box
|
||||
style={{
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
{item.name}
|
||||
</Box>
|
||||
</Box>
|
||||
<ImageButton
|
||||
key={item.path}
|
||||
dmIcon={item.icon}
|
||||
dmIconState={item.icon_state}
|
||||
disabled={item.amount < 1}
|
||||
tooltip={item.name}
|
||||
tooltipPosition={'bottom'}
|
||||
buttons={
|
||||
item.amount > 1 && (
|
||||
<NumberInput
|
||||
minValue={1}
|
||||
maxValue={item.amount}
|
||||
step={1}
|
||||
value={1}
|
||||
onChange={(value) => {
|
||||
act('Release', {
|
||||
path: item.path,
|
||||
amount: value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
buttonsAlt={
|
||||
<Stack bold color="rgb(185, 185, 185)" fontSize={0.8}>
|
||||
<Stack.Item grow />
|
||||
<Stack.Item style={{ textShadow: '0 1px 1px black' }}>
|
||||
x{item.amount}
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
}
|
||||
onClick={() =>
|
||||
act('Release', {
|
||||
path: item.path,
|
||||
amount: 1,
|
||||
})
|
||||
}
|
||||
onRightClick={() =>
|
||||
act('Release', {
|
||||
path: item.path,
|
||||
amount: item.amount,
|
||||
})
|
||||
}
|
||||
>
|
||||
{item.name}
|
||||
</ImageButton>
|
||||
) as any;
|
||||
};
|
||||
|
||||
const ItemList = ({ item }) => {
|
||||
const { act } = useBackend<Data>();
|
||||
const fallback = (
|
||||
<Icon name="spinner" lineHeight="32px" size={3} spin color="gray" />
|
||||
);
|
||||
const [itemCount, setItemCount] = useState(1);
|
||||
const disabled = item.amount <= 1;
|
||||
return (
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
p={0}
|
||||
m={0}
|
||||
color="transparent"
|
||||
width="32px"
|
||||
height="32px"
|
||||
onClick={() =>
|
||||
act('Release', {
|
||||
path: item.path,
|
||||
amount: 1,
|
||||
})
|
||||
}
|
||||
<ImageButton
|
||||
key={item.path}
|
||||
fluid
|
||||
imageSize={32}
|
||||
dmIcon={item.icon}
|
||||
dmIconState={item.icon_state}
|
||||
disabled={item.amount < 1}
|
||||
buttons={
|
||||
<Stack
|
||||
opacity={disabled && 0.5}
|
||||
backgroundColor={'rgba(175, 175, 175, 0.1)'}
|
||||
style={{ pointerEvents: disabled ? 'none' : 'auto' }}
|
||||
>
|
||||
<DmIcon
|
||||
fallback={fallback}
|
||||
icon={item.icon}
|
||||
icon_state={item.icon_state}
|
||||
<NumberInput
|
||||
width="40px"
|
||||
minValue={1}
|
||||
maxValue={item.amount}
|
||||
step={1}
|
||||
value={1}
|
||||
onChange={(value) => {
|
||||
act('Release', {
|
||||
path: item.path,
|
||||
amount: value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item
|
||||
style={{
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
lineHeight: '32px',
|
||||
}}
|
||||
>
|
||||
{item.name}
|
||||
</Stack.Item>
|
||||
<Stack.Item
|
||||
grow
|
||||
style={{
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
lineHeight: '32px',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
style={{
|
||||
marginTop: '20px',
|
||||
borderBottom: '1px dotted gray',
|
||||
}}
|
||||
/>
|
||||
</Stack.Item>
|
||||
{item.amount > 1 && (
|
||||
<Stack.Item
|
||||
style={{
|
||||
lineHeight: '32px',
|
||||
}}
|
||||
>
|
||||
{`x${item.amount}`}
|
||||
</Stack>
|
||||
}
|
||||
onClick={() =>
|
||||
act('Release', {
|
||||
path: item.path,
|
||||
amount: 1,
|
||||
})
|
||||
}
|
||||
onRightClick={() =>
|
||||
act('Release', {
|
||||
path: item.path,
|
||||
amount: item.amount,
|
||||
})
|
||||
}
|
||||
>
|
||||
<Stack textAlign="left">
|
||||
<Stack.Item grow>{item.name}</Stack.Item>
|
||||
<Stack.Item opacity={0.5} fontSize={0.8}>
|
||||
x{item.amount}
|
||||
</Stack.Item>
|
||||
)}
|
||||
<Stack.Item>
|
||||
<Button
|
||||
py="4px"
|
||||
mt="4px"
|
||||
height="24px"
|
||||
lineHeight="16px"
|
||||
onClick={() =>
|
||||
act('Release', {
|
||||
path: item.path,
|
||||
amount: itemCount,
|
||||
})
|
||||
}
|
||||
>
|
||||
Vend
|
||||
</Button>
|
||||
<NumberInput
|
||||
width="25px"
|
||||
minValue={1}
|
||||
maxValue={item.amount}
|
||||
step={1}
|
||||
value={itemCount}
|
||||
onChange={(value) => setItemCount(value)}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</ImageButton>
|
||||
) as any;
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-popper": "^2.3.0",
|
||||
"tgui-core": "^1.7.2",
|
||||
"tgui-core": "^1.7.4",
|
||||
"tgui-dev-server": "workspace:*",
|
||||
"tgui-polyfill": "workspace:*"
|
||||
}
|
||||
|
||||
+8
-8
@@ -18723,17 +18723,17 @@ __metadata:
|
||||
react: "npm:^18.3.1"
|
||||
react-dom: "npm:^18.3.1"
|
||||
tgui: "workspace:*"
|
||||
tgui-core: "npm:^1.7.2"
|
||||
tgui-core: "npm:^1.7.4"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"tgui-core@npm:^1.7.2":
|
||||
version: 1.7.2
|
||||
resolution: "tgui-core@npm:1.7.2"
|
||||
"tgui-core@npm:^1.7.4":
|
||||
version: 1.7.4
|
||||
resolution: "tgui-core@npm:1.7.4"
|
||||
peerDependencies:
|
||||
react: ^18.2.0
|
||||
react-dom: ^18.2.0
|
||||
checksum: 10c0/401102042d4d0ede4f8658160124cd523c4ffc44492e0f7d0500d25e0b8a085be2b6f829c89b81eb706c369af16d6d57375704337d7bcc813480caa749c258d4
|
||||
checksum: 10c0/06b9d8702d6ae170383b28725bf6308cd320499367ea8ea1f9dd5039ab371cfe34419a7d3d1e0e2b86884326e8d4ab116e5601208d2f85d215b7c464fd32fdbf
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -18761,7 +18761,7 @@ __metadata:
|
||||
react: "npm:^18.3.1"
|
||||
react-dom: "npm:^18.3.1"
|
||||
tgui: "workspace:*"
|
||||
tgui-core: "npm:^1.7.2"
|
||||
tgui-core: "npm:^1.7.4"
|
||||
tgui-dev-server: "workspace:*"
|
||||
tgui-polyfill: "workspace:*"
|
||||
languageName: unknown
|
||||
@@ -18788,7 +18788,7 @@ __metadata:
|
||||
react: "npm:^18.3.1"
|
||||
react-dom: "npm:^18.3.1"
|
||||
tgui: "workspace:*"
|
||||
tgui-core: "npm:^1.7.2"
|
||||
tgui-core: "npm:^1.7.4"
|
||||
tgui-polyfill: "workspace:*"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
@@ -18850,7 +18850,7 @@ __metadata:
|
||||
react: "npm:^18.3.1"
|
||||
react-dom: "npm:^18.3.1"
|
||||
react-popper: "npm:^2.3.0"
|
||||
tgui-core: "npm:^1.7.2"
|
||||
tgui-core: "npm:^1.7.4"
|
||||
tgui-dev-server: "workspace:*"
|
||||
tgui-polyfill: "workspace:*"
|
||||
languageName: unknown
|
||||
|
||||
Reference in New Issue
Block a user