Communicator Reply Messages

This commit is contained in:
Casey
2022-07-03 12:14:33 -04:00
committed by Darlantan
parent 2f8873dff9
commit d1863ff7ab
6 changed files with 164 additions and 51 deletions

View File

@@ -85,7 +85,7 @@
cam_screen.vis_contents = visible_turfs
cam_background.icon_state = "clear"
cam_background.fill_rect(1, 1, (video_range * 2), (video_range * 2))
local_skybox.cut_overlays()
local_skybox.add_overlay(SSskybox.get_skybox(get_z(last_camera_turf)))
local_skybox.scale_to_view(video_range * 2)
@@ -381,6 +381,8 @@
exonet.send_message(their_address, "text", 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)
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)
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)

View File

@@ -108,7 +108,7 @@
exonet.send_message(comm.exonet.address, "text", 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)
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()
// Parameters: None

View File

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

View File

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

View File

@@ -17,7 +17,7 @@ data["manifest"] = PDA_Manifest
* ```
*/
export const CrewManifest = (props, context) => {
export const CrewManifest = () => {
return (
<Window width={400} height={600}>
<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) => {
const { act, data } = useBackend(context);
const { act, data } = useBackend<Data>(context);
const { manifest } = data;
@@ -45,8 +49,7 @@ export const CrewManifestContent = (props, context) => {
</Box>
</Box>
}
key={cat.cat}
level={2}>
key={cat.cat}>
<Table>
<Table.Row header color="white">
<Table.Cell>Name</Table.Cell>

View File

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