Merge pull request #4493 from CHOMPStation2/upstream-merge-13260

[MIRROR] Communicator Reply Messages
This commit is contained in:
Nadyr
2022-07-03 22:13:02 -04:00
committed by GitHub
7 changed files with 165 additions and 52 deletions

View File

@@ -381,6 +381,8 @@
exonet.send_message(their_address, "text", text) exonet.send_message(their_address, "text", text)
im_list += list(list("address" = exonet.address, "to_address" = their_address, "im" = text)) im_list += list(list("address" = exonet.address, "to_address" = their_address, "im" = text))
log_pda("(COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]", usr) log_pda("(COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]", usr)
var/obj/item/device/communicator/comm = exonet.get_atom_from_address(their_address)
to_chat(usr, "<span class='notice'>[bicon(src)] Sent message to [comm.owner], <b>\"[text]\"</b> (<a href='?src=\ref[src];action=Reply;target=\ref[exonet.get_atom_from_address(comm.exonet.address)]'>Reply</a>)</span>")
for(var/mob/M in player_list) for(var/mob/M in player_list)
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears)) if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat) if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)

View File

@@ -108,7 +108,7 @@
exonet.send_message(comm.exonet.address, "text", message) exonet.send_message(comm.exonet.address, "text", message)
im_list += list(list("address" = exonet.address, "to_address" = comm.exonet.address, "im" = message)) im_list += list(list("address" = exonet.address, "to_address" = comm.exonet.address, "im" = message))
log_pda("(COMM: [src]) sent \"[message]\" to [exonet.get_atom_from_address(comm.exonet.address)]", usr) log_pda("(COMM: [src]) sent \"[message]\" to [exonet.get_atom_from_address(comm.exonet.address)]", usr)
to_chat(usr, "<span class='notice'>[bicon(src)] Sent message to [comm.owner], <b>\"[message]\"</b></span>") to_chat(usr, "<span class='notice'>[bicon(src)] Sent message to [comm.owner], <b>\"[message]\"</b> (<a href='?src=\ref[src];action=Reply;target=\ref[exonet.get_atom_from_address(comm.exonet.address)]'>Reply</a>)</span>")
// Verb: text_communicator() // Verb: text_communicator()
// Parameters: None // Parameters: None

View File

