From c942de8bbf76d59a99794b2462f3e258cccca1e6 Mon Sep 17 00:00:00 2001 From: Mark Suckerberg Date: Thu, 22 Feb 2024 04:47:43 -0600 Subject: [PATCH] Small interview QoL improvements (#2743) ## About The Pull Request Ports tgstation/tgstation#59621 which allows us to embed links in interview questions. Also fixes an annoying config verification error that didn't mean anything. ## Why It's Good For The Game Allows us to link rules and lore in interviews, so people are asked to read them. ## Changelog :cl: bobbahbrown, Mark Suckerberg admin: Links can now be embedded in interview questions to get players to read them. /:cl: --------- Co-authored-by: Bobbahbrown --- .../controllers/configuration/config_entry.dm | 1 + code/modules/interview/interview.dm | 10 ++++++-- code/modules/interview/interview_manager.dm | 2 +- config/interviews.txt | 5 +++- tgui/packages/tgui/interfaces/Interview.js | 25 ++++++++++++++++--- 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm index 8a25babbb010..82a8a31ba86b 100644 --- a/code/controllers/configuration/config_entry.dm +++ b/code/controllers/configuration/config_entry.dm @@ -130,6 +130,7 @@ str_val = trim(str_val) if (str_val != "") config_entry_value += str_val + return TRUE /datum/config_entry/number_list abstract_type = /datum/config_entry/number_list diff --git a/code/modules/interview/interview.dm b/code/modules/interview/interview.dm index c1ed4dcd87ec..27b2c83321f7 100644 --- a/code/modules/interview/interview.dm +++ b/code/modules/interview/interview.dm @@ -60,7 +60,7 @@ GLOB.interviews.approved_ckeys |= owner_ckey GLOB.interviews.close_interview(src) log_admin_private("[key_name(approved_by)] has approved interview #[id] for [owner_ckey][!owner ? "(DC)": ""].") - message_admins("[key_name(approved_by)] has approved interview #[id] for [owner_ckey][!owner ? "(DC)": ""].") + message_admins("[key_name(approved_by)] has approved [link_self()] for [owner_ckey][!owner ? "(DC)": ""].") if (owner) SEND_SOUND(owner, sound('sound/effects/adminhelp.ogg')) to_chat(owner, "-- Interview Update --" \ @@ -79,7 +79,7 @@ GLOB.interviews.close_interview(src) GLOB.interviews.cooldown_ckeys |= owner_ckey log_admin_private("[key_name(denied_by)] has denied interview #[id] for [owner_ckey][!owner ? "(DC)": ""].") - message_admins("[key_name(denied_by)] has denied interview #[id] for [owner_ckey][!owner ? "(DC)": ""].") + message_admins("[key_name(denied_by)] has denied [link_self()] for [owner_ckey][!owner ? "(DC)": ""].") addtimer(CALLBACK(GLOB.interviews, TYPE_PROC_REF(/datum/interview_manager, release_from_cooldown), owner_ckey), 180) if (owner) SEND_SOUND(owner, sound('sound/effects/adminhelp.ogg')) @@ -160,3 +160,9 @@ "response" = responses.len < i ? null : responses[i] ) .["questions"] += list(data) + +/** + * Generates a clickable link to open this interview + */ +/datum/interview/proc/link_self() + return "Interview #[id]" diff --git a/code/modules/interview/interview_manager.dm b/code/modules/interview/interview_manager.dm index 05ced3b102d8..f5a557a854de 100644 --- a/code/modules/interview/interview_manager.dm +++ b/code/modules/interview/interview_manager.dm @@ -109,7 +109,7 @@ GLOBAL_DATUM_INIT(interviews, /datum/interview_manager, new) if(X.prefs.toggles & SOUND_ADMINHELP) SEND_SOUND(X, sound('sound/effects/adminhelp.ogg')) window_flash(X, ignorepref = TRUE) - to_chat(X, "Interview for [ckey] enqueued for review. Current position in queue: [to_queue.pos_in_queue]", confidential = TRUE) + to_chat(X, "[to_queue.link_self()] for [ckey] enqueued for review. Current position in queue: [to_queue.pos_in_queue]", confidential = TRUE) /** * Removes a ckey from the cooldown list, used for enforcing cooldown after an interview is denied. diff --git a/config/interviews.txt b/config/interviews.txt index 5bd80b815464..3406d7b89325 100644 --- a/config/interviews.txt +++ b/config/interviews.txt @@ -1,9 +1,12 @@ # Interview welcome message displayed at the top of all interview questionnaires # Should help to describe why the questionnaire is being given to the interviewee +# You can include links using markdown-style link notation, like [our rules](https://shiptest.net/wiki/Rules) INTERVIEW_WELCOME_MSG Welcome to our server. As you have not played here before, or played very little, we'll need you to answer a few questions below. After you submit your answers they will be reviewed and you may be asked further questions before being allowed to play. Please be patient as there may be others ahead of you. # Interview questions are listed here, in the order that they will be displayed in-game. +# You can include links using markdown-style link notation, like [our rules](https://shiptest.net/wiki/Rules) INTERVIEW_QUESTIONS Why have you joined the server today? INTERVIEW_QUESTIONS Have you played space-station 13 before? If so, on what servers? INTERVIEW_QUESTIONS Do you know anybody on the server today? If so, who? -INTERVIEW_QUESTIONS Do you have any additional comments? +INTERVIEW_QUESTIONS Have you read and understood our [rules](https://shiptest.net/wiki/Rules)? +INTERVIEW_QUESTIONS Do you have any additional comments or questions? diff --git a/tgui/packages/tgui/interfaces/Interview.js b/tgui/packages/tgui/interfaces/Interview.js index 66ce143ed9b2..d054e3396703 100644 --- a/tgui/packages/tgui/interfaces/Interview.js +++ b/tgui/packages/tgui/interfaces/Interview.js @@ -36,12 +36,31 @@ export const Interview = (props, context) => { } }; + // Matches a complete markdown-style link, capturing the whole [...](...) + const link_regex = /(\[[^[]+\]\([^)]+\))/; + // Decomposes a markdown-style link into the link and display text + const link_decompose_regex = /\[([^[]+)\]\(([^)]+)\)/; + + // Renders any markdown-style links within a provided body of text + const linkify_text = (text) => { + let parts = text.split(link_regex); + for (let i = 1; i < parts.length; i += 2) { + const match = link_decompose_regex.exec(parts[i]); + parts[i] = ( + + {match[1]} + + ); + } + return parts; + }; + return ( {(!read_only && (
-

{welcome_message}

+

{linkify_text(welcome_message)}

)) || rendered_status(status)} @@ -87,8 +106,8 @@ export const Interview = (props, context) => { )} {questions.map(({ qidx, question, response }) => (
-

{question}

- {(read_only && ( +

{linkify_text(question)}

+ {((read_only || is_admin) && (
{response || 'No response.'}
)) || (