mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-17 18:14:25 +01:00
Fixed CharacterDirectory (#15757)
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
* public
|
||||
*
|
||||
* Static Data to be sent to the UI.
|
||||
*
|
||||
* Static data differs from normal data in that it's large data that should be
|
||||
* sent infrequently. This is implemented optionally for heavy uis that would
|
||||
* be sending a lot of redundant data frequently. Gets squished into one
|
||||
@@ -65,6 +66,17 @@
|
||||
if(ui)
|
||||
ui.send_full_update()
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Will force an update on static data for all viewers.
|
||||
* Should be done manually whenever something happens to
|
||||
* change static data.
|
||||
*/
|
||||
/datum/proc/update_static_data_for_all_viewers()
|
||||
for (var/datum/tgui/window as anything in open_uis)
|
||||
window.send_full_update()
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
@@ -130,7 +142,6 @@
|
||||
* Associative list of JSON-encoded shared states that were set by
|
||||
* tgui clients.
|
||||
*/
|
||||
|
||||
/datum/var/list/tgui_shared_states
|
||||
|
||||
/**
|
||||
@@ -194,8 +205,7 @@
|
||||
// Name the verb, and hide it from the user panel.
|
||||
set name = "uiclose"
|
||||
set hidden = TRUE
|
||||
|
||||
var/mob/user = src && src.mob
|
||||
var/mob/user = src?.mob
|
||||
if(!user)
|
||||
return
|
||||
// Close all tgui datums based on window_id.
|
||||
|
||||
+21
-12
@@ -11,7 +11,7 @@
|
||||
var/mob/user
|
||||
/// The object which owns the UI.
|
||||
var/datum/src_object
|
||||
/// The title of te UI.
|
||||
/// The title of the UI.
|
||||
var/title
|
||||
/// The window_id for browse() and onclose().
|
||||
var/datum/tgui_window/window
|
||||
@@ -76,22 +76,29 @@
|
||||
if(ui_x && ui_y)
|
||||
src.window_size = list(ui_x, ui_y)
|
||||
|
||||
/datum/tgui/Destroy()
|
||||
user = null
|
||||
src_object = null
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Open this UI (and initialize it with data).
|
||||
*
|
||||
* return bool - TRUE if a new pooled window is opened, FALSE in all other situations including if a new pooled window didn't open because one already exists.
|
||||
*/
|
||||
/datum/tgui/proc/open()
|
||||
if(!user.client)
|
||||
return null
|
||||
return FALSE
|
||||
if(window)
|
||||
return null
|
||||
return FALSE
|
||||
process_status()
|
||||
if(status < STATUS_UPDATE)
|
||||
return null
|
||||
return FALSE
|
||||
window = SStgui.request_pooled_window(user)
|
||||
if(!window)
|
||||
return null
|
||||
return FALSE
|
||||
opened_at = world.time
|
||||
window.acquire_lock(src)
|
||||
if(!window.is_ready())
|
||||
@@ -114,10 +121,14 @@
|
||||
window.set_mouse_macro()
|
||||
SStgui.on_open(src)
|
||||
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Close the UI, and all its children.
|
||||
* Close the UI.
|
||||
*
|
||||
* optional can_be_suspended bool
|
||||
*/
|
||||
/datum/tgui/proc/close(can_be_suspended = TRUE, logout = FALSE)
|
||||
if(closing)
|
||||
@@ -146,7 +157,7 @@
|
||||
*
|
||||
* Enable/disable auto-updating of the UI.
|
||||
*
|
||||
* required autoupdate bool Enable/disable auto-updating.
|
||||
* required value bool Enable/disable auto-updating.
|
||||
*/
|
||||
/datum/tgui/proc/set_autoupdate(autoupdate)
|
||||
src.autoupdate = autoupdate
|
||||
@@ -178,6 +189,8 @@
|
||||
* Makes an asset available to use in tgui.
|
||||
*
|
||||
* required asset datum/asset
|
||||
*
|
||||
* return bool - true if an asset was actually sent
|
||||
*/
|
||||
/datum/tgui/proc/send_asset(datum/asset/asset)
|
||||
if(!window)
|
||||
@@ -282,14 +295,12 @@
|
||||
return
|
||||
// Validate ping
|
||||
if(!initialized && world.time - opened_at > TGUI_PING_TIMEOUT)
|
||||
// #ifdef TGUI_DEBUGGING // Always log zombie windows
|
||||
log_tgui(user, \
|
||||
"Error: Zombie window detected, killing it with fire.\n" \
|
||||
+ "window_id: [window.id]\n" \
|
||||
+ "opened_at: [opened_at]\n" \
|
||||
+ "world.time: [world.time]")
|
||||
close(can_be_suspended = FALSE)
|
||||
// #endif
|
||||
return
|
||||
// Update through a normal call to ui_interact
|
||||
if(status != STATUS_DISABLED && (autoupdate || force))
|
||||
@@ -321,9 +332,7 @@
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Handle clicks from the UI.
|
||||
* Call the src_object's ui_act() if status is UI_INTERACTIVE.
|
||||
* If the src_object's ui_act() returns 1, update all UIs attacked to it.
|
||||
* Callback for handling incoming tgui messages.
|
||||
*/
|
||||
/datum/tgui/proc/on_message(type, list/payload, list/href_list)
|
||||
// Pass act type messages to tgui_act
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*!
|
||||
* Copyright (c) 2020 Aleksej Komarov
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
@@ -26,6 +26,18 @@
|
||||
var/initial_inline_css
|
||||
var/mouse_event_macro_set = FALSE
|
||||
|
||||
/**
|
||||
* Static list used to map in macros that will then emit execute events to the tgui window
|
||||
* A small disclaimer though I'm no tech wiz: I don't think it's possible to map in right or middle
|
||||
* clicks in the current state, as they're keywords rather than modifiers.
|
||||
*/
|
||||
var/static/list/byondToTguiEventMap = list(
|
||||
"MouseDown" = "byond/mousedown",
|
||||
"MouseUp" = "byond/mouseup",
|
||||
"Ctrl" = "byond/ctrldown",
|
||||
"Ctrl+UP" = "byond/ctrlup",
|
||||
)
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
@@ -165,8 +177,8 @@
|
||||
* Acquire the window lock. Pool will not be able to provide this window
|
||||
* to other UIs for the duration of the lock.
|
||||
*
|
||||
* Can be given an optional tgui datum, which will hook its on_message
|
||||
* callback into the message stream.
|
||||
* Can be given an optional tgui datum, which will be automatically
|
||||
* subscribed to incoming messages via the on_message proc.
|
||||
*
|
||||
* optional ui /datum/tgui
|
||||
*/
|
||||
@@ -175,6 +187,8 @@
|
||||
locked_by = ui
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Release the window lock.
|
||||
*/
|
||||
/datum/tgui_window/proc/release_lock()
|
||||
@@ -391,11 +405,6 @@
|
||||
if(mouse_event_macro_set)
|
||||
return
|
||||
|
||||
var/list/byondToTguiEventMap = list(
|
||||
"MouseDown" = "byond/mousedown",
|
||||
"MouseUp" = "byond/mouseup"
|
||||
)
|
||||
|
||||
for(var/mouseMacro in byondToTguiEventMap)
|
||||
var/command_template = ".output CONTROL PAYLOAD"
|
||||
var/event_message = TGUI_CREATE_MESSAGE(byondToTguiEventMap[mouseMacro], null)
|
||||
@@ -416,10 +425,6 @@
|
||||
/datum/tgui_window/proc/remove_mouse_macro()
|
||||
if(!mouse_event_macro_set)
|
||||
stack_trace("Unsetting mouse macro on tgui window that has none")
|
||||
var/list/byondToTguiEventMap = list(
|
||||
"MouseDown" = "byond/mousedown",
|
||||
"MouseUp" = "byond/mouseup"
|
||||
)
|
||||
for(var/mouseMacro in byondToTguiEventMap)
|
||||
winset(client, null, "[mouseMacro]Window[id]Macro.parent=null")
|
||||
mouse_event_macro_set = FALSE
|
||||
|
||||
@@ -25,17 +25,21 @@ const getTagColor = (tag) => {
|
||||
|
||||
export const CharacterDirectory = (props) => {
|
||||
const { act, data } = useBackend();
|
||||
|
||||
const { personalVisibility, personalTag, personalErpTag } = data;
|
||||
|
||||
const [overlay, setOverlay] = useState(null);
|
||||
|
||||
const [overwritePrefs, setOverwritePrefs] = useState(false);
|
||||
|
||||
function handleOverlay(value) {
|
||||
setOverlay(value);
|
||||
}
|
||||
|
||||
return (
|
||||
<Window width={640} height={480} resizeable>
|
||||
<Window.Content scrollable>
|
||||
{(overlay && <ViewCharacter />) || (
|
||||
{(overlay && (
|
||||
<ViewCharacter overlay={overlay} onOverlay={handleOverlay} />
|
||||
)) || (
|
||||
<>
|
||||
<Section
|
||||
title="Controls"
|
||||
@@ -92,7 +96,7 @@ export const CharacterDirectory = (props) => {
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
<CharacterDirectoryList />
|
||||
<CharacterDirectoryList onOverlay={handleOverlay} />
|
||||
</>
|
||||
)}
|
||||
</Window.Content>
|
||||
@@ -101,43 +105,41 @@ export const CharacterDirectory = (props) => {
|
||||
};
|
||||
|
||||
const ViewCharacter = (props) => {
|
||||
const [overlay, setOverlay] = useState(null);
|
||||
|
||||
return (
|
||||
<Section
|
||||
title={overlay.name}
|
||||
title={props.overlay.name}
|
||||
buttons={
|
||||
<Button
|
||||
icon="arrow-left"
|
||||
content="Back"
|
||||
onClick={() => setOverlay(null)}
|
||||
onClick={() => props.onOverlay(null)}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Section level={2} title="Species">
|
||||
<Box>{overlay.species}</Box>
|
||||
<Box>{props.overlay.species}</Box>
|
||||
</Section>
|
||||
<Section level={2} title="Vore Tag">
|
||||
<Box p={1} backgroundColor={getTagColor(overlay.tag)}>
|
||||
{overlay.tag}
|
||||
<Box p={1} backgroundColor={getTagColor(props.overlay.tag)}>
|
||||
{props.overlay.tag}
|
||||
</Box>
|
||||
</Section>
|
||||
<Section level={2} title="ERP Tag">
|
||||
<Box>{overlay.erptag}</Box>
|
||||
<Box>{props.overlay.erptag}</Box>
|
||||
</Section>
|
||||
<Section level={2} title="Character Ad">
|
||||
<Box style={{ 'word-break': 'break-all' }} preserveWhitespace>
|
||||
{overlay.character_ad || 'Unset.'}
|
||||
{props.overlay.character_ad || 'Unset.'}
|
||||
</Box>
|
||||
</Section>
|
||||
<Section level={2} title="OOC Notes">
|
||||
<Box style={{ 'word-break': 'break-all' }} preserveWhitespace>
|
||||
{overlay.ooc_notes || 'Unset.'}
|
||||
{props.overlay.ooc_notes || 'Unset.'}
|
||||
</Box>
|
||||
</Section>
|
||||
<Section level={2} title="Flavor Text">
|
||||
<Box style={{ 'word-break': 'break-all' }} preserveWhitespace>
|
||||
{overlay.flavor_text || 'Unset.'}
|
||||
{props.overlay.flavor_text || 'Unset.'}
|
||||
</Box>
|
||||
</Section>
|
||||
</Section>
|
||||
@@ -151,7 +153,6 @@ const CharacterDirectoryList = (props) => {
|
||||
|
||||
const [sortId, _setSortId] = useState('name');
|
||||
const [sortOrder, _setSortOrder] = useState('name');
|
||||
const [overlay, setOverlay] = useState(null);
|
||||
|
||||
return (
|
||||
<Section
|
||||
@@ -183,7 +184,7 @@ const CharacterDirectoryList = (props) => {
|
||||
<Table.Cell>{character.erptag}</Table.Cell>
|
||||
<Table.Cell collapsing textAlign="right">
|
||||
<Button
|
||||
onClick={() => setOverlay(character)}
|
||||
onClick={() => props.onOverlay(character)}
|
||||
color="transparent"
|
||||
icon="sticky-note"
|
||||
mr={1}
|
||||
|
||||
@@ -48,7 +48,8 @@ const defTag = [
|
||||
// Advanced HTML tags that we can trust admins (but not players) with
|
||||
const advTag = ['img'];
|
||||
|
||||
const defAttr = ['class', 'style'];
|
||||
// Background is here because it accepts image urls
|
||||
const defAttr = ['class', 'style', 'background'];
|
||||
|
||||
/**
|
||||
* Feed it a string and it should spit out a sanitized version.
|
||||
|
||||
+131
-131
File diff suppressed because one or more lines are too long
+43
-43
File diff suppressed because one or more lines are too long
@@ -516,9 +516,6 @@ window.replaceHtml = function (inline_html) {
|
||||
+ "<!-- tgui:inline-html-end -->"
|
||||
);
|
||||
};
|
||||
|
||||
// Signal tgui that we're ready to receive updates
|
||||
Byond.sendMessage('ready');
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@@ -662,5 +659,10 @@ Thank you for your cooperation.
|
||||
<div>Please enable Javascript and restart the game.</div>
|
||||
</div>
|
||||
</noscript>
|
||||
|
||||
<script>
|
||||
// Signal tgui that we're ready to receive updates
|
||||
Byond.sendMessage('ready');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user