mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-17 11:05:16 +01:00
[MIRROR] TGUI Communications console (#1286)
* TGUI Communications console * fix Co-authored-by: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com> Co-authored-by: Gandalf <jzo123@hotmail.com>
This commit is contained in:
@@ -187,31 +187,26 @@ SUBSYSTEM_DEF(shuttle)
|
||||
return S
|
||||
WARNING("couldn't find dock with id: [id]")
|
||||
|
||||
/// Check if we can call the evac shuttle.
|
||||
/// Returns TRUE if we can. Otherwise, returns a string detailing the problem.
|
||||
/datum/controller/subsystem/shuttle/proc/canEvac(mob/user)
|
||||
var/srd = CONFIG_GET(number/shuttle_refuel_delay)
|
||||
if(world.time - SSticker.round_start_time < srd)
|
||||
to_chat(user, "<span class='alert'>The emergency shuttle is refueling. Please wait [DisplayTimeText(srd - (world.time - SSticker.round_start_time))] before trying again.</span>")
|
||||
return FALSE
|
||||
return "The emergency shuttle is refueling. Please wait [DisplayTimeText(srd - (world.time - SSticker.round_start_time))] before attempting to call."
|
||||
|
||||
switch(emergency.mode)
|
||||
if(SHUTTLE_RECALL)
|
||||
to_chat(user, "<span class='alert'>The emergency shuttle may not be called while returning to CentCom.</span>")
|
||||
return FALSE
|
||||
return "The emergency shuttle may not be called while returning to CentCom."
|
||||
if(SHUTTLE_CALL)
|
||||
to_chat(user, "<span class='alert'>The emergency shuttle is already on its way.</span>")
|
||||
return FALSE
|
||||
return "The emergency shuttle is already on its way."
|
||||
if(SHUTTLE_DOCKED)
|
||||
to_chat(user, "<span class='alert'>The emergency shuttle is already here.</span>")
|
||||
return FALSE
|
||||
return "The emergency shuttle is already here."
|
||||
if(SHUTTLE_IGNITING)
|
||||
to_chat(user, "<span class='alert'>The emergency shuttle is firing its engines to leave.</span>")
|
||||
return FALSE
|
||||
return "The emergency shuttle is firing its engines to leave."
|
||||
if(SHUTTLE_ESCAPE)
|
||||
to_chat(user, "<span class='alert'>The emergency shuttle is moving away to a safe distance.</span>")
|
||||
return FALSE
|
||||
if(SHUTTLE_STRANDED, SHUTTLE_DISABLED)
|
||||
to_chat(user, "<span class='alert'>The emergency shuttle has been disabled by CentCom.</span>")
|
||||
return FALSE
|
||||
return "The emergency shuttle is moving away to a safe distance."
|
||||
if(SHUTTLE_STRANDED)
|
||||
return "The emergency shuttle has been disabled by CentCom."
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -229,7 +224,9 @@ SUBSYSTEM_DEF(shuttle)
|
||||
Good luck.")
|
||||
emergency = backup_shuttle
|
||||
|
||||
if(!canEvac(user))
|
||||
var/can_evac_or_fail_reason = SSshuttle.canEvac(user)
|
||||
if(can_evac_or_fail_reason != TRUE)
|
||||
to_chat(user, "<span class='alert'>[can_evac_or_fail_reason]</span>")
|
||||
return
|
||||
|
||||
call_reason = trim(html_encode(call_reason))
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
|
||||
minor_announce(input["message"], "Incoming message from [input["message_sender"]]")
|
||||
for(var/obj/machinery/computer/communications/CM in GLOB.machines)
|
||||
CM.overrideCooldown()
|
||||
CM.override_cooldown()
|
||||
|
||||
/datum/world_topic/news_report
|
||||
keyword = "News_Report"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -187,7 +187,6 @@
|
||||
name = "Communications (Computer Board)"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/communications
|
||||
var/lastTimeUsed = 0
|
||||
|
||||
/obj/item/circuitboard/computer/message_monitor
|
||||
name = "Message Monitor (Computer Board)"
|
||||
|
||||
@@ -38,10 +38,10 @@
|
||||
cross.icon_state = "holylight"
|
||||
font_color = "blue"
|
||||
prayer_type = "SPIRITUAL PRAYER"
|
||||
|
||||
|
||||
var/msg_tmp = msg
|
||||
msg = "<span class='adminnotice'>[icon2html(cross, GLOB.admins)]<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]: </font>[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]:</b> <span class='linkify'>[msg]</span></span>"
|
||||
|
||||
|
||||
for(var/client/C in GLOB.admins)
|
||||
if(C.prefs.chat_toggles & CHAT_PRAYER)
|
||||
to_chat(C, msg, confidential = TRUE)
|
||||
@@ -53,23 +53,26 @@
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Prayer") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
//log_admin("HELP: [key_name(src)]: [msg]")
|
||||
|
||||
/proc/CentCom_announce(text , mob/Sender)
|
||||
/// Used by communications consoles to message CentCom
|
||||
/proc/message_centcom(text, mob/sender)
|
||||
var/msg = copytext_char(sanitize(text), 1, MAX_MESSAGE_LEN)
|
||||
msg = "<span class='adminnotice'><b><font color=orange>CENTCOM:</font>[ADMIN_FULLMONTY(Sender)] [ADMIN_CENTCOM_REPLY(Sender)]:</b> [msg]</span>"
|
||||
msg = "<span class='adminnotice'><b><font color=orange>CENTCOM:</font>[ADMIN_FULLMONTY(sender)] [ADMIN_CENTCOM_REPLY(sender)]:</b> [msg]</span>"
|
||||
to_chat(GLOB.admins, msg, confidential = TRUE)
|
||||
for(var/obj/machinery/computer/communications/C in GLOB.machines)
|
||||
C.overrideCooldown()
|
||||
for(var/obj/machinery/computer/communications/console in GLOB.machines)
|
||||
console.override_cooldown()
|
||||
|
||||
/proc/Syndicate_announce(text , mob/Sender)
|
||||
/// Used by communications consoles to message the Syndicate
|
||||
/proc/message_syndicate(text, mob/sender)
|
||||
var/msg = copytext_char(sanitize(text), 1, MAX_MESSAGE_LEN)
|
||||
msg = "<span class='adminnotice'><b><font color=crimson>SYNDICATE:</font>[ADMIN_FULLMONTY(Sender)] [ADMIN_SYNDICATE_REPLY(Sender)]:</b> [msg]</span>"
|
||||
msg = "<span class='adminnotice'><b><font color=crimson>SYNDICATE:</font>[ADMIN_FULLMONTY(sender)] [ADMIN_SYNDICATE_REPLY(sender)]:</b> [msg]</span>"
|
||||
to_chat(GLOB.admins, msg, confidential = TRUE)
|
||||
for(var/obj/machinery/computer/communications/C in GLOB.machines)
|
||||
C.overrideCooldown()
|
||||
for(var/obj/machinery/computer/communications/console in GLOB.machines)
|
||||
console.override_cooldown()
|
||||
|
||||
/proc/Nuke_request(text , mob/Sender)
|
||||
/// Used by communications consoles to request the nuclear launch codes
|
||||
/proc/nuke_request(text, mob/sender)
|
||||
var/msg = copytext_char(sanitize(text), 1, MAX_MESSAGE_LEN)
|
||||
msg = "<span class='adminnotice'><b><font color=orange>NUKE CODE REQUEST:</font>[ADMIN_FULLMONTY(Sender)] [ADMIN_CENTCOM_REPLY(Sender)] [ADMIN_SET_SD_CODE]:</b> [msg]</span>"
|
||||
msg = "<span class='adminnotice'><b><font color=orange>NUKE CODE REQUEST:</font>[ADMIN_FULLMONTY(sender)] [ADMIN_CENTCOM_REPLY(sender)] [ADMIN_SET_SD_CODE]:</b> [msg]</span>"
|
||||
to_chat(GLOB.admins, msg, confidential = TRUE)
|
||||
for(var/obj/machinery/computer/communications/C in GLOB.machines)
|
||||
C.overrideCooldown()
|
||||
for(var/obj/machinery/computer/communications/console in GLOB.machines)
|
||||
console.override_cooldown()
|
||||
|
||||
@@ -313,7 +313,9 @@
|
||||
to_chat(usr, "<span class='warning'>Wireless control is disabled!</span>")
|
||||
return
|
||||
|
||||
if(!SSshuttle.canEvac(src))
|
||||
var/can_evac_or_fail_reason = SSshuttle.canEvac(src)
|
||||
if(can_evac_or_fail_reason != TRUE)
|
||||
to_chat(usr, "<span class='alert'>[can_evac_or_fail_reason]</span>")
|
||||
return
|
||||
|
||||
var/reason = input(src, "What is the nature of your emergency? ([CALL_SHUTTLE_REASON_LENGTH] characters required.)", "Confirm Shuttle Call") as null|text
|
||||
|
||||
@@ -0,0 +1,667 @@
|
||||
import { sortBy } from "common/collections";
|
||||
import { capitalize } from "common/string";
|
||||
import { useBackend, useLocalState } from "../backend";
|
||||
import { Box, Button, Flex, Input, Modal, Section, Table, TextArea } from "../components";
|
||||
import { Window } from "../layouts";
|
||||
|
||||
const STATE_BUYING_SHUTTLE = "buying_shuttle";
|
||||
const STATE_CHANGING_STATUS = "changing_status";
|
||||
const STATE_MAIN = "main";
|
||||
const STATE_MESSAGES = "messages";
|
||||
|
||||
// Used for whether or not you need to swipe to confirm an alert level change
|
||||
const SWIPE_NEEDED = "SWIPE_NEEDED";
|
||||
|
||||
const sortByCreditCost = sortBy(shuttle => shuttle.creditCost);
|
||||
|
||||
const AlertButton = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { alertLevelTick, canSetAlertLevel } = data;
|
||||
const { alertLevel, setShowAlertLevelConfirm } = props;
|
||||
|
||||
const thisIsCurrent = data.alertLevel === alertLevel;
|
||||
|
||||
return (
|
||||
<Button
|
||||
icon="exclamation-triangle"
|
||||
color={thisIsCurrent && "good"}
|
||||
content={capitalize(alertLevel)}
|
||||
onClick={() => {
|
||||
if (thisIsCurrent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (canSetAlertLevel === SWIPE_NEEDED) {
|
||||
setShowAlertLevelConfirm([alertLevel, alertLevelTick]);
|
||||
} else {
|
||||
act("changeSecurityLevel", {
|
||||
newSecurityLevel: alertLevel,
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const MessageModal = (props, context) => {
|
||||
const { data } = useBackend(context);
|
||||
const { maxMessageLength } = data;
|
||||
|
||||
const [input, setInput] = useLocalState(context, props.label, "");
|
||||
|
||||
const longEnough = props.minLength === undefined
|
||||
|| input.length >= props.minLength;
|
||||
|
||||
return (
|
||||
<Modal>
|
||||
<Flex direction="column">
|
||||
<Flex.Item fontSize="16px" maxWidth="90vw" mb={1}>
|
||||
{props.label}:
|
||||
</Flex.Item>
|
||||
|
||||
<Flex.Item mr={2} mb={1}>
|
||||
<TextArea
|
||||
fluid
|
||||
height="20vh"
|
||||
width="80vw"
|
||||
backgroundColor="black"
|
||||
textColor="white"
|
||||
onInput={(_, value) => {
|
||||
setInput(value.substring(0, maxMessageLength));
|
||||
}}
|
||||
value={input}
|
||||
/>
|
||||
</Flex.Item>
|
||||
|
||||
<Flex.Item>
|
||||
<Button
|
||||
icon={props.icon}
|
||||
content={props.buttonText}
|
||||
color="good"
|
||||
disabled={!longEnough}
|
||||
tooltip={!longEnough ? "You need a longer reason." : ""}
|
||||
tooltipPosition="right"
|
||||
onClick={() => {
|
||||
if (longEnough) {
|
||||
setInput("");
|
||||
props.onSubmit(input);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button
|
||||
icon="times"
|
||||
content="Cancel"
|
||||
color="bad"
|
||||
onClick={props.onBack}
|
||||
/>
|
||||
</Flex.Item>
|
||||
|
||||
{!!props.notice && (
|
||||
<Flex.Item maxWidth="90vw">{props.notice}</Flex.Item>
|
||||
)}
|
||||
</Flex>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
const PageBuyingShuttle = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Section>
|
||||
<Button
|
||||
icon="chevron-left"
|
||||
content="Back"
|
||||
onClick={() => act("setState", { state: STATE_MAIN })}
|
||||
/>
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
Budget: <b>{data.budget.toLocaleString()}</b> credits
|
||||
</Section>
|
||||
|
||||
{sortByCreditCost(data.shuttles).map(shuttle => (
|
||||
<Section
|
||||
title={(
|
||||
<span
|
||||
style={{
|
||||
display: "inline-block",
|
||||
width: "70%",
|
||||
}}>
|
||||
{shuttle.name}
|
||||
</span>
|
||||
)}
|
||||
key={shuttle.ref}
|
||||
buttons={(
|
||||
<Button
|
||||
content={`${shuttle.creditCost.toLocaleString()} credits`}
|
||||
disabled={data.budget < shuttle.creditCost}
|
||||
onClick={() => act("purchaseShuttle", {
|
||||
shuttle: shuttle.ref,
|
||||
})}
|
||||
tooltip={
|
||||
data.budget < shuttle.creditCost
|
||||
? `You need ${shuttle.creditCost - data.budget} more credits.`
|
||||
: undefined
|
||||
}
|
||||
tooltipPosition="left"
|
||||
/>
|
||||
)}>
|
||||
<Box>{shuttle.description}</Box>
|
||||
{
|
||||
shuttle.prerequisites
|
||||
? <b>Prerequisites: {shuttle.prerequisites}</b>
|
||||
: null
|
||||
}
|
||||
</Section>
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const PageChangingStatus = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { maxStatusLineLength } = data;
|
||||
|
||||
const [lineOne, setLineOne] = useLocalState(context, "lineOne", data.lineOne);
|
||||
const [lineTwo, setLineTwo] = useLocalState(context, "lineTwo", data.lineTwo);
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Section>
|
||||
<Button
|
||||
icon="chevron-left"
|
||||
content="Back"
|
||||
onClick={() => act("setState", { state: STATE_MAIN })}
|
||||
/>
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<Flex direction="column">
|
||||
<Flex.Item>
|
||||
<Button
|
||||
icon="times"
|
||||
content="Clear Alert"
|
||||
color="bad"
|
||||
onClick={() => act("setStatusPicture", { picture: "blank" })}
|
||||
/>
|
||||
</Flex.Item>
|
||||
|
||||
<Flex.Item mt={1}>
|
||||
<Button
|
||||
icon="check-square-o"
|
||||
content="Default"
|
||||
onClick={() => act("setStatusPicture", { picture: "default" })}
|
||||
/>
|
||||
|
||||
<Button
|
||||
icon="bell-o"
|
||||
content="Red Alert"
|
||||
onClick={() => act("setStatusPicture", { picture: "redalert" })}
|
||||
/>
|
||||
|
||||
<Button
|
||||
icon="exclamation-triangle"
|
||||
content="Lockdown"
|
||||
onClick={() => act("setStatusPicture", { picture: "lockdown" })}
|
||||
/>
|
||||
|
||||
<Button
|
||||
icon="exclamation-circle"
|
||||
content="Biohazard"
|
||||
onClick={() => act("setStatusPicture", { picture: "biohazard" })}
|
||||
/>
|
||||
|
||||
<Button
|
||||
icon="space-shuttle"
|
||||
content="Shuttle ETA"
|
||||
onClick={() => act("setStatusPicture", { picture: "shuttle" })}
|
||||
/>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
</Section>
|
||||
|
||||
<Section title="Message">
|
||||
<Flex direction="column">
|
||||
<Flex.Item mb={1}>
|
||||
<Input
|
||||
maxLength={maxStatusLineLength}
|
||||
value={lineOne}
|
||||
width="200px"
|
||||
onChange={(_, value) => setLineOne(value)}
|
||||
/>
|
||||
</Flex.Item>
|
||||
|
||||
<Flex.Item mb={1}>
|
||||
<Input
|
||||
maxLength={maxStatusLineLength}
|
||||
value={lineTwo}
|
||||
width="200px"
|
||||
onChange={(_, value) => setLineTwo(value)}
|
||||
/>
|
||||
</Flex.Item>
|
||||
|
||||
<Flex.Item>
|
||||
<Button
|
||||
icon="comment-o"
|
||||
content="Message"
|
||||
onClick={() => act("setStatusMessage", {
|
||||
lineOne,
|
||||
lineTwo,
|
||||
})}
|
||||
/>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
</Section>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const PageMain = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
alertLevel,
|
||||
alertLevelTick,
|
||||
callShuttleReasonMinLength,
|
||||
canBuyShuttles,
|
||||
canMakeAnnouncement,
|
||||
canMessageAssociates,
|
||||
canRequestNuke,
|
||||
canSendToSectors,
|
||||
canSetAlertLevel,
|
||||
canToggleEmergencyAccess,
|
||||
emagged,
|
||||
emergencyAccess,
|
||||
importantActionReady,
|
||||
sectors,
|
||||
shuttleCalled,
|
||||
shuttleCalledPreviously,
|
||||
shuttleCanEvacOrFailReason,
|
||||
shuttleLastCalled,
|
||||
shuttleRecallable,
|
||||
} = data;
|
||||
|
||||
const [callingShuttle, setCallingShuttle] = useLocalState(
|
||||
context, "calling_shuttle", false);
|
||||
const [messagingAssociates, setMessagingAssociates] = useLocalState(
|
||||
context, "messaging_associates", false);
|
||||
const [messagingSector, setMessagingSector] = useLocalState(
|
||||
context, "messaing_sector", null);
|
||||
const [requestingNukeCodes, setRequestingNukeCodes] = useLocalState(
|
||||
context, "requesting_nuke_codes", false);
|
||||
|
||||
const [
|
||||
[showAlertLevelConfirm, confirmingAlertLevelTick],
|
||||
setShowAlertLevelConfirm,
|
||||
] = useLocalState(context, "showConfirmPrompt", [null, null]);
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Section title="Emergency Shuttle">
|
||||
{
|
||||
shuttleCalled
|
||||
? <Button.Confirm
|
||||
icon="space-shuttle"
|
||||
content="Recall Emergency Shuttle"
|
||||
color="bad"
|
||||
disabled={!shuttleRecallable}
|
||||
tooltip={!shuttleRecallable && "It's too late for the emergency shuttle to be recalled."}
|
||||
tooltipPosition="bottom-right"
|
||||
onClick={() => act("recallShuttle")}
|
||||
/>
|
||||
: <Button
|
||||
icon="space-shuttle"
|
||||
content="Call Emergency Shuttle"
|
||||
disabled={shuttleCanEvacOrFailReason !== 1}
|
||||
tooltip={
|
||||
shuttleCanEvacOrFailReason !== 1
|
||||
? shuttleCanEvacOrFailReason
|
||||
: undefined
|
||||
}
|
||||
tooltipPosition="bottom-right"
|
||||
onClick={() => setCallingShuttle(true)}
|
||||
/>
|
||||
}
|
||||
|
||||
{!!shuttleCalledPreviously && (
|
||||
shuttleLastCalled && (
|
||||
<Box>
|
||||
Most recent shuttle call/recall traced to:
|
||||
{" "}<b>{shuttleLastCalled}</b>
|
||||
</Box>
|
||||
) || (
|
||||
<Box>Unable to trace most recent shuttle/recall signal.</Box>
|
||||
)
|
||||
)}
|
||||
</Section>
|
||||
|
||||
{!!canSetAlertLevel && (
|
||||
<Section title="Alert Level">
|
||||
<Flex justify="space-between">
|
||||
<Flex.Item>
|
||||
<Box>
|
||||
Currently on <b>{capitalize(alertLevel)}</b> Alert
|
||||
</Box>
|
||||
</Flex.Item>
|
||||
|
||||
<Flex.Item>
|
||||
<AlertButton
|
||||
alertLevel="green"
|
||||
showAlertLevelConfirm={showAlertLevelConfirm}
|
||||
setShowAlertLevelConfirm={setShowAlertLevelConfirm}
|
||||
/>
|
||||
|
||||
<AlertButton
|
||||
alertLevel="blue"
|
||||
showAlertLevelConfirm={showAlertLevelConfirm}
|
||||
setShowAlertLevelConfirm={setShowAlertLevelConfirm}
|
||||
/>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
</Section>
|
||||
)}
|
||||
|
||||
<Section title="Functions">
|
||||
<Flex
|
||||
direction="column">
|
||||
{!!canMakeAnnouncement && <Button
|
||||
icon="bullhorn"
|
||||
content="Make Priority Announcement"
|
||||
onClick={() => act("makePriorityAnnouncement")}
|
||||
/>}
|
||||
|
||||
{!!canToggleEmergencyAccess && <Button.Confirm
|
||||
icon="id-card-o"
|
||||
content={`${emergencyAccess ? "Disable" : "Enable"} Emergency Maintenance Access`}
|
||||
color={emergencyAccess ? "bad" : undefined}
|
||||
onClick={() => act("toggleEmergencyAccess")}
|
||||
/>}
|
||||
|
||||
<Button
|
||||
icon="desktop"
|
||||
content="Set Status Display"
|
||||
onClick={() => act("setState", { state: STATE_CHANGING_STATUS })}
|
||||
/>
|
||||
|
||||
<Button
|
||||
icon="envelope-o"
|
||||
content="Message List"
|
||||
onClick={() => act("setState", { state: STATE_MESSAGES })}
|
||||
/>
|
||||
|
||||
{(canBuyShuttles !== 0) && <Button
|
||||
icon="shopping-cart"
|
||||
content="Purchase Shuttle"
|
||||
disabled={canBuyShuttles !== 1}
|
||||
// canBuyShuttles is a string detailing the fail reason
|
||||
// if one can be given
|
||||
tooltip={canBuyShuttles !== 1 ? canBuyShuttles : undefined}
|
||||
tooltipPosition="right"
|
||||
onClick={() => act("setState", { state: STATE_BUYING_SHUTTLE })}
|
||||
/>}
|
||||
|
||||
{!!canMessageAssociates && <Button
|
||||
icon="comment-o"
|
||||
content={`Send message to ${emagged ? "[UNKNOWN]" : "CentCom"}`}
|
||||
disabled={!importantActionReady}
|
||||
onClick={() => setMessagingAssociates(true)}
|
||||
/>}
|
||||
|
||||
{!!canRequestNuke && <Button
|
||||
icon="radiation"
|
||||
content="Request Nuclear Authentication Codes"
|
||||
disabled={!importantActionReady}
|
||||
onClick={() => setRequestingNukeCodes(true)}
|
||||
/>}
|
||||
|
||||
{!!emagged && <Button
|
||||
icon="undo"
|
||||
content="Restore Backup Routing Data"
|
||||
onClick={() => act("restoreBackupRoutingData")}
|
||||
/>}
|
||||
</Flex>
|
||||
</Section>
|
||||
|
||||
{!!canMessageAssociates && messagingAssociates && <MessageModal
|
||||
label={`Message to transmit to ${emagged ? "[ABNORMAL ROUTING COORDINATES]" : "CentCom"} via quantum entanglement`}
|
||||
notice="Please be aware that this process is very expensive, and abuse will lead to...termination. Transmission does not guarantee a response."
|
||||
icon="bullhorn"
|
||||
buttonText="Send"
|
||||
onBack={() => setMessagingAssociates(false)}
|
||||
onSubmit={message => {
|
||||
setMessagingAssociates(false);
|
||||
act("messageAssociates", {
|
||||
message,
|
||||
});
|
||||
}}
|
||||
/>}
|
||||
|
||||
{!!canRequestNuke && requestingNukeCodes && <MessageModal
|
||||
label="Reason for requesting nuclear self-destruct codes"
|
||||
notice="Misuse of the nuclear request system will not be tolerated under any circumstances. Transmission does not guarantee a response."
|
||||
icon="bomb"
|
||||
buttonText="Request Codes"
|
||||
onBack={() => setRequestingNukeCodes(false)}
|
||||
onSubmit={reason => {
|
||||
setRequestingNukeCodes(false);
|
||||
act("requestNukeCodes", {
|
||||
reason,
|
||||
});
|
||||
}}
|
||||
/>}
|
||||
|
||||
{!!callingShuttle && <MessageModal
|
||||
label="Nature of emergency"
|
||||
icon="space-shuttle"
|
||||
buttonText="Call Shuttle"
|
||||
minLength={callShuttleReasonMinLength}
|
||||
onBack={() => setCallingShuttle(false)}
|
||||
onSubmit={reason => {
|
||||
setCallingShuttle(false);
|
||||
act("callShuttle", {
|
||||
reason,
|
||||
});
|
||||
}}
|
||||
/>}
|
||||
|
||||
{
|
||||
!!canSetAlertLevel
|
||||
&& showAlertLevelConfirm
|
||||
&& confirmingAlertLevelTick === alertLevelTick
|
||||
&& (
|
||||
<Modal>
|
||||
<Flex
|
||||
direction="column"
|
||||
textAlign="center"
|
||||
width="300px">
|
||||
<Flex.Item fontSize="16px" mb={2}>
|
||||
Swipe ID to confirm change
|
||||
</Flex.Item>
|
||||
|
||||
<Flex.Item mr={2} mb={1}>
|
||||
<Button
|
||||
icon="id-card-o"
|
||||
content="Swipe ID"
|
||||
color="good"
|
||||
fontSize="16px"
|
||||
onClick={() => act("changeSecurityLevel", {
|
||||
newSecurityLevel: showAlertLevelConfirm,
|
||||
})}
|
||||
/>
|
||||
|
||||
<Button
|
||||
icon="times"
|
||||
content="Cancel"
|
||||
color="bad"
|
||||
fontSize="16px"
|
||||
onClick={() => setShowAlertLevelConfirm(false)}
|
||||
/>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
!!canSendToSectors
|
||||
&& sectors.length > 0
|
||||
&& (
|
||||
<Section title="Allied Sectors">
|
||||
<Flex>
|
||||
{
|
||||
sectors.map(sectorName => (
|
||||
<Button
|
||||
content={
|
||||
`Send a message to station in ${sectorName} sector`
|
||||
}
|
||||
disabled={!importantActionReady}
|
||||
key={sectorName}
|
||||
onClick={() => setMessagingSector(sectorName)}
|
||||
/>
|
||||
))
|
||||
}
|
||||
|
||||
{sectors.length > 2 && (
|
||||
<Button
|
||||
content="Send a message to all allied stations"
|
||||
disabled={!importantActionReady}
|
||||
onClick={() => setMessagingSector("all")}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
!!canSendToSectors
|
||||
&& sectors.length > 0
|
||||
&& messagingSector
|
||||
&& <MessageModal
|
||||
label="Message to send to allied station"
|
||||
notice="Please be aware that this process is very expensive, and abuse will lead to...termination."
|
||||
icon="bullhorn"
|
||||
buttonText="Send"
|
||||
onBack={() => setMessagingSector(null)}
|
||||
onSubmit={message => {
|
||||
act("sendToOtherSector", {
|
||||
destination: messagingSector,
|
||||
message,
|
||||
});
|
||||
|
||||
setMessagingSector(null);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const PageMessages = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const messages = data.messages || [];
|
||||
|
||||
const children = [];
|
||||
|
||||
children.push((
|
||||
<Section>
|
||||
<Button
|
||||
icon="chevron-left"
|
||||
content="Back"
|
||||
onClick={() => act("setState", { state: STATE_MAIN })}
|
||||
/>
|
||||
</Section>
|
||||
));
|
||||
|
||||
const messageElements = [];
|
||||
|
||||
for (const [messageIndex, message] of Object.entries(messages)) {
|
||||
let answers = null;
|
||||
|
||||
if (message.possibleAnswers.length > 0) {
|
||||
answers = (
|
||||
<Box mt={1}>
|
||||
{message.possibleAnswers.map((answer, answerIndex) => (
|
||||
<Button
|
||||
content={answer}
|
||||
color={message.answered === answerIndex + 1 ? "good" : undefined}
|
||||
key={answerIndex}
|
||||
onClick={message.answered ? undefined : () => act("answerMessage", {
|
||||
message: messageIndex + 1,
|
||||
answer: answerIndex + 1,
|
||||
})}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
messageElements.push((
|
||||
<Section
|
||||
title={message.title}
|
||||
key={messageIndex}
|
||||
buttons={(
|
||||
<Button.Confirm
|
||||
icon="trash"
|
||||
content="Delete"
|
||||
color="red"
|
||||
onClick={() => act("deleteMessage", {
|
||||
message: messageIndex + 1,
|
||||
})}
|
||||
/>
|
||||
)}>
|
||||
<Box>{message.content}</Box>
|
||||
|
||||
{answers}
|
||||
</Section>
|
||||
));
|
||||
}
|
||||
|
||||
children.push(messageElements.reverse());
|
||||
|
||||
return children;
|
||||
};
|
||||
|
||||
export const CommunicationsConsole = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
authenticated,
|
||||
authorizeName,
|
||||
canLogOut,
|
||||
emagged,
|
||||
page,
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<Window
|
||||
width={400}
|
||||
height={650}
|
||||
theme={emagged ? "syndicate" : undefined}
|
||||
resizable>
|
||||
<Window.Content scrollable>
|
||||
{(canLogOut || !authenticated)
|
||||
? (
|
||||
<Section title="Authentication">
|
||||
<Button
|
||||
icon={authenticated ? "sign-out-alt" : "sign-in-alt"}
|
||||
content={authenticated ? `Log Out${authorizeName ? ` (${authorizeName})` : ""}` : "Log In"}
|
||||
color={authenticated ? "bad" : "good"}
|
||||
onClick={() => act("toggleAuthentication")}
|
||||
/>
|
||||
</Section>
|
||||
)
|
||||
: null}
|
||||
|
||||
{!!authenticated && (
|
||||
page === STATE_BUYING_SHUTTLE && <PageBuyingShuttle />
|
||||
|| page === STATE_CHANGING_STATUS && <PageChangingStatus />
|
||||
|| page === STATE_MAIN && <PageMain />
|
||||
|| page === STATE_MESSAGES && <PageMessages />
|
||||
|| <Box>Page not implemented: {page}</Box>
|
||||
)}
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user