mirror of
https://github.com/fulpstation/fulpstation.git
synced 2025-12-10 10:01:40 +00:00
uplink (#47727)
small tweaks proper theme search + input bar theming properly functional input theme rebuild
This commit is contained in:
committed by
Emmett Gaines
parent
494dac37fa
commit
525d39d9f1
@@ -26,6 +26,7 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
var/unlock_note
|
||||
var/unlock_code
|
||||
var/failsafe_code
|
||||
var/compact_mode = FALSE
|
||||
var/debug = FALSE
|
||||
|
||||
var/list/previous_attempts
|
||||
@@ -128,7 +129,7 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
active = TRUE
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "uplink", name, 450, 750, master_ui, state)
|
||||
ui = new(user, src, ui_key, "uplink", name, 720, 480, master_ui, state)
|
||||
ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input.
|
||||
ui.set_style("syndicate")
|
||||
ui.open()
|
||||
@@ -139,13 +140,17 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
var/list/data = list()
|
||||
data["telecrystals"] = telecrystals
|
||||
data["lockable"] = lockable
|
||||
data["compact_mode"] = compact_mode
|
||||
|
||||
return data
|
||||
|
||||
/datum/component/uplink/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["categories"] = list()
|
||||
for(var/category in uplink_items)
|
||||
var/list/cat = list(
|
||||
"name" = category,
|
||||
"items" = (category == selected_cat ? list() : null))
|
||||
if(category == selected_cat)
|
||||
for(var/item in uplink_items[category])
|
||||
var/datum/uplink_item/I = uplink_items[category][item]
|
||||
if(I.limited_stock == 0)
|
||||
@@ -199,6 +204,8 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
SStgui.close_uis(src)
|
||||
if("select")
|
||||
selected_cat = params["category"]
|
||||
if("compact_toggle")
|
||||
compact_mode = !compact_mode
|
||||
return TRUE
|
||||
|
||||
/datum/component/uplink/proc/MakePurchase(mob/user, datum/uplink_item/U)
|
||||
|
||||
@@ -132,11 +132,11 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
//Discounts (dynamically filled above)
|
||||
/datum/uplink_item/discounts
|
||||
category = "Discounted Gear"
|
||||
category = "Discounts"
|
||||
|
||||
//All bundles and telecrystals
|
||||
/datum/uplink_item/bundles_TC
|
||||
category = "Bundles and Telecrystals"
|
||||
category = "Bundles"
|
||||
surplus = 0
|
||||
cant_discount = TRUE
|
||||
|
||||
@@ -312,7 +312,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
// Dangerous Items
|
||||
/datum/uplink_item/dangerous
|
||||
category = "Conspicuous and Dangerous Weapons"
|
||||
category = "Conspicuous Weapons"
|
||||
|
||||
/datum/uplink_item/dangerous/rawketlawnchair
|
||||
name = "84mm Rocket Propelled Grenade Launcher"
|
||||
@@ -526,7 +526,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
// Stealthy Weapons
|
||||
/datum/uplink_item/stealthy_weapons
|
||||
category = "Stealthy and Inconspicuous Weapons"
|
||||
category = "Stealthy Weapons"
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/combatglovesplus
|
||||
name = "Combat Gloves Plus"
|
||||
@@ -857,7 +857,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
//Grenades and Explosives
|
||||
/datum/uplink_item/explosives
|
||||
category = "Grenades and Explosives"
|
||||
category = "Explosives"
|
||||
|
||||
/datum/uplink_item/explosives/bioterrorfoam
|
||||
name = "Bioterror Foam Grenade"
|
||||
@@ -1021,7 +1021,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
//Support and Mechs
|
||||
/datum/uplink_item/support
|
||||
category = "Support and Mechanized Exosuits"
|
||||
category = "Support and Exosuits"
|
||||
surplus = 0
|
||||
include_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
@@ -1095,7 +1095,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
// Stealth Items
|
||||
/datum/uplink_item/stealthy_tools
|
||||
category = "Stealth and Camouflage Items"
|
||||
category = "Stealth Gadgets"
|
||||
|
||||
/datum/uplink_item/stealthy_tools/agent_card
|
||||
name = "Agent Identification Card"
|
||||
@@ -1197,7 +1197,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
//Space Suits and Hardsuits
|
||||
/datum/uplink_item/suits
|
||||
category = "Space Suits and Hardsuits"
|
||||
category = "Space Suits"
|
||||
surplus = 40
|
||||
|
||||
/datum/uplink_item/suits/space_suit
|
||||
@@ -1239,7 +1239,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
// Devices and Tools
|
||||
/datum/uplink_item/device_tools
|
||||
category = "Devices and Tools"
|
||||
category = "Misc. Gadgets"
|
||||
|
||||
/datum/uplink_item/device_tools/cutouts
|
||||
name = "Adaptive Cardboard Cutouts"
|
||||
|
||||
@@ -128,7 +128,7 @@ export const resizeMoveHandler = event => {
|
||||
};
|
||||
|
||||
export const resizeEndHandler = event => {
|
||||
logger.log('resize end');
|
||||
logger.log('resize end', [dragState.currentSize.x, dragState.currentSize.y]);
|
||||
resizeHandler(event);
|
||||
document.removeEventListener('mousemove', resizeMoveHandler);
|
||||
document.removeEventListener('mouseup', resizeEndHandler);
|
||||
@@ -140,19 +140,25 @@ const resizeHandler = event => {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
let x = dragState.initialWindowSize.x
|
||||
dragState.currentSize = {
|
||||
x: (
|
||||
dragState.initialWindowSize.x
|
||||
+ (event.screenX
|
||||
- window.screenX
|
||||
+ dragState.dragPointOffset.x
|
||||
+ 1)
|
||||
* dragState.resizeMatrix.x;
|
||||
let y = dragState.initialWindowSize.y
|
||||
* dragState.resizeMatrix.x
|
||||
),
|
||||
y: (
|
||||
dragState.initialWindowSize.y
|
||||
+ (event.screenY
|
||||
- window.screenY
|
||||
+ dragState.dragPointOffset.y
|
||||
+ 1)
|
||||
* dragState.resizeMatrix.y;
|
||||
* dragState.resizeMatrix.y
|
||||
),
|
||||
};
|
||||
winset(dragState.windowRef, 'size',
|
||||
// Sane window size values
|
||||
Math.max(x, 250) + ',' + Math.max(y, 120));
|
||||
Math.max(dragState.currentSize.x, 250) + ',' + Math.max(dragState.currentSize.y, 120));
|
||||
};
|
||||
|
||||
218
tgui-next/packages/tgui/interfaces/Uplink.js
Normal file
218
tgui-next/packages/tgui/interfaces/Uplink.js
Normal file
@@ -0,0 +1,218 @@
|
||||
/* eslint-disable react/prefer-stateless-function */
|
||||
import { toFixed } from 'common/math';
|
||||
import { decodeHtmlEntities } from 'common/string';
|
||||
import { Fragment, Component } from 'inferno';
|
||||
import { act } from '../byond';
|
||||
import { Box, Button, LabeledList, NumberInput, Section, Tabs, Table, Input } from '../components';
|
||||
import { map } from 'common/fp';
|
||||
import { createLogger } from '../logging';
|
||||
import { classes } from 'common/react';
|
||||
|
||||
const logger = createLogger("uplink");
|
||||
|
||||
// It's a class because we need to store state in the form of the current hovered item, and current search terms
|
||||
export class Uplink extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
hoveredItem: {},
|
||||
currentSearch: "",
|
||||
};
|
||||
}
|
||||
|
||||
setHoveredItem(hoveredItem) {
|
||||
this.setState({
|
||||
hoveredItem: hoveredItem,
|
||||
});
|
||||
}
|
||||
|
||||
setSearchText(currentSearch) {
|
||||
this.setState({
|
||||
currentSearch: currentSearch,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { state } = this.props;
|
||||
const { config, data } = state;
|
||||
const { ref } = config;
|
||||
const {
|
||||
compact_mode,
|
||||
lockable,
|
||||
telecrystals,
|
||||
categories = [],
|
||||
} = data;
|
||||
const { hoveredItem, currentSearch } = this.state;
|
||||
const hoveredCost = hoveredItem.cost || 0;
|
||||
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") /* lock */}
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
>
|
||||
{currentSearch.length > 0 ? (
|
||||
<table className="Table">
|
||||
{categories.map(category => {
|
||||
const {
|
||||
items = [],
|
||||
name,
|
||||
} = category;
|
||||
return (
|
||||
<Fragment key={name}>
|
||||
{items.map(item => {
|
||||
const notSameItem = (hoveredItem.name !== item.name);
|
||||
const notEnoughHovered = (telecrystals - hoveredCost < item.cost);
|
||||
const disabledDueToHovered = (notSameItem && notEnoughHovered);
|
||||
if (!item.name.toLowerCase().includes(currentSearch.toLowerCase())) { return; }
|
||||
return (
|
||||
<tr
|
||||
key={item.name}
|
||||
className="Table__row candystripe"
|
||||
>
|
||||
<td className="Table__cell" >
|
||||
{item.name}
|
||||
</td>
|
||||
<td
|
||||
className="Table__cell"
|
||||
style={{
|
||||
"width": "6px",
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
fluid
|
||||
content={item.cost + " TC"}
|
||||
disabled={telecrystals < item.cost || disabledDueToHovered}
|
||||
tooltip={item.desc}
|
||||
tooltipPosition="left"
|
||||
onmouseover={() => this.setHoveredItem(item)}
|
||||
onmouseout={() => this.setHoveredItem({})}
|
||||
onClick={() => act(ref, "buy", {
|
||||
category: category,
|
||||
item: item.name,
|
||||
cost: item.cost,
|
||||
})}
|
||||
/>
|
||||
</td>
|
||||
</tr>);
|
||||
})}
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
</table>
|
||||
) : (
|
||||
<Tabs vertical>
|
||||
{categories.map(category => {
|
||||
const {
|
||||
items = [],
|
||||
name,
|
||||
} = category;
|
||||
return (
|
||||
<Tabs.Tab
|
||||
key={name}
|
||||
label={name}
|
||||
>
|
||||
{compact_mode ? (
|
||||
<Table>
|
||||
{items.map(item => {
|
||||
const notSameItem = (hoveredItem.name !== item.name);
|
||||
const notEnoughHovered = (telecrystals - hoveredCost < item.cost);
|
||||
const disabledDueToHovered = (notSameItem && notEnoughHovered);
|
||||
return (
|
||||
<Table.Row
|
||||
key={item.name}
|
||||
className="candystripe"
|
||||
>
|
||||
<Table.Cell bold>
|
||||
{decodeHtmlEntities(item.name)}:
|
||||
</Table.Cell>
|
||||
<Table.Cell
|
||||
textAlign="right"
|
||||
width={1}
|
||||
>
|
||||
<Button
|
||||
fluid
|
||||
content={item.cost + " TC"}
|
||||
disabled={telecrystals < item.cost || disabledDueToHovered}
|
||||
tooltip={item.desc}
|
||||
tooltipPosition="left"
|
||||
onmouseover={() => this.setHoveredItem(item)}
|
||||
onmouseout={() => this.setHoveredItem({})}
|
||||
onClick={() => act(ref, "buy", {
|
||||
category: category,
|
||||
item: item.name,
|
||||
cost: item.cost,
|
||||
})}
|
||||
/>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
);
|
||||
})}
|
||||
</Table>
|
||||
) : (
|
||||
items.map(item => {
|
||||
const notSameItem = (hoveredItem.name !== item.name);
|
||||
const notEnoughHovered = (telecrystals - hoveredCost < item.cost);
|
||||
const disabledDueToHovered = (notSameItem && notEnoughHovered);
|
||||
return (
|
||||
<Section
|
||||
key={item.name}
|
||||
title={item.name}
|
||||
level={2}
|
||||
buttons={(
|
||||
<Button
|
||||
content={item.cost + " TC"}
|
||||
disabled={telecrystals < item.cost || disabledDueToHovered}
|
||||
onmouseover={() => this.setHoveredItem(item)}
|
||||
onmouseout={() => this.setHoveredItem({})}
|
||||
onClick={() => act(ref, "buy", {
|
||||
category: category,
|
||||
item: item.name,
|
||||
cost: item.cost,
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
{decodeHtmlEntities(item.desc)}
|
||||
</Section>
|
||||
);
|
||||
})
|
||||
)}
|
||||
<LabeledList />
|
||||
</Tabs.Tab>
|
||||
);
|
||||
})}
|
||||
</Tabs>
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -56,6 +56,7 @@ import { SuitStorageUnit } from './interfaces/SuitStorageUnit';
|
||||
import { TankDispenser } from './interfaces/TankDispenser';
|
||||
import { ThermoMachine } from './interfaces/ThermoMachine';
|
||||
import { TurbineComputer } from './interfaces/TurbineComputer';
|
||||
import { Uplink } from './interfaces/Uplink';
|
||||
import { VaultController } from './interfaces/VaultController';
|
||||
import { Wires } from './interfaces/Wires';
|
||||
import { Holodeck } from './interfaces/Holodeck';
|
||||
@@ -314,6 +315,10 @@ const ROUTES = {
|
||||
component: () => TurbineComputer,
|
||||
scrollable: false,
|
||||
},
|
||||
uplink: {
|
||||
component: () => Uplink,
|
||||
scrollable: true,
|
||||
},
|
||||
vault_controller: {
|
||||
component: () => VaultController,
|
||||
scrollable: false,
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
'color-caution': #be6209,
|
||||
'color-danger': #9a9d00,
|
||||
));
|
||||
@include meta.load-css('../components/Input.scss', $with: (
|
||||
'border-color': colors.$primary,
|
||||
));
|
||||
@include meta.load-css('../components/Layout.scss');
|
||||
@include meta.load-css('../components/NoticeBox.scss', $with: (
|
||||
'color-first': #750000,
|
||||
@@ -36,6 +39,9 @@
|
||||
@include meta.load-css('../components/TitleBar.scss', $with: (
|
||||
'color-background': #910101,
|
||||
));
|
||||
@include meta.load-css('../components/Tooltip.scss', $with: (
|
||||
'color-background': #4a0202,
|
||||
));
|
||||
|
||||
.Layout__content {
|
||||
background-image: url('../../assets/bg-syndicate.svg');
|
||||
|
||||
Reference in New Issue
Block a user