mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 18:53:06 +00:00
[MIRROR] tgui say update (#10323)
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
a4493ca5ff
commit
ab171de574
@@ -11,3 +11,5 @@
|
|||||||
|
|
||||||
/// Simply removes the < and > characters, and limits the length of the message.
|
/// Simply removes the < and > characters, and limits the length of the message.
|
||||||
#define STRIP_HTML_SIMPLE(text, limit) (GLOB.angular_brackets.Replace(copytext(text, 1, limit), ""))
|
#define STRIP_HTML_SIMPLE(text, limit) (GLOB.angular_brackets.Replace(copytext(text, 1, limit), ""))
|
||||||
|
|
||||||
|
#define MAX_MESSAGE_CHUNKS 130
|
||||||
|
|||||||
@@ -45,6 +45,8 @@
|
|||||||
var/datum/tgui/parent_ui
|
var/datum/tgui/parent_ui
|
||||||
/// Children of this UI
|
/// Children of this UI
|
||||||
var/list/children = list()
|
var/list/children = list()
|
||||||
|
/// Any partial packets that we have received from TGUI, waiting to be sent
|
||||||
|
var/partial_packets
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* public
|
* public
|
||||||
@@ -349,6 +351,28 @@
|
|||||||
// Pass act type messages to tgui_act
|
// Pass act type messages to tgui_act
|
||||||
if(type && copytext(type, 1, 5) == "act/")
|
if(type && copytext(type, 1, 5) == "act/")
|
||||||
var/act_type = copytext(type, 5)
|
var/act_type = copytext(type, 5)
|
||||||
|
var/id = href_list["packetId"]
|
||||||
|
if(!isnull(id))
|
||||||
|
id = text2num(id)
|
||||||
|
|
||||||
|
var/total = text2num(href_list["totalPackets"])
|
||||||
|
if(id == 1)
|
||||||
|
if(total > MAX_MESSAGE_CHUNKS)
|
||||||
|
return
|
||||||
|
|
||||||
|
partial_packets = new /list(total)
|
||||||
|
|
||||||
|
partial_packets[id] = href_list["packet"]
|
||||||
|
|
||||||
|
if(id != total)
|
||||||
|
return
|
||||||
|
|
||||||
|
var/assembled_payload = ""
|
||||||
|
for(var/packet in partial_packets)
|
||||||
|
assembled_payload += packet
|
||||||
|
|
||||||
|
payload = json_decode(assembled_payload)
|
||||||
|
partial_packets = null
|
||||||
#ifdef TGUI_DEBUGGING
|
#ifdef TGUI_DEBUGGING
|
||||||
log_tgui(user, "Action: [act_type] [href_list["payload"]], Window: [window.id], Source: [src_object]")
|
log_tgui(user, "Action: [act_type] [href_list["payload"]], Window: [window.id], Source: [src_object]")
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -31,6 +31,8 @@
|
|||||||
var/datum/tgui_window/window
|
var/datum/tgui_window/window
|
||||||
/// Boolean for whether the tgui_say was opened by the user.
|
/// Boolean for whether the tgui_say was opened by the user.
|
||||||
var/window_open
|
var/window_open
|
||||||
|
/// Any partial packets that we have received from TGUI, waiting to be sent
|
||||||
|
var/partial_packets
|
||||||
|
|
||||||
/** Creates the new input window to exist in the background. */
|
/** Creates the new input window to exist in the background. */
|
||||||
/datum/tgui_say/New(client/client, id)
|
/datum/tgui_say/New(client/client, id)
|
||||||
@@ -64,14 +66,14 @@
|
|||||||
/datum/tgui_say/proc/load()
|
/datum/tgui_say/proc/load()
|
||||||
window_open = FALSE
|
window_open = FALSE
|
||||||
|
|
||||||
var/minimum_height = client?.prefs?.read_preference(/datum/preference/numeric/tgui_say_height) || 1
|
var/minimum_width = client?.prefs?.read_preference(/datum/preference/numeric/tgui_say_width) || 1
|
||||||
var/minimu_width = client?.prefs?.read_preference(/datum/preference/numeric/tgui_say_width) || 1
|
var/minimum_height = (client?.prefs?.read_preference(/datum/preference/numeric/tgui_say_height) || 1) * 20 + 10
|
||||||
winset(client, "tgui_say", "pos=410,400;size=360,30;is-visible=0;")
|
winset(client, "tgui_say", "pos=410,400;size=360,30;is-visible=0;")
|
||||||
|
|
||||||
window.send_message("props", list(
|
window.send_message("props", list(
|
||||||
lightMode = client?.prefs?.read_preference(/datum/preference/toggle/tgui_say_light),
|
lightMode = client?.prefs?.read_preference(/datum/preference/toggle/tgui_say_light),
|
||||||
|
minimumWidth = minimum_width,
|
||||||
minimumHeight = minimum_height,
|
minimumHeight = minimum_height,
|
||||||
minimumWidth = minimu_width,
|
|
||||||
maxLength = max_length,
|
maxLength = max_length,
|
||||||
))
|
))
|
||||||
|
|
||||||
@@ -106,7 +108,7 @@
|
|||||||
* The equivalent of ui_act, this waits on messages from the window
|
* The equivalent of ui_act, this waits on messages from the window
|
||||||
* and delegates actions.
|
* and delegates actions.
|
||||||
*/
|
*/
|
||||||
/datum/tgui_say/proc/on_message(type, payload)
|
/datum/tgui_say/proc/on_message(type, payload, href_list)
|
||||||
if(type == "ready")
|
if(type == "ready")
|
||||||
load()
|
load()
|
||||||
return TRUE
|
return TRUE
|
||||||
@@ -128,6 +130,28 @@
|
|||||||
start_typing(payload["channel"])
|
start_typing(payload["channel"])
|
||||||
return TRUE
|
return TRUE
|
||||||
if(type == "entry" || type == "force")
|
if(type == "entry" || type == "force")
|
||||||
|
var/id = href_list["packetId"]
|
||||||
|
if(!isnull(id))
|
||||||
|
id = text2num(id)
|
||||||
|
|
||||||
|
var/total = text2num(href_list["totalPackets"])
|
||||||
|
if(id == 1)
|
||||||
|
if(total > MAX_MESSAGE_CHUNKS)
|
||||||
|
return
|
||||||
|
|
||||||
|
partial_packets = new /list(total)
|
||||||
|
|
||||||
|
partial_packets[id] = href_list["packet"]
|
||||||
|
|
||||||
|
if(id != total)
|
||||||
|
return
|
||||||
|
|
||||||
|
var/assembled_payload = ""
|
||||||
|
for(var/packet in partial_packets)
|
||||||
|
assembled_payload += packet
|
||||||
|
|
||||||
|
payload = json_decode(assembled_payload)
|
||||||
|
partial_packets = null
|
||||||
handle_entry(type, payload)
|
handle_entry(type, payload)
|
||||||
return TRUE
|
return TRUE
|
||||||
if(type == "lenwarn")
|
if(type == "lenwarn")
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
* * encode - Toggling this determines if input is filtered via html_encode. Setting this to FALSE gives raw input.
|
* * encode - Toggling this determines if input is filtered via html_encode. Setting this to FALSE gives raw input.
|
||||||
* * timeout - The timeout of the textbox, after which the modal will close and qdel itself. Set to zero for no timeout.
|
* * timeout - The timeout of the textbox, after which the modal will close and qdel itself. Set to zero for no timeout.
|
||||||
*/
|
*/
|
||||||
/proc/tgui_input_text(mob/user, message = "", title = "Text Input", default, max_length = INFINITY, multiline = FALSE, encode = FALSE, timeout = 0, prevent_enter = FALSE)
|
/proc/tgui_input_text(mob/user, message = "", title = "Text Input", default, max_length = 130000, multiline = FALSE, encode = FALSE, timeout = 0, prevent_enter = FALSE) // 130k limit due to chunking limit... if we need longer that needs fixing
|
||||||
if (!user)
|
if (!user)
|
||||||
user = usr
|
user = usr
|
||||||
if (!istype(user))
|
if (!istype(user))
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ $border-color: rgba(140, 140, 140, 0.5) !default;
|
|||||||
border-radius: 0.25em;
|
border-radius: 0.25em;
|
||||||
width: 3.75em;
|
width: 3.75em;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
user-select: 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
.Ping__indicator {
|
.Ping__indicator {
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import { byondMessages } from './timers';
|
|||||||
|
|
||||||
type ByondOpen = {
|
type ByondOpen = {
|
||||||
channel: Channel;
|
channel: Channel;
|
||||||
|
minimumWidth: number;
|
||||||
|
minimumHeight: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ByondProps = {
|
type ByondProps = {
|
||||||
@@ -287,8 +289,8 @@ export function TguiSay() {
|
|||||||
function handleOpen(data: ByondOpen): void {
|
function handleOpen(data: ByondOpen): void {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
innerRef.current?.focus();
|
innerRef.current?.focus();
|
||||||
windowSet(WindowSize.Width, WindowSize.Small);
|
setSize(minimumHeight);
|
||||||
setSize(WindowSize.Width);
|
windowSet(minimumWidth, minimumHeight);
|
||||||
}, 1);
|
}, 1);
|
||||||
|
|
||||||
const { channel } = data;
|
const { channel } = data;
|
||||||
@@ -339,7 +341,7 @@ export function TguiSay() {
|
|||||||
} else {
|
} else {
|
||||||
newSize = WindowSize.Small;
|
newSize = WindowSize.Small;
|
||||||
}
|
}
|
||||||
newSize = clamp(newSize, minimumHeight * 20 + 10, WindowSize.Max);
|
newSize = clamp(newSize, minimumHeight, WindowSize.Max);
|
||||||
|
|
||||||
if (size !== newSize) {
|
if (size !== newSize) {
|
||||||
setSize(newSize);
|
setSize(newSize);
|
||||||
@@ -370,16 +372,24 @@ export function TguiSay() {
|
|||||||
{buttonContent}
|
{buttonContent}
|
||||||
</button>
|
</button>
|
||||||
<textarea
|
<textarea
|
||||||
|
spellCheck
|
||||||
autoCorrect="off"
|
autoCorrect="off"
|
||||||
className={`textarea textarea-${theme}`}
|
className={`textarea textarea-${theme}`}
|
||||||
maxLength={maxLength}
|
maxLength={maxLength}
|
||||||
onInput={handleInput}
|
onInput={handleInput}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
ref={innerRef}
|
ref={innerRef}
|
||||||
spellCheck={false}
|
|
||||||
rows={ROWS[size] || 1}
|
rows={ROWS[size] || 1}
|
||||||
value={value}
|
value={value}
|
||||||
/>
|
/>
|
||||||
|
<button
|
||||||
|
key="escape"
|
||||||
|
className={`button button-${theme}`}
|
||||||
|
onClick={handleClose}
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
X
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -118,7 +118,7 @@
|
|||||||
background-color: black;
|
background-color: black;
|
||||||
display: grid;
|
display: grid;
|
||||||
font: 'tgfont';
|
font: 'tgfont';
|
||||||
grid-template-columns: 3.5rem 1fr;
|
grid-template-columns: 7rem 1fr 2rem;
|
||||||
inset: 2px;
|
inset: 2px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ export const COLORS = {
|
|||||||
science: '#9b59b6',
|
science: '#9b59b6',
|
||||||
engineering: '#f1c40f',
|
engineering: '#f1c40f',
|
||||||
cargo: '#f39c12',
|
cargo: '#f39c12',
|
||||||
|
service: '#7cc46a',
|
||||||
centcom: '#00c100',
|
centcom: '#00c100',
|
||||||
other: '#c38312',
|
other: '#c38312',
|
||||||
},
|
},
|
||||||
@@ -66,24 +67,28 @@ export const COLORS = {
|
|||||||
|
|
||||||
// Colors defined in CSS
|
// Colors defined in CSS
|
||||||
export const CSS_COLORS = [
|
export const CSS_COLORS = [
|
||||||
'black',
|
|
||||||
'white',
|
|
||||||
'red',
|
|
||||||
'orange',
|
|
||||||
'yellow',
|
|
||||||
'olive',
|
|
||||||
'green',
|
|
||||||
'teal',
|
|
||||||
'blue',
|
|
||||||
'violet',
|
|
||||||
'purple',
|
|
||||||
'pink',
|
|
||||||
'brown',
|
|
||||||
'grey',
|
|
||||||
'good',
|
|
||||||
'average',
|
'average',
|
||||||
'bad',
|
'bad',
|
||||||
|
'black',
|
||||||
|
'blue',
|
||||||
|
'brown',
|
||||||
|
'darkgray',
|
||||||
|
'darkgreen',
|
||||||
|
'maroon',
|
||||||
|
'good',
|
||||||
|
'green',
|
||||||
|
'grey',
|
||||||
'label',
|
'label',
|
||||||
|
'olive',
|
||||||
|
'orange',
|
||||||
|
'pink',
|
||||||
|
'purple',
|
||||||
|
'red',
|
||||||
|
'teal',
|
||||||
|
'transparent',
|
||||||
|
'violet',
|
||||||
|
'white',
|
||||||
|
'yellow',
|
||||||
];
|
];
|
||||||
|
|
||||||
// VOREStation Edit Start
|
// VOREStation Edit Start
|
||||||
|
|||||||
@@ -591,10 +591,10 @@ const rank2color = {
|
|||||||
'Off-duty Explorer': 'white',
|
'Off-duty Explorer': 'white',
|
||||||
'Off-duty Worker': 'white',
|
'Off-duty Worker': 'white',
|
||||||
// AI / Robot
|
// AI / Robot
|
||||||
AI: 'darkgrey',
|
AI: 'maroon',
|
||||||
Cyborg: 'darkgrey',
|
Cyborg: 'maroon',
|
||||||
Robot: 'darkgrey',
|
Robot: 'maroon',
|
||||||
Drone: 'darkgrey',
|
Drone: 'maroon',
|
||||||
// Clown / Mime
|
// Clown / Mime
|
||||||
Clown: 'green',
|
Clown: 'green',
|
||||||
Jester: 'green',
|
Jester: 'green',
|
||||||
@@ -627,11 +627,11 @@ const rank2color = {
|
|||||||
Security: 'red',
|
Security: 'red',
|
||||||
Combat: 'yellow',
|
Combat: 'yellow',
|
||||||
Engineering: 'orange',
|
Engineering: 'orange',
|
||||||
Gravekeeper: 'dark-grey',
|
Gravekeeper: 'maroon',
|
||||||
Lost: 'grey',
|
Lost: 'grey',
|
||||||
Protector: 'darkred',
|
Protector: 'maroon',
|
||||||
Mechanist: 'darkred',
|
Mechanist: 'maroon',
|
||||||
'Combat Medic': 'darkred',
|
'Combat Medic': 'maroon',
|
||||||
};
|
};
|
||||||
|
|
||||||
type rank_icon = { rank: string; color: string };
|
type rank_icon = { rank: string; color: string };
|
||||||
|
|||||||
@@ -204,7 +204,25 @@
|
|||||||
// JSON-encode the payload
|
// JSON-encode the payload
|
||||||
if (message.payload !== null && message.payload !== undefined) {
|
if (message.payload !== null && message.payload !== undefined) {
|
||||||
message.payload = JSON.stringify(message.payload);
|
message.payload = JSON.stringify(message.payload);
|
||||||
|
|
||||||
|
if(!Byond.TRIDENT && message.payload.length > 1024) {
|
||||||
|
var chunks = [];
|
||||||
|
|
||||||
|
for(var i = 0, charsLength = message.payload.length; i < charsLength; i += 1024) {
|
||||||
|
chunks.push(message.payload.substring(i, i + 1024))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(var i = 0; i < chunks.length; i++) {
|
||||||
|
var to_send = chunks[i]
|
||||||
|
|
||||||
|
message = { type: type, packet: to_send, packetId: i + 1, totalPackets: chunks.length, tgui: 1, window_id: Byond.windowId };
|
||||||
|
Byond.topic(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Append an identifying header
|
// Append an identifying header
|
||||||
assign(message, {
|
assign(message, {
|
||||||
tgui: 1,
|
tgui: 1,
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ export const IconCutterTarget = new Juke.Target({
|
|||||||
'icons/**/*.png',
|
'icons/**/*.png',
|
||||||
`icons/**/*${CUTTER_SUFFIX}`,
|
`icons/**/*${CUTTER_SUFFIX}`,
|
||||||
`cutter_templates/**/*${CUTTER_SUFFIX}`,
|
`cutter_templates/**/*${CUTTER_SUFFIX}`,
|
||||||
|
`tgui/public/tgui.html`,
|
||||||
cutter_path,
|
cutter_path,
|
||||||
],
|
],
|
||||||
outputs: ({ get }) => {
|
outputs: ({ get }) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user