From f0b36ddc59e26fef737ab9ccf90479811f56adff Mon Sep 17 00:00:00 2001
From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com>
Date: Sat, 30 Jul 2022 16:15:05 +0100
Subject: [PATCH] Changelog improvements (#18498)
* Changelog improvements
* Farie tweaks
* Fix
* Improvements
---
code/controllers/subsystem/changelog.dm | 178 +++++++-----------
code/modules/client/client_procs.dm | 1 +
code/modules/client/preference/preferences.dm | 1 +
.../client/preference/preferences_mysql.dm | 2 +
.../packages/tgui/interfaces/ChangelogView.js | 65 +++++++
tgui/packages/tgui/public/tgui.bundle.js | 4 +-
6 files changed, 141 insertions(+), 110 deletions(-)
create mode 100644 tgui/packages/tgui/interfaces/ChangelogView.js
diff --git a/code/controllers/subsystem/changelog.dm b/code/controllers/subsystem/changelog.dm
index 488be1d32c0..713436a1d82 100644
--- a/code/controllers/subsystem/changelog.dm
+++ b/code/controllers/subsystem/changelog.dm
@@ -15,9 +15,8 @@ SUBSYSTEM_DEF(changelog)
flags = SS_NO_FIRE
var/current_cl_timestamp = "0" // Timestamp is seconds since UNIX epoch (1st January 1970). ITs also a string because BYOND doesnt like big numbers.
var/ss_ready = FALSE // Is the SS ready? We dont want to run procs if we have not generated yet
- var/list/startup_clients_button = list() // Clients who connected before initialization who need their button color updating
- var/list/startup_clients_open = list() // Clients who connected before initialization who need the CL opening
- var/changelogHTML = "" // HTML that the changelog will use to display
+ var/list/client/startup_clients_open = list() // Clients who connected before initialization who need the CL opening
+ var/list/changelog_data = list() // Parsed changelog data
/datum/controller/subsystem/changelog/Initialize()
// This entire subsystem relies on SQL being here.
@@ -32,20 +31,21 @@ SUBSYSTEM_DEF(changelog)
while(latest_cl_date.NextRow())
current_cl_timestamp = latest_cl_date.item[1]
+
qdel(latest_cl_date)
- if(!GenerateChangelogHTML()) // if this failed to generate
+ if(!GenerateChangelogData()) // if this failed to generate
to_chat(world, "WARNING: Changelog failed to generate. Please inform a coder/server dev")
return ..()
ss_ready = TRUE
- // Now we can alert anyone who wanted to check the changelog
- for(var/x in startup_clients_button)
- var/client/C = x
+
+ // Update buttons for those who logged in
+ for(var/client/C as anything in GLOB.clients)
UpdatePlayerChangelogButton(C)
// Now we can alert anyone who wanted to check the changelog
- for(var/client/C in startup_clients_open)
+ for(var/client/C as anything in startup_clients_open)
OpenChangelog(C)
return ..()
@@ -59,49 +59,40 @@ SUBSYSTEM_DEF(changelog)
winset(C, "rpane.changelog", "background-color=#40628a;font-color=#ffffff;font-style=none")
else
winset(C, "rpane.changelog", "background-color=none;font-style=none")
+
+
C.prefs.lastchangelog = current_cl_timestamp
var/datum/db_query/updatePlayerCLTime = SSdbcore.NewQuery(
- "UPDATE player SET lastchangelog=:lastchangelog WHERE ckey=:ckey",
- list(
+ "UPDATE player SET lastchangelog=:lastchangelog WHERE ckey=:ckey", list(
"lastchangelog" = current_cl_timestamp,
"ckey" = C.ckey
)
)
+
// We dont do anything with this query so we dont care about errors too much
updatePlayerCLTime.warn_execute()
qdel(updatePlayerCLTime)
/datum/controller/subsystem/changelog/proc/UpdatePlayerChangelogButton(client/C)
- // If SQL aint even enabled, just set the button to default style
- if(!SSdbcore.IsConnected())
+ // If SQL aint even enabled, or we aint ready just set the button to default style
+ if(!SSdbcore.IsConnected() || !ss_ready)
if(C.prefs.toggles & PREFTOGGLE_UI_DARKMODE)
winset(C, "rpane.changelog", "background-color=#40628a;text-color=#FFFFFF")
else
winset(C, "rpane.changelog", "background-color=none;text-color=#000000")
return
- // If SQL is enabled but we aint ready, queue them up, and use the default style
- if(!ss_ready)
- startup_clients_button |= C
+ // If we are ready, process the button style
+ if(C.prefs.lastchangelog != current_cl_timestamp)
+ winset(C, "rpane.changelog", "background-color=#bb7700;text-color=#FFFFFF;font-style=bold")
+ to_chat(C, "Changelog has changed since your last visit.")
+ else
if(C.prefs.toggles & PREFTOGGLE_UI_DARKMODE)
winset(C, "rpane.changelog", "background-color=#40628a;text-color=#FFFFFF")
else
winset(C, "rpane.changelog", "background-color=none;text-color=#000000")
- return
-
- // Sanity check to ensure clients still exist (If a client DCs mid startup this would runtime)
- if(C && C.prefs)
- // If we are ready, process the button style
- if(C.prefs.lastchangelog != current_cl_timestamp)
- winset(C, "rpane.changelog", "background-color=#bb7700;text-color=#FFFFFF;font-style=bold")
- to_chat(C, "Changelog has changed since your last visit.")
- else
- if(C.prefs.toggles & PREFTOGGLE_UI_DARKMODE)
- winset(C, "rpane.changelog", "background-color=#40628a;text-color=#FFFFFF")
- else
- winset(C, "rpane.changelog", "background-color=none;text-color=#000000")
/datum/controller/subsystem/changelog/proc/OpenChangelog(client/C)
@@ -119,9 +110,7 @@ SUBSYSTEM_DEF(changelog)
UpdatePlayerChangelogDate(C)
UpdatePlayerChangelogButton(C)
- var/datum/browser/cl_popup = new(C.mob, "changelog", "Changelog", 700, 800)
- cl_popup.set_content(changelogHTML)
- cl_popup.open()
+ ui_interact(C.mob)
/client/verb/changes()
set name = "Changelog"
@@ -130,51 +119,13 @@ SUBSYSTEM_DEF(changelog)
// Just invoke the actual CL thing
SSchangelog.OpenChangelog(src)
-// Helper to turn CL types into a fontawesome icon instead of an image
-// The colors are #28a745 for green, #fd7e14 for orange, and #dc3545 for red.
-// These colours are from bootstrap and look good with black and white
-/datum/controller/subsystem/changelog/proc/Text2Icon(text)
- switch(text)
- if("FIX")
- return "" // Fixes are white because while they are good, they have no negative coutnerpart
- if("WIP")
- return "" // WIP stuff is orange because new code is good but its not done yet
- if("TWEAK")
- return "" // Tweaks are white because they could be good or bad, and theres no specific add or remove
- if("SOUNDADD")
- return "" // Sound additions are green because its something new
- if("SOUNDDEL")
- return "" // Sound removals are red because something has been removed
- if("CODEADD")
- return "" // Code additions are green because its something new
- if("CODEDEL")
- return "" // Code removals are red becuase someting has been removed
- if("IMAGEADD")
- return "" // Image additions are green because something has been added
- if("IMAGEDEL")
- return "" // Image removals are red because something has been removed
- if("SPELLCHECK")
- return "" // Spellcheck is white because theres no dedicated negative to it, so theres no red for it to collate with
- if("EXPERIMENT")
- return "" // Experimental stuff is orange because while its a new feature, its unstable
- else // Just incase the DB somehow breaks
- return "" // Same here
-
// This proc is the star of the show
-/datum/controller/subsystem/changelog/proc/GenerateChangelogHTML()
+/datum/controller/subsystem/changelog/proc/GenerateChangelogData()
+ // This value will be returned if the proc crashes
. = FALSE
- // Modify the code below to modify the header of the changelog
- var/changelog_header = {"
-
-
- "}
var/list/prs_to_process = list()
+
// Grab all from last 30 days
var/datum/db_query/pr_list_query = SSdbcore.NewQuery("SELECT DISTINCT pr_number FROM changelog WHERE date_merged BETWEEN NOW() - INTERVAL 30 DAY AND NOW() ORDER BY date_merged DESC")
if(!pr_list_query.warn_execute())
@@ -183,10 +134,8 @@ SUBSYSTEM_DEF(changelog)
while(pr_list_query.NextRow())
prs_to_process += text2num(pr_list_query.item[1])
- qdel(pr_list_query)
- // Load in the header
- changelogHTML += changelog_header
+ qdel(pr_list_query)
// We put all these queries into a list so we can batch-execute them to avoid excess delays
// We index these based on PR numbers. MAKE SURE YOU USE STRING INDICIES IN THIS IF YOU EVER TWEAK IT -aa
@@ -196,7 +145,7 @@ SUBSYSTEM_DEF(changelog)
// Create some queries for each PR
for(var/pr_number in prs_to_process)
var/datum/db_query/pr_meta = SSdbcore.NewQuery(
- "SELECT author, DATE_FORMAT(date_merged, '%Y-%m-%d at %T') AS date FROM changelog WHERE pr_number = :prnum LIMIT 1",
+ "SELECT author, DATE_FORMAT(date_merged, '%Y-%m-%d at %T') AS date, CAST(UNIX_TIMESTAMP(date_merged) AS CHAR) AS ts FROM changelog WHERE pr_number = :prnum LIMIT 1",
list("prnum" = pr_number)
)
@@ -221,26 +170,27 @@ SUBSYSTEM_DEF(changelog)
SSdbcore.MassExecute(entry_queries, TRUE, FALSE, TRUE)
for(var/pr_number in prs_to_process)
- // Initial declarations
- var/pr_block = "" // HTML for the changelog section
- var/author = "" // Author of the PR
- var/merge_date = "" // Timestamp of when the PR was merged
+ var/list/this_pr = list()
+ this_pr["num"] = pr_number
// Assemble metadata
while(meta_queries["[pr_number]"].NextRow())
- author = meta_queries["[pr_number]"].item[1]
- merge_date = meta_queries["[pr_number]"].item[2]
+ this_pr["author"] = meta_queries["[pr_number]"].item[1]
+ this_pr["merge_date"] = meta_queries["[pr_number]"].item[2]
+ this_pr["merge_ts"] = meta_queries["[pr_number]"].item[3]
- // Now for each actual entry
- pr_block += "
"
- pr_block += "
#[pr_number] by [author] (Merged on [merge_date])"
+ var/list/cl_entries = list()
while(entry_queries["[pr_number]"].NextRow())
- pr_block += "