From 52269881d26009d6f44f08e74fda83a3724d06d2 Mon Sep 17 00:00:00 2001 From: Burzah <116982774+Burzah@users.noreply.github.com> Date: Mon, 21 Apr 2025 06:55:07 -0700 Subject: [PATCH 1/6] Initial commit --- tgui/packages/tgui-panel/chat/constants.js | 4 ++-- tgui/public/tgui-panel.bundle.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tgui/packages/tgui-panel/chat/constants.js b/tgui/packages/tgui-panel/chat/constants.js index 4e3494ab65cb7..dc77bddd31192 100644 --- a/tgui/packages/tgui-panel/chat/constants.js +++ b/tgui/packages/tgui-panel/chat/constants.js @@ -5,8 +5,8 @@ */ export const MAX_VISIBLE_MESSAGES = 2500; -export const MAX_PERSISTED_MESSAGES = 1000; -export const MESSAGE_SAVE_INTERVAL = 10000; +export const MAX_PERSISTED_MESSAGES = 500; +export const MESSAGE_SAVE_INTERVAL = 60000; export const MESSAGE_PRUNE_INTERVAL = 60000; export const COMBINE_MAX_TIME_WINDOW = 5000; export const COMBINE_MAX_MESSAGES = 5; diff --git a/tgui/public/tgui-panel.bundle.js b/tgui/public/tgui-panel.bundle.js index d67a04110418c..fc8fe222b765c 100644 --- a/tgui/public/tgui-panel.bundle.js +++ b/tgui/public/tgui-panel.bundle.js @@ -118,7 +118,7 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT - */var t=e.MAX_VISIBLE_MESSAGES=2500,n=e.MAX_PERSISTED_MESSAGES=1e3,r=e.MESSAGE_SAVE_INTERVAL=1e4,o=e.MESSAGE_PRUNE_INTERVAL=6e4,a=e.COMBINE_MAX_TIME_WINDOW=5e3,u=e.COMBINE_MAX_MESSAGES=5,i=e.IMAGE_RETRY_DELAY=250,l=e.IMAGE_RETRY_LIMIT=10,p=e.IMAGE_RETRY_MESSAGE_AGE=6e4,h=e.MESSAGE_TYPE_UNKNOWN="unknown",s=e.MESSAGE_TYPE_INTERNAL="internal",d=e.MESSAGE_TYPE_SYSTEM="system",c=e.MESSAGE_TYPE_LOCALCHAT="localchat",g=e.MESSAGE_TYPE_RADIO="radio",f=e.MESSAGE_TYPE_INFO="info",v=e.MESSAGE_TYPE_WARNING="warning",m=e.MESSAGE_TYPE_DEADCHAT="deadchat",E=e.MESSAGE_TYPE_OOC="ooc",I=e.MESSAGE_TYPE_ADMINPM="adminpm",O=e.MESSAGE_TYPE_MENTORPM="mentorpm",b=e.MESSAGE_TYPE_COMBAT="combat",S=e.MESSAGE_TYPE_ADMINCHAT="adminchat",T=e.MESSAGE_TYPE_MENTORCHAT="mentorchat",C=e.MESSAGE_TYPE_DEVCHAT="devchat",A=e.MESSAGE_TYPE_EVENTCHAT="eventchat",P=e.MESSAGE_TYPE_ADMINLOG="adminlog",M=e.MESSAGE_TYPE_ATTACKLOG="attacklog",w=e.MESSAGE_TYPE_DEBUG="debug",V=e.MESSAGE_TYPES=[{type:d,name:"System Messages",description:"Messages from your client, always enabled",selector:".boldannounceooc",important:!0},{type:c,name:"Local",description:"In-character local messages (say, emote, etc)",selector:".say, .emote"},{type:g,name:"Radio",description:"All departments of radio messages",selector:".alert, .syndradio, .centradio, .airadio, .entradio, .comradio, .secradio, .engradio, .medradio, .sciradio, .supradio, .srvradio, .expradio, .radio, .deptradio, .newscaster, .proradio"},{type:f,name:"Info",description:"Non-urgent messages from the game and items",selector:".notice:not(.pm), .adminnotice, .info, .sinister, .cult"},{type:v,name:"Warnings",description:"Urgent messages from the game and items",selector:".warning:not(.pm), .critical, .userdanger, .italics, .boldannounceic, .boldwarning"},{type:m,name:"Deadchat",description:"All of deadchat",selector:".deadsay"},{type:E,name:"OOC",description:"The bluewall of global OOC messages",selector:".ooc, .adminooc, .interface"},{type:I,name:"Admin PMs",description:"Messages to/from admins (adminhelp)",selector:".adminpm, .adminhelp, .adminticket, .adminticketalt"},{type:O,name:"Mentor PMs",description:"Messages to/from mentors (mentorhelp)",selector:".mentorpm, .mentorhelp"},{type:b,name:"Combat Log",description:"Urist McTraitor has stabbed you with a knife!",selector:".danger"},{type:h,name:"Unsorted",description:"Everything we could not sort, always enabled"},{type:S,name:"Admin Chat",description:"ASAY messages",selector:".admin_channel, .adminsay",admin:!0},{type:T,name:"Mentor Chat",description:"MSAY messages",selector:".mentor_channel",admin:!0},{type:C,name:"Developer Chat",description:"DEVSAY messages",selector:".dev_channel",admin:!0},{type:P,name:"Admin Log",description:"ADMIN LOG: Urist McAdmin has jumped to coordinates X, Y, Z",selector:".log_message",admin:!0},{type:M,name:"Attack Log",description:"Urist McTraitor has shot John Doe",admin:!0},{type:w,name:"Debug Log",description:"DEBUG: SSPlanets subsystem Recover().",selector:".pr_announce, .debug",admin:!0}]},96835:function(y,e,t){"use strict";e.__esModule=!0,e.chatReducer=e.chatMiddleware=e.ChatTabs=e.ChatPanel=e.ChatPageSettings=void 0;var n=t(15039);e.ChatPageSettings=n.ChatPageSettings;var r=t(44675);e.ChatPanel=r.ChatPanel;var o=t(41125);e.ChatTabs=o.ChatTabs;var a=t(84807);e.chatMiddleware=a.chatMiddleware;var u=t(40147);e.chatReducer=u.chatReducer},84807:function(y,e,t){"use strict";e.__esModule=!0,e.chatMiddleware=void 0;var n=s(t(22734)),r=t(27108),o=t(36471),a=t(77034),u=t(37152),i=t(69126),l=t(41950),p=t(15916),h=t(23429);function s(S){return S&&S.__esModule?S:{default:S}}function d(S,T){var C=typeof Symbol!="undefined"&&S[Symbol.iterator]||S["@@iterator"];if(C)return(C=C.call(S)).next.bind(C);if(Array.isArray(S)||(C=c(S))||T&&S&&typeof S.length=="number"){C&&(S=C);var A=0;return function(){return A>=S.length?{done:!0}:{done:!1,value:S[A++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function c(S,T){if(S){if(typeof S=="string")return g(S,T);var C={}.toString.call(S).slice(8,-1);return C==="Object"&&S.constructor&&(C=S.constructor.name),C==="Map"||C==="Set"?Array.from(S):C==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(C)?g(S,T):void 0}}function g(S,T){(T==null||T>S.length)&&(T=S.length);for(var C=0,A=Array(T);C=0;--Et){var st=this.tryEntries[Et],yt=st.completion;if(st.tryLoc==="root")return pt("end");if(st.tryLoc<=this.prev){var Pt=A.call(st,"catchLoc"),Ct=A.call(st,"finallyLoc");if(Pt&&Ct){if(this.prev=0;--pt){var Et=this.tryEntries[pt];if(Et.tryLoc<=this.prev&&A.call(Et,"finallyLoc")&&this.prev=0;--nt){var pt=this.tryEntries[nt];if(pt.finallyLoc===tt)return this.complete(pt.completion,pt.afterLoc),mt(pt),K}}return k}(),catch:function(){function k(tt){for(var nt=this.tryEntries.length-1;nt>=0;--nt){var pt=this.tryEntries[nt];if(pt.tryLoc===tt){var Et=pt.completion;if(Et.type==="throw"){var st=Et.arg;mt(pt)}return st}}throw Error("illegal catch attempt")}return k}(),delegateYield:function(){function k(tt,nt,pt){return this.delegate={iterator:et(tt),resultName:nt,nextLoc:pt},this.method==="next"&&(this.arg=S),K}return k}()},T}function v(S,T,C,A,P,M,w){try{var V=S[M](w),U=V.value}catch(j){return void C(j)}V.done?T(U):Promise.resolve(U).then(A,P)}function m(S){return function(){var T=this,C=arguments;return new Promise(function(A,P){var M=S.apply(T,C);function w(U){v(M,A,P,w,V,"next",U)}function V(U){v(M,A,P,w,V,"throw",U)}w(void 0)})}}/** + */var t=e.MAX_VISIBLE_MESSAGES=2500,n=e.MAX_PERSISTED_MESSAGES=500,r=e.MESSAGE_SAVE_INTERVAL=6e4,o=e.MESSAGE_PRUNE_INTERVAL=6e4,a=e.COMBINE_MAX_TIME_WINDOW=5e3,u=e.COMBINE_MAX_MESSAGES=5,i=e.IMAGE_RETRY_DELAY=250,l=e.IMAGE_RETRY_LIMIT=10,p=e.IMAGE_RETRY_MESSAGE_AGE=6e4,h=e.MESSAGE_TYPE_UNKNOWN="unknown",s=e.MESSAGE_TYPE_INTERNAL="internal",d=e.MESSAGE_TYPE_SYSTEM="system",c=e.MESSAGE_TYPE_LOCALCHAT="localchat",g=e.MESSAGE_TYPE_RADIO="radio",f=e.MESSAGE_TYPE_INFO="info",v=e.MESSAGE_TYPE_WARNING="warning",m=e.MESSAGE_TYPE_DEADCHAT="deadchat",E=e.MESSAGE_TYPE_OOC="ooc",I=e.MESSAGE_TYPE_ADMINPM="adminpm",O=e.MESSAGE_TYPE_MENTORPM="mentorpm",b=e.MESSAGE_TYPE_COMBAT="combat",S=e.MESSAGE_TYPE_ADMINCHAT="adminchat",T=e.MESSAGE_TYPE_MENTORCHAT="mentorchat",C=e.MESSAGE_TYPE_DEVCHAT="devchat",A=e.MESSAGE_TYPE_EVENTCHAT="eventchat",P=e.MESSAGE_TYPE_ADMINLOG="adminlog",M=e.MESSAGE_TYPE_ATTACKLOG="attacklog",w=e.MESSAGE_TYPE_DEBUG="debug",V=e.MESSAGE_TYPES=[{type:d,name:"System Messages",description:"Messages from your client, always enabled",selector:".boldannounceooc",important:!0},{type:c,name:"Local",description:"In-character local messages (say, emote, etc)",selector:".say, .emote"},{type:g,name:"Radio",description:"All departments of radio messages",selector:".alert, .syndradio, .centradio, .airadio, .entradio, .comradio, .secradio, .engradio, .medradio, .sciradio, .supradio, .srvradio, .expradio, .radio, .deptradio, .newscaster, .proradio"},{type:f,name:"Info",description:"Non-urgent messages from the game and items",selector:".notice:not(.pm), .adminnotice, .info, .sinister, .cult"},{type:v,name:"Warnings",description:"Urgent messages from the game and items",selector:".warning:not(.pm), .critical, .userdanger, .italics, .boldannounceic, .boldwarning"},{type:m,name:"Deadchat",description:"All of deadchat",selector:".deadsay"},{type:E,name:"OOC",description:"The bluewall of global OOC messages",selector:".ooc, .adminooc, .interface"},{type:I,name:"Admin PMs",description:"Messages to/from admins (adminhelp)",selector:".adminpm, .adminhelp, .adminticket, .adminticketalt"},{type:O,name:"Mentor PMs",description:"Messages to/from mentors (mentorhelp)",selector:".mentorpm, .mentorhelp"},{type:b,name:"Combat Log",description:"Urist McTraitor has stabbed you with a knife!",selector:".danger"},{type:h,name:"Unsorted",description:"Everything we could not sort, always enabled"},{type:S,name:"Admin Chat",description:"ASAY messages",selector:".admin_channel, .adminsay",admin:!0},{type:T,name:"Mentor Chat",description:"MSAY messages",selector:".mentor_channel",admin:!0},{type:C,name:"Developer Chat",description:"DEVSAY messages",selector:".dev_channel",admin:!0},{type:P,name:"Admin Log",description:"ADMIN LOG: Urist McAdmin has jumped to coordinates X, Y, Z",selector:".log_message",admin:!0},{type:M,name:"Attack Log",description:"Urist McTraitor has shot John Doe",admin:!0},{type:w,name:"Debug Log",description:"DEBUG: SSPlanets subsystem Recover().",selector:".pr_announce, .debug",admin:!0}]},96835:function(y,e,t){"use strict";e.__esModule=!0,e.chatReducer=e.chatMiddleware=e.ChatTabs=e.ChatPanel=e.ChatPageSettings=void 0;var n=t(15039);e.ChatPageSettings=n.ChatPageSettings;var r=t(44675);e.ChatPanel=r.ChatPanel;var o=t(41125);e.ChatTabs=o.ChatTabs;var a=t(84807);e.chatMiddleware=a.chatMiddleware;var u=t(40147);e.chatReducer=u.chatReducer},84807:function(y,e,t){"use strict";e.__esModule=!0,e.chatMiddleware=void 0;var n=s(t(22734)),r=t(27108),o=t(36471),a=t(77034),u=t(37152),i=t(69126),l=t(41950),p=t(15916),h=t(23429);function s(S){return S&&S.__esModule?S:{default:S}}function d(S,T){var C=typeof Symbol!="undefined"&&S[Symbol.iterator]||S["@@iterator"];if(C)return(C=C.call(S)).next.bind(C);if(Array.isArray(S)||(C=c(S))||T&&S&&typeof S.length=="number"){C&&(S=C);var A=0;return function(){return A>=S.length?{done:!0}:{done:!1,value:S[A++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function c(S,T){if(S){if(typeof S=="string")return g(S,T);var C={}.toString.call(S).slice(8,-1);return C==="Object"&&S.constructor&&(C=S.constructor.name),C==="Map"||C==="Set"?Array.from(S):C==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(C)?g(S,T):void 0}}function g(S,T){(T==null||T>S.length)&&(T=S.length);for(var C=0,A=Array(T);C=0;--Et){var st=this.tryEntries[Et],yt=st.completion;if(st.tryLoc==="root")return pt("end");if(st.tryLoc<=this.prev){var Pt=A.call(st,"catchLoc"),Ct=A.call(st,"finallyLoc");if(Pt&&Ct){if(this.prev=0;--pt){var Et=this.tryEntries[pt];if(Et.tryLoc<=this.prev&&A.call(Et,"finallyLoc")&&this.prev=0;--nt){var pt=this.tryEntries[nt];if(pt.finallyLoc===tt)return this.complete(pt.completion,pt.afterLoc),mt(pt),K}}return k}(),catch:function(){function k(tt){for(var nt=this.tryEntries.length-1;nt>=0;--nt){var pt=this.tryEntries[nt];if(pt.tryLoc===tt){var Et=pt.completion;if(Et.type==="throw"){var st=Et.arg;mt(pt)}return st}}throw Error("illegal catch attempt")}return k}(),delegateYield:function(){function k(tt,nt,pt){return this.delegate={iterator:et(tt),resultName:nt,nextLoc:pt},this.method==="next"&&(this.arg=S),K}return k}()},T}function v(S,T,C,A,P,M,w){try{var V=S[M](w),U=V.value}catch(j){return void C(j)}V.done?T(U):Promise.resolve(U).then(A,P)}function m(S){return function(){var T=this,C=arguments;return new Promise(function(A,P){var M=S.apply(T,C);function w(U){v(M,A,P,w,V,"next",U)}function V(U){v(M,A,P,w,V,"throw",U)}w(void 0)})}}/** * @file * @copyright 2020 Aleksej Komarov * @license MIT From 314457b45706b554e625c0be1a0d579b7ce7bd71 Mon Sep 17 00:00:00 2001 From: Burzah <116982774+Burzah@users.noreply.github.com> Date: Sun, 27 Apr 2025 20:12:08 -0700 Subject: [PATCH 2/6] chat saving toggle --- tgui/packages/tgui-panel/chat/middleware.js | 13 ++ .../tgui-panel/settings/SettingsPanel.js | 17 ++ tgui/public/tgui-panel.bundle.js | 206 +++++++++--------- 3 files changed, 133 insertions(+), 103 deletions(-) diff --git a/tgui/packages/tgui-panel/chat/middleware.js b/tgui/packages/tgui-panel/chat/middleware.js index 5fe3d92a5b131..531762327e908 100644 --- a/tgui/packages/tgui-panel/chat/middleware.js +++ b/tgui/packages/tgui-panel/chat/middleware.js @@ -37,6 +37,12 @@ import { selectChat, selectCurrentChatPage } from './selectors'; const blacklisted_tags = ['a', 'iframe', 'link', 'video']; const saveChatToStorage = async (store) => { + // Early return if chat saving is disabled + const chatSavingEnabled = await storage.get('chat-saving-enabled'); + if (chatSavingEnabled === false) { + return; + } + const state = selectChat(store.getState()); const fromIndex = Math.max(0, chatRenderer.messages.length - MAX_PERSISTED_MESSAGES); const messages = chatRenderer.messages.slice(fromIndex).map((message) => serializeMessage(message)); @@ -45,6 +51,13 @@ const saveChatToStorage = async (store) => { }; const loadChatFromStorage = async (store) => { + // Early return if chat saving is disabled + const chatSavingEnabled = await storage.get('chat-saving-enabled'); + if (chatSavingEnabled === false) { + store.dispatch(loadChat()); + return; + } + const [state, messages] = await Promise.all([storage.get('chat-state'), storage.get('chat-messages')]); // Discard incompatible versions if (state && state.version <= 4) { diff --git a/tgui/packages/tgui-panel/settings/SettingsPanel.js b/tgui/packages/tgui-panel/settings/SettingsPanel.js index a1ffd06110d3c..ff6cac70fc18a 100644 --- a/tgui/packages/tgui-panel/settings/SettingsPanel.js +++ b/tgui/packages/tgui-panel/settings/SettingsPanel.js @@ -35,6 +35,7 @@ import { import { SETTINGS_TABS, FONTS, MAX_HIGHLIGHT_SETTINGS } from './constants'; import { selectActiveTab, selectSettings, selectHighlightSettings, selectHighlightSettingById } from './selectors'; import { SettingsStatPanel } from './SettingsStatPanel'; +import { storage } from 'common/storage'; export const SettingsPanel = (props, context) => { const activeTab = useSelector(context, selectActiveTab); @@ -76,6 +77,14 @@ export const SettingsGeneral = (props, context) => { const { theme, fontFamily, fontSize, lineHeight } = useSelector(context, selectSettings); const dispatch = useDispatch(context); const [freeFont, setFreeFont] = useLocalState(context, 'freeFont', false); + const [chatSaving, setChatSaving] = useLocalState(context, 'chatSaving', false); + + // Update storage when chatSaving changes + const updateChatSaving = (value) => { + setChatSaving(value); + storage.set('chat-saving-enabled', value); + }; + return (
@@ -194,6 +203,14 @@ export const SettingsGeneral = (props, context) => { + + updateChatSaving(!chatSaving)} + /> +