@@ -11,7 +11,7 @@ import { BoxProps, computeBoxClassName, computeBoxProps } from './Box';
interface SectionProps extends BoxProps { interface SectionProps extends BoxProps {
className?: string; className?: string;
title?: string; title?: string | InfernoElement<string>;
buttons?: InfernoNode; buttons?: InfernoNode;
fill?: boolean; fill?: boolean;
fitted?: boolean; fitted?: boolean;

View File

@@ -1,4 +1,5 @@
import { filter } from 'common/collections'; import { filter } from 'common/collections';
import { BooleanLike } from 'common/react';
import { decodeHtmlEntities, toTitleCase } from 'common/string'; import { decodeHtmlEntities, toTitleCase } from 'common/string';
import { Fragment } from 'inferno'; import { Fragment } from 'inferno';
import { useBackend, useLocalState } from '../backend'; import { useBackend, useLocalState } from '../backend';
@@ -19,8 +20,30 @@ const SETTTAB = 9;
let TabToTemplate = {}; // Populated under each template let TabToTemplate = {}; // Populated under each template
type Data = {
// GENERAL
currentTab: number;
video_comm: BooleanLike;
mapRef: string;
// FOOTER
time: string;
connectionStatus: BooleanLike;
owner: string;
occupation: string;
// HEADER
flashlight: BooleanLike;
// NOTIFICATIONS
voice_mobs: [];
communicating: [];
requestsReceived: [];
invitesSent: [];
};
export const Communicator = (props, context) => { export const Communicator = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<Data>(context);
const { currentTab, video_comm, mapRef } = data; const { currentTab, video_comm, mapRef } = data;
@@ -54,7 +77,7 @@ export const Communicator = (props, context) => {
}; };
const VideoComm = (props, context) => { const VideoComm = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<Data>(context);
const { video_comm, mapRef } = data; const { video_comm, mapRef } = data;
@@ -164,7 +187,7 @@ const VideoComm = (props, context) => {
}; };
const TemplateError = (props, context) => { const TemplateError = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<Data>(context);
const { currentTab } = data; const { currentTab } = data;
@@ -172,7 +195,7 @@ const TemplateError = (props, context) => {
}; };
const CommunicatorHeader = (props, context) => { const CommunicatorHeader = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<Data>(context);
const { time, connectionStatus, owner, occupation } = data; const { time, connectionStatus, owner, occupation } = data;
@@ -194,7 +217,7 @@ const CommunicatorHeader = (props, context) => {
}; };
const CommunicatorFooter = (props, context) => { const CommunicatorFooter = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<Data>(context);
const { flashlight } = data; const { flashlight } = data;
@@ -245,7 +268,7 @@ const CommunicatorFooter = (props, context) => {
/* Helper for notifications (yes this is a mess, but whatever, it works) */ /* Helper for notifications (yes this is a mess, but whatever, it works) */
const hasNotifications = (app, context) => { const hasNotifications = (app, context) => {
const { data } = useBackend(context); const { data } = useBackend<Data>(context);
const { const {
/* Phone Notifications */ /* Phone Notifications */
@@ -267,9 +290,13 @@ const hasNotifications = (app, context) => {
/* Tabs Below this point */ /* Tabs Below this point */
type HomeTabData = {
homeScreen: { number: number; module: string; icon: string }[];
};
/* Home tab, provides access to all other tabs. */ /* Home tab, provides access to all other tabs. */
const HomeTab = (props, context) => { const HomeTab = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<HomeTabData>(context);
const { homeScreen } = data; const { homeScreen } = data;
@@ -305,9 +332,19 @@ const HomeTab = (props, context) => {
TabToTemplate[HOMETAB] = <HomeTab />; TabToTemplate[HOMETAB] = <HomeTab />;
type PhoneTabData = {
targetAddress: string;
voice_mobs: { name: string; true_name: string; ref: string }[];
communicating: { address: string; name: string; true_name: string; ref: string }[];
requestsReceived: { address: string; name: string; ref: string }[];
invitesSent: { address: string; name: string }[];
video_comm: string;
selfie_mode: BooleanLike;
};
/* Phone tab, provides a phone interface! */ /* Phone tab, provides a phone interface! */
const PhoneTab = (props, context) => { const PhoneTab = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<PhoneTabData>(context);
const { targetAddress, voice_mobs, communicating, requestsReceived, invitesSent, video_comm, selfie_mode } = data; const { targetAddress, voice_mobs, communicating, requestsReceived, invitesSent, video_comm, selfie_mode } = data;
@@ -326,7 +363,7 @@ const PhoneTab = (props, context) => {
</LabeledList.Item> </LabeledList.Item>
</LabeledList> </LabeledList>
<NumberPad /> <NumberPad />
<Section title="Connection Management" level={2} mt={2}> <Section title="Connection Management" mt={2}>
<LabeledList> <LabeledList>
<LabeledList.Item label="Camera Mode"> <LabeledList.Item label="Camera Mode">
<Button <Button
@@ -336,7 +373,7 @@ const PhoneTab = (props, context) => {
/> />
</LabeledList.Item> </LabeledList.Item>
</LabeledList> </LabeledList>
<Section title="External Connections" level={3}> <Section title="External Connections">
{(!!voice_mobs.length && ( {(!!voice_mobs.length && (
<LabeledList> <LabeledList>
{voice_mobs.map((mob) => ( {voice_mobs.map((mob) => (
@@ -352,7 +389,7 @@ const PhoneTab = (props, context) => {
</LabeledList> </LabeledList>
)) || <Box>No connections</Box>} )) || <Box>No connections</Box>}
</Section> </Section>
<Section title="Internal Connections" level={3}> <Section title="Internal Connections">
{(!!communicating.length && ( {(!!communicating.length && (
<Table> <Table>
{communicating.map((comm) => ( {communicating.map((comm) => (
@@ -386,7 +423,7 @@ const PhoneTab = (props, context) => {
</Table> </Table>
)) || <Box>No connections</Box>} )) || <Box>No connections</Box>}
</Section> </Section>
<Section title="Requests Received" level={3}> <Section title="Requests Received">
{(!!requestsReceived.length && ( {(!!requestsReceived.length && (
<LabeledList> <LabeledList>
{requestsReceived.map((request) => ( {requestsReceived.map((request) => (
@@ -401,7 +438,7 @@ const PhoneTab = (props, context) => {
</LabeledList> </LabeledList>
)) || <Box>No requests received.</Box>} )) || <Box>No requests received.</Box>}
</Section> </Section>
<Section title="Invites Sent" level={3}> <Section title="Invites Sent">
{(!!invitesSent.length && ( {(!!invitesSent.length && (
<LabeledList> <LabeledList>
{invitesSent.map((invite) => ( {invitesSent.map((invite) => (
@@ -428,7 +465,7 @@ const PhoneTab = (props, context) => {
// Subtemplate // Subtemplate
const NumberPad = (props, context) => { const NumberPad = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<PhoneTabData>(context);
const { targetAddress } = data; const { targetAddress } = data;
@@ -438,7 +475,7 @@ const NumberPad = (props, context) => {
<Button key={char} content={char} fontSize={2} fluid onClick={() => act('add_hex', { add_hex: char })} /> <Button key={char} content={char} fontSize={2} fluid onClick={() => act('add_hex', { add_hex: char })} />
)); ));
let finalArray = []; let finalArray: any[] = [];
for (let i = 0; i < buttonArray.length; i += 4) { for (let i = 0; i < buttonArray.length; i += 4) {
finalArray.push( finalArray.push(
@@ -492,9 +529,13 @@ const NumberPad = (props, context) => {
TabToTemplate[PHONTAB] = <PhoneTab />; TabToTemplate[PHONTAB] = <PhoneTab />;
type ContactsTabData = {
knownDevices: { address: string; name: string }[];
};
/* Contacts */ /* Contacts */
const ContactsTab = (props, context) => { const ContactsTab = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<ContactsTabData>(context);
const { knownDevices } = data; const { knownDevices } = data;
@@ -552,9 +593,19 @@ const ContactsTab = (props, context) => {
TabToTemplate[CONTTAB] = <ContactsTab />; TabToTemplate[CONTTAB] = <ContactsTab />;
type MessagingTabData = {
// TAB
imContacts: { address: string; name: string }[];
// THREAD
targetAddressName: string;
targetAddress: string;
imList: { im: string }[];
};
/* Messaging */ /* Messaging */
const MessagingTab = (props, context) => { const MessagingTab = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<MessagingTabData>(context);
const { imContacts } = data; const { imContacts } = data;
@@ -605,7 +656,7 @@ const IsIMOurs = (im, targetAddress) => {
return im.address !== targetAddress; return im.address !== targetAddress;
}; };
const enforceLengthLimit = (prefix, name, length) => { const enforceLengthLimit = (prefix: string, name: string, length: number) => {
if ((prefix + name).length > length) { if ((prefix + name).length > length) {
if (name.length > length) { if (name.length > length) {
return name.slice(0, length) + '...'; return name.slice(0, length) + '...';
@@ -631,7 +682,7 @@ const findClassMessage = (im, targetAddress, lastIndex, filterArray) => {
}; };
const MessagingThreadTab = (props, context) => { const MessagingThreadTab = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<MessagingTabData>(context);
const { targetAddressName, targetAddress, imList } = data; const { targetAddressName, targetAddress, imList } = data;
@@ -722,9 +773,28 @@ const MessagingThreadTab = (props, context) => {
TabToTemplate[MESSSUBTAB] = <MessagingThreadTab />; TabToTemplate[MESSSUBTAB] = <MessagingThreadTab />;
type NewsTabData = {
feeds: { index: number; name: string }[];
target_feed: { name: string; author: string; messages: NewsMessage[] };
latest_news: NewsMessage[];
};
type NewsMessage = {
ref: string;
body: string;
img: string;
caption: string;
message_type: string;
author: string;
time_stamp: string;
index: number;
channel: string;
};
/* News */ /* News */
const NewsTab = (props, context) => { const NewsTab = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<NewsTabData>(context);
const { feeds, target_feed } = data; const { feeds, target_feed } = data;
@@ -737,14 +807,13 @@ const NewsTab = (props, context) => {
}; };
const NewsTargetFeed = (props, context) => { const NewsTargetFeed = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<NewsTabData>(context);
const { target_feed } = data; const { target_feed } = data;
return ( return (
<Section <Section
title={decodeHtmlEntities(target_feed.name) + ' by ' + decodeHtmlEntities(target_feed.author)} title={decodeHtmlEntities(target_feed.name) + ' by ' + decodeHtmlEntities(target_feed.author)}
level={2}
buttons={<Button content="Back" icon="chevron-up" onClick={() => act('newsfeed', { newsfeed: null })} />}> buttons={<Button content="Back" icon="chevron-up" onClick={() => act('newsfeed', { newsfeed: null })} />}>
{target_feed.messages.map((message) => ( {target_feed.messages.map((message) => (
<Section key={message.ref}> <Section key={message.ref}>
@@ -765,13 +834,13 @@ const NewsTargetFeed = (props, context) => {
}; };
const NewsFeed = (props, context) => { const NewsFeed = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<NewsTabData>(context);
const { feeds, latest_news } = data; const { feeds, latest_news } = data;
return ( return (
<Fragment> <Fragment>
<Section title="Recent News" level={2}> <Section title="Recent News">
<Section> <Section>
{latest_news.map((news) => ( {latest_news.map((news) => (
<Box mb={2} key={news.index}> <Box mb={2} key={news.index}>
@@ -802,7 +871,7 @@ const NewsFeed = (props, context) => {
))} ))}
</Section> </Section>
</Section> </Section>
<Section title="News Feeds" level={2}> <Section title="News Feeds">
{feeds.map((feed) => ( {feeds.map((feed) => (
<Button <Button
key={feed.index} key={feed.index}
@@ -819,9 +888,13 @@ const NewsFeed = (props, context) => {
TabToTemplate[NEWSTAB] = <NewsTab />; TabToTemplate[NEWSTAB] = <NewsTab />;
type NoteTabData = {
note: string;
};
/* Note Keeper */ /* Note Keeper */
const NoteTab = (props, context) => { const NoteTab = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<NoteTabData>(context);
const { note } = data; const { note } = data;
@@ -861,17 +934,45 @@ const getItemColor = (value, min2, min1, max1, max2) => {
return 'good'; return 'good';
}; };
type WeatherTabData = {
aircontents: AirContent[];
weather: Weather[];
};
type AirContent = {
entry: string;
val;
bad_low: number;
poor_low: number;
poor_high: number;
bad_high: number;
units;
};
type Weather = {
Planet: string;
Time: string;
Weather: string;
Temperature;
High;
Low;
WindDir;
WindSpeed;
Forecast: string;
};
const WeatherTab = (props, context) => { const WeatherTab = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<WeatherTabData>(context);
const { aircontents, weather } = data; const { aircontents, weather } = data;
return ( return (
<Section title="Weather"> <Section title="Weather">
<Section level={2} title="Current Conditions"> <Section title="Current Conditions">
<LabeledList> <LabeledList>
{filter((i) => i.val !== '0' || i.entry === 'Pressure' || i.entry === 'Temperature')(aircontents).map( {filter((i: AirContent) => i.val !== '0' || i.entry === 'Pressure' || i.entry === 'Temperature')(
(item) => ( aircontents
).map((item: AirContent) => (
<LabeledList.Item <LabeledList.Item
key={item.entry} key={item.entry}
label={item.entry} label={item.entry}
@@ -879,11 +980,10 @@ const WeatherTab = (props, context) => {
{item.val} {item.val}
{decodeHtmlEntities(item.units)} {decodeHtmlEntities(item.units)}
</LabeledList.Item> </LabeledList.Item>
) ))}
)}
</LabeledList> </LabeledList>
</Section> </Section>
<Section level={2} title="Weather Reports"> <Section title="Weather Reports">
{(!!weather.length && ( {(!!weather.length && (
<LabeledList> <LabeledList>
{weather.map((wr) => ( {weather.map((wr) => (
@@ -914,9 +1014,19 @@ TabToTemplate[WTHRTAB] = <WeatherTab />;
// Lol just steal it from the existing template // Lol just steal it from the existing template
TabToTemplate[MANITAB] = <CrewManifestContent />; TabToTemplate[MANITAB] = <CrewManifestContent />;
type SettingsTabData = {
owner: string;
occupation: string;
connectionStatus: BooleanLike;
address: string;
visible: BooleanLike;
ring: BooleanLike;
selfie_mode: BooleanLike;
};
/* Settings */ /* Settings */
const SettingsTab = (props, context) => { const SettingsTab = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<SettingsTabData>(context);
const { owner, occupation, connectionStatus, address, visible, ring, selfie_mode } = data; const { owner, occupation, connectionStatus, address, visible, ring, selfie_mode } = data;

View File

@@ -17,7 +17,7 @@ data["manifest"] = PDA_Manifest
* ``` * ```
*/ */
export const CrewManifest = (props, context) => { export const CrewManifest = () => {
return ( return (
<Window width={400} height={600}> <Window width={400} height={600}>
<Window.Content scrollable> <Window.Content scrollable>
@@ -27,8 +27,12 @@ export const CrewManifest = (props, context) => {
); );
}; };
type Data = {
manifest: { elems: { name: string; rank: string; active: string }[]; cat: string }[];
};
export const CrewManifestContent = (props, context) => { export const CrewManifestContent = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend<Data>(context);
const { manifest } = data; const { manifest } = data;
@@ -45,8 +49,7 @@ export const CrewManifestContent = (props, context) => {
</Box> </Box>
</Box> </Box>
} }
key={cat.cat} key={cat.cat}>
level={2}>
<Table> <Table>
<Table.Row header color="white"> <Table.Row header color="white">
<Table.Cell>Name</Table.Cell> <Table.Cell>Name</Table.Cell>

View File

@@ -6,9 +6,7 @@ import { Window } from '../layouts';
import { decodeHtmlEntities } from 'common/string'; import { decodeHtmlEntities } from 'common/string';
import { CrewManifestContent } from './CrewManifest'; import { CrewManifestContent } from './CrewManifest';
export const IdentificationComputer = (props, context) => { export const IdentificationComputer = () => {
const { act, data } = useBackend(context);
return ( return (
<Window width={600} height={700}> <Window width={600} height={700}>
<Window.Content resizable> <Window.Content resizable>

File diff suppressed because one or more lines are too long