mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-08-23 05:07:51 +01:00
Communicator Reply Messages
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
+151
-41
@@ -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;
|
||||
|
||||
+7
-4
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user