Discord/Shapes - Events

Events Feature for Shapes

  1. // ==UserScript==
  2. // @name Discord/Shapes - Events
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.4
  5. // @description Events Feature for Shapes
  6. // @author Vishanka
  7. // @match https://discord.com/channels/*
  8. // @grant unsafeWindow
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. // Wait for storagePanel to be available
  15. function waitForStoragePanel() {
  16. if (typeof unsafeWindow.DCstoragePanel !== 'undefined') {
  17. initializeButton();
  18. } else {
  19. setTimeout(waitForStoragePanel, 500);
  20. }
  21. }
  22.  
  23. waitForStoragePanel();
  24.  
  25. function initializeButton() {
  26. // Create button to open profile management panel
  27. const button = document.createElement('button');
  28. button.innerText = 'Manage Events';
  29. button.style.margin = '10px';
  30. button.onclick = openProfilePanel;
  31.  
  32. // Append the button to storagePanel
  33. unsafeWindow.DCstoragePanel.appendChild(button);
  34. }
  35.  
  36. function openProfilePanel() {
  37. // Create profile management panel
  38. const profilePanel = document.createElement('div');
  39. profilePanel.style.position = 'fixed';
  40. profilePanel.style.top = '50%';
  41. profilePanel.style.left = '50%';
  42. profilePanel.style.transform = 'translate(-50%, -50%)';
  43. profilePanel.style.width = '800px';
  44. profilePanel.style.height = '700px';
  45. profilePanel.style.backgroundColor = '#2F2F2F';
  46. profilePanel.style.color = 'white';
  47. profilePanel.style.borderRadius = '20px';
  48. profilePanel.style.padding = '20px';
  49. profilePanel.style.zIndex = '1000';
  50. profilePanel.style.display = 'flex';
  51. profilePanel.style.flexDirection = 'row';
  52.  
  53. // Create close button for profilePanel
  54. // Create close button for profilePanel
  55. const closeButton = document.createElement('button');
  56. closeButton.style.position = 'absolute';
  57. closeButton.style.top = '15px';
  58. closeButton.style.right = '15px';
  59. closeButton.style.width = '30px';
  60. closeButton.style.height = '30px';
  61. closeButton.style.backgroundColor = 'transparent';
  62. closeButton.style.color = '#ffffff';
  63. closeButton.style.border = 'none';
  64. closeButton.style.borderRadius = '50%';
  65. closeButton.style.cursor = 'pointer';
  66. closeButton.style.display = 'flex';
  67. closeButton.style.alignItems = 'center';
  68. closeButton.style.zIndex = '1001';
  69. closeButton.style.justifyContent = 'center';
  70. closeButton.style.transition = 'background-color 0.2s ease';
  71. closeButton.style.boxSizing = 'border-box';
  72.  
  73. // Create span for the '✕' character
  74. const closeIcon = document.createElement('span');
  75. closeIcon.innerText = '✕';
  76. closeIcon.style.fontSize = '16px';
  77. closeIcon.style.position = 'relative';
  78. closeIcon.style.top = '-1px'; // Adjust this value to move the character up
  79.  
  80. // Append the span to the button
  81. closeButton.appendChild(closeIcon);
  82.  
  83. // Hover effect
  84. closeButton.addEventListener('mouseenter', () => {
  85. closeButton.style.backgroundColor = '#676767';
  86. });
  87.  
  88. closeButton.addEventListener('mouseleave', () => {
  89. closeButton.style.backgroundColor = 'transparent';
  90. });
  91.  
  92. // Close button action
  93. closeButton.onclick = function() {
  94. document.body.removeChild(profilePanel);
  95. };
  96.  
  97. // Append the button to the profile panel
  98. profilePanel.appendChild(closeButton);
  99.  
  100.  
  101. // Create profile list container
  102. const profileListContainer = document.createElement('div');
  103. profileListContainer.style.flex = '0.50';
  104. profileListContainer.style.marginRight = '20px';
  105. profileListContainer.style.paddingRight = '20px';
  106. profileListContainer.style.display = 'flex';
  107. profileListContainer.style.flexDirection = 'column';
  108. profileListContainer.style.borderRight = '1px solid #444444';
  109. profileListContainer.style.overflowY = 'auto';
  110. profileListContainer.style.maxHeight = '660px';
  111.  
  112. // Create header for profile list
  113. const profileListHeader = document.createElement('h4');
  114. profileListHeader.innerText = 'Profiles';
  115. profileListHeader.style.marginBottom = '10px';
  116. profileListContainer.appendChild(profileListHeader);
  117.  
  118. // Create profile list
  119. const profileList = document.createElement('ul');
  120. profileList.style.overflowY = 'auto';
  121. profileList.style.height = '600px';
  122. profileListContainer.appendChild(profileList);
  123.  
  124. // Create button to add profile
  125. const addProfileButton = document.createElement('button');
  126. addProfileButton.innerText = 'Add Profile';
  127. addProfileButton.style.padding = '8px';
  128. addProfileButton.style.border = '0.2px solid #4E4E4E';
  129.  
  130. addProfileButton.style.backgroundColor = 'transparent';
  131. addProfileButton.style.color = '#fff';
  132. addProfileButton.style.borderRadius = '20px';
  133. addProfileButton.style.cursor = 'pointer';
  134.  
  135. addProfileButton.onmouseover = () => {
  136. addProfileButton.style.backgroundColor = '#424242';
  137. };
  138. addProfileButton.onmouseout = () => {
  139. addProfileButton.style.backgroundColor = 'transparent';
  140. };
  141. addProfileButton.onclick = function() {
  142. openAddProfileDialog();
  143. };
  144. profileListContainer.appendChild(addProfileButton);
  145.  
  146. // Create key-value input container
  147. const keyValueContainer = document.createElement('div');
  148. keyValueContainer.style.flex = '2.3';
  149. keyValueContainer.style.display = 'flex';
  150. keyValueContainer.style.flexDirection = 'column';
  151. keyValueContainer.style.gap = '10px';
  152.  
  153. // Create entries list
  154. const entriesList = document.createElement('div');
  155. entriesList.style.overflowY = 'auto';
  156. entriesList.style.height = '340px';
  157. entriesList.style.width = '100%';
  158. entriesList.style.paddingRight = '20px';
  159. entriesList.style.borderCollapse = 'collapse';
  160. entriesList.style.display = 'block';
  161. entriesList.style.overflowY = 'auto';
  162.  
  163. // Create a header above the headerRow
  164. const manageEventsHeader = document.createElement('h2');
  165. manageEventsHeader.innerText = 'Manage Event List';
  166. manageEventsHeader.style.marginBottom = '-10px';
  167. keyValueContainer.appendChild(manageEventsHeader);
  168.  
  169. // Create table header
  170. const headerRow = document.createElement('tr');
  171. const headers = ['Key', 'Value', '%', 'Time', ''];
  172. headers.forEach(headerText => {
  173. const header = document.createElement('th');
  174. header.innerText = headerText;
  175. header.style.padding = '5px';
  176. header.style.textAlign = 'left';
  177.  
  178. if (headerText === 'Value') {
  179. header.style.width = '60%';
  180. } else if (headerText === 'Key') {
  181. header.style.width = '15%';
  182. } else if (headerText === '%' || headerText === 'Time') {
  183. header.style.width = '10%';
  184. } else if (headerText === '') {
  185. header.style.width = '5%';
  186. }
  187.  
  188. headerRow.appendChild(header);
  189. });
  190. const headerContainer = document.createElement('div');
  191. headerContainer.style.position = 'sticky';
  192. headerContainer.style.top = '0';
  193. headerContainer.style.backgroundColor = '#2F2F2F';
  194. headerContainer.style.zIndex = '1';
  195. headerContainer.appendChild(headerRow);
  196. entriesList.appendChild(headerContainer);
  197. entriesList.style.position = 'sticky';
  198. entriesList.style.top = '0';
  199. entriesList.style.backgroundColor = '#2F2F2F';
  200. // Create a separate header for the entries list
  201. const entriesHeaderContainer = document.createElement('div');
  202. entriesHeaderContainer.style.position = 'sticky';
  203. entriesHeaderContainer.style.top = '0';
  204. entriesHeaderContainer.style.backgroundColor = '#2F2F2F';
  205. entriesHeaderContainer.style.zIndex = '1';
  206. const entriesHeader = document.createElement('div');
  207. entriesHeader.style.display = 'flex';
  208. entriesHeader.style.padding = '5px 0';
  209. entriesHeader.style.borderBottom = '1px solid #444444';
  210. headers.forEach(headerText => {
  211. const header = document.createElement('div');
  212. header.innerText = headerText;
  213. header.style.padding = '5px';
  214. header.style.textAlign = 'left'; // Align headers to the left
  215. if (headerText === 'Value') {
  216. header.style.width = '57%';
  217. } else if (headerText === 'Key') {
  218. header.style.width = '15%';
  219. } else if (headerText === '%' || headerText === 'Time') {
  220. header.style.width = '7%';
  221. } else if (headerText === '') {
  222. header.style.width = '5%';
  223. }
  224. entriesHeader.appendChild(header);
  225. });
  226. entriesHeaderContainer.appendChild(entriesHeader);
  227. keyValueContainer.appendChild(entriesHeaderContainer);
  228. keyValueContainer.appendChild(entriesList);
  229. // Create container for probability and time range inputs
  230. // Create container for probability and time range inputs
  231. const probTimeContainer = document.createElement('div');
  232. probTimeContainer.style.display = 'flex';
  233. probTimeContainer.style.gap = '10px';
  234. probTimeContainer.style.marginBottom = '-4px';
  235.  
  236. // Create probability label and input
  237. const probabilityContainer = document.createElement('div');
  238. probabilityContainer.style.display = 'flex';
  239. probabilityContainer.style.flexDirection = 'column';
  240. probabilityContainer.style.width = '30%'; // Adjust width to fit the row better
  241.  
  242. const probabilityLabel = document.createElement('div');
  243. probabilityLabel.innerText = 'Event Probability';
  244. probabilityLabel.style.color = 'white';
  245. probabilityLabel.style.marginBottom = '0px';
  246. probabilityContainer.appendChild(probabilityLabel);
  247.  
  248. const probabilityInputContainer = document.createElement('div');
  249. probabilityInputContainer.style.display = 'flex';
  250. probabilityInputContainer.style.alignItems = 'center';
  251.  
  252. const probabilityInput = document.createElement('input');
  253. probabilityInput.type = 'number';
  254. probabilityInput.placeholder = '0-100';
  255. probabilityInput.style.backgroundColor = '#1E1E1E';
  256. probabilityInput.style.color = 'white';
  257. probabilityInput.style.border = '1px solid #444444';
  258. probabilityInput.style.borderRadius = '5px';
  259. probabilityInput.style.padding = '5px';
  260. probabilityInput.style.width = '85%';
  261. probabilityInput.style.marginRight = '5px';
  262. probabilityInputContainer.appendChild(probabilityInput);
  263.  
  264. const probabilityPercentLabel = document.createElement('span');
  265. probabilityPercentLabel.innerText = '%';
  266. probabilityPercentLabel.style.color = 'white';
  267. probabilityInputContainer.appendChild(probabilityPercentLabel);
  268.  
  269. probabilityContainer.appendChild(probabilityInputContainer);
  270. probTimeContainer.appendChild(probabilityContainer);
  271.  
  272. // Create time range label and input
  273. const timeRangeContainer = document.createElement('div');
  274. timeRangeContainer.style.display = 'flex';
  275. timeRangeContainer.style.flexDirection = 'column';
  276. timeRangeContainer.style.width = '30%'; // Adjust width to fit the row better
  277.  
  278. const timeRangeLabel = document.createElement('div');
  279. timeRangeLabel.innerText = 'Time Range';
  280. timeRangeLabel.style.color = 'white';
  281. timeRangeLabel.style.marginBottom = '0px';
  282. timeRangeContainer.appendChild(timeRangeLabel);
  283.  
  284. const timeRangeInputContainer = document.createElement('div');
  285. timeRangeInputContainer.style.display = 'flex';
  286. timeRangeInputContainer.style.alignItems = 'center';
  287.  
  288. const timeRangeInput = document.createElement('input');
  289. timeRangeInput.type = 'text';
  290. timeRangeInput.placeholder = '0-24';
  291. timeRangeInput.value = '0-24'; // Set default value
  292.  
  293. timeRangeInput.style.backgroundColor = '#1E1E1E';
  294. timeRangeInput.style.color = 'white';
  295. timeRangeInput.style.border = '1px solid #444444';
  296. timeRangeInput.style.borderRadius = '5px';
  297. timeRangeInput.style.padding = '5px';
  298. timeRangeInput.style.width = '85%';
  299. timeRangeInput.style.marginRight = '5px';
  300.  
  301. timeRangeInput.addEventListener('blur', () => {
  302. const timeValue = timeRangeInput.value.trim();
  303. const timeRegex = /^([0-9]|1[0-9]|2[0-3])-(?:[0-9]|1[0-9]|2[0-3])$/;
  304. if (!timeRegex.test(timeValue)) {
  305. alert('Please enter a valid time range between 0-23, e.g., "8-16" or "0-24". Defaulting to "0-24".');
  306. timeRangeInput.value = '0-24';
  307. }
  308. });
  309.  
  310. timeRangeInputContainer.appendChild(timeRangeInput);
  311.  
  312. const timeRangeUnitLabel = document.createElement('span');
  313. timeRangeUnitLabel.innerText = 'h';
  314. timeRangeUnitLabel.style.color = 'white';
  315. timeRangeInputContainer.appendChild(timeRangeUnitLabel);
  316.  
  317. timeRangeContainer.appendChild(timeRangeInputContainer);
  318. probTimeContainer.appendChild(timeRangeContainer);
  319.  
  320. // Create overall probability label and input
  321. const overallProbabilityContainer = document.createElement('div');
  322. overallProbabilityContainer.style.display = 'flex';
  323. overallProbabilityContainer.style.flexDirection = 'column';
  324. overallProbabilityContainer.style.width = '30%'; // Adjust width to fit the row better
  325.  
  326. const overallProbabilityLabel = document.createElement('div');
  327. overallProbabilityLabel.innerText = 'Overall Probability';
  328. overallProbabilityLabel.style.color = 'white';
  329. overallProbabilityLabel.style.marginBottom = '0px';
  330. overallProbabilityContainer.appendChild(overallProbabilityLabel);
  331.  
  332. const overallProbabilityInputContainer = document.createElement('div');
  333. overallProbabilityInputContainer.style.display = 'flex';
  334. overallProbabilityInputContainer.style.alignItems = 'center';
  335.  
  336. const overallProbabilityInput = document.createElement('input');
  337. overallProbabilityInput.type = 'number';
  338. overallProbabilityInput.placeholder = '0-100';
  339. overallProbabilityInput.style.backgroundColor = '#202530';
  340. overallProbabilityInput.style.color = 'white';
  341. overallProbabilityInput.style.border = '1px solid #444444';
  342. overallProbabilityInput.style.borderRadius = '5px';
  343. overallProbabilityInput.style.padding = '5px';
  344. overallProbabilityInput.style.marginRight = '5px';
  345. overallProbabilityInput.style.width = '85%';
  346.  
  347. // Load the existing overall probability value if set
  348. const savedProbability = localStorage.getItem('events.probability');
  349. if (savedProbability) {
  350. overallProbabilityInput.value = savedProbability;
  351. }
  352.  
  353. // Add event listener to save the value to localStorage when changed
  354. overallProbabilityInput.addEventListener('input', () => {
  355. const probabilityValue = overallProbabilityInput.value.trim();
  356. if (probabilityValue !== '' && probabilityValue >= 0 && probabilityValue <= 100) {
  357. localStorage.setItem('events.probability', probabilityValue);
  358. } else {
  359. alert('Please enter a valid probability between 0 and 100.');
  360. }
  361. });
  362.  
  363. overallProbabilityInputContainer.appendChild(overallProbabilityInput);
  364.  
  365. const overallProbabilityPercentLabel = document.createElement('span');
  366. overallProbabilityPercentLabel.innerText = '%';
  367. overallProbabilityPercentLabel.style.color = 'white';
  368. overallProbabilityInputContainer.appendChild(overallProbabilityPercentLabel);
  369.  
  370. overallProbabilityContainer.appendChild(overallProbabilityInputContainer);
  371. probTimeContainer.appendChild(overallProbabilityContainer);
  372.  
  373. // Append probability and time range container to the main keyValue container
  374. keyValueContainer.appendChild(probTimeContainer);
  375.  
  376. // Create input for key
  377. const keyInput = document.createElement('input');
  378. keyInput.type = 'text';
  379. keyInput.placeholder = 'Enter key';
  380. keyInput.style.backgroundColor = '#1E1E1E';
  381. keyInput.style.color = 'white';
  382. keyInput.style.border = '1px solid #444444';
  383. keyInput.style.borderRadius = '5px';
  384. keyInput.style.padding = '5px';
  385. keyInput.style.marginBottom = '-4px';
  386. keyValueContainer.appendChild(keyInput);
  387.  
  388. // Create input for value
  389. const valueInput = document.createElement('textarea');
  390. valueInput.placeholder = 'Enter value';
  391. valueInput.style.backgroundColor = '#1E1E1E';
  392. valueInput.style.color = 'white';
  393. valueInput.style.border = '1px solid #444444';
  394. valueInput.style.borderRadius = '5px';
  395. valueInput.style.padding = '5px';
  396. valueInput.style.height = '80px';
  397. valueInput.style.overflowWrap = 'break-word';
  398. valueInput.style.overflow = 'auto';
  399. valueInput.style.marginBottom = '-4px';
  400. keyValueContainer.appendChild(valueInput);
  401.  
  402.  
  403. // Create button to add key-value pair
  404. const addEntryButton = document.createElement('button');
  405. addEntryButton.innerText = 'Add Entry';
  406. addEntryButton.innerText = 'Add Entry';
  407. addEntryButton.style.padding = '10px 20px';
  408. addEntryButton.style.border = '0.2px solid #4E4E4E';
  409. addEntryButton.style.backgroundColor = '#2F2F2F';
  410. addEntryButton.style.color = '#fff';
  411. addEntryButton.style.borderRadius = '50px';
  412. addEntryButton.style.cursor = 'pointer';
  413.  
  414. addEntryButton.onmouseover = () => {
  415. addEntryButton.style.backgroundColor = '#424242';
  416. };
  417. addEntryButton.onmouseout = () => {
  418. addEntryButton.style.backgroundColor = 'transparent';
  419. };
  420.  
  421. addEntryButton.onclick = function () {
  422. if (!selectedProfile) {
  423. alert('Please select a profile before adding entries.');
  424. return;
  425. }
  426.  
  427. const key = keyInput.value.trim();
  428. const value = `<${valueInput.value.trim()}>`;
  429. const probability = probabilityInput.value.trim();
  430. const timeRange = timeRangeInput.value.trim();
  431. const fullKey = `events.${selectedProfile}:${key}`;
  432.  
  433. if (key && value) {
  434. if (!localStorage.getItem(fullKey)) {
  435. const entryData = {
  436. value: value,
  437. probability: probability || '100',
  438. timeRange: timeRange || '0-24'
  439. };
  440. localStorage.setItem(fullKey, JSON.stringify(entryData));
  441. loadEntries();
  442.  
  443. // Clear the input fields after adding the entry
  444. keyInput.value = '';
  445. valueInput.value = '';
  446. probabilityInput.value = '100';
  447. timeRangeInput.value = '0-24';
  448.  
  449.  
  450.  
  451. } else {
  452. alert('Entry with this key already exists. Please use a different key.');
  453. }
  454. }
  455. };
  456. keyValueContainer.appendChild(addEntryButton);
  457.  
  458. // Append containers to profilePanel
  459. profilePanel.appendChild(profileListContainer);
  460. profilePanel.appendChild(keyValueContainer);
  461.  
  462.  
  463.  
  464. // Load saved profiles and entries
  465. let selectedProfile = localStorage.getItem('events.selectedProfile');
  466.  
  467. function loadProfiles() {
  468. profileList.innerHTML = '';
  469. for (let key in localStorage) {
  470. if (key.startsWith('events.profile.')) {
  471. const profileName = key.replace('events.profile.', '');
  472. const listItem = document.createElement('li');
  473. listItem.style.display = 'flex';
  474. listItem.style.alignItems = 'center';
  475. listItem.style.cursor = 'pointer';
  476.  
  477. const nameSpan = document.createElement('span');
  478. nameSpan.innerText = profileName;
  479. nameSpan.style.flex = '1';
  480. listItem.appendChild(nameSpan);
  481.  
  482. listItem.onclick = function() {
  483. if (selectedProfile === profileName) {
  484. selectedProfile = null;
  485. localStorage.setItem('events.selectedProfile', '');
  486. listItem.style.backgroundColor = '';
  487. loadEntries();
  488. } else {
  489. selectedProfile = profileName;
  490. localStorage.setItem('events.selectedProfile', selectedProfile);
  491. loadEntries();
  492. highlightSelectedProfile(listItem);
  493. }
  494. };
  495.  
  496. const deleteButton = document.createElement('button');
  497. // deleteButton.innerText = 'x';
  498. deleteButton.style.backgroundColor = 'transparent';
  499. deleteButton.style.borderRadius = '50%';
  500. deleteButton.style.marginLeft = '10px';
  501. deleteButton.style.border = 'none';
  502. deleteButton.style.color = '#ffffff';
  503. deleteButton.style.cursor = 'pointer';
  504. deleteButton.style.padding = '14px';
  505. deleteButton.style.width = '15px';
  506. deleteButton.style.height = '15px';
  507. deleteButton.style.display = 'flex';
  508. deleteButton.style.alignItems = 'center';
  509. deleteButton.style.justifyContent = 'center';
  510.  
  511. deleteButton.style.transition = 'background-color 0.1s';
  512.  
  513. // Hover effect
  514. deleteButton.addEventListener('mouseenter', () => {
  515. // closeButton.style.transform = 'scale(1.1)';
  516. deleteButton.style.backgroundColor = '#676767';
  517. });
  518.  
  519. deleteButton.addEventListener('mouseleave', () => {
  520. // closeButton.style.transform = 'scale(1)';
  521. deleteButton.style.backgroundColor = 'transparent';
  522. });
  523.  
  524.  
  525.  
  526. const closeIcon2 = document.createElement('span');
  527. closeIcon2.innerText = '✕';
  528. closeIcon2.style.fontSize = '16px';
  529. closeIcon2.style.color = '#ffffff';
  530. closeIcon2.style.position = 'relative';
  531. closeIcon2.style.top = '-1px'; // Adjust this value to move the character up
  532.  
  533. deleteButton.appendChild(closeIcon2);
  534.  
  535.  
  536.  
  537. deleteButton.onclick = function(event) {
  538. event.stopPropagation();
  539. localStorage.removeItem(`events.profile.${profileName}`);
  540. if (selectedProfile === profileName) {
  541. selectedProfile = null;
  542. localStorage.setItem('events.selectedProfile', '');
  543. }
  544. loadProfiles();
  545. loadEntries();
  546. };
  547. listItem.appendChild(deleteButton);
  548.  
  549. if (selectedProfile === profileName) {
  550. highlightSelectedProfile(listItem);
  551. }
  552. profileList.appendChild(listItem);
  553. }
  554. }
  555. }
  556.  
  557. function openAddProfileDialog() {
  558. const dialog = document.createElement('div');
  559. dialog.style.position = 'fixed';
  560. dialog.style.top = '50%';
  561. dialog.style.left = '50%';
  562. dialog.style.transform = 'translate(-50%, -50%)';
  563. dialog.style.backgroundColor = '#424242';
  564. dialog.style.padding = '20px';
  565. dialog.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)';
  566. dialog.style.zIndex = '1100';
  567.  
  568. const input = document.createElement('input');
  569. input.type = 'text';
  570. input.placeholder = 'Enter profile name';
  571. dialog.appendChild(input);
  572.  
  573. const addButton = document.createElement('button');
  574. addButton.innerText = 'Add';
  575. addButton.style.marginLeft = '10px';
  576. addButton.onclick = function() {
  577. const profileName = input.value.trim();
  578. if (profileName && !localStorage.getItem(`events.profile.${profileName}`)) {
  579. localStorage.setItem(`events.profile.${profileName}`, JSON.stringify({}));
  580. loadProfiles();
  581. document.body.removeChild(dialog);
  582. }
  583. };
  584. dialog.appendChild(addButton);
  585.  
  586. const cancelButton = document.createElement('button');
  587. cancelButton.innerText = 'Cancel';
  588. cancelButton.style.marginLeft = '10px';
  589. cancelButton.onclick = function() {
  590. document.body.removeChild(dialog);
  591. };
  592. dialog.appendChild(cancelButton);
  593.  
  594. document.body.appendChild(dialog);
  595. }
  596.  
  597. function loadEntries() {
  598. entriesList.innerHTML = '';
  599. // Add header back after clearing
  600. if (selectedProfile) {
  601. for (let key in localStorage) {
  602. if (key.startsWith(`events.${selectedProfile}:`)) {
  603. const entryData = JSON.parse(localStorage.getItem(key));
  604. const row = document.createElement('div');
  605. row.style.padding = '10px';
  606. row.style.margin = '5px 0';
  607. row.style.borderRadius = '10px';
  608. row.style.marginBottom = '12px';
  609. row.style.backgroundColor = '#424242';
  610. row.style.display = 'flex';
  611. row.style.alignItems = 'center';
  612.  
  613. // Create cells for key, value, probability, and time range
  614. const keyCell = document.createElement('div');
  615. keyCell.innerText = key.split(':')[1];
  616. keyCell.style.padding = '5px';
  617. keyCell.style.width = '15%';
  618. row.appendChild(keyCell);
  619.  
  620. const valueCell = document.createElement('div');
  621. valueCell.innerText = entryData.value.slice(1, -1); // Remove surrounding brackets
  622. valueCell.style.padding = '5px';
  623. valueCell.style.width = '60%';
  624. row.appendChild(valueCell);
  625.  
  626. const probabilityCell = document.createElement('div');
  627. probabilityCell.innerText = `${entryData.probability}%`;
  628. probabilityCell.style.padding = '5px';
  629. probabilityCell.style.width = '10%';
  630. row.appendChild(probabilityCell);
  631.  
  632. const timeRangeCell = document.createElement('div');
  633. timeRangeCell.innerText = entryData.timeRange;
  634. timeRangeCell.style.padding = '5px';
  635. timeRangeCell.style.width = '10%';
  636. row.appendChild(timeRangeCell);
  637.  
  638.  
  639.  
  640. /*// Create close button for profilePanel
  641. const closeButton = document.createElement('button');
  642. closeButton.style.position = 'absolute';
  643. closeButton.style.top = '15px';
  644. closeButton.style.right = '15px';
  645. closeButton.style.width = '30px';
  646. closeButton.style.height = '30px';
  647. closeButton.style.backgroundColor = 'transparent';
  648. closeButton.style.color = '#ffffff';
  649. closeButton.style.border = 'none';
  650. closeButton.style.borderRadius = '50%';
  651. closeButton.style.cursor = 'pointer';
  652. closeButton.style.display = 'flex';
  653. closeButton.style.alignItems = 'center';
  654. closeButton.style.justifyContent = 'center';
  655. closeButton.style.transition = 'background-color 0.2s ease';
  656. closeButton.style.boxSizing = 'border-box';
  657.  
  658. // Create span for the '✕' character
  659. const closeIcon = document.createElement('span');
  660. closeIcon.innerText = '✕';
  661. closeIcon.style.fontSize = '16px';
  662. closeIcon.style.position = 'relative';
  663. closeIcon.style.top = '-1px'; // Adjust this value to move the character up
  664.  
  665. // Append the span to the button
  666. closeButton.appendChild(closeIcon);
  667.  
  668. */
  669.  
  670. // Add remove button for each entry
  671. const actionCell = document.createElement('div');
  672. actionCell.style.padding = '5px';
  673. actionCell.style.width = '5%';
  674. const removeButton = document.createElement('button');
  675. // removeButton.innerText = '✕';
  676. removeButton.style.backgroundColor = 'transparent';
  677. removeButton.style.border = 'none';
  678. removeButton.style.cursor = 'pointer';
  679. removeButton.style.display = 'flex';
  680. removeButton.style.alignItems = 'center';
  681. removeButton.style.justifyContent = 'center';
  682. removeButton.style.width = '100%';
  683. removeButton.style.height = '100%';
  684. removeButton.style.transition = 'background-color 0.2s ease';
  685. removeButton.style.borderRadius = '50%';
  686. removeButton.style.width = '28px';
  687. removeButton.style.height = '28px';
  688. removeButton.style.marginLeft = '-3px';
  689. removeButton.style.boxSizing = 'border-box';
  690. removeButton.onclick = function() {
  691. localStorage.removeItem(key);
  692. loadEntries();
  693. };
  694.  
  695. const closeIcon1 = document.createElement('span');
  696. closeIcon1.innerText = '✕';
  697. closeIcon1.style.fontSize = '16px';
  698. closeIcon1.style.position = 'relative';
  699. closeIcon1.style.color = '#ffffff';
  700. closeIcon1.style.top = '-1px'; // Adjust this value to move the character up
  701.  
  702. // Append the span to the button
  703. removeButton.appendChild(closeIcon1);
  704. actionCell.appendChild(removeButton);
  705. row.appendChild(actionCell);
  706.  
  707. // Hover effect
  708. removeButton.addEventListener('mouseenter', () => {
  709. removeButton.style.backgroundColor = '#676767';
  710. });
  711.  
  712. removeButton.addEventListener('mouseleave', () => {
  713. removeButton.style.backgroundColor = 'transparent';
  714. });
  715.  
  716.  
  717. // Make the row editable when clicked
  718. row.onclick = function() {
  719. keyInput.value = key.split(':')[1];
  720. valueInput.value = entryData.value.slice(1, -1); // Remove surrounding brackets for editing
  721. probabilityInput.value = entryData.probability;
  722. timeRangeInput.value = entryData.timeRange;
  723. };
  724.  
  725. entriesList.appendChild(row);
  726. }
  727. }
  728. }
  729. }
  730.  
  731.  
  732.  
  733.  
  734.  
  735. function highlightSelectedProfile(selectedItem) {
  736. // Remove highlight from all items
  737. Array.from(profileList.children).forEach(item => {
  738. item.style.backgroundColor = '';
  739. });
  740. // Highlight the selected item
  741. selectedItem.style.backgroundColor = '#444444';
  742. selectedItem.style.borderRadius = '10px';
  743. selectedItem.style.padding = '10px';
  744. }
  745.  
  746. loadProfiles();
  747. loadEntries();
  748.  
  749. // Append profilePanel to body
  750. document.body.appendChild(profilePanel);
  751. }
  752. /*
  753. // Function to select a random entry and output to console
  754. function getRandomEntry() {
  755. const selectedProfile = localStorage.getItem('events.selectedProfile');
  756. if (selectedProfile) {
  757. let profileEntries = [];
  758. const currentHour = new Date().getHours();
  759. for (let key in localStorage) {
  760. if (key.startsWith(`events.${selectedProfile}:`)) {
  761. const entryData = JSON.parse(localStorage.getItem(key));
  762. const [startHour, endHour] = entryData.timeRange.split('-').map(Number);
  763. // Check if current hour is within the specified time range
  764. if (currentHour >= startHour && currentHour < endHour) {
  765. profileEntries.push({ key, ...entryData });
  766. }
  767. }
  768. }
  769. if (profileEntries.length > 0) {
  770. const probability = parseInt(localStorage.getItem('events.probability') || '100', 10);
  771. let selectedEntry = null;
  772. while (profileEntries.length > 0) {
  773. // Randomly select an entry from the available entries
  774. const randomIndex = Math.floor(Math.random() * profileEntries.length);
  775. const randomEntry = profileEntries[randomIndex];
  776. // Check if the entry passes the individual probability check
  777. if (Math.random() * 100 < randomEntry.probability) {
  778. selectedEntry = randomEntry;
  779. break;
  780. } else {
  781. // Remove the entry from the list if it fails the probability check
  782. profileEntries.splice(randomIndex, 1);
  783. }
  784. }
  785. if (selectedEntry && Math.random() * 100 < probability) {
  786. console.log(`Random Entry - Key: ${selectedEntry.key}, Value: ${selectedEntry.value}`);
  787.  
  788. // Add the entry to the textarea
  789. const textarea = document.querySelector('div#prompt-textarea.ProseMirror');
  790. if (textarea) {
  791. // Create a new paragraph element for the random entry, like the customMessages
  792. const newParagraph = document.createElement('p');
  793. newParagraph.textContent = selectedEntry.value;
  794. textarea.appendChild(newParagraph);
  795.  
  796. console.log('Random entry added as a new paragraph.');
  797. } else {
  798. console.log('Textarea not found.');
  799. }
  800. } else {
  801. console.log('No entry selected this time based on the given probability.');
  802. }
  803. } else {
  804. console.log('No entries available for the selected profile in the current time range.');
  805. }
  806. } else {
  807. console.log('No profile selected. Please select a profile to retrieve a random entry.');
  808. }
  809. }
  810.  
  811. // Expose the function to be accessible from other scripts
  812. unsafeWindow.getRandomEntry = getRandomEntry;
  813. */
  814. })();